/* Custom styles based on MAUI application design */
/* Color palette reference: https://color.romanuke.com/tsvetovaya-palitra-3852/ */

/* ════════════════════════════════════════════════════════════════════════════
   Colour token system — THREE tiers (see color-consolidation-effort).
     1. TONES  (--tone-*)  — the ONLY place a hex literal lives. Named by colour
        (raw material). One tone = one value; dup values collapsed here.
     2. ROLES  (--action-* / --text-* / --surface-* / --status-* / --tint-*)  —
        named by USE, never by colour. Reference a tone. This is the vocabulary
        new code should consume. A theme swap re-points tones (or a role), never
        renames a role.
     3. LEGACY --tt-* shims — every historical --tt-* var now points at a role,
        so the ~400 existing call-sites keep working untouched while they migrate
        to roles over time. Do NOT add new --tt-* vars; consume roles directly.
   Light theme only. MAUI Colors.xaml mirrors tiers 1–2 (TonePascalCase / RolePascalCase).
   ════════════════════════════════════════════════════════════════════════════ */
:root {
    /* ─────────── Tier 1 — TONES (hex lives here only) ─────────── */
    /* Brand clay (DECISION 4: all clay collapsed to #b27c62; legacy #b6846b dropped) */
    --tone-brand-clay: #b27c62;
    --tone-brand-clay-dark: #9c6a52;
    --tone-brand-clay-tint: #F7F3EF;
    --tone-brand-gold: #b0935a;
    --tone-dark-clay-ink: #59392D;      /* opaque dark clay-brown filter text */
    --tone-dark-clay-ink-soft: #A06F5B; /* filter reset label */
    --tone-hand-pill-taupe: #7A6A52;
    --tone-hand-pill-taupe-bg: #F1ECE1;
    --tone-hand-pill-taupe-border: #E2D8C4;
    --tone-ring-gold: #c2a878;    /* DESIGNER: gold avatar ring (was clay) */

    /* Protocol loser-arrow stage palette (design_handoff_bracket_protocol §3.2 PB2_ARW): each consolation
       stage — a receiver column — gets one of 5 cycled colours. Clay reuses the brand token; the other four
       are stage-only. */
    --tone-arrow-pine: #2f7468;
    --tone-arrow-blue: #54648f;
    --tone-arrow-plum: #8a5a78;
    --tone-arrow-ochre: #a3752c;

    /* Reds */
    --tone-accent-red: #D23B2E;   /* accent / loss / section-red (absorbed sharp #f73149) */
    --tone-danger-red: #c0392b;   /* solid destructive (logout/delete) — DECISION 2 kept */
    --tone-reject-rose: #CD5C5C;
    --tone-maroon: #8C2F24;       /* error text only (DECISION E: geo split out) */
    --tone-geo-distance: #8C2F24; /* distance meta — own tone so errors recolour independently */
    --tone-geo-distance-pin: #7E2A20;

    /* Greens (DESIGNER Q1: gain-green folded into win-green → rating-up == win). Two greens. */
    --tone-ok-green: #3f9f6a;     /* confirm/success (legacy #52E02C dropped) */
    --tone-win-green: #1F9D57;    /* win / live / rating-up (absorbed gain #58A943) */
    --tone-live-grad-top: #1f8a52;
    --tone-live-grad-bot: #2da866;
    --tone-loss-rose: #BA4A57;    /* rating-down in tiles */

    /* Amber / gold / blues */
    --tone-amber: #C98A1E;        /* draw / pending (absorbed #b58324) */
    --tone-warn-amber: #b9772b;
    --tone-gold-badge: #9A6F2E;
    --tone-medal-gold: #c9a227;   /* 1st-place / top-3 medal + protocol place number */
    --tone-info-blue: #3f93d6;
    --tone-telegram-blue: #2aabee;
    --tone-slate-blue: #5b6b7a;   /* lock / no-DM pill text */

    /* Text inks */
    --tone-ink-primary: #222222;   /* absorbed #262626 / #2B2B2B / #000010 */
    --tone-ink-secondary: #5e5b57; /* absorbed #5a5a5a / #6B6B6B / #7A7A7A / #3A3A3A */
    --tone-ink-tertiary: #9A9A9A;  /* absorbed #938d85 / #8a8a8a / #A8A8A8 */
    --tone-ink-heading: #3b3a38;
    --tone-white: #FFFFFF;

    /* Brand chrome grey — DESIGNER: kept distinct from gray-200 (appbar/tabbar restored to #CACAC8) */
    --tone-chrome-grey: #CACAC8;

    /* Neutral scale */
    --tone-gray-50: #F5F5F5;
    --tone-gray-100: #E1E1E1;
    --tone-gray-200: #C8C8C8;
    --tone-gray-300: #ACACAC;
    --tone-gray-400: #919191;
    --tone-gray-500: #6E6E6E;   /* absorbed TertiaryDark #686869 (~2pt) */
    --tone-gray-600: #404040;
    --tone-gray-700: #7D7D7D;   /* off-scale legacy SecondaryDark (open question) */
    --tone-gray-900: #212121;
    --tone-gray-950: #141414;
    --tone-faint-separator: #CFCDC7;       /* darker separator/chevron — NOT the light hairline */
    --tone-faint-separator-light: #BCBCBC; /* delta-unit separator */

    /* Surfaces / borders / tints */
    --tone-page-bg: #F5F3F0;      /* DESIGNER Q3: single page bg; #FFF7EF (page-bg-warm) folded away */
    --tone-card-warm: #fbfaf8;
    --tone-border-card: #E4E1DA;  /* absorbed GameCard_Border #E0E0E0 */
    --tone-border-warm: #d8d5d0;  /* absorbed row-hover #d7d2c8 / #d0ccc4 */
    --tone-hairline: #eceae7;     /* light divider (absorbed #E4E2DD) */
    --tone-tint-warm-neutral: #f1eee7; /* absorbed #efedea / #EFECE6 / #ece9e4 */
    --tone-tint-highlight-me: #F7E1D5; /* DESIGNER Q4: single "me" highlight; tournament cream #fbf6ee folded away */
    --tone-border-me-row: #eccbb8;
    --tone-tint-ok: #e6f3ec;      /* absorbed win-badge #DBE9DE */
    --tone-tint-amber: #fdf3e7;
    --tone-tint-info: #eaf3fb;
    --tone-tint-error: #fdf1f0;
    --tone-tint-lock: #eef2f6;
    --tone-border-info: #cfe4f5;
    --tone-border-warn: #f2dcc0;
    --tone-border-error: #f1cac4;

    /* Tournament status-badge tints (DECISION 3: three kept distinct) */
    --tone-status-reg-bg: #EEE7E2;
    --tone-status-neutral-bg: #e6e4df;
    --tone-status-draft-bg: #e9e7e0;
    --tone-status-finished-fg: #8a8a8a; /* distinct from draft/cancelled #9a9a9a */

    /* Misc accents */
    --tone-tab-band-lilac: #F2ECF1;
    --tone-status-inactive-grey: #B3ACA4; /* absorbed lock glyph #B0A79E */
    --tone-nodm-brick: #BF5A4F;
    --tone-header-grad-top: #ebeae7;
    --tone-header-grad-bot: #d9d8d5;
    --tone-tour-disabled-bg: #faf8f4;
    --tone-tour-disabled-text: #cfcabf;
    /* Protocol ("схема") blank-sheet BLOCK borders — the cross-table cells and bracket match boxes. A
       deliberately "paper"-toned line, stronger than the light card border, so the empty protocol reads
       as a printable sheet (prototype #c9c3b8). The bracket CONNECTORS (stubs + rail between blocks) use
       the lighter --border-card instead, so the links sit visually behind the blocks. */
    --tone-protocol-grid: #c9c3b8;
    --tone-badge-gold-tint: #F6EED9;
    --tone-badge-gold-border: #E7D6AD;
    --tone-qualifying-cream: #F6EED9;

    /* ─────────── Tier 2 — ROLES (named by use; reference tones) ─────────── */
    /* Actions */
    --action-primary: var(--tone-brand-clay);
    --action-primary-pressed: var(--tone-brand-clay-dark);
    --action-confirm: var(--tone-ok-green);
    --action-destructive: var(--tone-accent-red);        /* outlined destructive (tournaments) */
    --action-destructive-strong: var(--tone-danger-red); /* solid logout/delete (open question) */
    --action-reject: var(--tone-reject-rose);
    --action-secondary: var(--tone-white);
    --action-neutral-warm: var(--tone-tint-warm-neutral);
    --action-telegram: var(--tone-telegram-blue);
    --action-disabled-bg: var(--tone-gray-200);
    --action-disabled-text: var(--tone-gray-950);

    /* Controls */
    --control-track: var(--tone-tint-warm-neutral);
    --control-selected-tint: var(--tone-brand-clay-tint);
    --focus-ring: var(--tone-brand-clay);

    /* Text */
    --text-primary: var(--tone-ink-primary);
    --text-secondary: var(--tone-ink-secondary);
    --text-muted: var(--tone-ink-tertiary);
    --text-heading-warm: var(--tone-ink-heading);
    --text-disabled: var(--tone-gray-300);
    --text-on-accent: var(--tone-white);
    --text-link: var(--tone-brand-clay-dark);
    --text-filter-name: var(--tone-dark-clay-ink);
    --text-filter-reset: var(--tone-dark-clay-ink-soft);
    --text-error: var(--tone-maroon);
    --text-accent: var(--tone-accent-red);
    --text-name-suffix: var(--tone-brand-gold);
    --text-place-medal: var(--tone-medal-gold);
    --text-distance: var(--tone-geo-distance);
    --text-score-dimmed: var(--tone-gray-200);
    --text-neutral-strong: var(--tone-gray-600);
    --neutral-mid: var(--tone-gray-500);

    /* Surfaces */
    --surface-page: var(--tone-page-bg);
    --surface-card: var(--tone-white);
    --surface-card-warm: var(--tone-card-warm);
    --surface-sheet: var(--tone-gray-100);
    --surface-selected-row: var(--tone-gray-100);
    --surface-me-row: var(--tone-tint-highlight-me);
    --surface-tab-band: var(--tone-tab-band-lilac);
    --surface-disabled-warm: var(--tone-tour-disabled-bg);
    --surface-distance-pin: var(--tone-geo-distance-pin);
    --surface-header-gradient-top: var(--tone-header-grad-top);
    --surface-header-gradient-bot: var(--tone-header-grad-bot);
    --text-disabled-warm: var(--tone-tour-disabled-text);

    /* Borders / lines */
    --border-card: var(--tone-border-card);
    --border-card-warm: var(--tone-border-warm);
    --border-hairline: var(--tone-hairline);
    --border-separator: var(--tone-faint-separator);
    --border-separator-light: var(--tone-faint-separator-light);
    --border-me-row: var(--tone-border-me-row);
    --border-avatar: var(--tone-ring-gold); /* DESIGNER: gold avatar ring (was clay) */
    --border-protocol-grid: var(--tone-protocol-grid);
    --line-input: var(--tone-gray-400);
    --line-divider: var(--tone-gray-200);

    /* Chrome */
    --chrome-appbar: var(--tone-chrome-grey); /* DESIGNER: restored to #CACAC8, distinct from gray-200 */
    --chrome-dark-surface: var(--tone-gray-700);

    /* Statuses */
    --status-win: var(--tone-win-green);
    --status-win-tint: var(--tone-tint-ok);
    --status-live-gradient-top: var(--tone-live-grad-top);
    --status-live-gradient-bot: var(--tone-live-grad-bot);
    --status-rating-up: var(--tone-win-green); /* DESIGNER Q1: rating-up == win */
    --status-loss: var(--tone-accent-red);
    --status-loss-tint: var(--tone-tint-error);
    --status-rating-down: var(--tone-loss-rose);
    --status-pending: var(--tone-amber);
    --status-registration-bg: var(--tone-status-reg-bg);
    --status-registration-fg: var(--tone-brand-clay-dark);
    --status-neutral-bg: var(--tone-status-neutral-bg);
    --status-draft-bg: var(--tone-status-draft-bg);
    --status-finished-fg: var(--tone-status-finished-fg);
    --status-lock: var(--tone-slate-blue);
    --status-inactive: var(--tone-status-inactive-grey);
    --status-nodm: var(--tone-nodm-brick);

    /* Badges / alerts (composite roles keep their fg tone here; bg/border via tint/border tones) */
    --badge-qualifying-fg: var(--tone-gold-badge);
    --badge-qualifying-bg: var(--tone-badge-gold-tint);
    --badge-qualifying-border: var(--tone-badge-gold-border);
    --badge-hand-fg: var(--tone-hand-pill-taupe);
    --badge-hand-bg: var(--tone-hand-pill-taupe-bg);
    --badge-hand-border: var(--tone-hand-pill-taupe-border);
    --alert-info-fg: var(--tone-info-blue);
    --alert-info-bg: var(--tone-tint-info);
    --alert-info-border: var(--tone-border-info);
    --alert-warn-fg: var(--tone-warn-amber);
    --alert-warn-bg: var(--tone-tint-amber);
    --alert-warn-border: var(--tone-border-warn);
    --alert-error-fg: var(--tone-maroon);
    --alert-error-bg: var(--tone-tint-error);
    --alert-error-border: var(--tone-border-error);
    --status-lock-bg: var(--tone-tint-lock);

    /* Alpha washes (web: color-mix from base tone; MAUI: #AARRGGBB literal) */
    --tint-clay-soft: color-mix(in srgb, var(--tone-brand-clay) 10%, transparent);
    --tint-clay-strip: color-mix(in srgb, var(--tone-brand-clay) 13%, transparent);
    --tint-clay-border: color-mix(in srgb, var(--tone-brand-clay) 38%, transparent);
    --tint-clay-reset-border: color-mix(in srgb, var(--tone-brand-clay) 50%, transparent);
    --tint-accent-soft: color-mix(in srgb, var(--tone-accent-red) 9%, transparent);
    --tint-loss-soft: color-mix(in srgb, var(--tone-accent-red) 11%, transparent);
    --tint-win-soft: color-mix(in srgb, var(--tone-win-green) 12%, transparent);
    --tint-pending-soft: color-mix(in srgb, var(--tone-amber) 13%, transparent);
    --tint-tg-soft: color-mix(in srgb, var(--tone-telegram-blue) 11%, transparent);
    --tint-live-shadow: color-mix(in srgb, var(--tone-live-grad-bot) 28%, transparent);
    --tint-danger-hover: color-mix(in srgb, var(--tone-accent-red) 8%, transparent);

    /* Layout / typography (not colours) */
    --tt-border-radius: 8px;
    --tt-appbar-height: 64px;
    --tt-bottomnav-height: 64px;
    --tt-font-family: 'Roboto', system-ui, sans-serif;
    --tt-font-size-body: 0.9375rem; /* 15px */
    --tt-font-size-secondary: 0.8125rem; /* 13px */

    /* ─────────── Tier 3 — LEGACY --tt-* SHIMS (point at roles; do not extend) ───────────
       Every historical colour var below now resolves through a role so existing
       call-sites are appearance-preserving. Migrate sites to roles, then delete a shim. */
    --tt-primary: var(--chrome-appbar);
    --tt-primary-text: var(--text-primary);
    --tt-primary-dark: var(--action-primary);
    --tt-primary-dark-text: var(--text-accent);
    --tt-secondary: var(--action-primary);
    --tt-secondary-text: var(--text-on-accent);
    --tt-secondary-dark: var(--chrome-dark-surface);
    --tt-secondary-dark-text: #A7A6A6; /* dark-mode only, out of scope — retained verbatim */
    --tt-tertiary: var(--status-loss);
    --tt-tertiary-soft: var(--text-accent);
    --tt-tertiary-dark: var(--neutral-mid);
    --tt-tertiary-dark-text: #8B8A8C; /* dark-mode only, out of scope */
    --tt-alert-error-bg: var(--alert-error-bg);
    --tt-alert-error-border: var(--alert-error-border);
    --tt-alert-error-text: var(--alert-error-fg);
    --tt-accept: var(--action-confirm);
    --tt-reject: var(--action-reject);
    --tt-increased-rating: var(--status-rating-up);
    --tt-decreased-rating: var(--status-rating-down);
    --tt-white: var(--tone-white);
    --tt-black: var(--text-primary);
    --tt-off-black: #1f1f1f; /* dark-mode surface, out of scope */
    --tt-gray-50: var(--tone-gray-50);
    --tt-gray-100: var(--tone-gray-100);
    --tt-gray-200: var(--tone-gray-200);
    --tt-gray-300: var(--tone-gray-300);
    --tt-gray-400: var(--tone-gray-400);
    --tt-gray-500: var(--tone-gray-500);
    --tt-gray-600: var(--tone-gray-600);
    --tt-gray-900: var(--tone-gray-900);
    --tt-gray-950: var(--tone-gray-950);
    --tt-current-player-top-bg: var(--surface-me-row);
    --tt-card-bg-dark: #322F37; /* dark-mode only, out of scope */
    --tt-card-title-dark: #F4EFF4;
    --tt-card-alt-title-light: #CAC4D0;
    --tt-card-alt-title-dark: #79747E;
    --tt-bottom-sheet-bg-light: var(--surface-sheet);
    --tt-bottom-sheet-bg-dark: #25232A; /* dark-mode only, out of scope */
    --tt-bottom-sheet-separator-light: var(--border-hairline);
    --tt-bottom-sheet-separator-dark: #E7E0EC;
    --tt-page-bg: var(--surface-page);
    --tt-page-bg-dark: #080808; /* dark-mode only, out of scope */
    --tt-game-result-win: var(--status-win);
    --tt-game-result-loss: var(--status-loss);
    --tt-game-result-draw: var(--status-pending);
    --tt-game-result-neutral: var(--text-muted);
    --tt-game-card-border: var(--border-card);
    --tt-game-card-separator: var(--border-hairline);
    --tt-game-card-pressed: var(--control-selected-tint);
    --tt-game-text-name: var(--text-primary);
    --tt-game-text-name-strong: var(--text-primary);
    --tt-game-text-sub: var(--text-secondary);
    --tt-game-text-separator: var(--border-separator);
    --tt-game-text-accent-amber: var(--text-name-suffix);
    --tt-game-text-muted: var(--text-muted);
    --tt-game-text-secondary: var(--text-secondary);
    --tt-game-text-delta-unit: var(--border-separator-light);
    --tt-game-qualifying-text: var(--badge-qualifying-fg);
    --tt-game-qualifying-bg: var(--badge-qualifying-bg);
    --tt-game-qualifying-border: var(--badge-qualifying-border);
    --tt-game-hand-pill-text: var(--badge-hand-fg);
    --tt-game-hand-pill-bg: var(--badge-hand-bg);
    --tt-game-hand-pill-border: var(--badge-hand-border);
    --tt-settings-accent: var(--action-primary);
    --tt-settings-accent-dark: var(--action-primary-pressed);
    --tt-settings-accent-tint: var(--control-selected-tint);
    --tt-settings-bg: var(--surface-page);
    --tt-settings-card: var(--surface-card-warm);
    --tt-settings-card-border: var(--border-card-warm);
    --tt-settings-line: var(--border-hairline);
    --tt-settings-ink: var(--text-heading-warm);
    --tt-settings-ink-2: var(--text-secondary);
    --tt-settings-ink-3: var(--text-muted);
    --tt-ok-green: var(--action-confirm);
    --tt-settings-danger: var(--action-destructive-strong);
    --tt-settings-info: var(--alert-info-fg);
    --tt-settings-info-bg: var(--alert-info-bg);
    --tt-settings-info-border: var(--alert-info-border);
    --tt-settings-warn: var(--alert-warn-fg);
    --tt-settings-warn-bg: var(--alert-warn-bg);
    --tt-settings-warn-border: var(--alert-warn-border);
    --tt-settings-tg-blue: var(--action-telegram);
    --tt-settings-tg-blue-soft: var(--tint-tg-soft);
    --tt-settings-pill-neutral-bg: var(--control-track);
    --tt-settings-pill-neutral-text: var(--text-secondary);
    --tt-settings-pill-ok-bg: var(--status-win-tint);
    --tt-settings-pill-lock-bg: var(--status-lock-bg);
    --tt-settings-pill-lock-text: var(--status-lock);
    --tt-settings-header-grad-top: var(--surface-header-gradient-top);
    --tt-settings-header-grad-bot: var(--surface-header-gradient-bot);
    --tt-tour-badge-clay-bg: var(--status-registration-bg);
    --tt-tour-badge-clay-fg: var(--status-registration-fg);

    /* Protocol loser-arrow stage colours (5-colour cycle) + their 10%/38% chip tints (§2.1). */
    --tt-arrow-0: var(--tone-brand-clay-dark);
    --tt-arrow-1: var(--tone-arrow-pine);
    --tt-arrow-2: var(--tone-arrow-blue);
    --tt-arrow-3: var(--tone-arrow-plum);
    --tt-arrow-4: var(--tone-arrow-ochre);
    --tt-arrow-0-bg: color-mix(in srgb, var(--tt-arrow-0) 10%, transparent);
    --tt-arrow-1-bg: color-mix(in srgb, var(--tt-arrow-1) 10%, transparent);
    --tt-arrow-2-bg: color-mix(in srgb, var(--tt-arrow-2) 10%, transparent);
    --tt-arrow-3-bg: color-mix(in srgb, var(--tt-arrow-3) 10%, transparent);
    --tt-arrow-4-bg: color-mix(in srgb, var(--tt-arrow-4) 10%, transparent);
    --tt-arrow-0-bd: color-mix(in srgb, var(--tt-arrow-0) 38%, transparent);
    --tt-arrow-1-bd: color-mix(in srgb, var(--tt-arrow-1) 38%, transparent);
    --tt-arrow-2-bd: color-mix(in srgb, var(--tt-arrow-2) 38%, transparent);
    --tt-arrow-3-bd: color-mix(in srgb, var(--tt-arrow-3) 38%, transparent);
    --tt-arrow-4-bd: color-mix(in srgb, var(--tt-arrow-4) 38%, transparent);
    --tt-tour-badge-win-bg: var(--status-win-tint);
    --tt-tour-badge-win-fg: var(--status-win);
    --tt-tour-badge-amber-fg: var(--status-pending);
    --tt-tour-badge-amber-bg: var(--tint-pending-soft);
    --tt-tour-badge-loss-fg: var(--status-loss);
    --tt-tour-badge-loss-bg: var(--tint-loss-soft);
    --tt-tour-badge-mute-fg: var(--text-muted);
    --tt-tour-badge-mute-bg: var(--status-neutral-bg);
    --tt-tour-badge-neutral-bg: var(--status-neutral-bg);
    --tt-tour-badge-draft-bg: var(--status-draft-bg);
    --tt-tour-live-grad-top: var(--status-live-gradient-top);
    --tt-tour-live-grad-bot: var(--status-live-gradient-bot);
    --tt-tour-live-shadow: var(--tint-live-shadow);
    --tt-tour-suffix-gold: var(--text-name-suffix);
    --tt-tour-place-medal: var(--text-place-medal);
    --tt-tour-score-lose: var(--text-score-dimmed);
    --tt-tour-card-border: var(--border-card);
    --tt-tour-protocol-grid: var(--border-protocol-grid);
    --tt-tour-chip-bg: var(--control-track);
    --tt-tour-row-current: var(--surface-me-row); /* DESIGNER Q4: unified "me" highlight */
    --tt-tour-ink-2: var(--text-secondary);
    --tt-tour-ink-soft: var(--text-secondary);
    --tt-tour-handle: var(--text-muted);
    --tt-tour-disabled-bg: var(--surface-disabled-warm);
    --tt-tour-disabled-text: var(--text-disabled-warm);
    --tt-rate-accent: var(--text-accent);
    --tt-rate-accent-soft: var(--tint-accent-soft);
    --tt-rate-ink: var(--text-primary);
    --tt-rate-muted: var(--text-muted);
    --tt-rate-sub: var(--text-muted);
    --tt-rate-line: var(--border-hairline);
    --tt-rate-line2: var(--border-hairline);
    --tt-rate-card-bg: var(--surface-card);
    --tt-rate-card-bd: var(--border-card);
    --tt-rate-sunk: var(--control-track);
    --tt-rate-delta-up: var(--status-win);
    --tt-rate-delta-down: var(--status-loss);
    --tt-rate-delta-flat: var(--text-muted);
    --tt-rate-dist: var(--text-distance);
    --tt-rate-dist-pin: var(--surface-distance-pin);
    --tt-rate-inactive: var(--status-inactive);
    --tt-rate-nodm: var(--status-nodm);
    --tt-rate-lock: var(--status-inactive);
    --tt-rate-tg: var(--action-telegram);
    --tt-rate-you-bg: var(--surface-me-row);
    --tt-rate-you-bd: var(--border-me-row);
}

