﻿/* Self-hosted display face — headings, stat numerals, wordmark. Latin subset only:
   Korean/Japanese glyphs fall through per-glyph to the system CJK fonts in the stack
   (see --font-display), which keeps mixed-script headings from going anemic. */
@font-face {
    font-family: 'Barlow Condensed';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/barlow-condensed-500.woff2') format('woff2');
}

@font-face {
    font-family: 'Barlow Condensed';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/fonts/barlow-condensed-600.woff2') format('woff2');
}

@font-face {
    font-family: 'Barlow Condensed';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/fonts/barlow-condensed-700.woff2') format('woff2');
}

:root {
    --font-display: 'Barlow Condensed', 'Malgun Gothic', 'Yu Gothic UI', 'Apple SD Gothic Neo', 'Hiragino Sans', sans-serif;
    /* Body face, matching MudBlazor's default. Declared here because MudBlazor's own copy
       arrives with the circuit, and the shell paints before that. */
    --font-body: Roboto, Helvetica, Arial, sans-serif;
}

/* The shell paints before any circuit, and every --mud-* custom property is emitted by
   MudThemeProvider inside one — including the palette MudBlazor's own body rule reads. So the
   shell owns its base, from --mix-* tokens the server emits (docs/design/static-shell.md D5). */
body {
    background: var(--mix-bg);
    color: var(--mix-ink);
    font-family: var(--font-body);
}

/* MudBlazor 8.15 sizes a temporary drawer `width: var(--mud-drawer-width)` and puts no
   max-width on it anywhere, so a drawer declared wider than the glass hangs off the edge it
   is anchored to and nothing brings it back — a drawer scrolls vertically only. /Charts'
   filter drawer is 420px, which is past a folded Fold's cover screen. max-width beats width
   whatever the specificity, and a fixed element resolves the percentage against the viewport,
   so a declared width still applies wherever it fits and only an over-wide drawer is clamped.
   Site-wide because /Titles' detail drawer (400px) loses the same strip at 360px. */
.mud-drawer.mud-drawer-temporary {
    max-width: 100%;
}

/* Big-number treatment for stats (rating, Pumbility, scores). tabular-nums keeps digit
   columns steady while values tick up live. */
.stat-display {
    font-family: var(--font-display);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: .02em;
}

/* ===== The circuit-drop overlay =====
   App.razor supplies #components-reconnect-modal, so Blazor stops building its own and just
   toggles state classes on ours. The framework's user-supplied-dialog path sets classes and
   nothing else — no inert, no scroll lock — so how much of the page an outage covers is
   decided entirely here, and it covers a corner. A dropped circuit leaves the rendered page
   readable: scrolling works, the static shell's nav works, and every navigation is a full
   document load, so a link the reader can still see and click is the fastest repair available
   to them. Dimming the page hid that and left them watching a spinner instead.
   Everything here is --mix-*: a dropped circuit is exactly the moment MudThemeProvider's
   --mud-* vars can't be relied on. Every rule is id-scoped because MudBlazor ships its own
   #components-reconnect-modal rules (background, z-index, and a
   `#components-reconnect-modal button` that outranks a bare class). */

#components-reconnect-modal {
    display: none;
    position: fixed;
    /* Docked, not draped: under the app bar, clear of the mobile bottom nav. */
    inset: auto;
    top: calc(var(--shell-appbar-h) + 8px);
    right: 8px;
    max-width: min(340px, calc(100vw - 16px));
    /* !important answers MudBlazor's own !important background; site.css loads after theirs. */
    background: none !important;
    /* The box shrink-wraps its card today, so this changes nothing today. It is what keeps a
       later padding or max-width edit from quietly parking a dead click zone over the page. */
    pointer-events: none;
}

/* No state class means no circuit trouble; -hide is the reconnected case. Both stay down.
   Every other class the framework can set has to be listed: an unlisted one leaves the box
   hidden, which is a frozen page with nothing on screen accounting for it. */
#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-paused,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-resume-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
}

#components-reconnect-modal .reconnect-card {
    display: flex;
    gap: 12px;
    padding: 12px 15px;
    border-radius: 10px;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    background: var(--mix-surface);
    color: var(--mix-ink);
    box-shadow: 0 14px 44px -16px color-mix(in srgb, var(--mix-bg) 90%, transparent);
    font-family: var(--font-body);
    text-align: left;
    /* The dock above is inert so the page keeps its clicks; the card takes its own back,
       because two of the three states carry a button that has to be reachable. */
    pointer-events: auto;
}

/* A dead session reads differently from a retry in progress: same box, louder edge. */
#components-reconnect-modal.components-reconnect-failed .reconnect-card,
#components-reconnect-modal.components-reconnect-resume-failed .reconnect-card,
#components-reconnect-modal.components-reconnect-rejected .reconnect-card {
    border-left: 3px solid var(--mix-secondary);
}

/* Paused is neither: the circuit is waiting to be picked up, not gone. */
#components-reconnect-modal.components-reconnect-paused .reconnect-card {
    border-left: 3px solid var(--mix-accent);
}

/* Every state ships; the class Blazor set decides which one has a box. */
#components-reconnect-modal .reconnect-state { display: none; }

#components-reconnect-modal.components-reconnect-show .reconnect-on-show,
#components-reconnect-modal.components-reconnect-paused .reconnect-on-paused,
#components-reconnect-modal.components-reconnect-failed .reconnect-on-failed,
#components-reconnect-modal.components-reconnect-resume-failed .reconnect-on-resume-failed,
#components-reconnect-modal.components-reconnect-rejected .reconnect-on-rejected {
    display: flex;
    gap: 12px;
    align-items: flex-start;
}

#components-reconnect-modal .reconnect-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

#components-reconnect-modal .reconnect-title {
    margin: 0;
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1.15;
}

/* Says which controls are dead. Undimmed, nothing else on screen says it. */
#components-reconnect-modal .reconnect-sub {
    margin: 0;
    font-size: .78rem;
    color: var(--mix-ink-muted);
}

/* -retrying rides on top of -show once the ladder starts backing off. Before that the
   attempts are instant, so there is no wait worth counting and the line stays down. */
#components-reconnect-modal .reconnect-retry-line {
    font-variant-numeric: tabular-nums;
}

#components-reconnect-modal:not(.components-reconnect-retrying) .reconnect-retry-line {
    display: none;
}

#components-reconnect-modal .reconnect-spinner {
    display: block;
    width: 20px;
    height: 20px;
    flex: none;
    margin-top: 3px;
    border-radius: 50%;
    border: 3px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
    border-top-color: var(--mix-primary);
    animation: reconnect-spin .9s linear infinite;
}

@keyframes reconnect-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    #components-reconnect-modal .reconnect-spinner { animation-duration: 3s; }
}

#components-reconnect-modal .reconnect-btn {
    margin-top: 8px;
    align-self: flex-start;
    padding: 6px 14px;
    border-radius: 6px;
    border: 1px solid var(--mix-primary);
    background: var(--mix-primary);
    color: var(--mix-primary-contrast);
    /* The shorthand resets every font-* longhand, so the size must come after it. */
    font: inherit;
    font-size: .82rem;
    font-weight: 600;
    cursor: pointer;
}

#components-reconnect-modal .reconnect-btn:hover {
    background: color-mix(in srgb, var(--mix-primary) 85%, var(--mix-ink));
}

/* ===== Shell: app bar, wordmark, top nav, mega-menus, mix pill =====
   The bar and its menus are server-rendered HTML with no circuit behind them, so every value
   MudAppBar/MudMenu used to supply is pinned here. Heights and z-indexes match the MudTheme
   defaults they replace (docs/design/static-shell.md §9): appbar height is Dense
   (64px - 64px/4 = 48px) and ZIndex.AppBar is 1300, which is what keeps the bar stacked
   correctly against Mud's popovers (1200) and dialogs (1400). */

:root {
    --shell-appbar-h: 48px;
}

.shell-appbar {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    z-index: 1300;
    display: flex;
    align-items: center;
    gap: 4px;
    height: var(--shell-appbar-h);
    box-sizing: border-box;
    padding: 0 12px;
    background: var(--mix-nav);
    color: var(--mix-ink);
    box-shadow: 0 2px 4px -1px rgba(0, 0, 0, .2), 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12);
}

.shell-main {
    padding-top: var(--shell-appbar-h);
}

.shell-spacer {
    flex: 1 1 auto;
}

/* Breakpoint seam at Mud's Md (960px), replacing MudHidden — which needed JS to measure the
   viewport before it could decide what to render. Each side only ever hides: the elements
   themselves own their display value, because the bottom nav (flex) and the More sheet
   (block) don't share one. */
@media (max-width: 959.98px) {
    .shell-desktop-only {
        display: none !important;
    }
}

@media (min-width: 960px) {
    .shell-mobile-only {
        display: none !important;
    }
}

/* ===== Shell menus (the static stand-in for MudMenu + its popover) ===== */

.shell-menu {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.shell-menu-panel {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 1;
    display: none;
    min-width: 200px;
    max-width: calc(100vw - 16px);
    padding: 4px 0;
    border-radius: 4px;
    background: var(--mix-surface);
    box-shadow: 0 5px 5px -3px rgba(0, 0, 0, .2), 0 8px 10px 1px rgba(0, 0, 0, .14), 0 3px 14px 2px rgba(0, 0, 0, .12);
}

/* Menus at the bar's right edge open inward. nav.js shifts any panel that still overflows. */
.shell-menu-panel-end {
    left: auto;
    right: 0;
}

.shell-menu.open .shell-menu-panel {
    display: block;
}

.shell-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    cursor: pointer;
    font-size: .875rem;
    color: var(--mix-ink);
    text-decoration: none;
    white-space: nowrap;
    list-style: none;
}

.shell-menu-item:hover {
    background: rgba(255, 255, 255, .08);
    text-decoration: none;
}

.shell-menu-item::-webkit-details-marker {
    display: none;
}

.shell-menu-caption {
    padding: 4px 16px;
    font-size: .8rem;
    color: var(--mix-ink-muted);
}

.shell-menu-divider {
    margin: 4px 0;
    border-top: 1px solid rgba(255, 255, 255, .12);
}

/* Native disclosure carries the mix picker's collections and the More sheet's subgroups —
   no circuit, and keyboard support comes free. */
.shell-disclosure > summary {
    display: flex;
}

.shell-disclosure[open] > summary .mud-icon-root {
    transform: rotate(90deg);
}

.shell-disclosure-body .shell-menu-item {
    padding-left: 40px;
}

.shell-avatar-btn,
.shell-icon-btn {
    display: inline-flex;
    align-items: center;
    padding: 4px;
    background: none;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    color: var(--mix-ink);
}

.shell-avatar-btn:hover,
.shell-icon-btn:hover {
    background: rgba(255, 255, 255, .08);
}

.wordmark {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: .08em;
    color: var(--mix-ink);
    text-shadow: 0 0 12px var(--mix-glow);
    text-decoration: none;
    white-space: nowrap;
}

.top-nav {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: 14px;
}

.top-nav-btn {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 6px 10px;
    border-radius: 6px;
    font-family: var(--font-display);
    font-weight: 500;
    font-size: .95rem;
    letter-spacing: .05em;
    color: var(--mix-ink);
    text-decoration: none;
    white-space: nowrap;
}

.top-nav-btn:hover {
    background: rgba(255, 255, 255, .08);
}

/* Tier Lists is top-level when the bar has room for seven items and folds into Play when
   it doesn't. 1280 is MudBlazor's Lg — the ladder the rest of the app speaks — and it puts
   every tablet-landscape width (1024, 1180, 1194) on the folded side while every real
   laptop keeps the full bar. Both copies ship in the HTML; exactly one is ever shown. */
.nav-wide-only {
    display: none;
}

@media (min-width: 1280px) {
    .top-nav .nav-wide-only {
        display: inline-flex;
    }

    .nav-folded-only {
        display: none;
    }
}

.mix-pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    background: transparent;
    border: 1px solid var(--mix-primary);
    border-radius: 16px;
    padding: 3px 12px;
    cursor: pointer;
    font-family: var(--font-display);
    font-weight: 500;
    font-size: .8rem;
    letter-spacing: .08em;
    color: var(--mix-ink);
    white-space: nowrap;
}

.mix-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--mix-primary);
    box-shadow: 0 0 8px var(--mix-glow);
}

/* The mix dropdown's primary rows lead with the game's wordmark in a fixed slot, so the names
   line up whatever the mark's width. */
.mix-row-mark {
    width: 56px;
    flex: 0 0 56px;
    display: inline-flex;
    justify-content: center;
    align-items: center;
}

.mix-row-logo {
    height: 22px;
    width: auto;
    max-width: 56px;
    object-fit: contain;
}

/* App-bar chart search — a quiet pill that matches the mix pill, not a form field.
   The outlined border and dropdown caret are stripped; focus brings the theme primary in. */
.appbar-search .mud-input-control {
    margin: 0;
}

.appbar-search .mud-input.mud-input-outlined {
    background: rgba(255, 255, 255, .07);
    border-radius: 16px;
    font-size: .85rem;
}

.appbar-search .mud-input.mud-input-outlined:focus-within {
    background: rgba(255, 255, 255, .11);
    box-shadow: 0 0 0 1px var(--mix-primary);
}

.appbar-search .mud-input.mud-input-outlined input {
    color: var(--mix-ink);
    padding: 5px 14px;
    height: unset;
}

.appbar-search .mud-input.mud-input-outlined input::placeholder {
    color: var(--mix-ink-muted);
    opacity: 1;
}

.appbar-search .mud-input.mud-input-outlined .mud-input-outlined-border {
    border: none;
}

.appbar-search .mud-input-adornment {
    display: none;
}

/* The site search's list: three sections in one MudAutocomplete. A section label is a
   disabled row — the arrow keys skip it — and a player row wears the board row-glow states
   (.is-community / .is-rival / .is-both) by bleeding its own box out to the list item's edges,
   since the item element is Mud's. */
.site-search-list .mud-list-item-disabled {
    opacity: 1;
    pointer-events: none;
}

.site-search-head {
    display: block;
    font-family: var(--font-display);
    font-size: .74rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    padding-top: 4px;
}

.site-search-list .mud-list-item-disabled + .mud-list-item .site-search-row {
    margin-top: 0;
}

.site-search-row {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
    margin: -6px -16px;
    padding: 6px 16px;
}

/* The name is the row; it keeps its width and the game tag beside it is what gives way when a
   row runs short — a name cut to "12be…" next to a whole tag was the wrong thing truncated. */
.site-search-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.site-search-sub {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 45%;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: .72rem;
    color: var(--mix-ink-muted);
    white-space: nowrap;
}

.site-search-note {
    margin-left: auto;
    font-size: .68rem;
    color: var(--mix-ink-muted);
    white-space: nowrap;
}

.site-search-verified {
    margin-left: auto;
    flex: none;
}

/* One pulse when something opens the search programmatically (shell.openSearch) —
   settles into the same ring the focused field already wears. */
@media (prefers-reduced-motion: no-preference) {
    .appbar-search.search-flash .mud-input.mud-input-outlined {
        animation: search-flash .9s ease-out;
    }

    @keyframes search-flash {
        0% { box-shadow: 0 0 0 5px var(--mix-primary), 0 0 26px var(--mix-glow); }
        100% { box-shadow: 0 0 0 1px var(--mix-primary); }
    }
}

/* ===== Atmosphere: per-mix page-ground light, derived from each game's attract screen.
   Ground only — cards and surfaces stay flat so contrast is untouched. Trial feature:
   deleting a theme's block (or all three) fully removes it. ===== */

body.theme-phoenix {
    background:
        radial-gradient(1200px 800px at 85% -10%, rgba(255, 107, 53, .10), transparent 60%),
        radial-gradient(1000px 700px at 10% 110%, rgba(63, 169, 245, .08), transparent 60%),
        var(--mix-bg);
    background-attachment: fixed;
    min-height: 100vh;
}

body.theme-xx {
    background:
        radial-gradient(1100px 700px at 80% -10%, rgba(255, 47, 160, .10), transparent 60%),
        radial-gradient(900px 700px at 5% 105%, rgba(53, 200, 255, .08), transparent 60%),
        var(--mix-bg);
    background-attachment: fixed;
    min-height: 100vh;
}

body.theme-phoenix2 {
    background:
        radial-gradient(1200px 700px at 70% -15%, rgba(79, 227, 63, .10), transparent 55%),
        radial-gradient(1000px 800px at 15% 115%, rgba(43, 193, 216, .07), transparent 60%),
        var(--mix-bg);
    background-attachment: fixed;
    min-height: 100vh;
}

/* RISE: the yellow of the title and the profile's hot pink, on ink navy. */
body.theme-rise {
    background:
        radial-gradient(1200px 700px at 75% -15%, rgba(255, 198, 26, .10), transparent 55%),
        radial-gradient(1000px 800px at 10% 115%, rgba(255, 61, 138, .07), transparent 60%),
        var(--mix-bg);
    background-attachment: fixed;
    min-height: 100vh;
}

/* RISE's Arcade Station: aqua stepball light over midnight water, lavender below. */
body.theme-rise-arcade {
    background:
        radial-gradient(1200px 700px at 70% -15%, rgba(90, 197, 222, .10), transparent 55%),
        radial-gradient(1000px 800px at 15% 115%, rgba(180, 140, 255, .07), transparent 60%),
        var(--mix-bg);
    background-attachment: fixed;
    min-height: 100vh;
}

/* ===== Mobile: bottom nav + More sheet ===== */

.bottom-nav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1300;
    display: flex;
    align-items: stretch;
    background: var(--mix-nav);
    border-top: 1px solid rgba(255, 255, 255, .08);
    padding-bottom: env(safe-area-inset-bottom);
}

.bottom-nav .bn {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 8px 0 9px;
    background: none;
    border: none;
    cursor: pointer;
    font-family: var(--font-display);
    font-size: .68rem;
    letter-spacing: .04em;
    color: var(--mix-ink-muted);
    text-decoration: none;
}

.bottom-nav .bn.active {
    color: var(--mix-primary);
}

/* The Communities slot only earns space on squarish viewports (fold phones, landscape). */
.bottom-nav .bn-wide {
    display: none;
}

@media (min-aspect-ratio: 1/1) {
    .bottom-nav .bn-wide {
        display: flex;
    }
}

/* Keep page content clear of the fixed bottom nav (Md breakpoint = 960px). */
@media (max-width: 959.98px) {
    .shell-main {
        padding-bottom: 72px;
    }

    /* Pages with a dock need clearance for both bars (the at-rest worst case). */
    html.has-dock .shell-main {
        padding-bottom: 132px;
    }
}

/* ===== Page dock (docs/design/randomizer-overhaul.md) =====
   Page-registered primary actions above the bottom nav. Scrolling down slides the
   nav away (html.nav-away, set by page-dock.js) and the dock takes the bottom edge;
   both bars only coexist at rest. */

:root {
    --bottom-nav-h: calc(53px + env(safe-area-inset-bottom));
}

.bottom-nav {
    transition: transform .25s ease;
}

html.nav-away .bottom-nav {
    transform: translateY(110%);
}

.page-dock {
    position: fixed;
    left: 0;
    right: 0;
    bottom: var(--bottom-nav-h);
    z-index: 1299;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    background: var(--mix-nav);
    border-top: 1px solid rgba(255, 255, 255, .08);
    transition: bottom .25s ease, padding-bottom .25s ease;
}

html.nav-away .page-dock,
html.focus-mode .page-dock {
    bottom: 0;
    padding-bottom: calc(8px + env(safe-area-inset-bottom));
}

@media (prefers-reduced-motion: reduce) {
    .bottom-nav,
    .page-dock {
        transition: none;
    }
}

/* Focus mode: shell chrome gone. The page owes the user an explicit exit affordance.
   Both bars are server-rendered now, so both are hidden here rather than skipped. */
html.focus-mode .shell-appbar,
html.focus-mode .bottom-nav {
    display: none !important;
}

html.focus-mode .shell-main {
    padding-top: 12px;
}

/* The mobile More sheet, replacing MudDrawer's temporary-bottom variant. It hides by
   translating its own height off-screen, so the height must be fixed — "auto" leaves nothing
   to translate and the sheet renders permanently open. */
.more-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1400;
    height: 75vh;
    overflow-y: auto;
    background: var(--mix-nav);
    transform: translateY(100%);
    transition: transform .225s cubic-bezier(0, 0, .2, 1);
    scrollbar-width: none;
}

.more-sheet::-webkit-scrollbar {
    display: none;
}

.more-sheet.open {
    transform: translateY(0);
}

.more-sheet-body {
    padding: 8px 0 16px;
}

.more-sheet-scrim {
    position: fixed;
    inset: 0;
    z-index: 1399;
    background: rgba(0, 0, 0, .5);
    opacity: 0;
    pointer-events: none;
    transition: opacity .225s cubic-bezier(0, 0, .2, 1);
}

html.sheet-open .more-sheet-scrim {
    opacity: 1;
    pointer-events: auto;
}

/* The search sheet drops from the TOP, unlike More. The phone keyboard takes the bottom half
   of the screen the moment the input focuses, so a bottom-anchored field opens underneath the
   thing typing into it. It is only as tall as it needs to be — this asks one question. */
.search-sheet {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    z-index: 1400;
    background: var(--mix-nav);
    border-bottom: 1px solid rgba(255, 255, 255, .10);
    transform: translateY(-100%);
    transition: transform .225s cubic-bezier(0, 0, .2, 1);
}

.search-sheet.open {
    transform: translateY(0);
}

.search-sheet-body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 14px 16px 18px;
}

.search-sheet-label {
    font-family: var(--font-display);
    font-size: .6875rem;
    letter-spacing: .08em;
    line-height: 1.4;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

/* The autocomplete's popover is teleported to the provider at the document root, so it is
   never clipped by this box — the sheet only has to frame the input. */
.search-sheet-input {
    display: flex;
    align-items: center;
}

/* A thumb target, not an app-bar accent: taller than the desktop pill, and never under 16px
   — iOS Safari zooms the whole viewport when a smaller input takes focus. */
.search-sheet-input .mud-input.mud-input-outlined {
    width: 100%;
    border-radius: 10px;
}

.search-sheet-input .mud-input.mud-input-outlined input {
    padding: 11px 14px;
    font-size: 1rem;
}

/* The group head is a section label by default. nav.js promotes it to a tappable row when
   the viewport is too narrow for the grid; until then its chevron stays hidden so it never
   advertises an interaction it doesn't have. */
.more-sheet .more-group-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px 2px;
    font-family: var(--font-display);
    font-size: .6875rem;
    letter-spacing: .08em;
    line-height: 1.4;
    text-transform: uppercase;
    opacity: .65;
}

.more-sheet .more-group-head .mud-icon-root {
    font-size: .95rem;
}

.more-sheet .more-group-chevron,
.more-sheet .more-back {
    display: none;
}

/* ---- Drill-down: narrow, tall viewports ----------------------------------------------
   No horizontal room for tiles, so the groups collapse to a root list of section names and
   open one at a time. nav.js adds .drill-mode (layout is narrow) and .drill-inside (a group
   is open); the markup is identical to the grid's. */
.more-sheet .drill-mode .more-group-head {
    padding: 8px 16px;
    font-family: var(--font-body);
    font-size: .875rem;
    letter-spacing: normal;
    text-transform: none;
    opacity: 1;
    cursor: pointer;
}

.more-sheet .drill-mode .more-group-head:hover,
.more-sheet .drill-mode .more-group-head:focus-visible {
    background: rgba(255, 255, 255, .08);
}

.more-sheet .drill-mode .more-group-head .mud-icon-root {
    font-size: 1.25rem;
}

/* Pushed to the far edge so the row reads as "there is more this way". */
.more-sheet .drill-mode .more-group-chevron {
    display: inline-flex;
    margin-left: auto;
    opacity: .5;
}

.more-sheet .drill-mode .more-group-body {
    display: none;
}

.more-sheet .drill-mode .more-group.drill-open .more-group-body {
    display: block;
}

/* The open group's own head is redundant once the back bar names the section. */
.more-sheet .drill-mode .more-group.drill-open .more-group-head {
    display: none;
}

.more-sheet .drill-mode.drill-inside > .shell-menu-item {
    display: none;
}

.more-sheet .drill-mode .more-back {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 10px 16px;
    background: none;
    border: 0;
    border-bottom: 1px solid rgba(255, 255, 255, .08);
    color: var(--mix-primary);
    font-family: var(--font-display);
    font-size: .9375rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    cursor: pointer;
}

/* ---- Icon grid: squarish or wide viewports -------------------------------------------
   The aspect half is the same rule the bottom nav's wide-only slot uses (fold phones,
   landscape). The width floor catches portrait tablets, which are taller than 1:1 but have
   room to spare. Above 960 none of this applies — the desktop top nav has taken over. */
@media (min-aspect-ratio: 1/1), (min-width: 700px) {
    .more-sheet .more-group-body {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
        gap: 6px;
        padding: 4px 10px 2px;
    }

    .more-sheet .more-group-body .shell-menu-item {
        flex-direction: column;
        gap: 6px;
        min-height: 82px;
        padding: 12px 6px 10px;
        border-radius: 10px;
        background: var(--mix-surface);
        text-align: center;
        white-space: normal;
    }

    .more-sheet .more-group-body .shell-menu-item .mud-icon-root {
        font-size: 1.4rem;
    }

    /* Two lines, then ellipsis. Tournament names are owner-authored and can be any length,
       so the tile has to survive one without stretching the row it sits in. */
    .more-sheet .more-group-body .shell-menu-item span {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        font-size: .75rem;
        line-height: 1.25;
    }
}

@media (prefers-reduced-motion: reduce) {
    .more-sheet,
    .more-sheet-scrim {
        transition: none;
    }
}

/* ===== Randomizer draw cards (docs/design/randomizer-overhaul.md) =====
   Rides the tier-chart-card base. Held deliberately wears the mix-primary ring, NOT
   the owner-locked pass-green; vetoed dims + strikes in place (state words print in
   chips/tooltips, so hue never travels alone). */

.draw-card-order {
    position: absolute;
    top: 4px;
    right: 4px;
    min-width: 20px;
    height: 20px;
    padding: 0 5px;
    border-radius: 6px;
    display: grid;
    place-items: center;
    background: var(--mix-accent);
    color: var(--mix-primary-contrast);
    font-size: .72rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    box-shadow: 0 1px 4px rgba(0, 0, 0, .55);
}

/* Held/vetoed border rules live with the tier-card border language further down —
   the base card declares a `border` shorthand at equal specificity, so source order
   is what lets the state colors win (same rule as the pass/To-Do states). */

.draw-card-vetoed .tier-chart-card-jacket {
    filter: grayscale(.85) brightness(.5);
}

.draw-card-vetoed .draw-card-name {
    text-decoration: line-through;
    color: var(--mud-palette-text-secondary);
}

.draw-card-state-chip {
    position: absolute;
    bottom: 4px;
    right: 4px;
    border-radius: 6px;
    padding: 1px 7px;
    font-size: .62rem;
    font-weight: 800;
    letter-spacing: .07em;
    text-transform: uppercase;
}

.draw-card-state-held-chip {
    background: var(--mix-primary);
    color: var(--mix-primary-contrast);
}

.draw-card-state-vetoed-chip {
    background: var(--mud-palette-error);
    color: var(--mud-palette-error-text);
}

/* Compact keeps a name line (identity survives unfamiliar jackets, rule 2). */
.draw-card .tier-chart-card-name {
    font-size: .72rem;
    line-height: 1.5;
    display: block;
}

/* Comfortable wraps the name in its tooltip, whose root is inline-block and, inside the body's
   block layout, would grow to the whole name and leave the "…" nothing to cut. */
.draw-card .tier-chart-card-body > .mud-tooltip-root {
    display: block;
}

/* ===== Randomizer page (draw-first layout) ===== */

.rand-header {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}


.rand-anon-note {
    color: var(--mix-ink-muted);
    margin-bottom: 4px;
}

.rand-chipbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
    margin: 4px 0;
}

.rand-countline {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 8px;
}

.rand-count-n {
    font-weight: 800;
    color: var(--mix-primary);
    font-variant-numeric: tabular-nums;
}

.rand-count-label {
    font-size: .78rem;
    color: var(--mix-ink-muted);
}

.rand-actionbar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

/* Reference strip below the cards: what this draw was configured with. */
.rand-draw-settings {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
    margin-top: 18px;
    opacity: .8;
}

.rand-draw-settings-label {
    font-family: var(--font-display);
    font-size: .68rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    margin-right: 8px;
}

.rand-grid {
    display: grid;
    gap: 8px;
}

.rand-grid-compact {
    grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
}

.rand-grid-comfortable {
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
}

/* A ghost of the card that will land there: same shape, surface, and radius as a
   tier-chart-card, dashed to read as "empty slot". */
.rand-add-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    border: 2px dashed var(--mud-palette-lines-default);
    border-radius: 8px;
    background: var(--mud-palette-surface);
    color: var(--mix-ink-muted);
    min-height: 104px;
    cursor: pointer;
}

.rand-add-tile:hover {
    border-color: var(--mix-primary);
    color: var(--mix-ink);
}

.rand-add-tile-plus {
    font-size: 1.6rem;
    line-height: 1;
}

.rand-add-tile-label {
    font-family: var(--font-display);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .05em;
}

.rand-add-tile:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
}

.rand-add-anchor {
    display: flex;
}

.rand-add-anchor .rand-add-tile {
    flex: 1;
    width: 100%;
}

.rand-add-pop {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 300px;
    max-width: 90vw;
}

/* New match popover (round 12): the panel content inside whichever trigger's popover. */
.rand-new-match-pop {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 300px;
    max-width: 90vw;
    padding: 14px;
}

/* Header + empty-state anchors hug their button; the dock anchor fills the CTA slot. */
.rand-newmatch-anchor {
    display: inline-flex;
}

.dock-cta-anchor {
    flex: 1;
    display: flex;
}

.rand-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 40px 16px;
    text-align: center;
    color: var(--mix-ink-muted);
}

.rand-table .rand-table-order {
    font-weight: 800;
    color: var(--mix-accent);
    font-variant-numeric: tabular-nums;
    width: 34px;
}

.rand-table .rand-table-name {
    font-weight: 600;
}

.rand-table .rand-table-actions {
    text-align: right;
    white-space: nowrap;
}

.rand-row-vetoed .rand-table-name {
    text-decoration: line-through;
    color: var(--mud-palette-text-secondary);
}

.rand-row-held .rand-table-name {
    color: var(--mix-primary);
}

.rand-drawer {
    display: flex;
    flex-direction: column;
}

.rand-drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 16px 16px 8px;
}

/* The drawer is viewport-wide (bottom sheet), but its content column isn't — full-bleed
   controls floated the Advanced toggle mid-screen on desktop (round 7). */
.rand-drawer-body > * {
    max-width: 720px;
    margin-left: auto;
    margin-right: auto;
}

.rand-drawer-footer > * {
    flex-shrink: 0;
}

.rand-drawer-footer {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
    border-top: 1px solid rgba(255, 255, 255, .08);
}

.rand-footer-row {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    width: 100%;
    max-width: 720px;
    margin: 0 auto;
}

.rand-drawer-count {
    display: flex;
    align-items: baseline;
    gap: 6px;
    margin-right: auto;
}

.rand-save-name {
    max-width: 200px;
}

/* Dock content shared by randomizer (and future dock pages). */
.page-dock .dock-cta {
    flex: 1;
    height: 44px;
    border-radius: 12px;
    background: var(--mix-primary);
    color: var(--mix-primary-contrast);
    font-weight: 800;
    letter-spacing: .04em;
    box-shadow: 0 0 20px var(--mix-glow);
}

.page-dock .dock-side {
    border: 1px solid rgba(255, 255, 255, .08);
    border-radius: 12px;
}

/* Tournament context + draft mode (docs/design/randomizer-overhaul.md C9). */

.rand-context-select {
    max-width: 260px;
}

.rand-create-tournament {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    border: 1px dashed var(--mud-palette-lines-default);
    border-radius: 10px;
    padding: 10px 12px;
    margin: 6px 0;
}

.rand-create-tournament .mud-input-control {
    flex: 1;
    min-width: 200px;
}

.rand-invites {
    display: flex;
    flex-direction: column;
    gap: 6px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 10px;
    padding: 10px 12px;
    margin: 6px 0;
}

.rand-invite-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.rand-invite-role {
    font-weight: 700;
    font-size: .82rem;
    min-width: 82px;
}

.rand-invite-expiry {
    font-size: .78rem;
    color: var(--mix-ink-muted);
    margin-right: auto;
}

.rand-invite-mint {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    border-top: 1px dashed var(--mud-palette-lines-default);
    padding-top: 8px;
}

.rand-invite-mint .mud-input-control {
    max-width: 150px;
}

/* Match picker (round 9): rides the header, right-aligned — the field carries only
   "which match am I looking at". New match joins it on desktop; the dock CTA covers
   phones. On phone widths it takes its own full line instead of squeezing the title. */
.rand-header-match {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 10px;
}

.rand-header-match .rand-match-select {
    min-width: 200px;
    max-width: 300px;
}

@media (max-width: 599.98px) {
    .rand-header-match {
        flex: 1 1 100%;
        margin-left: 0;
    }

    .rand-header-match .rand-match-select {
        max-width: none;
        flex: 1;
    }
}

/* Manage-tournament drawer (round 8): stacked role-layered sections. */
.rand-manage-section {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 26px;
}

.rand-manage-heading {
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--mix-ink-muted);
}

.rand-manage-rename {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.rand-manage-rename .mud-input-control {
    flex: 1;
    min-width: 200px;
}

.rand-manage-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.rand-staff-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.rand-staff-row .rand-invite-role {
    margin-right: auto;
}

/* Draft mode: the staff tablet in player hands — loud mode control, explicit exit. */
.rand-draft-head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

/* Two-line preset items: name + summary — legible on touch, no hover needed. */
.rand-preset-item {
    display: flex;
    flex-direction: column;
    line-height: 1.3;
    padding: 2px 0;
}

.rand-preset-name {
    font-weight: 700;
    font-size: .85rem;
}

/* Summaries render only on the open dropdown's list items — the closed select shows
   just the preset name (round 7: the two-line clone skewed the input's layout).
   Scoped to .mud-list-item, not .mud-popover, so it stays hidden even when the whole
   select lives inside another popover, like the New match panel (round 12). */
.rand-preset-summary {
    display: none;
    font-size: .7rem;
    color: var(--mix-ink-muted);
}

.mud-list-item .rand-preset-summary {
    display: block;
}

.rand-preset-select {
    min-width: 220px;
}

.rand-drawer-presets {
    margin-bottom: 14px;
}

.rand-exit-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 999px;
    padding: 6px 14px;
    background: none;
    cursor: pointer;
    font-size: .82rem;
    font-weight: 700;
    color: var(--mix-ink);
}

.rand-tour-pill {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 999px;
    padding: 6px 14px;
    font-size: .82rem;
    font-weight: 700;
    background: var(--mix-surface);
}

.rand-draft-armed {
    margin-bottom: 12px;
}

.rand-live {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-display);
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .14em;
    color: var(--mud-palette-error);
}

.rand-live-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--mud-palette-error);
    box-shadow: 0 0 8px var(--mud-palette-error);
    animation: rand-live-pulse 1.6s infinite;
}

@keyframes rand-live-pulse {
    50% {
        opacity: .35;
    }
}

@media (prefers-reduced-motion: reduce) {
    .rand-live-dot {
        animation: none;
    }
}

.rand-legend {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: .72rem;
    color: var(--mix-ink-muted);
    margin-left: 10px;
}

.rand-legend i {
    width: 10px;
    height: 10px;
    border-radius: 3px;
}

.rand-legend-held {
    background: var(--mix-primary);
}

.rand-legend-vetoed {
    background: var(--mud-palette-error);
}

.page-dock .rand-staff-btn {
    border: 1px solid rgba(255, 255, 255, .08);
    border-radius: 12px;
    color: var(--mud-palette-error);
}

/* ===== Randomizer settings panel ===== */

.rand-settings {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.rand-settings-row {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.rand-settings-label {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
}

.rand-type-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.rand-count-presets {
    display: flex;
    align-items: center;
    gap: 6px;
}

.rand-count-preset,
.rand-coop-chip,
.rand-seg,
.rand-grade-chip {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 9px;
    background: none;
    cursor: pointer;
    color: var(--mix-ink-muted);
    font-family: var(--font-display);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.rand-count-preset {
    min-width: 40px;
    padding: 7px 0;
    font-size: .82rem;
}

.rand-count-custom {
    max-width: 76px;
}

.rand-count-preset.on,
.rand-coop-chip.on,
.rand-seg.on,
.rand-grade-chip.on {
    background: var(--mix-primary);
    border-color: var(--mix-primary);
    color: var(--mix-primary-contrast);
}

/* The Released row's head carries the through select at its right edge, dropping to its own
   line when the panel is narrow; the buttons beside it act on the row, so they are text. */
.rand-row-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 6px 12px;
}

.rand-through {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
    font-size: .8rem;
    color: var(--mix-ink-muted);
}

.rand-through-select {
    max-width: 180px;
    background: var(--mix-surface);
    color: var(--mix-ink);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    padding: 6px 8px;
    font: inherit;
    font-size: .85rem;
}

.rand-through-btn {
    background: none;
    border: none;
    color: var(--mix-secondary);
    cursor: pointer;
    font: inherit;
    font-size: .8rem;
    padding: 2px 4px;
}

.rand-through-btn:hover,
.rand-through-btn:focus-visible {
    color: var(--mix-ink);
    outline: none;
}

.rand-coop-chips {
    display: flex;
    gap: 6px;
}

.rand-coop-chip {
    padding: 6px 13px;
    font-size: .8rem;
}

.rand-seg-group {
    display: flex;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 9px;
    overflow: hidden;
}

.rand-seg {
    flex: 1;
    border: none;
    border-radius: 0;
    padding: 8px 0;
    font-size: .78rem;
}

.rand-grade-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}

.rand-grade-chip {
    padding: 4px 10px;
    font-size: .72rem;
}

.rand-gated-reason {
    color: var(--mix-ink-muted);
}

.rand-advanced-toggle {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    text-align: left;
    gap: 8px;
    width: 100%;
    border: 1px dashed var(--mud-palette-lines-default);
    border-radius: 10px;
    padding: 10px 12px;
    background: none;
    cursor: pointer;
    color: var(--mix-ink-muted);
    font-size: .8rem;
}

/* Slider heads carry a lone switch/note that belongs on the right; the Co-Op head
   still has its label on the left (round 10 fix — a blanket flex-end dragged it over). */
.rand-type-head > :only-child {
    margin-left: auto;
}

.rand-advanced-body {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-top: 8px;
}

/* Opt-in advanced sections: a quiet switch row until enabled. */
.rand-adv-section {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 10px;
    padding: 4px 12px 6px;
}

.rand-adv-section-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.rand-adv-section-content {
    padding: 6px 2px 8px;
}

.rand-section-body {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.rand-owned-note {
    color: var(--mix-ink-muted);
}

.rand-section-hint {
    color: var(--mix-ink-muted);
    display: block;
}

.rand-weighted-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding-top: 4px;
}

.rand-min-mode {
    max-width: 440px;
}

.folder-grid {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 6px;
}

.rand-plain-rows {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 4px;
}

.rand-coop-bounds {
    display: flex;
    gap: 10px;
}

/* Dynamic weight rows (FolderWeightList). */
.weight-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: flex-start;
}

.weight-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.weight-row-label {
    min-width: 52px;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
}

.weight-row-weight {
    font-size: .7rem;
    color: var(--mix-ink-muted);
}

.weight-row-field {
    max-width: 90px;
}

/* ===== Armed action selector ===== */

.armed-selector {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.armed-selector-label {
    font-family: var(--font-display);
    font-size: .68rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.armed-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    border: 2px solid var(--mud-palette-lines-default);
    border-radius: 11px;
    padding: 8px 16px;
    background: none;
    cursor: pointer;
    font-family: var(--font-display);
    font-size: .8rem;
    font-weight: 800;
    letter-spacing: .04em;
    color: var(--mix-ink-muted);
}

.armed-btn:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
}

.armed-btn-on {
    background: var(--mix-primary);
    border-color: var(--mix-primary);
    color: var(--mix-primary-contrast);
    box-shadow: 0 0 18px var(--mix-glow);
}

.armed-btn-on-veto {
    background: var(--mud-palette-error);
    border-color: var(--mud-palette-error);
    color: var(--mud-palette-error-text);
}

/* Staff-tablet sizing: readable at arm's length, tappable in a hurry. */
.armed-selector-loud .armed-btn {
    padding: 12px 24px;
    font-size: .95rem;
    border-radius: 13px;
}

/* ===== Level range slider (dual thumb) ===== */

.range-slider {
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* A thumb's centre travels between half a thumb in from each end, never the full box.
       The fill and the tick rail both measure against that inset so all three agree; the
       fill's calc lives in RangeSlider.razor because the script painting a drag writes the
       same expression. One size across engines: Firefox's default thumb is smaller, and a
       band that reads 20px on one browser and 14px on another is 14px to plan for. */
    --range-thumb: 20px;
}

.range-slider-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.range-slider-label {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
}

.range-slider-value {
    margin-left: auto;
    font-family: var(--font-display);
    font-size: .78rem;
    color: var(--mix-primary);
    font-variant-numeric: tabular-nums;
}

.range-slider-track-wrap {
    position: relative;
    height: 28px;
}

.range-slider-track {
    position: absolute;
    top: 12px;
    left: 0;
    right: 0;
    height: 4px;
    border-radius: 2px;
    background: var(--mix-surface-muted);
}

.range-slider-fill {
    position: absolute;
    top: 12px;
    height: 4px;
    border-radius: 2px;
    background: var(--mix-primary);
    box-shadow: 0 0 8px var(--mix-glow);
}

/* Two overlaid native inputs; only the thumbs take pointer events. */
.range-slider-track-wrap input[type=range] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 28px;
    margin: 0;
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    pointer-events: none;
}

.range-slider-track-wrap input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    pointer-events: auto;
    width: var(--range-thumb);
    height: var(--range-thumb);
    border-radius: 50%;
    background: var(--mix-primary);
    border: 3px solid var(--mix-bg);
    box-shadow: 0 0 0 1.5px var(--mix-primary);
    cursor: pointer;
    margin-top: 4px;
}

.range-slider-track-wrap input[type=range]::-moz-range-thumb {
    pointer-events: auto;
    box-sizing: border-box;
    width: var(--range-thumb);
    height: var(--range-thumb);
    border-radius: 50%;
    background: var(--mix-primary);
    border: 3px solid var(--mix-bg);
    box-shadow: 0 0 0 1.5px var(--mix-primary);
    cursor: pointer;
}

.range-slider-ticks {
    position: relative;
    height: 14px;
    margin: 0 calc(var(--range-thumb) / 2);
}

.range-slider-ticks span {
    position: absolute;
    transform: translateX(-50%);
    font-family: var(--font-display);
    font-size: .6rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.range-slider-disabled .range-slider-fill {
    background: var(--mix-surface-muted);
    box-shadow: none;
}

.range-slider-disabled .range-slider-value {
    color: var(--mix-ink-muted);
}

.range-slider-disabled input[type=range]::-webkit-slider-thumb {
    background: var(--mix-ink-muted);
    box-shadow: 0 0 0 1.5px var(--mix-ink-muted);
    opacity: .5;
    cursor: default;
}

.range-slider-disabled input[type=range]::-moz-range-thumb {
    background: var(--mix-ink-muted);
    box-shadow: 0 0 0 1.5px var(--mix-ink-muted);
    opacity: .5;
    cursor: default;
}

/* Rarity treatment ramp — glow intensity rises with the band. Hue alone can't order the
   bands monotonically (gold is brighter than sapphire), so treatment does; the percentile
   number always rides alongside, so color is never the only channel. Shadows omit a color
   on purpose: they take currentColor from the band hue. */
.rarity-glow-1 {
    text-shadow: 0 0 6px;
}

.rarity-glow-2 {
    text-shadow: 0 0 4px, 0 0 10px;
}

.rarity-glow-3 {
    text-shadow: 0 0 4px, 0 0 10px, 0 0 18px;
    font-weight: 600;
}

/* Legacy difficulty chips (docs/design/legacy-mixes.md): rendered, not image bubbles.
   Pre-Exceed slots, Half-Doubles, and levelled legacy co-ops announce "different
   scale" by looking deliberately unlike the modern bubble art. Hue rides the
   --slot-* tokens via inline style from ThemeScales.SlotColor. */
.legacy-chip {
    display: inline-flex;
    align-items: center;
    border: 2px solid var(--slot-neutral);
    border-radius: 12px;
    padding: 1px 8px;
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: .06em;
    color: var(--slot-neutral);
    white-space: nowrap;
    line-height: 1.5;
}
/* ===== Tier-list component vocabulary: sections, chart cards + the border language,
   lamp strip, border legend, folder picker. These back Components/* (TierSection,
   TierListChartCard, TierListSkeleton, LampStrip, BorderLegend, FolderPicker), so they
   live here rather than in any page's style block — the components must render
   correctly wherever they're reused. ===== */

.tier-section {
    margin: 12px 0;
}

.tier-section-header {
    display: flex;
    align-items: baseline;
    gap: 8px;
    cursor: pointer;
    border-left: 4px solid var(--tier-section-color, var(--mud-palette-text-secondary));
    padding-left: 8px;
}

.tier-section-name {
    color: var(--tier-section-color, var(--mud-palette-text-secondary));
}

.tier-section-count, .tier-section-stat {
    color: var(--mud-palette-text-secondary);
}

.tier-section-body {
    margin-top: 8px;
}

.tier-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    gap: 10px;
}

.tier-card-grid-compact {
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 6px;
}

/* Two per row on a phone rather than one. auto-fill against a 170px minimum needs 350px of
   content box for a second column, and a narrow handset does not have it once the page's own
   padding is out — so the tiles went full width and a fold showed two charts (owner, field test
   round three). Below the fold-out width the count is stated instead of derived. */
@media (max-width: 479.98px) {
    .tier-card-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.tier-chart-card {
    border: 2px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    background: var(--mud-palette-surface);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* Taller than it was, because the body now overlaps its bottom (see below): at the old 92px
   the overlap left too little art to recognise a jacket by. */
.tier-chart-card-jacket {
    height: 108px;
    background-size: cover;
    background-position: center;
    position: relative;
    cursor: pointer;
}

/* The scrim the overlapping body sits on — the session highlight card's own treatment. It
   keeps the name and score legible over any jacket, dark or bright, without dimming the art
   a reader is actually looking at: transparent through the top two thirds, near-solid only
   where the text lands. */
.tier-chart-card-jacket::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: linear-gradient(180deg, color-mix(in srgb, var(--mix-bg) 0%, transparent) 30%,
        color-mix(in srgb, var(--mix-bg) 55%, transparent) 62%,
        color-mix(in srgb, var(--mix-bg) 92%, transparent) 97%);
}

/* Everything that sits ON the jacket clears the scrim. Without this the gradient paints over
   the bubble and the corner badge, which is most visible exactly where it matters — the
   bottom corners, where the scrim is at its most opaque. */
.tier-chart-card-bubble,
.tier-chart-card-corner,
.tier-chart-card-lens-dot,
.tier-chart-card-compact-grade {
    z-index: 2;
}

.tier-chart-card-bubble {
    position: absolute;
    top: 4px;
    left: 4px;
}

/* Desktop wants to be told the jacket is the way in. It was a cursor change and nothing else
   (owner, 2026-08-26) — a cursor is invisible until you are already on the target, so it can
   confirm an affordance but cannot advertise one. Hover-capable pointers only: on a touch
   screen :hover sticks after a tap and the card would stay lit. */
@media (hover: hover) {
    /* The clickable indicator is a ring around the card, the treatment .sbd-card uses on the
       session pages (owner, 2026-09-12). It deliberately does NOT recolour the border: that
       border is owner-locked state language — solid success is a pass, dashed info is To-Do,
       dashed success is another mix, solid gold is your top 50 — so a hover that touched it
       would overwrite what the card is telling you. A ring outside the border says "clickable"
       without saying anything about the chart.
       Lighting the artwork instead was the old treatment; it competed with the jacket's own
       scrim and, once the whole jacket stopped being a play button, there was nothing to
       advertise there but the same open-details action the ring already covers.
       Hover-capable pointers only: on a touch screen :hover sticks after a tap. */
    .tier-chart-card {
        transition: box-shadow .12s ease;
    }

    /* The two things that actually open the chart. The body's chips and captions do not, so
       hovering them promises nothing. */
    .tier-chart-card:has(.tier-chart-card-jacket:hover),
    .tier-chart-card:has(.tier-chart-card-head:hover) {
        box-shadow: 0 0 0 1px color-mix(in srgb, var(--mix-primary) 45%, transparent),
        0 0 18px color-mix(in srgb, var(--mix-primary) 13%, transparent);
    }
}

.tier-chart-card-jacket:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: -2px;
}

/* The head rides up onto the scrim, so the name and score read as part of the jacket rather
   than as a caption under it — the session highlight card's layout (hl-card-body). ONLY the
   head does: it reserves its height empty, which keeps a folder's cards aligned and stops
   anything else inheriting the overlap merely by being first in the body.
   min-height is the reservation, and it matches the pull exactly — a card with neither a name
   nor a score shows clean art with its chips below, at the same height as its neighbours. */
/* The head's LAST line straddles the jacket's bottom edge rather than sitting above it — the
   session highlight card's treatment, where the score is half on the art and half on the card
   and reads as belonging to both. Bottom-aligned content plus a min-height 12px taller than the
   pull is what puts that line's centre on the edge; with a song name shown, the name rides
   above it on the art and the score still straddles.
   Sitting the score flush INSIDE the jacket instead (min-height == pull) leaves it floating on
   the artwork with a hard rule under it, which is what this looked like on the first pass. */
.tier-chart-card-head {
    position: relative;
    z-index: 2;
    margin-top: -30px;
    min-height: 42px;
    padding: 0 8px;
    min-width: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}

/* Deliberately unpulled, and shared with the randomizer's draw tile — which has no head and
   should sit below its jacket exactly as it always has. */
.tier-chart-card-body {
    padding: 4px 8px;
    min-width: 0;
    flex-grow: 1;
}

.tier-chart-card-name {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The name's line: the name and, when the list prints one, its value. The name's tooltip root is
   the part allowed to shrink, so a long name ends in "…" where the value starts; the value keeps
   its width at the line's end. */
.tier-chart-card-nameline {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

/* The two lines' own box. Its in-flow content is the score line alone, so its height IS the
   score's and the name hangs directly off its top edge - against the head, the name landed at
   the head's top, 14px clear of the score with bare artwork between (owner, 2026-09-12). */
.tier-chart-card-headlines {
    position: relative;
    min-width: 0;
}

/* The score owns the edge, and the name rides above it on the art (owner, 2026-09-12).
   Out of flow ON PURPOSE: in flow, a name added its own line to a bottom-justified column
   whose top was pinned by the pull, so the box grew DOWNWARD and carried the score with it.
   The score sat on the edge with names off and a line below it with names on — which is
   what "the tier list bumps the score down when the song name is showing" was.
   Only when there IS a score: a card with a name and no score has nothing else to anchor, so
   the name stays in flow and takes the edge itself. */
.tier-chart-card-headlines:has(.tier-chart-card-scoreline) .tier-chart-card-nameline {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
}

.tier-chart-card-nameline > .mud-tooltip-root {
    min-width: 0;
}

.tier-chart-card-nameline-value {
    flex: none;
    margin-left: auto;
    border-radius: 4px;
}

/* 14px against subtitle1's 16px, so more names fit whole at two cards to a row. subtitle1's line
   height is a unitless ratio, so the line shrinks with the text — which keeps a name with no score
   under it centered on the jacket's bottom edge. */
.tier-chart-card-head .tier-chart-card-name {
    font-size: 14px;
}

.tier-chart-card-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 0 4px 4px;
}

/* The card always stacks its grade over its plate, at every width. The player page's rows do
   this only when they run short of horizontal room; a tier card is short of it by definition,
   and the whole point here is the vertical space it gives back. Higher specificity than the
   shared rules on purpose — it has to beat both the base and the media query. */
.tier-chart-card-scoreline .sbd-score-stack {
    display: inline-grid;
    grid-auto-flow: row;
    grid-template-columns: auto auto;
    grid-template-rows: repeat(2, auto);
    align-items: center;
    column-gap: 5px;
    row-gap: 0;
    line-height: 1.05;
}

.tier-chart-card-scoreline .sbd-score-stack > img {
    grid-column: 1;
    height: 12px !important;
}

/* The score spans both icon rows and centres against the pair. 1 / -1 needs the explicit
   two-row track above it: against implicit rows -1 resolves to line 1 and the number ends up
   centred on the grade alone. A broken score has no plate, and the empty second track is
   simply zero tall. */
.tier-chart-card-scoreline .sbd-score-stack > p {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    margin: 0;
    padding-left: 0 !important;
    font-size: .92rem;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
}

.tier-chart-card-compact {
    cursor: pointer;
}

.tier-chart-card-compact-jacket {
    height: 72px;
}

.tier-chart-card-compact-grade {
    position: absolute;
    bottom: 3px;
    right: 3px;
    background: var(--mud-palette-background);
    border-radius: 4px;
    padding: 1px 3px;
}

/* A printed value in the jacket corner. Opaque backdrop rather than a tint, because it
   sits on album art and has to stay legible over any of it. */
.tier-chart-card-corner {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 12px;
    line-height: 1.25;
    font-variant-numeric: tabular-nums;
    background: rgba(0, 0, 0, .82);
    color: var(--mix-ink);
    padding: 1px 5px;
    border: 1px solid transparent;
}

/* The jacket's other bottom corner. Position only — the chrome rides .tier-chart-card-corner
   alongside it, so the two badges cannot drift apart. Declared after it so the tighter
   padding a picture wants beats the padding a printed value wants, on source order. */
.tier-chart-card-corner-start {
    position: absolute;
    bottom: 3px;
    left: 3px;
    display: flex;
    align-items: center;
    border-radius: 4px;
    padding: 1px 3px;
}

.tier-chart-card-extra {
    margin-top: 2px;
}

.tier-chart-card-lens-dot {
    position: absolute;
    top: 3px;
    right: 3px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, .45);
}

.tier-chart-card-tier {
    display: block;
}

.tier-chart-card-meta {
    display: block;
    color: var(--mud-palette-text-secondary);
}

.tier-chart-card-skills {
    display: flex;
    flex-wrap: wrap;
    gap: 3px;
    padding-bottom: 4px;
}

/* max-width is the guard, not tidiness: a chip is nowrap so a long one used to run straight
   out past the card's edge and get clipped by the jacket's overflow — "Hardest 19s: Bracket
   Runs, Bracket D" and then nothing (field test, 2026-08-26). */
.tier-chart-card-skill {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 8px;
    padding: 0 5px;
    font-size: .65rem;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The one chip that names two things wraps instead of truncating. Cutting it mid-badge loses
   the whole second claim, where two lines lose nothing. */
.tier-chart-card-skill.chip-section {
    white-space: normal;
    overflow: visible;
}

/* The owner's five badge families (docs/design/nuke-old-skill-categories.md §2): the granular
   piucenter vocabulary's identity colors, feeding the --skill-chip variable the chip and bar
   rules read. They replaced the rollup's arbitrary buckets, whose tokens went with it. */
.badgecat-brackets { --skill-chip: var(--badgecat-brackets); }
.badgecat-twists { --skill-chip: var(--badgecat-twists); }
.badgecat-staminaandruns { --skill-chip: var(--badgecat-staminaandruns); }
.badgecat-tech { --skill-chip: var(--badgecat-tech); }
.badgecat-doublestech { --skill-chip: var(--badgecat-doublestech); }

.tier-chart-card-skill[class*="badgecat-"] {
    color: color-mix(in srgb, var(--skill-chip) 55%, var(--mix-ink));
    background: color-mix(in srgb, var(--skill-chip) 16%, transparent);
    border-color: color-mix(in srgb, var(--skill-chip) 45%, transparent);
}

/* An identity chip fills; a feature keeps the outline it always had. On a card that is the
   whole distinction — the named groups live on the chart page, where there is room for two
   words of scaffolding (owner, 2026-08-26). */
.tier-chart-card-skill.chip-identity[class*="badgecat-"] {
    color: #fff;
    font-weight: 600;
    background: color-mix(in srgb, var(--skill-chip) 42%, var(--mud-palette-surface));
    border-color: color-mix(in srgb, var(--skill-chip) 80%, transparent);
}

/* Identity chip kinds (docs/design/chart-identity.md §3). The family tint still carries
   WHAT the chip is; these carry what KIND of claim it makes, so the two read together
   and neither is load-bearing alone (rule 8 — the printed name says it either way). */
.chip-unique {
    font-weight: 600;
}

/* The two speed claims wear the ends of the Speed list's own ramp, so a chip and the folder
   section it came from cannot disagree about what "Very Fast" looks like. The ramp is cool-to-
   hot and deliberately NOT the difficulty ramp: a slow chart at a high level is not an easy
   one (docs/design/chart-identity.md §2). */
.tier-chart-card-skill.chip-speed-slow { --skill-chip: var(--speed-1); }
/* Only the detail surfaces ever print the middle band: a card has room for a claim, not for a
   measurement that says the chart is ordinary. */
.tier-chart-card-skill.chip-speed-mid { --skill-chip: var(--speed-3); }
.tier-chart-card-skill.chip-speed-fast { --skill-chip: var(--speed-5); }

.tier-chart-card-skill[class*="chip-speed-"] {
    color: color-mix(in srgb, var(--skill-chip) 55%, var(--mix-ink));
    background: color-mix(in srgb, var(--skill-chip) 16%, transparent);
    border-color: color-mix(in srgb, var(--skill-chip) 45%, transparent);
}

.tier-chart-card-skill.chip-identity[class*="chip-speed-"] {
    color: #fff;
    font-weight: 600;
    background: color-mix(in srgb, var(--skill-chip) 42%, var(--mud-palette-surface));
    border-color: color-mix(in srgb, var(--skill-chip) 80%, transparent);
}

/* The hard-section chip names a stretch and carries two badges at once, so its body stays
   neutral and each badge keeps its own family inside it — merging the pair costs no
   information that way. */
.tier-chart-card-skill.chip-section {
    background: color-mix(in srgb, var(--mix-ink) 5%, transparent);
    border-color: var(--mud-palette-lines-default);
}

.tier-chart-card-skill.chip-section.chip-identity {
    background: color-mix(in srgb, var(--mix-ink) 13%, var(--mud-palette-surface));
    border-color: color-mix(in srgb, var(--mix-ink) 32%, transparent);
    color: var(--mix-ink);
    font-weight: 600;
}

.tier-chart-card-skill .chip-part {
    color: color-mix(in srgb, var(--skill-chip, var(--mix-ink)) 62%, var(--mix-ink));
    font-weight: 600;
}

.tier-chart-card-skill.chip-identity .chip-part {
    color: color-mix(in srgb, var(--skill-chip, var(--mix-ink)) 55%, #fff);
}

/* The spike is the one chip that is not a skill, so it is the one chip outside the family
   palette: an amber warning hue, mix-invariant like the judgment colors. */
/* The spike is always an identity claim, so it always fills — there is no quiet version of
   "this plays above its rating". */
.tier-chart-card-skill.chip-spike {
    color: #fff;
    font-weight: 600;
    background: color-mix(in srgb, var(--spike) 42%, var(--mud-palette-surface));
    border-color: color-mix(in srgb, var(--spike) 80%, transparent);
}

/* Piucenter's own picks, shown when nothing stood out — quieter than a claim we made. */
.tier-chart-card-skill.chip-fallback {
    opacity: .8;
}

.tier-table-skills .tier-chart-card-skill {
    margin-right: 3px;
}

/* Folder Stats: personal per-skill pass rates, weakest first (piucenter round 3).
   Rides the same --skill-chip category tint the chips use. */
.tier-folder-skills {
    margin-top: 8px;
}

.tier-folder-skills-title {
    display: block;
    color: var(--mix-ink-muted);
}

/* Bar + % = ability over played charts; the trailing count = completion (played /
   charts carrying the skill). Sorted by their product upstream. */
.tier-folder-skill-row {
    display: grid;
    grid-template-columns: 92px 1fr 38px 44px;
    align-items: center;
    gap: 8px;
    font-size: .75rem;
    padding: 1px 0;
}

/* Badge names are longer than the rollup's one-word buckets ever were ("Cross-pad
   Transitions" against "Tech"), so the label column widens to hold them rather than
   ellipsing every second row (docs/design/chart-identity.md §7, Variant B). */
.tier-folder-skill-row-badge {
    grid-template-columns: 140px 1fr 38px 44px;
}

.tier-folder-skill-label {
    color: color-mix(in srgb, var(--skill-chip) 60%, var(--mix-ink));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tier-folder-skill-track {
    height: 5px;
    border-radius: 3px;
    background: color-mix(in srgb, var(--skill-chip) 14%, transparent);
    overflow: hidden;
}

.tier-folder-skill-fill {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: var(--skill-chip);
}

.tier-folder-skill-value {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.tier-folder-skill-count {
    text-align: right;
    color: var(--mix-ink-muted);
    font-size: .68rem;
    font-variant-numeric: tabular-nums;
}

/* A row, because the printed value sits on it (owner, 2026-09-12) rather than taking a line of
   its own above the artwork. The stack keeps its intrinsic width and the value is pushed to the
   end by its own margin, the same way it ended the name's line. */
.tier-chart-card-scoreline {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.lamp-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 8px 0;
}

.lamp-chip {
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 12px;
    padding: 2px 8px;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: .75rem;
}

.lamp-chip-meter {
    width: 48px;
    height: 4px;
    background: var(--mud-palette-lines-default);
    border-radius: 2px;
    overflow: hidden;
    display: inline-block;
}

.lamp-chip-fill {
    display: block;
    height: 100%;
    background: var(--mud-palette-primary);
}

.lamp-chip-complete .lamp-chip-fill {
    background: var(--mud-palette-success);
}

.border-legend {
    font-size: .75rem;
    color: var(--mud-palette-text-secondary);
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: center;
    margin: 8px 0;
}

.border-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.border-legend-swatch {
    width: 20px;
    height: 12px;
    display: inline-block;
    border: 2px solid var(--mud-palette-lines-default);
    border-radius: 3px;
}

/* The card border language (owner-locked): solid success = passed, dashed info = To-Do,
   dashed success = passed in another mix. Declared AFTER the card and swatch bases on
   purpose — those declare `border` shorthands at equal specificity, so source order is
   what guarantees the state classes win everywhere they're worn. */
.tier-chart-card-pass {
    border-color: var(--mud-palette-success);
    border-style: solid;
}

/* Hardmode's one addition to the border vocabulary: gold means "this counts". It is the share
   card's own "Top 50 — combined" boundary (ShareCardComposer.Boundary), so the same fact wears
   the same colour in the page and in the download, and it outranks the green pass where both
   apply — exactly as the card composer orders them
   (docs/design/hardmode-leaderboard.md D12). */
.tier-chart-card-top50 {
    border-color: var(--rarity-gold);
    border-style: solid;
}

.tier-chart-card-todo {
    border-color: var(--mud-palette-info);
    border-style: dashed;
}

.tier-chart-card-other-mix {
    border-color: var(--mud-palette-success);
    border-style: dashed;
}

/* Played and broke. Grey rather than the pass green because the run earned nothing, and
   dotted rather than dashed so the three "we have seen you here" states stay separable at
   a glance. The mix token rather than a Mud palette entry: this is the only one of the
   four whose colour is a shade of the page rather than a semantic. */
.tier-chart-card-broken {
    border-color: color-mix(in srgb, var(--mix-ink-muted) 70%, transparent);
    border-style: dotted;
}

/* Randomizer draw states join the same source-order contract: held = mix-primary ring
   (deliberately NOT the pass-green), vetoed = error red — both in every density, on
   top of the dim/strike second channels. */
.draw-card-held {
    border-color: var(--mix-primary);
    border-style: solid;
    box-shadow: 0 0 0 1px var(--mix-primary), 0 0 14px var(--mix-glow);
}

.draw-card-vetoed {
    border-color: var(--mud-palette-error);
    border-style: solid;
}

.folder-picker {
    display: flex;
    align-items: center;
    gap: 2px;
}

.folder-picker-anchor {
    position: relative;
}

.folder-picker-pop {
    padding: 8px;
}

.folder-picker-types {
    margin-bottom: 8px;
}

.folder-picker-levels {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 2px;
    max-height: 260px;
    overflow-y: auto;
}

.folder-picker-level {
    background: none;
    border: none;
    border-radius: 4px;
    padding: 6px 0;
    cursor: pointer;
    font: inherit;
    color: var(--mud-palette-text-primary);
    text-align: center;
}

.folder-picker-level:hover {
    background: rgba(255, 255, 255, .08);
}

.folder-picker-current {
    color: var(--mud-palette-primary);
    font-weight: 600;
}

/* A folder this host has nothing for. Dimmed rather than hidden: the grid is a map of
   the level range, and holes in it are information — they say the change landed
   somewhere else. */
.folder-picker-level-off {
    opacity: .3;
    cursor: default;
}

.folder-picker-level-off:hover {
    background: none;
}

/* ===== Home dashboard (unlisted pre-release, D7): 4-column desktop grid, mobile
   derives a single column from auto-flow order (D3), cells span via size presets
   (D5). The widget frame is owned by WidgetHost so every widget wears identical
   chrome. ===== */

.dash-hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 56px 16px;
    text-align: center;
}

.dash-pagebar {
    display: flex;
    gap: 4px;
    margin-bottom: 14px;
    flex-wrap: wrap;
}

.dash-pagetab {
    background: none;
    border: none;
    cursor: pointer;
    padding: 6px 14px;
    border-radius: 8px 8px 0 0;
    font-family: var(--font-display);
    font-weight: 500;
    font-size: .95rem;
    letter-spacing: .05em;
    color: var(--mix-ink-muted);
    border-bottom: 2px solid transparent;
}

.dash-pagetab.active {
    color: var(--mix-ink);
    border-bottom-color: var(--mix-primary);
    text-shadow: 0 0 10px var(--mix-glow);
}

.dash-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: 168px;
    grid-auto-flow: row;
    gap: 14px;
}

.dash-cell {
    min-width: 0;
}

.dash-cols-2 { grid-column: span 2; }
.dash-cols-3 { grid-column: span 3; }
.dash-cols-4 { grid-column: span 4; }
.dash-rows-2 { grid-row: span 2; }

.dash-widget {
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .06);
    border-radius: 10px;
    padding: 12px 14px;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.dash-widget-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    flex: none;
}

.dash-widget-title {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .82rem;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.dash-widget-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.dash-widget-message {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    color: var(--mix-ink-muted);
}

/* Stale-while-revalidate: once a widget has rendered, a reload dims the current content
   in place instead of collapsing to a spinner — on the auto-height mobile column a
   spinner swap shrinks the page under a mid-scroll finger and kills the gesture. The
   wrapper mirrors .dash-widget-body's flex chain so widget roots keep stretching. */
.dash-refreshable {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    transition: opacity .2s ease;
}

.dash-stale {
    opacity: .6;
}

/* Import Scores widget (§4): a credential form has to live in a 1x1 body, so the fields and
   button pack into a tight flex column that scrolls rather than clipping the action off. */
.import-widget-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
}

.import-widget-body .mud-input-control {
    margin-top: 0;
}

/* Saved-credential state: alert + full-width action, packed to the middle. */
.import-saved {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* Spinner / done state: everything centered on both axes. */
.import-progress {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
}

/* Typed one-time credentials: username/password stacked, a tall import button beside them. */
.import-typed {
    display: flex;
    gap: 6px;
    align-items: stretch;
}

.import-typed-fields {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.import-typed-go {
    min-width: 48px;
    height: auto;
}

/* Nav-bar import indicator: a pulsing dot on the avatar while a background import runs. */
.nav-avatar-wrap {
    position: relative;
    display: inline-flex;
}

.nav-import-pulse {
    position: absolute;
    top: -1px;
    right: -1px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--mix-primary);
    border: 1px solid var(--mix-surface);
    animation: nav-import-pulse 1.4s ease-out infinite;
}

@keyframes nav-import-pulse {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mix-primary) 65%, transparent); }
    70% { box-shadow: 0 0 0 7px color-mix(in srgb, var(--mix-primary) 0%, transparent); }
    100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--mix-primary) 0%, transparent); }
}

/* Quick Record widget (§4.2): the arcade recorder, purpose-built to fit a 1x1 body. */
.qr-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.qr-hint {
    font-size: .68rem;
    color: var(--mix-ink-muted);
}

/* The selected chart — a display header, not a chip: nothing here navigates. */
.qr-selected {
    display: flex;
    align-items: center;
    gap: 7px;
}

.qr-mini-art {
    flex: none;
    display: inline-flex;
}

.qr-mini-art img {
    width: 22px;
    height: 22px;
    border-radius: 4px;
}

.qr-selected-name {
    flex: 1;
    min-width: 0;
    font-family: var(--font-display);
    letter-spacing: .03em;
    font-size: .9rem;
    color: var(--mix-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.qr-scorerow {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Score and the plate/result dropdown share the row (owner, 2026-07-13): score cut to
   ~half, plate lifted up beside it as shorthand. On the legacy row the score dominates and
   the letter-grade box stays compact (owner, field test). */
.qr-score-field {
    flex: 1 1 0;
    min-width: 96px;
}

/* Plate lives on the Save row (owner, 2026-07-13): compact on the left, Save pushed right. */
.qr-plate-field {
    flex: 0 1 auto;
    min-width: 104px;
    max-width: 168px;
}

/* The derived grade doubles as the broken toggle — click to flip pass/broken while keeping
   the plate (plated broken). Deliberately subtle: pointer + a hover tint, no label. */
.qr-grade-toggle {
    flex: none;
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    border-radius: 6px;
    padding: 2px;
}

.qr-grade-toggle:hover {
    background: rgba(255, 255, 255, .07);
}

.qr-actionrow {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Second row: plate on the left, Save pushed to the right (margin-left auto) so it never
   clips on narrow widths (the mobile bug). Pinned to the bottom of the body. */
.qr-actionrow-save {
    margin-top: auto;
}

.qr-actionrow-save .qr-save-btn {
    margin-left: auto;
}

/* MudBlazor fields carry generous default margins — reclaim them for the tight footprint. */
.qr-body .mud-input-control {
    margin-top: 0;
}

.qr-saved {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    gap: 12px;
}

.qr-saved-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.qr-saved-title {
    font-family: var(--font-display);
    text-transform: uppercase;
    letter-spacing: .13em;
    font-size: .74rem;
    color: var(--mud-palette-success);
}

.qr-saved-song {
    font-family: var(--font-display);
    font-size: 1rem;
    color: var(--mix-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

.qr-saved-detail {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: .78rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.qr-saved-grade {
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--mix-ink);
}

/* All-mixes mode: the runtime picker + the mix chip on the recording header. The chip is
   neutral (not the theme accent) so it doesn't imply the active theme is the record mix. */
.qr-mix-field {
    flex: none;
}

/* Legacy grade strip (owner, 2026-07-13): tap a grade image to pick it (passing), tap the
   selected one again to mark broken (its art goes cracked). Replaces the select + checkbox. */
/* The grade strip is the primary/lead row in legacy (score dropped below it); 4 primaries +
   a "more" menu, spread with a little air. */
.qr-graderow {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.qr-graderow-disabled {
    pointer-events: none;
    opacity: .5;
}

/* "More" overflow (B and lower) — either a … affordance or the selected lower grade. */
.qr-grade-more {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 26px;
    min-width: 26px;
    cursor: pointer;
    border-radius: 5px;
    color: var(--mix-ink-muted);
    font-size: 1.15rem;
    line-height: 1;
    opacity: .75;
}

.qr-grade-more:hover {
    opacity: 1;
    background: rgba(255, 255, 255, .06);
}

.qr-grade-menu-img {
    height: 24px;
    width: auto;
}

.qr-grade-opt {
    height: 30px;
    width: auto;
    cursor: pointer;
    border-radius: 5px;
    padding: 2px 3px;
    opacity: .5;
    transition: opacity .12s, transform .12s, background .12s;
}

.qr-grade-opt:hover {
    opacity: .85;
    background: rgba(255, 255, 255, .06);
}

.qr-grade-opt-sel {
    opacity: 1;
    background: color-mix(in srgb, var(--mix-primary) 22%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mix-primary) 55%, transparent);
    transform: scale(1.08);
}

.qr-mixchip {
    font-family: var(--font-display);
    font-size: .6rem;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--mix-ink-muted);
    background: var(--mix-surface-muted);
    border: 1px solid rgba(255, 255, 255, .08);
    padding: 1px 6px;
    border-radius: 5px;
    flex: none;
    max-width: 88px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Column stagger (round 3): 4 on desktop, 3 on small desktop/tablet, 2 on landscape
   phones, 1 on portrait phones. Spans clamp to the column count. */
@media (max-width: 1279.98px) {
    .dash-grid { grid-template-columns: repeat(3, 1fr); }

    .dash-cols-4, .dash-cols-3 { grid-column: span 3; }
}

@media (max-width: 959.98px) {
    .dash-grid { grid-template-columns: repeat(2, 1fr); }

    .dash-cols-4, .dash-cols-3, .dash-cols-2 { grid-column: span 2; }
}

@media (max-width: 599.98px) {
    .dash-grid {
        grid-template-columns: 1fr;
        grid-auto-rows: minmax(168px, auto);
    }

    .dash-cols-2, .dash-cols-3, .dash-cols-4 { grid-column: span 1; }

    .dash-rows-2, .dash-rows-3 { grid-row: span 1; }
}

/* Edit mode: toolbar, edit chrome, add-drawer. */

.dash-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 14px;
    flex-wrap: wrap;
}

.dash-toolbar .dash-pagebar {
    margin-bottom: 0;
}

.dash-pagetab-new {
    color: var(--mix-primary);
}

.dash-widget-editing {
    border-style: dashed;
    border-color: color-mix(in srgb, var(--mix-primary) 45%, transparent);
}

.dash-edit-controls {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    flex: none;
}

/* Header refresh action (shuffle etc.): first auto margin wins the free space, so it
   sits far right in browse mode and immediately left of the edit controls in edit. */
.dash-head-action {
    margin-left: auto;
    flex: none;
}

/* Widget-pushed title-bar content (§2.3 header slot) — e.g. Quick Record's selected chart.
   Sits at the right of the title; the mini-art/bubble/✕ line up compactly. */
.dash-head-slot {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    overflow: hidden;
}

.dash-head-slot .qr-mini-art img {
    width: 28px;
    height: 28px;
    border-radius: 4px;
}

/* Header-slot status glyph (e.g. Hot Streak's fallback note) — icon + tooltip only. */
.dash-head-flag {
    display: inline-flex;
    align-items: center;
    cursor: help;
}

.dash-drawer-body {
    padding: 16px;
}

.dash-drawer-item {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px;
    border-radius: 8px;
    cursor: pointer;
}

.dash-drawer-item:hover {
    background: rgba(255, 255, 255, .06);
}

.dash-drawer-item.disabled {
    opacity: .45;
    pointer-events: none;
}

.dash-chart-fill {
    flex: 1;
    min-height: 0;
}

/* Pumbility widget: stat block + scrollable target list with dismiss. */

.dash-pumbility {
    display: flex;
    gap: 16px;
    flex: 1;
    min-height: 0;
}

.dash-pumbility-left {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: none;
    max-width: 46%;
}

.dash-stat-num {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 2.2rem;
    line-height: 1;
    color: var(--rarity-gold);
    font-variant-numeric: tabular-nums;
}

.dash-stat-delta {
    color: var(--mud-palette-success);
    font-size: .8rem;
    font-weight: 600;
}

.dash-sparkline {
    width: 100%;
    height: 26px;
}

.dash-muted {
    color: var(--mix-ink-muted);
}

.dash-pumbility-targets {
    flex: 1;
    min-width: 0;
    min-height: 0; /* flex-column children refuse to shrink without this — the tall variant could never scroll */
    display: flex;
    flex-direction: column;
    border-left: 1px solid rgba(255, 255, 255, .06);
    padding-left: 14px;
}

.dash-targets {
    flex: 1;
    min-height: 0;
}

.dash-target-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 0;
    font-size: .8rem;
}

.dash-target-name {
    min-width: 0;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-display);
    letter-spacing: .04em;
    color: var(--mix-ink-muted);
}

/* Suggested Charts only: a full-width single column shows the name to fill the gap the
   right-aligned score would leave, but a cramped narrow cell hands that width back to
   the score. Scoped to .dash-suggested's container so the always-named Weekly and Daily
   Step rows (which share this class but sit in no such container) keep their names. */
@container dash-suggested (max-width: 209.98px) {
    .dash-target-name { display: none; }
}

.dash-skillchip {
    font-size: .68rem;
    white-space: nowrap;
    flex: none;
}

.dash-target-gain {
    font-family: var(--font-display);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-success);
    flex: none;
}

/* Weekly widget: board rows + rotation countdown. */

.dash-weekly {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

.dash-weekly-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 4px;
    flex: none;
}

.dash-countdown {
    font-family: var(--font-display);
    font-size: .7rem;
    letter-spacing: .08em;
    color: var(--mix-accent);
    border: 1px solid color-mix(in srgb, var(--mix-accent) 40%, transparent);
    border-radius: 10px;
    padding: 1px 8px;
    white-space: nowrap;
}

.dash-weekly-expiry {
    font-family: var(--font-display);
    font-size: .68rem;
    letter-spacing: .05em;
    color: var(--mix-ink-muted);
    flex: none;
}

.dash-weekly-place {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .75rem;
    flex: none;
    font-variant-numeric: tabular-nums;
}

/* Community Highlights feed (docs/design/home-page-widgets.md §7). */
.dash-ch-feed {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    /* Never pans: overflow-y:auto forces this axis from visible to auto, so any
       too-long line would otherwise mint a horizontal scrollbar for the whole feed. */
    overflow-x: hidden;
    height: 100%;
    /* So win rows can respond to the widget's own width, not just the viewport. */
    container-type: inline-size;
}

.dash-ch-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .25rem;
    text-align: center;
    padding: 1rem;
}

.rvl-feed-lead {
    margin: 14px 0 4px;
}

.rvl-cmp-folder {
    margin: 6px 0 10px;
}

/* The picker and the unshared switch share one row above the compare table; the switch sits at
   the far end so the folder controls keep their place whether or not it renders. */
.rvl-cmp-controls {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}

.rvl-cmp-controls .rvl-cmp-folder {
    margin: 6px 0;
}

.rvl-cmp-switch {
    margin-left: auto;
}

/* A row only one of you has played: same table, muted, so the shared rows above stay the
   comparison and these read as the appendix they are. */
.rvl-cmp-table tr.rvl-cmp-unshared td {
    color: var(--mix-ink-muted);
}

.rvl-tile-unshared {
    outline: 1px dashed rgba(255, 255, 255, .14);
    outline-offset: -1px;
}

/* ---------------------------------------------------------------------------
   The player page (/Player/{id}) — docs/design/player-page-and-site-search.md.
   Hero: gem + PUMBILITY + identity on ONE row, the four rating tiles a full-width row beneath.
   The row stacks only at 1:1 or narrower — the same breakpoint the compare table uses to drop
   its difference column, so the page folds in one place. The .cmp-* vocabulary is the community
   player page's, moved here when that page retired. */

/* The shell leaves the page flush against the nav, and this one opens on a paper's edge (or the
   patience card's) rather than on a heading, so it owes itself the breathing room. */
.ph-page {
    margin-top: 16px;
}

.ph-top {
    display: flex;
    align-items: center;
    gap: 26px;
}

.ph-pum {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: none;
}

/* The level gem tucks against the number, eating the art's transparent frame, so gem and
   number read as one unit — the account widget's treatment. */
.ph-pum .pumbility-level-badge {
    flex: none;
    margin-right: -6px;
}

.ph-identity {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}

.ph-identity-avatar {
    width: 56px;
    height: 56px;
    border-radius: 12px;
    object-fit: cover;
    flex: none;
}

/* Competitive level, stacked S over D the way the account widget stacks its S/D pools beside
   the total. Never the overall figure. */
.ph-cl {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-left: 16px;
    border-left: 1px solid rgba(255, 255, 255, .08);
}

.ph-cl-eyebrow {
    font-size: .6rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    color: var(--mix-ink-muted);
    margin-bottom: 2px;
}

.ph-cl-row {
    display: flex;
    gap: 6px;
    align-items: baseline;
    white-space: nowrap;
    font-size: .9rem;
    font-variant-numeric: tabular-nums;
}

.ph-cl-row > span:first-child {
    font-weight: 600;
}

.ph-cl-row b {
    font-weight: 700;
}

.ph-cl-singles {
    color: var(--chart-singles);
}

.ph-cl-doubles {
    color: var(--chart-doubles);
}

@media (max-aspect-ratio: 1/1) {
    .ph-top {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
    }
}

.ph-card-head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.ph-links {
    display: flex;
    gap: 18px;
    flex-wrap: wrap;
}

.cmp-hero-pum {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

.cmp-hero-num {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 3.4rem;
    line-height: 1;
    color: var(--rarity-gold);
    text-shadow: 0 0 14px var(--mix-glow);
    font-variant-numeric: tabular-nums;
}

.cmp-hero-cap {
    font-size: .62rem;
    text-transform: uppercase;
    letter-spacing: .14em;
    color: var(--mix-ink-muted);
    margin-top: 4px;
}

.cmp-tiles {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
    margin-top: 16px;
}

@media (max-width: 640px) {
    .cmp-tiles {
        grid-template-columns: repeat(2, 1fr);
    }
}

.cmp-tile {
    background: var(--mix-surface-muted);
    border-radius: 11px;
    padding: 12px;
}

.cmp-tile-label {
    font-size: .62rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--mix-ink-muted);
}

.cmp-tile-num {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.4rem;
    margin-top: 3px;
    font-variant-numeric: tabular-nums;
}

/* Folder completion keeps the real folder slope: each track's height follows the folder's chart
   count (no per-folder normalization). Singles and doubles are separate folders with separate
   standings, so they get separate graphs side by side, and each column fills with its folder's
   own grade spectrum — height says how big the folder is, fill says how far through it you
   are, hue says how well. */
.cmp-folder-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(14px, 3vw, 30px);
}

@media (max-width: 700px) {
    .cmp-folder-pair {
        grid-template-columns: 1fr;
    }
}

.cmp-folder-head {
    font-family: var(--font-display);
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    margin-bottom: 6px;
}

.cmp-folder-head-singles {
    color: var(--type-singles);
}

.cmp-folder-head-doubles {
    color: var(--type-doubles);
}

/* Twenty-odd folders at a fixed bar width is wider than a phone, so the columns share the width
   they have: each takes an equal fraction and the bar fills its column up to the full-size 34px.
   The MudTooltip wrapper sits between the two and defaults to an auto-width inline-block, which
   is what collapsed a percentage-width bar to nothing before — it stretches with the column now. */
.cmp-folders {
    display: flex;
    align-items: flex-end;
    gap: clamp(3px, 1.2vw, 10px);
    height: 150px;
    padding-top: 4px;
}

.cmp-folder-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    flex: 1 1 0;
    min-width: 0;
    justify-content: flex-end;
    height: 100%;
}

.cmp-folder-col > .mud-tooltip-root {
    display: block;
    width: 100%;
    min-width: 0;
}

.cmp-folder-track {
    width: 100%;
    max-width: 34px;
    margin: 0 auto;
    border-radius: 5px 5px 0 0;
    overflow: hidden;
}

/* The spectrum is horizontal everywhere else, so the column hands it a full-height box and the
   vertical variant grows from the base. */
.cmp-folder-track > .fl-spectrum,
.cmp-folder-track > .fl-spectrum > .fl-track {
    height: 100%;
}

/* A two-digit label is wider than its column once the bars are sharing a phone. */
.cmp-folder-label {
    font-size: clamp(.54rem, 1.8vw, .72rem);
    line-height: 1;
    font-weight: 700;
    color: var(--mix-ink-muted);
}

/* The rail and its arrows. The native horizontal scrollbar is hidden on the desktop rail: it
   is chunky, it steals a row of height under the cards, and it is the only scrollbar on the
   page that runs sideways, so it reads as a stray control rather than a hint. The arrows
   replace it — they only render where the rail is actually horizontal. */
.rvl-rail-wrap {
    position: relative;
}

.dash-ch-feed.rvl-feed-rail {
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.dash-ch-feed.rvl-feed-rail::-webkit-scrollbar {
    display: none;
}

.rvl-rail-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    color: var(--mix-ink);
    background: color-mix(in srgb, var(--mix-surface) 88%, transparent);
    box-shadow: 0 1px 8px -2px rgba(0, 0, 0, .6);
}

.rvl-rail-arrow:hover {
    background: var(--mix-surface);
}

.rvl-rail-arrow.prev {
    left: -6px;
}

.rvl-rail-arrow.next {
    right: -6px;
}

/* Below the rail's own breakpoint the feed is a plain column, so a sideways arrow would
   scroll nothing. */
@media (max-width: 700px) {
    .rvl-rail-arrow {
        display: none;
    }
}

/* ── The rivals rail ───────────────────────────────────────────────────────────────────
   Same feed component, laid out as a strip. On the Rivals page the feed is the first thing
   above the fold, and a column there pushes the roster off screen to say what a strip says
   in one glance. Cards are fixed-width and snap, so a partially visible next card is what
   tells you the rail scrolls — no arrows, no scrollbar chrome to style.

   Below 700px it reverts to the column it already is: a horizontal scroller on a phone
   competes with the page's own vertical scroll and loses. */
.dash-ch-feed.rvl-feed-rail {
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    gap: 10px;
    height: auto;
    padding-bottom: 6px;
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain;
}

.dash-ch-feed.rvl-feed-rail > .dash-ch-entry {
    flex: 0 0 clamp(230px, 26vw, 310px);
    scroll-snap-align: start;
    border-bottom: 0;
    border-radius: 8px;
    padding: .55rem .6rem;
    background: color-mix(in srgb, var(--mix-ink-muted) 7%, transparent);
}

@media (max-width: 700px) {
    .dash-ch-feed.rvl-feed-rail {
        flex-direction: column;
        overflow-x: visible;
        overflow-y: auto;
        max-height: 340px;
    }

    .dash-ch-feed.rvl-feed-rail > .dash-ch-entry {
        flex: none;
    }
}

.dash-ch-entry {
    display: flex;
    gap: .6rem;
    /* Right side breathes: on a marked row the audience band paints the entry, and a
       score flush against the band's edge read as clipped (owner, field test). */
    padding: .55rem .5rem .55rem .25rem;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink-muted) 15%, transparent);
}

.dash-ch-avatar {
    flex: none;
    width: 2rem;
    height: 2rem;
}

.dash-ch-body {
    min-width: 0;
    flex: 1;
}

.dash-ch-head {
    display: flex;
    align-items: baseline;
    gap: .5rem;
}

.dash-ch-name {
    font-weight: 600;
    font-size: .85rem;
}

.dash-ch-time {
    margin-left: auto;
    font-size: .7rem;
    white-space: nowrap;
}

.dash-ch-wins {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    margin-top: .15rem;
}

.dash-ch-win {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .35rem;
    font-size: .78rem;
}

.dash-ch-chart {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    min-width: 0;
}

.dash-ch-song {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 12rem;
}

/* Prose rows (titles, folders, level-ups) wrap; only the scored one-liner below
   pins its caption to a single line, and the narrow reflows release even that. */
.dash-ch-why {
    color: var(--mix-ink-muted);
    overflow-wrap: break-word;
    min-width: 0;
}

/* Scored win = one line on wide: chart (the song name truncates) + highlight, then a right-aligned
   grade/plate + score. The narrow queries below reflow it into a chart+score line and a subtitle. */
.dash-ch-win-scored {
    flex-wrap: nowrap;
    align-items: center;
    gap: .35rem;
}

.dash-ch-win-scored .dash-ch-why {
    white-space: nowrap;
}

/* The level-up row is a badge image plus text — centered as a unit, not baseline-hung. */
.dash-ch-lvlup {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
}

.dash-ch-win-scored .dash-ch-chart {
    min-width: 0; /* the song name ellipsises rather than shove the score off the line */
}

.dash-ch-score-right {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
    padding-left: .4rem;
}

.dash-ch-score {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    padding-left: .25rem;
}

/* Narrow — a 1-wide widget (container query on the feed) or mobile, where the dashboard is one
   column (media query): hide the song name and drop the highlight onto its own subtitle line. */
@container (max-width: 340px) {
    .dash-ch-song { display: none; }
    .dash-ch-win-scored { flex-wrap: wrap; }
    .dash-ch-win-scored .dash-ch-score-right { order: 2; }
    .dash-ch-win-scored .dash-ch-why { order: 3; flex-basis: 100%; font-size: .72rem; white-space: normal; }
}

@media (max-width: 600px) {
    .dash-ch-song { display: none; }
    .dash-ch-win-scored { flex-wrap: wrap; }
    .dash-ch-win-scored .dash-ch-score-right { order: 2; }
    .dash-ch-win-scored .dash-ch-why { order: 3; flex-basis: 100%; font-size: .72rem; white-space: normal; }
}

/* Card-strip person divider (avatar + vertical name) — the community analog of the
   Suggested-Charts category divider, reusing that strip's card CSS + arrow pager. */
.dash-strip-person {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 2px 3px;
    min-width: 0;
}

.dash-strip-pname {
    writing-mode: vertical-rl;
    font-family: var(--font-display);
    font-size: .62rem;
    font-weight: 700;
    letter-spacing: .02em;
    max-height: 62px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: var(--mix-ink);
}

.dash-strip-person.you .dash-strip-pname {
    color: var(--mix-primary);
}

/* A title or full-folder clear has no chart art — it reads as a centered text card. */
.dash-card-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    gap: 3px;
}

.dash-card-emoji {
    font-size: 1.35rem;
    line-height: 1;
}

/* The cards/dividers are wrapped in MudTooltip, so its root is the strip's flex child —
   keep it a fixed-size item so the cards don't grow or shrink. */
.dash-card-strip > .mud-tooltip-root {
    flex: none;
    min-width: 0;
    display: inline-flex;
}

/* Drag chrome: handle (desktop pointer only), dragged-cell dim, insertion marker. */

.dash-drag-handle {
    cursor: grab;
    color: var(--mix-ink-muted);
    font-size: .9rem;
    user-select: none;
    touch-action: none;
    flex: none;
}

.dash-dragging {
    opacity: .35;
}

.dash-drop-target {
    outline: 2px dashed var(--mix-primary);
    outline-offset: 2px;
    border-radius: 10px;
}

.dash-json textarea {
    font-family: Consolas, monospace;
    font-size: .78rem;
}

@media (max-width: 959.98px) {
    .dash-drag-handle {
        display: none;
    }
}

/* Field-test round 1: 3-row spans, swap indicator, mini art, clickable rows,
   tall pumbility. */

.dash-rows-3 { grid-row: span 3; }

.dash-swap-target {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
    border-radius: 10px;
}

.dash-mini-art {
    flex: none;
    width: 24px;
    height: 24px;
    border-radius: 5px;
    overflow: hidden;
    display: inline-flex;
}

.dash-mini-art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Suggested Charts widget: goal sections inside one scroll + a right-hand score column. */

.dash-suggested {
    height: 100%;
    min-height: 0;
    display: flex;
    flex-direction: column;
    /* Its own inline size decides whether target rows show the song name. */
    container: dash-suggested / inline-size;
}

.dash-target-caption {
    padding-top: 6px;
    text-transform: uppercase;
    letter-spacing: .08em;
    font-family: var(--font-display);
}

.dash-target-score {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-variant-numeric: tabular-nums;
    font-size: .75rem;
    /* Suggested rows drop the name at 1x2 — the score column right-aligns itself. */
    margin-left: auto;
}

.dash-target-detail {
    font-size: .7rem;
}

/* Card strips (suggested-charts field test): wide widgets read as compact chart cards
   scrolling horizontally, not tabled text. Hover-revealed pager arrows (clicks handled
   by dashboard-grid.js delegation); honest x-axis fades mirror the vertical ones. */

.dash-strips {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.dash-strip-wrap {
    position: relative;
    flex: none;
    min-width: 0;
}

.dash-card-strip {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    scrollbar-width: none;
    /* Bottom padding keeps the score line off the widget edge (owner, round 6). */
    padding: 2px 2px 8px;
    mask-image: linear-gradient(to right,
        transparent 0,
        #000 var(--dash-fade-left),
        #000 calc(100% - var(--dash-fade-right)),
        transparent 100%);
}

.dash-card-strip::-webkit-scrollbar {
    display: none;
}

@property --dash-fade-left {
    syntax: "<length>";
    inherits: false;
    initial-value: 0px;
}

@property --dash-fade-right {
    syntax: "<length>";
    inherits: false;
    initial-value: 20px;
}

@supports (animation-timeline: scroll()) {
    .dash-card-strip {
        animation: dash-strip-fades linear both;
        animation-timeline: scroll(self x);
    }

    @keyframes dash-strip-fades {
        0% {
            --dash-fade-left: 0px;
            --dash-fade-right: 20px;
        }

        10% {
            --dash-fade-left: 20px;
            --dash-fade-right: 20px;
        }

        90% {
            --dash-fade-left: 20px;
            --dash-fade-right: 20px;
        }

        100% {
            --dash-fade-left: 20px;
            --dash-fade-right: 0px;
        }
    }
}

.dash-strip-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, .14);
    background: color-mix(in srgb, var(--mix-surface-muted) 88%, transparent);
    color: var(--mix-ink);
    cursor: pointer;
    display: grid;
    place-items: center;
    font-size: 15px;
    line-height: 1;
    opacity: 0;
    transition: opacity .15s;
}

.dash-widget:hover .dash-strip-arrow,
.dash-strip-arrow:focus-visible {
    opacity: .85;
}

.dash-strip-arrow-left {
    left: 2px;
}

.dash-strip-arrow-right {
    right: 2px;
}

/* Touch scrolls the strip directly — pager arrows are a pointer affordance. */
@media (hover: none) {
    .dash-strip-arrow {
        display: none;
    }
}

.dash-chart-card {
    /* Sized so art + name + score clear a 2x1 cell on desktop (owner, round 6). */
    flex: none;
    width: 76px;
    min-width: 0;
}

@media (max-width: 599.98px) {
    /* Mobile cells auto-grow — the roomier card reads better there. */
    .dash-chart-card {
        width: 86px;
    }
}

.dash-card-art {
    position: relative;
    width: 100%;
    aspect-ratio: 1;
    border-radius: 8px;
    overflow: hidden;
    background: var(--mix-surface-muted);
}

@media (min-width: 600px) {
    /* Desktop strip cells are fixed-height (168px rows): landscape-crop the art so
       name + score + detail all clear the cell (owner, round 7). Mobile cells
       auto-grow, so the square art stays there. */
    .dash-card-art {
        aspect-ratio: auto;
        height: 52px;
    }
}

/* Direct child only — the DifficultyBubble overlay nests its own img inside this box,
   and a blanket rule blew it up to full card size (owner, round 4). */
.dash-card-art > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.dash-card-bubble {
    position: absolute;
    left: 3px;
    bottom: 3px;
}

.dash-card-veto {
    position: absolute;
    top: 2px;
    right: 2px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--mix-surface) 78%, transparent);
}

.dash-card-name {
    margin-top: 3px;
    font-family: var(--font-display);
    font-size: .72rem;
    line-height: 1.25;
    letter-spacing: .03em;
    color: var(--mix-ink-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-card-score {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: .72rem;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.dash-card-detail {
    font-size: .65rem;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Category context inside a merged strip: a slim vertical label opens each group
   (owner, round 7 — "which flavor of Score Push is this?"). */
.dash-strip-divider {
    flex: none;
    writing-mode: vertical-rl;
    font-family: var(--font-display);
    font-size: .62rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: 2px 1px;
    border-left: 1px solid rgba(255, 255, 255, .10);
}

.dash-clickable {
    cursor: pointer;
}

.dash-clickable:hover {
    background: rgba(255, 255, 255, .05);
    border-radius: 6px;
}

.dash-pumbility-tall {
    flex-direction: column;
    gap: 8px;
}

.dash-pumbility-tall .dash-pumbility-left {
    max-width: none;
    flex: none;
}

.dash-pumbility-tall .dash-pumbility-targets {
    border-left: none;
    padding-left: 0;
    border-top: 1px solid rgba(255, 255, 255, .06);
    padding-top: 8px;
}

/* Round 2: target rows get air (the tall/mobile variant was crushing lines). */

.dash-target-row {
    min-height: 34px;
    padding: 3px 0;
}

.dash-pumbility-tall .dash-target-row {
    padding: 5px 0;
}

.dash-mini-art {
    width: 26px;
    height: 26px;
}

.dash-endzone {
    box-shadow: inset 0 -3px 0 0 var(--mix-primary);
    border-radius: 10px;
}

.dash-pools {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    font-variant-numeric: tabular-nums;
}

/* Account Stats widget: glowy Pumbility + competitive level, then the closest matches. */
.dash-acct {
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 1;
    min-height: 0;
}

.dash-acct-stats {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: none;
}

.dash-acct-eyebrow {
    font-size: .6rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    font-weight: 700;
    color: var(--mud-palette-text-disabled);
}

.dash-acct-cl-eyebrow {
    margin-top: 6px;
}

.dash-acct-hero {
    display: flex;
    align-items: center;
    gap: 16px;
}

/* The P2 level gem beside the total — a fixed square so a slow image load never
   reflows the hero. The negative margin eats the hero gap plus the art's own
   transparent frame, so gem and number read as one unit (owner, field test). */
.dash-acct-hero .pumbility-level-badge {
    flex: none;
    margin-right: -8px;
}

.dash-acct-total {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    flex: none;
}

/* S/D Pumbility pools stacked to the right of the big total (owner, field-test). */
.dash-acct-pools {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
}

.dash-acct-poolrow {
    display: flex;
    gap: 6px;
    align-items: baseline;
    white-space: nowrap;
}

.dash-acct-poolrow > span:first-child {
    font-weight: 600;
}

.dash-acct-poolnum {
    font-weight: 700;
}

.dash-acct-active {
    box-shadow: 0 2px 0 var(--mix-primary);
}

.dash-acct-matches {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    border-top: 1px solid rgba(255, 255, 255, .06);
    padding-top: 8px;
}

.dash-acct-mhead {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 6px;
}

.dash-acct-mlabel {
    font-size: .6rem;
    text-transform: uppercase;
    letter-spacing: .1em;
    font-weight: 700;
    color: var(--mud-palette-text-disabled);
}

.dash-acct-you {
    font-size: .72rem;
    color: var(--mud-palette-text-secondary);
    font-variant-numeric: tabular-nums;
}

.dash-acct-you b {
    color: var(--daily-you);
    font-weight: 700;
}

.dash-acct-mlist {
    display: flex;
    flex-direction: column;
    gap: 5px;
    overflow-y: auto;
    min-height: 0;
}

.dash-acct-who {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
}

.dash-acct-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.dash-acct-trail {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    white-space: nowrap;
}

.dash-acct-lvl {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.dash-acct-empty {
    font-size: .72rem;
    font-style: italic;
    color: var(--mud-palette-text-disabled);
    padding: 8px 4px;
    text-align: center;
}

.dash-acct-mixpill {
    font-size: .58rem;
    font-weight: 800;
    letter-spacing: .03em;
    padding: 1px 7px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--mix-primary) 16%, transparent);
    color: var(--mix-primary);
    border: 1px solid color-mix(in srgb, var(--mix-primary) 40%, transparent);
}

/* Daily Step widget (docs/design/daily-step.md): the shared daily chart as a leaderboard card. */

/* Row-highlight tokens, global so the leaderboard dialog can glow too: you (blue), community
   (green), rival (red). Mix-invariant like the judgment and lifebar groups — a rival reads as a
   rival in every theme.

   --daily-rival is NOT MixPalette.Error (#C72020): that one is too dark to read at 13% fill and
   already means "something went wrong". This sits clear of the Phoenix secondary orange
   (#FF6B35) too, so a rival never reads as a brand accent (docs/design/rivals.md D39). */
:root {
    --daily-you: #4bb8ff;
    --daily-community: #43dc86;
    --daily-rival: #FF3B5C;
}

/* ── Row highlighting, one utility set over four unrelated row layouts ──────────────────
   ONE GEOMETRY for every state: a tint plus a bar down each edge. Colour is the only variable,
   so the segmented row is not a special case — it is the same shape with a different colour at
   each end. Rings were the original treatment and are gone: at row height a 1.5px ring reads as
   a box drawn around the row, which fought the board's own grid, and it made the segmented row
   look like a different component rather than the same one carrying two states.
   .weekly-lb-row (flex), .dash-ch-entry (feed card), the challenge board rows and the rival
   roster row share no layout at all, so the treatment is applied OVER whichever they use rather
   than grown as a variant inside each family (docs/design/rivals.md §3.6).

   Precedence is you → both → rival → community: you always wins, and a rival who is also a
   clubmate is more interesting as both than as either. */
.is-rival {
    background: color-mix(in srgb, var(--daily-rival) 13%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-rival), inset -3px 0 0 var(--daily-rival);
}

/* The green half of the pair. The weekly board had its own community row style before this
   utility set existed (.weekly-lb-community) and keeps it; the feed card and roster families
   have no such ancestor, so without this rule they emit a class that styles nothing. */
.is-community {
    background: color-mix(in srgb, var(--daily-community) 13%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-community), inset -3px 0 0 var(--daily-community);
}

/* Split fill plus a left and a right edge bar. A two-tone border-image ring would read as
   segmented too, but it kills border-radius; this keeps the corners every other row has. */
.is-both {
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--daily-rival) 14%, transparent) 0 50%,
        color-mix(in srgb, var(--daily-community) 14%, transparent) 50% 100%);
    box-shadow: inset 3px 0 0 var(--daily-rival), inset -3px 0 0 var(--daily-community);
}

/* A board-only rival's score came from the last weekly sweep. The asterisk is the whole
   disclaimer — the footnote under the board carries the date (D27). */
.rival-official-mark {
    color: var(--mix-accent);
    font-weight: 700;
    cursor: help;
}

.dash-daily {
    display: flex;
    flex-direction: column;
    gap: 12px;
    min-height: 0;
}

.dash-daily-limbo {
    align-self: flex-start;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .78rem;
    padding: 3px 8px;
    border-radius: 6px;
    border: 1px solid var(--mix-primary);
    color: var(--mix-primary);
}

.dash-daily-chart {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    padding-bottom: 2px;
    border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.dash-daily-board {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-height: 0;
}

/* The taller sizes scroll the whole board; dash-scroll supplies the quiet themed scrollbar. */
.dash-daily-board.dash-scroll {
    overflow-y: auto;
    flex: 1 1 auto;
}

.dash-lb-row {
    display: grid;
    grid-template-columns: 28px 1fr auto;
    align-items: center;
    gap: 8px;
    padding: 5px 7px;
    border-radius: 7px;
    background: color-mix(in srgb, var(--mix-surface-muted) 55%, transparent);
    font-size: .82rem;
}

.dash-lb-place {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.dash-lb-who {
    display: flex;
    align-items: center;
    gap: 5px;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-lb-score {
    display: flex;
    align-items: center;
    gap: 6px;
    justify-content: flex-end;
    font-variant-numeric: tabular-nums;
}

.dash-lb-pts {
    font-weight: 600;
}

.dash-lb-you {
    background: color-mix(in srgb, var(--daily-you) 15%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-you), inset -3px 0 0 var(--daily-you),
        0 0 12px -4px var(--daily-you);
}

.dash-lb-community {
    background: color-mix(in srgb, var(--daily-community) 13%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-community), inset -3px 0 0 var(--daily-community);
}

.dash-lb-divider {
    font-size: .62rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--mix-ink) 55%, transparent);
    padding: 4px 2px 1px;
}

/* Your row always sits below the scrolling board — the board takes the flex space and scrolls
   internally, so this stays anchored at the widget's bottom. */
.dash-lb-pinned {
    flex: none;
    padding-top: 4px;
    margin-top: 2px;
    border-top: 1px solid rgba(255, 255, 255, .1);
}

.dash-daily-controls {
    display: flex;
    justify-content: flex-end;
    gap: 2px;
}

/* 1x1 split: a short top-three (name + grade, score on hover) on the left, your standing on the right. */
.dash-daily-split {
    flex: 1;
    display: flex;
    gap: 8px;
    min-height: 0;
    align-items: stretch;
}

.dash-daily-top3 {
    flex: 1.15;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 3px;
}

.dash-top3-row {
    display: grid;
    grid-template-columns: 16px 1fr auto;
    align-items: center;
    gap: 6px;
    padding: 4px 6px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--mix-surface-muted) 50%, transparent);
    font-size: .78rem;
}

.dash-top3-place {
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    text-align: center;
}

.dash-top3-name {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-weight: 600;
}

.dash-top3-grade {
    font-weight: 800;
    font-size: .72rem;
}

/* A place with no entrant yet — the rank still shows, the rest dashes out. */
.dash-top3-empty {
    opacity: .45;
}

.dash-daily-mine {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 8px;
    border-radius: 9px;
    text-align: center;
}

.dash-daily-mine-empty {
    background: color-mix(in srgb, var(--mix-surface-muted) 45%, transparent);
}

.dash-mine-label {
    font-size: .6rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    font-weight: 800;
    opacity: .85;
}

.dash-mine-rank {
    font-size: 1.6rem;
    font-weight: 800;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
}

.dash-mine-line {
    font-size: .74rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.weekly-lb-verified {
    font-size: 0.9rem;
    opacity: 0.75;
}

.weekly-lb-photo {
    /* An icon-button squeezed to text scale so the proof link sits inline with the name. */
    padding: 0 2px;
}

.weekly-lb-photo .mud-icon-root {
    font-size: 0.95rem;
}

.weekly-lb-legend {
    color: color-mix(in srgb, var(--mix-ink) 55%, transparent);
}

/* Weekly leaderboard dialog (round 3, option 1). */

.weekly-lb-title {
    display: flex;
    align-items: center;
    gap: 10px;
}

.weekly-lb-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 6px;
    border-radius: 6px;
}

.weekly-lb-row + .weekly-lb-row {
    border-top: 1px solid rgba(255, 255, 255, .05);
}

.weekly-lb-me {
    background: color-mix(in srgb, var(--daily-you) 15%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-you), inset -3px 0 0 var(--daily-you);
}

.weekly-lb-community {
    background: color-mix(in srgb, var(--daily-community) 13%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-community), inset -3px 0 0 var(--daily-community);
}

.weekly-lb-place {
    font-family: var(--font-display);
    font-weight: 700;
    min-width: 36px;
    font-variant-numeric: tabular-nums;
}

.weekly-lb-user {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ===== Quiet scrolling (round 4): widget inner scrollers show NO scrollbar at rest —
   the edge fades are the "there's more" affordance. Desktop reveals a thin themed
   thumb on hover (hover = intent); touch keeps native auto-hiding overlays. Where
   scroll-driven animations exist, the fades are honest: top fade only once scrolled,
   bottom fade gone at the end. Elsewhere the static bottom fade remains. ===== */

@property --dash-fade-top {
    syntax: "<length>";
    inherits: false;
    initial-value: 0px;
}

@property --dash-fade-bottom {
    syntax: "<length>";
    inherits: false;
    initial-value: 24px;
}

.dash-scroll,
.dash-drawer .mud-drawer-content {
    scrollbar-width: thin;
    scrollbar-color: transparent transparent;
}

.dash-scroll:hover,
.dash-drawer .mud-drawer-content:hover {
    scrollbar-color: color-mix(in srgb, var(--mix-ink-muted) 35%, transparent) transparent;
}

.dash-scroll::-webkit-scrollbar,
.dash-drawer .mud-drawer-content::-webkit-scrollbar {
    width: 6px;
}

.dash-scroll::-webkit-scrollbar-track,
.dash-drawer .mud-drawer-content::-webkit-scrollbar-track {
    background: transparent;
}

.dash-scroll::-webkit-scrollbar-thumb,
.dash-drawer .mud-drawer-content::-webkit-scrollbar-thumb {
    background: transparent;
    border-radius: 3px;
}

.dash-scroll:hover::-webkit-scrollbar-thumb,
.dash-drawer .mud-drawer-content:hover::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--mix-ink-muted) 35%, transparent);
}

.dash-scroll {
    overflow-y: auto;
    mask-image: linear-gradient(to bottom,
        transparent 0,
        #000 var(--dash-fade-top),
        #000 calc(100% - var(--dash-fade-bottom)),
        transparent 100%);
}

@supports (animation-timeline: scroll()) {
    .dash-scroll {
        animation: dash-scroll-fades linear both;
        animation-timeline: scroll(self);
    }

    @keyframes dash-scroll-fades {
        0% {
            --dash-fade-top: 0px;
            --dash-fade-bottom: 24px;
        }

        10% {
            --dash-fade-top: 24px;
            --dash-fade-bottom: 24px;
        }

        90% {
            --dash-fade-top: 24px;
            --dash-fade-bottom: 24px;
        }

        100% {
            --dash-fade-top: 24px;
            --dash-fade-bottom: 0px;
        }
    }
}

/* Phone column: cells auto-grow to their content, so no widget list overflows — which is
   also why the scroll(self) timeline above never advances there. Left alone, the mask
   would park at its initial value and permanently ghost every list's last row into a
   "scroll me" that scrolls nothing.

   This block sits AFTER the two rules it overrides on purpose. Every selector involved is
   (0,1,0), and neither a media query nor @supports adds specificity, so source order is
   the only thing that can decide — the same suppression written above them is inert. That
   is not hypothetical: it shipped that way twice, once here and once as a .dash-targets
   rule that spent its whole life dead. If this ever moves, it stops working silently. */
@media (max-width: 599.98px) {
    .dash-scroll {
        mask-image: none;
        animation: none;
    }
}

/* Themed ApexCharts tooltips (round 5): Apex's own dark theme half-applies — pin the
   popover to our tokens instead. Keyed on the shared wrapper class so every graph on
   the site can adopt it (ApexChartTheming.WrapperClass). */

.themed-apex .apexcharts-tooltip {
    background: rgba(8, 12, 18, .94) !important;
    border: 1px solid rgba(255, 255, 255, .16) !important;
    color: #ffffff !important;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .5) !important;
}

.themed-apex .apexcharts-tooltip-title {
    background: rgba(255, 255, 255, .06) !important;
    border-bottom: 1px solid rgba(255, 255, 255, .1) !important;
    color: #ffffff !important;
    font-family: var(--font-display) !important;
}

/* All the tooltip text runs white — the token ink was too dim to read over the chart (owner). */
.themed-apex .apexcharts-tooltip-text,
.themed-apex .apexcharts-tooltip-text-y-label,
.themed-apex .apexcharts-tooltip-text-y-value,
.themed-apex .apexcharts-tooltip-text-label,
.themed-apex .apexcharts-tooltip-text-value,
.themed-apex .apexcharts-tooltip-y-group,
.themed-apex .apexcharts-tooltip-series-group {
    color: #ffffff !important;
}

/* ===== Chart details page (docs/design/chart-details-overhaul.md, mock R2) =====
   Answer -> evidence -> record -> onward. Static-SSR-ready: everything here styles from
   tokens; the sections that need a circuit are components (the Stage-3 islands). */

.chart-empty {
    max-width: 560px;
    margin: 32px auto;
    display: grid;
    gap: 10px;
}

.chart-empty-sub {
    color: var(--mix-ink-muted);
}

.chart-hero {
    display: grid;
    grid-template-columns: 300px 1fr;
    gap: 28px;
    align-items: start;
    padding: 18px 0 8px;
}

/* The jacket column: art, then your score in the nook beneath it. */
.chart-hero-jacket-col {
    display: flex;
    flex-direction: column;
    gap: 12px;
    width: 300px;
    flex: none;
}

/* The chart you are on stays in its song's lineup, ringed rather than removed — taking it
   out made the row read as "the other ones" and hid where you sit in the ladder. */
.chart-hero-sibling-current {
    display: inline-flex;
    padding: 3px;
    border-radius: 10px;
    border: 1px solid var(--mix-primary);
    box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 45%, transparent);
}

.chart-section-credit {
    margin-top: 14px;
    font-size: .74rem;
    color: var(--mix-ink-muted);
}

.chart-jacket {
    position: relative;
    width: 300px;
    border-radius: 14px;
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, .10);
    background: var(--mix-surface);
    box-shadow: 0 18px 50px rgba(0, 0, 0, .5);
}

/* Scoped to the jacket wrapper, never `.chart-jacket .mud-image`: the difficulty bubble is
   a MudImage in this box too, and telling it to fill the frame made it 300px wide. */
.chart-jacket-art,
.chart-jacket-art .mud-image {
    width: 100%;
    height: auto;
    display: block;
}

.chart-jacket-video {
    width: 100%;
    aspect-ratio: 16 / 9;
    border: 0;
    display: block;
}

/* The jacket is the button, same as the shelf's cards — two ways to start a video on one
   page is one too many. The bubble stays outside it: it labels the art, it does not play. */
.chart-jacket-playable {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    position: relative;
}

/* Centred circle, revealed on hover — .chart-card-play's treatment at the hero's scale.
   pointer-events: none so the button underneath owns every pixel of the art. */
.chart-jacket-play {
    position: absolute;
    left: 50%;
    top: 50%;
    translate: -50% -50%;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 62px;
    height: 62px;
    padding-left: 4px;
    border-radius: 99px;
    pointer-events: none;
    background: rgba(0, 0, 0, .8);
    border: 1px solid rgba(255, 255, 255, .2);
    color: #fff;
    opacity: .85;
    transform: scale(.94);
    transition: opacity .12s, transform .12s, background .12s, border-color .12s;
}

.chart-jacket-play::before {
    content: "";
    border-style: solid;
    border-width: 10px 0 10px 16px;
    border-color: transparent transparent transparent currentColor;
}

.chart-jacket-playable:hover .chart-jacket-play,
.chart-jacket-playable:focus-visible .chart-jacket-play {
    opacity: 1;
    transform: scale(1);
}

.chart-jacket-playable:hover .chart-jacket-play {
    background: rgba(0, 0, 0, .93);
    border-color: var(--mix-primary);
}

.chart-jacket-close {
    position: absolute;
    right: 12px;
    top: 12px;
    z-index: 4;
    cursor: pointer;
    font-weight: 600;
    font-size: .68rem;
    color: #fff;
    background: rgba(0, 0, 0, .8);
    border: 1px solid rgba(255, 255, 255, .2);
    border-radius: 99px;
    width: 24px;
    height: 24px;
    line-height: 1;
}

.chart-jacket-close:hover {
    border-color: var(--mix-primary);
}

.chart-jacket-bubble {
    position: absolute;
    right: 10px;
    top: 10px;
    filter: drop-shadow(0 4px 10px rgba(0, 0, 0, .6));
}

.chart-hero-title {
    font-family: var(--font-display);
    font-size: 2.3rem;
    font-weight: 800;
    line-height: 1.05;
    margin: 0;
    text-wrap: balance;
}

.chart-hero-sub {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 8px;
    color: var(--mix-ink-muted);
    font-size: .9rem;
}

.chart-hero-siblings {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 10px;
}

.chart-hero-facts {
    display: flex;
    gap: 26px;
    flex-wrap: wrap;
    margin-top: 16px;
}

.chart-fact-value {
    display: block;
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.chart-fact-label {
    display: block;
    font-size: .68rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    margin-top: 1px;
}

.chart-verdict {
    margin-top: 16px;
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .10);
    border-left: 3px solid var(--mix-accent);
    border-radius: 12px;
    padding: 14px 17px;
}

.chart-verdict-head {
    font-size: 1.12rem;
    font-weight: 700;
    line-height: 1.35;
    text-wrap: balance;
}

.chart-verdict-sub {
    color: var(--mix-ink-muted);
    font-size: .86rem;
    margin-top: 5px;
    max-width: 62ch;
}

.chart-verdict-chips {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 11px;
}

/* The identity chips sit between the verdict sentences and the tier chips, and take the same
   gap the tier chips do — the component's own margin is tuned for a dialog, where it is the
   whole block rather than the middle of one. */
.chart-verdict .chart-identity-groups {
    margin: 11px 0 0;
}

.chart-verdict-chip {
    border: 1px solid;
    border-radius: 99px;
    font-size: .74rem;
    font-weight: 700;
    padding: 3px 11px;
    white-space: nowrap;
}

.chart-verdict-chip-muted {
    color: var(--mix-ink-muted);
    border-color: rgba(255, 255, 255, .22);
}

.chart-hero-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-top: 16px;
}

.chart-overline {
    display: block;
    font-size: .68rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    font-weight: 600;
}

.chart-section {
    margin: 26px 0;
}

.chart-section-head {
    display: flex;
    align-items: baseline;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.chart-section-sub {
    color: var(--mix-ink-muted);
}

/* Your best + record inputs (the record island at Stage 3). */
/* One card in the hero's nook, not two panels down the page: your score is the first thing
   you look for, and recording is a mode of it rather than a separate destination. */
.chart-record {
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 12px;
    padding: 14px 16px;
}

.chart-record-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.chart-record-edit {
    flex: none;
    color: var(--mix-ink-muted);
}

.chart-record-edit:hover {
    color: var(--mix-primary);
}

.chart-record-inputs {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 10px;
}

.chart-record-score {
    margin-top: 8px;
}

/* A legacy best is a grade icon with the era number beside it, when the player gave one.
   Tabular figures because the number is a measurement, not a label. */
.chart-record-legacy-score {
    margin-left: 8px;
    font-variant-numeric: tabular-nums;
    vertical-align: middle;
}

.chart-record-age, .chart-record-note {
    display: block;
    color: var(--mix-ink-muted);
    margin-top: 4px;
}

.chart-record-empty {
    color: var(--mix-ink-muted);
    margin-top: 8px;
}

/* ScoreJourneyList — shared by the chart page's record panel and the details dialog's
   History tab. It lives here rather than in the component's own <style> block because a
   style block only reaches the DOM on the renders that include it, and this component has
   two hosts. No flex-grow on the score: the grade icon sits beside the number rather than
   floating to the far right (owner, piucenter round 4). */
.score-journey {
    margin-top: 12px;
    border-top: 1px dashed rgba(255, 255, 255, .14);
    padding-top: 9px;
}

.score-journey-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 0;
}

.score-journey-date {
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.score-journey-score {
    font-variant-numeric: tabular-nums;
}

.score-journey-stagebreak {
    color: var(--mix-ink-muted);
}

.score-journey-empty {
    color: var(--mix-ink-muted);
}

.chart-record-row {
    display: grid;
    grid-template-columns: minmax(120px, 1fr) minmax(120px, 1fr);
    gap: 10px 12px;
    align-items: center;
    margin-top: 8px;
}

/* Evidence graph cards - sentence first, curve second. */
.chart-evidence {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
}

.chart-evidence-card {
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 12px;
    padding: 13px 15px;
}

.chart-evidence-caption {
    font-size: .92rem;
    font-weight: 600;
    line-height: 1.4;
    margin: 4px 0 8px;
    max-width: 48ch;
}

.chart-evidence-empty {
    grid-column: 1 / -1;
    color: var(--mix-ink-muted);
}

/* The PUMBILITY presence graph (docs/design/chart-presence-graph.md). Titles down by default; a host that
   allows it turns the titles across at the Desktop rung. Every mark sits at a percent of its panel, with
   the panels themselves at fixed heights, so nothing needs a script to draw or to reflow on an unfold. */
.presence {
    --presence-ground: var(--mix-bg);
    margin-top: 14px;
    container-type: inline-size;
    container-name: presence;
}

.chart-details-dialog .presence {
    --presence-ground: var(--mix-surface);
}

.presence-caption {
    font-size: .92rem;
    font-weight: 600;
    line-height: 1.4;
    margin: 4px 0;
    max-width: 64ch;
}

.presence-line {
    font-size: .86rem;
    line-height: 1.4;
    margin: 0 0 4px;
    max-width: 64ch;
}

/* The callout on a chart whose official ranking is crowded: an arrow in a ring beside a heading and its sentence. */
.presence-note {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 3px 10px;
    margin: 8px 0;
    padding: 9px 12px;
    max-width: 64ch;
    border-radius: 6px;
    background: color-mix(in srgb, var(--mix-secondary) 8%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mix-secondary) 32%, transparent);
}

.presence-note-glyph {
    grid-row: 1 / span 2;
    display: inline-grid;
    place-items: center;
    width: 16px;
    height: 16px;
    margin-top: 1px;
    border: 1.25px solid currentColor;
    border-radius: 50%;
    font-size: 10px;
    font-weight: 700;
    line-height: 1;
    color: var(--mix-secondary);
}

.presence-note-head {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 13px;
    line-height: 1.3;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--mix-ink);
}

.presence-note-body {
    font-size: .8rem;
    line-height: 1.45;
    color: var(--mix-ink-muted);
}

/* A title the crowded ranking undercounts: a dashed box past the end of its share bar. */
.presence-more {
    position: absolute;
    display: block;
    border: 1.25px dashed var(--mix-secondary);
    border-radius: 2px;
}

.presence-mark,
.presence-you {
    position: absolute;
    display: block;
}

.is-thin .presence-mark {
    opacity: .42;
}

.presence-ghost {
    background: color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 2px;
}

.presence-ghost-median {
    background: color-mix(in srgb, var(--mix-ink) 50%, transparent);
}

.presence-whisker,
.presence-cap {
    background: color-mix(in srgb, var(--mix-secondary) 70%, transparent);
}

.presence-box {
    background: var(--mix-secondary);
    border-radius: 1.5px;
    box-shadow: 0 0 0 2px var(--presence-ground);
}

.presence-median {
    background: var(--mix-ink);
}

.presence-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--mix-secondary);
    box-shadow: 0 0 0 1.5px var(--presence-ground);
}

.presence-you {
    width: 7px;
    height: 7px;
    background: var(--mix-accent);
    box-shadow: 0 0 0 2px var(--presence-ground);
}

/* The diamond that points out your title beside its name, or above its column. */
.presence-you-mark {
    display: inline-block;
    flex: none;
    width: 6px;
    height: 6px;
    background: var(--mix-accent);
    box-shadow: 0 0 0 1.5px var(--presence-ground);
    transform: rotate(45deg);
}

.presence-bar {
    background: var(--mix-secondary);
}

.presence-tip {
    display: none;
    position: absolute;
    z-index: 6;
    width: max-content;
    max-width: 230px;
    padding: 7px 10px;
    background: var(--mix-nav);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 25%, transparent);
    border-radius: 4px;
    box-shadow: 0 8px 22px rgba(0, 0, 0, .5);
    font-size: 12.5px;
    line-height: 1.45;
    text-align: left;
    pointer-events: none;
}

.presence-tip-head {
    display: block;
    margin-bottom: 2px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13px;
    line-height: 1.3;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.presence-tip-line,
.presence-tip-muted,
.presence-tip-you {
    display: block;
    color: var(--mix-ink);
}

.presence-tip-muted {
    color: var(--mix-ink-muted);
}

.presence-tip-you {
    margin-top: 4px;
    padding-top: 3px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
}

.presence-tip-more {
    color: var(--mix-secondary);
}

.presence-col:focus-within .presence-tip,
.presence-row:focus-within .presence-tip {
    display: block;
}

@media (hover: hover) {
    .presence-col:hover .presence-tip,
    .presence-row:not(.presence-head):hover .presence-tip {
        display: block;
    }

    .presence-col:hover,
    .presence-row:not(.presence-head):hover {
        background: color-mix(in srgb, var(--mix-ink) 6%, transparent);
    }
}

/* Titles across: a gutter of tick labels, then one grid column per title over two panels. */
.presence-across {
    display: none;
    margin-top: 10px;
}

@media (min-width: 900px) {
    .presence-can-cross .presence-across {
        display: block;
    }

    .presence-can-cross .presence-down {
        display: none;
    }
}

/* Your column's flag, a row above the plot: the diamond and "You", or the diamond alone on a narrow column.
   A chart outside your top 50 has no diamond, so its flag keeps the word at every width. */
.presence-flag {
    display: grid;
    grid-template-columns: 32px repeat(var(--presence-columns), minmax(0, 1fr));
    height: 14px;
}

.presence-flag-you {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    container-type: inline-size;
}

.presence-flag-you b {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 10.5px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--mix-ink);
}

@container (max-width: 37.98px) {
    .presence-flag-you:not(.is-word) b {
        display: none;
    }
}

.presence-plot {
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr);
}

.presence-gutter {
    position: relative;
    height: 328px;
}

.presence-gutter span {
    position: absolute;
    right: 5px;
    transform: translateY(-50%);
    font-size: 10px;
    font-weight: 500;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.presence-cols {
    position: relative;
    display: grid;
    grid-template-columns: repeat(var(--presence-columns), minmax(0, 1fr));
    height: 328px;
}

.presence-grid {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.presence-grid i {
    position: absolute;
    left: 0;
    right: 0;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
}

.presence-grid i.is-base {
    border-top-color: color-mix(in srgb, var(--mix-ink) 26%, transparent);
}

.presence-panel {
    position: absolute;
    left: 0;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 10px;
    line-height: 14px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.presence-col {
    position: relative;
    border-radius: 4px;
    outline: none;
}

.presence-col:focus-visible {
    box-shadow: inset 0 0 0 1.5px var(--mix-ink);
}

.presence-col.is-you {
    background: color-mix(in srgb, var(--mix-accent) 9%, transparent);
}

/* A faint rule where one gem gives way to the next. */
.presence-col.is-gem-start::before {
    content: "";
    position: absolute;
    top: 10px;
    bottom: 2px;
    left: 0;
    border-left: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
}

.presence-share {
    position: absolute;
    top: 18px;
    left: 0;
    right: 0;
    height: 64px;
}

.presence-spots {
    position: absolute;
    top: 112px;
    left: 0;
    right: 0;
    height: 210px;
}

.presence-across .presence-mark,
.presence-across .presence-you {
    left: 50%;
}

.presence-across .presence-bar {
    bottom: 0;
    width: min(18px, 56%);
    transform: translateX(-50%);
    border-radius: 3px 3px 0 0;
}

.presence-peak {
    position: absolute;
    left: 50%;
    transform: translate(-50%, -4px);
    font-size: 11px;
    font-weight: 500;
    color: var(--mix-ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.presence-col.is-thin .presence-peak {
    color: var(--mix-ink-muted);
}

/* The dashed box sits a pixel above the bar, and the peak's value rises over it. */
.presence-across .presence-more {
    left: 50%;
    width: min(18px, 56%);
    height: 9px;
    margin-bottom: 1px;
    transform: translateX(-50%);
}

.presence-peak.is-more {
    transform: translate(-50%, -14px);
}

.presence-across .presence-ghost {
    width: min(23px, 90%);
    min-height: 2px;
    transform: translateX(-50%);
}

.presence-across .presence-ghost-median {
    width: min(23px, 90%);
    height: 2px;
    transform: translate(-50%, -50%);
}

.presence-across .presence-whisker {
    width: 1.25px;
    transform: translateX(-50%);
}

.presence-across .presence-cap {
    width: min(8px, 30%);
    height: 1.25px;
    transform: translate(-50%, -50%);
}

.presence-across .presence-box {
    width: min(14px, 50%);
    min-height: 2px;
    transform: translateX(-50%);
}

.presence-across .presence-median {
    width: min(16px, 60%);
    height: 2px;
    transform: translate(-50%, -50%);
}

.presence-across .presence-dot {
    transform: translate(-50%, -50%);
}

.presence-across .presence-you {
    transform: translate(-50%, -50%) rotate(45deg);
}

.presence-col .presence-tip {
    top: 112px;
    left: calc(100% + 6px);
}

.presence-col.is-flip .presence-tip {
    left: auto;
    right: calc(100% + 6px);
}

/* Gem names on the first row, a bracket under a gem that opens, its level numbers below. */
.presence-labels {
    display: grid;
    grid-template-columns: 32px repeat(var(--presence-columns), minmax(0, 1fr));
    grid-template-rows: auto 7px auto;
    row-gap: 2px;
    margin-top: 6px;
}

.presence-gem {
    grid-row: 1;
    justify-self: center;
    align-self: start;
    text-align: center;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 10.5px;
    line-height: 1.2;
    letter-spacing: .06em;
    color: var(--mix-ink);
}

.presence-bracket {
    grid-row: 2;
    margin: 0 6px;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 30%, transparent);
    border-bottom: 0;
}

.presence-level {
    grid-row: 3;
    align-self: start;
    text-align: center;
    white-space: nowrap;
    container-type: inline-size;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 10.5px;
    letter-spacing: .04em;
    color: var(--mix-ink-muted);
}

/* A column too narrow for "LV.1" keeps the number. */
@container (max-width: 29.98px) {
    .presence-level-prefix {
        display: none;
    }
}

@container presence (max-width: 959.98px) {
    .presence-gem.is-single {
        grid-row: 1 / span 3;
        writing-mode: vertical-rl;
        transform: rotate(180deg);
    }
}

/* Titles down: one row per title, the spot axis running #50 on the left to #1 on the right. */
.presence-down {
    margin-top: 10px;
}

.presence-row {
    position: relative;
    display: grid;
    grid-template-columns: 88px minmax(0, 1fr) 38px 30px;
    column-gap: 7px;
    align-items: center;
    min-height: 20px;
    border-radius: 3px;
    outline: none;
}

@container presence (min-width: 440px) {
    .presence-row {
        grid-template-columns: 128px minmax(0, 1fr) 110px 40px;
        column-gap: 12px;
        min-height: 23px;
    }

    .presence-down .presence-box {
        height: 10px;
    }

    .presence-down .presence-median {
        height: 12px;
    }

    .presence-down .presence-ghost {
        height: 17px;
    }

    .presence-down .presence-ghost-median {
        height: 19px;
    }

    .presence-head .is-narrow {
        display: none;
    }
}

@container presence (max-width: 439.98px) {
    .presence-head .is-wide {
        display: none;
    }
}

.presence-row.is-gem-start {
    margin-top: 7px;
}

/* A faint rule where one gem gives way to the next. */
.presence-row.is-gem-start::before {
    content: "";
    position: absolute;
    top: -4px;
    left: 0;
    right: 0;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
}

.presence-head + .presence-row {
    margin-top: 2px;
}

.presence-head + .presence-row::before {
    content: none;
}

.presence-row:focus-visible {
    box-shadow: inset 0 0 0 1.5px var(--mix-ink);
}

.presence-row.is-you {
    background: color-mix(in srgb, var(--mix-accent) 9%, transparent);
}

.presence-row-title {
    display: flex;
    align-items: center;
    gap: 9px;
    min-width: 0;
}

.presence-row-gem {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11.5px;
    letter-spacing: .05em;
    color: var(--mix-ink);
}

.presence-row-level {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    flex: none;
    margin-left: auto;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .04em;
    color: var(--mix-ink-muted);
}

.presence-row-plot {
    position: relative;
    height: 18px;
    container-type: inline-size;
}

/* Every ten spots where the plot has room for the labels; #25 alone between the ends where it has not. */
@container (max-width: 169.98px) {
    .presence-row-plot .is-fine {
        display: none;
    }
}

@container (min-width: 170px) {
    .presence-row-plot .is-coarse {
        display: none;
    }
}

.presence-row-grid {
    position: absolute;
    top: -3px;
    bottom: -3px;
    border-left: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
}

.presence-down .presence-mark,
.presence-down .presence-you {
    top: 50%;
}

.presence-down .presence-ghost {
    height: 16px;
    min-width: 2px;
    transform: translateY(-50%);
}

.presence-down .presence-ghost-median {
    width: 2px;
    height: 18px;
    transform: translate(-50%, -50%);
}

.presence-down .presence-whisker {
    height: 1.25px;
    transform: translateY(-50%);
}

.presence-down .presence-cap {
    width: 1.25px;
    height: 6px;
    transform: translate(-50%, -50%);
}

.presence-down .presence-box {
    height: 9px;
    min-width: 2px;
    transform: translateY(-50%);
}

.presence-down .presence-median {
    width: 2px;
    height: 11px;
    transform: translate(-50%, -50%);
}

.presence-down .presence-dot {
    transform: translate(-50%, -50%);
}

.presence-down .presence-you {
    transform: translate(-50%, -50%) rotate(45deg);
}

.presence-row-share {
    position: relative;
    height: 8px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--mix-ink) 7%, transparent);
}

.presence-down .presence-bar {
    top: 0;
    bottom: 0;
    left: 0;
    border-radius: 0 3px 3px 0;
}

/* The dashed box starts a pixel past the bar and runs up to 11px, stopping at the end of the track. */
.presence-down .presence-more {
    top: 0;
    bottom: 0;
    left: var(--presence-bar);
    width: max(0px, min(11px, calc(100% - var(--presence-bar) - 1px)));
    margin-left: 1px;
}

.presence-row-value {
    justify-self: end;
    font-size: 10px;
    font-weight: 500;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.presence-row-value.is-peak {
    font-size: 11px;
    color: var(--mix-ink);
}

.presence-row.is-thin .presence-row-value {
    color: var(--mix-ink-muted);
}

.presence-head {
    min-height: 18px;
}

.presence-head .presence-row-title,
.presence-head .presence-row-share {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 10px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.presence-head .presence-row-share {
    grid-column: 3 / span 2;
    height: auto;
    background: none;
}

.presence-head .presence-row-plot b {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    font-size: 10px;
    font-weight: 500;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.presence-head .presence-row-plot b:first-child {
    transform: translate(-100%, -50%);
}

.presence-head .presence-row-plot b:last-child {
    transform: translate(0, -50%);
}

.presence-row .presence-tip {
    top: calc(100% + 2px);
    left: 0;
}

.presence-row.is-flip .presence-tip {
    top: auto;
    bottom: calc(100% + 2px);
}

.presence-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 14px;
    margin-top: 8px;
    font-size: 11.5px;
    color: var(--mix-ink-muted);
}

.presence-legend span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.presence-legend svg {
    display: block;
    flex: none;
}

.presence-key-bar {
    fill: var(--mix-secondary);
}

.presence-key-thin {
    opacity: .42;
}

.presence-key-whisker {
    stroke: var(--mix-secondary);
    stroke-width: 1.25;
    opacity: .7;
}

.presence-key-median {
    stroke: var(--mix-ink);
    stroke-width: 2;
}

.presence-key-ghost {
    fill: var(--mix-ink);
    opacity: .18;
}

.presence-key-ghost-median {
    stroke: var(--mix-ink);
    stroke-width: 2;
    opacity: .5;
}

.presence-key-you {
    fill: var(--mix-accent);
}

.presence-key-more {
    fill: none;
    stroke: var(--mix-secondary);
    stroke-width: 1.25;
    stroke-dasharray: 2 2;
}

/* History band. */
.chart-timeline {
    display: flex;
    overflow-x: auto;
    padding-bottom: 4px;
}

.chart-timeline-node {
    flex: 1;
    min-width: 150px;
    position: relative;
    padding: 14px 18px 4px 0;
}

.chart-timeline-node::before {
    content: "";
    position: absolute;
    top: 21px;
    left: 0;
    right: 0;
    height: 2px;
    background: rgba(255, 255, 255, .18);
}

.chart-timeline-node::after {
    content: "";
    position: absolute;
    top: 16px;
    left: 0;
    width: 12px;
    height: 12px;
    border-radius: 99px;
    background: var(--mix-bg);
    border: 3px solid var(--mix-primary);
}

.chart-timeline-dim::after {
    border-color: var(--mix-ink-muted);
}

.chart-timeline-mix {
    margin-top: 22px;
    font-weight: 800;
    font-size: .92rem;
}

.chart-timeline-level {
    margin-top: 4px;
    font-size: .82rem;
    color: var(--mix-ink-muted);
}

.chart-timeline-delta {
    margin-left: 6px;
    color: var(--diff-hard);
    font-weight: 800;
}

/* The legend chips, still worn by the official chart-board dialog. The page's own
   leaderboard table is gone — chart details renders ChartLeaderboardScopes now, which
   brings the .weekly-lb-row vocabulary with it. */
.chart-lb-legend {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .74rem;
    color: var(--mix-ink-muted);
}

.chart-lb-dot {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 3px;
}

.chart-lb-dot-community {
    background: var(--daily-community);
}

.chart-lb-dot-me {
    background: var(--daily-you);
    margin-left: 10px;
}

.chart-shelf-empty {
    color: var(--mix-ink-muted);
}

/* Similar-charts shelf - the internal link mesh. Three across, then two, then one; no
   density modes, because the card is sized around 16:9 art and that shape is the point. */
.chart-shelf {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
}

/* The static card grid is the crawlable mesh; the interactive shelf renders the same cards
   plus its controls and marks its root data-island-ready the moment it connects, which
   hides the static copy. Both render real <a href> cards, so nothing reflows on handoff. */
.chart-shelf-wrap:has([data-island-ready]) .chart-shelf-static {
    display: none;
}

.chart-shelf-controls {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    align-items: center;
    margin-bottom: 12px;
}

.chart-shelf-sort {
    display: flex;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 4px;
    overflow: hidden;
}

.chart-shelf-sort button {
    font-size: .75rem;
    color: var(--mix-ink-muted);
    background: transparent;
    border: 0;
    padding: 7px 12px;
    cursor: pointer;
    transition: color .12s, background .12s;
}

.chart-shelf-sort button + button {
    border-left: 1px solid rgba(255, 255, 255, .12);
}

.chart-shelf-sort button[aria-pressed="true"] {
    color: var(--mix-ink);
    background: var(--mix-surface-muted);
}

.chart-shelf-sort button:disabled {
    opacity: .4;
    cursor: not-allowed;
}

.chart-shelf-personal {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .75rem;
    color: var(--mix-ink-muted);
    cursor: pointer;
}

.chart-shelf-personal input {
    accent-color: var(--mix-primary);
    cursor: pointer;
}

.chart-shelf-personal:has(input:disabled) {
    opacity: .4;
    cursor: not-allowed;
}

.chart-shelf-addfilter {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: .75rem;
    color: var(--mix-ink-muted);
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 4px;
    padding: 6px 10px;
    cursor: pointer;
    transition: color .12s, border-color .12s;
}

.chart-shelf-addfilter:hover:not(:disabled),
.chart-shelf-addfilter[aria-expanded="true"] {
    color: var(--mix-ink);
    border-color: var(--mix-primary);
}

.chart-shelf-addfilter:disabled {
    opacity: .4;
    cursor: not-allowed;
}

/* How many filters are on, when the panel that would show you is shut. */
.chart-shelf-fcount {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    font-size: .65rem;
    font-weight: 700;
    color: var(--mix-primary-contrast);
    background: var(--mix-primary);
}

.chart-shelf-filterpanel {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-bottom: 14px;
    padding: 14px;
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 6px;
}

.chart-shelf-ftoggles {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

.chart-shelf-ftoggles label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .75rem;
    color: var(--mix-ink-muted);
    cursor: pointer;
}

.chart-shelf-ftoggles input {
    accent-color: var(--mix-primary);
    cursor: pointer;
}

.chart-shelf-ftoggles label:has(input:checked) {
    color: var(--mix-ink);
}

.chart-shelf-funavailable {
    opacity: .4;
    cursor: not-allowed;
}

/* Below the line because it is not one of the four: it asks the opposite question rather
   than narrowing this one. */
.chart-shelf-fopposite {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .75rem;
    color: var(--mix-ink-muted);
    cursor: pointer;
    padding-top: 12px;
    border-top: 1px solid rgba(255, 255, 255, .08);
}

.chart-shelf-fopposite input {
    accent-color: var(--mix-primary);
    cursor: pointer;
}

.chart-shelf-fopposite:has(input:checked) {
    color: var(--mix-ink);
}

.chart-shelf-fopposite:has(input:disabled) {
    opacity: .4;
    cursor: not-allowed;
}

.chart-shelf-fapply {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* The count owns the row; the buttons sit at the end of it. */
.chart-shelf-fcompare {
    flex: 1 1 auto;
    font-size: .74rem;
    color: var(--mix-ink-muted);
}

.chart-shelf-fclear,
.chart-shelf-fgo {
    font-size: .75rem;
    border-radius: 4px;
    padding: 6px 14px;
    cursor: pointer;
    transition: opacity .12s;
}

.chart-shelf-fclear {
    color: var(--mix-ink-muted);
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .12);
}

.chart-shelf-fgo {
    color: var(--mix-primary-contrast);
    background: var(--mix-primary);
    border: 1px solid var(--mix-primary);
    font-weight: 600;
}

.chart-shelf-fclear:disabled,
.chart-shelf-fgo:disabled {
    opacity: .4;
    cursor: not-allowed;
}

/* Filters that ran, as against filters being chosen — read-only, because the panel
   above is where they change and two edit points would fight. */
.chart-shelf-fchipclear {
    font-size: .72rem;
    color: var(--mix-ink-muted);
    background: transparent;
    border: 0;
    padding: 4px 6px;
    cursor: pointer;
    text-decoration: underline;
}

.chart-shelf-fchipclear:hover {
    color: var(--mix-primary);
}

.chart-shelf-hint,
.chart-shelf-reach {
    font-size: .74rem;
    color: var(--mix-ink-muted);
}

.chart-shelf-reach {
    margin-top: 10px;
}

.chart-shelf-filters {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}

.chart-shelf-fchip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .72rem;
    color: var(--mix-ink-muted);
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 4px;
    padding: 4px 4px 4px 8px;
}

.chart-shelf-fchip span {
    color: var(--mix-ink);
    font-weight: 600;
}


.chart-shelf-nearmiss {
    margin-top: 18px;
}

.chart-shelf-nearmiss > summary {
    cursor: pointer;
    color: var(--mix-ink-muted);
    font-size: .8rem;
    padding: 6px 0;
}

.chart-shelf-nearmiss > .chart-shelf {
    margin-top: 10px;
}

.chart-card {
    position: relative;
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 4px;
    transition: border-color .12s, background .12s;
}

.chart-card:hover {
    border-color: var(--mix-primary);
    background: var(--mix-surface-muted);
}

/* 16:9 from the start, so the video drops into the art's exact box: the card never
   changes height and the grid never jumps. The jacket is the play target; the link out
   is the icon by the name, so the two never fight over a pixel. */
.chart-card-art {
    position: relative;
    display: block;
    aspect-ratio: 16 / 9;
    margin: 10px 10px 0;
    /* Minus the 10px side margins, so the art stays inside the card. A dead `width: 100%`
       sat above this and never applied. */
    width: calc(100% - 20px);
    border-radius: 2px;
    background: rgba(0, 0, 0, .35);
    padding: 0;
    border: 0;
}

button.chart-card-art {
    cursor: pointer;
}

/* Scoped to the jacket wrapper, never `.chart-card-art img`: the bubble is an <img> in
   that box too, and telling it to fill the box makes it the size of the card. */
.chart-card-jacket,
.chart-card-jacket > * {
    display: block;
    width: 100%;
    height: 100%;
}

.chart-card-jacket img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 2px;
}

.chart-card-art-playing {
    overflow: hidden;
    border: 1px solid var(--mix-primary);
}

.chart-card-video {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

.chart-card-bubble {
    position: absolute;
    right: -6px;
    bottom: -8px;
    z-index: 3;
    filter: drop-shadow(0 2px 7px rgba(0, 0, 0, .6));
}

.chart-card-body {
    display: block;
    min-width: 0;
    padding: 12px 12px 12px;
}

.chart-card-title {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 9px;
}

.chart-card-title h3 {
    display: flex;
    align-items: center;
    gap: 5px;
    min-width: 0;
    margin: 0;
    font-weight: 600;
    font-size: .88rem;
    line-height: 1.25;
}

/* The name is its own element because a "…" never draws on a flex container — declared on the
   h3, a long name clips mid-letter and pushes the link icon out of view. */
.chart-card-name {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The card's only <a>. Small, but a real link — the crawler follows this. */
.chart-card-golink {
    flex: none;
    display: inline-flex;
    align-items: center;
    color: var(--mix-primary);
    opacity: .65;
    transition: opacity .12s;
}

.chart-card-golink:hover,
.chart-card-golink:focus-visible {
    opacity: 1;
}

.chart-card-golink .mud-icon-root {
    font-size: .95rem;
}

.chart-card-pct {
    font-weight: 700;
    font-size: .8rem;
    color: var(--mix-primary);
    font-variant-numeric: tabular-nums;
}

.chart-card-meta {
    display: block;
    margin-top: 4px;
    font-size: .69rem;
    line-height: 1.5;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.chart-card-meta em {
    font-style: normal;
    color: var(--mix-ink);
}

.chart-card-meta i {
    font-style: normal;
    opacity: .45;
    padding: 0 4px;
}

.chart-card-wl {
    display: block;
    margin: 10px 0 5px;
    font-weight: 600;
    font-size: .56rem;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.chart-card-why {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}

.chart-card-why b {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    font-weight: 500;
    font-size: .69rem;
    padding: 4px 6px;
    border-radius: 2px;
    color: var(--mix-ink);
    background: color-mix(in srgb, var(--mix-primary) 11%, transparent);
    border: 1px solid color-mix(in srgb, var(--mix-primary) 40%, transparent);
}

.chart-card-why b var {
    font-weight: 600;
    font-size: .62rem;
    font-style: normal;
    color: var(--mix-primary);
    font-variant-numeric: tabular-nums;
}

/* Intensity is a different KIND of reason and must not read as a skill. */
.chart-card-why-intensity {
    background: color-mix(in srgb, var(--mix-secondary) 11%, transparent) !important;
    border-color: color-mix(in srgb, var(--mix-secondary) 40%, transparent) !important;
}

.chart-card-why-intensity var {
    color: var(--mix-secondary) !important;
}

/* Mirrors the art's box so the button centres on the art without knowing its height.
   Transparent to the mouse, so the link underneath keeps the whole card as its target
/* Decoration: the whole jacket is the button, so this only says so. */
.chart-card-play {
    position: absolute;
    left: 50%;
    top: 50%;
    translate: -50% -50%;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 50px;
    height: 50px;
    padding-left: 3px;
    border-radius: 99px;
    pointer-events: none;
    background: rgba(0, 0, 0, .8);
    border: 1px solid rgba(255, 255, 255, .2);
    color: #fff;
    opacity: 0;
    transform: scale(.88);
    transition: opacity .13s, transform .13s, background .13s, border-color .13s;
}

.chart-card-play::before {
    content: "";
    border-style: solid;
    border-width: 8px 0 8px 13px;
    border-color: transparent transparent transparent currentColor;
}

.chart-card-art-playable:hover .chart-card-play,
.chart-card-art-playable:focus-visible .chart-card-play {
    opacity: 1;
    transform: scale(1);
}

.chart-card-art-playable:hover .chart-card-play {
    background: rgba(0, 0, 0, .93);
    border-color: var(--mix-primary);
}

.chart-card-close {
    position: absolute;
    right: 15px;
    top: 15px;
    z-index: 4;
    cursor: pointer;
    font-weight: 600;
    font-size: .68rem;
    color: #fff;
    background: rgba(0, 0, 0, .8);
    border: 1px solid rgba(255, 255, 255, .2);
    border-radius: 2px;
    padding: 4px 6px;
}

.chart-card-close:hover {
    border-color: var(--mix-primary);
}

.chart-admin {
    margin: 26px 0 12px;
}

@media (max-width: 900px) {
    .chart-hero {
        grid-template-columns: 1fr;
    }

    .chart-jacket {
        width: min(300px, 100%);
    }

    .chart-hero-title {
        font-size: 1.7rem;
    }

    .chart-record, .chart-evidence {
        grid-template-columns: 1fr;
    }

    .chart-shelf {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 600px) {
    .chart-shelf {
        grid-template-columns: 1fr;
    }
}

/* ============================================================================
   Weekly Charts — the challenges hub (docs/design/weekly-charts-overhaul.md).
   A static-SSR page: --mix-* / semantic tokens only, no --mud-* (static-shell.md
   D5). The one island is the dialog host; these classes are pure layout + the
   two semantic ramps.
   ============================================================================ */

.challenge-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 14px;
    margin: 14px 0 12px;
}

.challenge-head h1 {
    margin: 0;
}

.challenge-yourweek {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    font-size: 12.5px;
}

.challenge-chip {
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 12px;
    padding: 2px 10px;
    color: var(--mix-ink);
    white-space: nowrap;
}

.challenge-chip b {
    color: var(--mix-accent);
    font-weight: 600;
}

.challenge-controls {
    margin-left: auto;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Native-details pickers (week, communities): no circuit, the shell's mix-picker precedent. */
.challenge-picker {
    position: relative;
}

.challenge-picker > summary {
    list-style: none;
    cursor: pointer;
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 6px;
    padding: 3px 10px;
    font-size: 12.5px;
    color: var(--mix-ink);
    user-select: none;
    white-space: nowrap;
}

.challenge-picker > summary::-webkit-details-marker {
    display: none;
}

.challenge-picker > summary::after {
    content: " \25BE";
    color: var(--mix-ink-muted);
}

.challenge-picker[open] > summary {
    border-color: var(--mix-primary);
}

.challenge-picker-menu {
    position: absolute;
    right: 0;
    z-index: 20;
    margin-top: 5px;
    min-width: 220px;
    max-height: 280px;
    overflow: auto;
    background: var(--mix-surface-muted);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 8px;
    padding: 6px;
    box-shadow: 0 8px 22px rgba(0, 0, 0, .5);
}

.challenge-picker-menu a,
.challenge-picker-menu label {
    display: block;
    padding: 5px 9px;
    border-radius: 5px;
    color: var(--mix-ink);
    text-decoration: none;
    font-size: 13px;
    cursor: pointer;
}

.challenge-picker-menu a:hover,
.challenge-picker-menu label:hover {
    background: rgba(255, 255, 255, .06);
}

.challenge-picker-menu a.on {
    color: var(--mix-accent);
}

.challenge-picker-apply {
    margin: 6px 4px 2px;
    background: var(--mix-primary);
    color: var(--mix-primary-contrast);
    border: 0;
    border-radius: 5px;
    padding: 3px 12px;
    font-weight: 600;
    cursor: pointer;
}

.challenge-section {
    margin: 18px 0;
}

.challenge-sect-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 8px;
    flex-wrap: wrap;
}

.challenge-sect-head h2 {
    margin: 0;
}

.challenge-sect-head .sub {
    color: var(--mix-ink-muted);
    font-size: 12.5px;
}

.challenge-sect-head .right {
    margin-left: auto;
    display: flex;
    gap: 6px;
    align-items: center;
}

/* ---- shared row bits ------------------------------------------------------ */
.challenge-lb-place {
    min-width: 1.7em;
    text-align: right;
    font-weight: 700;
}

.challenge-flag {
    font-size: 10.5px;
    opacity: .8;
    margin-right: 4px;
}

.challenge-empty {
    border: 1px dashed rgba(255, 255, 255, .12);
    border-radius: 10px;
    padding: 16px;
    text-align: center;
    color: var(--mix-ink-muted);
}

.challenge-empty a {
    color: var(--mix-accent);
}

.challenge-muted {
    color: var(--mix-ink-muted);
}

/* ---- daily step strip ----------------------------------------------------- */
.challenge-limbo-chip {
    background: var(--mix-secondary);
    color: var(--mix-bg);
    font-weight: 700;
    border-radius: 4px;
    padding: 0 7px;
    font-size: 11.5px;
    text-transform: uppercase;
    white-space: nowrap;
}

/* ---- buttons -------------------------------------------------------------- */
.challenge-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: var(--mix-primary);
    color: var(--mix-primary-contrast);
    font-weight: 600;
    border: 0;
    border-radius: 6px;
    padding: 3px 11px;
    cursor: pointer;
    font-size: 12.5px;
    text-decoration: none;
    white-space: nowrap;
}

.challenge-btn.ghost {
    background: transparent;
    color: var(--mix-primary);
    border: 1px solid var(--mix-primary);
}

.challenge-iconbtn {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .12);
    color: var(--mix-ink-muted);
    border-radius: 4px;
    padding: 0 6px;
    cursor: pointer;
    font-size: 11.5px;
    line-height: 1.6;
}

.challenge-iconbtn:hover {
    color: var(--mix-ink);
    border-color: var(--mix-primary);
}

/* ---- weekly grid ---------------------------------------------------------- */
.challenge-gridbar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.challenge-gridbar h2 {
    margin: 0;
}

.challenge-filter-note {
    color: var(--mix-ink-muted);
    font-size: 12px;
}

.challenge-filter-note a {
    color: var(--mix-accent);
    text-decoration: none;
}

/* Density switcher, right-aligned (Tier Lists treatment). */
.challenge-den-group {
    margin-left: auto;
    display: flex;
    gap: 2px;
}

.challenge-den-btn {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .12);
    color: var(--mix-ink-muted);
    border-radius: 5px;
    width: 28px;
    height: 26px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.challenge-den-btn.on {
    color: var(--mix-primary);
    border-color: var(--mix-primary);
}

/* ── The week's grid, round-12 anatomy (§12): unsquished cards, top-3 + you, both ranking
   worlds shipped. Density keys on the grid's own data-density. ── */
.challenge-grid {
    display: grid;
    gap: 14px;
    /* Cap the comfortable grid at 6 columns: a wide monitor otherwise fits a 7th, and the
       weekly board's chart count divides cleanly by 6, so the 7th just orphans the last row.
       Each track is at least 280px but never narrower than a sixth of the row, so at most six
       ever fill the width — fewer when the row can't hold six at 280px. */
    grid-template-columns: repeat(auto-fill, minmax(max(280px, (100% - 5 * 14px) / 6), 1fr));
}

.challenge-grid.suggested-only .challenge-card[data-suggested="false"] {
    display: none;
}

/* The filter note follows the grid's state — both texts ship, :has() picks one. */
.challenge-main:has(.challenge-grid.suggested-only) .challenge-filter-note .when-all,
.challenge-main:not(:has(.challenge-grid.suggested-only)) .challenge-filter-note .when-filtered {
    display: none;
}

.challenge-card {
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .06);
    border-radius: 10px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    position: relative;
}

.challenge-card[data-suggested="true"] {
    border-color: color-mix(in srgb, var(--mix-accent) 55%, transparent);
    box-shadow: 0 0 14px -8px var(--mix-accent);
}

.challenge-card-jacket {
    position: relative;
    aspect-ratio: 16 / 7.5;
    background-size: cover;
    background-position: center;
    display: block;
}

.challenge-card-bubble {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 2;
}

.challenge-card-body {
    padding: 8px 10px 6px;
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.challenge-card-name {
    display: block;
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--mix-ink);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Same as .challenge-lb-row: the avatar moved into the name cell with the country wash. */
.challenge-card-line {
    display: grid;
    grid-template-columns: 26px minmax(0, 1fr) auto;
    gap: 7px;
    align-items: center;
    font-size: 12.2px;
    white-space: nowrap;
    color: var(--mix-ink);
    padding: 2px 4px;
    border-radius: 6px;
}

.challenge-card-line .who {
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    color: var(--mix-ink-muted);
    font-weight: 600;
}

.challenge-card-line .score {
    justify-self: end;
}

.challenge-card-line.mine {
    background: color-mix(in srgb, var(--daily-you) 15%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-you), inset -3px 0 0 var(--daily-you),
        0 0 12px -4px var(--daily-you);
}

.challenge-card-line.mine .who {
    color: var(--mix-ink);
}

.challenge-card-line.unplayed {
    display: flex;
    color: color-mix(in srgb, var(--mix-ink-muted) 55%, transparent);
}

.challenge-card-foot {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 8px 7px;
    border-top: 1px solid rgba(255, 255, 255, .05);
    color: var(--mix-ink-muted);
    font-size: 11.5px;
    margin-top: auto;
}

.challenge-card-foot .spacer,
.challenge-gridbar .spacer,
.challenge-railhead .spacer,
.challenge-railfoot .spacer {
    flex: 1;
}

/* ── The two ranking worlds (M20). Default shows the overall head; .relevant-on swaps to the
   renumbered in-range head. Rows/counters carry .co (overall) and .cr (in-range) pairs. ── */
.challenge-card-line.w-r:not(.w-o) {
    display: none;
}

.relevant-on .challenge-card-line {
    display: none;
}

.relevant-on .challenge-card-line.w-r {
    display: grid;
}

.relevant-on .challenge-card-line.unplayed.w-r {
    display: flex;
}

.challenge-card .cr {
    display: none;
}

.relevant-on .challenge-card .co {
    display: none;
}

.relevant-on .challenge-card .cr {
    display: inline;
}

.relevant-on .challenge-card-line[data-inrange="false"]:not(.mine) {
    display: none;
}

/* Compact keeps one action: the count chip opens the board (tier-list corner-chip). */
.challenge-count-chip {
    display: none;
    position: absolute;
    right: 5px;
    bottom: 5px;
    z-index: 2;
    background: color-mix(in srgb, var(--mix-bg) 85%, transparent);
    color: var(--mix-ink);
    border: 1px solid rgba(255, 255, 255, .18);
    border-radius: 999px;
    padding: 1px 8px;
    font-size: 10.5px;
    line-height: 1.6;
    cursor: pointer;
}

.challenge-count-chip:hover {
    border-color: var(--mix-primary);
    color: var(--mix-primary);
}

.challenge-grid[data-density="Compact"] {
    grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
    gap: 10px;
}

.challenge-grid[data-density="Compact"] .challenge-card-body,
.challenge-grid[data-density="Compact"] .challenge-card-foot {
    display: none;
}

.challenge-grid[data-density="Compact"] .challenge-card-jacket {
    aspect-ratio: 1 / 1;
}

.challenge-grid[data-density="Compact"] .challenge-count-chip {
    display: block;
}

/* Table renders jacket and bubble side by side (M19) — the tier-table pattern, never overlaid. */
.challenge-grid[data-density="Table"] {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.challenge-grid[data-density="Table"] .challenge-card {
    flex-direction: row;
    align-items: center;
    gap: 10px;
    padding: 6px 10px;
}

.challenge-grid[data-density="Table"] .challenge-card-jacket {
    width: 76px;
    aspect-ratio: 16 / 9;
    border-radius: 6px;
    flex: none;
}

.challenge-grid[data-density="Table"] .challenge-card-bubble {
    position: static;
    order: 1;
}

.challenge-grid[data-density="Table"] .challenge-card-body {
    flex-direction: row;
    align-items: center;
    gap: 14px;
    padding: 0;
    order: 2;
}

.challenge-grid[data-density="Table"] .challenge-card-name {
    width: 170px;
    flex: none;
    font-size: .92rem;
}

.challenge-grid[data-density="Table"] .challenge-card-line {
    flex: 1;
    background: none;
    box-shadow: none;
}

/* Table is top-1 + you: every visible-world row after the first hides unless it's yours. */
.challenge-grid[data-density="Table"]:not(.relevant-on)
.challenge-card-line.w-o:not(.mine) ~ .challenge-card-line.w-o:not(.mine) {
    display: none;
}

.challenge-grid[data-density="Table"].relevant-on
.challenge-card-line.w-r:not(.mine) ~ .challenge-card-line.w-r:not(.mine) {
    display: none;
}

.challenge-grid[data-density="Table"] .challenge-card-foot {
    border: 0;
    margin: 0;
    padding: 0;
    order: 3;
}

.challenge-poollink {
    color: var(--mix-ink-muted);
    font-size: 12.5px;
    margin-top: 8px;
}

/* ── The rail layout (§12.1, M14/M22): boards left in widget chrome, the grid right.
   The collapse ladder: ≥1080 rail-left · 640–1080 rail 2-up above the grid · <640 single
   column in fold order Daily → This Week → Monthly. ── */
.challenge-layout {
    display: grid;
    grid-template-columns: 330px minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-top: 12px;
}

.challenge-rail {
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
}

.challenge-main {
    min-width: 0;
}

@media (max-width: 1079.98px) {
    .challenge-layout {
        grid-template-columns: 1fr;
    }

    .challenge-rail {
        display: grid;
        grid-template-columns: 1fr 1fr;
        align-items: start;
    }
}

@media (max-width: 639.98px) {
    .challenge-layout {
        display: flex;
        flex-direction: column;
    }

    .challenge-rail {
        display: contents;
    }

    .challenge-railcard#daily {
        order: 0;
    }

    .challenge-main {
        order: 1;
    }

    .challenge-railcard#monthly {
        order: 2;
    }
}

/* ── Rail cards: the homepage dash-widget chrome. ── */
.challenge-railcard {
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .06);
    border-radius: 10px;
    padding: 12px 14px;
    min-width: 0;
}

.challenge-railcard.limbo {
    border-left: 3px solid var(--mix-secondary);
}

.challenge-railhead {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
}

.challenge-kicker {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.challenge-railchart {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 10px;
}

.challenge-rail-jacket {
    width: 44px;
    height: 44px;
    border-radius: 6px;
    background-size: cover;
    background-position: center;
    flex: none;
    display: block;
}

.challenge-railchart-id {
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.challenge-railchart-id .name {
    font-weight: 700;
    font-size: .98rem;
    color: var(--mix-ink);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.challenge-railchart-id .sub {
    font-size: .72rem;
    color: var(--mix-ink-muted);
}

.challenge-railsub {
    font-size: .72rem;
    color: var(--mix-ink-muted);
    margin: -4px 0 8px;
}

.challenge-railfoot {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    font-size: .74rem;
    color: var(--mix-ink-muted);
}

.challenge-ghostbtn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: .76rem;
    color: var(--mix-ink-muted);
    background: transparent;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 6px;
    padding: 4px 10px;
    cursor: pointer;
    transition: color .12s, border-color .12s;
}

.challenge-ghostbtn:hover {
    color: var(--mix-accent);
    border-color: var(--mix-accent);
}

/* ── Rail leaderboard rows: place · avatar · name · (CL) · value. ── */
.challenge-lb {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

/* The avatar lost its own track when UserLabel took it over: it now sits in the name cell so
   the country wash can run under both. */
.challenge-lb-row {
    display: grid;
    grid-template-columns: 24px minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 8px;
    padding: 4px 7px;
    border-radius: 7px;
    font-size: .83rem;
}

/* The row group is mix-invariant by design, so these read --daily-* like every other board
   rather than the per-mix brand colour they used to. The ladder now emits .is-rival/.is-both
   onto these same rows, and two greens (or two blues) for one meaning on one board is worse
   than a board whose you-row is not brand-coloured. */
.challenge-lb-row.mine {
    background: color-mix(in srgb, var(--daily-you) 15%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-you), inset -3px 0 0 var(--daily-you),
        0 0 12px -4px var(--daily-you);
}

.challenge-lb-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    color: var(--mix-ink);
}

.challenge-lb-total {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--mix-accent);
}

.challenge-lb-divider {
    font-size: .62rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    margin: 6px 2px 2px;
}

.challenge-avatar {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    object-fit: cover;
    display: block;
}

.challenge-cl {
    font-size: .68rem;
    color: var(--mix-ink-muted);
    background: var(--mix-surface-muted);
    border-radius: 4px;
    padding: 1px 5px;
    font-variant-numeric: tabular-nums;
}

.challenge-mboard[hidden] {
    display: none;
}

/* ── The title-progress pointer (Phoenix 2 tier lists): the one line left where the folder-title
   track used to draw its bar — a pointer at the PUMBILITY page, where titles are tracked now, and
   a × that hides it for good. Boxed the way the track's "behind your top 50" whisper was, so it
   sits on the page as a row rather than as floating text (owner, 2026-09-05). --mix-* only. ── */
.title-pointer {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 8px;
    /* Room above the box: without the context line it sat flush under the toolbar (field test). */
    margin: 10px 0 12px;
    padding: 5px 6px 5px 14px;
    min-height: 32px;
    font-size: 13.5px;
    color: var(--mix-ink-muted);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    background: color-mix(in srgb, var(--mix-surface) 55%, transparent);
    border-radius: 10px;
}

.title-pointer-ic {
    flex: none;
    color: var(--mix-ink-muted);
}

.title-pointer-link {
    color: var(--mix-primary);
    font-weight: 500;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-color: color-mix(in srgb, var(--mix-primary) 45%, transparent);
}

.title-pointer-link:hover {
    text-decoration-color: var(--mix-primary);
}

/* The × rides the far end of the row — a box has a far end. */
.title-pointer-x {
    margin-left: auto;
    color: var(--mix-ink-muted);
}

/* ── The tier-list segment row (M18): joined buttons, filled primary when active. ── */
.challenge-seg {
    display: inline-flex;
    margin-bottom: 10px;
}

.challenge-seg-btn {
    font-size: .74rem;
    font-weight: 600;
    border: 1px solid color-mix(in srgb, var(--mix-primary) 55%, transparent);
    background: transparent;
    color: var(--mix-primary);
    padding: 3px 12px;
    cursor: pointer;
    margin-left: -1px;
    transition: background .12s, color .12s;
}

.challenge-seg-btn:first-child {
    border-radius: 6px 0 0 6px;
    margin-left: 0;
}

.challenge-seg-btn:last-child {
    border-radius: 0 6px 6px 0;
}

.challenge-seg-btn:hover {
    background: color-mix(in srgb, var(--mix-primary) 14%, transparent);
}

.challenge-seg-btn.on {
    background: var(--mix-primary);
    color: var(--mix-primary-contrast);
}

/* ── The relevant-players switch (M20) — deliberately quiet. ── */
.challenge-switch {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: .72rem;
    color: var(--mix-ink-muted);
    cursor: pointer;
    user-select: none;
    opacity: .85;
}

.challenge-switch:hover {
    opacity: 1;
}

.challenge-switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.challenge-switch i {
    width: 30px;
    height: 16px;
    border-radius: 999px;
    background: var(--mix-surface-muted);
    border: 1px solid rgba(255, 255, 255, .14);
    position: relative;
    transition: background .12s;
    flex: none;
}

.challenge-switch i::after {
    content: "";
    position: absolute;
    top: 1px;
    left: 1px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--mix-ink-muted);
    transition: left .12s, background .12s;
}

.challenge-switch input:checked + i {
    background: color-mix(in srgb, var(--mix-primary) 45%, var(--mix-surface-muted));
}

.challenge-switch input:checked + i::after {
    left: 15px;
    background: var(--mix-primary);
}

.challenge-switch input:focus-visible + i {
    outline: 2px solid var(--mix-primary);
    outline-offset: 1px;
}

/* ── Field-test round 1 ── */

/* The show-all/show-suggested toggles are actions, not text. */
.challenge-filter-note a {
    cursor: pointer;
}

/* Grade art and the score numeral center on one line and never wrap mid-row. */
.challenge-card-line .score,
.challenge-lb-score {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    white-space: nowrap;
    justify-self: end;
}

.challenge-card-line .score .mud-typography,
.challenge-lb-score .mud-typography {
    vertical-align: baseline !important;
}

/* Card mini-boards rank with a literal #N — one quiet color, no rarity ramp (the colored
   1s read as meaning; the ramp stays on the big boards where percentile is real). */
.challenge-card-line .challenge-lb-place {
    color: var(--mix-ink-muted);
    font-size: 11px;
    text-align: right;
}

.challenge-card-line.mine .challenge-lb-place {
    color: var(--mix-ink);
}

/* Shared-community rows glow green (the homepage widgets' treatment), you glow blue. */
.challenge-lb-row.community,
.challenge-card-line.community {
    background: color-mix(in srgb, var(--daily-community) 13%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-community), inset -3px 0 0 var(--daily-community);
}

.challenge-monthly tr.community td {
    background: color-mix(in srgb, var(--daily-community) 10%, transparent);
}

.challenge-monthly tr.community td:first-child {
    box-shadow: inset 3px 0 0 var(--daily-community);
}

.challenge-monthly tr.community td:last-child {
    box-shadow: inset -3px 0 0 var(--daily-community);
}

/* UserLabel inside board rows: avatar + name on one truncating line. The gap matches the
   label's own, so a row that falls back to the standalone avatar ("You", a dead account)
   spaces its face exactly like the rows around it. */
.challenge-lb-name,
.challenge-card-line .who {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
    overflow: hidden;
}

/* Record dialog: score, live grade, and plate share a row; stacked again on narrow phones. */
.challenge-record-row {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
}

.challenge-iconbtn.rec:hover {
    color: var(--mix-primary);
    border-color: var(--mix-primary);
}

.challenge-iconbtn.tro:hover {
    color: var(--mix-accent);
    border-color: var(--mix-accent);
}

/* ── The monthly dialog's counted-score stickers (M21): the official-leaderboards compact
   pattern, board-sized — jacket, bubble, grade/score strip, points badge. No song names. ── */
.challenge-mrow-who {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.challenge-stik-row {
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
}

.challenge-stik-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: 6px;
    background: var(--mix-surface-muted);
    border-radius: 8px;
    padding: 10px;
    margin-top: 6px;
}

.challenge-stik {
    position: relative;
    display: block;
    width: 96px;
    aspect-ratio: 1 / 1;
    border-radius: 7px;
    overflow: hidden;
}

.challenge-stik-row .challenge-stik {
    width: 44px;
    aspect-ratio: 1 / 1;
}

.challenge-stik-row .challenge-stik .challenge-stik-line {
    display: none;
}

.challenge-stik-j {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
}

.challenge-stik-bubble {
    position: absolute;
    top: 4px;
    left: 4px;
    z-index: 2;
}

.challenge-stik-line {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    gap: 4px;
    background: color-mix(in srgb, var(--mix-bg) 85%, transparent);
    padding: 2px 5px;
    font-size: .64rem;
    z-index: 2;
}

.challenge-stik-line b {
    margin-left: auto;
    color: var(--mix-accent);
    font-variant-numeric: tabular-nums;
}

.challenge-poollink a {
    color: var(--mix-accent);
}

/* ---- monthly board -------------------------------------------------------- */
.challenge-monthly {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    min-width: 620px;
}

.challenge-monthly th {
    text-align: left;
    text-transform: uppercase;
    letter-spacing: .05em;
    font-size: 12px;
    color: var(--mix-ink-muted);
    padding: 6px 10px;
    border-bottom: 1px solid rgba(255, 255, 255, .12);
    background: var(--mix-surface);
}

.challenge-monthly td {
    padding: 5px 10px;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
    vertical-align: middle;
}

.challenge-monthly tr:last-child td {
    border-bottom: 0;
}

.challenge-monthly tr.mine td {
    background: color-mix(in srgb, var(--daily-you) 10%, transparent);
}

.challenge-monthly tr.mine td:first-child {
    box-shadow: inset 3px 0 0 var(--daily-you);
}

.challenge-monthly tr.mine td:last-child {
    box-shadow: inset -3px 0 0 var(--daily-you);
}

.challenge-mono-place {
    font-weight: 700;
    font-size: 15px;
}

.challenge-total {
    font-weight: 700;
    font-size: 15px;
    color: var(--mix-accent);
}

.challenge-expand > summary {
    cursor: pointer;
    color: var(--mix-primary);
    list-style: none;
}

.challenge-expand > summary::-webkit-details-marker {
    display: none;
}

.challenge-expand > summary::after {
    content: " \25B8";
}

.challenge-expand[open] > summary::after {
    content: " \25BE";
}

.challenge-expand-body {
    display: flex;
    gap: 7px;
    flex-wrap: wrap;
    padding: 7px 2px 2px;
}

/* ---- daily history -------------------------------------------------------- */
.challenge-history {
    display: flex;
    flex-direction: column;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 9px;
    overflow: hidden;
}

.challenge-hist-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 5px 12px;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
    font-size: 13px;
    background: var(--mix-surface);
}

.challenge-hist-row:nth-child(even) {
    background: var(--mix-surface-muted);
}

.challenge-hist-row:last-child {
    border-bottom: 0;
}

.challenge-hist-date {
    color: var(--mix-ink-muted);
    min-width: 58px;
}

.challenge-hist-chart {
    display: flex;
    align-items: center;
    gap: 7px;
    flex: 1;
    min-width: 0;
}

.challenge-hist-chart a {
    color: var(--mix-ink);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.challenge-limbo-tag {
    background: var(--mix-secondary);
    color: var(--mix-bg);
    font-size: 9.5px;
    font-weight: 700;
    border-radius: 3px;
    padding: 0 5px;
    text-transform: uppercase;
}

.challenge-hist-place {
    min-width: 74px;
    text-align: right;
}

.challenge-hist-score {
    min-width: 118px;
    display: flex;
    justify-content: flex-end;
}

/* ---- legend --------------------------------------------------------------- */
.challenge-legend {
    display: flex;
    gap: 24px;
    flex-wrap: wrap;
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 9px;
    padding: 12px 15px;
}

.challenge-legend h3 {
    margin: 0 0 6px;
    font-size: 1rem;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    letter-spacing: .06em;
}

.challenge-ladder {
    display: grid;
    grid-template-columns: auto auto;
    gap: 1px 14px;
    font-size: 13px;
    align-items: center;
}

.challenge-rules {
    max-width: 42ch;
    color: var(--mix-ink-muted);
    font-size: 12.5px;
    margin: 0;
    padding-left: 18px;
}

.challenge-rules li {
    margin-bottom: 4px;
}

/* ---- mobile dock (jump links + reset countdown) --------------------------- */
.challenge-dock {
    display: flex;
    gap: 14px;
    align-items: center;
    font-size: 13px;
}

.challenge-dock a {
    color: var(--mix-ink);
    text-decoration: none;
    text-transform: uppercase;
}

.challenge-dock .reset {
    margin-left: auto;
    color: var(--mix-ink-muted);
    font-size: 12px;
}

/* /UploadPhoenixScores - the manual-import expander's numbered steps. */
.import-manual-steps {
    margin: 0;
    padding-left: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* ============================================================
   The 404 page - "your path was a MISS" (Pages/NotFound.razor).
   The title-screen image is the hero; the judgment slams over
   its lower edge like the in-game MISS flash. Judgment red is
   semantic (a judgment, not the mix accent); the credit counter
   mirrors the arcade credit line in the source frame.
   ============================================================ */
.nf-eyebrow {
    text-align: center;
    font-size: .68rem;
    letter-spacing: .22em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    margin: 28px 0 14px;
}

.nf-stage {
    position: relative;
    max-width: 860px;
    margin: 0 auto;
}

.nf-frame {
    display: block;
    width: 100%;
    border-radius: 10px;
    box-shadow: 0 30px 80px -20px rgba(196, 15, 61, .45);
}

.nf-judgment {
    position: relative;
    /* Only the MISS's top ~20% rides over the frame — any deeper covers the title text. */
    margin-top: clamp(-26px, -3vw, -12px);
    text-align: center;
    pointer-events: none;
}

.nf-miss {
    display: block;
    font-family: Impact, "Arial Black", sans-serif;
    font-style: italic;
    font-size: clamp(4.2rem, 15vw, 8.5rem);
    line-height: .92;
    letter-spacing: .04em;
    transform: skewX(-8deg) rotate(-2deg);
    background: linear-gradient(180deg, #ff8f9f 4%, #ff2f4e 42%, #a30822 96%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    filter: drop-shadow(0 0 22px rgba(255, 47, 78, .55)) drop-shadow(0 6px 0 rgba(20, 2, 8, .9));
}

@media (prefers-reduced-motion: no-preference) {
    .nf-miss {
        animation: nf-slam .34s cubic-bezier(.2, 1.6, .35, 1) .18s both;
    }

    @keyframes nf-slam {
        0% { opacity: 0; transform: skewX(-8deg) rotate(-2deg) scale(1.9); }
        70% { opacity: 1; transform: skewX(-8deg) rotate(-2deg) scale(.96); }
        100% { opacity: 1; transform: skewX(-8deg) rotate(-2deg) scale(1); }
    }
}

.nf-explain {
    max-width: 46ch;
    margin: 18px auto 0;
    text-align: center;
    color: var(--mix-ink-muted);
    font-size: .95rem;
    line-height: 1.55;
    text-wrap: balance;
}

.nf-actions {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 26px;
}

.nf-credit {
    margin: clamp(36px, 7vh, 64px) 0 24px;
    text-align: center;
    font-family: Consolas, "Courier New", monospace;
    font-size: .8rem;
    letter-spacing: .3em;
    color: #ffd94d;
    text-shadow: 0 0 12px rgba(255, 217, 77, .35);
}

/* ===== Charts SRP (docs/design/charts-srp.md) ================================
   The page stack: header (title + scope) → query chips → answer line → results.
   Tokens only — the two ramps and --mix-* carry every color. */
.srp-head {
    display: flex;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

.srp-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    min-height: 34px;
}

/* An applied-filter token is dismissed occasionally rather than hunted for, so it sits a
   little under the drawer chips' 40px — but its ✕ is still a real target, not a 16px icon. */
.srp-chip {
    min-height: 36px;
    font-size: .8rem;
}

    .srp-chip .mud-chip-close-button {
        width: 28px;
        height: 28px;
        margin-left: 2px;
    }

        .srp-chip .mud-chip-close-button .mud-icon-root {
            font-size: 1.1rem;
        }

.srp-chip-sort {
    border-color: var(--mix-accent) !important;
}

/* The count and the controls. Six targets plus the count are wider than a phone, so the
   row wraps — the controls stay one block, right-aligned, and drop to their own line
   rather than pushing the page sideways. */
.srp-answer {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 4px 0 12px;
}

.srp-answer-controls {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
}

.srp-count {
    font-variant-numeric: tabular-nums;
}

.srp-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
    gap: 12px;
}

.srp-pager {
    display: flex;
    justify-content: center;
    margin: 18px 0 8px;
}

.srp-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 48px 0;
    color: var(--mix-ink-muted);
}

/* min-width:0 is load-bearing, not tidying. A grid item's automatic minimum size is its
   MIN-CONTENT width, and the card's title is `nowrap` — so one long song name ("Extreme
   Music School 2nd period feat. Nanahira", 482px) floored the whole column at its width,
   stretched every other card to match, and scrolled the page sideways. Letting the card
   shrink is also what lets the title's ellipsis do its job. */
.srp-card {
    position: relative;
    display: flex;
    min-width: 0;
    gap: 12px;
    background: var(--mix-surface);
    border: 1px solid var(--mix-surface-muted);
    border-radius: 10px;
    padding: 12px;
    transition: border-color .15s, box-shadow .15s;
}

.srp-card:hover,
.srp-card:focus-within {
    border-color: var(--mix-primary);
    box-shadow: 0 0 14px var(--mix-glow);
}

.srp-card-link {
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: 10px;
}

.srp-card-art {
    flex: 0 0 auto;
}

.srp-card-main {
    flex: 1;
    min-width: 0;
}

.srp-card-title {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.srp-card-song {
    font-weight: 600;
    font-size: 1.05rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.srp-card-songtype {
    font-size: .7rem;
    color: var(--mix-ink-muted);
    white-space: nowrap;
}

.srp-card-artist {
    font-size: .75rem;
    color: var(--mix-ink-muted);
}

.srp-card-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 6px;
    align-items: center;
}

.srp-card-tier {
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .03em;
    border: 1px solid;
    border-radius: 5px;
    padding: 1px 7px;
    white-space: nowrap;
}

.srp-card-facts {
    margin-top: 7px;
    font-size: .72rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    display: flex;
    flex-wrap: wrap;
    gap: 3px 10px;
}

.srp-card-fact-lead {
    color: var(--mix-ink);
    font-weight: 600;
}

.srp-card-my {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 3px;
    min-width: 70px;
    text-align: right;
}

.srp-card-unplayed {
    font-size: .7rem;
    color: var(--mix-ink-muted);
    border: 1px dashed var(--mix-surface-muted);
    border-radius: 4px;
    padding: 2px 7px;
}

.srp-card-plate {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .05em;
}

.srp-card-score {
    font-size: .75rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.srp-card-actions {
    position: absolute;
    right: 8px;
    bottom: 6px;
    z-index: 2;
    display: flex;
    gap: 2px;
}

.srp-drawer {
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.srp-drawer-head {
    display: flex;
    align-items: center;
}

.srp-drawer-range {
    display: flex;
    gap: 10px;
}

/* The bottom way out, separated from the last facet so it doesn't read as one more
   filter. */
.srp-drawer-foot {
    border-top: 1px solid var(--mix-surface-muted);
    padding-top: 12px;
}

@media (max-width: 600px) {
    /* minmax(0, …), not a bare 1fr: `1fr` is minmax(auto, 1fr) and that `auto` floors the
       track at the widest card's min-content, which is how the one-column phone layout
       ended up wider than the phone. */
    .srp-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .srp-head {
        gap: 12px;
    }
}

/* The bottom nav outranks the drawer, so the drawer's close button has to clear it —
   only where the nav exists (the same Md seam the shell uses). */
@media (max-width: 959.98px) {
    .srp-drawer-foot {
        padding-bottom: calc(var(--bottom-nav-h) + 12px);
    }
}

/* SRP card state borders — the tier lists' owner-locked language */
.srp-card-pass {
    border-color: var(--mud-palette-success);
}

.srp-card-todo {
    border-style: dashed;
    border-color: var(--mud-palette-info);
}

.srp-head-mix {
    color: var(--mix-ink-muted);
    font-size: .9rem;
    letter-spacing: .04em;
    text-transform: uppercase;
}

/* SRP drawer: badge cloud + switch rows */
.srp-drawer-sub {
    font-size: .65rem;
    color: var(--mix-ink-muted);
    text-transform: none;
    letter-spacing: 0;
}

.srp-badge-cloud {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* Skill tags borrow the tier list's chip, which is sized to sit quietly on a card. Here
   each one is something you tap, so the SRP's copy takes the same 40px target as the
   other filter chips while keeping the category tint. */
.srp-badge-opt {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    padding: 0 12px;
    font-size: .8rem;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    cursor: pointer;
    opacity: .75;
}

.srp-badge-opt:hover,
.srp-badge-opt:focus-visible {
    opacity: 1;
}

.srp-badge-opt-sel {
    opacity: 1;
    outline: 1px solid var(--mix-primary);
}

.srp-card-stepartist {
    color: var(--mix-ink-muted);
}

/* SRP export dialog */
.srp-export {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.srp-export-count {
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.srp-export-columns {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
}

.srp-export-grp {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.srp-export-all {
    background: none;
    border: 0;
    padding: 2px 4px;
    font: inherit;
    font-size: .72rem;
    color: var(--mix-primary);
    cursor: pointer;
}

.srp-export-all:hover,
.srp-export-all:focus-visible {
    text-decoration: underline;
}

/* A bundle chip wears the ordinary chip. Its multiplier is what says it is worth many
   columns, and that reads without a second visual language on top. */
.srp-export-mult {
    margin-left: 7px;
    font-size: .74rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.srp-export-unstable {
    color: var(--mix-ink-muted);
    border-top: 1px dashed var(--mix-surface-muted);
    padding-top: 7px;
}

.srp-export-hint {
    color: var(--mix-ink-muted);
}

.srp-export-file {
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    border-top: 1px solid var(--mix-surface-muted);
    padding-top: 8px;
}

/* The shared table shell: the tier lists' table density and the chart SRP's both render
   it, so it lives here rather than in either page. The wrap is what side-scrolls — a
   ten-column table on a phone must move inside its own box, never take the page with it. */
.tier-table-wrap {
    overflow-x: auto;
    max-width: 100%;
}

.tier-table {
    width: 100%;
    border-collapse: collapse;
}

.tier-table th {
    text-align: left;
    color: var(--mud-palette-text-secondary);
    font-size: .75rem;
    padding: 4px 8px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.tier-table td {
    padding: 4px 8px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

/* SRP densities: sticker sheet + table. The sheet itself is the tier lists'
   .tier-card-grid.tier-card-grid-compact — the tiles take their width from that grid. */
.srp-table .srp-th-sortable {
    cursor: pointer;
    white-space: nowrap;
}

.srp-table .srp-th-sorted {
    color: var(--mix-ink);
    border-bottom: 2px solid var(--mix-accent);
}

.srp-table-link {
    color: var(--mix-ink);
    font-weight: 600;
}

.srp-table-link:hover {
    color: var(--mix-primary);
}

.srp-table-muted {
    color: var(--mix-ink-muted);
}

.srp-table-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* SRP drawer facets: chip sets, range-slider headers, debut-mix eras */
.srp-facet {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.srp-facet-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: .75rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.srp-facet-value {
    text-transform: none;
    letter-spacing: 0;
    color: var(--mix-ink);
    font-variant-numeric: tabular-nums;
}

.srp-chipset {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.srp-chipset-sub {
    padding-left: 10px;
    border-left: 2px solid var(--mix-surface-muted);
}

/* A filter chip is the drawer's primary control, and a thumb is about 9mm wide: these
   sit at the 40px target rather than the 22px the type alone would give them. The
   drawer is 420px, so a row still fits two or three of the longest names. */
.srp-facet-chip {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
    font-size: .85rem;
    border: 1px solid var(--mix-surface-muted);
    border-radius: 999px;
    padding: 0 14px;
    color: var(--mix-ink-muted);
    cursor: pointer;
    white-space: nowrap;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    transition: border-color .12s, color .12s, background-color .12s;
}

.srp-facet-chip:hover,
.srp-facet-chip:focus-visible {
    color: var(--mix-ink);
    border-color: var(--mix-primary);
}

/* A plate chip wears its own plate colour, so the row reads as the plate ladder it is rather
   than five identical pills. --plate-chip is set inline from ThemeScales.PlateColor. */
.srp-facet-chip[style*="--plate-chip"] {
    color: color-mix(in srgb, var(--plate-chip) 62%, var(--mix-ink));
    border-color: color-mix(in srgb, var(--plate-chip) 50%, transparent);
}

    .srp-facet-chip[style*="--plate-chip"].srp-facet-chip-on {
        color: var(--mix-primary-contrast);
        background: var(--plate-chip);
        border-color: var(--plate-chip);
    }

.srp-facet-chip-on {
    color: var(--mix-primary-contrast);
    background: var(--mix-primary);
    border-color: var(--mix-primary);
    font-weight: 600;
}

/* The through select sits at the facet head's right edge and drops to its own line when
   the drawer is too narrow for both; the buttons beside it are text, not chips, because
   they act on the row rather than picking a value. */
.srp-facet-head-version {
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 8px 12px;
}

.srp-through {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
    text-transform: none;
    letter-spacing: 0;
}

.srp-through-select {
    max-width: 180px;
    background: var(--mix-surface);
    color: var(--mix-ink);
    border: 1px solid var(--mix-surface-muted);
    border-radius: 8px;
    padding: 6px 8px;
    font: inherit;
    font-size: .85rem;
}

.srp-through-btn {
    background: none;
    border: none;
    color: var(--mix-secondary);
    cursor: pointer;
    font: inherit;
    font-size: .8rem;
    padding: 2px 4px;
}

.srp-through-btn:hover,
.srp-through-btn:focus-visible {
    color: var(--mix-ink);
    outline: none;
}

.srp-era {
    margin-top: 6px;
}

.srp-era-name {
    font-size: .68rem;
    color: var(--mix-ink-muted);
    margin-bottom: 3px;
}

/* ── The leaderboard skin ─────────────────────────────────────────────────────
   The Official Leaderboards rankings board is the golden standard for every
   ranked collection on the site, so its vocabulary lives here rather than in
   the section's own <style> block: the Communities boards wear the same look.
   Names keep their olb- prefix — the Official pages and the E2E suite pin them. */

/* Rankings and chart boards render as compact card rows, never tables — a phone
   reads rank, player, and rating with zero side-scrolling (UX rule: tabular
   collections lean compact). */
.olb-rank-card, .olb-board-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 8px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    flex-wrap: wrap;
}

.olb-rank-rankbox { min-width: 52px; display: inline-flex; align-items: center; gap: 4px; }

/* Mud chips ship 4px of margin — inside a row that is already budgeting every
   pixel, that reads as a misalignment rather than as spacing. */
.olb-rank-card .mud-chip { margin: 0; }

.olb-board-place { min-width: 40px; font-weight: 700; }

.olb-rank-tail {
    margin-left: auto; flex: 0 0 auto;
    display: flex; align-items: center; justify-content: flex-end; gap: 8px;
}

.olb-rank-expand { padding: 4px 0 10px; }

/* The column variant of the same row. A board carrying several figures per player
   reads as a pile when every figure is flush right, so the figures spread into
   their own columns instead: the owning page supplies the template in
   --olb-grid-cols (and --olb-grid-cols-narrow for the width where its optional
   columns drop out), and the identity column stays pinned left. */
.olb-grid-row, .olb-grid-head {
    display: grid;
    grid-template-columns: var(--olb-grid-cols);
    align-items: center;
    gap: 8px;
    padding: 4px 8px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
}

.olb-grid-row .mud-chip { margin: 0; }

/* Column names, in the table-head voice the sortable boards already use. The header
   is the row template with labels in it, so it drops the same columns at the same
   widths; a label that outruns its column clips rather than reflowing the row. */
.olb-grid-head {
    color: var(--mix-ink-muted);
    font-size: 11.5px;
    letter-spacing: .4px;
    text-transform: uppercase;
    line-height: 1.25;
}

.olb-grid-head span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Figures are read down a column, so they align on their right edge. */
.olb-grid-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    display: inline-flex;
    align-items: center;
    justify-content: flex-end;
    gap: 2px;
}

/* Competitive level and PUMBILITY are two ordinary grid columns, never stacked (owner
   call) — the wrapper is display:contents so its two children sit in the template's cells
   directly, at every width. */
.olb-stack { display: contents; }

/* A label that has a short form: the long one until the row runs out of width. */
.olb-short-form { display: none; }

/* Board tags run long (LIKEASLAM01#8073). Lists print the human half — the digits
   identify an account, they don't name anyone — and truncate what's still too long;
   the full tag stays in the row's tooltip and on the player's own page. */
/* The flag is atomic and the name is what gives: a UserLabel truncated as one box
   spends the width on the flag and prints a bare "…", so the label lays out as a
   flex row whose last child — the name — is the only part allowed to shrink.
   min-width:0 is what permits that shrink; without it the text keeps its full
   width and the ellipsis swallows the whole name. */
.olb-player-name {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    vertical-align: middle;
    min-width: 0;
    max-width: 22ch;
    overflow: hidden;
}

.olb-player-name > :not(:last-child) { flex: 0 0 auto; }

.olb-player-name > :last-child {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
}

/* Every UserLabel, everywhere: optional avatar then name, laid out so a bounded caller
   truncates the NAME. max-width keeps the label inside its container instead of overflowing
   as one atomic box — an overflowing atomic box is replaced wholesale by the container's
   ellipsis, which is how a flagged player used to render as a bare "…". */
.user-label {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    vertical-align: middle;
    min-width: 0;
    max-width: 100%;
    position: relative;
    isolation: isolate;
}

/* The avatar sat in the row's own grid track before the wash moved it in here, where the
   gap between it and the name is the label's rather than the row's. The wash starts where
   the avatar ends: a face is already a picture, and a flag washed under one reads as a
   printing error rather than as a country. 4px of the 7px gap is lead-in. */
.user-label.has-avatar {
    gap: 7px;
    --label-wash-left: calc(var(--label-avatar-size, 20px) + 4px);
}

.user-label > :not(:last-child) { flex: 0 0 auto; }

.user-label > :last-child {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
}

/* The label reserves the room its own wash needs. An absolutely positioned pseudo-element
   contributes nothing to its parent's width, and most boards wrap the label in a shrink-to-fit
   `overflow: hidden` box (`.olb-player-name` is `inline-flex`, so it is exactly as wide as
   avatar + name) — so a flag drawn wider than the name was clipped straight back to the name's
   edge and every board rendered as though the flag were still name-sized. That is not a
   caller's bug to fix: a component owns its own narrow-width behaviour (UX rule 3), so the
   label states the width the wash occupies and the wrapper shrink-wraps around it.
   The wash is (label height + 6px) tall at 11:7, and the label is as tall as the avatar or one
   line of the name, whichever wins. This only ever binds on a name SHORTER than its flag —
   a longer name is already wider than this and the min-width is inert — so it can never steal
   room from a name that needed it. */
.user-label.has-flag {
    --label-wash-h: calc(max(var(--label-avatar-size, 0px), 1lh) + 6px);
    min-width: calc(var(--label-wash-left, -6px) + var(--label-wash-h) * 11 / 7);
}

/* The country wash. The flag paints behind the NAME — never under the avatar, which is a
   picture already — at its own aspect, so it reads as the player's country rather than as a
   band of colour across the row. isolation on the label is what keeps a
   z-index of -1 from sinking past the row's background: the label is its own stacking
   context, so -1 means behind the label's contents, not behind the board. The URL arrives as
   --label-flag on the element because only the component knows it — the port is what
   resolves a country to an image. */
.user-label.has-flag::before {
    content: "";
    position: absolute;
    top: -3px;
    bottom: -3px;
    left: var(--label-wash-left, -6px);
    /* The box is the FLAG, not the name: the row gives it its height and the flag's own 11:7
       gives it its width — every country PNG is 22x14 — so a two-letter name and a
       twenty-letter one carry the same flag. Bounded by both edges instead, as it was, a short
       name squeezed the box below the flag's full-height width and `contain` shrank the flag to
       fit it: the country ended early and sat short of the row (owner, field test 4: "the
       underlying flags for usernames are cutting off early if the name is short. we should have
       flag be full width regardless of username length"). `right` stays auto — that is what
       lets the width come from the ratio rather than from the name. A short name now carries a
       flag wider than itself, which the bounded callers clip at their column edge. */
    aspect-ratio: 11 / 7;
    z-index: -1;
    border-radius: 6px;
    background-image: var(--label-flag);
    background-position: left center;
    /* contain, never cover: a flag has to keep its own proportions to read as that country at
       all (owner, field test 2: "we shouldn't stretch the flags, just let them be their natural
       aspect ratio"), and cover scales one until it fills the box, cropping away everything but
       a blown-up horizontal slice — Germany a red bar, Japan a white one. The box carries the
       flag's ratio itself now, so contain fills it exactly; it stays contain so a country that
       ever ships at another shape letterboxes rather than stretches. */
    background-size: contain;
    background-repeat: no-repeat;
    /* A third of a flag over a dark board is a smudge you have to be told about (owner, field
       test 1: "definitely too transparent"). Half-plus is the level where a country reads at
       a glance and the name still wins the contrast, which the shadow below guarantees. */
    opacity: .55;
    pointer-events: none;
}

/* A white-heavy flag (Japan, and Korea, which is the most common country on the site) washes
   to a pale ground that a light name disappears into, and at better than half opacity that is
   a real mid-grey rather than a tint — the shadow is what keeps the name readable over every
   flag rather than most, so it is sized for the worst one. */
.user-label.has-flag .user-label-name { text-shadow: 0 1px 3px rgba(0, 0, 0, .8); }

/* Every avatar on the site is a circle. The community rankings' was the one square left, from
   the MudImage it used before the label owned it, and one board wearing a different face shape
   read as a bug rather than as a variation. Only the size is still the caller's. */
.user-label-avatar {
    width: var(--label-avatar-size, 20px);
    height: var(--label-avatar-size, 20px);
    border-radius: 50%;
    object-fit: cover;
}

/* Inline-block, not block: this rule reaches every UserLabel on the site, and the
   label sits inline in most of them. It only truncates where a caller has bounded
   the width. */
.user-label-name {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
}

/* A "50× <grade art>" column head: the multiplier and the letter picture read as one
   token, so they never wrap apart. */
.olb-tier-head {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    white-space: nowrap;
}

.olb-delta-up { color: var(--mix-primary); font-weight: 700; }

.olb-delta-down { color: var(--mix-accent); font-weight: 700; }

.olb-delta-flat { color: var(--mix-ink-muted); }

/* The leaderboard skin for the collections that need real table semantics
   (sortable columns): same flat surface, hairlines, and row rhythm as the
   rankings cards — the site's one leaderboard look. */
.olb-board-table.mud-table { background: transparent; }

.olb-board-table .mud-table-cell {
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    padding: 4px 8px;
}

.olb-board-table .mud-table-head .mud-table-cell {
    color: var(--mix-ink-muted);
    font-size: 11.5px;
    letter-spacing: .4px;
    text-transform: uppercase;
}

.olb-board-table .mud-table-body .mud-table-row:hover .mud-table-cell {
    background: color-mix(in srgb, var(--mix-ink) 5%, transparent);
}

/* A supplemented row: one whose score came from a linked player's own ledger rather
   than from piugame. Deliberately a rail and a chip, never a background tint — the
   same row can also be YOUR row or a community row, and those own the background.
   Marking it any other way would mean choosing which fact to hide. */
.olb-row-supp {
    border-left: 2px dashed var(--mix-secondary);
    padding-left: 6px;
}

.olb-supp-chip {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 10px;
    letter-spacing: .07em;
    text-transform: uppercase;
    padding: 1px 6px;
    border-radius: 3px;
    white-space: nowrap;
    color: var(--mix-secondary);
    border: 1px solid color-mix(in srgb, var(--mix-secondary) 50%, transparent);
    background: color-mix(in srgb, var(--mix-secondary) 12%, transparent);
}

.olb-board-table tr.olb-row-supp td:first-child {
    border-left: 2px dashed var(--mix-secondary);
}

/* The rail, explained next to the table it marks. The swatch is the same dashed border on
   the same token as .olb-row-supp, so the key cannot drift from the thing it describes. */
.olb-supp-legend {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 6px 0 10px;
    font-size: .8rem;
    color: var(--mix-ink-muted);
}

.olb-supp-legend-rail {
    flex: 0 0 auto;
    width: 0;
    height: 16px;
    border-left: 2px dashed var(--mix-secondary);
}

/* A note the supplemented reading pins above a board it cannot change. */
.olb-reading-note {
    display: flex;
    gap: 9px;
    align-items: flex-start;
    padding: 9px 12px;
    border-radius: 7px;
    margin-bottom: 14px;
    font-size: .875rem;
    line-height: 1.45;
    color: var(--mix-ink);
    background: color-mix(in srgb, var(--mix-secondary) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--mix-secondary) 34%, transparent);
}

.olb-reading-note .mud-icon-root { color: var(--mix-secondary); flex: 0 0 auto; }

/* Row glow: the dashboard vocabulary — you blue, your opt-in crews green. */
.olb-row-me {
    background: color-mix(in srgb, var(--daily-you) 15%, transparent);
    box-shadow: inset 0 0 0 1.5px var(--daily-you);
    border-radius: 6px;
}

.olb-row-community {
    background: color-mix(in srgb, var(--daily-community) 13%, transparent);
    box-shadow: inset 3px 0 0 var(--daily-community), inset -3px 0 0 var(--daily-community);
    border-radius: 6px;
}

/* A board sheds width one column at a time: at 760 the sortable-table variant pins its
   row identifier while the rest side-scrolls and song titles step aside; the community
   grid then drops its play count at 600 and its playstyle chip at 500 (see those blocks
   below); at 500 the compact card rows tighten padding and long labels fall back to their
   short forms. Figures never stack — every value keeps its own column. */
@media (max-width: 760px) {
    .olb-hide-mobile { display: none !important; }

    .olb-song-text { display: none; }

    .olb-player-name { max-width: 16ch; }

    .olb-sticky-first td:first-child, .olb-sticky-first th:first-child {
        position: sticky;
        left: 0;
        z-index: 2;
        background: var(--mix-surface);
        max-width: 200px;
        overflow: hidden;
    }

    .olb-sticky-first td:first-child .mud-typography {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .olb-pager-tight .mud-table-pagination { padding-inline: 2px; }

    .olb-pager-tight .mud-table-pagination-caption { font-size: 11px; margin: 0 4px; }
}

/* The community grid sheds whole columns, never stacking its figures: at 600 the play
   count drops, at 500 the playstyle chip drops (no initials fallback — owner call). The
   header, built from the same template, loses the same columns at the same widths. */
@media (max-width: 600px) {
    .olb-grid-row, .olb-grid-head {
        grid-template-columns: var(--olb-grid-cols-600, var(--olb-grid-cols));
        gap: 6px;
        padding: 3px 4px;
    }

    /* Columns size to their content now, so the header sets smaller to not out-widen a figure. */
    .olb-grid-head { font-size: 10px; letter-spacing: .2px; }

    .olb-hide-narrow { display: none !important; }
}

@media (max-width: 500px) {
    .olb-grid-row, .olb-grid-head {
        grid-template-columns: var(--olb-grid-cols-500, var(--olb-grid-cols-600, var(--olb-grid-cols)));
    }

    .olb-hide-phone { display: none !important; }

    .olb-long-form { display: none; }

    .olb-short-form { display: inline; }

    .olb-rank-card, .olb-board-row { gap: 5px; padding: 3px 4px; }

    .olb-rank-rankbox { min-width: 42px; }

    .olb-rank-card .mud-chip {
        height: 20px;
        padding: 0 7px;
        font-size: 10.5px;
    }

    .olb-rank-card .mud-icon-button { padding: 2px; }

    .olb-first-tail, .olb-hero-listtail, .olb-rank-tail {
        flex-direction: column;
        align-items: flex-end;
        gap: 0;
    }
}

/* ============================================================================
   Life Calculator (/LifeCalculator) — docs/design/life-calculator-redesign.md
   The lifebar is the page's hero instrument: the visible bar (0-1000, the
   rainbow) and the overflow above it, drawn to true proportion.
   ============================================================================ */

.lc-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 18px 24px;
    flex-wrap: wrap;
    padding-bottom: 16px;
}

.lc-sub {
    margin: 7px 0 0;
    max-width: 56ch;
    color: var(--mix-ink-muted);
    font-size: .95rem;
    line-height: 1.5;
}

.lc-eyebrow {
    display: block;
    font-size: .68rem;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    font-weight: 600;
}

.lc-provenance {
    background: none;
    border: 1px solid color-mix(in srgb, var(--mix-accent) 45%, transparent);
    color: var(--mix-accent);
    border-radius: 2px;
    padding: 4px 9px;
    font: 600 .66rem/1.3 var(--font-body);
    letter-spacing: .09em;
    text-transform: uppercase;
    cursor: pointer;
    white-space: nowrap;
}

.lc-provenance-body {
    margin: 10px 0 0;
    padding: 10px 13px;
    border-left: 2px solid var(--mix-accent);
    background: var(--mix-surface);
    font-size: .85rem;
    line-height: 1.55;
    color: var(--mix-ink-muted);
    max-width: 74ch;
}

/* ---------- the bench ---------- */
.lc-bench {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
    border-radius: 3px;
    padding: 18px 20px 20px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 232px;
    gap: 22px 26px;
}

.lc-bench-main {
    min-width: 0;
}

.lc-bench-head {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 12px 18px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}

.lc-level {
    display: flex;
    align-items: center;
    gap: 12px;
}

.lc-level-value {
    font-family: var(--font-display);
    font-size: 1.9rem;
    line-height: 1;
    font-weight: 700;
    min-width: 2.1ch;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.lc-level input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    width: clamp(120px, 20vw, 210px);
    height: 3px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--mix-ink) 18%, transparent);
    cursor: pointer;
}

.lc-level input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--mix-primary);
    border: none;
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--mix-primary) 22%, transparent);
    cursor: pointer;
}

.lc-level input[type="range"]::-moz-range-thumb {
    width: 15px;
    height: 15px;
    border: none;
    border-radius: 50%;
    background: var(--mix-primary);
}

/* ---------- the readout ---------- */
.lc-readout {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.lc-life {
    font-family: var(--font-display);
    font-size: clamp(2.2rem, 6vw, 3.3rem);
    font-weight: 700;
    line-height: .95;
    font-variant-numeric: tabular-nums;
}

.lc-life-max {
    font-size: .95rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.lc-state {
    margin-left: auto;
    font-family: var(--font-display);
    font-size: .95rem;
    letter-spacing: .11em;
    text-transform: uppercase;
    padding: 2px 9px;
    border-radius: 2px;
}

.lc-state[data-state="overflow-full"] {
    color: var(--life-overflow);
    background: color-mix(in srgb, var(--life-overflow) 15%, transparent);
}

.lc-state[data-state="into-overflow"] {
    color: var(--life-r7);
    background: color-mix(in srgb, var(--life-r7) 15%, transparent);
}

.lc-state[data-state="ok"] {
    color: var(--mix-ink-muted);
    background: color-mix(in srgb, var(--mix-ink) 8%, transparent);
}

.lc-state[data-state="danger"] {
    color: var(--life-danger);
    background: color-mix(in srgb, var(--life-danger) 16%, transparent);
}

.lc-state[data-state="dead"] {
    color: var(--mix-bg);
    background: var(--life-danger);
}

/* ---------- the bar ---------- */
.lc-zones {
    display: flex;
    gap: 2px;
    margin-bottom: 5px;
}

.lc-zone-cap {
    font-size: .62rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 16%, transparent);
    padding-top: 3px;
}

.lc-zone-cap b {
    color: var(--mix-ink);
    font-variant-numeric: tabular-nums;
}

.lc-zone-cap-overflow {
    border-top-color: color-mix(in srgb, var(--life-overflow) 42%, transparent);
    text-align: right;
}

.lc-track {
    position: relative;
    display: flex;
    gap: 2px;
    height: 52px;
    background: var(--mix-bg);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    padding: 3px;
    border-radius: 2px;
}

.lc-zone {
    position: relative;
    overflow: hidden;
    min-width: 2px;
}

.lc-zone::before {
    content: "";
    position: absolute;
    inset: 0;
    opacity: .1;
}

.lc-zone-visible::before {
    background: var(--life-rainbow);
}

.lc-zone-overflow::before {
    background: var(--life-overflow);
}

/* A multi-note press sweeps rather than snapping. The durations ride custom
   properties the page sets inline, so a x50 press can take longer than a x1 —
   pure CSS, which is what keeps it free on a server circuit. The two zones run in
   SEQUENCE, not together: gaining, the visible bar fills before the overflow starts;
   draining, the overflow empties first. Life crosses the zones in that order. */
.lc-fill {
    position: absolute;
    inset: 0;
}

.lc-fill-visible {
    background: var(--life-rainbow);
    transition: clip-path var(--lc-vis-sweep, .13s) linear var(--lc-vis-delay, 0s);
}

.lc-fill-overflow {
    background:
        repeating-linear-gradient(115deg, transparent 0 5px, color-mix(in srgb, var(--mix-bg) 55%, transparent) 5px 8px),
        linear-gradient(90deg, color-mix(in srgb, var(--life-overflow) 62%, transparent), var(--life-overflow));
    transition: clip-path var(--lc-overflow-sweep, .13s) linear var(--lc-overflow-delay, 0s);
}

.lc-glow {
    position: absolute;
    inset: -1px;
    pointer-events: none;
    border-radius: 2px;
    opacity: 0;
    transition: opacity .35s ease;
    box-shadow: inset 0 0 22px 2px color-mix(in srgb, var(--life-r7) 55%, transparent);
}

.lc-track[data-rainbow="true"] .lc-glow {
    opacity: 1;
}

.lc-track[data-danger="true"] {
    border-color: var(--life-danger);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--life-danger) 45%, transparent);
}

.lc-tick {
    position: absolute;
    top: -3px;
    bottom: -3px;
    width: 1px;
    background: color-mix(in srgb, var(--mix-ink) 55%, transparent);
    pointer-events: none;
}

.lc-tick-danger {
    background: var(--life-danger);
}

.lc-tick span {
    position: absolute;
    top: calc(100% + 3px);
    left: 0;
    transform: translateX(-50%);
    font-size: .6rem;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    white-space: nowrap;
}

.lc-tick-danger span {
    color: var(--life-danger);
}

.lc-scale {
    height: 15px;
}

/* ---------- judgment keys ---------- */
.lc-keys {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 6px;
    margin-top: 22px;
}

.lc-key {
    --lc-k: var(--mix-ink);
    position: relative;
    background: var(--mix-surface-muted);
    border: 1px solid color-mix(in srgb, var(--lc-k) 38%, transparent);
    border-bottom-width: 3px;
    border-bottom-color: var(--lc-k);
    border-radius: 3px;
    padding: 9px 6px 7px;
    cursor: pointer;
    color: var(--mix-ink);
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    transition: transform .07s ease, background .12s ease;
}

.lc-key:hover {
    background: color-mix(in srgb, var(--lc-k) 16%, var(--mix-surface-muted));
}

.lc-key:active {
    transform: translateY(2px);
    border-bottom-width: 1px;
    margin-bottom: 2px;
    background: color-mix(in srgb, var(--lc-k) 30%, var(--mix-surface-muted));
}

.lc-key-delta {
    font-family: var(--font-body);
    font-size: .7rem;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--lc-k);
    font-variant-numeric: tabular-nums;
}

.lc-key-hint {
    position: absolute;
    top: 3px;
    right: 5px;
    font-family: var(--font-body);
    font-size: .58rem;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--mix-ink-muted);
}

.lc-key-step {
    color: var(--lc-k);
    margin-left: 3px;
}

.lc-key-perfect {
    --lc-k: var(--judg-perfect);
}

.lc-key-great {
    --lc-k: var(--judg-great);
}

.lc-key-good {
    --lc-k: var(--judg-good);
}

.lc-key-bad {
    --lc-k: var(--judg-bad);
}

.lc-key-miss {
    --lc-k: var(--judg-miss);
}

/* ---------- step toggle + run buttons ---------- */
.lc-runs {
    display: flex;
    align-items: center;
    gap: 7px 10px;
    flex-wrap: wrap;
    margin-top: 11px;
}

.lc-runs-label {
    font-size: .63rem;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    font-weight: 600;
}

.lc-runs-gap {
    flex: 1 1 12px;
}

.lc-seg {
    display: inline-flex;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
    border-radius: 3px;
    overflow: hidden;
}

.lc-seg button {
    background: none;
    border: none;
    color: var(--mix-ink-muted);
    font: 600 .74rem/1.3 var(--font-body);
    padding: 5px 12px;
    cursor: pointer;
    font-variant-numeric: tabular-nums;
}

.lc-seg button + button {
    border-left: 1px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
}

.lc-seg button[aria-pressed="true"] {
    background: var(--mix-primary);
    color: var(--mix-primary-contrast);
}

.lc-ghost {
    background: none;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 20%, transparent);
    color: var(--mix-ink-muted);
    border-radius: 2px;
    padding: 4px 10px;
    font: 600 .72rem/1.3 var(--font-body);
    cursor: pointer;
}

.lc-ghost:hover {
    color: var(--mix-ink);
    border-color: color-mix(in srgb, var(--mix-ink) 42%, transparent);
}

/* Phoenix 2's electric overflow effect: the note lights up when the state it
   describes is actually on screen. */
.lc-note {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 14px 0 0;
    font-size: .8rem;
    line-height: 1.45;
    color: var(--mix-ink-muted);
    max-width: 62ch;
    transition: color .25s ease;
}

.lc-bolt {
    flex: none;
    font-size: .95rem;
    opacity: .35;
    transition: opacity .25s ease, filter .25s ease;
}

.lc-note[data-live="true"] {
    color: var(--mix-ink);
}

.lc-note[data-live="true"] .lc-bolt {
    opacity: 1;
    filter: drop-shadow(0 0 6px var(--mix-accent));
}

/* ---------- telemetry rail ---------- */
.lc-tele {
    display: flex;
    flex-direction: column;
    gap: 13px;
    border-left: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    padding-left: 20px;
}

.lc-tele-label {
    display: block;
    font-size: .63rem;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    font-weight: 600;
}

.lc-tele-value {
    display: block;
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.lc-tele-miss {
    color: var(--judg-miss);
}

.lc-tele-note {
    display: block;
    font-size: .76rem;
    color: var(--mix-ink-muted);
    margin-top: 1px;
}

.lc-mult-meter {
    position: relative;
    height: 5px;
    margin-top: 6px;
    background: color-mix(in srgb, var(--mix-ink) 12%, transparent);
    border-radius: 3px;
    overflow: hidden;
}

.lc-mult-fill {
    position: absolute;
    inset: 0 auto 0 0;
    background: linear-gradient(90deg, color-mix(in srgb, var(--judg-perfect) 45%, transparent), var(--judg-perfect));
    transition: width var(--lc-sweep, .13s) linear;
}

/* ---------- sections ---------- */
.lc-section {
    margin-top: 34px;
}

.lc-section-head {
    display: flex;
    align-items: baseline;
    gap: 8px 14px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}

.lc-section-sub {
    margin: 0 0 14px;
    color: var(--mix-ink-muted);
    font-size: .9rem;
    line-height: 1.5;
    max-width: 70ch;
}

/* ---------- survival budget ---------- */
.lc-budget {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
}

.lc-bud {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
    border-top: 2px solid var(--lc-bud-c, var(--mix-primary));
    border-radius: 3px;
    padding: 12px 13px 13px;
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.lc-bud-miss {
    --lc-bud-c: var(--judg-miss);
}

.lc-bud-bad {
    --lc-bud-c: var(--judg-bad);
}

.lc-bud-value {
    font-family: var(--font-display);
    font-size: clamp(2rem, 4vw, 2.7rem);
    font-weight: 700;
    line-height: .95;
    font-variant-numeric: tabular-nums;
    display: flex;
    align-items: baseline;
    gap: 7px;
}

.lc-bud-unit {
    font-family: var(--font-body);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    line-height: 1.2;
}

.lc-bud-what {
    font-size: .86rem;
    line-height: 1.4;
    color: var(--mix-ink);
}

.lc-bud-bar {
    position: relative;
    height: 6px;
    background: var(--mix-bg);
    border-radius: 2px;
    overflow: hidden;
    margin-top: auto;
}

.lc-bud-bar i {
    position: absolute;
    inset: 0 auto 0 0;
    background: var(--life-rainbow);
}

.lc-bud-settle {
    font-size: .72rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.lc-budget-note {
    margin: 11px 0 0;
    font-size: .82rem;
    color: var(--mix-ink-muted);
}

/* ---------- level ladder ---------- */
.lc-ladder {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
    border-radius: 3px;
    padding: 14px 16px 16px;
}

.lc-ladder-head,
.lc-ladder-row {
    display: grid;
    grid-template-columns: 3ch minmax(0, 1fr) 7ch;
    gap: 12px;
}

.lc-ladder-head {
    font-size: .62rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    padding-bottom: 7px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
}

.lc-ladder-head span:last-child {
    text-align: right;
}

.lc-ladder-row {
    align-items: center;
    padding: 2px 0;
    background: none;
    border: none;
    width: 100%;
    color: inherit;
    font: inherit;
    cursor: pointer;
    text-align: left;
}

.lc-ladder-row:hover {
    background: color-mix(in srgb, var(--mix-ink) 5%, transparent);
}

.lc-ladder-row[data-current="true"] {
    background: color-mix(in srgb, var(--mix-primary) 13%, transparent);
    box-shadow: inset 2px 0 0 var(--mix-primary);
}

.lc-ladder-level {
    font-family: var(--font-display);
    font-size: .95rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: var(--mix-ink-muted);
}

.lc-ladder-row[data-current="true"] .lc-ladder-level {
    color: var(--mix-ink);
}

.lc-ladder-bar {
    display: flex;
    height: 9px;
    gap: 1px;
}

.lc-ladder-visible {
    background: var(--life-rainbow);
    opacity: .95;
}

.lc-ladder-overflow {
    background:
        repeating-linear-gradient(115deg, transparent 0 4px, color-mix(in srgb, var(--mix-surface) 70%, transparent) 4px 6px),
        color-mix(in srgb, var(--life-overflow) 78%, transparent);
}

.lc-ladder-max {
    font-size: .76rem;
    font-variant-numeric: tabular-nums;
    color: var(--mix-ink-muted);
    text-align: right;
}

.lc-ladder-row[data-current="true"] .lc-ladder-max {
    color: var(--mix-ink);
}

.lc-ladder-key {
    display: flex;
    gap: 18px;
    flex-wrap: wrap;
    margin-top: 12px;
    font-size: .76rem;
    color: var(--mix-ink-muted);
}

.lc-ladder-key i {
    display: inline-block;
    width: 22px;
    height: 8px;
    vertical-align: -1px;
    margin-right: 7px;
}

.lc-ladder-key i.lc-k-visible {
    background: var(--life-rainbow);
}

.lc-ladder-key i.lc-k-overflow {
    background:
        repeating-linear-gradient(115deg, transparent 0 4px, color-mix(in srgb, var(--mix-surface) 70%, transparent) 4px 6px),
        color-mix(in srgb, var(--life-overflow) 78%, transparent);
}

/* ---------- rules of thumb ---------- */
.lc-rules {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}

.lc-rule {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
    border-radius: 3px;
    padding: 14px 15px 15px;
}

.lc-rule-value {
    font-family: var(--font-display);
    font-size: 2.1rem;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--lc-rule-c, var(--mix-ink));
}

.lc-rule h3 {
    font-size: 1.08rem;
    letter-spacing: .02em;
    margin: 8px 0 5px;
}

.lc-rule p {
    margin: 0;
    font-size: .87rem;
    line-height: 1.5;
    color: var(--mix-ink-muted);
}

.lc-rule-miss {
    --lc-rule-c: var(--judg-miss);
}

.lc-rule-bad {
    --lc-rule-c: var(--judg-bad);
}

.lc-rule-perfect {
    --lc-rule-c: var(--judg-perfect);
}

.lc-rule-good {
    --lc-rule-c: var(--judg-good);
}

/* ---------- mechanics ---------- */
.lc-mech {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}

.lc-mech-col {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
    border-radius: 3px;
    padding: 14px 15px 15px;
}

.lc-mech-col h3 {
    font-size: 1.05rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    margin: 0 0 9px;
}

.lc-mech-gain {
    color: var(--judg-perfect);
}

.lc-mech-loss {
    color: var(--judg-miss);
}

.lc-mech-mult {
    color: var(--mix-accent);
}

.lc-mech-col ul {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.lc-mech-col li {
    font-size: .87rem;
    line-height: 1.5;
    color: var(--mix-ink-muted);
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 10px;
    align-items: baseline;
}

.lc-mech-col li b {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 700;
    color: var(--mix-ink);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.lc-formula {
    margin: 11px 0 0;
    padding-top: 10px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
    font-size: .74rem;
    line-height: 1.5;
    color: var(--mix-ink-muted);
    word-break: break-word;
}

/* ---------- footer ---------- */
.lc-foot {
    margin-top: 36px;
    padding-top: 18px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 20px 30px;
    align-items: start;
}

.lc-quote {
    margin: 0;
    font-family: var(--font-display);
    font-size: 1.5rem;
    line-height: 1.15;
    color: var(--mix-ink);
}

.lc-quote cite {
    display: block;
    margin-top: 5px;
    font-family: var(--font-body);
    font-size: .78rem;
    font-style: normal;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

/* ===== /Titles =====
   Titles are ladders, so the page draws one rail per ladder rather than one row per title
   (docs/design/titles-overhaul.md). Tokens only: this page carries no colour-literal
   allowance and is not to acquire one. */

/* The shell leaves the page flush against the nav, and this one opens on a panel edge or a
   section rule rather than on a heading, so it owes itself the breathing room. */
.title-standing,
.title-anon,
.title-skeleton {
    margin-top: 16px;
}

.title-standing {
    display: grid;
    grid-template-columns: minmax(230px, 1fr) minmax(250px, 1fr);
    gap: 14px 30px;
    align-items: center;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 4px;
    padding: 14px 16px;
    margin-bottom: 20px;
}

.title-eyebrow {
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    margin: 0 0 6px;
}

.title-worn {
    font-family: var(--font-display);
    font-size: clamp(26px, 6vw, 44px);
    font-weight: 700;
    line-height: 1;
    margin: 0;
    color: var(--mix-ink);
    text-wrap: balance;
}

.title-worn-note {
    color: var(--mix-ink-muted);
    font-size: 13.5px;
    margin: 8px 0 0;
}

.title-tally {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 5px;
}

.title-tally-num {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 30px;
    line-height: 1;
    color: var(--mix-ink);
    font-variant-numeric: tabular-nums;
}

.title-tally-of {
    font-size: 13px;
    color: var(--mix-ink-muted);
}

.title-meter {
    height: 10px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--mix-ink) 9%, transparent);
    overflow: hidden;
}

.title-meter i {
    display: block;
    height: 100%;
    background: var(--mix-primary);
    box-shadow: 0 0 8px var(--mix-glow);
}

.title-meter-legend {
    font-size: 12px;
    color: var(--mix-ink-muted);
    margin-top: 6px;
}

.title-anon {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-primary) 40%, transparent);
    border-radius: 4px;
    padding: 12px 16px;
    margin-bottom: 18px;
}

.title-anon p {
    margin: 0;
    flex: 1 1 260px;
    font-size: 14px;
    color: var(--mix-ink);
}

/* Filter furniture sits above the list and never sticks (UX rule 6). */
.title-controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    padding: 9px 0;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    margin-bottom: 18px;
}

.title-search {
    flex: 1 1 190px;
    min-width: 150px;
    margin: 0;
}

.title-chips {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

.title-chip {
    font: inherit;
    font-size: 13px;
    background: transparent;
    color: var(--mix-ink-muted);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 20%, transparent);
    border-radius: 999px;
    padding: 2px 12px;
    cursor: pointer;
    transition: color .15s, border-color .15s, background .15s;
}

.title-chip:hover {
    color: var(--mix-ink);
    border-color: color-mix(in srgb, var(--mix-ink) 40%, transparent);
}

.title-chip.on {
    background: color-mix(in srgb, var(--mix-primary) 20%, transparent);
    border-color: var(--mix-primary);
    color: var(--mix-ink);
    font-weight: 600;
}

.title-chip .n {
    opacity: .65;
    margin-left: 5px;
    font-variant-numeric: tabular-nums;
}

.title-section {
    margin: 0 0 26px;
}

.title-section-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding-bottom: 5px;
    margin-bottom: 10px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
}

.title-section-head h2 {
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 600;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--mix-ink);
    margin: 0;
}

.title-section-count {
    font-size: 12.5px;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    margin-left: auto;
    white-space: nowrap;
}

.title-rails {
    display: flex;
    flex-direction: column;
}

/* Boss breakers are one short rail per mix, so they tile instead of stacking. */
/* Boss breakers are one short rail per mix. The mix name sits ABOVE its buttons rather than
   beside them: side by side, a long mix name and a 150px button fought over a 190px cell and
   the name lost, truncating to nothing. Stacked, every cell also gets the same button width
   for free — the labels are chart data rather than UI strings, so they are the same two
   near-identical widths in every language, which is what made them look misaligned. */
.title-rails.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 4px 18px;
    align-items: start;
}

.title-rail {
    display: grid;
    grid-template-columns: 168px 1fr auto;
    align-items: center;
    gap: 4px 14px;
    padding: 7px 6px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
}

.title-rails.grid .title-rail {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    padding: 6px 6px 10px;
}

.title-rails.grid .title-rail-track {
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
}

/* Identical width per cell, so a column of them reads as a column. */
.title-rails.grid .title-pip.wide {
    width: 100%;
    min-width: 0;
    justify-content: center;
}

.title-rail:last-child {
    border-bottom: 0;
}

.title-rail:hover {
    background: color-mix(in srgb, var(--mix-ink) 4%, transparent);
}

.title-rail-name {
    font-family: var(--font-display);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: .04em;
    line-height: 1.1;
    display: flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
}

.title-rail-name > span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Stacked, the mix name owns the full cell width and no longer needs to truncate. */
.title-rails.grid .title-rail-name > span:first-child {
    overflow: visible;
    white-space: normal;
}

.title-rails.grid .title-rail-name {
    font-size: 14px;
    letter-spacing: .1em;
    color: var(--mix-ink-muted);
}

.title-rail-track {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}

.title-rail-tail {
    font-family: var(--font-display);
    font-size: 17px;
    font-weight: 700;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.title-rail-tail b {
    color: var(--mix-ink);
}

.title-rails.grid .title-rail-tail {
    display: none;
}

.title-pip {
    position: relative;
    width: 32px;
    height: 30px;
    flex: 0 0 auto;
    border-radius: 3px;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 20%, transparent);
    background: transparent;
    color: var(--mix-ink-muted);
    font-family: var(--font-display);
    font-size: 15px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    overflow: hidden;
    transition: transform .12s ease, border-color .15s, box-shadow .15s;
}

.title-pip:hover {
    transform: translateY(-2px);
    border-color: var(--mix-ink);
    z-index: 2;
}

.title-pip:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
    z-index: 2;
}

.title-pip > span {
    position: relative;
    z-index: 1;
}

.title-pip.wide {
    width: auto;
    min-width: 62px;
    padding: 0 9px;
    font-size: 13px;
    letter-spacing: .06em;
}

.title-pip.earned {
    border-color: color-mix(in srgb, var(--mix-primary) 62%, transparent);
    background: color-mix(in srgb, var(--mix-primary) 17%, transparent);
    color: var(--mix-ink);
}

.title-pip.pg {
    border-color: var(--plate-pg);
    box-shadow: 0 0 8px color-mix(in srgb, var(--plate-pg) 45%, transparent);
}

.title-pip.active {
    border-color: var(--mix-accent);
    color: var(--mix-ink);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--mix-accent) 30%, transparent);
}

/* The fill is this rung's own climb from the rung below it. */
.title-pip.active::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: var(--fill, 0%);
    background: color-mix(in srgb, var(--mix-accent) 30%, transparent);
    z-index: 0;
}

.title-pip.locked {
    border-color: color-mix(in srgb, var(--mix-ink) 15%, transparent);
    color: color-mix(in srgb, var(--mix-ink) 34%, transparent);
}

.title-pip.official {
    border-style: dashed;
}

/* One-offs: titles with no ladder behind them. Name colour is how many players hold it,
   and the glow ramp orders the bands where hue cannot. */
.title-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.title-badge {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 4px 11px 4px 8px;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
    border-radius: 3px;
    background: color-mix(in srgb, var(--mix-ink) 4%, transparent);
    font: inherit;
    color: var(--mix-ink);
    cursor: pointer;
    transition: transform .12s, border-color .15s;
}

.title-badge:hover {
    transform: translateY(-1px);
    border-color: color-mix(in srgb, var(--mix-ink) 45%, transparent);
}

.title-badge:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
}

.title-badge.official {
    border-style: dashed;
}

.title-badge-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--band);
}

.title-badge-name {
    font-family: var(--font-display);
    font-size: 16px;
    font-weight: 600;
    letter-spacing: .03em;
    color: var(--band);
}

.title-badge.owned {
    border-color: color-mix(in srgb, var(--mix-primary) 55%, transparent);
    background: color-mix(in srgb, var(--mix-primary) 12%, transparent);
}

.title-badge.unowned {
    opacity: .42;
}

.title-badge.unowned .title-badge-name {
    color: var(--mix-ink-muted);
}

.title-empty {
    color: var(--mix-ink-muted);
    padding: 12px 0;
}

/* Loading looks like the layout it becomes (UX rule 9), not a lone spinner. */
.title-skeleton {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-top: 12px;
}

.title-skeleton-rail {
    height: 44px;
    border-radius: 3px;
    background: color-mix(in srgb, var(--mix-ink) 7%, transparent);
    animation: title-skeleton-pulse 1.4s ease-in-out infinite;
}

@keyframes title-skeleton-pulse {
    0%, 100% {
        opacity: 1;
    }

    50% {
        opacity: .55;
    }
}

/* ---- the detail drawer ---- */
.title-drawer {
    display: flex;
    flex-direction: column;
    height: 100%;
    color: var(--mix-ink);
}

.title-drawer-head {
    position: relative;
    padding: 14px 16px 10px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    flex: 0 0 auto;
}

.title-drawer-eyebrow {
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.lc-foot-src {
    font-size: .84rem;
    line-height: 1.55;
    color: var(--mix-ink-muted);
}

.lc-foot-src a {
    color: var(--mix-primary);
}

/* ---------- narrow widths ---------- */
@media (max-width: 959.98px) {
    .lc-bench {
        grid-template-columns: minmax(0, 1fr);
    }

    .lc-tele {
        border-left: none;
        border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
        padding-left: 0;
        padding-top: 15px;
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
        gap: 14px 18px;
    }

    .lc-budget {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .lc-rules {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .lc-mech {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 639.98px) {
    .lc-track {
        height: 40px;
    }

    .lc-bench {
        padding: 14px 13px 16px;
    }

    .lc-rules {
        grid-template-columns: minmax(0, 1fr);
    }

    .lc-foot {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 479.98px) {
    .lc-keys {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .lc-budget {
        grid-template-columns: minmax(0, 1fr);
    }
}

.title-drawer-head h3 {
    font-family: var(--font-display);
    font-size: 27px;
    font-weight: 700;
    line-height: 1.05;
    margin: 2px 0 4px;
    padding-right: 40px;
}

.title-drawer-close {
    position: absolute;
    top: 8px;
    right: 10px;
}

.title-drawer-body {
    padding: 12px 16px 24px;
    overflow-y: auto;
    flex: 1 1 auto;
}

.title-req {
    font-size: 14px;
    background: color-mix(in srgb, var(--mix-ink) 6%, transparent);
    border-left: 2px solid var(--mix-primary);
    padding: 7px 10px;
    margin: 0 0 14px;
}

.title-note {
    font-size: 12.5px;
    color: var(--mix-ink-muted);
    border: 1px dashed color-mix(in srgb, var(--mix-ink) 26%, transparent);
    border-radius: 3px;
    padding: 7px 9px;
    margin: 0 0 14px;
}

.title-label {
    font-family: var(--font-display);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    margin: 16px 0 6px;
}

.title-bar {
    position: relative;
    height: 9px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--mix-ink) 10%, transparent);
    overflow: hidden;
}

/* PUMBILITY rung ticks on a one-gem bar (docs/design/pumbility-levels.md §8). The frame wraps
   the bar: 18px of reserved headroom carries the LV.n labels, the overlay aligns to the bar's
   own box, and the ticks overshoot its edges — the bar underneath keeps its rounded clip. The
   current rung's tick and label are the bright ones; hover names the rung in full. */
.pmb-lvl-frame {
    position: relative;
    padding-top: 18px;
}

.pmb-lvl-overlay {
    position: absolute;
    inset: 18px 0 0 0;
    pointer-events: none;
}

.pmb-lvl-tick {
    position: absolute;
    top: -3px;
    bottom: -3px;
    width: 3px;
    margin-left: -1.5px;
    border-radius: 1px;
    background: color-mix(in srgb, var(--mix-ink) 45%, transparent);
    pointer-events: auto;
}

.pmb-lvl-tick b {
    position: absolute;
    bottom: calc(100% + 3px);
    left: 50%;
    transform: translateX(-50%);
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: .03em;
    color: var(--mix-ink-muted);
    white-space: nowrap;
}

.pmb-lvl-tick.cur {
    background: var(--mix-ink);
}

.pmb-lvl-tick.cur b {
    color: var(--mix-ink);
}

.title-bar i {
    display: block;
    height: 100%;
    background: var(--mix-accent);
}

.title-bar.done i {
    background: var(--rarity-emerald);
}

.title-figures {
    display: flex;
    justify-content: space-between;
    font-size: 12.5px;
    color: var(--mix-ink-muted);
    margin-top: 4px;
    font-variant-numeric: tabular-nums;
}

.title-figures b {
    color: var(--mix-ink);
}

.title-hint {
    font-size: 12.5px;
    color: var(--mix-ink-muted);
    margin: 6px 0 0;
}

.title-hint b {
    color: var(--mix-ink);
}

.title-suggest {
    display: flex;
    align-items: center;
    gap: 10px;
    background: color-mix(in srgb, var(--mix-primary) 10%, transparent);
    border-left: 2px solid var(--mix-primary);
    padding: 8px 10px;
}

.title-suggest-folder {
    font-family: var(--font-display);
    font-size: 24px;
    font-weight: 700;
    line-height: 1;
    color: var(--mix-primary);
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
}

.title-suggest-ask {
    font-size: 13px;
    line-height: 1.35;
}

/* One row per reference grade. The rows block is a flex item of .title-suggest, so it has to
   claim the remaining width or its children size to content and the asks stop lining up. */
.title-suggest-rows {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.title-suggest-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
}

/* The folder column is fixed so every grade's ask starts on the same edge, single-type and
   merged-pool rungs alike. Out-specifies the standalone .title-suggest-folder above. */
.title-suggest-row .title-suggest-folder {
    font-size: 23px;
    min-width: 96px;
}

/* A grade no folder reaches: the number is the ceiling that falls short, not an answer. */
.title-suggest-row.short .title-suggest-folder {
    font-size: 20px;
    color: color-mix(in srgb, var(--mix-ink) 34%, transparent);
}

.title-suggest-row.short .title-suggest-ask {
    color: var(--mix-ink-muted);
}

.title-rarity {
    display: flex;
    align-items: baseline;
    gap: 9px;
}

.title-rarity-pct {
    font-family: var(--font-display);
    font-size: 31px;
    font-weight: 700;
    line-height: 1;
    color: var(--band);
}

.title-holders {
    display: flex;
    flex-direction: column;
}

/* The gem-rung drawer: flat level groups, strongest first (docs/design/pumbility-levels.md §4).
   The group rows stay unmarked on purpose — the viewer's own holder row is the list's only
   highlight, because "Where you stand" above already carries their rung. */
.title-stand {
    display: flex;
    align-items: center;
    gap: 10px;
}

.title-stand-id {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.title-stand-name {
    font-weight: 600;
}

.title-stand-next,
.title-stand-range {
    font-size: 13px;
    color: var(--mix-ink-muted);
}

.title-stand-range {
    white-space: nowrap;
}

.title-lvls {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.title-lvl-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 6px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--mix-ink) 5%, transparent);
}

.title-lvl.empty {
    opacity: .45;
}

.title-lvl-name {
    font-weight: 600;
}

.title-lvl-th {
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.title-lvl-n {
    margin-left: auto;
    font-size: 13px;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.title-lvl-holders {
    display: flex;
    flex-direction: column;
    margin-left: 8px;
    padding: 2px 0 4px 10px;
    border-left: 2px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
}

.title-lvl-pool {
    margin-left: auto;
    font-size: 13px;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

@media (max-width: 860px) {
    .title-standing {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 700px) {
    .title-standing {
        gap: 10px;
        padding: 11px 12px;
        margin-bottom: 14px;
    }

    .title-worn {
        font-size: clamp(24px, 8vw, 34px);
    }

    .title-controls {
        padding: 7px 0;
        margin-bottom: 12px;
        gap: 6px 8px;
    }

    .title-search {
        flex: 1 1 100%;
    }

    .title-chip {
        padding: 2px 9px;
        font-size: 12.5px;
    }

    .title-section {
        margin-bottom: 20px;
    }

    /* The rail wraps onto its own row; it never side-scrolls. */
    .title-rail {
        grid-template-columns: 1fr auto;
        gap: 3px 10px;
        padding: 9px 4px;
    }

    .title-rail-name {
        grid-column: 1;
    }

    .title-rail-tail {
        grid-column: 2;
    }

    .title-rail-track {
        grid-column: 1 / -1;
        margin-top: 2px;
    }
}

/* Filtered out, not removed: a ladder with holes punched through it stops reading as a
   ladder, so a non-matching rung fades in place. */
.title-pip.dim {
    opacity: .16;
    pointer-events: none;
}

.title-badge.dim {
    opacity: .16;
    pointer-events: none;
}

/* ── Folder levels (docs/design/folder-level-progression.md): a folder is two numbers, and
   these are the two ways it renders. The chip carries the grade in its metal with the glow
   stepping by completion tier; the spectrum lays the whole folder out best-first so length
   reads as completion and hue reads as quality. All colour arrives as tokens — the grade
   metals via --grade-*, everything unplayed via --unplayed-grade. ── */
.fl-chip {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    min-width: 58px;
    padding: 6px 7px 5px;
    border-radius: 9px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
    font-family: var(--font-display);
    font-variant-numeric: tabular-nums;
}

.fl-chip-grade {
    font-size: 23px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: .01em;
}

.fl-chip-pct,
.fl-chip-count {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: .07em;
    color: var(--mix-ink-muted);
}

.fl-chip-count {
    font-size: 15px;
    color: var(--unplayed-grade);
}

/* A lamped folder is ringed in its own grade metal — the trophy state, and the one rung
   content growth can take back. */
.fl-lamped {
    border-color: currentColor;
    box-shadow: 0 0 0 1px currentColor, 0 0 16px -4px currentColor;
}

.fl-spectrum {
    width: 100%;
}

.fl-track {
    position: relative;
    height: 18px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--mix-bg) 55%, #000);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
}

.fl-slim .fl-track {
    height: 11px;
    border-radius: 7px;
}

.fl-chunky .fl-track {
    height: 22px;
    border-radius: 11px;
}

.fl-fill {
    position: absolute;
    inset: 1px;
    border-radius: 9px;
}

.fl-slim .fl-fill {
    border-radius: 6px;
}

.fl-chunky .fl-fill {
    border-radius: 10px;
}

/* Ticks are cut out of the bar rather than drawn over it, so they read at every fill colour. */
.fl-tick {
    position: absolute;
    top: -4px;
    bottom: -4px;
    width: 2px;
    border-radius: 1px;
    background: var(--mix-bg);
}


/* The tier list's folder standing: one line and the bar, sitting under the title track. */
.fl-header {
    display: grid;
    gap: 8px;
    margin: 0 0 16px;
    padding: 2px 2px 4px;
}

.fl-header-line {
    font-family: var(--font-display);
    font-size: 22px;
    font-weight: 700;
    letter-spacing: .02em;
    line-height: 1.1;
}

.fl-header-dot {
    color: var(--mix-ink-muted);
    font-weight: 400;
    margin: 0 4px;
}

/* Folder Levels widget: a 1x1 gives one folder the whole cell, everything wider stacks rows. */
.dash-fl-hero {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    text-align: center;
}

.dash-fl-hero-grade {
    font-family: var(--font-display);
    font-size: 40px;
    font-weight: 700;
    line-height: 1;
}

.dash-fl-hero-pct {
    font-family: var(--font-display);
    font-size: 13px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.dash-fl-hero-bar {
    width: 100%;
}

.dash-fl-hero-left {
    font-family: var(--font-display);
    font-size: 11px;
    color: var(--mix-ink-muted);
    margin-top: 6px;
    font-variant-numeric: tabular-nums;
}

.dash-fl-rows {
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 12px;
    justify-content: center;
}

.dash-fl-row-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 5px;
}

.dash-fl-row-name {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.dash-fl-row-count {
    font-family: var(--font-display);
    font-size: 12px;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dash-fl-row-grade {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 16px;
}

.dash-fl-row-pct {
    font-family: var(--font-display);
    font-size: 11px;
    letter-spacing: .05em;
    color: var(--mix-ink-muted);
    margin-left: 6px;
    font-variant-numeric: tabular-nums;
}

/* Vertical spectrum: the community profile stacks folders as columns, so the long axis
   flips and the fill grows from the base. Ticks become horizontal rules. */
.fl-vertical .fl-track {
    height: 100%;
    border-radius: 5px 5px 0 0;
}

.fl-vertical .fl-fill {
    border-radius: 4px 4px 0 0;
}

.fl-vertical .fl-tick {
    top: auto;
    bottom: 0;
    left: -4px;
    right: -4px;
    width: auto;
    height: 2px;
}


/* A lamped folder glows, in its own grade metal — a folder lamped at AA burns copper and one
   lamped at SSS+ burns ice-blue, so the glow says how well it was lamped and not only that it
   was. The hue arrives as currentColor from the component. There is deliberately no
   end-of-track marker: the track own end already IS 100%, so a flag there drew a finish line
   on top of the finish line. */
.fl-track-lamped {
    border-color: currentColor;
    box-shadow: 0 0 12px -2px currentColor;
}

/* Folder Levels config: the running count sits above the grid so a full widget explains
   itself before a tap does nothing. */
.fl-cfg-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    font-family: var(--font-display);
    font-size: 13px;
    letter-spacing: .04em;
    color: var(--mix-ink-muted);
    margin-bottom: 6px;
}

.fl-cfg-picks {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-bottom: 10px;
}

/* The Select Folders popover anchor — same shape as the tier list's folder picker. */
.fl-cfg-anchor {
    position: relative;
    display: inline-block;
}

/* A folder grid at its host's cap: unpicked cells go quiet so the grid reads as full,
   while the picked ones stay live because removing is how you make room. */
.folder-picker-level:disabled {
    opacity: .35;
    cursor: not-allowed;
}

/* The 1x1 hero leads with the difficulty ball — nothing else in that cell names the folder. */
.dash-fl-hero > .mud-tooltip-root,
.dash-fl-hero > .difficulty-bubble {
    flex: none;
}

/* ===== Mix Changes — the mix diff =====
   The board wears the rankings-board skin (compact rows, hairline separators, no card per
   row) because that is the site's standard for any dense board. The one encoding this page
   adds is direction: warm means the game calls it harder, cool means easier, taken off the
   existing difficulty ramp so it is never the tier lists' red/green. Every direction colour
   is paired with an arrow and the printed delta. */
.mc {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.mc-head {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.mc-title {
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 1;
    letter-spacing: .01em;
}

.mc-sub {
    color: var(--mix-ink-muted);
    max-width: 52ch;
    margin-top: 5px;
}

.mc-mixpair {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.mc-mixsel {
    min-width: 168px;
    max-width: 220px;
}

.mc-tween {
    color: var(--mix-ink-muted);
}

.mc-lookup {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.mc-hint {
    font-size: .82rem;
    color: var(--mix-ink-muted);
}

.mc-notice {
    margin: 0;
}

/* ---- the answer card ---- */
.mc-answer {
    display: flex;
    gap: 13px;
    align-items: flex-start;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-left: 3px solid var(--mix-primary);
    border-radius: 5px;
    padding: 13px 15px;
}

.mc-answer-up {
    border-left-color: var(--diff-hard);
}

.mc-answer-down {
    border-left-color: var(--diff-overrated);
}

.mc-answer-new {
    border-left-color: var(--mix-accent);
}

.mc-answer-gone {
    border-left-color: var(--diff-overrated);
}

.mc-answer-same {
    border-left-color: color-mix(in srgb, var(--mix-ink) 20%, transparent);
}

.mc-answer-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.mc-answer-id {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.mc-answer-song {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.28rem;
    line-height: 1.12;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mc-answer-artist {
    font-size: .79rem;
    color: var(--mix-ink-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mc-verdict {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.06rem;
    line-height: 1.3;
    margin: 0;
}

.mc-moves {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.mc-move {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 13%, transparent);
    border-radius: 5px;
    padding: 4px 8px;
}

.mc-move-pinned {
    border-color: var(--mix-primary);
    box-shadow: 0 0 0 1px var(--mix-glow);
}

/* The earlier mix's bubble, stated as past tense. */
.mc-was {
    filter: grayscale(.5) brightness(.82);
    display: inline-flex;
}

.mc-arrow {
    color: var(--mix-ink-muted);
    font-size: .85rem;
}

.mc-delta {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: .86rem;
    font-variant-numeric: tabular-nums;
    min-width: 30px;
    text-align: right;
}

.mc-up {
    color: var(--diff-hard);
}

.mc-down {
    color: var(--diff-overrated);
}

.mc-quiet {
    font-size: .8rem;
    color: var(--mix-ink-muted);
}

.mc-restepped {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* What did NOT move is part of the answer, so it is always shown rather than hidden
   behind a toggle. */
.mc-unchanged {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.mc-unchanged-label {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .72rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.mc-unchanged-list {
    display: flex;
    flex-wrap: wrap;
    gap: 3px;
    align-items: center;
}

/* Note counts line up as a column across rows, so they get tabular figures. */
.mc-notes {
    font-variant-numeric: tabular-nums;
    font-size: .85rem;
    color: var(--mix-ink-muted);
    white-space: nowrap;
}

.mc-linkish {
    background: none;
    border: 0;
    padding: 0;
    color: var(--mix-secondary);
    cursor: pointer;
    font: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.mc-linkish:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
}

/* ---- tabs ---- */
.mc-tabs {
    display: flex;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    overflow-x: auto;
}

.mc-tab {
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    cursor: pointer;
    padding: 9px 14px 8px;
    color: var(--mix-ink-muted);
    white-space: nowrap;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.02rem;
    letter-spacing: .02em;
    display: flex;
    align-items: baseline;
    gap: 7px;
}

.mc-tab-n {
    font-variant-numeric: tabular-nums;
    font-size: .86rem;
    opacity: .75;
}

.mc-tab[aria-selected="true"] {
    color: var(--mix-ink);
    border-bottom-color: var(--mix-primary);
}

.mc-tab:hover {
    color: var(--mix-ink);
}

.mc-tab:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: -2px;
}

/* ---- the folder picker and what narrows inside it ---- */
.mc-filters {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    margin: 14px 0;
}

.mc-filters .folder-picker { margin-right: 4px; }

/* The chart-selector suggestion's mix suffix — present only where several mixes feed it. */
.chart-selector-mix { color: var(--mix-ink-muted); font-size: .82em; }

.mc-chip {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 13%, transparent);
    color: var(--mix-ink-muted);
    border-radius: 99px;
    padding: 3px 12px;
    cursor: pointer;
    font-size: .83rem;
}

.mc-chip:hover {
    color: var(--mix-ink);
}

.mc-chip:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
}

.mc-chip[aria-pressed="true"] {
    background: color-mix(in srgb, var(--mix-primary) 15%, var(--mix-surface));
    border-color: color-mix(in srgb, var(--mix-primary) 55%, transparent);
    color: var(--mix-ink);
}

.mc-filter-sep {
    width: 1px;
    height: 18px;
    background: color-mix(in srgb, var(--mix-ink) 13%, transparent);
}

.mc-groupby {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: .8rem;
    color: var(--mix-ink-muted);
}

.mc-seg {
    display: inline-flex;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 13%, transparent);
    border-radius: 5px;
    overflow: hidden;
}

.mc-seg button {
    background: var(--mix-surface);
    border: 0;
    color: var(--mix-ink-muted);
    cursor: pointer;
    padding: 3px 10px;
    font-size: .81rem;
}

.mc-seg button[aria-pressed="true"] {
    background: color-mix(in srgb, var(--mix-primary) 18%, var(--mix-surface));
    color: var(--mix-ink);
}

.mc-seg button:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: -2px;
}

/* ---- the folder in view, and its rows ---- */
.mc-fgroup {
    display: flex;
    flex-direction: column;
}

/* Names the folder the picker selected. Not a control — the picker is. */
.mc-fhead {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 8px 5px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 22%, transparent);
    position: sticky;
    top: -1px;
    background: var(--mix-surface);
    z-index: 2;
}

.mc-ftitle {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.14rem;
    letter-spacing: .01em;
}

.mc-fcount {
    font-size: .79rem;
    color: var(--mix-ink-muted);
    margin-left: auto;
    font-variant-numeric: tabular-nums;
}

.mc-row {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 4px 6px;
    width: 100%;
    border: 0;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    background: var(--mix-surface);
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.mc-row:hover {
    box-shadow: inset 2px 0 0 var(--mix-primary);
}

.mc-row:hover .mc-name {
    color: var(--mix-primary);
}

.mc-row:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: -2px;
}

.mc-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: .92rem;
}

.mc-tail {
    margin-left: auto;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 7px;
}

/* ---- sticker sheet ---- */
.mc-sheet {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 14px;
}

.mc-stickers {
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
}

.mc-sticker {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
    border-radius: 5px;
    padding: 9px;
    display: flex;
    flex-direction: column;
    gap: 7px;
    text-align: left;
    color: inherit;
    min-width: 0;
}

/* Jacket art is a ~16:9 banner. A fixed height sizes the width from the aspect and
   overflows a fluid card, so the box owns the geometry and the image is bounded to it. */
.mc-sticker-art {
    width: 100%;
    aspect-ratio: 16 / 9;
    border-radius: 3px;
    overflow: hidden;
    background: var(--mix-surface-muted);
    display: flex;
    align-items: center;
    justify-content: center;
}

.mc-sticker-art img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The one thing on a sticker worth clicking. */
.mc-ball {
    background: none;
    border: 0;
    padding: 0;
    line-height: 0;
    cursor: pointer;
    border-radius: 3px;
}

.mc-ball:hover {
    filter: brightness(1.25);
}

.mc-ball:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 1px;
}

/* Dimming the card is what says "gone" — desaturating the bubbles instead would cost the
   red-Single / green-Double read for no extra meaning. */
.mc-sticker-gone {
    opacity: .72;
}

.mc-sticker-gone:hover {
    opacity: 1;
}

.mc-sticker-name {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.02rem;
    line-height: 1.13;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.mc-sticker-artist {
    font-size: .72rem;
    color: var(--mix-ink-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mc-sticker-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
}

.mc-loose {
    display: flex;
    flex-direction: column;
}

.mc-loose-title {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .72rem;
    letter-spacing: .15em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    margin: 8px 0 6px;
}

.mc-empty {
    padding: 26px 14px;
    text-align: center;
    color: var(--mix-ink-muted);
    font-size: .9rem;
    border: 1px dashed color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 5px;
}

@media (min-width: 820px) {
    .mc-head {
        flex-direction: row;
        align-items: flex-end;
        justify-content: space-between;
        gap: 24px;
    }
}

/* Narrow: the grouping control takes its own line instead of squeezing in beside a wrapped
   direction chip. */
@media (max-width: 600px) {
    .mc-groupby {
        margin-left: 0;
        width: 100%;
        justify-content: flex-start;
    }
}

/* ============================================================================
   QUALIFIERS (docs/design/qualifiers-overhaul.md)

   One player page: status, your standing, the board, the pool, how it is scored.
   The board wears the sitewide .olb-rank-card skin; what is new here is the chip,
   which carries one play as a jacket ringed in its grade's metal.
   ============================================================================ */

.qual-status {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    padding: 11px 13px;
    border-radius: 10px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

.qual-status-id {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.qual-kicker {
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: .15em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.qual-status h1 {
    margin: 0;
    font-size: 17px;
    line-height: 1.2;
    font-weight: 700;
    letter-spacing: -.012em;
    text-wrap: balance;
}

.qual-clock {
    margin-left: auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 1px;
    flex: 0 0 auto;
}

.qual-clock-label {
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.qual-clock-value {
    font-variant-numeric: tabular-nums;
    font-size: 17px;
    font-weight: 700;
    line-height: 1.15;
}

/* The urgency thresholds the page already branched on, made visible. */
.qual-clock-far { color: var(--mix-primary); }
.qual-clock-near { color: var(--mix-accent); }
.qual-clock-now { color: var(--mix-secondary); }

/* ---- your standing ---- */
.qual-you {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 14px;
    padding: 12px 13px;
    border-radius: 10px;
    background: var(--mix-surface);
    box-shadow: inset 0 0 0 1.5px var(--mix-primary), 0 0 22px -8px var(--mix-glow);
}

.qual-you-rank {
    display: flex;
    align-items: baseline;
    gap: 4px;
    flex: 0 0 auto;
}

.qual-you-place {
    font-size: 30px;
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.03em;
}

.qual-you-of {
    font-size: 12px;
    font-weight: 700;
    color: var(--mix-ink-muted);
}

.qual-you-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 130px;
}

.qual-you-name {
    font-weight: 700;
    font-size: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qual-you-gap { font-size: 12px; color: var(--mix-ink-muted); }
.qual-you-gap b { color: var(--mix-accent); font-variant-numeric: tabular-nums; }

.qual-you-total { text-align: right; flex: 0 0 auto; margin-left: auto; }

.qual-you-total-value {
    font-size: 19px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.015em;
}

.qual-you-total-label {
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.qual-you-empty { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--mix-ink) 16%, transparent); }

/* ---- auto-submit strip ---- */
.qual-link {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    padding: 9px 11px;
    border-radius: 9px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    font-size: 12px;
}

.qual-link-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--mix-ink-muted);
}

.qual-link-on .qual-link-dot {
    background: var(--type-doubles);
    box-shadow: 0 0 7px var(--type-doubles);
}

.qual-link-text { color: var(--mix-ink-muted); flex: 1 1 150px; min-width: 0; }
.qual-link-text b { color: var(--mix-ink); font-weight: 700; }

/* ---- the chip: one play, jacket ringed in its grade ----
   The grade rides as the ring rather than a separate icon, which is what buys
   enough room to show a ten-chart top N in the row. The ladder is deliberately
   not injective (SS+/SS share a metal), so the rating prints underneath and the
   title carries the exact grade and score. */
.qual-chips {
    display: flex;
    align-items: flex-start;
    gap: 5px;
    flex-wrap: nowrap;
}

.qual-chip {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto;
    appearance: none;
    background: transparent;
    border: 0;
    padding: 0;
    margin: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
}

.qual-chip-thumb {
    position: relative;
    width: 40px;
    height: 23px;
    border-radius: 3px;
    overflow: hidden;
    display: block;
    box-shadow: 0 0 0 2px var(--qual-grade, var(--unplayed-grade));
    transition: transform .12s ease, box-shadow .12s ease;
}

.qual-chip-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Perfect Game is a plate, not a grade, so it layers a halo over the ring. */
.qual-chip-pg .qual-chip-thumb {
    box-shadow: 0 0 0 2px var(--plate-pg), 0 0 9px 1px color-mix(in srgb, var(--plate-pg) 85%, transparent);
}

.qual-chip-rating {
    font-variant-numeric: tabular-nums;
    font-size: 9.5px;
    line-height: 1.1;
    color: var(--mix-ink-muted);
}

.qual-chip:hover .qual-chip-thumb {
    transform: translateY(-1px);
    box-shadow: 0 0 0 2px var(--qual-grade, var(--unplayed-grade)), 0 3px 9px rgba(0, 0, 0, .55);
}

.qual-chip:focus-visible { outline: none; }
.qual-chip:focus-visible .qual-chip-thumb { outline: 2px solid var(--mix-ink); outline-offset: 2px; }

.qual-chip-more {
    align-self: center;
    font-size: 10.5px;
    font-weight: 700;
    color: var(--mix-ink-muted);
    padding: 5px 6px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--mix-ink) 8%, transparent);
}

/* ---- the pool ----
   Auto-fill on a minimum track, so a four-chart pool and a thirteen-chart pool
   lay out without a mode switch; the tile floor just drops once it gets big. */
.qual-pool {
    display: grid;
    gap: 9px;
    --qual-card-min: 150px;
    grid-template-columns: repeat(auto-fill, minmax(var(--qual-card-min), 1fr));
}

.qual-pool-many { --qual-card-min: 88px; gap: 7px; }

@media (min-width: 720px) {
    .qual-pool { --qual-card-min: 172px; }
    .qual-pool-many { --qual-card-min: 108px; }
}

.qual-card {
    border-radius: 9px;
    overflow: hidden;
    background: var(--mix-surface);
    display: flex;
    flex-direction: column;
    position: relative;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    appearance: none;
    padding: 0;
    margin: 0;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
    transition: transform .13s ease, filter .13s ease;
}

.qual-card:hover { transform: translateY(-2px); filter: brightness(1.09); }
.qual-card:focus-visible { outline: 2px solid var(--mix-ink); outline-offset: 2px; }

.qual-card-jacket {
    position: relative;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    display: block;
}

/* Scoped to the art itself, never `.qual-card-jacket img`: the difficulty bubble is a
   MudImage in this box too, and telling it to fill the frame stretched it across the whole
   tile. Same trap as .chart-jacket-art on the chart page. */
.qual-card-art {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.qual-card-jacket::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(7, 11, 21, .05) 40%, rgba(7, 11, 21, .88));
}

/* Same treatment as .chart-jacket-play on the chart page - the jacket is the
   button, and tapping it opens the chart with its video already running. */
.qual-card-play {
    position: absolute;
    left: 50%;
    top: 50%;
    translate: -50% -50%;
    z-index: 3;
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    padding-left: 2px;
    border-radius: 99px;
    pointer-events: none;
    background: rgba(0, 0, 0, .8);
    border: 1px solid rgba(255, 255, 255, .2);
    color: #fff;
    opacity: .85;
    transform: scale(.94);
    transition: opacity .12s, transform .12s, background .12s, border-color .12s;
}

.qual-card-play::before {
    content: "";
    border-style: solid;
    border-width: 6px 0 6px 10px;
    border-color: transparent transparent transparent currentColor;
}

.qual-card:hover .qual-card-play,
.qual-card:focus-visible .qual-card-play { opacity: 1; transform: scale(1); }
.qual-card:hover .qual-card-play { background: rgba(0, 0, 0, .93); border-color: var(--mix-primary); }

.qual-pool-many .qual-card-play { width: 26px; height: 26px; }
.qual-pool-many .qual-card-play::before { border-width: 5px 0 5px 8px; }

.qual-card-bubble { position: absolute; left: 5px; top: 5px; z-index: 2; }

.qual-card-name {
    position: absolute;
    left: 6px;
    right: 6px;
    bottom: 4px;
    z-index: 2;
    font-size: 10.5px;
    font-weight: 700;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .9);
}

.qual-card-body {
    padding: 7px;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.qual-card-result { display: flex; align-items: center; gap: 6px; }

.qual-card-grade {
    font-weight: 800;
    font-size: 11px;
    letter-spacing: .02em;
    flex: 0 0 auto;
}

.qual-card-score { font-variant-numeric: tabular-nums; font-size: 11.5px; color: var(--mix-ink-muted); }

.qual-card-rating {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 13px;
}

.qual-card-empty { font-size: 11.5px; color: var(--mix-ink-muted); }

.qual-card-state {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    align-self: flex-start;
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: .09em;
    text-transform: uppercase;
    padding: 2px 6px;
    border-radius: 4px;
}

.qual-card-state-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

/* Four states, each with a ring, a word and a legend entry that agree. */
.qual-card-counting { box-shadow: inset 0 0 0 2px var(--mix-primary), 0 0 20px -10px var(--mix-glow); }

.qual-card-counting .qual-card-state {
    background: color-mix(in srgb, var(--mix-primary) 20%, transparent);
    color: var(--mix-primary);
}

.qual-card-banked { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mix-ink) 28%, transparent); }

.qual-card-banked .qual-card-state {
    background: color-mix(in srgb, var(--mix-ink) 10%, transparent);
    color: var(--mix-ink-muted);
}

/* The suggested state: a gold ring on a chart you have not posted yet. This is the
   nudge the original page computed and, from 2025-06-16, stopped painting. */
.qual-card-suggested { box-shadow: inset 0 0 0 2px var(--mix-accent); }

.qual-card-suggested .qual-card-state {
    background: color-mix(in srgb, var(--mix-accent) 20%, transparent);
    color: var(--mix-accent);
}

.qual-legend-suggested { background: var(--mix-accent); }

.qual-card-untouched {
    border-style: dashed;
    border-color: color-mix(in srgb, var(--mix-ink) 24%, transparent);
    background: transparent;
}

.qual-card-untouched .qual-card-state {
    background: color-mix(in srgb, var(--mix-ink) 7%, transparent);
    color: var(--mix-ink-muted);
}

.qual-card-untouched .qual-card-art { opacity: .5; }

.qual-legend { display: flex; flex-wrap: wrap; gap: 5px 12px; padding-top: 2px; }

.qual-legend span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 10.5px;
    color: var(--mix-ink-muted);
}

.qual-legend i { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 auto; }
.qual-legend-counting { background: var(--mix-primary); }
.qual-legend-banked { background: color-mix(in srgb, var(--mix-ink) 35%, transparent); }
.qual-legend-untouched { border: 1.5px dashed color-mix(in srgb, var(--mix-ink) 45%, transparent); }

/* ---- entrants with no score, off the ladder ---- */
.qual-unscored {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 8px;
    font-size: 12px;
    color: var(--mix-ink-muted);
    border-top: 1px dashed color-mix(in srgb, var(--mix-ink) 18%, transparent);
}

.qual-unscored b { color: var(--mix-ink); font-weight: 600; }

/* ---- how this is scored ---- */
.qual-rules {
    padding: 11px 13px;
    border-radius: 10px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.qual-rules p { margin: 0; font-size: 12.5px; color: var(--mix-ink-muted); }
.qual-rules p b { color: var(--mix-ink); font-weight: 600; }

.qual-closed {
    padding: 11px 13px;
    border-radius: 10px;
    font-size: 12.5px;
    background: color-mix(in srgb, var(--mix-secondary) 14%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mix-secondary) 45%, transparent);
}

/* ---- submit dialog ---- */
.qual-submit-hero {
    position: relative;
    aspect-ratio: 16 / 7;
    overflow: hidden;
    border-radius: 8px;
    margin-bottom: 10px;
}

/* Same scoping as the pool tile: the hero carries a bubble as well as the art. */
.qual-submit-hero-art { width: 100%; height: 100%; object-fit: cover; display: block; }

.qual-submit-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(7, 11, 21, .15) 30%, rgba(22, 30, 44, .97));
}

.qual-submit-hero-text {
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: 8px;
    z-index: 2;
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
}

.qual-submit-hero-text h3 {
    margin: 0;
    font-size: 17px;
    font-weight: 700;
    text-shadow: 0 2px 6px rgba(0, 0, 0, .85);
}

.qual-drop {
    border: 2px dashed color-mix(in srgb, var(--mix-ink) 28%, transparent);
    border-radius: 9px;
    padding: 16px 12px;
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 5px;
    align-items: center;
    transition: border-color .13s, background .13s;
}

.qual-drop:hover {
    border-color: var(--mix-primary);
    background: color-mix(in srgb, var(--mix-primary) 8%, transparent);
}

.qual-drop-title { font-size: 13px; font-weight: 700; }
.qual-drop-hint { font-size: 11px; color: var(--mix-ink-muted); }

.qual-drop-filled {
    border-style: solid;
    border-color: var(--mix-primary);
    padding: 0;
    overflow: hidden;
}

.qual-drop-filled img { width: 100%; display: block; max-height: 150px; object-fit: cover; }

.qual-judge {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 7px;
}

.qual-calc {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 10px 11px;
    border-radius: 8px;
    background: color-mix(in srgb, var(--mix-ink) 6%, transparent);
}

.qual-calc-label {
    font-size: 9px;
    font-weight: 800;
    letter-spacing: .11em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.qual-calc-value {
    font-size: 19px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.02em;
}

.qual-calc-tail {
    margin-left: auto;
    text-align: right;
    display: flex;
    flex-direction: column;
    gap: 1px;
    align-items: flex-end;
}

.qual-calc-plate { font-size: 11px; font-weight: 700; }

/* ---- the organiser's own screen ----
   Photos live here and nowhere else: they are reference material for the TO,
   not evidence the field has to audit. There is no approval queue. */
.qual-admin-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 10px 12px;
    border-radius: 10px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

.qual-admin-kicker {
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: .15em;
    text-transform: uppercase;
    color: var(--mix-accent);
}

.qual-admin-bar h1 {
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    letter-spacing: -.012em;
}

.qual-tallies {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 7px;
}

.qual-tally {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
    border-radius: 8px;
    padding: 8px;
}

.qual-tally-key {
    font-size: 8.5px;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.qual-tally-value {
    font-size: 17px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.02em;
}

.qual-tally-flag { color: var(--mix-accent); }

/* duplicates: the pair side by side, keep versus delete */
.qual-dupe {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 10px 11px;
    border-radius: 10px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

.qual-dupe p { margin: 0; font-size: 11.5px; color: var(--mix-ink-muted); line-height: 1.45; }
.qual-dupe p b { color: var(--mix-ink); }

.qual-dupe-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 7px 9px;
    border-radius: 7px;
    background: color-mix(in srgb, var(--mix-ink) 6%, transparent);
}

.qual-dupe-keep { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--type-doubles) 60%, transparent); }
.qual-dupe-name { font-weight: 700; font-size: 12.5px; }
.qual-dupe-meta { font-size: 10.5px; color: var(--mix-ink-muted); }

.qual-dupe-total {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 13px;
}

/* entries */
.qual-entry {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 7px 8px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
}

.qual-entry-stale { background: color-mix(in srgb, var(--mix-accent) 8%, transparent); }

.qual-entry-who {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 120px;
}

.qual-entry-name {
    font-weight: 600;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qual-entry-sub {
    font-size: 10px;
    color: var(--mix-ink-muted);
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
}

.qual-source-chip {
    font-size: 8.5px;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
    padding: 1px 5px;
    border-radius: 3px;
    flex: 0 0 auto;
}

.qual-source-account {
    background: color-mix(in srgb, var(--mix-primary) 20%, transparent);
    color: var(--mix-primary);
}

.qual-source-anon {
    background: color-mix(in srgb, var(--mix-ink) 10%, transparent);
    color: var(--mix-ink-muted);
}

.qual-entry-tail {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}

.qual-entry-total { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13.5px; }

/* per-entry submission review */
.qual-submission {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    padding: 7px 8px;
    border-radius: 8px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
}

.qual-submission-jacket {
    width: 46px;
    height: 26px;
    border-radius: 4px;
    object-fit: cover;
    flex: 0 0 auto;
    display: block;
}

.qual-submission-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 auto;
}

.qual-submission-name {
    font-size: 12px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qual-submission-row {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: var(--mix-ink-muted);
}

.qual-submission-tail {
    margin-left: auto;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 7px;
}

/* An imported score has no photo because the official site is the evidence. */
.qual-no-photo {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    padding: 3px 6px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--mix-ink) 7%, transparent);
    text-align: center;
    line-height: 1.25;
    flex: 0 0 auto;
}

.qual-photo {
    max-width: 100%;
    border-radius: 8px;
    display: block;
    margin: 0 auto;
}

.qual-danger {
    padding: 9px 11px;
    border-radius: 8px;
    font-size: 12px;
    line-height: 1.45;
    background: color-mix(in srgb, var(--mix-secondary) 14%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mix-secondary) 42%, transparent);
}

.qual-danger b { font-weight: 700; }

.qual-confirm-list {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin-top: 9px;
}

.qual-confirm-item {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    padding: 6px 9px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--mix-ink) 6%, transparent);
}

.qual-confirm-item-tail {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    color: var(--mix-ink-muted);
}

.qual-setup-row {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 7px 0;
    font-size: 12.5px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
}

.qual-setup-row:last-child { border-bottom: 0; }
.qual-setup-key { color: var(--mix-ink-muted); }
.qual-setup-value { margin-left: auto; font-weight: 700; text-align: right; }

/* Both qualifier dialogs ask for MaxWidth.False on purpose: MaxWidth.Small would tag them
   `mud-dialog-width-sm`, and charts.css carries a site-wide
   `.mud-dialog-width-sm { max-width: none !important }` that no normal-weight rule can beat.
   With False, MudBlazor never applies that class and these caps govern. */
.mud-dialog.qual-dialog {
    max-width: 520px;
}

.mud-dialog.qual-photo-dialog {
    max-width: 720px;
}

.mud-dialog.qual-photo-dialog .qual-photo {
    max-height: 60vh;
    width: auto;
    object-fit: contain;
}

/* Row breakdown: a chip opens the scores behind the total rather than the chart page. */
.qual-breakdown {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 6px 8px 12px;
}

.qual-breakdown-row {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 8px;
    border-radius: 8px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
}

.qual-breakdown-art {
    width: 46px;
    height: 26px;
    border-radius: 4px;
    object-fit: cover;
    flex: 0 0 auto;
    display: block;
}

.qual-breakdown-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    flex: 1 1 auto;
}

.qual-breakdown-name {
    font-size: 12.5px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qual-breakdown-sub { display: flex; align-items: center; gap: 6px; }

.qual-breakdown-rating {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    font-size: 13.5px;
    flex: 0 0 auto;
}

/* Chart picker: the jacket is the identifier here too, and a long song title truncates
   rather than wrapping the row to two lines. */
.qual-pick {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    width: 100%;
}

.qual-pick-art {
    width: 54px;
    height: 30px;
    border-radius: 4px;
    object-fit: cover;
    flex: 0 0 auto;
    display: block;
}

.qual-pick-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ===== ChartLeaderboardDialog =====================================================
   The scope rail is the only new furniture here; rows, glows and place colouring are
   LeaderboardDialog's .weekly-lb-* vocabulary so the two boards read as one system. */

.cld-scopes {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    padding-bottom: 10px;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
}

.cld-sub {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    padding: 9px 0;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
}

.cld-chip {
    font-size: .74rem;
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .14);
    background: color-mix(in srgb, var(--mix-ink) 4%, transparent);
    color: var(--mix-ink-muted);
    cursor: pointer;
    white-space: nowrap;
    font-family: inherit;
}

.cld-chip:hover:not(:disabled) {
    color: var(--mix-ink);
}

.cld-chip-on {
    background: color-mix(in srgb, var(--mix-primary) 16%, transparent);
    border-color: color-mix(in srgb, var(--mix-primary) 55%, transparent);
    color: var(--mix-ink);
    font-weight: 600;
}

/* A scope with nothing behind it greys and explains nothing — a disabled control already
   reads as "not here", and a sentence about cohorts costs more than it buys. */
.cld-chip-off {
    opacity: .4;
    cursor: default;
}

.cld-standing {
    display: flex;
    align-items: baseline;
    gap: 9px;
    padding: 10px 0 8px;
}

.cld-standing-place {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.35rem;
    font-variant-numeric: tabular-nums;
}

.cld-standing-scope {
    font-size: .72rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.cld-body {
    max-height: 46vh;
    overflow-y: auto;
}

.cld-empty {
    padding: 18px 4px;
    text-align: center;
    font-size: .85rem;
    color: var(--mix-ink-muted);
}

/* ===== Session breakdown (/Player/{id}/Sessions) ==================================
   The hero's own vocabulary. Score rows are the page's own; the peer boards borrow
   .weekly-lb-* so every ranked list on the site reads the same way. */

.sbd-hero {
    border-radius: 8px;
    overflow: hidden;
}

.sbd-hero-head {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 14px 18px;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
}

.sbd-hero-who {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.sbd-hero-title {
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 600;
    line-height: 1.1;
}

.sbd-hero-when {
    font-size: .78rem;
    color: var(--mix-ink-muted);
}

.sbd-hero-tag {
    margin-left: 6px;
    padding: 1px 7px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .14);
}

.sbd-tally {
    margin-left: auto;
    display: flex;
    gap: 18px;
}

.sbd-tally div {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
}

.sbd-tally-v {
    font-family: var(--font-display);
    font-size: 1.4rem;
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.sbd-pass {
    color: var(--mud-palette-success);
}

.sbd-up {
    color: var(--mix-primary);
}

.sbd-tally-k {
    font-size: .62rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.sbd-eyebrow {
    font-family: var(--font-display);
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

/* --- the answer, above the fold --------------------------------------------- */
.sbd-ceremony {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    border-bottom: 1px solid rgba(255, 255, 255, .07);
}

.sbd-pumb {
    padding: 20px 18px 18px;
    border-right: 1px solid rgba(255, 255, 255, .07);
}

.sbd-pumb-lead {
    display: flex;
    align-items: flex-end;
    gap: 12px;
    flex-wrap: wrap;
}

.sbd-pumb-big {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 3.6rem;
    line-height: .86;
    letter-spacing: -.015em;
    font-variant-numeric: tabular-nums;
    color: var(--rarity-prism);
    text-shadow: 0 0 14px var(--mix-glow);
}

.sbd-delta {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.1rem;
    line-height: 1;
    color: var(--mud-palette-success);
    font-variant-numeric: tabular-nums;
}

.sbd-from {
    margin-top: 8px;
    font-size: .76rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.sbd-rank {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid rgba(255, 255, 255, .07);
    display: flex;
    align-items: baseline;
    gap: 9px;
    flex-wrap: wrap;
}

.sbd-rank-value {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.35rem;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    color: var(--rarity-sapphire);
}

.sbd-asof {
    font-size: .68rem;
    color: var(--mix-ink-muted);
}

.sbd-compet {
    padding: 20px 18px 18px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.sbd-compet-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
}

.sbd-compet-label {
    font-size: .76rem;
    color: var(--mix-ink-muted);
    width: 62px;
    flex: none;
}

.sbd-compet-value {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.3rem;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

/* --- sections ---------------------------------------------------------------- */
.sbd-section {
    padding: 14px 18px;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
}

.sbd-section:last-child {
    border-bottom: 0;
}

.sbd-section-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.sbd-section-note {
    font-size: .72rem;
    color: var(--mix-ink-muted);
    margin-left: auto;
}

/* --- title bars -------------------------------------------------------------- */
.sbd-tbar {
    margin-bottom: 14px;
}

.sbd-tbar:last-child {
    margin-bottom: 0;
}

.sbd-tbar-meta {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

.sbd-tbar-scope {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: .8rem;
    color: var(--mix-ink-muted);
    min-width: 28px;
}

.sbd-tbar-name {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1rem;
}

.sbd-tbar-pct {
    margin-left: auto;
    font-family: var(--font-display);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.sbd-tbar-was {
    color: var(--mix-ink-muted);
    font-weight: 400;
}

.sbd-tbar-cap {
    margin-top: 5px;
    font-size: .72rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.sbd-track {
    position: relative;
    height: 11px;
    border-radius: 6px;
    background: var(--mix-surface-muted);
    border: 1px solid rgba(255, 255, 255, .07);
    overflow: hidden;
}

.sbd-track-held {
    position: absolute;
    inset: 0 auto 0 0;
    background: color-mix(in srgb, var(--mix-primary) 34%, transparent);
}

/* The travelled segment is the point of the bar, so it is the only part that glows. */
.sbd-track-gain {
    position: absolute;
    top: 0;
    bottom: 0;
    background: linear-gradient(90deg, var(--mix-primary), var(--rarity-prism));
    box-shadow: 0 0 12px var(--mix-glow);
}

/* --- score rows --------------------------------------------------------------- */
.sbd-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 2px;
    border-bottom: 1px solid rgba(255, 255, 255, .05);
}

.sbd-row:last-child {
    border-bottom: 0;
}

.sbd-row-body {
    flex: 1;
    min-width: 0;
}

.sbd-row-line {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.sbd-badge {
    font-size: .74rem;
}

.sbd-peerpct {
    font-size: .68rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

/* "Stage break · 31% in" — where a grade, plate and number would sit on a finished play. Muted
   ink, no glow, no colour: the run set no score, so there is nothing to rank or to celebrate,
   and the row must not read as a result. */
.sbd-stagebreak {
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

/* "+27,450 over P1". Gold rather than the success green every other gain on this row
   wears: the tail already prints a green delta over your previous Phoenix 2 score, and
   two green numbers measuring different baselines a few pixels apart read as one fact
   repeated. Plain text, not a pill — the pumbility badge is the only outlined thing a
   row gets. */
.sbd-p1 {
    font-size: .72rem;
    color: var(--rarity-gold);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* What this play added to your PUMBILITY pool. The tier list's gain treatment, moved onto a
   row: success green on a green hairline over an 82%-black ground, the same build the
   pumbility page's targets wear so one number means one thing across both pages. The only
   outlined thing in the strip — everything beside it is a bare glyph, which is the point. */
.sbd-gain {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: .74rem;
    line-height: 1.25;
    font-variant-numeric: tabular-nums;
    background: rgba(0, 0, 0, .82);
    color: var(--mud-palette-success);
    border: 1px solid var(--mud-palette-success);
    border-radius: 2px;
    padding: 1px 5px;
    white-space: nowrap;
}

/* "23.6 (+0.4)" — the arrow's caption rather than a badge of its own, so it stays quiet
   next to the glyph it explains. */
.sbd-comp {
    font-size: .72rem;
    color: var(--mud-palette-success);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.sbd-row-tail {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
}

.sbd-lbbtn {
    flex: none;
}

/* --- community peers ---------------------------------------------------------- */
.sbd-peerboard {
    margin-bottom: 14px;
}

.sbd-peerboard:last-child {
    margin-bottom: 0;
}

.sbd-peerboard-head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 5px;
}

.sbd-peerboard-name {
    font-weight: 600;
    font-size: .86rem;
}

.sbd-peer-club {
    font-size: .68rem;
    color: var(--mix-ink-muted);
    margin-left: 6px;
}

/* Empty states name the action that fills them (UX rule 9). */
.sbd-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 3px;
    padding: 18px;
    border: 1px dashed rgba(255, 255, 255, .14);
    border-radius: 6px;
    font-size: .8rem;
    color: var(--mix-ink-muted);
}

/* --- history table ------------------------------------------------------------ */
.sbd-history {
    margin-top: 8px;
}

.sbd-history-table .sbd-num {
    text-align: right;
}

.sbd-history-current td {
    background: color-mix(in srgb, var(--mix-primary) 8%, transparent);
}

.sbd-mixdot {
    display: inline-block;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    margin-right: 6px;
    vertical-align: middle;
}

.sbd-viewing {
    font-size: .7rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

/* The width ladder stacks the ceremony below the shell's own 960 switch. */
@media (max-width: 959.98px) {
    .sbd-ceremony {
        grid-template-columns: 1fr;
    }

    .sbd-pumb {
        border-right: 0;
        border-bottom: 1px solid rgba(255, 255, 255, .07);
    }

    .sbd-tally {
        width: 100%;
        margin-left: 0;
        justify-content: space-between;
    }
}

/* Height, not aspect: a landscape phone is 844 WIDE and 390 TALL, so the width rule above
   would stack the ceremony exactly when the scarce axis is vertical. A fold unfolded and a
   landscape tablet are both squarish but have height to spare and must not compress. */
@media (max-height: 520px) {
    .sbd-ceremony {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }

    .sbd-pumb {
        border-right: 1px solid rgba(255, 255, 255, .07);
        border-bottom: 0;
        padding: 12px 16px;
    }

    .sbd-pumb-big {
        font-size: 2.4rem;
    }

    .sbd-from {
        display: none;
    }

    .sbd-compet {
        padding: 12px 16px;
        gap: 8px;
    }

    .sbd-tbar-cap {
        display: none;
    }
}

/* ===== Session history cards =======================================================
   Replaces the table. Jackets and counts come from the journal so every session has
   them; the footer only exists where capture ran, which is why the art carries the
   card and the headline is a bonus. */

.sbd-history-filter {
    margin-left: auto;
}

.sbd-datepicker {
    max-width: 170px;
}

/* Four across the 1132px content column at the 268px floor — the page size is two full
   rows, because a page ending mid-row reads as a rendering fault. */
.sbd-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
    gap: 14px;
}

.sbd-card {
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .12);
    border-top: 2px solid var(--mix-primary);
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    cursor: pointer;
    transition: border-color .12s, box-shadow .12s;
}

.sbd-card:hover {
    border-color: color-mix(in srgb, var(--mix-primary) 45%, transparent);
}

.sbd-card:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
}

.sbd-card-now {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--mix-primary) 45%, transparent),
    0 0 22px color-mix(in srgb, var(--mix-primary) 13%, transparent);
}

.sbd-card-head {
    padding: 10px 13px 8px;
}

.sbd-card-when {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.15;
}

.sbd-card-meta {
    font-size: .72rem;
    color: var(--mix-ink-muted);
    margin-top: 1px;
}

.sbd-card-art {
    display: flex;
    gap: 4px;
    padding: 0 13px 10px;
    align-items: center;
}

.sbd-card-more {
    font-size: .72rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    margin-left: 2px;
}

.sbd-card-counts {
    display: flex;
    gap: 14px;
    padding: 0 13px 9px;
    align-items: baseline;
}

.sbd-card-k {
    display: flex;
    flex-direction: column;
}

.sbd-card-v {
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 600;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.sbd-card-l {
    font-size: .62rem;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.sbd-card-span {
    margin-left: auto;
    font-size: .68rem;
    color: var(--mix-ink-muted);
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: .04em;
}

/* Pinned to the bottom so cards of different heights still line their footers up. */
.sbd-card-foot {
    margin-top: auto;
    border-top: 1px solid rgba(255, 255, 255, .06);
    padding: 8px 13px;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    min-height: 37px;
}

.sbd-card-tag {
    font-size: .75rem;
    white-space: nowrap;
    color: var(--mix-accent);
}

.sbd-card-quiet {
    font-size: .72rem;
    color: var(--mix-ink-muted);
    font-style: italic;
}

.sbd-card-now-tag {
    margin-left: auto;
    font-family: var(--font-display);
    font-size: .64rem;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-primary);
}

@media (max-width: 599.98px) {
    .sbd-cards {
        grid-template-columns: 1fr;
    }

    .sbd-history-filter {
        margin-left: 0;
        width: 100%;
    }

    .sbd-datepicker {
        max-width: none;
    }
}

/* A targeted rebuild, not a page load: the content stays put and softens while it swaps.
   Skeletons belong to the first load only. */
.sbd-busy {
    opacity: .55;
    transition: opacity .12s ease-out;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    .sbd-busy {
        transition: none;
    }
}

/* ===== Leaderboard row trimmings ===================================================
   Flags come from UserLabel, which owns its own narrow-width behaviour: the flag is
   pinned and only the name shrinks. */

/* Stacking the grade over the plate buys back enough width that the avatar fits at
   every size, so it is no longer the thing that gets dropped. */
.sbd-avatar {
    display: inline-flex;
    align-items: center;
    flex: none;
}

/* The avatar's 24px is the row's height, and everything else here stays under it. These
   read at a glance by colour — the letter itself is confirmation, not the message — so
   they can run well below the type beside them without costing anything. */
.sbd-score-stack {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    line-height: 1.1;
}

.sbd-score-stack > img {
    height: 14px !important;
}

/* margin:0 is load-bearing, not tidiness. Nothing resets <p> — not the UA sheet, not
   MudBlazor, not this file — so the score arrives with a 1em block margin that pushes the
   stack past the row it sits in and leaves the number floating off the icons beside it. */
.sbd-score-stack > p {
    font-size: .82rem;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    margin: 0;
    align-self: center;
}

/* The always-stacked variant (UX rule 3, owner 2026-09-05): the grid at EVERY width, not only
   portrait. ScoreBreakdown Stacked="true" emits this wrapper itself, so a caller gets the pair
   exactly as tall as the number wherever it prints a score — session rows, MoM boards and cards. */
.sbd-score-stack.sbd-score-stack-fixed {
    display: inline-grid;
    grid-auto-flow: row;
    grid-template-columns: auto auto;
    grid-template-rows: repeat(2, auto);
    align-items: center;
    column-gap: 4px;
    row-gap: 0;
    line-height: 1.05;
}
.sbd-score-stack.sbd-score-stack-fixed > img {
    grid-column: 1;
    height: 11px !important;
}
.sbd-score-stack.sbd-score-stack-fixed > p {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    margin: 0;
    padding-left: 0 !important;
}

/* Portrait and square: grade above plate in one column, score beside them. Keyed on aspect
   rather than width because that is the axis that decides whether a row has horizontal room —
   a portrait tablet is wide in pixels and still short of it.

   These rows pass Tooltip="false" to ScoreBreakdown, so the icons and the score are direct
   children here and the grid can simply place them. Two earlier attempts tried to lay out
   through MudTooltip's wrapper instead, and neither worked: display:contents only flattened
   one level, and nth-of-type counts within each element's own parent, so images in separate
   wrappers both read as the first. */
@media (max-aspect-ratio: 1/1), (max-width: 599.98px) {
    /* The two rows are declared rather than left to auto-flow, because the score spans them
       with 1 / -1 and -1 counts back from the end of the EXPLICIT grid. Against implicit
       rows it resolves to line 1, the span collapses to a single row, and the score centres
       on the grade alone instead of on the pair. A broken score has no plate, and the second
       row is then an empty auto track, which is zero tall. */
    .sbd-score-stack {
        display: inline-grid;
        grid-auto-flow: row;
        grid-template-columns: auto auto;
        grid-template-rows: repeat(2, auto);
        align-items: center;
        column-gap: 4px;
        row-gap: 0;
        line-height: 1.05;
    }

    /* Both icons claim column 1; auto-flow drops them into successive rows. Two of them
       at 11px fit inside the avatar's 24px, so stacking costs the row no height over
       sitting side by side. */
    .sbd-score-stack > img {
        grid-column: 1;
        height: 11px !important;
    }

    .sbd-score-stack > p {
        grid-column: 2;
        grid-row: 1 / -1;
        align-self: center;
        margin: 0;
        padding-left: 0 !important;
    }
}

/* The club name is hidden on narrow screens only — a portrait tablet has the width for it,
   and it is width that was truncating it to a letter or two. */
@media (max-width: 599.98px) {
    .sbd-peer-club {
        display: none;
    }
}

.sbd-peer-level {
    font-size: .68rem;
    color: var(--mix-ink-muted);
    margin-left: 6px;
    font-variant-numeric: tabular-nums;
}

/* One line under a rivals board: what the asterisk means, and how much of the roster is missing.
   Silently dropping rivals would make a six-row board look like the whole list. */
.cld-footnote {
    font-size: .68rem;
    color: var(--mix-ink-muted);
    margin: 8px 0 0;
    padding-top: 7px;
    border-top: 1px solid rgba(255, 255, 255, .06);
}

/* ── Rivals (docs/design/rivals.md) ───────────────────────────────────────────────────── */

.rvl-roster {
    display: grid;
    gap: 6px;
}

.rvl-row {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 8px 10px;
    border-radius: 7px;
    background: var(--mix-surface-muted);
    font-size: .85rem;
}

.rvl-row-main {
    flex: 1;
    min-width: 0;
}

.rvl-row-name {
    font-weight: 600;
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.rvl-row-meta {
    font-size: .7rem;
    color: var(--mix-ink-muted);
    margin-top: 1px;
}

/* The reverse list carries three buttons on one row; on a phone they wrap into a block rather
   than pushing the row wider than the screen. */
.rvl-row-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 6px;
}

.rvl-tag {
    font-size: .6rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    font-weight: 700;
    padding: 1px 6px;
    border-radius: 3px;
    border: 1px solid;
}

.rvl-tag-ghost {
    color: var(--mix-accent);
    border-color: color-mix(in srgb, var(--mix-accent) 45%, transparent);
}

.rvl-tag-crew {
    color: var(--daily-community);
    border-color: color-mix(in srgb, var(--daily-community) 45%, transparent);
}

/* The player page's "Rival" tag: the rival red, the same token every board row wears for one. */
.rvl-tag-rival {
    color: var(--daily-rival);
    border-color: color-mix(in srgb, var(--daily-rival) 45%, transparent);
}

.rvl-tag-priv, .rvl-tag-gone {
    color: var(--mix-ink-muted);
    border-color: color-mix(in srgb, var(--mix-ink-muted) 40%, transparent);
}

/* A code you copy sits in a well below its card, not on a block above it: the page's own ground
   plus the hairline, which is how .ct-secret draws the API key. --mix-bg is the token; there is
   no --mix-background, and an undefined var() in a background shorthand computes to transparent,
   so this rendered as a bordered box with the card showing through. */
.rvl-code {
    display: flex;
    align-items: center;
    gap: 9px;
    background: var(--mix-bg);
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 5px;
    padding: 7px 11px;
}

.rvl-code-value {
    font-family: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, monospace;
    font-size: .92rem;
    letter-spacing: .1em;
    flex: 1;
}

.rvl-h2h-top {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 4px 2px 14px;
    flex-wrap: wrap;
}

.rvl-h2h-who {
    display: flex;
    align-items: center;
    gap: 9px;
}

.rvl-h2h-vs {
    font-family: var(--font-display);
    font-size: 1.1rem;
    color: var(--mix-ink-muted);
    letter-spacing: .1em;
}

.rvl-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
    gap: 8px;
}

.rvl-tile {
    background: var(--mix-surface-muted);
    border-radius: 6px;
    padding: 8px 10px;
    text-align: center;
}

.rvl-tile b {
    font-family: var(--font-display);
    font-size: 1.3rem;
    display: block;
    line-height: 1.05;
}

.rvl-tile span {
    font-size: .61rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--mix-ink-muted);
}

/* Ahead is the community green, behind is the rival red — the row-glow vocabulary doing a
   second job rather than a second palette meaning the same thing. */
.rvl-tile-win b, .rvl-ahead {
    color: var(--daily-community);
}

.rvl-tile-lose b, .rvl-behind {
    color: var(--daily-rival);
}

.rvl-muted {
    color: var(--mix-ink-muted);
}

.rvl-cmp-row {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 5px 4px;
    font-size: .8rem;
    border-radius: 5px;
}

.rvl-cmp-row + .rvl-cmp-row {
    border-top: 1px solid rgba(255, 255, 255, .05);
}

/* The chart cell is one hit target and one LINE. nowrap on the flex row is what stops the art
   and the bubble stacking when the column narrows — without it they wrap like words and the row
   grows a second storey. The name truncates instead, with the full title in the tooltip. */
.rvl-cmp-chart {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: nowrap;
    min-width: 0;
    cursor: pointer;
}

.rvl-cmp-chart > :not(.rvl-cmp-song) {
    flex: none;
}

.rvl-cmp-chart:hover .rvl-cmp-song {
    text-decoration: underline;
}

.rvl-cmp-song {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* MudTable ships its OWN overflow-x:auto container, so the scrolling at tablet widths was
   never the wrapper's — it was the table growing past its column and Mud's container obliging.
   Two things fix it, and both are needed.

   First, cap the chart column. A table cell sizes to its content, so a long song name widened
   the whole table instead of truncating inside it; nothing downstream could shrink it back. */
.rvl-cmp-table .mud-table-cell:first-child {
    max-width: 260px;
}

/* Second, the container only scrolls at mobile. Above that the row has room — the name is
   already gone below 760px (.olb-hide-mobile) — so a sideways scrollbar there is a control
   with nothing to do. */
.rvl-cmp-table .mud-table-container {
    overflow-x: visible;
}

@media (max-width: 599.98px) {
    .rvl-cmp-table .mud-table-container {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* The real floor of a mobile row: art, bubble and two score stacks, difference dropped. */
    .rvl-cmp-table .mud-table-container > table {
        min-width: 340px;
    }
}

/* Same breakpoint the score stack uses: at 1:1 and narrower the row has no horizontal room to
   spare, and the difference is the one column whose value is already on screen twice. */
@media (max-aspect-ratio: 1/1), (max-width: 599.98px) {
    .rvl-cmp-diff-col {
        display: none;
    }
}

.rvl-cmp-score {
    font-variant-numeric: tabular-nums;
    min-width: 74px;
    text-align: right;
}

.rvl-cmp-delta {
    min-width: 66px;
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-size: .74rem;
}

.rvl-cmp-score.rvl-ahead, .rvl-cmp-score.rvl-behind, .rvl-cmp-delta.rvl-ahead, .rvl-cmp-delta.rvl-behind {
    font-weight: 600;
}

.rvl-absent {
    padding: 9px 10px;
    border: 1px dashed rgba(255, 255, 255, .14);
    border-radius: 6px;
    font-size: .74rem;
    color: var(--mix-ink-muted);
}

/* ---------------------------------------------------------------------------
   Community Tools: the secret block.
   A key or an invite URL is a thing you copy, not a thing you read, so it wears
   the shape every other developer console uses for one — monospace on a recessed
   ground with the copy control welded to its edge, rather than body text with a
   button somewhere nearby.
   --------------------------------------------------------------------------- */
.ct-secret {
    display: flex;
    align-items: stretch;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 4px;
    background: color-mix(in srgb, var(--mix-bg) 60%, transparent);
    overflow: hidden;
}

.ct-secret pre {
    flex: 1;
    min-width: 0;
    margin: 0;
    padding: 10px 12px;
    font-family: ui-monospace, "Cascadia Mono", Consolas, "Liberation Mono", monospace;
    font-size: .82rem;
    line-height: 1.5;
    /* The value can be a 64-character key on a 360px phone, so it scrolls inside
       its own box rather than pushing the dialog sideways. */
    overflow-x: auto;
    white-space: pre;
}

.ct-secret .ct-secret-copy {
    flex: 0 0 auto;
    border-left: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 0;
    margin: 0;
}

/* Wraps instead of scrolling where the value is a URL a maker reads to tell two
   links apart. */
.ct-secret.ct-secret-wrap pre {
    white-space: pre-wrap;
    word-break: break-all;
    overflow-x: visible;
}

/* ---------------------------------------------------------------------------
   Community Tools: the first-tool wizard.
   Breadcrumbs rather than a step count. Several screens share a crumb — the
   key is created on one and read on the next — and a count would present that
   as more work to endure rather than as one job still in progress.
   --------------------------------------------------------------------------- */
.ct-wiz-crumbs {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    background: color-mix(in srgb, var(--mix-nav) 70%, transparent);
}

.ct-wiz-crumb {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 11px 14px 11px 18px;
    font-size: .82rem;
    font-weight: 600;
    color: var(--mix-ink-muted);
    background: none;
    border: 0;
    cursor: default;
    position: relative;
    font-family: inherit;
}

.ct-wiz-crumb + .ct-wiz-crumb { padding-left: 22px; }

.ct-wiz-crumb + .ct-wiz-crumb::before {
    content: "";
    position: absolute;
    left: 6px;
    top: 50%;
    width: 6px;
    height: 6px;
    margin-top: -3px;
    border-top: 1.5px solid color-mix(in srgb, var(--mix-ink) 20%, transparent);
    border-right: 1.5px solid color-mix(in srgb, var(--mix-ink) 20%, transparent);
    transform: rotate(45deg);
}

.ct-wiz-crumb .ct-wiz-tick {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 1.5px solid color-mix(in srgb, var(--mix-ink) 22%, transparent);
    display: grid;
    place-items: center;
    font-size: .62rem;
    line-height: 1;
}

.ct-wiz-crumb[data-state="done"] { color: var(--mix-ink); cursor: pointer; }
.ct-wiz-crumb[data-state="done"] .ct-wiz-tick { border-color: var(--rarity-emerald); color: var(--rarity-emerald); }
.ct-wiz-crumb[data-state="current"] { color: var(--mix-ink); box-shadow: inset 0 -2px 0 var(--mix-primary); }
.ct-wiz-crumb[data-state="current"] .ct-wiz-tick { border-color: var(--mix-primary); background: var(--mix-primary); }
.ct-wiz-crumb:focus-visible { outline: 2px solid var(--mix-primary); outline-offset: -2px; }

.ct-wiz-optional {
    font-weight: 500;
    opacity: .6;
    font-size: .72rem;
    margin-left: 4px;
}

.ct-wiz-body { padding: 22px 20px 8px; }

/* The controls belong to the step, not to the page around it — inside the
   card's border, on their own ground, right-aligned with the primary last the
   way every dialog in the app already does it. */
.ct-wiz-foot {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
    justify-content: flex-end;
    padding: 14px 20px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    background: color-mix(in srgb, var(--mix-nav) 55%, transparent);
}

.ct-wiz-foot .ct-wiz-note { margin-right: auto; font-size: .76rem; color: var(--mix-ink-muted); }

@media (max-width: 599.98px) {
    .ct-wiz-crumb { padding: 9px 8px 9px 14px; font-size: .74rem; }
    .ct-wiz-crumb + .ct-wiz-crumb { padding-left: 16px; }
    .ct-wiz-optional { display: none; }
}

/* The house rules. Set apart from app chrome because the voice inside is first
   person and singular — these are one person's rules, not the site talking — so
   the left rail is the secondary hue rather than the primary one every other
   panel uses. */
.ct-rules {
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-left: 3px solid var(--mix-secondary);
    border-radius: 4px;
    background: color-mix(in srgb, var(--mix-surface-muted) 60%, transparent);
    padding: 18px 20px;
}

.ct-rules-preamble {
    margin: 0 0 16px;
    border-left: 2px solid color-mix(in srgb, var(--mix-accent) 55%, transparent);
    padding-left: 12px;
    font-style: italic;
    max-width: 60ch;
}

.ct-rules ol {
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: ct-rule;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.ct-rules li {
    counter-increment: ct-rule;
    display: grid;
    grid-template-columns: 22px 1fr;
    gap: 10px;
}

.ct-rules li::before {
    content: counter(ct-rule);
    font-size: .74rem;
    font-weight: 700;
    color: var(--mix-secondary);
    font-variant-numeric: tabular-nums;
    padding-top: 3px;
}

.ct-rules li > div > b { display: block; margin-bottom: 2px; }

.ct-rules-foot {
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
}

.ct-rules-agree {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
}

/* Quieter than the rules above it: registration is the ordinary half of the screen. */
.ct-register {
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 4px;
    padding: 18px 20px;
}

/* The repository check state, beside the field it belongs to. */
.ct-check-state { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ---------------------------------------------------------------------------
   Developer console. The page is a section with routed destinations rather
   than one scroll, so the chrome here is nav plus grouping — the sections
   themselves are ordinary forms and board rows.
   --------------------------------------------------------------------------- */

.ct-console-head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}

.ct-console-pick {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 1.35rem;
    font-weight: 500;
    color: var(--mix-ink);
    background: none;
    border: 0;
    padding: 0;
    font-family: inherit;
    cursor: pointer;
}

span.ct-console-pick { cursor: default; }

.ct-console-nav {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 12px;
}

/* A group header carries its own escape hatch to the section that owns it. */
.ct-group {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin: 26px 0 10px;
}

.ct-group > :last-child { margin-left: auto; }

.ct-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
    gap: 10px;
}

.ct-stat {
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 4px;
    padding: 12px 14px;
}

.ct-stat .ct-stat-n {
    font-size: 1.55rem;
    font-weight: 500;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.ct-stat .ct-stat-n.ct-stat-sm { font-size: 1.1rem; }

.ct-stat .ct-stat-k {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--mix-ink-muted);
    margin-top: 3px;
}

/* Where every inline "why" paragraph went. Opened by the few who want it. */
.ct-why { margin: 4px 0 14px; max-width: 64ch; }

.ct-why summary {
    cursor: pointer;
    font-size: .78rem;
    color: var(--mix-primary);
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.ct-why summary::-webkit-details-marker { display: none; }

.ct-why summary::before {
    content: "?";
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 1px solid currentColor;
    font-size: .62rem;
    display: grid;
    place-items: center;
}

.ct-why[open] summary::before { content: "\00d7"; }

.ct-why p {
    margin: 7px 0 0 19px;
    font-size: .82rem;
    color: var(--mix-ink-muted);
}

/* One delivery mode, or one choice, per line — see the note in ToolWebhookPanel. */
.ct-choices {
    display: flex;
    flex-direction: column;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 4px;
    max-width: 620px;
}

.ct-choice {
    padding: 10px 14px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
}

.ct-choice:last-child { border-bottom: none; }

.ct-choice .ct-choice-sub {
    display: block;
    font-size: .8rem;
    color: var(--mix-ink-muted);
    margin-left: 32px;
}

/* ---------------------------------------------------------------------------
   Tool directory. Browsing is the job, so rows carry enough to choose from and
   the monogram gives each one something to aim at while scanning.
   --------------------------------------------------------------------------- */

.ct-dir-row {
    display: flex;
    align-items: center;
    gap: 13px;
    flex-wrap: wrap;
    padding: 12px 4px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
}

.ct-dir-row:last-child { border-bottom: none; }

/* Derived from the name — tools have no icon, and a letter is enough to make a
   list of rows scannable without inventing an image field for them. */
.ct-dir-mark {
    width: 38px;
    height: 38px;
    border-radius: 8px;
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    font-weight: 700;
    font-size: .9rem;
    color: var(--mix-bg);
}

.ct-dir-who { flex: 1 1 300px; min-width: 0; }

.ct-dir-tail {
    margin-left: auto;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* The page's standing answer to "who can see my stuff", in either direction. */
.ct-dir-strip {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-left: 3px solid var(--mix-primary);
    border-radius: 4px;
    padding: 10px 14px;
    margin-bottom: 22px;
}

.ct-dir-strip.ct-dir-strip-empty { border-left-color: var(--mix-ink-muted); }

.ct-dir-strip > :last-child { margin-left: auto; }

@media (max-width: 599.98px) {
    .ct-dir-mark { display: none; }
    .ct-dir-tail { margin-left: 0; width: 100%; }
}

/* A console section's content. No card, no border — the section nav above it is
   already the boundary, and a paper inside a paper is what made the old console
   read as a stack of equally-loud panels. */
.ct-section { display: block; }

/* ---------------------------------------------------------------------------
   Console cards. One responsibility per card, replacing the horizontal rules
   the sections used to separate concerns — a rule says "something changed"
   without saying what belongs to what, and a page of them reads as one strip.
   --------------------------------------------------------------------------- */

.ct-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 14px;
    align-items: start;
}

/* A card that owns a form wide enough to need the row, or a list. */
.ct-cards > .ct-card-wide { grid-column: 1 / -1; }

.ct-card {
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 6px;
    background: color-mix(in srgb, var(--mix-surface) 45%, transparent);
    overflow: hidden;
}

.ct-card-head {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 11px 16px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
    background: color-mix(in srgb, var(--mix-nav) 45%, transparent);
}

.ct-card-head .ct-card-action { margin-left: auto; }

.ct-card-body { padding: 16px; }

/* A revealed secret box: shown only after "Set new token", because an empty
   password field beside a value that already exists reads as "it is gone". */
.ct-reveal { max-width: 320px; }

/* ============================================================================
   PUMBILITY page (/Pumbility) — docs/design/pumbility-overhaul.md
   The bar is the organising device: the hero prints it, the curve draws it, the
   board rules it across the pool. Everything is --mix-* so it survives a mix
   switch without a circuit.
   ============================================================================ */

/* The shell leaves the page flush against the nav, and this one opens on an eyebrow rather
   than on a heading, so it owes itself the breathing room. It also carries the section's one
   outbound link on its right: space-between rather than margin-left:auto, so a label too long
   for the line drops to the left of the next line instead of stranding itself against the far
   edge (docs/design/pumbility-overhaul.md D15). */
.pmb-eyebrow {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 4px 16px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    margin: 16px 0 8px;
}

/* The only thing on the line that leaves the section, so it carries the primary rather than
   the eyebrow's muted ink. */
.pmb-eyebrow-link {
    color: var(--mix-primary);
    border-bottom: 1px dotted color-mix(in srgb, var(--mix-primary) 55%, transparent);
    text-decoration: none;
    padding-bottom: 1px;
}

.pmb-eyebrow-link:hover {
    border-bottom-color: var(--mix-primary);
}

.pmb-eyebrow-link:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
}

/* The section frame: the number, the pool selector and the bar, above the nav and shared by
   every page in the section. Everything in it starts at the same left edge — the bar card
   used to be pushed right, which reads fine on one line and strands it against the far edge
   with nothing under it the moment the row wraps. */
.pmb-frame {
    display: flex;
    align-items: center;
    gap: 14px 22px;
    flex-wrap: wrap;
    padding-bottom: 14px;
}

.pmb-frame-figure {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* Holds the band's height while the number is still arriving, so the nav under it does not
   jump once it lands. */
.pmb-frame-waiting {
    min-height: 74px;
}

.pmb-frame-nav {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    align-items: center;
    padding-top: 12px;
    margin-bottom: 4px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

.pmb-curve {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 14px 16px 16px;
}

.pmb-hero-value {
    font-size: 46px;
    line-height: .96;
}

.pmb-hero-sub {
    font-size: 13px;
    color: var(--mix-ink-muted);
    margin-top: 4px;
}

/* Pool selector — Phoenix 2 only, and it re-ranks the whole section. */
.pmb-poolsplit {
    display: flex;
    gap: 6px;
}

.pmb-poolsplit-seg {
    flex: 0 0 auto;
    min-width: 0;
    border-radius: 4px;
    padding: 6px 8px;
    cursor: pointer;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    background: transparent;
    color: var(--mix-ink-muted);
    font: inherit;
    font-size: 11px;
    text-align: left;
}

.pmb-poolsplit-seg strong {
    display: block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 17px;
    color: var(--mix-ink);
    font-variant-numeric: tabular-nums;
}

.pmb-poolsplit-seg[aria-pressed="true"] {
    border-color: var(--mix-primary);
    color: var(--mix-ink);
    background: color-mix(in srgb, var(--mix-primary) 12%, transparent);
}

.pmb-poolsplit-seg:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 2px;
}

/* The bar callout — the mechanic the section is organised around. */
.pmb-barcard {
    padding: 10px 12px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--mix-accent) 9%, transparent);
    border-left: 3px solid var(--mix-accent);
}

/* Not an empty state: below fifty charts nothing is displaced, so there is no bar
   rather than a missing one. */
.pmb-barcard-none {
    background: color-mix(in srgb, var(--mix-ink) 6%, transparent);
    border-left-color: color-mix(in srgb, var(--mix-ink) 25%, transparent);
}

.pmb-barcard-top {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.pmb-barcard-num {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 26px;
    color: var(--mix-accent);
    font-variant-numeric: tabular-nums;
}

.pmb-barcard-label {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.pmb-barcard-who {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    font-size: 12.5px;
    margin-top: 4px;
}

.pmb-barcard-say {
    font-size: 12px;
    color: var(--mix-ink-muted);
    margin-top: 5px;
}

.pmb-dot {
    color: var(--mix-ink-muted);
}

/* --- the pool curve --- */
.pmb-curve {
    display: flex;
    flex-direction: column;
}

.pmb-curve-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.pmb-curve-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 16px;
}

.pmb-curve-note {
    font-size: 12px;
    color: var(--mix-ink-muted);
}

/* A DEFINITE height, not min-height. Every bar sizes itself with a percentage height, and a
   percentage resolves against auto as auto — so the whole plot painted empty the moment the
   curve stopped being a grid cell that stretched to a neighbour's height. */
.pmb-curve-plot {
    position: relative;
    height: 190px;
    display: flex;
    align-items: flex-end;
    gap: 2px;
}

.pmb-cbar {
    flex: 1;
    min-width: 0;
    border-radius: 1px 1px 0 0;
    background: var(--chart-doubles);
}

.pmb-cbar.s {
    background: var(--chart-singles);
}

.pmb-cbar.ghost {
    opacity: .3;
}

.pmb-cbar.is-bar {
    outline: 1px solid var(--mix-accent);
}

.pmb-curve-line {
    position: absolute;
    left: 0;
    right: 0;
    border-top: 1px dashed var(--mix-accent);
    pointer-events: none;
}

.pmb-curve-line span {
    position: absolute;
    right: 0;
    top: -18px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 11px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-accent);
    background: var(--mix-surface);
    padding: 0 4px;
}

.pmb-curve-axis {
    display: flex;
    justify-content: space-between;
    font-size: 10.5px;
    color: var(--mix-ink-muted);
    margin-top: 5px;
}

.pmb-curve-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 5px 14px;
    font-size: 11.5px;
    color: var(--mix-ink-muted);
    margin-top: 6px;
}

.pmb-legend-ghost {
    opacity: .6;
}

.pmb-swatch {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 2px;
    margin-right: 5px;
    vertical-align: -1px;
}

.pmb-swatch-ghost {
    background: var(--chart-doubles);
    opacity: .3;
}

.pmb-curve-read {
    margin: 10px 0 0;
    padding-top: 10px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    font-size: 13px;
}

/* --- sections --- */
.pmb-block {
    margin-top: 28px;
}

.pmb-block-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 4px;
}

.pmb-block-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 22px;
    margin: 0;
}

.pmb-block-lede {
    font-size: 13.5px;
    color: var(--mix-ink-muted);
    max-width: 62ch;
    margin: 2px 0 14px;
}

/* What the list is standing on when it is standing on very little — a thin peer band, a pool
   short of fifty. A muted line in the lede's own slot rather than a chip: a chip reads as a
   status badge, and this is a sentence the player has to actually read once. */
.pmb-block-note {
    font-size: 12.5px;
    line-height: 1.45;
    color: color-mix(in srgb, var(--mix-ink-muted) 88%, var(--mix-bg));
    max-width: 62ch;
    margin: 0 0 12px;
}

/* The Phoenix 2 peer line under the targets' lede: one chip per chart type in the selected pool —
   the peer count, or "N/50 charts" for a type whose pool is not yet full — with the definition in
   the chip's tooltip. A count, not a sentence (docs/design/pumbility-overhaul.md §3.3). */
.pmb-peer-line {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: -6px 0 12px;
}

.pmb-peer-chip {
    display: inline-block;
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
    padding: 4px 8px;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
    color: var(--mix-ink);
    cursor: help;
}

.pmb-peer-chip[data-lit="false"] {
    color: var(--mix-ink-muted);
    font-weight: 500;
    border-style: dashed;
}


/* --- targets, comfortable --- */
/* One treatment for both jacket badges: the mix accent on the mix accent, over the black
   backdrop. The number says how MUCH and nothing else, the grade says what you would come
   away with — which KIND of row it is rides the card's border (owner, 2026-08-06).
   Deliberately the mix accent rather than the pass green: the border language owns green,
   and MixPalette.Success is one constant across every mix, so a badge painted with it says
   nothing about where you are. Declared AFTER .tier-chart-card-corner so it wins that rule's
   border shorthand on source order, the same contract the card border language runs on. */
.pmb-corner-gain {
    border-color: var(--mix-primary);
    color: var(--mix-primary);
}

.pmb-legend {
    margin-top: 0;
}

.pmb-tcard-meta {
    font-size: 11.5px;
    color: var(--mix-ink-muted);
    margin-top: 3px;
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.pmb-tcard-why {
    font-size: 11px;
    margin-top: 3px;
}

.pmb-arrow {
    color: var(--mix-ink-muted);
    font-size: 11px;
}

.pmb-none {
    color: var(--mix-ink-muted);
}

.pmb-num {
    font-variant-numeric: tabular-nums;
}

.pmb-muted {
    color: var(--mix-ink-muted);
}

.pmb-empty {
    color: var(--mix-ink-muted);
    font-size: 13.5px;
}

/* --- targets, table --- */
.pmb-table td {
    white-space: nowrap;
}

.pmb-table .pmb-r {
    text-align: right;
}

.pmb-row {
    cursor: pointer;
}

.pmb-ident {
    white-space: normal;
}

.pmb-ident-cell {
    display: flex;
    align-items: center;
    gap: 8px;
}

.pmb-ident-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 30ch;
}

.pmb-gain-cell {
    color: var(--mix-primary);
    font-variant-numeric: tabular-nums;
}

/* The Peers IQR: the peers' first and third quartiles as two grades with a dash between them
   (docs/design/pumbility-overhaul.md D30). One dash on every row — the grades say the width. */
.pmb-iqr {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    cursor: help;
}

.pmb-iqr-conn {
    color: var(--mix-ink-muted);
    font-size: 12px;
    line-height: 1;
}

.pmb-iqr-label {
    font-family: var(--font-display);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

/* --- Your PUMBILITY peers: the Phoenix 2 Play page (docs/design/pumbility-overhaul.md §3.10) --- */
/* The control row above the list: grouped-by, its switch, then the density trio at the far end. */
.pmb-peers-controls {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 6px 14px;
    flex-wrap: wrap;
    margin: 6px 0 4px;
}

/* The left half: the select and whichever switch that grouping owns, side by side. Their
   position is structural — space-between over two groups — rather than the result of an auto
   margin, because two auto margins in one row split the slack and put the switch in the middle. */
.pmb-peers-controls-start {
    display: inline-flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 6px 14px;
    min-width: 0;
}

/* The select sizes to its longest option and no further: at desktop width a flex item with
   only a min-width took the whole row, which put the density trio a screen away from it. */
.pmb-peers-controls-select {
    min-width: 170px;
    max-width: 230px;
    flex: 0 1 230px;
}

/* The switch group, immediately right of the select inside the left half. MudBlazor's own left
   offset on a switch is taken out so it starts where the select's text does when the row wraps. */
.pmb-peers-controls-switches {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    gap: 14px;
}

.pmb-peers-controls-switches .mud-switch {
    margin-left: 0;
}

.pmb-peers-controls-end {
    display: inline-flex;
    align-items: center;
}

/* Under Projected gains the prevalence tier rides a top-edge stripe on a Compact tile, since
   the corner is the gain's and the top-right dot is the variability's. */
.pmb-prevalence-stripe {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
}

/* The card body's peers line: label, the median grade, the variability. */
.pmb-peers-line {
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
    font-size: 12px;
    color: var(--mix-ink-muted);
    line-height: 1.5;
}

.pmb-peers-line-label {
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    font-size: 10.5px;
}

.pmb-peers-none {
    color: color-mix(in srgb, var(--mix-ink-muted) 75%, transparent);
    font-size: 11.5px;
}

.pmb-pool-line {
    display: block;
    font-size: 11.5px;
    color: var(--mix-ink-muted);
}

.pmb-pool-line b {
    color: var(--mix-ink);
    font-weight: 600;
}

/* A carried Phoenix 1 row's line: your score there, repriced here (D29, D38). */
.pmb-carried-line {
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
    font-size: 11.5px;
    color: var(--mud-palette-success);
}

/* Gain-band sections under Projected gains wear the gain's own colour, not a ramp — the
   rarity ramp is the prevalence tiers' and one hue meaning two things on one page is a mess. */
.pmb-gain-section .tier-section-name {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: .01em;
}

/* The roster (D39): the tier table's skin, your own row highlighted where you would sit, and
   the site's you/crew/rival vocabulary over it (field test round one). The utility set paints a
   row element; a table row cannot carry that shadow across collapsed cells, so the same geometry
   is drawn on the cells here — tint on every cell, the edge bars on the first and the last. */
.pmb-roster tr.is-rival td {
    background: color-mix(in srgb, var(--daily-rival) 13%, transparent);
}

.pmb-roster tr.is-community td {
    background: color-mix(in srgb, var(--daily-community) 13%, transparent);
}

/* Both: the utility set splits the fill left-to-right and puts a different colour at each end.
   A cell cannot carry half of a row-wide gradient, so the fill is the two tints over each other
   and the ends still say which is which. */
.pmb-roster tr.is-both td {
    background: color-mix(in srgb, var(--daily-rival) 8%,
        color-mix(in srgb, var(--daily-community) 9%, transparent));
}

.pmb-roster tr.is-rival td:first-child,
.pmb-roster tr.is-both td:first-child {
    box-shadow: inset 3px 0 0 var(--daily-rival);
}

.pmb-roster tr.is-rival td:last-child {
    box-shadow: inset -3px 0 0 var(--daily-rival);
}

.pmb-roster tr.is-community td:first-child {
    box-shadow: inset 3px 0 0 var(--daily-community);
}

.pmb-roster tr.is-community td:last-child,
.pmb-roster tr.is-both td:last-child {
    box-shadow: inset -3px 0 0 var(--daily-community);
}

.pmb-roster tr.pmb-roster-you td {
    background: color-mix(in srgb, var(--daily-you) 12%, transparent);
}

.pmb-roster tr.pmb-roster-you td:first-child {
    box-shadow: inset 3px 0 0 var(--daily-you);
}

.pmb-roster-you-tag {
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 10.5px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--daily-you);
    border: 1px solid color-mix(in srgb, var(--daily-you) 60%, transparent);
    border-radius: 3px;
    padding: 0 5px;
    margin-left: 6px;
}

/* A peer the official board is the only record of: named by their public tag, and marked, because
   the row carries no level and no competitive levels and the reader should know why
   (docs/design/pumbility-overhaul.md D62). */
.pmb-roster-board-name {
    font-weight: 500;
}

.pmb-roster-board-tag {
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 10.5px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-secondary);
    border: 1px solid color-mix(in srgb, var(--mix-secondary) 45%, transparent);
    border-radius: 3px;
    padding: 0 5px;
    margin-left: 6px;
    cursor: help;
}

.pmb-roster-level {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 12px;
    letter-spacing: .04em;
    white-space: nowrap;
}

.pmb-roster-level small {
    font-weight: 600;
    color: var(--mix-ink-muted);
}

.pmb-overlap {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pmb-overlap-bar {
    display: inline-block;
    width: 60px;
    height: 5px;
    border-radius: 3px;
    background: color-mix(in srgb, var(--mix-ink) 12%, transparent);
    overflow: hidden;
}

.pmb-overlap-bar b {
    display: block;
    height: 100%;
    background: var(--mix-secondary);
}

/* Legend swatches for the marks a Compact tile wears that a border cannot say. */
.pmb-legend-corner {
    position: static;
    display: inline-block;
}

.pmb-legend-stripe {
    display: inline-block;
    width: 20px;
    height: 3px;
    vertical-align: middle;
}

.pmb-roster-note {
    font-size: 12px;
    color: var(--mix-ink-muted);
    margin: 8px 0 0;
}

/* --- where the levels sit, as the spread of everyone holding your title (D68) --- */
.pmb-spread {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* One tile per chart type, side by side — never one plot striping the two together (D68, owner). */
.pmb-spread-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 10px;
}

.pmb-spread-tile {
    background: var(--mix-surface-muted);
    border-radius: 6px;
    padding: 10px 10px 4px;
    min-width: 0;
}

.pmb-spread-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 2px 8px;
    margin-bottom: 4px;
}

.pmb-spread-label {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

/* A gutter for the tick labels, then the columns. Every position inside a column is a percent of its
   height, on one scale for the whole chart; the glyphs keep their own pixel sizes. */
.pmb-spread-plot {
    position: relative;
    padding-left: 22px;
}

.pmb-spread-grid {
    position: absolute;
    top: 0;
    left: 22px;
    right: 0;
    height: 168px;
    pointer-events: none;
}

.pmb-spread-gridline {
    position: absolute;
    left: 0;
    right: 0;
    height: 0;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 9%, transparent);
}

.pmb-spread-gridline.is-base {
    border-top-color: color-mix(in srgb, var(--mix-ink) 24%, transparent);
}

.pmb-spread-gridline b {
    position: absolute;
    top: 0;
    right: calc(100% + 5px);
    transform: translateY(-50%);
    font-size: 10px;
    font-weight: 500;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.pmb-spread-cols {
    position: relative;
    display: flex;
}

.pmb-spread-col {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    outline: none;
    cursor: crosshair;
}

/* The card's own type colours, so a level's two columns are never read as one (D68). */
.pmb-spread-col.is-s {
    --spread-hue: var(--chart-singles);
}

.pmb-spread-col.is-d {
    --spread-hue: var(--chart-doubles);
}

.pmb-spread-colplot {
    position: relative;
    height: 168px;
    border-radius: 4px;
}

.pmb-spread-col[data-active] .pmb-spread-colplot {
    background: color-mix(in srgb, var(--mix-ink) 5%, transparent);
}

.pmb-spread-col:focus-visible .pmb-spread-colplot {
    box-shadow: inset 0 0 0 1.5px var(--mix-ink);
}

.pmb-spread-colplot i {
    position: absolute;
    left: 50%;
    display: block;
}

.pmb-spread-bin {
    transform: translateX(-50%);
    min-width: 3px;
    max-width: 68px;
    background: var(--spread-hue, var(--mix-secondary));
    opacity: .3;
}

.pmb-spread-bin[data-hot] {
    opacity: .65;
}

.pmb-spread-whisker {
    width: 1.25px;
    transform: translateX(-50%);
    background: var(--spread-hue, var(--mix-secondary));
    opacity: .75;
}

/* A line past the top of the scale ends in a caret rather than a cap. */
.pmb-spread-clip {
    width: 7px;
    height: 7px;
    border-left: 1.5px solid var(--spread-hue, var(--mix-secondary));
    border-top: 1.5px solid var(--spread-hue, var(--mix-secondary));
    transform: translateX(-50%) rotate(45deg);
}

.pmb-spread-box {
    width: 8px;
    transform: translateX(-50%);
    background: var(--spread-hue, var(--mix-secondary));
    border-radius: 2px;
    box-shadow: 0 0 0 2px var(--mix-surface-muted);
}

.pmb-spread-median {
    width: 16px;
    height: 2.5px;
    transform: translateX(-50%);
    background: var(--mix-ink);
    border-radius: 1.25px;
}

.pmb-spread-you {
    width: 9px;
    height: 9px;
    transform: translateX(-50%) rotate(45deg);
    background: var(--mix-accent);
    box-shadow: 0 0 0 2px var(--mix-surface-muted);
}


.pmb-spread-level {
    display: block;
    padding: 4px 0 2px;
    text-align: center;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .04em;
    color: var(--mix-ink-muted);
}

.pmb-spread-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 16px;
    font-size: 11.5px;
    color: var(--mix-ink-muted);
}

.pmb-spread-legend span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pmb-spread-key {
    display: inline-block;
    flex: none;
}

.pmb-spread-key-shape {
    width: 14px;
    height: 8px;
    border-radius: 1px;
    background: var(--mix-secondary);
    opacity: .3;
}

.pmb-spread-key-shape.is-s {
    background: var(--chart-singles);
    opacity: .55;
}

.pmb-spread-key-shape.is-d {
    background: var(--chart-doubles);
    opacity: .55;
}

.pmb-spread-key-box {
    width: 6px;
    height: 12px;
    border-radius: 1.5px;
    background: var(--mix-secondary);
}

.pmb-spread-key-median {
    width: 14px;
    height: 3px;
    border-radius: 1.5px;
    background: var(--mix-ink);
}

.pmb-spread-key-you {
    width: 8px;
    height: 8px;
    margin: 0 2px;
    transform: rotate(45deg);
    background: var(--mix-accent);
}

/* The tooltip level-spread.js opens beside the pointer, filled from the column's own hidden lines. */
.pmb-spread-tip {
    position: absolute;
    z-index: 5;
    display: none;
    pointer-events: none;
    min-width: 190px;
    max-width: 260px;
    padding: 7px 9px;
    background: var(--mix-nav);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 25%, transparent);
    border-radius: 4px;
    box-shadow: 0 8px 22px color-mix(in srgb, var(--mix-bg) 70%, transparent);
    font-size: 12px;
    line-height: 1.45;
}

.pmb-spread-tip[data-open] {
    display: block;
}

.pmb-spread-tiphead {
    margin-bottom: 2px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13px;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.pmb-spread-tip strong {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.pmb-spread-tip span {
    color: var(--mix-ink-muted);
}

.pmb-spread-tipyou strong {
    color: var(--mix-accent);
}

.pmb-spread-tippointer {
    margin-bottom: 3px;
    padding-bottom: 3px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
}

/* The chart's value, as the Your top 50 lens prints it. */
.pmb-val {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}

/* --- Phoenix 2 carryover --- */
.pmb-flip {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 15px 16px;
}

.pmb-flip-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px 22px;
}

.pmb-flip-col-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 7px;
}

.pmb-flip-col-name {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13px;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.pmb-flip-col-name.pmb-p1 {
    color: var(--mix-ink-muted);
}

.pmb-flip-col-name.pmb-p2 {
    color: var(--mix-primary);
}

.pmb-flip-total {
    font-size: 12px;
    color: var(--mix-primary);
}

.pmb-flip-bar {
    display: flex;
    height: 30px;
    border-radius: 3px;
    overflow: hidden;
}

.pmb-flip-seg {
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13px;
    color: var(--mix-ink);
}

.pmb-flip-seg.s {
    background: var(--chart-singles);
}

.pmb-flip-seg.d {
    background: var(--chart-doubles);
}

.pmb-flip-say {
    margin-top: 14px;
    font-size: 14px;
    line-height: 1.55;
}

.pmb-factrow {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
    margin-top: 14px;
}

.pmb-fact {
    background: var(--mix-surface-muted);
    border-radius: 4px;
    padding: 9px 11px;
}

.pmb-fact-num {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 24px;
    font-variant-numeric: tabular-nums;
    line-height: 1.05;
}

.pmb-fact-of {
    font-size: 15px;
}

.pmb-fact-lbl {
    font-size: 11.5px;
    color: var(--mix-ink-muted);
    margin-top: 2px;
}

/* Where a repriced record would land on each ladder. Never a title held — the label says
   "would", and every chip carries the pool value that put it there (section 8.2). */
.pmb-lands {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.pmb-lands-lbl {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.pmb-lands-row {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.pmb-chip {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 6px 11px;
    border-radius: 4px;
    background: var(--mix-surface-muted);
    border: 1px solid color-mix(in srgb, var(--mix-primary) 35%, transparent);
    min-width: 0;
}

.pmb-chip-t {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: .05em;
    color: var(--mix-primary);
    white-space: nowrap;
}

.pmb-chip-m {
    font-size: 11px;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* --- the projection spread: a folder laid out on what your level scores there --- */
/* Lives here rather than in a Razor <style> block, which is page-scoped — a shared component
   styled that way renders unstyled on every other page that picks it up. */
.spread-scroll {
    overflow-x: auto;
}

/* No value column: the numbers live on the markers, which buys the track most of the width
   back — the thing the spread is actually made of. */
.spread {
    /* The region overlay derives its inset from the same two numbers as the grid below, because
       pixel-guessing the alignment is exactly what breaks when a column width changes. */
    --spread-namecol: 190px;
    --spread-gap: 14px;
    min-width: 460px;
    position: relative;
    display: flex;
    flex-direction: column;
    padding-top: 26px;
}

.spread-row {
    position: relative;
    display: grid;
    grid-template-columns: var(--spread-namecol) 1fr;
    align-items: center;
    gap: var(--spread-gap);
    height: 34px;
    border-radius: 4px;
}

/* The row highlight is the alignment aid — it is what lets an eye carry a dot back to the title
   it belongs to. A vertical rule through the dot as well was one guide too many. */
.spread-row:hover {
    background: color-mix(in srgb, var(--mix-ink) 7%, transparent);
}

.spread-row:hover .spread-title {
    color: var(--mix-ink);
}

.spread-regions {
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(var(--spread-namecol) + var(--spread-gap));
    right: 0;
    pointer-events: none;
}

.spread-region {
    position: absolute;
    top: 0;
    bottom: 0;
}

.spread-region i {
    position: absolute;
    inset: 0;
    opacity: .13;
}

/* Vertical at every width. Rotated, a band label needs about 12px rather than the 90 its
   horizontal form wanted, so it survives a narrow band and a phone alike — which is what lets
   the row drop the tier name entirely instead of printing it beside every number. */
.spread-region b {
    position: absolute;
    top: 3px;
    left: 2px;
    font-size: 9px;
    letter-spacing: .08em;
    text-transform: uppercase;
    font-weight: 700;
    white-space: nowrap;
    writing-mode: vertical-rl;
    text-orientation: mixed;
    max-height: calc(100% - 6px);
    overflow: hidden;
}

.spread-edge {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: color-mix(in srgb, var(--mix-ink) 22%, transparent);
}

.spread-name {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    font-size: 12.5px;
    color: var(--mix-ink-muted);
    cursor: pointer;
}

.spread-name:hover .spread-title, .spread-name:focus-visible .spread-title {
    color: var(--mix-primary);
    text-decoration: underline;
}

.spread-jacket {
    width: 24px;
    height: 24px;
    border-radius: 3px;
    flex: none;
    background-size: cover;
    background-position: center;
}

/* A long title ellipses rather than widening the column and dragging the track with it. */
.spread-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.spread-title.spread-unplayed {
    font-style: italic;
}

.spread-track {
    position: relative;
    height: 100%;
}

/* The marker is the hit area and the tooltip's anchor. It is OUR element with the tooltip
   inside it, never MudTooltip's own root: that root carries .mud-tooltip-root{width:auto} and
   .mud-tooltip-inline{display:inline-block} at the same specificity as anything added
   alongside, so a marker class landing there loses its width and its display and collapses.
   22px because a fingertip cannot reliably hit an 11px dot, and the readout is now the only
   place the number lives. */
.spread-marker {
    position: absolute;
    top: 50%;
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
}

.spread-marker .mud-tooltip-root {
    position: absolute;
    inset: 0;
}

/* Centred on margins rather than a transform, so the diamond below can spend its transform on
   the rotation without having to restate the centring. */
.spread-shape {
    display: block;
    position: absolute;
    left: 50%;
    top: 50%;
    width: 11px;
    height: 11px;
    margin: -5.5px 0 0 -5.5px;
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--mix-bg);
}

/* Unplayed loses its fill and nothing else — the projection is just as real there. */
.spread-shape.spread-unplayed {
    background: var(--mix-bg) !important;
    border: 2px solid;
    box-shadow: none;
}

.spread-mine .spread-shape {
    width: 9px;
    height: 9px;
    margin: -4.5px 0 0 -4.5px;
    border-radius: 0;
    transform: rotate(45deg);
    border: 1.5px solid var(--mix-ink);
    background: var(--mix-bg);
    box-shadow: none;
}

/* Clamped to the edge and drawn as an arrow: the row still says "off the bottom" rather than
   claiming the score sits at the axis floor. The border box is 13x10, so the centring margins
   are its own halves rather than the circle's. */
.spread-off .spread-shape {
    width: 0;
    height: 0;
    border: 5px solid transparent;
    margin: -5px 0 0 -6.5px;
    background: none;
    transform: none;
    box-shadow: none;
    border-radius: 0;
}

/* currentColor, so the arrow keeps whatever the marker was going to be: the band's colour for
   a projection, the behind/ahead ramp for the player's own score. */
.spread-off-left .spread-shape {
    border-right: 8px solid currentColor;
}

.spread-off-right .spread-shape {
    border-left: 8px solid currentColor;
}

/* Catches the click that dismisses a pinned readout, and nothing else: no background, no
   scroll lock, below the popover's 1200 and above the page. */
.spread-clickaway {
    position: fixed;
    inset: 0;
    z-index: 1198;
}

/* While a readout is pinned the spread rises above the click-away layer, so tapping a SECOND
   marker reaches that marker and moves the readout. Without it the layer is the hit target for
   the whole viewport and moving a readout took two taps: one to dismiss, one to open. Below
   MudPopover's 1200 so the readout itself still draws on top. */
.spread-pinned {
    z-index: 1199;
}

/* The popover's own box: MudPopover brings no padding of its own. */
.spread-pop {
    padding: 7px 10px;
}

/* The grade rail: the first marker to reach each letter carries its badge, giving the track a
   scale down its side without the value column coming back. Click-through, so it cannot steal
   the marker's hit area, and flipped inside near the right edge so it never hangs off. */
.spread-rail {
    position: absolute;
    top: 50%;
    left: calc(100% + 1px);
    transform: translateY(-50%);
    pointer-events: none;
    opacity: .92;
    line-height: 0;
}

.spread-rail-left {
    left: auto;
    right: calc(100% + 1px);
}

.spread-readout {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* The song, so a pinned readout says which row it belongs to. Below 700px the row is a jacket
   and a track, so without this a number on screen names nothing. Ellipsed rather than wrapped:
   a two-line title pushes the figures off a phone. */
.spread-pop-title {
    font-size: 11px;
    font-weight: 600;
    color: var(--mix-ink-muted);
    max-width: 24ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.spread-figures {
    display: flex;
    align-items: center;
    gap: 6px;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    white-space: nowrap;
}

.spread-offnote {
    font-weight: 400;
    opacity: .75;
}

/* Below this the title gives way to the jacket alone and the track takes the width. The band
   labels stay: vertical, they fit here as well as anywhere, and they are what keeps the dot's
   colour from being the only channel carrying the tier. */
@media (max-width: 700px) {
    .spread {
        --spread-namecol: 30px;
        --spread-gap: 8px;
        min-width: 0;
        padding-top: 0;
    }

    .spread-row {
        height: 38px;
        border-radius: 0;
        border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent);
    }

    .spread-title {
        display: none;
    }
}

/* --- the patience card: sitewide, for waits a page cannot shorten --- */
/* Lives here rather than in a Razor <style> block, which is page-scoped — a shared component
   styled that way renders unstyled on every other page that uses it. */
/* Full width of whatever it is dropped into, with its contents centred: it stands in for a
   whole region rather than sitting beside one, so anything less than the full width reads as
   a second thing still loading next to the thing that is telling you so. */
.patience-card {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 28px 16px 30px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 14px;
}

/* Five panels stepping in sequence. Motion without a spinner, and the one thing on the page
   that could only belong to this game. */
.patience-pad {
    /* One step of the chart. Every pattern below counts its cycle in these. */
    --patience-beat: .32s;
    display: grid;
    grid-template-columns: repeat(3, 20px);
    grid-template-rows: repeat(3, 20px);
    gap: 4px;
}

.patience-panel {
    display: block;
    border-radius: 3px;
    background: color-mix(in srgb, var(--mix-ink) 13%, transparent);
    animation-timing-function: steps(1, end);
    animation-iteration-count: infinite;
}

.patience-ul { grid-area: 1 / 1; }
.patience-ur { grid-area: 1 / 3; }
.patience-ct { grid-area: 2 / 2; }
.patience-dl { grid-area: 3 / 1; }
.patience-dr { grid-area: 3 / 3; }

/* Real step patterns, one per CYCLE (owner, 2026-08-08). Each begins AND ends on the
   bottom-left arrow, so whichever comes next picks up mid-stride — which is what lets
   js/patience.js swap the pattern at the cycle boundary with no visible seam. The server picks
   the first one, so a pad still steps a real chart when the script never arrives.

   A panel that lights ONCE gets the shared flash keyframe plus a delay. A panel that lights
   more than once gets a keyframe of its own, spelling out every beat.

   ⚠ It cannot instead declare the shared keyframe twice with two delays, which is the obvious
   economy and is wrong: two animations on one element do not merge, they compete, and for any
   property both of them touch the LAST one in the list wins outright. Since these keyframes
   span the whole cycle, the second instance overrode the first at every moment and only its
   delay was ever visible — M run collapsed to a right-to-left sweep and Spin's centre lit once
   instead of four times.

   The flash lasts exactly one beat, so its width is a fraction of the cycle — hence one shared
   keyframe per cycle length rather than one overall. */
@keyframes patience-flash-8 {
    0% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    11.25% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    12.5%, 100% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
}

@keyframes patience-flash-6 {
    0% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    15% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    16.667%, 100% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
}

/* Keyframes for the panels that light more than once. Beat i of an eight-step cycle runs from
   i × 12.5%, and of a six-step cycle from i × 16.667%; the panel is lit for the first nine
   tenths of its beat and dark the rest of the cycle. */
@keyframes patience-mrun-ul { /* beats 1 and 7 */
    0%, 12.49% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    12.5% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    23.75% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    25%, 87.49% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    87.5% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    98.75% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    100% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
}

@keyframes patience-mrun-ct { /* beats 2 and 6 */
    0%, 24.99% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    25% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    36.25% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    37.5%, 74.99% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    75% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    86.25% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    87.5%, 100% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
}

@keyframes patience-mrun-ur { /* beats 3 and 5 */
    0%, 37.49% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    37.5% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    48.75% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    50%, 62.49% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    62.5% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    73.75% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    75%, 100% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
}

@keyframes patience-spin-ct { /* beats 1, 3, 5 and 7 — the centre carries this whole pattern */
    0%, 12.49% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    12.5% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    23.75% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    25%, 37.49% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    37.5% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    48.75% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    50%, 62.49% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    62.5% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    73.75% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    75%, 87.49% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    87.5% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    98.75% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    100% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
}

@keyframes patience-six-ct { /* beats 1 and 4 of six — shared by the standard run and cross overs */
    0%, 16.66% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    16.667% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    31.667% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    33.333%, 66.66% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
    66.667% { background: var(--mix-primary); box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent); }
    81.667% { background: color-mix(in srgb, var(--mix-primary) 45%, transparent); box-shadow: 0 0 0 transparent; }
    83.333%, 100% { background: color-mix(in srgb, var(--mix-ink) 13%, transparent); box-shadow: 0 0 0 transparent; }
}

/* M run — up the left, through the middle, down the right, and back the way it came.
   BL · TL · C · TR · BR · TR · C · TL */
.patience-mrun .patience-panel { animation-name: patience-flash-8; animation-duration: calc(var(--patience-beat) * 8); }
.patience-mrun .patience-dl { animation-delay: 0s; }
.patience-mrun .patience-ul { animation-name: patience-mrun-ul; }
.patience-mrun .patience-ct { animation-name: patience-mrun-ct; }
.patience-mrun .patience-ur { animation-name: patience-mrun-ur; }
.patience-mrun .patience-dr { animation-delay: calc(var(--patience-beat) * 4); }

/* Spin — back to the centre between every corner.
   BL · C · TL · C · TR · C · BR · C */
.patience-spin .patience-panel { animation-name: patience-flash-8; animation-duration: calc(var(--patience-beat) * 8); }
.patience-spin .patience-dl { animation-delay: 0s; }
.patience-spin .patience-ct { animation-name: patience-spin-ct; }
.patience-spin .patience-ul { animation-delay: calc(var(--patience-beat) * 2); }
.patience-spin .patience-ur { animation-delay: calc(var(--patience-beat) * 4); }
.patience-spin .patience-dr { animation-delay: calc(var(--patience-beat) * 6); }

/* Standard run — the ordinary way round.
   BL · C · TL · TR · C · BR */
.patience-run .patience-panel { animation-name: patience-flash-6; animation-duration: calc(var(--patience-beat) * 6); }
.patience-run .patience-dl { animation-delay: 0s; }
.patience-run .patience-ct { animation-name: patience-six-ct; }
.patience-run .patience-ul { animation-delay: calc(var(--patience-beat) * 2); }
.patience-run .patience-ur { animation-delay: calc(var(--patience-beat) * 3); }
.patience-run .patience-dr { animation-delay: calc(var(--patience-beat) * 5); }

/* Cross overs — every step lands on the far side.
   BL · C · TR · BR · C · TL */
.patience-cross .patience-panel { animation-name: patience-flash-6; animation-duration: calc(var(--patience-beat) * 6); }
.patience-cross .patience-dl { animation-delay: 0s; }
.patience-cross .patience-ct { animation-name: patience-six-ct; }
.patience-cross .patience-ur { animation-delay: calc(var(--patience-beat) * 2); }
.patience-cross .patience-dr { animation-delay: calc(var(--patience-beat) * 3); }
.patience-cross .patience-ul { animation-delay: calc(var(--patience-beat) * 5); }

.patience-line {
    font-family: var(--font-display);
    font-size: 21px;
    font-weight: 600;
    letter-spacing: .01em;
    line-height: 1.15;
    color: var(--mix-ink);
    margin: 0;
}

.patience-sub {
    font-size: 13px;
    line-height: 1.5;
    color: var(--mix-ink-muted);
    margin: 0;
    max-width: 34ch;
}

/* Two classes deliberately, not one: the step patterns above select as `.patience-mrun
   .patience-ul`, and a bare `.patience-panel` here would lose to them on specificity and leave
   the pad animating for someone who asked it not to. Matching their weight and sitting later in
   the file is what makes this win. */
@media (prefers-reduced-motion: reduce) {
    .patience-pad .patience-panel {
        animation: none;
    }

    .patience-pad .patience-ct {
        background: var(--mix-primary);
        box-shadow: 0 0 10px color-mix(in srgb, var(--mix-primary) 55%, transparent);
    }
}

/* --- loading, rule 9: shaped like what it becomes --- */
.pmb-skeleton {
    background: color-mix(in srgb, var(--mix-ink) 8%, transparent);
    border-radius: 6px;
    animation: pmb-pulse 1.4s ease-in-out infinite;
}

.pmb-skeleton-targets {
    min-height: 220px;
    margin-top: 10px;
}

@keyframes pmb-pulse {
    0%, 100% {
        opacity: 1;
    }

    50% {
        opacity: .55;
    }
}

@media (prefers-reduced-motion: reduce) {
    .pmb-skeleton {
        animation: none;
    }
}

/* --- a re-read of the Play list (D56): the previous list stays on screen at its own height,
       every card and every table cell blanked to a pulsing block, so the sections, the scroll
       and the controls above hold still until the new record lands. Only the first paint shows
       the patience card. --- */
.pmb-list-reloading {
    pointer-events: none;
}

.pmb-list-reloading .tier-chart-card,
.pmb-list-reloading .pmb-table tbody td {
    background: color-mix(in srgb, var(--mix-ink) 8%, transparent);
    border-color: transparent;
    border-radius: 6px;
    box-shadow: none;
    animation: pmb-pulse 1.4s ease-in-out infinite;
}

.pmb-list-reloading .tier-chart-card > *,
.pmb-list-reloading .pmb-table tbody td > * {
    visibility: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .pmb-list-reloading .tier-chart-card,
    .pmb-list-reloading .pmb-table tbody td {
        animation: none;
    }
}

/* --- the class ladder (UX-GUIDELINES section 1): tablet under 900, fold under 700,
       mobile under 500. One class, one shed, least dense information first. --- */

/* The frame needs no width rung of its own: it is a wrapping row, so a narrow viewport
   stacks the number, the selector and the bar in that order against one left edge. The
   860 rung the two-up hero needed went with the hero. */

/* Tablet: the evidence line goes first, least information per pixel on the row. */
@media (max-width: 899.98px) {
    .pmb-col-why {
        display: none;
    }
}

/* Fold: the song name steps aside; jacket and difficulty bubble already say which
   chart it is (the .olb-song-text rule). */
@media (max-width: 699.98px) {
    .pmb-ident-name {
        display: none;
    }

    .pmb-flip-grid {
        grid-template-columns: 1fr;
    }
}

/* Mobile: scores drop to grade art alone. The art is narrower than the number it
   replaces and the score still rides the row tooltip. */
@media (max-width: 499.98px) {
    .pmb-score-text {
        display: none;
    }

    .pmb-hero-value {
        font-size: 38px;
    }

    .pmb-curve-plot {
        height: 128px;
        gap: 1px;
    }

    .pmb-table th,
    .pmb-table td {
        padding-right: 7px;
    }
}

/* Landscape phone: 844 wide and 390 tall. A width rule stacks the hero exactly when
   height is the scarce axis, so this compresses instead. The one rule the width
   ladder cannot express (session-breakdown.md section 5 draws the same line). */
@media (max-height: 520px) and (min-width: 700px) {
    .pmb-hero-value {
        font-size: 34px;
    }

    .pmb-frame {
        gap: 8px 16px;
        padding-bottom: 9px;
    }

    .pmb-frame-nav {
        padding-top: 8px;
    }

    .pmb-curve {
        padding: 10px 12px 11px;
    }

    .pmb-curve-plot {
        height: 84px;
    }

    .pmb-curve-legend {
        display: none;
    }

    .pmb-barcard {
        padding: 7px 10px;
    }

    .pmb-barcard-num {
        font-size: 20px;
    }

    .pmb-barcard-say {
        display: none;
    }
}

/* --- your PUMBILITY titles: three ladders and the per-chart ask --- */
.pmb-rails {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.pmb-rail {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 13px 15px;
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.pmb-rail-top {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}

.pmb-rail-pool {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 11px;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    padding: 1px 7px;
    border-radius: 3px;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 20%, transparent);
}

.pmb-rail-pool.pmb-rail-s {
    color: var(--chart-singles);
    border-color: color-mix(in srgb, var(--chart-singles) 45%, transparent);
}

.pmb-rail-pool.pmb-rail-d {
    color: var(--chart-doubles);
    border-color: color-mix(in srgb, var(--chart-doubles) 45%, transparent);
}

.pmb-rail-value {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 22px;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.pmb-rail-track {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.pmb-rail-bar {
    position: relative;
    height: 9px;
    border-radius: 2px;
    background: var(--mix-surface-muted);
    overflow: hidden;
}

.pmb-rail-fill {
    position: absolute;
    inset: 0 auto 0 0;
    background: var(--mix-primary);
}

/* Three cells, so the distance still to travel sits between the two rungs it is the distance
   across — rather than at the foot of the rail, where it read as a number with no unit beside
   figures that were all per-chart. */
.pmb-rail-ends {
    display: flex;
    align-items: baseline;
    gap: 10px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 11.5px;
    letter-spacing: .07em;
    color: var(--mix-ink-muted);
}

.pmb-rail-ends > :first-child,
.pmb-rail-ends > :last-child {
    flex: 1 1 0;
    min-width: 0;
}

.pmb-rail-ends .pmb-rail-mid {
    flex: 0 0 auto;
    text-align: center;
    color: var(--mix-accent);
}

.pmb-rail-ends .pmb-rail-next {
    color: var(--mix-primary);
    text-align: right;
}

/* The projected pool clearing the ask is the good answer, so it reads as one — the accent
   otherwise on this row means "still to find". */
.pmb-ask-cell.pmb-ask-reach {
    background: color-mix(in srgb, var(--mix-primary) 14%, transparent);
}

.pmb-ask-cell.pmb-ask-reach .pmb-ask-num,
.pmb-ask-cell.pmb-ask-reach .pmb-ask-lbl {
    color: var(--mix-primary);
}

/* The grade rides the same line as its level, always: in a shared caption underneath, three
   levels read as a path — and the low one is the hard one, not the first step. */
.pmb-rail-eg {
    display: inline-block;
    margin-left: 8px;
    white-space: nowrap;
    font-weight: 600;
    color: var(--mix-ink);
}

/* The ask: what the next rung wants of every chart, against what yours are worth now. It
   never assumes a play order, which is the whole reason it replaced counting charts. */
.pmb-ask {
    display: flex;
    align-items: stretch;
    border-radius: 4px;
    overflow: hidden;
    background: var(--mix-surface-muted);
    flex-wrap: wrap;
}

.pmb-ask-cell {
    padding: 7px 12px;
    display: flex;
    flex-direction: column;
    flex: 1 1 130px;
    min-width: 0;
    border-right: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

.pmb-ask-cell:last-child {
    border-right: 0;
}

.pmb-ask-lbl {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 10px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.pmb-ask-num {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 19px;
    font-variant-numeric: tabular-nums;
    line-height: 1.25;
}

.pmb-ask-cell.pmb-ask-gap {
    background: color-mix(in srgb, var(--mix-accent) 14%, transparent);
}

.pmb-ask-cell.pmb-ask-gap .pmb-ask-num,
.pmb-ask-cell.pmb-ask-gap .pmb-ask-lbl {
    color: var(--mix-accent);
}

.pmb-rail-say {
    font-size: 12.5px;
    color: var(--mix-ink-muted);
    margin: 0;
}

.pmb-rail-say b {
    color: var(--mix-ink);
    font-weight: 600;
}

/* --- where your PUMBILITY comes from --- */
.pmb-wpc {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 15px 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.pmb-wpc-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.pmb-wpc-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 16px;
}

.pmb-wpc-total {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 15px;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

/* True to scale. The plate segment is a hairline because it IS a hairline — widening it to
   be visible would be arguing the opposite of what the section says. It gets its own
   magnified rail below instead. */
.pmb-wpc-stack {
    display: flex;
    height: 34px;
    border-radius: 3px;
    overflow: hidden;
    background: var(--mix-surface-muted);
}

.pmb-wpc-seg {
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13px;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    color: var(--mix-primary-contrast);
}

.pmb-wpc-seg.pmb-wpc-level {
    background: var(--mix-primary);
}

.pmb-wpc-seg.pmb-wpc-score {
    background: var(--mix-secondary);
}

.pmb-wpc-seg.pmb-wpc-plate {
    background: var(--mix-accent);
}

.pmb-wpc-keys {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
}

.pmb-wpc-key {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding-left: 10px;
    border-left: 3px solid var(--mix-ink-muted);
    min-width: 0;
}

.pmb-wpc-key.pmb-wpc-level {
    border-left-color: var(--mix-primary);
}

.pmb-wpc-key.pmb-wpc-score {
    border-left-color: var(--mix-secondary);
}

.pmb-wpc-key.pmb-wpc-plate {
    border-left-color: var(--mix-accent);
}

.pmb-wpc-k-lbl {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.pmb-wpc-k-num {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 23px;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.pmb-wpc-k-pct {
    font-size: 11.5px;
    color: var(--mix-ink-muted);
}

.pmb-wpc-plated {
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    padding-top: 11px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.pmb-wpc-plate-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    font-size: 12.5px;
}

.pmb-wpc-plate-head strong {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-accent);
}

/* The sliver, on a scale it can be read on: the worst plate on all fifty to the best. */
.pmb-wpc-rail {
    position: relative;
    height: 12px;
    border-radius: 2px;
    background: var(--mix-surface-muted);
    overflow: hidden;
}

.pmb-wpc-rail-fill {
    position: absolute;
    inset: 0 auto 0 0;
    background: var(--mix-accent);
    opacity: .85;
}

.pmb-wpc-say {
    font-size: 13px;
    margin: 0;
}

/* --- the archetype spectrum, inside the card (D69) --- */
/* Five segments as wide as the share of the cohort standing in each, in the chips' own metal
   colours. Ordered by the average they band, which is the only order a spectrum has — the
   archetypes themselves are lateral, so nothing here reads as a rank. */
.pmb-arch {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.pmb-arch-strip {
    position: relative;
}

.pmb-arch-bands {
    display: flex;
    height: 26px;
    border-radius: 3px;
    overflow: hidden;
}

.pmb-arch-band {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 2px;
}

.pmb-arch-band[data-k="1"] { background: var(--ptype-1); }
.pmb-arch-band[data-k="2"] { background: var(--ptype-2); }
.pmb-arch-band[data-k="3"] { background: var(--ptype-3); }
.pmb-arch-band[data-k="4"] { background: var(--ptype-4); }
/* The summit archetype glows, the way PlayerTypeChip glows it — the only thing separating it
   from Competitive, which sits one shade away on the same metal. */
.pmb-arch-band[data-k="5"] {
    background: var(--ptype-5);
    box-shadow: inset 0 0 10px rgba(255, 255, 255, .4);
}

/* Drawn on a pseudo-element so the outline sits inside the clipped band rather than being
   trimmed off with it. */
.pmb-arch-band.is-mine::after {
    content: '';
    position: absolute;
    inset: 0;
    outline: 2px solid var(--mix-ink);
    outline-offset: -2px;
}

/* The chip's own phone-width short form, which fits wherever the label is drawn at all. */
/* The page's own ground, on the light metal the band is painted in. --mix-bg is the token the
   theme emits; --mix-background is not one, and an undefined var() on an inherited property
   falls back to the ink, which is near-white on every one of the five. */
.pmb-arch-band b {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 11px;
    letter-spacing: .08em;
    color: var(--mix-bg);
    white-space: nowrap;
}

.pmb-arch-you {
    position: absolute;
    top: -6px;
    width: 11px;
    height: 11px;
    transform: translateX(-50%) rotate(45deg);
    background: var(--mix-accent);
    box-shadow: 0 0 0 2px var(--mix-surface-muted);
}

.pmb-arch-ticks {
    display: flex;
    margin-top: 5px;
}

.pmb-arch-tick {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-align: center;
    font-size: 10.5px;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.pmb-arch-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 14px;
    font-size: 11.5px;
    color: var(--mix-ink-muted);
}

.pmb-arch-legend span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.pmb-arch-key {
    width: 10px;
    height: 10px;
    display: inline-block;
    border-radius: 2px;
}

.pmb-arch-key[data-k="1"] { background: var(--ptype-1); }
.pmb-arch-key[data-k="2"] { background: var(--ptype-2); }
.pmb-arch-key[data-k="3"] { background: var(--ptype-3); }
.pmb-arch-key[data-k="4"] { background: var(--ptype-4); }
.pmb-arch-key[data-k="5"] { background: var(--ptype-5); }

.pmb-arch-key-you {
    width: 8px;
    height: 8px;
    border-radius: 0;
    transform: rotate(45deg);
    background: var(--mix-accent);
}

/* --- you against your peers, inside the card (D58) --- */
.pmb-wpc-sub {
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    padding-top: 11px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.pmb-wpc-sub-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    font-size: 12.5px;
}

.pmb-wpc-sub-head strong {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13px;
    letter-spacing: .1em;
    text-transform: uppercase;
}

/* --- who both comparisons are against: the players holding your title (D68) --- */
.pmb-cohort {
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    padding-top: 11px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 6px 12px;
}

.pmb-cohort-pick {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    min-width: 0;
}

.pmb-cohort-lbl {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.pmb-cohort-sel {
    max-width: 220px;
    padding: 4px 8px;
    background: var(--mix-surface-muted);
    color: var(--mix-ink);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 22%, transparent);
    border-radius: 4px;
    font: inherit;
    font-size: 12.5px;
}

.pmb-cohort-count {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 2px 8px;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

.pmb-cohort-count strong {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: .06em;
}

/* Two bars in rows labelled You and the band: the Phoenix 1 card's bar, sized by value here, each
   segment reading what it is worth and how many charts it is. The label column takes a title
   rather than a word now, so it grows to one and wraps instead of running into the bar. */
.pmb-splitrows {
    display: grid;
    grid-template-columns: minmax(44px, 96px) 1fr;
    gap: 6px 8px;
    align-items: center;
}

.pmb-splitrow-lbl {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    overflow-wrap: anywhere;
}

.pmb-splitrows .pmb-flip-seg {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    padding: 0 6px;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 699.98px) {
    .pmb-wpc-keys {
        grid-template-columns: 1fr;
    }
}

/* Source label on a target row. It only renders when the list actually mixes a repriced
   Phoenix 1 score with a peer estimate, so the carried rows read as the harder currency
   they are rather than as one more guess. */
.pmb-src {
    display: inline-block;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 10px;
    letter-spacing: .1em;
    text-transform: uppercase;
    white-space: nowrap;
    padding: 1px 6px;
    border-radius: 3px;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
    color: var(--mix-ink-muted);
}

.pmb-src-carry {
    border-color: color-mix(in srgb, var(--mix-accent) 60%, transparent);
    background: color-mix(in srgb, var(--mix-accent) 12%, transparent);
    color: var(--mix-accent);
}


/* MixUnavailableNotice — what a page says when the mix in view cannot answer it. Shared
   rather than page-scoped: .tier-list-cta was declared inside ChartSkills' own <style>
   block, so every other page that reused the class rendered it unstyled. */
.mix-unavailable {
    border: 1px dashed var(--mud-palette-lines-default);
    border-radius: 8px;
    padding: 16px;
    margin: 12px 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: flex-start;
}

.mix-unavailable-detail {
    color: var(--mix-ink-muted);
    max-width: 60ch;
}

.mix-unavailable-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* ============================================================================
   PUMBILITY Calculator (/PumbilityCalculator/{mix}) — docs/design/pumbility-calculator.md
   A static reference page: the formula, its constants, the value tables, the
   level-equivalent ruler and the population answers, all real HTML. What moves
   (the type toggle, the table's contour click, the quick calculator) is
   wwwroot/js/pumbility-calculator.js working on this markup. Tokens only.
   ============================================================================ */

.pc-page {
    display: flex;
    flex-direction: column;
    gap: 34px;
    padding: 16px 0 72px;
}

/* --- hero --- */
.pc-hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 18px 32px;
    align-items: end;
}

.pc-eyebrow {
    display: flex;
    gap: 10px;
    align-items: baseline;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 12.5px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.pc-eyebrow .pc-sep {
    color: color-mix(in srgb, var(--mix-ink) 18%, transparent);
}

.pc-eyebrow a {
    color: var(--mix-ink-muted);
    border-bottom: 1px dotted var(--mix-ink-muted);
    text-decoration: none;
}

.pc-eyebrow a:hover {
    color: var(--mix-ink);
}

/* The one link on the line that leaves for your own data rather than for the same page on
   another mix, so it carries the primary the way the section's eyebrow does. */
.pc-eyebrow a.pc-mine {
    color: var(--mix-primary);
    border-bottom-color: color-mix(in srgb, var(--mix-primary) 55%, transparent);
}

.pc-eyebrow a.pc-mine:hover {
    color: var(--mix-primary);
    border-bottom-color: var(--mix-primary);
}

.pc-h1 {
    margin: 8px 0 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 46px;
    line-height: 1;
    letter-spacing: .005em;
    text-wrap: balance;
}

.pc-h1 span {
    color: var(--mix-primary);
}

.pc-lede {
    max-width: 66ch;
    margin: 12px 0 0;
    font-size: 15px;
    line-height: 1.5;
}

.pc-lede .pc-muted {
    color: var(--mix-ink-muted);
}

/* The Singles/Doubles group heads the run of type-specific sections it governs — the ruler is
   the first thing on the page that changes with it, so it sits right above the ruler's title,
   pulled in against the page gap so the two read as one. */
.pc-typebar {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: -18px;
}

.pc-hint {
    font-size: 11.5px;
    color: var(--mix-ink-muted);
}

.pc-typegroup {
    display: inline-flex;
    border: 1px solid var(--mix-primary);
    border-radius: 4px;
    overflow: hidden;
}

.pc-typegroup button {
    appearance: none;
    background: transparent;
    border: 0;
    color: var(--mix-primary);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: 7px 16px;
    cursor: pointer;
}

.pc-typegroup button + button {
    border-left: 1px solid var(--mix-primary);
}

.pc-typegroup button[aria-pressed="true"] {
    background: var(--mix-primary);
    color: var(--mix-primary-contrast);
}

.pc-typegroup button:focus-visible {
    outline: 2px solid var(--mix-secondary);
    outline-offset: -2px;
}

/* --- shared section vocabulary --- */
.pc-sec {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.pc-sec-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
}

.pc-h2 {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 24px;
    letter-spacing: .005em;
    text-wrap: balance;
}

.pc-h2.pc-q {
    font-size: 26px;
}

.pc-h2.pc-q::before {
    content: "Q";
    display: inline-grid;
    place-items: center;
    width: 22px;
    height: 22px;
    margin-right: 10px;
    border-radius: 4px;
    font-size: 14px;
    background: var(--mix-secondary);
    color: var(--mix-primary-contrast);
    vertical-align: 4px;
}

.pc-h3 {
    margin: 0 0 8px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 15px;
    letter-spacing: .02em;
}

.pc-sub {
    max-width: 72ch;
    font-size: 13px;
    color: var(--mix-ink-muted);
}

.pc-sub b {
    color: var(--mix-ink);
    font-weight: 600;
}

.pc-card {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 16px 18px;
}

.pc-lbl {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.pc-muted {
    color: var(--mix-ink-muted);
}

.pc-foot {
    margin: 10px 0 0;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-mark {
    color: var(--mix-accent);
}

/* --- the formula --- */
.pc-formula {
    display: grid;
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    gap: 16px;
}

.pc-formula-line {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 6px 10px;
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 34px;
    line-height: 1.1;
    letter-spacing: .01em;
}

.pc-formula-line small {
    width: 100%;
    font: 400 15px/1.4 var(--font-body);
    color: var(--mix-ink-muted);
}

.pc-op {
    color: var(--mix-ink-muted);
    font-weight: 600;
}

.pc-t-level {
    color: var(--mix-primary);
    font-style: normal;
}

.pc-t-grade {
    color: var(--mix-secondary);
    font-style: normal;
}

.pc-t-plate {
    color: var(--mix-accent);
    font-style: normal;
}

.pc-terms {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
    margin-top: 16px;
}

.pc-term {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    padding-left: 10px;
    border-left: 3px solid var(--mix-ink-muted);
}

.pc-term-level {
    border-left-color: var(--mix-primary);
}

.pc-term-grade {
    border-left-color: var(--mix-secondary);
}

.pc-term-plate {
    border-left-color: var(--mix-accent);
}

.pc-term-val {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 20px;
    line-height: 1.15;
}

.pc-term-val small {
    font-size: 13px;
    font-weight: 600;
    color: var(--mix-ink-muted);
}

.pc-term-say {
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-zero {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    align-items: baseline;
    margin-top: 14px;
    font-size: 12.5px;
    color: var(--mix-ink-muted);
}

.pc-zero-item {
    color: var(--mix-ink);
}

.pc-examples {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.pc-example {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 4px 12px;
    align-items: baseline;
    font-size: 13px;
}

.pc-example-who {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 15px;
    white-space: nowrap;
}

.pc-example-math {
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.pc-example-math b {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 16px;
    color: var(--mix-ink);
}

/* --- the ruler --- */
.pc-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    align-items: center;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-legend i {
    display: inline-block;
    width: 18px;
    height: 8px;
    margin-right: 6px;
    border-radius: 2px;
    vertical-align: 0;
}

.pc-legend i.pc-legend-tail {
    height: 5px;
    opacity: .45;
}

.pc-legend i.pc-legend-anchor {
    width: 2px;
    height: 14px;
    background: var(--mix-ink);
    vertical-align: -3px;
}

.pc-ruler {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) 46px;
    gap: 0 10px;
    margin-top: 12px;
}

.pc-ruler-axis {
    grid-column: 2;
    position: relative;
    height: 22px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-ruler-axis span {
    position: absolute;
    bottom: 4px;
    transform: translateX(-50%);
}

.pc-ruler-axis .pc-ruler-cap {
    left: 0;
    transform: none;
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.pc-ruler-axis .pc-ruler-cap-past {
    transform: translateX(6px);
    opacity: .7;
    font-size: 11px;
    letter-spacing: .08em;
    text-transform: uppercase;
}

.pc-ruler-lbl {
    height: 22px;
    margin-bottom: 4px;
    line-height: 22px;
    text-align: right;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.pc-ruler-track {
    position: relative;
    height: 22px;
    margin-bottom: 4px;
}

.pc-ruler-grid {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

.pc-ruler-grid.pc-ruler-grid-5 {
    background: color-mix(in srgb, var(--mix-ink) 18%, transparent);
}

.pc-ruler-past {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    background: repeating-linear-gradient(135deg, transparent 0 4px, color-mix(in srgb, var(--mix-ink) 6%, transparent) 4px 5px);
}

.pc-seg {
    position: absolute;
    top: 5px;
    height: 12px;
}

.pc-seg-tail {
    top: 8px;
    height: 6px;
    opacity: .45;
    background: var(--plate-rg);
}

.pc-seg-copper {
    background: var(--plate-fg);
}

.pc-seg-silver {
    background: var(--plate-tg);
}

.pc-seg-gold {
    background: var(--plate-sg);
}

.pc-seg-ice {
    background: var(--plate-ug);
}

.pc-ruler-track:hover .pc-seg {
    filter: brightness(1.15);
}

.pc-ruler-anchor {
    position: absolute;
    top: 2px;
    width: 2px;
    height: 18px;
    background: var(--mix-ink);
    transform: translateX(-1px);
}

.pc-ruler-end {
    height: 22px;
    margin-bottom: 4px;
    line-height: 22px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 12.5px;
    font-variant-numeric: tabular-nums;
}

.pc-ruler-foot {
    margin: 10px 0 0;
    max-width: 80ch;
    font-size: 12.5px;
    color: var(--mix-ink-muted);
}

.pc-ruler-foot b {
    color: var(--mix-ink);
    font-weight: 600;
}

/* --- the value table --- */
.pc-tablewrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    background: var(--mix-surface);
}

.pc-tablewrap-plain {
    border: 0;
    border-radius: 0;
    background: transparent;
}

.pc-vt {
    width: 100%;
    min-width: 900px;
    border-collapse: separate;
    border-spacing: 0;
    font-variant-numeric: tabular-nums;
}

.pc-vt th,
.pc-vt td {
    padding: 0;
    text-align: center;
    font-size: 12.5px;
}

.pc-vt thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 8px 4px 6px;
    background: var(--mix-surface);
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: .02em;
}

.pc-vt .pc-floor {
    display: block;
    margin-top: 1px;
    font: 400 10.5px/1.3 var(--font-body);
    color: var(--mix-ink-muted);
    letter-spacing: 0;
}

.pc-metal {
    display: block;
    width: 60%;
    height: 3px;
    margin: 4px auto 0;
    border-radius: 2px;
}

.pc-vt thead th.pc-lv,
.pc-vt tbody td.pc-lv {
    position: sticky;
    left: 0;
    z-index: 2;
    text-align: left;
    padding-left: 12px;
    background: var(--mix-surface);
}

.pc-vt thead th.pc-lv {
    z-index: 3;
}

.pc-vt tbody td.pc-lv {
    white-space: nowrap;
    border-right: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 15px;
}

.pc-vt tbody td.pc-lv small {
    margin-left: 6px;
    font-size: 11px;
    font-weight: 600;
    color: var(--mix-ink-muted);
}

.pc-vt tbody td.pc-lv sup {
    margin-left: 2px;
    font-size: 10px;
    color: var(--mix-accent);
}

.pc-vt tbody td.pc-v {
    height: 30px;
    cursor: pointer;
    border: 2px solid transparent;
    border-radius: 3px;
    transition: transform .08s;
}

.pc-vt tbody td.pc-v:hover {
    position: relative;
    z-index: 1;
    transform: scale(1.06);
}

.pc-vt tbody td.pc-v.pc-hit {
    border-color: var(--mix-ink);
    box-shadow: 0 0 0 1px var(--mix-bg) inset;
}

.pc-vt tbody td.pc-v.pc-pick {
    border-color: var(--mix-secondary);
    box-shadow: 0 0 0 2px var(--mix-secondary), 0 0 12px var(--mix-secondary);
}

.pc-vt tbody td.pc-v.pc-far {
    opacity: .35;
}

.pc-vt tbody td.pc-v-muted {
    background: var(--mix-surface-muted);
    color: var(--mix-ink-muted);
    cursor: default;
}

.pc-vt tbody td.pc-n {
    padding: 0 10px;
    white-space: nowrap;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-vt tbody tr.pc-coop td.pc-lv {
    border-top: 1px dashed color-mix(in srgb, var(--mix-ink) 18%, transparent);
}

/* The value ramp: one hue, the mix's primary, from the surface up — a set of classes on the
   tokens rather than an inline colour, so the ratchet reads it and a theme can re-hue it. */
.pc-ramp-0 { background: color-mix(in oklab, var(--mix-primary) 6%, var(--mix-surface-muted)); color: var(--mix-ink); }
.pc-ramp-1 { background: color-mix(in oklab, var(--mix-primary) 15%, var(--mix-surface-muted)); color: var(--mix-ink); }
.pc-ramp-2 { background: color-mix(in oklab, var(--mix-primary) 24%, var(--mix-surface-muted)); color: var(--mix-ink); }
.pc-ramp-3 { background: color-mix(in oklab, var(--mix-primary) 33%, var(--mix-surface-muted)); color: var(--mix-ink); }
.pc-ramp-4 { background: color-mix(in oklab, var(--mix-primary) 42%, var(--mix-surface-muted)); color: var(--mix-ink); }
.pc-ramp-5 { background: color-mix(in oklab, var(--mix-primary) 51%, var(--mix-surface-muted)); color: var(--mix-primary-contrast); }
.pc-ramp-6 { background: color-mix(in oklab, var(--mix-primary) 60%, var(--mix-surface-muted)); color: var(--mix-primary-contrast); }
.pc-ramp-7 { background: color-mix(in oklab, var(--mix-primary) 70%, var(--mix-surface-muted)); color: var(--mix-primary-contrast); }
.pc-ramp-8 { background: color-mix(in oklab, var(--mix-primary) 80%, var(--mix-surface-muted)); color: var(--mix-primary-contrast); }
.pc-ramp-9 { background: color-mix(in oklab, var(--mix-primary) 90%, var(--mix-surface-muted)); color: var(--mix-primary-contrast); }

.pc-contour-cap {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    align-items: baseline;
    min-height: 20px;
    font-size: 13px;
    color: var(--mix-ink-muted);
}

.pc-contour-cap b {
    font-family: var(--font-display);
    font-size: 16px;
    color: var(--mix-ink);
}

.pc-contour-cap .pc-eq {
    color: var(--mix-ink);
}

.pc-contour-cap button {
    appearance: none;
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
    border-radius: 3px;
    padding: 2px 8px;
    font-size: 11px;
    color: var(--mix-ink-muted);
    cursor: pointer;
}

.pc-table-foot {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-rampkey {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.pc-rampkey i {
    display: inline-block;
    width: 90px;
    height: 8px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--mix-surface-muted), var(--mix-primary));
}

/* --- the constants --- */
/* Stacked, never side by side: the grade ladder is seventeen columns and the plate table nine,
   and neither fits in a share of the row without a scroller. Full width, the ladder's grade
   columns also line up under the value table's. */
.pc-consts {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
}

.pc-ct {
    width: 100%;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.pc-ct th,
.pc-ct td {
    padding: 6px 4px;
    text-align: center;
    font-size: 12.5px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

.pc-ct th {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 13.5px;
}

.pc-ct td.pc-rl,
.pc-ct th.pc-rl {
    text-align: left;
    padding-right: 8px;
    white-space: nowrap;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.pc-ct td.pc-diff {
    color: var(--mix-ink);
    font-weight: 600;
}

.pc-ct td.pc-same {
    color: var(--mix-ink-muted);
}

.pc-ct td.pc-floor-cell {
    font-size: 11px;
    color: var(--mix-ink-muted);
}

@media (max-width: 860px) {
    .pc-hero {
        grid-template-columns: 1fr;
    }

    .pc-h1 {
        font-size: 38px;
    }

    .pc-formula {
        grid-template-columns: 1fr;
    }

    .pc-formula-line {
        font-size: 28px;
    }

    .pc-terms {
        grid-template-columns: 1fr;
    }
}

@media (prefers-reduced-motion: reduce) {
    .pc-vt tbody td.pc-v {
        transition: none;
    }
}

/* --- the comparison (this mix in primary, the other in secondary) --- */
.pc-cmp-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-cmp-legend i {
    display: inline-block;
    width: 18px;
    height: 8px;
    margin-right: 6px;
    border-radius: 2px;
    vertical-align: 0;
}

.pc-cmp-swatch-other {
    background: var(--mix-secondary);
}

.pc-cmp-swatch-mine {
    background: var(--mix-primary);
}

.pc-cmp {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) 62px;
    gap: 0 10px;
    margin-top: 12px;
}

.pc-cmp-axis {
    grid-column: 2;
    position: relative;
    height: 22px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-cmp-axis span {
    position: absolute;
    bottom: 4px;
    transform: translateX(-50%);
}

.pc-cmp-lbl {
    height: 40px;
    margin-bottom: 6px;
    line-height: 40px;
    text-align: right;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 14px;
}

.pc-cmp-track {
    position: relative;
    height: 40px;
    margin-bottom: 6px;
}

.pc-cmp-grid {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 1px;
    background: color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

.pc-cmp-bar {
    position: absolute;
    height: 14px;
    border-radius: 0 3px 3px 0;
}

.pc-cmp-bar-other {
    top: 4px;
    background: var(--mix-secondary);
}

.pc-cmp-bar-mine {
    top: 22px;
    background: var(--mix-primary);
}

.pc-cmp-bar span {
    position: absolute;
    left: calc(100% + 6px);
    top: -1px;
    white-space: nowrap;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 12.5px;
    color: var(--mix-ink);
}

.pc-cmp-anchor {
    position: absolute;
    top: 2px;
    bottom: 2px;
    width: 2px;
    background: var(--mix-ink);
    transform: translateX(-1px);
}

/* Where the two curves cross, said under the bars that show it. */
.pc-cmp-note {
    margin: 12px 0 0;
    padding-top: 10px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    font-size: 12.5px;
    color: var(--mix-ink-muted);
}

.pc-cmp-facts {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}

.pc-cmp-fact {
    display: flex;
    flex-direction: column;
    gap: 3px;
    border-left: 3px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
}

.pc-cmp-fact.pc-cmp-hero {
    border-left-color: var(--mix-primary);
    background: color-mix(in srgb, var(--mix-primary) 7%, var(--mix-surface));
}

.pc-cmp-fact.pc-cmp-hero .pc-lbl {
    color: var(--mix-ink);
}

.pc-cmp-pair {
    display: flex;
    gap: 14px;
    align-items: baseline;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 22px;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.pc-cmp-hero .pc-cmp-pair {
    font-size: 26px;
}

.pc-cmp-other {
    color: var(--mix-secondary);
}

.pc-cmp-mine {
    color: var(--mix-primary);
}

.pc-cmp-vs {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .1em;
    color: var(--mix-ink-muted);
}

.pc-cmp-say {
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-cmp-say b {
    color: var(--mix-ink);
    font-weight: 600;
}

.pc-answer {
    margin: 0;
    max-width: 78ch;
    font-size: 14px;
    line-height: 1.5;
}

.pc-answer b {
    color: var(--mix-ink);
    font-weight: 600;
}

.pc-answer .pc-n {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 16px;
}

@media (max-width: 860px) {
    .pc-cmp-facts {
        grid-template-columns: 1fr;
    }
}

/* A type block is a run of sections; the script hides the type not selected. The explicit
   [hidden] rule matters: the flex display below would otherwise beat the attribute. */
.pc-type-block {
    display: flex;
    flex-direction: column;
    gap: 34px;
}

.pc-type-block[hidden] {
    display: none;
}

/* --- the quick calculator --- */
.pc-calc {
    display: grid;
    grid-template-columns: auto auto auto minmax(0, 1fr);
    gap: 14px 22px;
    align-items: end;
}

.pc-calc-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.pc-calc select {
    appearance: none;
    min-width: 130px;
    padding: 8px 32px 8px 10px;
    background: var(--mix-surface-muted);
    color: var(--mix-ink);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 18%, transparent);
    border-radius: 4px;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 16px;
    background-image: linear-gradient(45deg, transparent 50%, var(--mix-ink-muted) 50%), linear-gradient(135deg, var(--mix-ink-muted) 50%, transparent 50%);
    background-position: calc(100% - 16px) 55%, calc(100% - 11px) 55%;
    background-size: 5px 5px;
    background-repeat: no-repeat;
}

.pc-calc select:focus-visible {
    outline: 2px solid var(--mix-secondary);
    outline-offset: 1px;
}

.pc-calc-static {
    padding: 8px 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 16px;
    color: var(--mix-ink-muted);
}

.pc-calc-out {
    display: flex;
    flex-direction: column;
    gap: 4px;
    justify-self: end;
    text-align: right;
}

.pc-calc-big {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 44px;
    line-height: 1;
    letter-spacing: .01em;
    font-variant-numeric: tabular-nums;
}

.pc-calc-math {
    font-size: 13px;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

.pc-calc-eq {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
    padding-top: 10px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    font-size: 13px;
    color: var(--mix-ink-muted);
}

.pc-calc-eq:empty {
    display: none;
}

.pc-calc-eq b {
    color: var(--mix-ink);
    font-weight: 600;
}

@media (max-width: 860px) {
    .pc-calc {
        grid-template-columns: 1fr 1fr;
    }

    .pc-calc-out {
        grid-column: 1 / -1;
        justify-self: start;
        text-align: left;
    }
}

/* --- the population answers --- */
.pc-pop-bands {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
    margin: 0;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.pc-pop-bands b {
    color: var(--mix-ink);
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: .04em;
}

.pc-plate-rail {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* The plate ladder as one bar, Rough Game to Perfect Game: every plate a segment in its own
   plate colour, sized by its bonus, carrying what it is worth on the reference chart. */
.pc-plate-track {
    position: relative;
    display: flex;
    height: 44px;
    border-radius: 4px;
    background: var(--mix-surface-muted);
    overflow: hidden;
}

.pc-plate-seg {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-width: 0;
    overflow: hidden;
    /* The plate fills are light in every theme and the page ground is dark in every theme, so
       the ground colour is the ink that reads on all of them. */
    color: var(--mix-bg);
    font-family: var(--font-display);
    line-height: 1.15;
    border-right: 2px solid var(--mix-surface);
}

.pc-plate-seg:last-child {
    border-right: 0;
}

.pc-plate-seg-name {
    font-weight: 700;
    font-size: 12.5px;
    letter-spacing: .04em;
}

.pc-plate-seg-val {
    font-weight: 600;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

/* Where the tracked pools' average plate falls on the same scale. */
.pc-plate-marker {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--mix-ink);
}

.pc-plate-poolrow {
    position: relative;
    height: 16px;
}

.pc-plate-pool {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: 11.5px;
    color: var(--mix-ink);
}

.pc-plate-ends {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    font-size: 11.5px;
    color: var(--mix-ink-muted);
}

/* On a phone the seven segments are too narrow to carry their labels: the bar stays coloured
   and the labels move into a list beneath it. */
.pc-plate-list {
    display: none;
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (max-width: 640px) {
    .pc-plate-track {
        height: 14px;
    }

    .pc-plate-seg span {
        display: none;
    }

    .pc-plate-poolrow {
        height: auto;
    }

    .pc-plate-pool {
        position: static;
        transform: none;
        white-space: normal;
    }

    .pc-plate-list {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 4px 12px;
        font-size: 12px;
    }

    .pc-plate-list i {
        display: inline-block;
        width: 10px;
        height: 10px;
        margin-right: 6px;
        border-radius: 2px;
        vertical-align: -1px;
    }

    .pc-plate-list b {
        font-variant-numeric: tabular-nums;
    }
}


/* ============================================================================
   Phoenix Score Calculator (/PhoenixCalculator/{mix}) — docs/design/phoenix-score-calculator.md
   A static reference page: the formula, judgement costs, both mixes' letter
   cutoffs and the measured population/note-count/hold-tick sections, all real
   HTML. What moves (the live calculator, its bars and next-letter walk, the
   plays dialog, the toggles, chart tooltips) is wwwroot/js/phoenix-calculator.js
   working on this markup. Tokens only.
   ============================================================================ */

.sc-page {
    display: flex;
    flex-direction: column;
    gap: 34px;
    padding: 16px 0 72px;
}

.sc-eyebrow {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: baseline;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 12.5px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.sc-eyebrow .sc-sep {
    color: color-mix(in srgb, var(--mix-ink) 18%, transparent);
}

.sc-eyebrow .sc-mix {
    color: var(--mix-primary);
}

.sc-eyebrow a {
    color: var(--mix-ink-muted);
    border-bottom: 1px dotted var(--mix-ink-muted);
    text-decoration: none;
}

.sc-eyebrow a:hover {
    color: var(--mix-ink);
}

.sc-h1 {
    margin: 8px 0 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 46px;
    line-height: 1;
    letter-spacing: .005em;
    text-wrap: balance;
}

.sc-h1 span {
    color: var(--mix-primary);
}

.sc-lede {
    max-width: 66ch;
    margin: 12px 0 0;
    font-size: 15px;
    line-height: 1.5;
}

.sc-muted {
    color: var(--mix-ink-muted);
}

.sc-sec {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.sc-sec-head {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.sc-h2 {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 24px;
    letter-spacing: .005em;
    text-wrap: balance;
}

.sc-h3 {
    margin: 10px 0 0;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 17px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.sc-sub {
    max-width: 76ch;
    font-size: 13px;
    color: var(--mix-ink-muted);
}

.sc-card {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 16px 18px;
}

.sc-foot {
    max-width: 78ch;
    margin: 2px 0 0;
    font-size: 13px;
    color: var(--mix-ink-muted);
}

.sc-srcline {
    margin: 0;
    font-size: 12.5px;
    font-style: italic;
    color: var(--mix-ink-muted);
}

.sc-num {
    font-variant-numeric: tabular-nums;
}

/* --- the calculator --- */
.sc-calc {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
}

@media (min-width: 900px) {
    .sc-calc {
        grid-template-columns: minmax(0, 10fr) minmax(0, 11fr);
        gap: 26px;
    }

    .sc-result {
        border-left: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
        padding-left: 26px;
    }
}

.sc-inputs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    align-content: start;
}

.sc-field {
    display: block;
}

.sc-lbl {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 4px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.sc-lbl em {
    font-style: normal;
    text-transform: none;
    letter-spacing: 0;
}

.sc-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: none;
}

.sc-dot.judg-perfect { background: var(--judg-perfect); }
.sc-dot.judg-great { background: var(--judg-great); }
.sc-dot.judg-good { background: var(--judg-good); }
.sc-dot.judg-bad { background: var(--judg-bad); }
.sc-dot.judg-miss { background: var(--judg-miss); }
.sc-dot.sc-dot-combo { background: var(--mix-secondary); }

.sc-field input {
    width: 100%;
    font: 500 19px/1.2 var(--font-body);
    font-variant-numeric: tabular-nums;
    color: var(--mix-ink);
    background: var(--mix-surface-muted);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    border-radius: 6px;
    padding: 9px 11px;
}

.sc-field input:focus {
    outline: none;
    border-color: var(--mix-primary);
}

.sc-loadrow {
    grid-column: 1 / -1;
}

.sc-btn {
    font: 600 14px var(--font-body);
    color: var(--mix-primary);
    background: none;
    border: 1px solid var(--mix-primary);
    border-radius: 6px;
    padding: 8px 14px;
    cursor: pointer;
}

.sc-btn:hover {
    background: var(--mix-surface-muted);
}

.sc-scoreline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
}

.sc-bigscore {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(44px, 6vw, 60px);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.sc-scoreline .sc-gradeimg {
    height: 30px;
    width: auto;
    object-fit: scale-down;
}

.sc-scoreline .sc-plateimg {
    height: 26px;
    width: auto;
    object-fit: scale-down;
}

.sc-table td img {
    vertical-align: middle;
}

.sc-bigscore.sc-empty {
    color: color-mix(in srgb, var(--mix-ink) 22%, transparent);
}

.sc-hint {
    margin: 8px 0 0;
    font-size: 13.5px;
    color: var(--mix-ink-muted);
}

.sc-crossmix {
    margin: 6px 0 0;
    font-size: 13.5px;
    color: var(--mix-ink-muted);
}

.sc-next {
    margin: 14px 0 0;
    padding: 10px 12px;
    background: var(--mix-surface-muted);
    border-radius: 6px;
    font-size: 14px;
}

.sc-next b {
    color: var(--mix-primary);
}

.sc-next .sc-next-label {
    display: block;
    margin-bottom: 3px;
    font-size: 11px;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.sc-bars {
    display: grid;
    gap: 16px;
    margin-top: 16px;
}

.sc-bar h4 {
    margin: 0 0 6px;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 14px;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.sc-bar h4 .sc-range {
    font-family: var(--font-body);
    font-size: 12px;
    letter-spacing: 0;
    text-transform: none;
    font-variant-numeric: tabular-nums;
}

.sc-bartrack {
    position: relative;
    height: 26px;
    border-radius: 5px;
    background: var(--mix-surface-muted);
    overflow: hidden;
}

.sc-barseg {
    position: absolute;
    top: 0;
    bottom: 0;
}

.sc-barseg.sc-clip {
    background-image: linear-gradient(90deg, rgba(255, 255, 255, .3), transparent 8px);
}

.sc-barseg.judg-perfect { background-color: var(--judg-perfect); }
.sc-barseg.judg-great { background-color: var(--judg-great); }
.sc-barseg.judg-good { background-color: var(--judg-good); }
.sc-barseg.judg-bad { background-color: var(--judg-bad); }
.sc-barseg.judg-miss { background-color: var(--judg-miss); }
.sc-barseg.sc-seg-combo { background-color: var(--mix-secondary); }

.sc-barlegend {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    margin-top: 6px;
    font-size: 12.5px;
    color: var(--mix-ink-muted);
}

.sc-barlegend .sc-it {
    display: flex;
    gap: 6px;
    align-items: center;
}

.sc-barlegend b {
    color: var(--mix-ink);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}

.sc-barlegend .sc-sw-empty {
    background: var(--mix-surface-muted);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 15%, transparent);
}

.sc-calrow {
    margin: 12px 0 0;
    font-size: 13.5px;
    color: var(--mix-ink-muted);
}

.sc-calrow b {
    color: var(--mix-ink);
    font-variant-numeric: tabular-nums;
}

/* --- the formula --- */
.sc-formula {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(16px, 2.4vw, 24px);
    font-variant-numeric: tabular-nums;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 18px 16px;
    overflow-x: auto;
    white-space: nowrap;
    text-align: center;
}

.sc-formula .sc-op {
    font-style: normal;
    color: var(--mix-ink-muted);
}

.sc-formula b {
    font-weight: 600;
}

.sc-formula .judg-perfect { color: var(--judg-perfect); }
.sc-formula .judg-great { color: var(--judg-great); }
.sc-formula .judg-good { color: var(--judg-good); }
.sc-formula .judg-bad { color: var(--judg-bad); }
.sc-formula .sc-t-combo { color: var(--mix-secondary); }

.sc-fnotes {
    display: grid;
    gap: 8px;
    margin: 4px 0 0;
    padding: 0;
    list-style: none;
    max-width: 78ch;
}

.sc-fnotes li {
    position: relative;
    padding-left: 18px;
    font-size: 14px;
}

.sc-fnotes li::before {
    content: "";
    position: absolute;
    left: 2px;
    top: .5em;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--mix-primary);
}

.sc-credit {
    margin: 6px 0 0;
    font-size: 13px;
    color: var(--mix-ink-muted);
}

/* --- costs --- */
.sc-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.sc-chip {
    font: 600 13.5px var(--font-body);
    font-variant-numeric: tabular-nums;
    color: var(--mix-ink-muted);
    background: none;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 20px;
    padding: 5px 13px;
    cursor: pointer;
}

.sc-chip[aria-pressed="true"] {
    color: var(--mix-primary-contrast);
    background: var(--mix-primary);
    border-color: var(--mix-primary);
}

.sc-costcards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px;
}

.sc-costcard {
    display: flex;
    flex-direction: column;
    gap: 2px;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 12px 14px;
}

.sc-cost-l {
    display: flex;
    align-items: center;
    gap: 7px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 12px;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
}

.sc-cost-v {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 26px;
    font-variant-numeric: tabular-nums;
}

.sc-cost-s {
    font-size: 12px;
    color: var(--mix-ink-muted);
}

/* --- tables --- */
.sc-tablewrap {
    overflow-x: auto;
}

.sc-table {
    border-collapse: collapse;
    width: 100%;
    font-size: 13.5px;
}

.sc-table th {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 13px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--mix-ink-muted);
    text-align: right;
    padding: 7px 10px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    white-space: nowrap;
}

.sc-table th:first-child,
.sc-table td:first-child {
    text-align: left;
    padding-left: 0;
}

.sc-table td {
    padding: 6px 10px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.sc-table tr:last-child td {
    border-bottom: 0;
}

.sc-table .sc-th-left,
.sc-table .sc-td-left {
    text-align: left;
}

.sc-table tr.sc-you td {
    background: var(--mix-surface-muted);
}

.sc-table th .sc-dot {
    display: inline-block;
    vertical-align: 1px;
}

/* --- the ladder --- */
.sc-moved {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.sc-pill {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 7px 12px;
    font-size: 13.5px;
    font-variant-numeric: tabular-nums;
}

.sc-pill img {
    height: 16px;
    width: auto;
    vertical-align: -3px;
}

.sc-pill s {
    color: var(--mix-ink-muted);
}

.sc-plates {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
    gap: 8px;
}

.sc-platerow {
    display: flex;
    gap: 10px;
    align-items: baseline;
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
    border-radius: 6px;
    padding: 8px 12px;
    font-size: 13.5px;
}

.sc-platerow img {
    flex: none;
    align-self: center;
}

.sc-platerule {
    color: var(--mix-ink-muted);
    font-size: 12.5px;
}

/* --- charts --- */
.sc-chartwrap {
    overflow-x: auto;
}

.sc-chartwrap svg {
    display: block;
    min-width: 600px;
    width: 100%;
    height: auto;
}

.sc-grid {
    stroke: color-mix(in srgb, var(--mix-ink) 8%, transparent);
    stroke-width: 1;
}

.sc-tick {
    font-size: 11px;
    fill: var(--mix-ink-muted);
}

.sc-band-below { fill: var(--unplayed-grade); stroke: rgba(255, 255, 255, .28); stroke-width: .6; }
.sc-band-copper { fill: var(--grade-aa); }
.sc-band-silver { fill: var(--grade-aaa); }
.sc-band-gold { fill: var(--grade-s); }
.sc-band-ice { fill: var(--grade-sssplus); }

i.sc-band-below { background: var(--unplayed-grade); }
i.sc-band-copper { background: var(--grade-aa); }
i.sc-band-silver { background: var(--grade-aaa); }
i.sc-band-gold { background: var(--grade-s); }
i.sc-band-ice { background: var(--grade-sssplus); }

.sc-noteband {
    fill: var(--mix-primary);
    opacity: .22;
}

.sc-noteline {
    fill: none;
    stroke: var(--mix-primary);
    stroke-width: 2;
    stroke-linejoin: round;
}

.sc-notedot {
    fill: var(--mix-ink-muted);
    opacity: .7;
}

.sc-holdband {
    fill: var(--mix-secondary);
    opacity: .2;
}

.sc-holdline {
    fill: none;
    stroke: var(--mix-secondary);
    stroke-width: 2;
    stroke-linejoin: round;
}

.sc-fline {
    stroke: var(--judg-miss);
    stroke-width: 1.5;
    stroke-dasharray: 6 5;
    opacity: .85;
}

.sc-fline-label {
    font-size: 11px;
    fill: var(--judg-miss);
}

.sc-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    font-size: 13px;
    color: var(--mix-ink-muted);
}

.sc-legend-item {
    display: flex;
    gap: 7px;
    align-items: center;
}

.sc-sw {
    width: 12px;
    height: 12px;
    border-radius: 3px;
    flex: none;
}

.sc-sw-holdline { background: var(--mix-secondary); }
.sc-sw-holdband { background: var(--mix-secondary); opacity: .25; }
.sc-sw-fline { background: none; border-top: 2px dashed var(--judg-miss); height: 0; border-radius: 0; }

.sc-typebar {
    display: flex;
    gap: 4px;
    background: var(--mix-surface-muted);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
    border-radius: 6px;
    padding: 3px;
    width: max-content;
}

.sc-typebar button {
    font: 600 14px var(--font-body);
    color: var(--mix-ink-muted);
    background: none;
    border: 0;
    border-radius: 4px;
    padding: 6px 16px;
    cursor: pointer;
}

.sc-typebar button[aria-pressed="true"] {
    background: var(--mix-primary);
    color: var(--mix-primary-contrast);
}

.sc-holdlists {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
}

@media (min-width: 700px) {
    .sc-holdlists {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

/* --- the plays dialog --- */
.sc-dlg-overlay {
    position: fixed;
    inset: 0;
    z-index: 1400;
    background: rgba(0, 0, 0, .6);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.sc-dlg-overlay[hidden] {
    display: none;
}

.sc-dlg {
    background: var(--mix-surface);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    border-radius: 8px;
    width: min(680px, 100%);
    max-height: min(80vh, 640px);
    display: flex;
    flex-direction: column;
    box-shadow: 0 18px 60px rgba(0, 0, 0, .55);
}

.sc-dlg-head {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 18px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

.sc-dlg-head h3 {
    margin: 0;
    flex: 1;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 20px;
}

.sc-dlg-head button {
    font: 20px/1 var(--font-body);
    color: var(--mix-ink-muted);
    background: none;
    border: 0;
    cursor: pointer;
    padding: 4px 8px;
}

.sc-dlg-head button:hover {
    color: var(--mix-ink);
}

.sc-dlg-body {
    padding: 12px 18px 16px;
    overflow-y: auto;
}

.sc-dlg-body > input {
    width: 100%;
    font: 14px var(--font-body);
    color: var(--mix-ink);
    background: var(--mix-surface-muted);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    border-radius: 6px;
    padding: 8px 11px;
    margin-bottom: 10px;
}

.sc-ptwrap {
    overflow-x: auto;
}

.sc-playtable {
    border-collapse: collapse;
    width: 100%;
    font-size: 13.5px;
}

.sc-playtable td {
    padding: 5px 8px;
    border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
    vertical-align: middle;
    white-space: nowrap;
}

.sc-playtable tr[data-sc-play] {
    cursor: pointer;
}

.sc-playtable tr[data-sc-play]:hover td {
    background: var(--mix-surface-muted);
}

.sc-playtable tr:last-child td {
    border-bottom: 0;
}

.sc-jk {
    height: 22px;
    width: auto;
    object-fit: scale-down;
    display: block;
}

.sc-bub {
    height: 22px;
    width: auto;
    object-fit: scale-down;
    display: block;
}

.sc-bubtext {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.sc-pt-name {
    max-width: 170px;
    overflow: hidden;
    text-overflow: ellipsis;
}


.sc-pt-j {
    font-variant-numeric: tabular-nums;
    font-size: 12.5px;
}

.sc-pt-j .judg-perfect { color: var(--judg-perfect); }
.sc-pt-j .judg-great { color: var(--judg-great); }
.sc-pt-j .judg-good { color: var(--judg-good); }
.sc-pt-j .judg-bad { color: var(--judg-bad); }
.sc-pt-j .judg-miss { color: var(--judg-miss); }
.sc-pt-j .sc-pt-combo { color: var(--mix-secondary); }

.sc-pt-j .sc-sl {
    color: var(--mix-ink-muted);
    opacity: .6;
}

.sc-pt-score {
    text-align: right;
}

.sc-pt-score .sc-wrap {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.sc-pt-score .sc-n {
    font-weight: 500;
    font-size: 14.5px;
    font-variant-numeric: tabular-nums;
}

.sc-gstack {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    min-width: 38px;
}

.sc-gstack-grade {
    height: 14px;
    width: auto;
    object-fit: scale-down;
}

.sc-gstack-plate {
    height: 11px;
    width: auto;
    object-fit: scale-down;
}

.sc-playsnote {
    margin: 8px 0 0;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.sc-chartcell {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* --- the shared chart tooltip (created by the script) --- */
.sc-tip {
    position: fixed;
    z-index: 1500;
    pointer-events: none;
    max-width: 300px;
    background: color-mix(in srgb, var(--mix-bg) 92%, transparent);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    border-radius: 6px;
    padding: 8px 11px;
    font-size: 12.5px;
    font-variant-numeric: tabular-nums;
}

/* ── The judgement strip (JudgementStrip) ─────────────────────────────────────────────────
   A play's counts in the game's own --judg-* vocabulary: the colour is the label, the count
   is the value — the one score fact rendered as coloured text rather than art (UX guide,
   session-breakdown.md D43). Rendered as a <button> when it opens the Score Breakdown
   Dialog, a <span> when it is only a readout; both wear the same face, the button just says
   so on hover and focus. */
.judg-strip {
    display: inline-flex;
    /* Baseline, not center: the combo runs a size smaller, and box-centering left its
       digits floating off the counts' shared baseline (owner, field test). */
    align-items: baseline;
    gap: 8px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .84rem;
    font-variant-numeric: tabular-nums;
    line-height: 1.4;
    padding: 1px 8px;
    border-radius: 6px;
    border: 1px solid color-mix(in srgb, var(--mix-ink) 14%, transparent);
    background: color-mix(in srgb, var(--mix-bg) 45%, transparent);
    color: var(--mix-ink);
}

button.judg-strip {
    cursor: pointer;
}

button.judg-strip:hover {
    border-color: color-mix(in srgb, var(--mix-ink) 34%, transparent);
}

button.judg-strip:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 1px;
}

.judg-strip-sm {
    gap: 6px;
    font-size: .76rem;
    padding: 0 6px;
}

.judg-strip .judg-perfect { color: var(--judg-perfect); }
.judg-strip .judg-great { color: var(--judg-great); }
.judg-strip .judg-good { color: var(--judg-good); }
.judg-strip .judg-bad { color: var(--judg-bad); }
.judg-strip .judg-miss { color: var(--judg-miss); }

.judg-strip-combo {
    color: var(--mix-ink-muted);
    font-size: .9em;
}

/* ── The Score Breakdown Dialog ───────────────────────────────────────────────────────────
   The calculator's bars and walk (score-breakdown.js markup, sc-bar* classes above) inside
   a dialog frame. Width capped here rather than via MaxWidth.Small — charts.scss globally
   un-caps `.mud-dialog-width-sm`, the ChartDetailsDialog precedent. */
.mud-dialog.score-breakdown-dialog {
    max-width: 480px;
}

.mud-dialog.score-breakdown-dialog .mud-dialog-content {
    max-height: min(70vh, 720px);
    overflow-y: auto;
}

.sbdlg-title {
    display: flex;
    align-items: center;
    gap: 8px;
}

.sbdlg-sub {
    display: block;
    color: var(--mix-ink-muted);
    margin: 2px 0 8px;
}

.sbdlg-score {
    margin: 4px 0 8px;
}

.sbdlg-next {
    display: block;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent);
}

/* ── The attempt thread (All plays, D49) ──────────────────────────────────────────────────
   A dotted rail joining adjacent plays of one chart — annotation over the flat log, never a
   grouping: every row stays a row. Threaded rows indent to make room; the rail half-heights
   at a run's ends so it reads as joining rows, not as a column of its own. */
.sbd-row.sbd-thread {
    position: relative;
    padding-left: 12px;
}

.sbd-thread::before {
    content: "";
    position: absolute;
    left: 3px;
    top: 0;
    bottom: 0;
    border-left: 2px dotted color-mix(in srgb, var(--mix-primary) 45%, transparent);
}

.sbd-thread-start::before {
    top: 50%;
}

.sbd-thread-end::before {
    bottom: 50%;
}

.sbd-attempt {
    font-size: .68rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

/* ── Highlight cards (SessionHighlightCards, D41) ─────────────────────────────────────────
   The session's flagged scores as jacket cards, one per chart. The ring is the same rarity
   band as the score's colour — same ramp, same shared-PG mute — and the glow classes keep
   carrying the monotonic ordering the hues cannot. Below 700px the grid becomes a
   scroll-snap strip so the jackets stay big instead of shrinking into columns. */
.hl-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(236px, 1fr));
    gap: 12px;
}

.hl-card {
    position: relative;
    border-radius: 10px;
    overflow: hidden;
    background: var(--mix-surface-muted);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent);
}

.hl-card-emerald { border-color: color-mix(in srgb, var(--rarity-emerald) 45%, transparent); }
.hl-card-gold {
    border-color: color-mix(in srgb, var(--rarity-gold) 55%, transparent);
    box-shadow: 0 0 14px -6px var(--rarity-gold);
}
.hl-card-sapphire {
    border-color: color-mix(in srgb, var(--rarity-sapphire) 55%, transparent);
    box-shadow: 0 0 14px -6px var(--rarity-sapphire);
}
.hl-card-prism {
    border-color: color-mix(in srgb, var(--rarity-prism) 70%, transparent);
    box-shadow: 0 0 18px -5px var(--rarity-prism);
}

/* The jacket, drawn the way the tier card draws it: a background-image div, which is also
   the card's ONE navigation target — a whole-card target put the judgement strip a near-miss
   away from opening chart details (owner, field test). */
.hl-card-art {
    position: relative;
    aspect-ratio: 16 / 8.2;
    background-color: var(--mix-bg);
    background-size: cover;
    background-position: center;
    cursor: pointer;
}

.hl-card-art:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: -2px;
}

/* The scrim keeps the body legible over any jacket; the body overlaps the art bottom. */
.hl-card-art::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, color-mix(in srgb, var(--mix-bg) 0%, transparent) 30%,
        color-mix(in srgb, var(--mix-bg) 92%, transparent) 96%);
}

.hl-card-bubble {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 2;
}

.hl-card-badges {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 2;
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
    justify-content: flex-end;
    max-width: 75%;
}

/* The row badge's face over album art: an opaque backdrop keeps it legible on any jacket. */
.hl-card-badge {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: .7rem;
    padding: 1px 7px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--mix-bg) 72%, transparent);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 20%, transparent);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.hl-card-body {
    position: relative;
    z-index: 2;
    padding: 0 11px 10px;
    margin-top: -34px;
}

.hl-card-song {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.06rem;
    line-height: 1.1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.hl-card-scoreline {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: 4px;
    flex-wrap: wrap;
}

.hl-card-scoreline .sbd-score,
.hl-card-score {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.1rem;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

/* The established gain chip (D48) rides the score line, aligned right. */
.hl-card-gain {
    margin-left: auto;
    border-radius: 4px;
}

.hl-card-foot {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 5px;
    flex-wrap: wrap;
}

.hl-card-standing {
    font-size: .72rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
}

/* The gained score, where the "Upscore" chip used to sit — the number says it better. */
.hl-card-delta {
    font-size: .74rem;
    font-weight: 600;
    color: var(--mud-palette-success);
    font-variant-numeric: tabular-nums;
}

@media (max-width: 700px) {
    .hl-cards {
        display: flex;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        padding-bottom: 6px;
        -webkit-overflow-scrolling: touch;
    }

    .hl-cards .hl-card {
        flex: 0 0 216px;
        scroll-snap-align: start;
    }
}

/* ===== Step chart & failure map (docs/design/step-chart-failure-map.md) ===== */
/* The strip viewer: content-width scroll box beside a sticky whole-chart minimap. The rail
   (pins) lives inside the canvas; everything here is layout, every color a token. */
/* The strip's root positions the comment panel, which the module lays over the frame's bottom
   edge from the strip to the map (step-chart-comments D16); the viewer is positioned too, so
   the box's offsets read against it. */
[data-stepchart] {
    position: relative;
}

.stepchart-viewer {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    /* Left-aligned on the page (owner, 2026-08-30); the dialog stays centered. */
    justify-content: flex-start;
    position: relative;
}

.stepchart-compact .stepchart-viewer {
    justify-content: center;
}

.stepchart-scroll {
    position: relative;
    height: 600px;
    overflow: auto;
    /* Reserve the vertical scrollbar's lane up front — measuring width before the bar
       arrives left a few pixels of horizontal scroll (owner, 2026-08-30). */
    scrollbar-gutter: stable;
    width: max-content;
    max-width: calc(100% - 106px);
    flex: none;
    border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 10px;
    background: var(--mix-surface-muted);
    scrollbar-width: thin;
    /* Pan and pinch stay; the browser's double-tap zoom goes, so a double-tap can mean
       "comment here" (step-chart-comments D2). */
    touch-action: manipulation;
}

.stepchart-compact .stepchart-scroll {
    height: 380px;
    max-width: calc(100% - 96px);
}

/* The dialog's minimap rides the dead space right of the rail — same map, compact sizes. */
.stepchart-compact .stepchart-minimap {
    width: 76px;
    height: 380px;
}

.stepchart-scroll canvas {
    display: block;
}

.stepchart-minicol {
    position: sticky;
    top: 14px;
}

.stepchart-minimap {
    display: block;
    width: 92px;
    height: 600px;
    border: 1px solid rgba(255, 255, 255, .10);
    border-radius: 10px;
    background: var(--mix-surface-muted);
    cursor: pointer;
}

/* Dense on purpose: more than three chips must not push the strip below the fold
   (owner, 2026-08-30). */
.stepchart-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin: 0 0 10px;
}

.stepchart-chip {
    font-size: .72rem;
    font-weight: 500;
    color: var(--mix-ink);
    background: var(--mix-surface);
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 999px;
    padding: 3px 9px 3px 7px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.stepchart-chip:hover {
    border-color: var(--mix-ink-muted);
}

.stepchart-chip i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--mix-ink-muted);
}

.stepchart-chip-struct i {
    background: var(--mix-primary);
}

.stepchart-chip-spike i {
    background: var(--life-danger);
}

/* Lit while the viewport sits inside the chip's section — the chips double as a "you are
   here" for the strip. */
.stepchart-chip-active {
    border-color: var(--mix-primary);
    background: var(--mix-surface-muted);
}

.stepchart-chip small {
    color: var(--mix-ink-muted);
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
}

.stepchart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
    margin-top: 12px;
    color: var(--mix-ink-muted);
    font-size: .8rem;
}

.stepchart-legend-entry {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.stepchart-legend-entry i {
    width: 9px;
    height: 9px;
    border-radius: 2px;
    display: inline-block;
}

.stepchart-caveat {
    border-left: 3px solid var(--mix-primary);
    background: var(--mix-surface);
    border-radius: 0 8px 8px 0;
    padding: 8px 12px;
    color: var(--mix-ink-muted);
    font-size: .84rem;
    margin: 0 0 12px;
}

@media (max-width: 760px) {
    /* Narrow screens SQUISH rather than scroll (owner, 2026-08-30): the map thins out, the
       gap tightens, and the module scales the strip to the width that remains - horizontal
       scrolling on mobile is a deal breaker. */
    .stepchart-viewer {
        gap: 8px;
    }

    .stepchart-minimap {
        width: 40px;
    }

    .stepchart-scroll {
        max-width: calc(100% - 50px);
    }
}

/* The rail's hover tooltip: fixed beside the cursor, ink on the deepest surface. */
.stepchart-tip {
    position: fixed;
    z-index: 3000;
    pointer-events: none;
    background: var(--mix-bg);
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 8px;
    padding: 8px 11px;
    font-size: .8rem;
    color: var(--mix-ink);
    max-width: 260px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, .5);
}

.stepchart-tip-time {
    color: var(--mix-ink-muted);
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
}

/* A comment mark's tooltip: who, two lines, the tally. */
.stepchart-tip-who {
    font-weight: 600;
    margin-top: 2px;
}

.stepchart-tip-who small {
    color: var(--mix-ink-muted);
    font-weight: 400;
    margin-left: 5px;
}

.stepchart-tip-excerpt {
    margin-top: 2px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.stepchart-tip-foot {
    color: var(--mix-ink-muted);
    font-size: .72rem;
    margin-top: 4px;
}

/* The hairline under the mouse with the second a double-click would land on. DOM, not
   canvas: it moves with every mouse event. */
.stepchart-second {
    position: absolute;
    left: 0;
    right: 0;
    height: 0;
    border-top: 1px solid rgba(255, 255, 255, .35);
    pointer-events: none;
}

.stepchart-second span {
    position: absolute;
    top: -9px;
    font-size: 10px;
    line-height: 18px;
    color: var(--mix-ink);
    background: var(--mix-bg);
    border: 1px solid rgba(255, 255, 255, .14);
    border-radius: 999px;
    padding: 0 7px;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.stepchart-tip-hedge {
    color: var(--mix-ink-muted);
    font-size: .76rem;
    margin-top: 3px;
}

/* The coloring-mode toggle: a segmented control, pressed state on the surface token. */
.stepchart-modes {
    display: inline-flex;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 9px;
    overflow: hidden;
    margin: 0 0 12px;
}

.stepchart-modes button {
    font-size: .8rem;
    font-weight: 500;
    color: var(--mix-ink-muted);
    background: transparent;
    border: none;
    padding: 8px 14px;
    cursor: pointer;
}

.stepchart-modes button + button {
    border-left: 1px solid rgba(255, 255, 255, .12);
}

.stepchart-modes button[aria-pressed="true"] {
    background: var(--mix-surface);
    color: var(--mix-ink);
}

.stepchart-modes button:disabled {
    opacity: .45;
    cursor: default;
}

.stepchart-tip-cmd {
    height: 20px;
    display: inline-block;
    vertical-align: middle;
    margin: 2px 4px 2px 0;
}

/* Modes + AV share one toolbar row; the AV stepper mirrors the segmented control. */
.stepchart-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
    margin: 0 0 12px;
}

.stepchart-toolbar .stepchart-modes {
    margin: 0;
}

.stepchart-av {
    display: inline-flex;
    align-items: center;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 9px;
    overflow: hidden;
}

.stepchart-av button {
    font-size: .8rem;
    font-weight: 500;
    color: var(--mix-ink-muted);
    background: transparent;
    border: none;
    padding: 8px 12px;
    cursor: pointer;
}

.stepchart-av button[aria-pressed="true"] {
    background: var(--mix-surface);
    color: var(--mix-ink);
}

.stepchart-av-value {
    font-size: .8rem;
    color: var(--mix-ink);
    padding: 0 4px;
    min-width: 56px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    border-left: 1px solid rgba(255, 255, 255, .12);
    border-right: 1px solid rgba(255, 255, 255, .12);
    align-self: stretch;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.stepchart-legend-cmd {
    height: 16px;
    vertical-align: middle;
}

/* ---------------------------------------------------------------------------------------------
   Peer standing (docs/design/peers-abstraction.md §4.4). PeerScore is the one component that
   paints a player's own score by their standing among the peers they chose; the standing text
   rides beside it (rule 8) and both are the tap target for the popover. The popover is a tap
   surface, never a hover one — a phone has no hover. */
.peer-score-anchor {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
}

.peer-score {
    display: inline-flex;
    align-items: center;
    border-radius: 3px;
}

.peer-score-open {
    cursor: pointer;
}

.peer-score-open:hover,
.peer-standing-open:hover {
    background: color-mix(in srgb, var(--mix-ink) 6%, transparent);
}

.peer-score-open:focus-visible,
.peer-standing-open:focus-visible {
    outline: 2px solid var(--mix-primary);
    outline-offset: 1px;
}

/* The printed standing: the sessions row's .sbd-peerpct, now shared by every surface. */
.peer-standing {
    font-size: .68rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    border-radius: 3px;
    padding: 1px 4px;
    border: 1px dashed transparent;
}

.peer-standing-open {
    cursor: pointer;
}

.peer-standing-open:hover {
    border-color: color-mix(in srgb, var(--mix-ink-muted) 40%, transparent);
}

/* Click-away layer, mounted only while a popover is open; below the popover (1200), above the
   page. A bare div, not MudOverlay — that locks body scrolling and shifts the page (ProjectionSpread). */
.peer-clickaway {
    position: fixed;
    inset: 0;
    z-index: 1198;
}

.peer-pop-frame {
    border-radius: 8px;
}

.peer-pop {
    width: min(300px, calc(100vw - 24px));
    padding: 12px 14px;
    font-family: var(--font-body);
    font-weight: 400;
    font-size: .8rem;
    color: var(--mix-ink);
    text-shadow: none;
    cursor: default;
}

.peer-pop-head {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.4rem;
    line-height: 1;
}

.peer-pop-sub {
    color: var(--mix-ink-muted);
    margin-top: 3px;
}

/* How far the score is from its next grade, while a grade glow rule is on (peers-abstraction.md D42). */
.peer-pop-next {
    display: grid;
    grid-template-columns: 12px minmax(0, 1fr);
    column-gap: 6px;
    align-items: baseline;
    margin-top: 9px;
    padding: 6px 8px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--mix-primary) 7%, transparent);
}

.peer-pop-next-arrow {
    color: var(--mix-primary);
    font-size: .55rem;
}

.peer-pop-next-sub {
    grid-column: 2;
    color: var(--mix-ink-muted);
    font-size: .72rem;
}

.peer-pop-rows {
    margin: 10px 0 8px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent);
    padding-top: 6px;
    display: grid;
    gap: 2px;
}

.peer-pop-row {
    display: grid;
    grid-template-columns: 18px 1fr auto 12px;
    gap: 8px;
    align-items: baseline;
    padding: 3px 4px;
    margin: 0 -4px;
    border-radius: 4px;
    color: inherit;
    text-decoration: none;
}

div.peer-pop-row {
    grid-template-columns: 18px 1fr auto;
}

a.peer-pop-row:hover {
    background: color-mix(in srgb, var(--mix-ink) 6%, transparent);
    text-decoration: none;
}

.peer-pop-row-off {
    color: var(--mix-ink-muted);
    opacity: .75;
}

.peer-pop-num {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.peer-pop-arrow {
    color: var(--mix-primary);
}

.peer-pop-note {
    display: block;
    font-size: .7rem;
    color: var(--mix-ink-muted);
}

.peer-pop-empty {
    color: var(--mix-ink-muted);
}

.peer-pop-muted {
    display: block;
    font-size: .72rem;
    color: var(--mix-ink-muted);
}

.peer-pop-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent);
    padding-top: 8px;
    margin-top: 8px;
    color: var(--mix-ink-muted);
    font-size: .72rem;
}

.peer-pop-foot a {
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

/* The Account tab for peers & score colors (peers-abstraction.md D1, D14, D15, D35). */
.pcd-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 12px;
}

/* A radio's whole option is its label, so the text toggles it too, and every option is its own
   row: MudBlazor lays a radio group out as a wrapping row, which sat "Actual letter grade" beside
   "three steps" (owner field test). */
.pcd .mud-radio-group {
    display: flex;
    flex-direction: column;
    align-items: stretch;
}

.pcd-radio {
    display: block;
    width: 100%;
}

.pcd-radio .mud-radio {
    display: flex;
    align-items: flex-start;
    width: 100%;
    margin: 0;
}

.pcd-radio .mud-radio .mud-radio-content {
    flex: 1;
    min-width: 0;
}

.pcd-lede {
    opacity: .75;
    max-width: 64ch;
    margin-top: 2px;
}

.pcd {
    display: grid;
    gap: 20px;
}

.pcd-title {
    font-weight: 500;
}

.pcd-help {
    display: block;
    color: var(--mix-ink-muted);
    margin-bottom: 6px;
    max-width: 64ch;
}

.pcd-opt {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 6px;
    align-items: center;
    padding: 2px 4px;
    border-radius: 6px;
    cursor: pointer;
}

.pcd-opt:hover {
    background: color-mix(in srgb, var(--mix-ink) 4%, transparent);
}

.pcd-opt-off {
    opacity: .55;
    cursor: not-allowed;
}

.pcd-opt-head {
    cursor: default;
    padding-top: 8px;
}

.pcd-opt-head:hover {
    background: none;
}

.pcd-opt-body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.pcd-opt-label {
    font-weight: 500;
}

.pcd-opt-inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    align-self: flex-start;
}

.pcd-opt-help {
    font-size: .78rem;
    color: var(--mix-ink-muted);
}

.pcd-opt-count {
    font-size: .78rem;
    color: var(--mix-ink-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.pcd-sub {
    margin-left: 32px;
    border-left: 2px solid color-mix(in srgb, var(--mix-ink) 7%, transparent);
    padding-left: 6px;
}

.pcd-tag {
    font-size: .66rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--mix-ink-muted);
    border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent);
    padding: 1px 5px;
    border-radius: 3px;
    margin-left: 6px;
    font-weight: 500;
}

.pcd-tally {
    margin-top: 8px;
    padding: 8px 10px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--mix-primary) 8%, transparent);
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    font-size: .8rem;
}

.pcd-tally b {
    font-family: var(--font-display);
    font-size: 1.1rem;
    line-height: 1;
    font-weight: 700;
}

.pcd-muted {
    color: var(--mix-ink-muted);
}

.pcd-swatches {
    display: inline-flex;
    gap: 3px;
    margin-left: 8px;
    vertical-align: middle;
}

.pcd-swatch {
    width: 12px;
    height: 12px;
    border-radius: 2px;
    display: inline-block;
}

/* Both glow inputs the same width: MudBlazor's input control grows to fill its row otherwise. */
.pcd-num {
    width: 72px;
    flex: 0 0 72px;
}

/* The grade rules' labels run long enough to wrap around their field on a phone. */
.pcd-opt-wrap {
    flex-wrap: wrap;
    row-gap: 2px;
}

/* A grade rule's quick selects: small outlined chips in a row under its help line. */
.pcd-chips {
    margin-top: 4px;
}

.pcd .pcd-chips .mud-chip {
    margin: 0 5px 4px 0;
}

/* One glow / Brighter the closer, under whichever grade rule is selected. */
.pcd-strength {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    margin-top: 6px;
    padding-top: 8px;
    border-top: 1px dashed color-mix(in srgb, var(--mix-ink) 18%, transparent);
}

/* The difficulty glow switch, under the score glow rules and set apart from them by a rule. */
.pcd-difficulty-glow {
    display: flex;
    flex-direction: column;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent);
}

.pcd-preview {
    background: var(--mix-bg);
    border-radius: 6px;
    padding: 10px 12px;
    display: grid;
    gap: 6px;
}

.pcd-prow {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: 10px;
    align-items: center;
    font-size: .8rem;
}

.pcd-prow-song {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The preview's score: grade over plate in one column, the number beside them — the tier card's
   scoreline and the player page's tables, at the same 12px icons. */
.pcd-prow .sbd-score-stack {
    display: inline-grid;
    grid-auto-flow: row;
    grid-template-columns: auto auto;
    grid-template-rows: repeat(2, auto);
    align-items: center;
    column-gap: 5px;
    row-gap: 0;
    line-height: 1.05;
}

.pcd-prow .sbd-score-stack > img {
    grid-column: 1;
    height: 12px !important;
}

.pcd-prow .sbd-score-stack > p {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    margin: 0;
    padding-left: 0 !important;
    font-size: .92rem;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
}

/* The Account Stats roster's "why they are a peer" tags (peers-abstraction.md D18). */
.dash-acct-trail {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.dash-acct-src {
    display: inline-flex;
    gap: 3px;
}

.dash-acct-tag {
    font-size: .58rem;
    font-weight: 700;
    letter-spacing: .04em;
    padding: 1px 4px;
    border-radius: 3px;
    background: color-mix(in srgb, var(--mix-ink) 8%, transparent);
    color: var(--mix-ink-muted);
    white-space: nowrap;
}

.dash-acct-tag-rival { color: var(--daily-rival, var(--mix-secondary)); }
.dash-acct-tag-community { color: var(--daily-community); }
.dash-acct-tag-competitive { color: var(--mix-primary); }
.dash-acct-tag-pumbility { color: var(--mix-accent); }
/* ============================================================================
   March of Murlocs (docs/design/march-of-murlocs.md §11, the 2026-09-05 redraw). The section
   wears the site's vocabulary — .pmb-eyebrow / .pmb-frame-nav / .pmb-poolsplit from the
   PUMBILITY frame, .olb-rank-card rows, UserLabel — and adds only what those do not have: the
   season hero and rail, the standing card, the row's figures, the seasons dialog rows.
   Every colour is a token; the hairline is the ink at 12%.
   ============================================================================ */
.mom-hero { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(280px, .9fr); gap: 18px 28px; align-items: end; padding: 6px 0 16px; }
.mom-title { font-family: var(--font-display); font-weight: 700; font-size: 54px; line-height: .92; letter-spacing: -.01em; margin: 0; }
.mom-title small { display: block; font-size: 15px; font-weight: 500; letter-spacing: .02em; color: var(--mix-ink-muted); font-family: var(--font-body); margin-top: 8px; }
.mom-rail { margin-top: 14px; }
.mom-rail-bar { height: 6px; border-radius: 999px; background: color-mix(in srgb, var(--mix-ink) 12%, transparent); overflow: hidden; }
.mom-rail-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--mix-primary), var(--mix-accent)); box-shadow: 0 0 10px var(--mix-glow); }
.mom-rail-meta { display: flex; justify-content: space-between; gap: 10px; margin-top: 6px; font-size: 12px; color: var(--mix-ink-muted); font-variant-numeric: tabular-nums; }
.mom-rail-meta b { color: var(--mix-accent); font-family: var(--font-display); font-size: 15px; letter-spacing: .02em; }
.mom-standing { display: flex; flex-direction: column; align-items: flex-end; text-align: right; gap: 2px; }
.mom-standing .k { font-family: var(--font-display); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--mix-ink-muted); }
.mom-standing .place { font-family: var(--font-display); font-weight: 700; font-size: 22px; color: var(--rarity-gold); text-shadow: 0 0 10px; line-height: 1; }
.mom-standing .place .of { font-size: 14px; font-weight: 500; color: var(--mix-ink-muted); text-shadow: none; }
.mom-standing .total { font-family: var(--font-display); font-weight: 700; font-size: 50px; line-height: .96; letter-spacing: .02em; font-variant-numeric: tabular-nums; color: var(--rarity-prism); text-shadow: 0 0 14px var(--mix-glow); }
.mom-standing .sub { font-size: 12.5px; color: var(--mix-ink-muted); margin-top: 4px; }
.mom-standing .cta { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; justify-content: flex-end; }
.mom-standing.empty .lead { font-family: var(--font-display); font-size: 22px; font-weight: 600; line-height: 1.1; }
.mom-poolsplit { margin-top: 4px; }
.mom-poolsplit .pmb-poolsplit-seg { text-decoration: none !important; color: var(--mix-ink-muted); }
.mom-poolsplit .pmb-poolsplit-seg .sub { font-size: 11.5px; display: block; }
.mom-poolsplit .pmb-poolsplit-seg .lbl { display: block; font-family: var(--font-display); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; }
.mom-poolsplit .pmb-poolsplit-seg[aria-pressed="true"] .lbl { color: var(--mix-primary); }
.mom-poolsplit .pmb-poolsplit-seg strong.muted { color: var(--mix-ink-muted); }
.mom-frame-nav { margin-top: 12px; }
.mom-frame-spacer { flex: 1; }
.mom-notice { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px; border-radius: 8px; background: var(--mix-surface); border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); margin-top: 14px; flex-direction: column; }
.mom-notice h4 { margin: 0 0 3px; font-family: var(--font-display); font-size: 17px; font-weight: 600; }
.mom-notice p { margin: 0; color: var(--mix-ink-muted); font-size: 13px; }
.mom-board { margin-top: 10px; }
.mom-board-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 0 8px 6px; }
.mom-board-count { font-size: 12px; color: var(--mix-ink-muted); }
.mom-legend { margin-left: auto; display: flex; gap: 12px; align-items: center; font-size: 11.5px; color: var(--mix-ink-muted); }
.mom-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 4px; vertical-align: -1px; }
.mom-legend i.you { background: var(--daily-you); }
.mom-legend i.rival { background: var(--daily-rival); }
.mom-legend i.community { background: var(--daily-community); }
.mom-rows .olb-rank-card.mom-row { text-decoration: none !important; color: inherit; }
.mom-row:hover { background: color-mix(in srgb, var(--mix-ink) 4%, transparent); }
.mom-place { font-family: var(--font-display); font-weight: 700; font-size: 17px; min-width: 30px; text-align: right; color: var(--mix-ink-muted); font-variant-numeric: tabular-nums; }
.mom-place.p1 { color: var(--rarity-gold); text-shadow: 0 0 8px; }
.mom-place.p2 { color: var(--rarity-silver); }
.mom-place.p3 { color: var(--plate-fg); }
.mom-place small { font-size: 10px; font-weight: 600; margin-left: 1px; }
.mom-row-player { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; }
.mom-runchip { display: inline-flex; align-items: center; height: 18px; padding: 0 6px; border-radius: 999px; font-size: 10px; letter-spacing: .06em; text-transform: uppercase; border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); color: var(--mix-ink-muted); white-space: nowrap; }
.mom-row-tail { flex-wrap: nowrap; }
.mom-total { font-family: var(--font-display); font-weight: 700; font-size: 20px; font-variant-numeric: tabular-nums; min-width: 72px; text-align: right; order: 10; }
.mom-stat { display: inline-flex; flex-direction: column; align-items: flex-end; line-height: 1.05; min-width: 52px; }
.mom-stat b { font-family: var(--font-display); font-weight: 600; font-size: 15px; font-variant-numeric: tabular-nums; }
.mom-stat span { font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--mix-ink-muted); }
.mom-stat-line { display: none; gap: 6px; font-size: 11px; color: var(--mix-ink-muted); font-variant-numeric: tabular-nums; }
.mom-date { font-size: 11.5px; color: var(--mix-ink-muted); min-width: 44px; text-align: right; }
.mom-vid { display: inline-flex; width: 22px; height: 22px; align-items: center; justify-content: center; color: var(--mix-ink-muted); }
.mom-vid.none { opacity: .25; }
.mom-empty-board { padding: 34px 18px; text-align: center; border: 1px dashed color-mix(in srgb, var(--mix-ink) 12%, transparent); border-radius: 10px; margin-top: 8px; }
.mom-empty-board h3 { margin: 0 0 14px; font-family: var(--font-display); font-size: 26px; font-weight: 600; }
.mom-empty-board .cta { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.mom-rules { margin-top: 18px; padding: 12px 14px; border-radius: 8px; background: var(--mix-surface); border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); font-size: 13px; color: var(--mix-ink-muted); }
.mom-rules summary { cursor: pointer; color: var(--mix-ink); font-family: var(--font-display); font-size: 15px; font-weight: 600; }
.mom-rules p { margin: 8px 0 0; }
.mom-foot { display: flex; justify-content: space-between; gap: 12px; margin-top: 22px; padding-top: 12px; border-top: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); font-size: 13px; }
.mom-foot .muted { color: var(--mix-ink-muted); }
.mom-dock { display: none; }
/* The seasons dialog (§11.8, D35): one link per season, one flex line per board. */
.mom-seasons-wait { display: flex; justify-content: center; padding: 20px 0; }
.mom-season-row { display: block; padding: 10px 10px 8px; border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); color: inherit; text-decoration: none !important; }
.mom-season-row:hover { background: color-mix(in srgb, var(--mix-ink) 4%, transparent); }
.mom-season-row:last-child { border-bottom: 0; }
.mom-season-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mom-season-name b { font-family: var(--font-display); font-size: 19px; font-weight: 600; }
.mom-season-dates { font-size: 12px; color: var(--mix-ink-muted); }
.mom-chip { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px; border-radius: 999px; font-size: 11.5px; font-weight: 500; }
.mom-chip-live { background: color-mix(in srgb, var(--daily-community) 16%, transparent); color: var(--daily-community); }
.mom-chip-live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; box-shadow: 0 0 6px currentColor; }
.mom-board-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; margin-top: 6px; }
.mom-board-type { color: var(--mix-ink-muted); font-family: var(--font-display); letter-spacing: .08em; text-transform: uppercase; font-size: 10.5px; min-width: 52px; }
.mom-board-n { white-space: nowrap; font-variant-numeric: tabular-nums; }
.mom-board-winner { display: inline-flex; align-items: center; gap: 6px; min-width: 0; white-space: nowrap; max-width: 60%; }
.mom-board-pts { font-family: var(--font-display); font-weight: 600; font-variant-numeric: tabular-nums; }
.mom-board-me { margin-left: auto; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--mix-ink-muted); }
.mom-board-me.won { color: var(--rarity-gold); font-weight: 600; }
.mom-board-me.placed { color: var(--mix-ink); }
.mom-board-none { color: var(--mix-ink-muted); }
@media (max-width: 760px) { .mom-hide-mobile { display: none !important; } }
@media (max-width: 700px) {
    .mom-hero { grid-template-columns: 1fr; gap: 12px; padding-bottom: 8px; }
    .mom-title { font-size: 40px; }
    .mom-standing { align-items: flex-start; text-align: left; padding: 12px 14px; border-radius: 10px; background: var(--mix-surface); border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); }
    .mom-standing .cta { justify-content: flex-start; }
    .mom-standing .total { font-size: 42px; }
    .mom-poolsplit { display: grid; grid-template-columns: 1fr 1fr; width: 100%; }
    .mom-poolsplit .pmb-poolsplit-seg { min-width: 0; padding: 8px 10px; }
    .mom-poolsplit .pmb-poolsplit-seg strong { font-size: 19px; }
    .mom-legend { margin-left: 0; width: 100%; }
    .mom-foot { flex-direction: column; gap: 6px; }
    .mom-desk-only { display: none !important; }
    .mom-dock { display: flex; gap: 8px; align-items: center; position: sticky; bottom: calc(var(--bottom-nav-h) + 8px); z-index: 19; padding: 8px 12px; margin-top: 12px; background: color-mix(in srgb, var(--mix-nav) 92%, transparent); backdrop-filter: blur(8px); border-radius: 10px; }
    .mom-dock .mud-button-root { flex: 1; }
}
@media (max-width: 500px) {
    .mom-row.olb-rank-card { gap: 5px; padding: 3px 4px; }
    .mom-row .olb-rank-rankbox { min-width: 42px; }
    .mom-row-tail { flex-direction: column; align-items: flex-end; gap: 0; }
    .mom-hide-phone { display: none !important; }
    .mom-stat-line { display: flex; }
    .mom-total { font-size: 18px; min-width: 0; order: -1; }
    .mom-board-me { flex-basis: 100%; margin-left: 0; padding-left: 60px; }
}

/* ---- March of Murlocs: the Session Breakdown (§11.3, D26) ---- */
.mom-crumbs a { color: var(--mix-ink-muted); text-decoration: none; }
.mom-crumbs a:hover { color: var(--mix-primary); }
.mom-session-hero .sbd-hero-head { gap: 14px 18px; }
.mom-hero-place { font-family: var(--font-display); font-weight: 700; font-size: 44px; line-height: .9; color: var(--rarity-gold); text-shadow: 0 0 12px; min-width: 60px; }
.mom-hero-place small { font-size: 16px; }
.mom-hero-total { font-family: var(--font-display); font-weight: 700; font-size: 3.4rem; line-height: .86; letter-spacing: -.015em; font-variant-numeric: tabular-nums; color: var(--rarity-prism); text-shadow: 0 0 14px var(--mix-glow); display: block; }
.mom-chip-draft { background: color-mix(in srgb, var(--mix-accent) 16%, transparent); color: var(--mix-accent); }
.mom-hero-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 10px 18px 12px; border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); }
.mom-formula { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 12.5px; color: var(--mix-ink-muted); font-variant-numeric: tabular-nums; }
.mom-formula b { font-family: var(--font-display); font-size: 16px; color: var(--mix-ink); }
.mom-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.mom-sort { min-width: 170px; }
.mom-four { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-top: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); }
.mom-four > div { padding: 14px 16px 12px; border-right: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); min-width: 0; }
.mom-four > div:last-child { border-right: 0; }
.mom-four .k { font-family: var(--font-display); font-size: .68rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--mix-ink-muted); }
.mom-four .v { font-family: var(--font-display); font-weight: 700; font-size: 30px; line-height: 1; font-variant-numeric: tabular-nums; margin: 4px 0 2px; display: flex; align-items: center; gap: 8px; }
.mom-four .v img { height: 26px !important; width: auto; }
.mom-four .v-score { font-size: 22px; }
.mom-four .sub { font-size: 11.5px; color: var(--mix-ink-muted); }
.mom-four .rank { display: block; font-size: 12px; color: var(--mix-accent); font-weight: 500; margin-top: 4px; }
.mom-four .rank.top { color: var(--rarity-gold); }
.mom-four .rank.muted { color: var(--mix-ink-muted); }
.mom-four .dots { display: flex; gap: 3px; margin-top: 8px; align-items: flex-end; height: 14px; }
.mom-four .dots i { width: 6px; border-radius: 2px; background: color-mix(in srgb, var(--mix-ink) 22%, transparent); height: 6px; }
.mom-four .dots i.you { background: var(--mix-primary); box-shadow: 0 0 6px var(--mix-primary); height: 14px; }
.mom-four .dots i.them { background: var(--mix-accent); height: 10px; }
.mom-pace { width: 100%; height: auto; display: block; }
.mom-pace .grid { stroke: color-mix(in srgb, var(--mix-ink) 6%, transparent); stroke-width: 1; }
.mom-pace .line { fill: none; stroke: var(--mix-primary); stroke-width: 2; stroke-linejoin: round; }
.mom-pace .avg { fill: none; stroke: var(--mix-accent); stroke-width: 1.2; stroke-dasharray: 4 4; }
.mom-pace .lbl { fill: var(--mix-ink-muted); font: 10px var(--font-body); }
.mom-pace .dot { fill: var(--mix-primary); }
.mom-pace .rest { fill: color-mix(in srgb, var(--mix-ink) 8%, transparent); }
.mom-card-score { font-family: var(--font-display); font-weight: 700; }
.mom-cards .hl-card-score .sbd-score-stack > p { font-size: 1.1rem; }
.mom-stickers { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }
.mom-sticker { position: relative; border-radius: 6px; overflow: hidden; background: var(--mix-surface); border: 2px solid var(--mud-palette-lines-default); cursor: pointer; }
.mom-sticker:focus-visible { outline: 2px solid var(--mix-primary); outline-offset: 1px; }
.mom-sticker-jacket { height: 72px; background-size: cover; background-position: center; position: relative; }
.mom-sticker-bubble { position: absolute; top: 3px; left: 3px; }
.mom-sticker-sub { position: absolute; bottom: 24px; right: 3px; font: 600 10.5px var(--font-display); color: var(--mix-ink); background: color-mix(in srgb, var(--mix-bg) 70%, transparent); padding: 0 4px; border-radius: 3px; font-variant-numeric: tabular-nums; }
.mom-sticker-pts { position: absolute; bottom: 3px; right: 3px; border-radius: 4px; }
.mom-table th { cursor: pointer; white-space: nowrap; }
.mom-table th.sorted { color: var(--mix-primary); }
.mom-table th.r, .mom-table td.r { text-align: right; font-variant-numeric: tabular-nums; }
.mom-table td { vertical-align: middle; }
.mom-table-row { cursor: pointer; }
.mom-table-row:hover td { background: color-mix(in srgb, var(--mix-ink) 5%, transparent); }
.mom-table-chart { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.mom-table-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 26ch; font-weight: 500; }
.mom-table-pts { font-family: var(--font-display); font-size: 15px; font-variant-numeric: tabular-nums; }
.mom-table .num { font-variant-numeric: tabular-nums; }
.mom-table .muted { color: var(--mix-ink-muted); }
.mom-cmp-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.mom-cmp-select { min-width: 200px; }
.mom-cmp-empty { color: var(--mix-ink-muted); font-size: 13px; margin: 6px 0 0; }
.mom-cmp-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.mom-cmp-cell { padding: 10px 12px; border-radius: 8px; background: var(--mix-surface-muted); border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); min-width: 0; }
.mom-cmp-cell .k { font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--mix-ink-muted); }
.mom-cmp-cell .pair { display: flex; align-items: baseline; gap: 6px; margin-top: 3px; font-family: var(--font-display); font-weight: 700; font-size: 22px; font-variant-numeric: tabular-nums; flex-wrap: wrap; }
.mom-cmp-cell .pair img { height: 20px !important; width: auto; }
.mom-cmp-cell .them { font-size: 15px; font-weight: 600; color: var(--mix-ink-muted); }
.mom-cmp-cell .them img { height: 16px !important; }
.mom-cmp-cell .d { display: block; font-size: 12px; margin-top: 2px; font-weight: 500; }
.d.up { color: var(--mud-palette-success); }
.d.down { color: var(--judg-miss); }
.d.flat { color: var(--mix-ink-muted); }
.mom-verdict { margin: 10px 0 0; font-size: 13.5px; color: var(--mix-ink-muted); }
.mom-cmp-sub { margin-top: 14px; }
.mom-gap-row .mom-gap-song { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.mom-gap-vs { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--mix-ink-muted); }
.mom-gap-pts { font-family: var(--font-display); font-weight: 700; color: var(--mix-ink); font-variant-numeric: tabular-nums; }
.mom-gap { font-family: var(--font-display); font-weight: 700; font-size: 16px; font-variant-numeric: tabular-nums; min-width: 64px; text-align: right; }
.mom-ledger { margin-top: 10px; border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); border-radius: 8px; overflow: hidden; }
.mom-ledger > div { display: grid; grid-template-columns: minmax(0, 1fr) 90px 90px; gap: 10px; padding: 7px 12px; border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); font-size: 13px; align-items: baseline; }
.mom-ledger > div:last-child { border-bottom: 0; }
.mom-ledger .r { text-align: right; font-variant-numeric: tabular-nums; font-family: var(--font-display); font-weight: 600; font-size: 15px; }
.mom-ledger .sub { color: var(--mix-ink-muted); padding-left: 18px; }
.mom-ledger .muted { color: var(--mix-ink-muted); }
.mom-ledger .hi { background: color-mix(in srgb, var(--mix-primary) 8%, transparent); }
.mom-ledger .hi .r { font-size: 18px; }
.mom-ledger-note { color: var(--mix-ink-muted); font-size: 12px; margin: 8px 0 0; }
@media (max-width: 899.98px) { .mom-table .w900 { display: none; } }
@media (max-width: 700px) {
    .mom-hero-total { font-size: 2.6rem; }
    .mom-cmp-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .mom-tools { margin-left: 0; width: 100%; }
    .mom-ledger > div { grid-template-columns: minmax(0, 1fr) 76px 76px; font-size: 12.5px; padding: 6px 10px; }
    .mom-four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .mom-four > div:nth-child(2) { border-right: 0; }
    .mom-four > div:nth-child(-n+2) { border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); }
    .mom-four .v { font-size: 26px; }
    .mom-table .w700 { display: none; }
}

/* ============================================================================
   March of Murlocs — the Rules page (docs/design/march-of-murlocs.md §11.11, D42). Static
   HTML built like the front door: a hero, six numbered sections, inline SVG that reads the mix
   tokens through the .mom-rl-svg classes, and a horizontal grade table that scrolls inside its
   own box. Every colour is a token; the letters and plates are the site's images.
   ============================================================================ */
.mom-rl-hero { padding: 10px 0 18px; border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); margin-bottom: 8px; }
.mom-rl-title { font-family: var(--font-display); font-weight: 700; font-size: 56px; line-height: .92; letter-spacing: -.01em; margin: 0; text-transform: uppercase; text-wrap: balance; }
.mom-rl-title small { display: block; font-family: var(--font-body); font-weight: 400; font-size: 17px; line-height: 1.4; letter-spacing: 0; text-transform: none; color: var(--mix-ink-muted); margin-top: 14px; max-width: 62ch; }
.mom-rl-toc { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 16px; }
.mom-rl-toc a { display: inline-flex; align-items: center; height: 26px; padding: 0 11px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); color: var(--mix-ink-muted); font-family: var(--font-display); font-size: 12.5px; letter-spacing: .08em; text-transform: uppercase; text-decoration: none; }
.mom-rl-toc a:hover { color: var(--mix-primary); border-color: color-mix(in srgb, var(--mix-primary) 50%, transparent); }
.mom-rl-sec { padding: 26px 0 8px; }
.mom-rl-sec + .mom-rl-sec { border-top: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); }
.mom-rl-sec h2 { font-family: var(--font-display); font-weight: 700; font-size: 30px; letter-spacing: .03em; text-transform: uppercase; margin: 0 0 4px; }
.mom-rl-sec h2 .k { color: var(--mix-primary); margin-right: 10px; font-size: 20px; vertical-align: 6px; letter-spacing: .1em; }
.mom-rl-sec .lede { color: var(--mix-ink-muted); margin: 0 0 16px; font-size: 15px; max-width: 70ch; }
.mom-rl-split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px 28px; align-items: start; }
.mom-rl-rules { margin: 16px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 10px; }
.mom-rl-split .mom-rl-rules { margin-top: 0; }
.mom-rl-rules li { display: grid; grid-template-columns: 22px 1fr; gap: 10px; font-size: 14.5px; line-height: 1.45; }
.mom-rl-rules li::before { content: ""; width: 8px; height: 8px; margin: 7px 0 0 6px; border-radius: 50%; background: var(--mix-primary); box-shadow: 0 0 8px var(--mix-glow); }
.mom-rl-rules b { color: var(--mix-ink); font-weight: 500; }
.mom-rl-fig { background: var(--mix-surface); border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); border-radius: 12px; padding: 14px 16px 12px; }
.mom-rl-fig svg { display: block; width: 100%; height: auto; }
.mom-rl-fig .fig-title { font-family: var(--font-display); font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--mix-ink-muted); margin-bottom: 8px; display: flex; justify-content: space-between; gap: 10px; }
.mom-rl-fig .fig-title b { color: var(--mix-ink); }
.mom-rl-svg .track { fill: color-mix(in srgb, var(--mix-ink) 5%, transparent); }
.mom-rl-svg .primary { fill: var(--mix-primary); opacity: .85; }
.mom-rl-svg .accent { fill: var(--mix-accent); }
.mom-rl-svg .zero { fill: color-mix(in srgb, var(--judg-miss) 10%, transparent); }
.mom-rl-svg .grid { stroke: color-mix(in srgb, var(--mix-ink) 8%, transparent); }
.mom-rl-svg .tick { stroke: var(--mix-ink-muted); stroke-width: 1; }
.mom-rl-svg .buzzer { stroke: var(--mix-ink); stroke-width: 2; stroke-dasharray: 3 3; }
.mom-rl-svg .start { stroke: var(--mix-primary); stroke-width: 2; }
.mom-rl-svg .line { fill: none; stroke: var(--mix-primary); stroke-width: 3; }
.mom-rl-svg .lbl { font-family: var(--font-body); font-size: 11px; fill: var(--mix-ink); }
.mom-rl-svg .lbl.display { font-family: var(--font-display); font-weight: 700; font-size: 12px; letter-spacing: .08em; }
.mom-rl-svg .lbl.small { font-size: 9.5px; }
.mom-rl-svg .muted { fill: var(--mix-ink-muted); }
.mom-rl-svg .ink { fill: var(--mix-ink); }
.mom-rl-svg .primary-ink { fill: var(--mix-primary); }
.mom-rl-svg .accent-ink { fill: var(--mix-accent); }
.mom-rl-svg .miss { fill: var(--judg-miss); font-size: 10px; }
.mom-rl-svg .pg { fill: var(--plate-pg); }
.mom-rl-quarters { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.mom-rl-q { border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); border-radius: 10px; padding: 12px 12px 10px; background: var(--mix-surface); position: relative; }
.mom-rl-q .nm { font-family: var(--font-display); font-weight: 700; font-size: 22px; letter-spacing: .02em; }
.mom-rl-q .mo { font-size: 12.5px; color: var(--mix-ink-muted); }
.mom-rl-q.live { border-color: color-mix(in srgb, var(--mix-primary) 60%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--mix-primary) 35%, transparent), 0 0 18px -8px var(--mix-glow); }
.mom-rl-live { position: absolute; top: 10px; right: 10px; display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px; border-radius: 999px; font-size: 11.5px; font-weight: 500; background: color-mix(in srgb, var(--daily-community) 16%, transparent); color: var(--daily-community); }
.mom-rl-live::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; box-shadow: 0 0 6px currentColor; }
.mom-rl-formula { display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap; padding: 18px 16px; border-radius: 12px; background: var(--mix-surface); border: 1px solid color-mix(in srgb, var(--mix-primary) 30%, transparent); margin: 6px 0 18px; }
.mom-rl-formula .t { font-family: var(--font-display); font-weight: 700; font-size: 26px; letter-spacing: .02em; text-transform: uppercase; }
.mom-rl-formula .t.res { color: var(--mix-accent); }
.mom-rl-formula .op { font-family: var(--font-display); font-size: 26px; color: var(--mix-ink-muted); }
.mom-rl-formula .sub { flex-basis: 100%; text-align: center; font-size: 12.5px; color: var(--mix-ink-muted); margin-top: -4px; }
.mom-rl-panels { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px 28px; }
.mom-rl-panel, .mom-rl-split > * { min-width: 0; }
.mom-rl-panel h3 { font-family: var(--font-display); font-weight: 600; font-size: 20px; letter-spacing: .05em; text-transform: uppercase; margin: 0 0 8px; display: flex; align-items: center; gap: 10px; }
.mom-rl-panel h3 .n { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 50%; background: var(--mix-primary); color: var(--mix-primary-contrast); font-size: 14px; }
.mom-rl-panel p { font-size: 14px; color: var(--mix-ink-muted); margin: 8px 0 0; }
.mom-rl-panel p b { color: var(--mix-ink); font-weight: 500; }
.mom-rl-panel.span { grid-column: 1 / -1; }
.mom-rl-scroll { overflow-x: auto; max-width: 100%; margin-top: 12px; border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); border-radius: 10px; background: var(--mix-surface); }
.mom-rl-grades { border-collapse: collapse; font-size: 13.5px; min-width: 100%; }
.mom-rl-grades th, .mom-rl-grades td { padding: 8px 10px; text-align: center; border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); font-variant-numeric: tabular-nums; white-space: nowrap; }
.mom-rl-grades th:first-child, .mom-rl-grades td:first-child { text-align: left; position: sticky; left: 0; background: var(--mix-surface); font-family: var(--font-display); font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--mix-ink-muted); font-weight: 600; box-shadow: 1px 0 0 color-mix(in srgb, var(--mix-ink) 12%, transparent); }
.mom-rl-grades thead th { border-bottom: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); vertical-align: bottom; }
.mom-rl-grades thead img, .mom-rl-grades thead .mud-image { height: 20px; width: auto; display: block; margin: 0 auto; }
.mom-rl-grades tr.plus td { color: var(--mix-ink); font-weight: 500; background: color-mix(in srgb, var(--mix-primary) 8%, transparent); }
.mom-rl-grades tr.plus td:first-child { color: var(--mix-primary); }
.mom-rl-grades tr.plus td.diff { color: var(--mix-accent); }
.mom-rl-grades tr.score td { color: var(--mix-ink-muted); font-size: 12px; }
.mom-rl-ex { margin-top: 14px; padding: 12px 14px; border-radius: 10px; border: 1px dashed color-mix(in srgb, var(--mix-accent) 50%, transparent); background: color-mix(in srgb, var(--mix-accent) 6%, var(--mix-surface)); font-size: 14px; }
.mom-rl-ex .k { font-family: var(--font-display); font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase; color: var(--mix-accent); margin-bottom: 4px; }
.mom-rl-ex .eq { font-variant-numeric: tabular-nums; }
.mom-rl-lens { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.mom-rl-len { flex: 1 1 120px; border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); border-radius: 10px; padding: 10px 12px; background: var(--mix-surface); }
.mom-rl-len .d { font-family: var(--font-display); font-weight: 700; font-size: 22px; }
.mom-rl-len .m { color: var(--mix-accent); font-family: var(--font-display); font-weight: 600; font-size: 15px; }
.mom-rl-len .bar { height: 6px; border-radius: 999px; background: color-mix(in srgb, var(--mix-ink) 12%, transparent); margin-top: 8px; overflow: hidden; }
.mom-rl-len .bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--mix-primary), var(--mix-accent)); }
.mom-rl-faq { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 14px 28px; }
.mom-rl-qa { border-top: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); padding-top: 10px; }
.mom-rl-qa h3 { margin: 0 0 4px; font-family: var(--font-display); font-size: 18px; font-weight: 600; letter-spacing: .02em; }
.mom-rl-qa p { margin: 0; font-size: 14px; color: var(--mix-ink-muted); }
.mom-rl-foot { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 26px; padding-top: 12px; border-top: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); font-size: 13px; color: var(--mix-ink-muted); }
@media (max-width: 700px) {
    .mom-rl-title { font-size: 40px; }
    .mom-rl-split, .mom-rl-panels, .mom-rl-faq { grid-template-columns: 1fr; }
    .mom-rl-quarters { grid-template-columns: 1fr 1fr; }
    .mom-rl-formula .t, .mom-rl-formula .op { font-size: 20px; }
    .mom-rl-grades { font-size: 12.5px; }
    .mom-rl-grades th, .mom-rl-grades td { padding: 6px 8px; }
}

/* ============================================================================
   March of Murlocs — the newcomer card on the Season page (docs/design/march-of-murlocs.md
   D44): the rules in one card until the viewer has published a session; the frame's
   How-it-works chip carries the link for everyone else.
   ============================================================================ */
.mom-howto { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(220px, .8fr); gap: 12px 24px; align-items: center; margin: 14px 0 4px; padding: 16px 18px; border-radius: 12px; background: var(--mix-surface); border: 1px solid color-mix(in srgb, var(--mix-primary) 35%, transparent); box-shadow: 0 0 24px -14px var(--mix-glow); }
.mom-howto .k { font-family: var(--font-display); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--mix-accent); }
.mom-howto h2 { margin: 2px 0 6px; font-family: var(--font-display); font-weight: 700; font-size: 26px; letter-spacing: .02em; line-height: 1; }
.mom-howto p { margin: 0 0 10px; font-size: 14px; color: var(--mix-ink-muted); max-width: 56ch; }
.mom-howto .facts { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.mom-howto .facts span { display: inline-flex; align-items: center; height: 22px; padding: 0 9px; border-radius: 999px; font-size: 11.5px; border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); color: var(--mix-ink-muted); }
.mom-howto .cta { display: flex; gap: 8px; flex-wrap: wrap; }
.mom-howto-art svg { display: block; width: 100%; height: auto; }
.mom-howto-art .track { fill: color-mix(in srgb, var(--mix-ink) 6%, transparent); }
.mom-howto-art .primary { fill: var(--mix-primary); opacity: .85; }
.mom-howto-art .accent { fill: var(--mix-accent); }
.mom-howto-art .buzzer { stroke: var(--mix-ink); stroke-width: 2; stroke-dasharray: 3 3; }
.mom-howto-art .lbl { font-family: var(--font-display); font-size: 11px; fill: var(--mix-ink); letter-spacing: .08em; }
@media (max-width: 700px) {
    .mom-howto { grid-template-columns: 1fr; padding: 14px; }
    .mom-howto-art { order: -1; }
    .mom-howto h2 { font-size: 22px; }
}

/* ===== March of Murlocs — Submit (docs/design/march-of-murlocs.md §11.4) ==================
   Recording a session: the budget bar that fills with song time, the three-key entry row, the
   session list, and the import dialog's blocks and checks. Tokens only — the page wears the mix
   theme like every other MoM surface. */
.sub-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.sub-title { font-family: var(--mud-typography-h4-family, inherit); font-weight: 700; font-size: 34px; line-height: 1; margin: 0; }
.sub-lede { color: var(--mix-ink-muted); font-size: 13px; margin: 6px 0 0; max-width: 60ch; }

/* The budget: song time fills it, and the lighter tail is the closing chart, which may overhang
   the window because a chart only has to START inside it (§1). */
.mom-budget { position: sticky; top: 48px; z-index: 15; margin: 14px 0 0; padding: 10px 14px 12px; border-radius: 10px; background: color-mix(in srgb, var(--mix-surface) 92%, transparent); backdrop-filter: blur(8px); border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); }
.mom-budget-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.mom-budget-top .played { font-weight: 700; font-size: 26px; line-height: 1; font-variant-numeric: tabular-nums; }
.mom-budget-top .of { color: var(--mix-ink-muted); font-size: 13px; }
.mom-budget-top .left { margin-left: auto; font-weight: 600; font-size: 16px; color: var(--mix-accent); font-variant-numeric: tabular-nums; }
.mom-budget-bar { height: 10px; border-radius: 999px; background: color-mix(in srgb, var(--mix-ink) 12%, transparent); margin-top: 8px; overflow: hidden; display: flex; }
.mom-budget-bar i { display: block; height: 100%; background: var(--mix-primary); }
.mom-budget-bar i.last { background: color-mix(in srgb, var(--mix-primary) 55%, transparent); }
.mom-budget-note { font-size: 12px; color: var(--mix-ink-muted); margin: 6px 0 0; }
.mom-budget.blocked { border-color: color-mix(in srgb, var(--judg-miss) 55%, transparent); }
.mom-budget.blocked .left { color: var(--judg-miss); }

.mom-entry { margin-top: 14px; padding: 14px; border-radius: 10px; background: var(--mix-surface); border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); }
.mom-entry-row { display: grid; grid-template-columns: minmax(0, 2.2fr) minmax(110px, .9fr) minmax(150px, 1fr) auto; gap: 10px; align-items: flex-end; }
.mom-entry-row > .mud-button-root { height: 40px; }
.mom-entry-hint { margin: 10px 0 0; font-size: 12.5px; color: var(--mix-ink-muted); }
.mom-entry-import { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; padding-top: 12px; border-top: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); font-size: 12.5px; color: var(--mix-ink-muted); }
.kbd { display: inline-block; padding: 0 5px; border-radius: 4px; border: 1px solid color-mix(in srgb, var(--mix-ink) 30%, transparent); font-size: 11px; line-height: 16px; color: var(--mix-ink); background: color-mix(in srgb, var(--mix-ink) 6%, transparent); }

/* The checks, shared by the entry row's repeat line and the import dialog's three. */
.mom-checks { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.mom-check { display: flex; gap: 8px; align-items: flex-start; font-size: 12.5px; }
.mom-check i { flex: none; width: 16px; height: 16px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 700; font-style: normal; margin-top: 1px; }
.mom-check.ok i { background: color-mix(in srgb, var(--daily-community) 25%, transparent); color: var(--daily-community); }
.mom-check.warn i { background: color-mix(in srgb, var(--mix-accent) 25%, transparent); color: var(--mix-accent); }
.mom-check.block i { background: color-mix(in srgb, var(--judg-miss) 25%, transparent); color: var(--judg-miss); }
.mom-check.note i { background: color-mix(in srgb, var(--mix-ink) 12%, transparent); color: var(--mix-ink-muted); }

.mom-sess { margin-top: 18px; }
.mom-sess-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.mom-sess-total { margin-left: auto; font-weight: 700; font-size: 22px; font-variant-numeric: tabular-nums; }
.mom-sess-total small { font-size: 12px; font-weight: 500; color: var(--mix-ink-muted); margin-left: 6px; }
.mom-sess-row { padding: 7px 4px; }
.mom-sess-row .song { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.mom-ordn { min-width: 22px; text-align: right; color: var(--mix-ink-muted); font-variant-numeric: tabular-nums; font-size: 12px; }
.mom-sess-empty { padding: 26px 16px; text-align: center; border: 1px dashed color-mix(in srgb, var(--mix-ink) 12%, transparent); border-radius: 10px; color: var(--mix-ink-muted); }
.mom-video { margin-top: 14px; }

.mom-footer-bar { display: flex; gap: 8px; align-items: center; margin-top: 18px; padding-top: 12px; border-top: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); }
.mom-footer-bar .spacer { flex: 1; }

.mom-published { margin-top: 14px; padding: 14px 16px; border-radius: 10px; background: color-mix(in srgb, var(--daily-community) 7%, var(--mix-surface)); border: 1px solid color-mix(in srgb, var(--daily-community) 45%, transparent); }
.mom-published h4 { margin: 0 0 3px; font-size: 17px; font-weight: 600; }
.mom-published p { margin: 0; color: var(--mix-ink-muted); font-size: 13px; }
.mom-published .cta { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }

.mom-chip-draft, .mom-chip-outline, .mom-chip-accent, .mom-chip-primary { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 8px; border-radius: 999px; font-size: 11.5px; font-weight: 500; white-space: nowrap; }
.mom-chip-draft, .mom-chip-outline { background: transparent; border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); color: var(--mix-ink-muted); }
.mom-chip-accent { background: color-mix(in srgb, var(--mix-accent) 16%, transparent); color: var(--mix-accent); }
.mom-chip-primary { background: color-mix(in srgb, var(--mix-primary) 18%, transparent); color: var(--mix-primary); }

/* The import dialog: every play stays on screen, dimmed where it cannot count, with the gap
   between blocks printed so the choice is legible rather than magic. */
.mom-imp-lede { color: var(--mix-ink-muted); font-size: 13px; margin: 0 0 10px; }
.mom-imp-lead { margin-right: auto; font-size: 12px; color: var(--mix-ink-muted); }
.mom-blk { border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); border-radius: 8px; overflow: hidden; margin-top: 8px; }
.mom-blk-head { display: flex; align-items: center; gap: 10px; padding: 6px 10px; background: var(--mix-surface-muted); font-size: 12px; color: var(--mix-ink-muted); }
.mom-blk-head b { color: var(--mix-ink); font-size: 14px; }
.mom-blk-head > :last-child { margin-left: auto; }
.mom-play { display: flex; align-items: center; gap: 8px; padding: 5px 10px; border-top: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); font-size: 13px; cursor: pointer; }
.mom-play:hover { background: color-mix(in srgb, var(--mix-ink) 4%, transparent); }
.mom-play .t { min-width: 44px; color: var(--mix-ink-muted); font-variant-numeric: tabular-nums; font-size: 12px; }
.mom-play .nm { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mom-play.sel { background: color-mix(in srgb, var(--mix-primary) 12%, transparent); box-shadow: inset 3px 0 0 var(--mix-primary); }
.mom-play.dim { opacity: .45; }
.mom-play .why { font-size: 11px; color: var(--mix-ink-muted); white-space: nowrap; }
.mom-gapline { display: flex; align-items: center; gap: 10px; margin: 6px 0; font-size: 11.5px; color: var(--mix-ink-muted); }
.mom-gapline::before, .mom-gapline::after { content: ""; flex: 1; border-top: 1px dashed color-mix(in srgb, var(--mix-ink) 12%, transparent); }

@media (max-width: 700px) {
    .sub-title { font-size: 28px; }
    .mom-budget { margin-left: -4px; margin-right: -4px; }
    .mom-entry-row { grid-template-columns: 1fr 1fr; }
    .mom-entry-row > .f-chart { grid-column: 1 / -1; }
    .mom-entry-row > .mud-button-root { grid-column: 1 / -1; justify-content: center; }
    .mom-play .why { display: none; }
}

/* ===== March of Murlocs — the My Sessions on-ramp (D32) ===================================
   Three states under one session's title: a night already on a board wears the gold chip, a
   night holding a session-shaped window gets the callout, everything else the quiet link. */
.mom-quiet { display: inline-flex; align-items: center; gap: 5px; margin-top: 6px; font-size: 12.5px; color: var(--mix-primary); text-decoration: none; }
.mom-quiet:hover { text-decoration: underline; }
.mom-recorded { display: inline-flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 8px; padding: 5px 10px; border-radius: 8px; border: 1px solid color-mix(in srgb, var(--rarity-gold) 55%, transparent); background: color-mix(in srgb, var(--rarity-gold) 10%, transparent); color: var(--rarity-gold); font-size: 12.5px; text-decoration: none; }
.mom-recorded .l2 { color: var(--mix-ink); font-variant-numeric: tabular-nums; }
.mom-recorded:hover { text-decoration: none; filter: brightness(1.1); }
.mom-callout { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; margin: 0 18px 14px; padding: 12px 14px; border-radius: 10px; border: 1px solid color-mix(in srgb, var(--mix-accent) 50%, transparent); background: color-mix(in srgb, var(--mix-accent) 7%, transparent); }
.mom-callout .ico { color: var(--mix-accent); display: flex; }
.mom-callout h3 { margin: 0 0 8px; font-size: 17px; font-weight: 600; }
.mom-callout .facts { display: flex; gap: 18px; flex-wrap: wrap; }
.mom-callout .fact { display: flex; flex-direction: column; line-height: 1.15; }
.mom-callout .fact b { font-size: 15px; font-variant-numeric: tabular-nums; }
.mom-callout .fact span { font-size: 11px; color: var(--mix-ink-muted); }
.mom-callout .act { margin-left: auto; align-self: center; }
@media (max-width: 700px) {
    .mom-callout { margin-left: 12px; margin-right: 12px; }
    .mom-callout .act { margin-left: 0; width: 100%; }
    .mom-callout .act .mud-button-root { width: 100%; justify-content: center; }
    .mom-recorded { width: 100%; }
}

/* ===== March of Murlocs — Planner (docs/design/march-of-murlocs.md §11.5) =================
   The Season's future tense: the controls, the projection, the two shelves and the record book
   in three densities. Selection reads as an outline, never as dimming — an unpicked chart is not
   lesser information, and fading four-fifths of a browsing surface to mark the fifth is the wrong
   way round. */
.pl-title { font-weight: 700; font-size: 34px; line-height: 1; margin: 0; }
.pl-lede { color: var(--mix-ink-muted); font-size: 13px; margin: 6px 0 0; }
.pl-controls { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 18px; margin-top: 14px; padding: 14px; border-radius: 10px; background: var(--mix-surface); border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); }
.pl-controls .k { display: block; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--mix-ink-muted); margin-bottom: 4px; }
.pl-controls .ctl-row { display: flex; gap: 18px; flex-wrap: wrap; }
.pl-slider { margin-top: 14px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pl-slider .mud-slider { flex: 1; min-width: 160px; }
.pl-slider .readout { font-variant-numeric: tabular-nums; font-weight: 600; min-width: 44px; }
.pl-note, .pl-push-note { font-size: 12px; color: var(--mix-ink-muted); margin: 6px 0 0; }
.pl-anchor { margin: 0 0 8px; font-size: 12.5px; color: var(--mix-ink-muted); }
.pl-anchor b { color: var(--mix-ink); font-size: 15px; margin-right: 6px; font-variant-numeric: tabular-nums; }
.pl-push { padding-left: 18px; border-left: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent); }

.pl-proj { margin-top: 14px; padding: 16px 18px 14px; border-radius: 10px; background: var(--mix-surface); border: 1px solid color-mix(in srgb, var(--mix-ink) 12%, transparent); border-top: 2px solid var(--mix-accent); }
.pl-proj-top { display: flex; align-items: flex-start; gap: 18px; flex-wrap: wrap; }
.pl-proj-k { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--mix-ink-muted); }
.pl-proj-big { font-weight: 700; font-size: 46px; line-height: .96; font-variant-numeric: tabular-nums; color: var(--rarity-prism); text-shadow: 0 0 14px var(--mix-glow); }
.pl-proj-big.zero { color: var(--mix-ink-muted); text-shadow: none; }
.pl-conversion { margin-left: auto; text-align: right; }
.pl-conversion b { display: block; font-weight: 700; font-size: 28px; line-height: 1; font-variant-numeric: tabular-nums; }
.pl-conversion span { font-size: 11.5px; color: var(--mix-ink-muted); }
.pl-say { margin: 6px 0 0; font-size: 12.5px; color: var(--mix-ink-muted); }
.pl-proj .four { margin-top: 12px; border-top: 1px solid color-mix(in srgb, var(--mix-ink) 7%, transparent); }
.pl-proj .four .k { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--mix-ink-muted); }
.pl-mixnote { margin: 10px 0 0; font-size: 12px; color: var(--mix-ink-muted); max-width: 70ch; }

.pl-shelf { margin-top: 18px; }
.pl-shelf-note { margin: 2px 0 8px; font-size: 12px; color: var(--mix-ink-muted); max-width: 80ch; }
.pl-shelf-rows { border: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent); border-radius: 10px; padding: 2px 10px; }
.pl-shelf-row { padding: 6px 2px; }

.pl-setbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 18px 0 8px; }
.pl-setbar .pl-tools { margin-left: auto; }
.pl-list.hl-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(236px, 1fr)); gap: 12px; }
/* Compact is the section's own sticker (.mom-sticker), at the size every compact list uses; the
   jacket opens the chart and the corner tick is what picks it. */
.pl-list.stickers { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }
.pl-card.picked, .pl-sticker.picked { border-color: var(--mix-primary); box-shadow: 0 0 0 1px var(--mix-primary), 0 0 14px -6px var(--mix-glow); }
.pl-sticker-tick { position: absolute; top: 3px; right: 3px; width: 20px; height: 20px; border-radius: 4px; border: 1.5px solid color-mix(in srgb, var(--mix-ink) 45%, transparent); background: color-mix(in srgb, var(--mix-bg) 70%, transparent); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.pl-sticker.picked .pl-sticker-tick { background: var(--mix-primary); border-color: var(--mix-primary); color: var(--mix-primary-contrast); }
.pl-sticker-tick .mud-icon-root { font-size: 14px; }
.pl-sticker-projected { position: absolute; bottom: 24px; left: 3px; font-size: 9.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--mix-accent); background: color-mix(in srgb, var(--mix-bg) 78%, transparent); padding: 0 4px; border-radius: 3px; }
.pl-open { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.pl-energy .mud-input-control { min-width: 160px; }
.pl-energy .mud-select { max-width: 200px; }

/* Every select, autocomplete and field in the section reads at one compact height (owner,
   2026-09-06). MudBlazor's dense margin is not enough on its own: the outlined input carries an
   explicit height AND mud-typography-subtitle1, so the row still stands twice as tall as the
   buttons beside it. The same shape the app-bar search already uses — unset the height, set the
   padding — applied to .mud-input-slot, which is the one class on both a text input and a
   select's visible value div. */
.mom-entry .mud-input-control.mud-input-control-margin-dense,
.pl-controls .mud-input-control.mud-input-control-margin-dense { margin-top: 0; margin-bottom: 0; }
.mom-entry .mud-input, .pl-controls .mud-input { font-size: 14px; line-height: 1.45; }
/* Out-specifies MudBlazor's own dense rule, which sets 10.5px top and bottom on the slot and is
   itself three classes deep — a two-class override loses to it silently. */
.mom-entry .mud-input.mud-input-outlined .mud-input-slot.mud-input-root,
.pl-controls .mud-input.mud-input-outlined .mud-input-slot.mud-input-root {
    height: unset;
    min-height: 0;
    padding-top: 5px;
    padding-bottom: 5px;
    font-size: 14px;
    line-height: 1.45;
}
.mom-entry .mud-input-label, .pl-controls .mud-input-label { font-size: 13px; }
/* A resting label is translated down by an amount tuned to the taller input, which leaves it
   sitting below centre once the input is this short. The floated one lands in the notch and is
   already right, so only the un-shrunk label moves — and a focused field floats its label with
   :focus-within rather than a class, so that state has to be excluded by hand or this rule
   out-specifies it and the label sits on top of what is being typed. */
.mom-entry .mud-input.mud-input-outlined:not(.mud-shrink):not(:focus-within) ~ .mud-input-label.mud-input-label-outlined,
.pl-controls .mud-input.mud-input-outlined:not(.mud-shrink):not(:focus-within) ~ .mud-input-label.mud-input-label-outlined {
    transform: translate(14px, 6px) scale(1);
}
.mom-entry .mud-input-adornment .mud-icon-root, .pl-controls .mud-input-adornment .mud-icon-root { font-size: 18px; }
.mom-entry .mud-input-adornment .mud-button-root, .pl-controls .mud-input-adornment .mud-button-root { padding: 2px; }
.pl-projected-toggle { margin-top: 10px; font-size: 13px; }
/* The delete sits under the three ways out, not beside them: it is the one that cannot be undone. */
.mom-published-delete { margin-top: 10px; padding-top: 10px; border-top: 1px solid color-mix(in srgb, var(--mix-ink) 8%, transparent); }
.pl-saveset { display: flex; align-items: center; gap: 10px; }
.pl-saveset .mud-input-control { flex: 1 1 auto; }
.pl-saveset-note { display: block; margin-top: 6px; color: var(--mix-ink-muted); }
.pl-setlist { margin-top: 14px; display: flex; flex-direction: column; gap: 6px; }
.pl-setrow { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border-radius: 8px; background: color-mix(in srgb, var(--mix-ink) 5%, transparent); }
.pl-setrow-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.pl-table-chart { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.pl-table-chart .w700 { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 26ch; }

@media (max-width: 900px) {
    .pl-controls { grid-template-columns: 1fr; }
    .pl-push { padding-left: 0; border-left: 0; padding-top: 14px; border-top: 1px solid color-mix(in srgb, var(--mix-ink) 10%, transparent); }
}
@media (max-width: 700px) {
    .pl-title { font-size: 28px; }
    .pl-proj-big { font-size: 38px; }
    .pl-conversion { margin-left: 0; text-align: left; }
}

/* ===== Hardmode (docs/design/hardmode-leaderboard.md) =====
   The three facts a qualifying chart carries under its score: how many pools hold it, and which
   of the three states it is in for this viewer. Each on its own line — two of them inline read
   as one run-on caption. */
.hmd-held,
.hmd-in,
.hmd-out,
.hmd-none {
    display: block;
    font-family: var(--font-display);
    font-size: 10.5px;
    letter-spacing: .07em;
    text-transform: uppercase;
    line-height: 1.5;
}

.hmd-held {
    color: var(--mix-ink-muted);
}

/* A chart no full pool holds is the rarest thing in its folder, so it reads at the top of the
   rarity ramp rather than as missing data. */
.hmd-held-zero {
    color: var(--rarity-prism);
}

.hmd-in {
    color: var(--rarity-gold);
}

.hmd-out {
    color: var(--mud-palette-success);
}

.hmd-none {
    color: var(--mix-ink-muted);
}

/* The board's rank and identity cells. The rank is coloured by percentile through the rarity
   ramp, like every other board on the site, and prints its place beside the colour. */
.hmd-rank {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 14px;
}

.hmd-player {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

/* ---- Hardmode mark (docs/design/hardmode-leaderboard.md D19) --------------------------
   One token, --hard-mark, for every surface that says a chart or a number is Hardmode:
   the score badge, the gain chip, the milestone strip, the session rail's gain segment,
   the history tag, the feed captions and the difficulty-bubble glow. Emitted by MixThemes
   and mix-invariant, like the judgment and lifebar groups. */

.hmd-badge {
    color: var(--hard-mark);
    border: 1px solid color-mix(in srgb, var(--hard-mark) 70%, transparent);
    background: rgba(0, 0, 0, .82);
    border-radius: 3px;
    padding: 1px 5px;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* The gain chip, matching .sbd-gain's geometry exactly so the two sit level on one score
   line — they differ only in which pool they measure. */
.hmd-gain {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: .74rem;
    line-height: 1.25;
    font-variant-numeric: tabular-nums;
    background: rgba(0, 0, 0, .82);
    color: var(--hard-mark);
    border: 1px solid var(--hard-mark);
    border-radius: 2px;
    padding: 1px 5px;
    white-space: nowrap;
}

/* The card-corner variant, alongside .pmb-corner-gain. Declared after
   .tier-chart-card-corner so it wins that rule's border shorthand on source order — the
   same contract the card border language runs on. */
.hmd-corner-gain {
    border-color: var(--hard-mark);
    color: var(--hard-mark);
}

/* The milestone strip. Same geometry as the amber PUMBILITY strip beside it; the rail's
   colour is the only difference, which is what lets six strips read as two families. */
.hmd-strip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    min-height: 34px;
    border-left: 3px solid var(--hard-mark);
    background: color-mix(in srgb, var(--hard-mark) 8%, transparent);
}

.hmd-strip-chip {
    flex: none;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: .74rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--hard-mark);
}

.hmd-section-head {
    color: var(--hard-mark);
}

.hmd-track-gain {
    background: var(--hard-mark);
}

.hmd-card-tag {
    color: var(--hard-mark);
}

/* The difficulty-bubble glow (D24). A drop-shadow filter rather than a border or a box
   shadow, so it traces the bubble art's own alpha and haloes the shape instead of a
   rectangle around it. Three stacked shadows: a tight core, a bloom, and a wide falloff
   that survives a near-white album jacket, which is the ground with the least to bloom
   into. Never suppressed anywhere, the Hardmode page's own list included — a folder where
   every chart glows is the point there, not a defect. */
.bubble-hardmode {
    filter: drop-shadow(0 0 3px var(--hard-mark))
    drop-shadow(0 0 9px var(--hard-mark))
    drop-shadow(0 0 16px color-mix(in srgb, var(--hard-mark) 60%, transparent));
}

/* The difficulty glow's most-held end (docs/design/hardmode-leaderboard.md D32): the same three
   stacked shadows as the Hardmode red above, in the mix-invariant mint, so the two ends read as one
   family. Mint rather than a theme green because the glow only renders on Phoenix 2, whose primary
   is already green. */
.bubble-easy {
    filter: drop-shadow(0 0 3px var(--easy-mark))
    drop-shadow(0 0 9px var(--easy-mark))
    drop-shadow(0 0 16px color-mix(in srgb, var(--easy-mark) 60%, transparent));
}

/* The Sessions-page Hardmode banner (D31): the March of Murlocs callout's geometry in D19's red,
   sitting above the hero rather than inside it, with a close at its far corner. Declared after
   .mom-callout's rules so its margins win on source order. */
.hmd-callout {
    position: relative;
    margin: 0 0 14px;
    padding-right: 44px;
    border-color: color-mix(in srgb, var(--hard-mark) 50%, transparent);
    background: color-mix(in srgb, var(--hard-mark) 7%, transparent);
}

.hmd-callout .ico {
    font-size: 24px;
    line-height: 1;
    filter: drop-shadow(0 0 6px color-mix(in srgb, var(--hard-mark) 70%, transparent));
}

.hmd-callout-body {
    flex: 1 1 380px;
    min-width: 0;
}

.hmd-callout-say {
    margin: 0 0 10px;
    font-size: 13.5px;
    line-height: 1.45;
    max-width: 68ch;
}

.hmd-callout .fact:first-child b {
    color: var(--hard-mark);
}

.hmd-callout-off {
    margin: 10px 0 0;
    font-size: 12px;
    color: var(--mix-ink-muted);
}

.hmd-callout-x {
    position: absolute;
    top: 6px;
    right: 6px;
    color: var(--mix-ink-muted);
}

@media (max-width: 700px) {
    .hmd-callout {
        margin-left: 0;
        margin-right: 0;
    }
}

/* The Hardmode switch under the Hardmode tab's number (D30): red while off, because off is the
   state it is asking you to change, and quiet once it is on. */
.hmd-optin {
    display: flex;
    align-items: center;
    gap: 10px 14px;
    flex-wrap: wrap;
    padding: 10px 12px;
    margin-bottom: 14px;
    border-radius: 8px;
    border: 1px solid color-mix(in srgb, var(--hard-mark) 45%, transparent);
    background: color-mix(in srgb, var(--hard-mark) 6%, transparent);
}

.hmd-optin-on {
    border-color: color-mix(in srgb, var(--mix-ink) 12%, transparent);
    background: color-mix(in srgb, var(--mix-surface) 60%, transparent);
}

.hmd-optin-glyph {
    font-size: 18px;
    line-height: 1;
}

.hmd-optin-say {
    margin: 0;
    flex: 1 1 280px;
    font-size: 13.5px;
    line-height: 1.45;
}

.hmd-optin-on .hmd-optin-say {
    color: var(--mix-ink-muted);
}