/* Base styles */
html {
    overflow-x: hidden;
    height: 100%;
    color-scheme: light;
}

body {
    /* clip, NOT hidden: overflow-x:hidden turns body into a scroll container (computed
       overflow-y:auto), and since the window — not body — actually scrolls, every
       position:sticky inside the app silently never engages (fixed keeps working).
       overflow-x:clip clips the same way without creating a scroll container. */
    overflow-x: clip;
    min-height: 100%;
    margin: 0;
    padding: 0;
    font-family: var(--tt-font-family);
}

/* MudBlazor overrides */
.mud-main-content {
    background-color: var(--tt-page-bg);
}

.mud-paper,
.mud-card,
.mud-button-root:not(.mud-switch-base),
.mud-input,
.mud-text-field {
    border-radius: var(--tt-border-radius);
}

/* MudSwitch renders its draggable knob as a .mud-switch-base, which also carries
   .mud-button-root (it is an internal MudIconButton). The global button sizing
   below was forcing min-height:44px and a square border-radius onto that knob,
   inflating it past the 38px track and pushing it down ("sagging" switch). Scope
   the override to real buttons by excluding the switch base. */
.mud-button-root:not(.mud-switch-base) {
    font-weight: 500;
    text-transform: none;
    padding: 10px 14px;
    min-height: 44px;
}

    /* Disabled button — mirrors MAUI VisualState Disabled:
   Gray200 background (#C8C8C8), Gray950 text (#141414), no shadow, no opacity fade. */
    .mud-button-root:not(.mud-switch-base):disabled,
    .mud-button-root:not(.mud-switch-base).mud-disabled {
        background-color: var(--tt-gray-200) !important;
        color: var(--tt-gray-950) !important;
        box-shadow: none !important;
        opacity: 1 !important;
        border-color: transparent !important;
        cursor: default;
    }

/* ============================================================================
   Tournament hand-CSS button family (prototype tour-chrome.jsx `Btn`) — the SINGLE
   home for the .btn look. Markup is `class="btn <color> [<size>]"`. Colour lives here
   once (this is what used to drift between scoped copies); size modifiers (.block/.sm)
   and any component-local size overrides (compact match-row, create/start block) stay
   in the scoped .razor.css of the component that needs them. Border tone for the white
   outline/neutral variants is --tt-settings-card-border (design token border-warm).
   ============================================================================ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: 1.5px solid transparent;
    border-radius: 8px;
    padding: 12px 16px;
    font-size: 15px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    color: var(--tt-white);
}

    .btn:disabled {
        opacity: 0.5;
        cursor: not-allowed;
    }

/* Full-width (block) modifier — width only; per prototype `full` does NOT change the
   md size. Pages that historically ran a smaller block button keep that size via a
   scoped override. Bottom spacing is NOT set here: some rails stack their block buttons
   and add margin-bottom in their own scope (TournamentDetailPage), while others space
   them with a flex `gap` (Create/Start .rail-buttons) — a global margin would double up. */
.btn.block {
    display: flex;
    width: 100%;
}

/* Compact (sm) modifier. */
.btn.sm {
    padding: 6px 12px;
    font-size: 12.5px;
}

/* Colour variants — the one place each fill/border/text lives. */
.btn.clay {
    background: var(--tt-settings-accent);
}

.btn.green {
    background: var(--tt-ok-green);
}

.btn.red {
    background: var(--tt-game-result-loss);
}

/* Confirm actions are the only green-filled buttons (design §4: green = confirm only).
   Transparent border (not none) so its height matches an outlined sibling in a pair. */
.btn.confirm-green {
    background: var(--tt-ok-green);
    color: var(--tt-white);
    border-color: transparent;
}

/* Accent outline (web .btn.outline): white fill, warm border, clay text. */
.btn.outline {
    background: var(--tt-white);
    border: 1.5px solid var(--tt-settings-card-border);
    color: var(--tt-settings-accent);
}

/* Neutral (web .btn.neutral): same warm border as .btn.outline; differs only by the
   muted INK2 label (not the clay text the outline variant uses). */
.btn.neutral {
    background: var(--tt-white);
    border: 1.5px solid var(--tt-settings-card-border);
    color: var(--tt-tour-ink-2);
}

/* Danger outline (web .btn.outline-red): white fill, red border + text. */
.btn.outline-red {
    background: var(--tt-white);
    border: 1.5px solid var(--tt-game-result-loss);
    color: var(--tt-game-result-loss);
}

/* Cancel-tournament outline: white fill, soft alert border, red text. */
.btn.cancel-tour {
    background: var(--tt-white);
    border: 1.5px solid var(--tt-alert-error-border);
    color: var(--tt-game-result-loss);
}

/* Leading icon / in-button spinner (prototype Btn icon=): inherits the button text color. */
.btn-icon {
    width: 18px;
    height: 18px;
    font-size: 18px;
    flex-shrink: 0;
}

.btn-spin {
    width: 18px !important;
    height: 18px !important;
    flex-shrink: 0;
    color: currentColor;
}

    .btn-spin .mud-progress-circular-circle {
        color: currentColor;
    }

/* Rating colors */
.tt-rating-increased {
    color: var(--tt-increased-rating);
    font-weight: 500;
}

.tt-rating-decreased {
    color: var(--tt-decreased-rating);
    font-weight: 500;
}

/* Action buttons */
.tt-accept-button {
    background-color: var(--tt-accept) !important;
    color: var(--tt-white) !important;
}

.tt-reject-button {
    background-color: var(--tt-reject) !important;
    color: var(--tt-white) !important;
}

/* Mobile adjustments */
@media (max-width: 959px) {
    .main-content-with-bottom-nav {
        padding-bottom: 80px !important;
    }

    /* Stick tab bar to the top on mobile, directly under the AppBar */
    .mud-tabs-tabbar {
        position: sticky;
        top: var(--tt-appbar-height);
        z-index: 100;
    }
}

/* Dark mode intentionally disabled — light-only app */

/* Bottom sheet action button: icon on top, label below (matches MAUI layout) */
.bs-action-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 70px;
    padding: 10px 0;
    background: transparent;
    border: none;
    cursor: pointer;
    color: inherit;
    gap: 6px;
}

    .bs-action-btn span {
        font-size: 12px;
        line-height: 1.2;
        text-align: center;
        white-space: nowrap;
    }

/* List tile shared styles */
.tt-tile {
    cursor: pointer;
}

.tt-tile--selected {
    background-color: var(--tt-gray-100) !important;
}

.tt-tile--current-player {
    background-color: var(--tt-current-player-top-bg) !important;
}

.tt-tile-secondary-text {
    color: var(--tt-gray-400);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Ratings section — cards · roomy · red accent · bracketed delta (design §5/§8/§14)
   ═══════════════════════════════════════════════════════════════════════════ */

/* Section host — caps the section to the content area so the OUTER page never scrolls; the inner
   list is sized to fill the remainder by fitScrollHeight (interop.js). No hardcoded per-page height:
   the cap follows the appbar/bottom-nav tokens, and the list top is measured live. */
.rate-page-host {
    height: calc(100dvh - var(--tt-appbar-height));
    overflow: hidden;
    box-sizing: border-box;
}

@media (max-width: 959px) {
    .rate-page-host {
        height: calc(100dvh - var(--tt-appbar-height) - var(--tt-bottomnav-height));
        /* No host padding on mobile: the white tab bar is full-bleed and flush under the AppBar
           (prototype AppHeader → SubTabs). Side padding is reintroduced on the tab PANELS below,
           so only the content (filters + list) is inset — the tab bar spans edge to edge. */
        padding: 0 !important;
    }

    /* The section already reserves space for the bottom nav via its height cap, so the global
       80px bottom padding on the main content would add a redundant scrollable strip here. */
    .main-content-with-bottom-nav:has(.rate-page-host) {
        padding-bottom: 0 !important;
    }
}

/* Section page column */
.rate-page {
    max-width: 860px;
    margin: 0 auto;
    height: 100%;
    box-sizing: border-box;
}

.rate-title {
    font-size: 30px;
    font-weight: 700;
    color: var(--tt-rate-ink);
    letter-spacing: -0.5px;
    margin: 4px 0 14px;
}

/* Mobile: no section title (matches the prototype's mobile shell — the section is implied by nav). */
@media (max-width: 959px) {
    .rate-title {
        display: none;
    }
}

/* Tabs — matched to the prototype SubTabs (design §10, rate-rows.jsx). Unlike the default
   MudTabs look, the prototype uses: sentence-case labels (NOT uppercase), a compact tab with
   the icon inline-left of the text, muted grey for the inactive tab, the red accent for the
   active one, and a thin rounded underline inset from the tab edges over a hairline tabbar border.
   Layout also lays the tabs out as a flex column so the list fits the viewport height, and
   neutralises the global mobile sticky rule that otherwise made the tabbar overlap the filters. */
.rate-tabs {
    height: 100%;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

    .rate-tabs > .mud-tabs-panels {
        flex: 1;
        min-height: 0;
        overflow: hidden;
        display: flex;
        flex-direction: column;
    }

    .rate-tabs .mud-tab-panel {
        height: 100%;
        min-height: 0;
    }
    /* Base (desktop / web-browser): unchanged from the original redesign — white tabbar with a
   hairline border and the red section accent (#D23B2E). The lilac plate + Tertiary underline
   look is scoped to web-mobile only (see the max-width:959px override below). */
    .rate-tabs .mud-tabs-tabbar {
        flex-shrink: 0;
        position: static !important; /* override global mobile sticky (it overlapped the filters) */
        background: var(--surface-card);
        border-bottom: 1px solid var(--tt-rate-line2); /* hairline under the whole tab row */
        min-height: 0;
    }
    /* Compact tab: sentence case, inline icon+label, prototype padding/typography (13px 12px 14px). */
    .rate-tabs .mud-tab {
        min-width: 0;
        min-height: 0;
        padding: 13px 12px 14px;
        text-transform: none; /* prototype keeps "Players"/"Chats", not uppercase */
        font-size: 13.5px;
        font-weight: 700;
        letter-spacing: 0.2px;
        color: var(--text-muted); /* inactive label */
    }

        .rate-tabs .mud-tab .mud-icon-root {
            font-size: 19px; /* inactive icon size — matches prototype (mob 19) */
            color: var(--text-muted);
            margin-right: 8px;
        }

        .rate-tabs .mud-tab.mud-tab-active,
        .rate-tabs .mud-tab.mud-tab-active .mud-icon-root {
            color: var(--tt-rate-accent);
        }
    /* Thin rounded underline inset from the tab edges (prototype: h3, radius 2, inset ~10px). */
    .rate-tabs .mud-tab-slider {
        background: var(--tt-rate-accent) !important;
        height: 3px !important;
        border-radius: 2px;
    }
/* Desktop: slightly larger label/icon, matching the prototype's `wide` SubTabs. */
@media (min-width: 960px) {
    .rate-tabs .mud-tab {
        padding: 15px 8px 16px;
        font-size: 14.5px;
    }

        .rate-tabs .mud-tab .mud-icon-root {
            font-size: 20px;
        }
}
/* Web-mobile only: light-lilac tab plate + left-aligned tabs + Tertiary underline, to match
   the MAUI HistoryPage / RatingsPage tab band (TabHeaderPanel_Background #F2ECF1). */
@media (max-width: 959px) {
    .rate-tabs .mud-tabs-tabbar {
        background: var(--surface-tab-band);
        border-bottom: none;
    }

    .rate-tabs .mud-tabs-tabbar-content {
        justify-content: flex-start;
    }

    .rate-tabs .mud-tab {
        padding: 13px 16px 14px;
    }

        .rate-tabs .mud-tab.mud-tab-active,
        .rate-tabs .mud-tab.mud-tab-active .mud-icon-root {
            color: var(--tt-tertiary);
        }

    .rate-tabs .mud-tab-slider {
        background: var(--tt-tertiary) !important;
    }
}

/* Filters column spacing */
.rate-filters {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-bottom: 18px;
}

/* Search field — thin card border, magnifier on the LEFT (prototype SearchField) */
.rate-search {
    display: flex;
    align-items: center;
    gap: 9px;
    background: var(--surface-card);
    border: 1px solid var(--tt-rate-card-bd);
    border-radius: 10px;
    padding: 10px 14px;
}

.rate-search-icon {
    display: inline-flex;
    flex-shrink: 0;
}

.rate-search-input {
    flex: 1;
    border: none;
    outline: none;
    background: none;
    font-family: var(--tt-font-family);
    font-size: 15px;
    color: var(--tt-rate-ink);
    min-width: 0;
}

    .rate-search-input::placeholder {
        color: var(--text-muted);
    }

.rate-search-clear {
    border: none;
    background: none;
    cursor: pointer;
    color: var(--text-disabled);
    display: flex;
    padding: 2px;
}

.rate-found {
    font-size: 14px;
    color: var(--text-muted);
}

/* Mobile: tighter vertical rhythm (matches the prototype's compact mobile shell).
   Placed AFTER the base rules so equal-specificity mobile overrides win. */
@media (max-width: 959px) {
    .rate-filters {
        gap: 12px;
        margin-bottom: 12px;
    }

    .rate-search {
        padding: 9px 12px;
    }
    /* Inset the panel content on mobile (the host no longer pads). The tab bar sits above the
       panels and stays full-bleed; only the filters + list get the 14px side gutter (prototype
       PlayersContent padding 12×14). Top padding trimmed so filters sit close under the tabs. */
    .rate-tabs > .mud-tabs-panels {
        padding: 12px 14px 0 !important;
    }

    /* Rows: mobile metrics from the prototype (padding 11×14, gap 11, pos 24, name 15). */
    .rate-row {
        padding: 11px 14px;
        gap: 11px;
    }

    .rate-row-pos {
        min-width: 24px;
        font-size: 14px;
    }

    .rate-row-name {
        font-size: 15px;
    }

    .rate-row-rating {
        font-size: 15px;
    }
}

/* Sort segment + distance on ONE row */
.rate-controls-row {
    display: flex;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
}

/* Sort segment (By rating / Near me) — sunken track, white active pill, red label */
.rate-seg {
    display: inline-flex;
    background: var(--tt-rate-sunk);
    border-radius: 9px;
    padding: 3px;
    gap: 2px;
    flex-shrink: 0;
}

.rate-seg-btn {
    border: none;
    border-radius: 7px;
    text-transform: none;
    font-family: var(--tt-font-family);
    font-size: 13.5px;
    font-weight: 600;
    padding: 6px 14px;
    color: var(--text-secondary);
    background: transparent;
    cursor: pointer;
    white-space: nowrap;
    transition: color .12s, background .12s;
}

.rate-seg-btn--on {
    background: var(--surface-card);
    color: var(--tt-rate-accent);
    font-weight: 700;
    box-shadow: 0 1px 2px rgba(0,0,0,0.08);
}

/* Distance control — inline with the segment */
.rate-dist-control {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: 1;
    min-width: 260px;
    max-width: 420px;
}

.rate-dist-label {
    font-size: 14px;
    color: var(--neutral-mid);
    flex-shrink: 0;
}
/* Fixed width (not just min-width): the label text changes as you drag the slider ("1000 km" ↔
   "all players"); a constant box keeps the slider's flex space stable so it doesn't resize mid-drag. */
.rate-dist-value {
    font-size: 14px;
    font-weight: 700;
    color: var(--tt-rate-accent);
    flex-shrink: 0;
    width: 92px;
    text-align: right;
    white-space: nowrap;
}
/* Distance slider — red accent, fixed height so dragging the thumb doesn't reflow the row.
   MudSlider grows its box while pressed (thumb scale + value popover); pin the height and clip. */
.rate-slider {
    margin: 0 !important;
    padding: 0 !important;
    height: 24px !important;
    min-height: 24px !important;
    display: flex !important;
    align-items: center !important;
}

    .rate-slider .mud-slider-track-filled,
    .rate-slider .mud-slider-thumb {
        color: var(--tt-rate-accent) !important;
    }
        /* Keep the thumb from enlarging the track box on press (no layout shift). */
        .rate-slider .mud-slider-thumb::before,
        .rate-slider .mud-slider-thumb::after {
            display: none !important;
        }

    .rate-slider input[type="range"] {
        margin: 0 !important;
    }

/* Interval chips (Day…All) */
.rate-chips .mud-chip {
    border-radius: 999px;
    font-weight: 500;
    font-size: 13.5px;
    border: 1px solid var(--tt-rate-card-bd);
    background: var(--surface-card);
    color: var(--text-secondary);
}

    .rate-chips .mud-chip.mud-chip-selected {
        border-color: var(--tt-rate-accent);
        background: var(--tt-rate-accent-soft);
        color: var(--tt-rate-accent);
        font-weight: 700;
    }

/* Self-rank link ("You are in N place.") — bars icon + red underlined link */
.rate-selfrank {
    font-size: 14px;
    color: var(--neutral-mid);
    display: flex;
    align-items: center;
    gap: 6px;
}

.rate-selfrank-icon {
    display: inline-flex;
    flex-shrink: 0;
}

.rate-selfrank-link {
    color: var(--tt-rate-accent);
    font-weight: 700;
    border-bottom: 1px solid var(--tt-rate-accent);
    cursor: pointer;
}

/* ── Unified rows as cards ─────────────────────────────────────────────── */
.rate-row {
    display: flex;
    align-items: center;
    gap: 14px;
    background: var(--tt-rate-card-bg);
    border: 1px solid var(--tt-rate-card-bd);
    border-radius: 12px;
    padding: 13px 16px;
    margin-bottom: 8px;
    cursor: pointer;
    transition: border-color .12s, background .12s;
}

    .rate-row:hover {
        border-color: var(--border-card-warm);
    }

.rate-row--selected {
    border-color: var(--tt-rate-accent);
    background: var(--surface-card);
}

/* Rank number */
.rate-row-pos {
    min-width: 30px;
    text-align: right;
    color: var(--tt-rate-muted);
    font-size: 15px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

/* Middle block */
.rate-row-main {
    min-width: 0;
    flex: 1;
}

.rate-row-nameline {
    display: flex;
    align-items: center;
    gap: 6px;
    line-height: 1.25;
}

.rate-row-name {
    font-size: 15.5px;
    font-weight: 600;
    color: var(--tt-rate-ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rate-row-handle {
    font-size: 13.5px;
    font-style: italic;
    color: var(--tt-rate-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.rate-row-sub {
    font-size: 12.5px;
    color: var(--text-muted);
    margin-top: 2px;
    font-variant-numeric: tabular-nums;
}

    .rate-row-sub b {
        font-weight: 700;
        color: var(--neutral-mid);
    }
/* Geo two-hand sub-lines: "right R · games: G" / "(left) R · games: G" (prototype PlayerRow). */
.rate-row-sub-lines {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.rate-hand-prefix {
    color: var(--text-muted);
}

/* Non-playing hand markers (ranking rows): accent "*" beside the name, caption underneath. */
.rate-row-weak-star {
    color: var(--tt-rate-accent);
    font-weight: 700;
    font-size: 15px;
    line-height: 1;
    flex-shrink: 0;
}

.rate-row-weak-cap {
    font-size: 12px;
    font-style: italic;
    color: var(--tt-rate-muted);
    margin-top: 1px;
}

/* Chat games wording swaps by width: long "Registered games:" on desktop (WebChats),
   compact "Games:" on mobile (ChatRow). Both spans are rendered; CSS shows one per breakpoint. */
.rate-chat-games--short {
    display: none;
}

@media (max-width: 959px) {
    .rate-chat-games--full {
        display: none;
    }

    .rate-chat-games--short {
        display: inline;
    }
}

/* Right block — ranking layout (rating big) */
.rate-row-right {
    text-align: right;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
}

.rate-row-rating {
    font-size: 15.5px;
    font-weight: 700;
    color: var(--tt-rate-ink);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.2px;
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
}

    .rate-row-rating .unit {
        font-size: 11.5px;
        font-weight: 600;
        color: var(--tt-rate-sub);
        letter-spacing: 0;
    }

.rate-row-games {
    font-size: 12.5px;
    color: var(--tt-rate-sub);
    font-variant-numeric: tabular-nums;
}

/* Delta (bracket style) */
.rate-delta {
    font-weight: 700;
    font-size: 13.5px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.rate-delta--up {
    color: var(--tt-rate-delta-up);
}

.rate-delta--down {
    color: var(--tt-rate-delta-down);
}

.rate-delta--flat {
    color: var(--tt-rate-delta-flat);
}

/* Right block — geo layout (distance big, warm maroon) */
.rate-row-dist {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    color: var(--tt-rate-dist);
    font-size: 15px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.rate-dist-pin {
    display: inline-flex;
    width: 15px;
    height: 15px;
    border-radius: 8px;
    background: var(--tt-rate-dist-pin);
    align-items: center;
    justify-content: center;
    color: var(--text-on-accent);
}
/* Geo player-row distance: warm brown, no pin (prototype PlayerRow). Chats keep the maroon Dist + pin. */
.rate-row-dist--geo {
    color: var(--tt-settings-accent-dark);
}

/* "you" badge */
.rate-you-badge {
    font-size: 11px;
    font-weight: 700;
    color: var(--tt-rate-accent);
    background: var(--tt-rate-accent-soft);
    padding: 1px 7px;
    border-radius: 4px;
    flex-shrink: 0;
}

/* Status markers */
.rate-inactive-icon {
    color: var(--tt-rate-inactive);
    display: inline-flex;
    flex-shrink: 0;
}

.rate-nodm-icon {
    color: var(--tt-rate-nodm);
    display: inline-flex;
    flex-shrink: 0;
}

.rate-lock-icon {
    color: var(--tt-rate-lock);
    display: inline-flex;
    flex-shrink: 0;
}

/* Chevron (card affordance) */
.rate-chevron {
    color: var(--border-separator);
    flex-shrink: 0;
    display: flex;
    margin-left: 2px;
}

/* ── Chat row ──────────────────────────────────────────────────────────── */
.rate-chat-icon {
    width: 44px;
    height: 44px;
    border-radius: 11px;
    background: var(--tint-tg-soft);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    color: var(--tt-rate-tg);
}

/* Empty state */
.rate-empty {
    text-align: center;
    color: var(--tt-rate-sub);
    font-size: 15px;
    padding: 60px 30px;
}

/* Chat top header */
.rate-chattop-title {
    font-size: 24px;
    font-weight: 700;
    color: var(--tt-rate-ink);
    letter-spacing: -0.3px;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rate-chattop-sub {
    font-size: 13px;
    color: var(--text-muted);
    margin-top: 2px;
}

.rate-back-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--tt-rate-accent);
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    background: none;
    border: none;
    padding: 0;
}

/* Chat input bar sticks to the bottom of the viewport while scrolling */
.chat-input-sticky {
    position: sticky;
    bottom: 0;
    background-color: var(--tt-page-bg);
    z-index: 10;
    padding-bottom: 8px;
}

/* Dark mode intentionally disabled */

/* On mobile, account for the bottom navigation bar */
@media (max-width: 959px) {
    .chat-input-sticky {
        bottom: var(--tt-bottomnav-height);
    }
}

.score-input .mud-input-root {
    text-align: center;
    font-size: 2rem !important;
    font-weight: bold;
}

/* ===== Unified page content width & left alignment =====
   Every non-login page renders inside <MudMainContent class="tt-main-content-left-aligned">.
   Pages wrap their body in <MudContainer MaxWidth="Large"> (1280px, margin:auto centered) or,
   for the profile, in .tt-settings-page (already 860px). We normalize both so all content shares
   one max-width (860px — the profile's width) and is pinned to the LEFT edge (against the drawer),
   instead of MudBlazor's default centering that leaves large side gutters on wide screens.
   The drawer still offsets the whole main-content area by its width (margin-left on .mud-main-content),
   so "left edge" here means flush against the side menu. */
.mud-main-content.tt-main-content-left-aligned .mud-container {
    max-width: 860px;
    margin-left: 0;
    margin-right: auto;
}

/* ===== Settings/profile redesign — page + buttons ===== */
.tt-settings-page {
    background: var(--tt-settings-bg);
    max-width: 860px;
    /* Left-aligned (was margin:0 auto) to match the unified layout. */
    margin: 0 auto 0 0;
    padding: 26px 28px 60px;
}

/* Caps label above a section (settings cards, guest-landing teasers, …).
   Shared design element — mirrors MAUI's SectionTitle style. No bottom gap:
   each use-site supplies its own spacing (card wrapper margin / MudGrid spacing). */
.tt-section-title {
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--tt-settings-ink-3);
    padding: 0 4px 0;
}

/* Shared explanatory / helper text — the single style for "here's what will happen" notes across the
   app, so their size doesn't drift page to page. Matches the New Game intro body (0.875rem / 1.5 /
   ink-2). Use it (add the class) instead of hand-rolling a per-page note size. */
.tt-hint-text {
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--tt-settings-ink-2);
}

@media (max-width: 599px) {
    .tt-settings-page {
        padding: 16px 16px 40px;
    }
}

/* Protocol dialog on mobile — EDGE-TO-EDGE full-screen sheet (handoff bracket-protocol screenshot 03). Uses the
   720px breakpoint so it matches the create-form action bar, which goes position:fixed at ≤720px (its scoped
   CreateTournamentPage.razor.css) — the dialog must cover the bar wherever the bar is fixed, else the form's
   Create/Draft buttons still show. Desktop (>720px) keeps the centered MaxWidth.Medium dialog. MudDialog markup
   is global, so these rules live in app.css, not a scoped file. */
@media (max-width: 720px) {
    /* The form action bar is position:fixed z-index:1401 (deliberately above the 1400 bottom nav). The MudBlazor
       dialog container defaults to --mud-zindex-dialog (1400), so WITHOUT this the form bar would sit ON TOP of
       the protocol dialog and its Create/Draft buttons would still show. Raise THIS dialog's container above the
       form bar so the full-screen sheet truly covers it (scoped to the protocol dialog via :has). */
    .mud-dialog-container:has(.mud-dialog.protocol-mud-dialog) {
        z-index: 1402;
    }

    /* Covers the create-form action rail so only the protocol's OWN footer (arrows toggle + close + print) is
       visible, not the form's Create/Draft rail. */
    .mud-dialog.protocol-mud-dialog {
        /* fixed + inset:0 ignores the container's centering/padding so the sheet truly reaches every edge. */
        position: fixed;
        inset: 0;
        width: 100vw;
        max-width: 100vw;
        height: 100dvh;
        max-height: 100dvh;
        margin: 0;
        border-radius: 0;
        display: flex;
        flex-direction: column;
    }

        /* Content grows and scrolls; the action bar stays pinned at the bottom of the sheet. Descendant (not
           child) combinators throughout: MudBlazor nests .mud-dialog-content / .mud-dialog-actions below the
           surface, so `>` would not match. */
        .mud-dialog.protocol-mud-dialog .mud-dialog-content {
            flex: 1 1 auto;
            max-height: none;
            overflow-y: auto;
        }

        .mud-dialog.protocol-mud-dialog .mud-dialog-actions {
            flex: 0 0 auto;
            flex-wrap: wrap;
        }

            /* Mobile (SPEC §3.1): the loser-transitions toggle sits on its OWN full-width row ABOVE the
               [close | print] row. flex-basis:100% forces the wrap; the MudBlazor spacer (class .flex-grow-1,
               NOT .mud-spacer) is collapsed so close + print pair up on the next line. */
            .mud-dialog.protocol-mud-dialog .mud-dialog-actions .proto-arrows-btn {
                flex: 0 0 100%;
                justify-content: center;
            }

            .mud-dialog.protocol-mud-dialog .mud-dialog-actions .flex-grow-1 {
                display: none;
            }

            /* Close + Print share the row below the toggle with DIFFERENT sizes (prototype tour-protocol.jsx:
               Закрыть is `flex:initial` = content-width, «Открыть для печати» is `flex:1` = fills the rest). Equal
               `flex:1 1 0` made print wrap to two lines; sizing it this way keeps both on ONE line, print wide.
               Close is a Variant.Outlined button (.mud-button-outlined) to match the secondary-button style used
               on pages like NewGame — hence the outlined selector here, not .mud-button-text. */
            .mud-dialog.protocol-mud-dialog .mud-dialog-actions .mud-button-outlined {
                flex: 0 0 auto;
            }

            .mud-dialog.protocol-mud-dialog .mud-dialog-actions .mud-button-filled {
                flex: 1 1 auto;
                white-space: nowrap;
            }
}

.tt-settings-primary.mud-button-root {
    height: 50px;
    border-radius: 13px;
    background-color: var(--tt-settings-accent) !important;
    color: var(--text-on-accent) !important;
    font-weight: 700;
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.10);
    text-transform: none;
}

    .tt-settings-primary.mud-button-root:hover {
        background-color: var(--tt-settings-accent-dark) !important;
    }

    .tt-settings-primary.mud-button-root:disabled,
    .tt-settings-primary.mud-button-root.mud-disabled {
        background-color: var(--tt-gray-200) !important;
        color: var(--tt-settings-ink-3) !important;
    }

.tt-settings-ghost.mud-button-root {
    height: 48px;
    border-radius: 13px;
    background-color: var(--surface-card);
    border: 1px solid var(--tt-settings-card-border);
    color: var(--tt-settings-ink);
    font-weight: 600;
    text-transform: none;
}

.tt-settings-ghost-danger.mud-button-root {
    height: 48px;
    border-radius: 13px;
    background-color: var(--surface-card);
    border: 1px solid var(--tt-settings-card-border);
    color: var(--tt-settings-danger);
    font-weight: 600;
    text-transform: none;
}

/* ===== New Game redesign =====
   Warm terracotta concept ported from the MAUI screen. Uses the settings
   accent (--tt-settings-accent #b27c62) as the page's primary tone. The
   --ng-* locals keep the palette in one place. */
.ng-card,
.ng-keepawake,
.ng-intro {
    --ng-terra: var(--tt-settings-accent);
    --ng-terra-dark: var(--tt-settings-accent-dark);
    --ng-ink: var(--tt-settings-ink);
    --ng-ink-2: var(--tt-settings-ink-2);
    --ng-ink-3: var(--tt-settings-ink-3);
    --ng-card-border: var(--tt-settings-card-border);
    --ng-gray-btn: var(--tone-tint-warm-neutral);
}

/* Intro block */
.ng-intro {
    text-align: center;
}

.ng-intro__title {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 300;
    color: var(--tt-settings-ink-2);
    letter-spacing: 0.01em;
}

.ng-intro__lead {
    margin: 6px 0 0;
    font-size: 0.9375rem;
    color: var(--ng-ink-2);
}

.ng-intro__body {
    margin: 12px 0 0;
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--ng-ink-2);
    text-align: left;
}

/* Keep-screen-on row */
.ng-keepawake__hint {
    margin-left: 52px;
    display: block;
}

/* ----- Hand toggle (segmented pill) ----- */
.ng-hand-toggle {
    display: inline-flex;
    gap: 0;
    border-radius: 8px;
    padding: 3px;
    background: var(--tt-settings-pill-neutral-bg, var(--control-track));
    border: 1px solid var(--tt-settings-card-border);
}

.ng-hand-seg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 5px 11px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--tt-settings-ink-3);
    font-size: 0.8125rem;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    transition: all 0.14s ease;
}

.ng-hand-seg--on {
    background: var(--tt-settings-accent);
    color: var(--text-on-accent);
    font-weight: 600;
}

.ng-hand-toggle--ink .ng-hand-seg--on {
    background: var(--tt-settings-ink-2);
}

/* ----- Registration card ----- */
.ng-card {
    position: relative;
    border-radius: 18px;
    border: 1px solid var(--ng-card-border);
    background: var(--tt-settings-card);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
    padding: 16px;
}

.ng-card__close {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    border: none;
    background: transparent;
    color: var(--tt-tertiary);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 1;
}

    .ng-card__close:hover {
        background: var(--tint-danger-hover);
    }

.ng-you-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-bottom: 4px;
}

.ng-you-label {
    font-size: 1rem;
    font-weight: 600;
    color: var(--ng-ink);
}

.ng-versus {
    text-align: center;
    font-size: 0.8125rem;
    color: var(--ng-ink-3);
    font-style: italic;
    margin: 2px 0 12px;
}

/* Empty-state opponent CTA */
.ng-opp-cta {
    width: 100%;
    height: 56px;
    border-radius: 14px;
    border: none;
    background: var(--ng-terra);
    color: var(--text-on-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.10);
    transition: background 0.14s ease;
}

    .ng-opp-cta:hover {
        background: var(--ng-terra-dark);
    }

/* Selected opponent card */
.ng-opp {
    border-radius: 14px;
    border: 1px solid var(--ng-card-border);
    background: var(--surface-card);
    padding: 12px;
}

.ng-opp__top {
    display: flex;
    align-items: center;
    gap: 12px;
}

.ng-opp__info {
    flex: 1;
    min-width: 0;
}

.ng-opp__name {
    font-size: 1rem;
    font-weight: 700;
    color: var(--ng-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ng-opp__meta {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 2px;
}

.ng-opp__rating {
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--ng-terra);
    font-variant-numeric: tabular-nums;
}

.ng-opp__unit {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--ng-ink-3);
}

.ng-opp__dot {
    color: var(--ng-ink-3);
}

.ng-opp__games {
    font-size: 0.8125rem;
    color: var(--ng-ink-3);
}

.ng-opp__hand {
    margin-top: 11px;
}

.ng-opp__swap {
    flex-shrink: 0;
    width: 44px;
    height: 44px;
    border-radius: 12px;
    border: none;
    background: var(--ng-terra);
    color: var(--text-on-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.10);
    transition: background 0.14s ease;
}

    .ng-opp__swap:hover {
        background: var(--ng-terra-dark);
    }

/* ----- Score steppers ----- */
.ng-score {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-top: 16px;
}

.ng-score__col {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: center;
}

.ng-score__colon {
    align-self: center;
    margin-top: 60px;
    font-size: 1.875rem;
    font-weight: 300;
    color: var(--ng-ink-3);
}

.ng-step {
    height: 62px;
    width: 100%;
    border-radius: 14px;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: filter 0.12s ease, transform 0.08s ease;
}

    .ng-step:active {
        transform: scale(0.97);
    }

.ng-step--plus {
    background: var(--ng-terra);
    color: var(--text-on-accent);
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.10);
}

    .ng-step--plus:hover {
        filter: brightness(0.96);
    }

.ng-step--minus {
    background: var(--ng-gray-btn);
    color: var(--ng-ink-2);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.04);
}

    .ng-step--plus .mud-icon-root,
    .ng-step--minus .mud-icon-root {
        font-size: 26px;
    }

.ng-score__value {
    height: 70px;
    width: 100%;
    border-radius: 14px;
    background: var(--surface-card);
    border: 1px solid var(--ng-card-border);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 2.75rem;
    font-weight: 700;
    color: var(--ng-ink);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.ng-score__label {
    font-size: 0.78rem;
    color: var(--ng-ink-3);
    font-weight: 500;
    margin-top: 1px;
    text-align: center;
}

/* ----- Common chat row ----- */
.ng-chat {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--ng-card-border);
}

.ng-chat__title {
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--ng-ink);
    margin-bottom: 8px;
}

.ng-chat__empty {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 12px;
    border: 1px solid var(--ng-card-border);
    background: var(--surface-card);
    font-size: 0.84rem;
    color: var(--ng-ink-3);
    font-style: italic;
}

.ng-chat__empty-icon {
    color: var(--tt-settings-tg-blue);
    flex-shrink: 0;
}

/* Bordered tap-row chat picker (replaces the dropdown field) */
.ng-chat__menu {
    width: 100%;
    display: block;
}

    .ng-chat__menu .mud-menu-activator {
        width: 100%;
    }

.ng-chat__row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 12px;
    border-radius: 12px;
    border: 1px solid var(--ng-card-border, var(--tt-settings-card-border));
    background: var(--surface-card);
    cursor: pointer;
    box-sizing: border-box;
}

.ng-chat__row-icon {
    color: var(--tt-settings-tg-blue);
    flex-shrink: 0;
}

.ng-chat__row-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.84rem;
    color: var(--tt-settings-ink);
}

.ng-chat__row-chevron {
    color: var(--tt-settings-ink-3);
    flex-shrink: 0;
}

/* ============================ Login redesign ============================
   High-fidelity element styles for the 5 login screens (prototype aa-auth.jsx).
   Structural chrome (topbar / hero band / centered column) lives in
   Components/LoginScreen.razor.css; these are the inner elements pages compose. */

.login-wordmark {
    font-weight: 800;
    letter-spacing: 1px;
    color: var(--tt-tertiary-soft);
    text-align: center;
    line-height: 1.1;
}

    .login-wordmark.lg {
        font-size: 42px;
    }

    .login-wordmark.sm {
        font-size: 32px;
    }

.login-tagline {
    font-size: 15px;
    font-weight: 600;
    color: var(--tt-settings-ink);
    text-align: center;
    margin-top: 8px;
    line-height: 1.35;
}

.login-title {
    font-size: 22px;
    font-weight: 700;
    color: var(--tt-game-text-name);
    text-align: center;
}

.login-prompt {
    font-size: 14px;
    line-height: 1.5;
    color: var(--tt-game-text-secondary);
    text-align: center;
    max-width: 330px;
    margin: 7px auto 0;
}

/* Field: white, radius 11, 1.5px border, 50 high, icon left, optional eye right. */
.login-field {
    position: relative;
    display: flex;
    align-items: center;
    height: 50px;
    border-radius: 11px;
    border: 1.5px solid var(--tt-game-card-separator);
    background: var(--tt-white);
    padding: 0 14px;
    box-sizing: border-box;
}

    .login-field:focus-within {
        border-color: var(--tt-settings-accent);
        box-shadow: 0 0 0 3px var(--tint-clay-soft);
    }

    .login-field .login-field-icon {
        color: var(--tt-gray-300);
        display: flex;
        flex-shrink: 0;
    }

    .login-field input {
        flex: 1;
        border: none;
        outline: none;
        background: transparent;
        font-family: var(--tt-font-family);
        font-size: 15px;
        color: var(--tt-game-text-name);
        margin-left: 10px;
        min-width: 0;
    }

        .login-field input::placeholder {
            color: var(--tt-gray-300);
        }

    .login-field .login-eye {
        background: none;
        border: none;
        cursor: pointer;
        color: var(--tt-game-text-muted);
        padding: 6px;
        display: flex;
        flex-shrink: 0;
    }

.login-field-label {
    display: block;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--tt-game-text-secondary);
    margin: 0 0 6px 2px;
}

/* Buttons. */
.login-btn {
    width: 100%;
    min-height: 50px;
    border-radius: 11px;
    font-family: var(--tt-font-family);
    font-size: 15.5px;
    font-weight: 700;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    border: 1.5px solid transparent;
    padding: 0 16px;
    /* Some login buttons render as <a> (navigation before WASM hydration); the -primary/-secondary
       variants set an explicit color, so only the default link underline needs removing. */
    text-decoration: none;
}

    .login-btn:disabled {
        opacity: 0.5;
        cursor: default;
    }

.login-btn-primary {
    background: var(--tt-settings-accent);
    color: var(--tt-white);
    border-color: var(--tt-settings-accent);
}

.login-btn-tg {
    background: var(--tt-settings-tg-blue);
    color: var(--tt-white);
    border-color: var(--tt-settings-tg-blue);
}

.login-btn-secondary {
    background: var(--tt-white);
    color: var(--tt-settings-ink);
    border-color: var(--tt-settings-card-border);
    font-weight: 600;
}
/* Auth-method row: icon in a white circle + centered label (brand colors stay readable on terracotta). */
.login-btn-method {
    min-height: 52px;
    position: relative;
    padding: 0 14px;
}

.login-method-icon {
    width: 28px;
    height: 28px;
    border-radius: 14px;
    background: var(--tt-white);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    position: absolute;
    left: 14px;
}

    .login-method-icon.tg {
        background: var(--tt-settings-tg-blue);
    }

    .login-method-icon img {
        width: 18px;
        height: 18px;
    }

.login-method-label {
    flex: 1;
    text-align: center;
}

/* Inline link (clay-dark, weight 700). */
.login-link {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--tt-settings-accent-dark);
    font-family: var(--tt-font-family);
    font-weight: 700;
    font-size: 13.5px;
    padding: 0;
    text-decoration: none;
}

    .login-link:hover {
        text-decoration: underline;
    }

/* Unconfirmed-email / generic alert plate. */
.login-alert {
    background: var(--tt-alert-error-bg);
    border: 1px solid var(--tt-alert-error-border);
    border-radius: 10px;
    padding: 11px 13px;
}

.login-alert-text {
    font-size: 13px;
    color: var(--tt-alert-error-text);
    line-height: 1.45;
}

/* Centered icon state block (check-email / sent). */
.login-state-icon {
    width: 72px;
    height: 72px;
    border-radius: 36px;
    background: var(--tint-clay-soft);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--tt-settings-accent-dark);
    margin: 0 auto 16px;
}

    .login-state-icon.tg {
        background: var(--tint-tg-soft);
        color: var(--tt-settings-tg-blue);
    }

/* Footer divider + privacy link. */
.login-divider {
    height: 1px;
    background: var(--tt-game-card-separator);
    margin: 22px 0 14px;
}

.login-privacy {
    display: block;
    text-align: center;
    font-size: 12.5px;
    color: var(--tt-game-text-muted);
    text-decoration: underline;
}

/* Login pages render inside MainLayout: drop the default content padding/centering so the
   hero band can span the full content width and the column centers itself. */
.mud-main-content.tt-main-content-left-aligned:has(.login-screen) {
    padding-left: 0;
    padding-right: 0;
}

/* Monochrome SVG icons rendered as CSS masks so they inherit currentColor (an <img>
   cannot). Used for Material Symbols glyphs missing from MudBlazor's icon set, so
   active/hover colours match the neighbouring MudIcons. Size matches MudIcon medium (24px). */
.tt-mask-icon {
    display: inline-block;
    width: 24px;
    height: 24px;
    background-color: currentColor;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
}

.tt-mask-icon--new-game {
    -webkit-mask-image: url('../images/new_game.svg');
    mask-image: url('../images/new_game.svg');
}

/* ============================================================================
   Home dashboard (authorized) — progress widgets (handoff "Главная / Dashboard" §6).
   One component set for both heads; the web grid is two columns and collapses to
   one on the phone. minmax(0,1fr) is REQUIRED — without it the achievements row and
   the heatmap force a horizontal overflow.
   ============================================================================ */
.dash-page {
    background: var(--surface-page);
    min-height: 100%;
}

.dash-page__inner {
    max-width: 960px;
    margin: 0 auto;
    padding: 26px 24px 40px;
}

.dash-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

/* Header */
.dash-header {
    margin-bottom: 4px;
}

.dash-header__line {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.dash-header__greeting {
    font-size: 24px;
    font-weight: 800;
    color: var(--text-primary);
}

.dash-header__subtitle {
    font-size: 13.5px;
    color: var(--text-muted);
    margin: 4px 0 16px;
}

.dash-streak-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: var(--status-win-tint);
    color: var(--status-win);
    font-size: 12.5px;
    font-weight: 700;
    padding: 3px 9px;
    border-radius: 999px;
}

.dash-streak-badge__icon {
    font-size: 14px !important;
    width: 14px !important;
    height: 14px !important;
    color: var(--status-win) !important;
}

/* Base card (DCard) */
.dash-card {
    background: var(--surface-card);
    border: 1px solid var(--border-card);
    border-radius: 15px;
    padding: 15px;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.dash-card--wide {
    grid-column: 1 / -1;
}

.dash-card__head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
}

.dash-card__title {
    font-size: 14.5px;
    font-weight: 700;
    color: var(--text-primary);
}

.dash-skel {
    border-radius: 15px !important;
}

/* Shared bits */
.dash-kicker {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: #a0a0a0;
}

.dash-kicker--clay {
    color: var(--action-primary-pressed);
}

.dash-link {
    background: none;
    border: none;
    color: var(--action-primary-pressed);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    padding: 0;
    font-family: inherit;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.dash-chip {
    font-weight: 700;
    font-size: 13px;
    padding: 4px 10px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-variant-numeric: tabular-nums;
}

.dash-chip__icon {
    font-size: 14px !important;
    width: 14px !important;
    height: 14px !important;
    color: inherit !important;
}

/* Segment control (Week/Month/Year) */
.dash-seg {
    display: flex;
    background: #efeae4;
    border-radius: 9px;
    padding: 3px;
    gap: 2px;
}

.dash-seg__btn {
    border: none;
    background: transparent;
    color: #8a7f75;
    font-weight: 700;
    font-size: 12.5px;
    padding: 6px 12px;
    border-radius: 7px;
    cursor: pointer;
    font-family: inherit;
}

.dash-seg__btn--on {
    background: #fff;
    color: var(--action-primary-pressed);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}

/* Widget 1 — Rating */
.dash-rating__top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
}

.dash-rating__figure {
    display: flex;
    align-items: flex-end;
    gap: 12px;
    margin-top: 8px;
    flex-wrap: wrap;
}

.dash-rating__value {
    font-size: 46px;
    font-weight: 800;
    color: var(--text-primary);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.dash-rating__unit {
    font-size: 16px;
    font-weight: 600;
    color: var(--text-muted);
    align-self: flex-end;
    margin-bottom: 2px;
}

.dash-rating__rankpill {
    background: var(--tint-clay-soft);
    color: var(--action-primary-pressed);
    font-weight: 700;
    font-size: 13px;
    padding: 4px 11px;
    border-radius: 999px;
    margin-bottom: 7px;
}

.dash-rating__spacer {
    flex: 1;
}

.dash-rating__record {
    font-size: 12.5px;
    color: var(--text-muted);
    margin-bottom: 5px;
    display: flex;
    align-items: center;
    gap: 5px;
    font-variant-numeric: tabular-nums;
}

.dash-rating__record-icon {
    font-size: 14px !important;
    width: 14px !important;
    height: 14px !important;
    color: var(--action-primary-pressed) !important;
}

.dash-rating__deltarow {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-top: 12px;
    flex-wrap: wrap;
}

.dash-rating__gamesnote {
    font-size: 12.5px;
    color: var(--text-muted);
}

.dash-rating__spark {
    margin-top: 12px;
    height: 60px;
}

/* Widget 2 — Quick actions */
.dash-quick {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: row;
    gap: 10px;
}

.dash-quick__btn {
    flex: 1;
}

/* Widget 3 — Stats donut */
.dash-stats__top {
    display: flex;
    gap: 16px;
    align-items: center;
}

.dash-donut {
    width: 94px;
    height: 94px;
    border-radius: 50%;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.dash-donut__core {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.dash-donut__pct {
    font-size: 22px;
    font-weight: 800;
    color: var(--text-primary);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.dash-donut__label {
    font-size: 10px;
    color: #a0a0a0;
    font-weight: 600;
}

.dash-stats__legend {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
}

.dash-stats__row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.dash-stats__marker {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    flex-shrink: 0;
}

.dash-stats__name {
    font-size: 13px;
    color: #7a7a7a;
    flex: 1;
}

.dash-stats__val {
    font-size: 14px;
    font-weight: 700;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.dash-stats__tiles {
    display: flex;
    gap: 10px;
    margin-top: 14px;
}

.dash-tile {
    flex: 1;
    border-radius: 10px;
    padding: 9px 11px;
    min-width: 0;
}

.dash-tile--win {
    background: var(--status-win-tint);
}

.dash-tile--sunk {
    background: var(--control-track);
}

.dash-tile__label {
    font-size: 11.5px;
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: 4px;
    color: #8a8a8a;
}

.dash-tile--win .dash-tile__label {
    color: var(--status-win);
}

.dash-tile__icon {
    font-size: 14px !important;
    width: 14px !important;
    height: 14px !important;
    color: var(--status-win) !important;
}

.dash-tile__value {
    font-size: 16.5px;
    font-weight: 800;
    color: var(--text-primary);
    margin-top: 2px;
}

/* Widget 4 — Rank progress */
.dash-rank__labels {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    margin-bottom: 8px;
}

.dash-rank__current {
    font-size: 14px;
    font-weight: 700;
    color: var(--action-primary-pressed);
}

.dash-rank__next {
    font-size: 14px;
    font-weight: 700;
    color: #b0b0b0;
}

.dash-rank__track {
    height: 12px;
    border-radius: 6px;
    background: #efeae4;
    overflow: hidden;
}

.dash-rank__fill {
    height: 100%;
    background: linear-gradient(90deg, var(--action-primary), var(--action-primary-pressed));
    border-radius: 6px;
}

.dash-rank__figures {
    display: flex;
    justify-content: space-between;
    margin-top: 8px;
}

.dash-rank__progress {
    font-size: 12.5px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.dash-rank__remaining {
    font-size: 13px;
    font-weight: 700;
    color: var(--text-primary);
}

.dash-rank__pace {
    font-size: 12px;
    color: #a0a0a0;
    margin-top: 10px;
    line-height: 1.45;
}

/* Widget 6 — Quips */
.dash-quip {
    background: linear-gradient(135deg, #fbf5ef, #f6efe6);
    border-color: var(--tint-clay-border);
}

.dash-quip__head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
    gap: 8px;
}

.dash-quip__more-icon {
    font-size: 14px !important;
    width: 14px !important;
    height: 14px !important;
    color: var(--action-primary-pressed) !important;
}

.dash-quip__body {
    display: flex;
    gap: 13px;
    align-items: flex-start;
    flex: 1;
}

.dash-quip__emoji {
    font-size: 30px;
    line-height: 1;
}

.dash-quip__text {
    font-size: 15.5px;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.45;
    flex: 1;
}

/* Widget 7 — Head-to-head */
.dash-h2h__row {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 10px 0;
    cursor: pointer;
    text-align: left;
}

.dash-h2h__row:not(.dash-h2h__row--top) {
    border-top: 1px solid var(--border-hairline);
}

.dash-h2h__body {
    flex: 1;
    min-width: 0;
}

.dash-h2h__name {
    font-size: 14.5px;
    font-weight: 700;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-h2h__tag {
    font-size: 12px;
    font-weight: 700;
    margin-top: 1px;
}

.dash-h2h__right {
    text-align: right;
    flex-shrink: 0;
}

.dash-h2h__score {
    font-size: 17px;
    font-weight: 800;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.dash-h2h__meetings {
    font-size: 11px;
    color: #a0a0a0;
}

/* Widget 8 — Recent games */
.dash-recent__row {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 9px 0;
    cursor: pointer;
    text-align: left;
}

.dash-recent__row:not(.dash-recent__row--top) {
    border-top: 1px solid var(--border-hairline);
}

.dash-recent__body {
    flex: 1;
    min-width: 0;
}

.dash-recent__name {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dash-recent__date {
    font-size: 12px;
    color: #a0a0a0;
}

.dash-recent__right {
    text-align: right;
    flex-shrink: 0;
}

.dash-recent__score {
    font-weight: 700;
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}

.dash-recent__delta {
    font-size: 12px;
    font-weight: 700;
}

/* Widget 9 — Nearest tournament */
.dash-tour {
    display: flex;
    gap: 13px;
    width: 100%;
    cursor: pointer;
    text-align: left;
}

.dash-tour__body {
    flex: 1;
    min-width: 0;
}

.dash-tour__name {
    font-size: 15px;
    font-weight: 700;
    color: var(--text-primary);
}

.dash-tour__meta {
    font-size: 12.5px;
    color: #8a8a8a;
    margin-top: 3px;
}

.dash-tour__badge {
    margin-top: 8px;
}

/* Widget 10 — Activity heatmap */
.dash-heatmap {
    display: grid;
    grid-template-columns: repeat(52, 1fr);
    grid-template-rows: repeat(7, 1fr);
    grid-auto-flow: column;
    gap: 2px;
    aspect-ratio: 52 / 7;
}

.dash-heatmap__cell {
    border-radius: 2px;
}

.dash-heatmap__legend {
    display: flex;
    align-items: center;
    gap: 5px;
    justify-content: flex-end;
    margin-top: 10px;
    font-size: 11.5px;
    color: #a0a0a0;
}

.dash-heatmap__key {
    width: 11px;
    height: 11px;
    border-radius: 2px;
    display: inline-block;
}

.dash-heatmap__summary {
    font-size: 12.5px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

/* Newbie empty state + error */
.dash-newbie {
    align-items: flex-start;
    text-align: left;
}

.dash-newbie__title {
    font-size: 16px;
    font-weight: 700;
    color: var(--text-primary);
}

.dash-newbie__text {
    font-size: 13.5px;
    color: var(--text-secondary);
    margin-top: 6px;
    line-height: 1.5;
}

.dash-newbie__hint {
    font-size: 12.5px;
    color: var(--text-muted);
    margin-top: 10px;
}

.dash-error {
    background: var(--surface-card);
    border: 1px solid var(--border-card);
    border-radius: 15px;
    padding: 24px;
    text-align: center;
    color: var(--text-secondary);
}

/* Responsive: one column on the phone, tighter padding, stacked quick actions (~720px break) */
@media (max-width: 720px) {
    .dash-page__inner {
        padding: 16px 14px 30px;
    }

    .dash-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .dash-header__greeting {
        font-size: 20px;
    }

    .dash-quick {
        flex-direction: column;
    }
}
