/* MyPokéSpace design system, "Scorecard".
 *
 * Linked from the root layout on every page. Everything is scoped under
 * the `.mps` class, which the layout puts on <body>.
 *
 * What this file does:
 *   1. Re-points the app's existing tokens (globals.css: --bg, --surface,
 *      --text, --brand, --link, --success, --result-*, --chart-*, …) at the
 *      design palette, so every legacy page on beta picks up the new
 *      colours without a rewrite. The design's own token names (--accent,
 *      --win-solid, --heat-*, --series-*, --s-*, --r-*, --e1…) are added
 *      alongside.
 *   2. Ships the design's component classes (.card, .composer, .stat, .row,
 *      .chip, .badge, .btn-*, .seg, .tag, .sprite-pair, t-* type, result
 *      marks/pips/tints, .nav-top, .tabbar, …) for the page agents. See
 *      apps/web/src/components/beta/README.md for the catalogue.
 *
 * Theme: follows <html data-theme> exactly like globals.css (and falls back
 * to prefers-color-scheme when data-theme is absent). The two dark blocks
 * below MUST stay identical.
 *
 * Pro result colours: solids read var(--match-win, var(--win-solid)) at the
 * consumer (the --match-* vars are set inline on a wrapper by
 * lib/match-colors.ts). For derived tints/lines/inks as well, wrap the page
 * in betaResultColorVars(profile) from lib/beta-result-colors.ts.
 *
 * Deliberately NOT copied from the design's mps.css: its element resets
 * (`.mps a { color }`, `.mps h1…p { margin: 0 }`, `.mps *` box-sizing), which
 * would restyle every legacy page on beta. The t-* classes zero their own
 * margins instead, and --link carries the accent. */

/* ===================================================================
 * 1. Tokens
 * =================================================================== */

.mps {
  color-scheme: light;
  /* ground */
  --bg: #f6f5f2;
  --surface: #ffffff;
  --surface-2: #efede8;
  --surface-3: #e5e2db;
  --border: #dcd8cf;
  --border-strong: #c4bfb3;
  /* ink */
  --text: #1b1a20;
  --text-muted: #5f5c6b;
  --text-faint: #8a8794;
  /* action */
  --primary: #1b1a20;
  --primary-hover: #34323d;
  --primary-ink: #ffffff;
  --accent: #4b3fc4;
  --accent-ink: #ffffff;
  --accent-soft: #ebe9fb;
  /* "Poké" in the wordmark (lib/brand-mark POKE_TEXT_RED): 5.2:1 */
  --poke-ink: #d61a1a;
  /* results — the three solids are what a Pro trainer overrides */
  --win-solid: #15795f;
  --win-ink: #0c6450;
  --win-tint: #dff1ea;
  --win-line: #b9dccf;
  --loss-solid: #b8461f;
  --loss-ink: #9c3516;
  --loss-tint: #fbe7e1;
  --loss-line: #f0c6b9;
  --tie-solid: #8a6a1c;
  --tie-ink: #6f5110;
  --tie-tint: #f5ecd3;
  --tie-line: #e3d3a4;
  --on-solid: #ffffff;
  /* matchup heat scale: underdog … even … favoured */
  --heat-n3: #e9a48f;
  --heat-n2: #f3c7b9;
  --heat-n1: #f9e2da;
  --heat-0: #efede8;
  --heat-p1: #d6ece4;
  --heat-p2: #a9d8c6;
  --heat-p3: #6fbfa3;
  --heat-ink: #1b1a20;
  /* chart series, fixed order, never cycled */
  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-4: #eda100;
  --series-5: #e87ba4;
  --series-6: #008300;
  --series-7: #4a3aa7;
  --series-other: #8a8794;
  --grid: #e5e2db;
  /* elevation */
  --e1: 0 1px 2px rgba(27, 26, 32, 0.06);
  --e2: 0 8px 24px rgba(27, 26, 32, 0.10), 0 1px 2px rgba(27, 26, 32, 0.06);
  --e3: 0 24px 64px rgba(27, 26, 32, 0.18);
  --scrim: rgba(27, 26, 32, 0.45);

  /* scale (theme-independent) */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 20px;
  --s-6: 24px;
  --s-8: 32px;
  --s-10: 40px;
  --s-12: 48px;
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 20px;
  --r-pill: 999px;
  /* Control height: ONE value for every form control that can share a row
   * with another — .input, .select, the custom Select (.sel), .picker,
   * date/time inputs, .seg used as a field, .btn next to them. The compact
   * size is for toolbars/filters (.btn-sm, .chip, .seg-sm). Page-local
   * stylesheets (bt.css, relaunch-styles, the events/meta CSS modules) read
   * these same two vars (with a 44/36 fallback outside .mps). */
  --control-h: 44px;
  --control-h-sm: 36px;
  /* Horizontal inset: ONE scale for every beta page. --gutter is the page's
   * side margin (also the nav bar's, so the wordmark lines up with the
   * content); --card-pad is the padding inside a card / composer; --row-pad-x
   * is the side padding of a list row that has its own tint or border (a
   * plain divider row inside a card gets none). Page-local stylesheets
   * (bt.css, relaunch-styles, the events/meta CSS modules) read these with a
   * desktop fallback outside .mps. They step down below 1024 and 600 in the
   * two media rules right after this block. */
  --gutter: 32px;
  --card-pad: 20px;
  --row-pad-x: 14px;
  --font-display: "Bricolage Grotesque", "Avenir Next", "Segoe UI", system-ui, sans-serif;
  --font-body: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-pixel: "Press Start 2P", ui-monospace, monospace;

  /* ---- the app's existing tokens (globals.css), re-pointed ----
   * var() references resolve on this element, so the dark blocks only
   * need to redefine the design tokens above. */
  --font-sans: var(--font-body);
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --brand: var(--primary);
  --brand-hover: var(--primary-hover);
  --brand-fg: var(--primary-ink);
  --link: var(--accent);
  --focus: var(--accent);
  --success: var(--win-ink);
  --success-bg: var(--win-tint);
  --danger: var(--loss-ink);
  --danger-bg: var(--loss-tint);
  --warning: var(--tie-ink);
  --warning-bg: var(--tie-tint);
  --shadow-sm: var(--e1);
  --shadow-md: var(--e2);
  --shadow-lg: var(--e3);
  --overlay: var(--scrim);
  --chart-1: var(--series-1);
  --chart-2: var(--series-2);
  --chart-3: var(--series-3);
  --chart-4: var(--series-4);
  --chart-5: var(--series-5);
  --chart-6: var(--series-6);
  --chart-7: var(--series-7);
  --chart-other: var(--series-other);
  --result-win: var(--win-solid);
  --result-loss: var(--loss-solid);
  --result-tie: var(--tie-solid);
  --result-tie-report: var(--tie-solid);
  --result-win-fill: var(--win-solid);
  --result-loss-fill: var(--loss-solid);
  --result-tie-fill: var(--tie-solid);
  --result-none-fill: var(--surface-3);
  --result-win-fill-fg: var(--on-solid);
  --result-loss-fill-fg: var(--on-solid);
  --result-tie-fill-fg: var(--on-solid);
  --result-none-fill-fg: var(--text-muted);
  --result-empty: var(--surface-3);
  --result-win-bg: var(--win-tint);
  --result-win-fg: var(--win-ink);
  --result-loss-bg: var(--loss-tint);
  --result-loss-fg: var(--loss-ink);
  --result-tie-bg: var(--tie-tint);
  --result-tie-fg: var(--tie-ink);
  --badge-live-bg: var(--win-tint);
  --badge-live-fg: var(--win-ink);
  --badge-warn-bg: var(--tie-tint);
  --badge-warn-fg: var(--tie-ink);

  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}
@media (max-width: 1023px) { .mps { --gutter: 20px; --card-pad: 16px; --row-pad-x: 12px; } }
@media (max-width: 599px) { .mps { --gutter: 12px; --card-pad: 14px; --row-pad-x: 10px; } }

:root[data-theme="dark"] .mps {
  color-scheme: dark;
  --bg: #141318;
  --surface: #1d1c22;
  --surface-2: #27262e;
  --surface-3: #32313b;
  --border: #2f2e38;
  --border-strong: #45434f;
  --text: #eceaf2;
  --text-muted: #a6a3b3;
  --text-faint: #6f6c7a;
  --primary: #eceaf2;
  --primary-hover: #ffffff;
  --primary-ink: #141318;
  --accent: #a99cff;
  --accent-ink: #141318;
  --accent-soft: #2a2745;
  --poke-ink: #ff4d4d;
  --win-solid: #3fa886;
  --win-ink: #8fd3b8;
  --win-tint: #1a2a25;
  --win-line: #27443a;
  --loss-solid: #d4674a;
  --loss-ink: #f0a48e;
  --loss-tint: #2f1f1b;
  --loss-line: #4d2e26;
  --tie-solid: #b99438;
  --tie-ink: #e0c27a;
  --tie-tint: #2b2618;
  --tie-line: #463d22;
  --on-solid: #141318;
  --heat-n3: #8a3b26;
  --heat-n2: #5e2d21;
  --heat-n1: #3d2520;
  --heat-0: #27262e;
  --heat-p1: #1f3a31;
  --heat-p2: #1f5443;
  --heat-p3: #237259;
  --heat-ink: #eceaf2;
  --series-1: #3987e5;
  --series-2: #d95926;
  --series-3: #199e70;
  --series-4: #c98500;
  --series-5: #d55181;
  --series-6: #008300;
  --series-7: #9085e9;
  --series-other: #6f6c7a;
  --grid: #2f2e38;
  --e1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --e2: 0 8px 24px rgba(0, 0, 0, 0.45), 0 1px 2px rgba(0, 0, 0, 0.4);
  --e3: 0 24px 64px rgba(0, 0, 0, 0.6);
  --scrim: rgba(8, 8, 10, 0.62);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .mps {
    color-scheme: dark;
    --bg: #141318;
    --surface: #1d1c22;
    --surface-2: #27262e;
    --surface-3: #32313b;
    --border: #2f2e38;
    --border-strong: #45434f;
    --text: #eceaf2;
    --text-muted: #a6a3b3;
    --text-faint: #6f6c7a;
    --primary: #eceaf2;
    --primary-hover: #ffffff;
    --primary-ink: #141318;
    --accent: #a99cff;
    --accent-ink: #141318;
    --accent-soft: #2a2745;
    --poke-ink: #ff4d4d;
    --win-solid: #3fa886;
    --win-ink: #8fd3b8;
    --win-tint: #1a2a25;
    --win-line: #27443a;
    --loss-solid: #d4674a;
    --loss-ink: #f0a48e;
    --loss-tint: #2f1f1b;
    --loss-line: #4d2e26;
    --tie-solid: #b99438;
    --tie-ink: #e0c27a;
    --tie-tint: #2b2618;
    --tie-line: #463d22;
    --on-solid: #141318;
    --heat-n3: #8a3b26;
    --heat-n2: #5e2d21;
    --heat-n1: #3d2520;
    --heat-0: #27262e;
    --heat-p1: #1f3a31;
    --heat-p2: #1f5443;
    --heat-p3: #237259;
    --heat-ink: #eceaf2;
    --series-1: #3987e5;
    --series-2: #d95926;
    --series-3: #199e70;
    --series-4: #c98500;
    --series-5: #d55181;
    --series-6: #008300;
    --series-7: #9085e9;
    --series-other: #6f6c7a;
    --grid: #2f2e38;
    --e1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --e2: 0 8px 24px rgba(0, 0, 0, 0.45), 0 1px 2px rgba(0, 0, 0, 0.4);
    --e3: 0 24px 64px rgba(0, 0, 0, 0.6);
    --scrim: rgba(8, 8, 10, 0.62);
  }
}

/* ===================================================================
 * 2. Type
 * =================================================================== */

.mps .t-hero { margin: 0; font-family: var(--font-display); font-weight: 700; font-size: 48px; line-height: 1.04; letter-spacing: -0.02em; }
.mps .t-display { margin: 0; font-family: var(--font-display); font-weight: 700; font-size: 36px; line-height: 1.1; letter-spacing: -0.02em; }
.mps .t-h1 { margin: 0; font-family: var(--font-display); font-weight: 700; font-size: 28px; line-height: 1.15; letter-spacing: -0.015em; }
.mps .t-h2 { margin: 0; font-family: var(--font-display); font-weight: 600; font-size: 22px; line-height: 1.2; letter-spacing: -0.01em; }
.mps .t-h3 { margin: 0; font-family: var(--font-body); font-weight: 700; font-size: 16px; line-height: 1.3; }
.mps .t-body { font-size: 15px; line-height: 1.45; }
.mps .t-sm { font-size: 13px; line-height: 1.4; }
.mps .t-xs { font-size: 12px; line-height: 1.35; }
.mps .t-eyebrow { font-size: 12px; line-height: 1.2; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.mps .t-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.mps .t-record { font-family: var(--font-mono); font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.mps .muted { color: var(--text-muted); }
.mps .wordmark { font-size: 13px; letter-spacing: -0.02em; line-height: 1; color: var(--text); text-decoration: none; display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; }
.mps .wordmark:hover { text-decoration: none; }
/* Phones: the display sizes step down so a 360px screen isn't one word per line. */
@media (max-width: 599px) {
  .mps .t-hero { font-size: 34px; }
  .mps .t-display { font-size: 28px; }
  .mps .t-h1 { font-size: 24px; }
}

/* ===================================================================
 * 3. Surfaces
 *    ONE filled surface per screen: the .composer (the thing you are doing
 *    right now). .card, .stat and neutral .row have no fill, only a border.
 *    Result-tinted rows keep their tints (data, not containers). Things
 *    that float (sheets, menus, popovers, toasts) keep their fill.
 * =================================================================== */

.mps .card { background: transparent; border: 1px solid var(--border); border-radius: var(--r-lg); min-width: 0; }
.mps .card-pad { padding: var(--card-pad); }
.mps a.card { color: var(--text); text-decoration: none; }
.mps a.card:hover { border-color: var(--border-strong); text-decoration: none; }
.mps .composer { background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-xl); box-shadow: var(--e1); min-width: 0; }
:root[data-theme="dark"] .mps .composer { background: var(--surface-2); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .mps .composer { background: var(--surface-2); } }
/* Doubled classes: globals.css styles bare inputs at (0,2,1), which would
 * otherwise beat a (0,2,0) `.mps .input`. */
.mps .composer .input.input, .mps .composer .select.select, .mps .composer .textarea.textarea, .mps .composer .picker, .mps .composer .sel { background: var(--bg); }
.mps .composer-pad { padding: var(--card-pad); }
.mps .well { background: var(--surface-2); border-radius: var(--r-md); }
.mps .divider { height: 1px; background: var(--border); border: 0; margin: 0; }
.mps .menu, .mps .popover { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--e2); }

/* ===================================================================
 * 4. Never-wrap and name rules
 * =================================================================== */

.mps .t-record, .mps .res, .mps .badge, .mps .chip, .mps .btn, .mps .seg > button, .mps .seg > a,
.mps .stat-value, .mps .nav-link, .mps .tab > span, .mps .t-mono, .mps .tag { white-space: nowrap; }
/* Archetype, event and store names: up to two lines, never a mid-word ellipsis on one line. */
.mps .name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; text-wrap: balance; }

/* ===================================================================
 * 5. Buttons
 * =================================================================== */

.mps .btn { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: var(--control-h); padding: 0 16px; border-radius: var(--r-md); border: 1px solid var(--border-strong); background: var(--surface); color: var(--text); font-family: inherit; font-weight: 600; font-size: 15px; line-height: 1.1; text-decoration: none; cursor: pointer; white-space: nowrap; flex: none; }
.mps .btn:hover { text-decoration: none; }
.mps .btn:not(:disabled):not([aria-disabled="true"]):hover { background: var(--surface-2); }
.mps .btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mps .btn:disabled, .mps .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }
.mps .btn-primary { background: var(--primary); color: var(--primary-ink); border-color: var(--primary); }
.mps .btn-primary:not(:disabled):not([aria-disabled="true"]):hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.mps .btn-accent { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.mps .btn-accent:not(:disabled):not([aria-disabled="true"]):hover { background: var(--accent); filter: brightness(1.08); }
.mps .btn-ghost { background: transparent; border-color: transparent; color: var(--text); }
.mps .btn-ghost:not(:disabled):not([aria-disabled="true"]):hover { background: var(--surface-2); }
.mps .btn-danger { background: transparent; border-color: var(--loss-line); color: var(--loss-ink); }
.mps .btn-danger:not(:disabled):not([aria-disabled="true"]):hover { background: var(--loss-tint); }
.mps .btn-sm { min-height: var(--control-h-sm); padding: 0 12px; font-size: 13px; border-radius: var(--r-sm); }
.mps .btn-lg { min-height: 52px; padding: 0 22px; font-size: 16px; border-radius: var(--r-lg); }
.mps .btn-icon { width: var(--control-h); padding: 0; }
.mps .btn-sm.btn-icon { width: var(--control-h-sm); }
.mps .btn-block { display: flex; width: 100%; }
/* Result buttons: win and loss carry the weight, tie is a quiet third. */
.mps .btn-win { background: var(--match-win, var(--win-solid)); border-color: var(--match-win, var(--win-solid)); color: var(--on-solid); }
.mps .btn-loss { background: var(--match-loss, var(--loss-solid)); border-color: var(--match-loss, var(--loss-solid)); color: var(--on-solid); }
/* Keep the solid fill on hover (the generic .btn hover would repaint it). */
.mps .btn-win:not(:disabled):not([aria-disabled="true"]):hover { background: var(--match-win, var(--win-solid)); filter: brightness(1.06); }
.mps .btn-loss:not(:disabled):not([aria-disabled="true"]):hover { background: var(--match-loss, var(--loss-solid)); filter: brightness(1.06); }
.mps .btn-tie { background: transparent; border-color: var(--tie-line); color: var(--tie-ink); }
.mps .btn-tie:not(:disabled):not([aria-disabled="true"]):hover { background: var(--tie-tint); }
/* Split button: a main action with an attached arrow (the "Report round N" + menu pattern). */
.mps .btn-split { display: inline-flex; align-items: stretch; flex: none; }
.mps .btn-split > .btn:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.mps .btn-split > .btn:last-child,
.mps .btn-split > .popover-root > summary.btn { border-top-left-radius: 0; border-bottom-left-radius: 0; width: 36px; padding: 0; border-left-color: color-mix(in srgb, var(--accent-ink) 30%, transparent); }

/* ===================================================================
 * 6. Chips, badges, segmented
 * =================================================================== */

.mps .chip { box-sizing: border-box; display: inline-flex; align-items: center; gap: 6px; min-height: var(--control-h-sm); padding: 0 14px; border-radius: var(--r-pill); border: 1px solid var(--border); background: var(--surface); color: var(--text-muted); font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; text-decoration: none; }
.mps .chip:hover { color: var(--text); text-decoration: none; }
.mps .chip.on, .mps .chip[aria-pressed="true"] { background: var(--text); border-color: var(--text); color: var(--bg); }
.mps .chip-count { font-family: var(--font-mono); font-weight: 500; opacity: 0.75; }
@media (pointer: coarse) { .mps .chip { min-height: var(--control-h); } }
.mps .badge { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px; border-radius: var(--r-sm); background: var(--surface-2); color: var(--text-muted); font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; white-space: nowrap; flex: none; }
.mps .badge-live { background: var(--win-tint); color: var(--win-ink); }
.mps .badge-accent { background: var(--accent-soft); color: var(--accent); }
.mps .badge-warn { background: var(--tie-tint); color: var(--tie-ink); }
.mps .badge-loss { background: var(--loss-tint); color: var(--loss-ink); }
.mps .dot-live { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--match-win, var(--win-solid)); flex: none; }
/* A .seg is a control like any other: exactly --control-h tall (3px ground
 * + items at --control-h − 6px), so it lines up with an .input beside it. */
.mps .seg { box-sizing: border-box; display: inline-flex; align-items: stretch; min-height: var(--control-h); padding: 3px; gap: 2px; background: var(--surface-2); border-radius: var(--r-md); max-width: 100%; }
.mps .seg > button, .mps .seg > a { box-sizing: border-box; min-height: calc(var(--control-h) - 6px); padding: 0 14px; border: 0; border-radius: 8px; background: transparent; color: var(--text-muted); font-family: inherit; font-weight: 600; font-size: 13px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 6px; text-decoration: none; }
.mps .seg > button:hover, .mps .seg > a:hover { color: var(--text); text-decoration: none; }
.mps .seg > .on, .mps .seg > [aria-checked="true"], .mps .seg > [aria-current="page"] { background: var(--surface); color: var(--text); box-shadow: var(--e1); }
.mps .seg-sm { min-height: var(--control-h-sm); }
.mps .seg-sm > button, .mps .seg-sm > a { min-height: calc(var(--control-h-sm) - 6px); padding: 0 10px; }
/* In a form row the seg fills its column, like the input next to it. */
.mps .seg-fill, .mps .field > .seg { display: flex; width: 100%; }
.mps .seg-fill > button, .mps .seg-fill > a, .mps .field > .seg > button, .mps .field > .seg > a { flex: 1 1 0; min-width: 0; padding: 0 6px; }

/* ===================================================================
 * 7. Sprites (render them with the app's sprite system — SpritePair /
 *    deckIconUrl for decks, <Sprite> for Pokémon; these classes only size
 *    and arrange). The base size skips <img width=…> so SpritePair's
 *    explicit sizes win.
 * =================================================================== */

.mps .sprite { object-fit: contain; image-rendering: pixelated; flex: none; }
.mps .sprite:not([width]) { width: 36px; height: 36px; }
.mps .sprite.sprite-sm { width: 28px; height: 28px; }
.mps .sprite.sprite-lg { width: 48px; height: 48px; }
.mps .sprite.sprite-xl { width: 72px; height: 72px; }
.mps .sprite-pair { display: inline-flex; align-items: center; flex: none; }
.mps .sprite-pair > .sprite + .sprite { margin-left: -8px; }
.mps .sprite-slot { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: var(--r-sm); border: 1px dashed var(--border-strong); color: var(--text-muted); font-size: 12px; font-weight: 700; flex: none; }

/* ===================================================================
 * 8. Result marks, rows, pips
 * =================================================================== */

.mps .res { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 8px; font-family: var(--font-mono); font-weight: 700; font-size: 13px; flex: none; }
.mps .res-sm { width: 22px; height: 22px; font-size: 11px; border-radius: 6px; }
.mps .res-w { background: var(--match-win, var(--win-solid)); color: var(--on-solid); }
.mps .res-l { background: var(--match-loss, var(--loss-solid)); color: var(--on-solid); }
.mps .res-t { background: var(--match-tie, var(--tie-solid)); color: var(--on-solid); }
.mps .res-none { background: var(--surface-2); color: var(--text-muted); }
.mps .row { display: flex; align-items: center; gap: 12px; min-height: 56px; min-width: 0; padding: 8px var(--row-pad-x); border-radius: var(--r-md); background: transparent; border: 1px solid var(--border); color: var(--text); text-decoration: none; }
.mps a.row:hover, .mps button.row:hover { border-color: var(--border-strong); text-decoration: none; }
.mps .row-w { background: var(--win-tint); border-color: var(--win-line); }
.mps .row-l { background: var(--loss-tint); border-color: var(--loss-line); }
.mps .row-t { background: var(--tie-tint); border-color: var(--tie-line); }
.mps .row-main { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mps .row-title { font-weight: 600; font-size: 15px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.mps .row-sub { font-size: 12px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mps .pips { display: inline-flex; gap: 3px; flex: none; }
.mps .pip { width: 8px; height: 8px; border-radius: 2px; background: var(--surface-3); flex: none; }
.mps .pip-w { background: var(--match-win, var(--win-solid)); }
.mps .pip-l { background: var(--match-loss, var(--loss-solid)); }
.mps .pip-t { background: var(--match-tie, var(--tie-solid)); }
.mps .note-mark { display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 7px; border-radius: var(--r-sm); background: var(--surface); border: 1px solid var(--border); color: var(--text-muted); font-size: 11px; font-weight: 600; white-space: nowrap; flex: none; }

/* ===================================================================
 * 9. Stat tile
 * =================================================================== */

.mps .stat { display: flex; flex-direction: column; gap: 4px; padding: 16px 18px; background: transparent; border: 1px solid var(--border); border-radius: var(--r-lg); min-width: 0; }
.mps .stat-label { font-size: 12px; font-weight: 600; color: var(--text-muted); }
.mps .stat-value { font-family: var(--font-mono); font-weight: 700; font-size: 26px; line-height: 1.1; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.mps .stat-foot { font-size: 12px; color: var(--text-muted); }
.mps .delta-up { color: var(--win-ink); font-weight: 600; }
.mps .delta-down { color: var(--loss-ink); font-weight: 600; }
@media (max-width: 599px) { .mps .stat { padding: 12px; } .mps .stat-value { font-size: 22px; } }

/* ===================================================================
 * 10. Forms
 * =================================================================== */

.mps .field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.mps .label { font-size: 13px; font-weight: 600; color: var(--text); }
.mps .hint { font-size: 12px; color: var(--text-muted); }
/* Every single-line control is exactly --control-h tall (border-box, fixed
 * height, vertical padding zeroed so the browser centres the text). A fixed
 * height rather than a min-height is what stops a native date input (taller
 * in Chrome and Safari), a sprite in a picker or a 16px phone font from
 * nudging one control in a row a few pixels past its neighbours. */
.mps .input.input, .mps .select.select, .mps .textarea.textarea, .mps .sel { box-sizing: border-box; width: 100%; min-width: 0; min-height: var(--control-h); padding: 10px 12px; border-radius: var(--r-md); border: 1px solid var(--border-strong); background: var(--surface); color: var(--text); font-family: inherit; font-size: 15px; line-height: 1.2; }
.mps .input.input, .mps .select.select, .mps .sel { height: var(--control-h); padding-top: 0; padding-bottom: 0; }
.mps .input.input-sm, .mps .select.select-sm, .mps .sel.sel-sm { height: var(--control-h-sm); min-height: var(--control-h-sm); font-size: 14px; padding-left: 10px; padding-right: 10px; }
.mps .textarea.textarea { height: auto; min-height: 84px; resize: vertical; }
.mps .input.input::placeholder, .mps .textarea.textarea::placeholder { color: var(--text-muted); opacity: 0.8; }
.mps .input.input:focus-visible, .mps .select.select:focus-visible, .mps .textarea.textarea:focus-visible, .mps .sel:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.mps .input.input[aria-invalid="true"], .mps .select.select[aria-invalid="true"], .mps .textarea.textarea[aria-invalid="true"], .mps .sel[aria-invalid="true"] { border-color: var(--loss-solid); }
.mps .input.input:disabled, .mps .select.select:disabled, .mps .textarea.textarea:disabled, .mps .sel:disabled { opacity: 0.55; cursor: not-allowed; }
/* Native date/time inputs: drop the platform chrome that makes them taller
 * (Chrome's datetime-edit padding, iOS Safari's centred value that also
 * collapses when empty) so they match a text input exactly. */
.mps .input.input:is([type="date"], [type="time"], [type="datetime-local"], [type="month"], [type="week"]) { -webkit-appearance: none; appearance: none; text-align: left; }
.mps .input.input::-webkit-date-and-time-value { text-align: left; min-height: 1.2em; margin: 0; }
.mps .input.input::-webkit-datetime-edit { padding: 0; line-height: 1.2; }
.mps .input.input::-webkit-datetime-edit-fields-wrapper { padding: 0; }
.mps .input.input::-webkit-calendar-picker-indicator { margin: 0 0 0 4px; padding: 0; cursor: pointer; }
.mps .input.input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
/* Deck picker trigger (sprites + one or two lines). The boards drew it at
 * 52px; the maintainer asked for every input to share one height, so it is
 * a --control-h control whose two lines are set tight enough to fit. */
.mps .picker { box-sizing: border-box; display: flex; align-items: center; gap: 10px; height: var(--control-h); min-height: var(--control-h); padding: 0 12px; border-radius: var(--r-md); border: 1px solid var(--border-strong); background: var(--surface); color: var(--text); font-family: inherit; text-align: left; cursor: pointer; width: 100%; min-width: 0; overflow: hidden; }
.mps .picker-main { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; }
.mps .picker-main > * { line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mps .picker .sprite:not([width]) { width: 32px; height: 32px; }
.mps .picker:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Rows of controls: every child stretches to the row's height, so a
 * control with an icon or a different intrinsic size can't stand taller
 * or shorter than its neighbours. */
.mps .control-row { display: flex; align-items: stretch; gap: 8px; min-width: 0; }
.mps .control-row > * { min-width: 0; }

/* The ArchetypePicker (the deck picker used across the beta forms): its
 * closed trigger and its search field are controls like any other. */
.mps .archetype-picker-trigger { box-sizing: border-box; height: var(--control-h); min-height: var(--control-h); padding: 0 12px; gap: 10px; border: 1px solid var(--border-strong); border-radius: var(--r-md); background: var(--surface); font-family: inherit; font-size: 15px; line-height: 1.2; text-align: left; overflow: hidden; min-width: 0; }
.mps .archetype-picker-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.mps .archetype-picker-trigger > span { min-width: 0; }
.mps .archetype-picker-trigger > span:not(.archetype-picker-main):not(.archetype-picker-change):not(.archetype-picker-sprites) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mps .archetype-picker-sprites, .mps .archetype-picker-slot, .mps .archetype-picker-change { flex: none; }
.mps .archetype-picker-change { color: var(--accent); font-weight: 600; font-size: 13px; }
.mps .composer .archetype-picker-trigger, .mps .bt-composer .archetype-picker-trigger, .mps .rl-composer .archetype-picker-trigger { background: var(--bg); }
.mps .archetype-picker .archetype-picker-search.archetype-picker-search { height: var(--control-h); padding: 0 12px; border-radius: var(--r-md); border: 1px solid var(--border-strong); font-size: 15px; }
/* The open panel, drawn like the Select's (.sel-panel / .sel-opt below).
 * It opens over the trigger, so the search row sits exactly where the
 * trigger was and is one --control-h control: no box-in-a-box. The focus
 * ring belongs to the panel (:focus-within: accent border + a 1px accent
 * shadow ring) rather than the input; an outline on the input itself was
 * clipped by the panel's edges. Scoped to .mps: production keeps its inline styles
 * (ArchetypePicker only drops them when <body> is .mps). */
.mps .archetype-picker-panel { position: absolute; top: 0; left: 0; right: 0; z-index: 30; box-sizing: border-box; display: flex; flex-direction: column; min-width: 0; background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-lg); box-shadow: var(--e2); color: var(--text); font-family: var(--font-body); overflow: hidden; }
.mps .archetype-picker-panel:focus-within { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), var(--e2); }
.mps .archetype-picker .archetype-picker-panel .archetype-picker-search.archetype-picker-search { flex: none; height: calc(var(--control-h) - 2px); min-height: 0; margin: 0; padding: 0 12px 0 38px; border: 0; border-bottom: 1px solid var(--border); border-radius: 0; background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%238a8794' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") no-repeat 12px center; color: var(--text); font-size: 15px; outline: none; box-shadow: none; }
.mps .archetype-picker-panel .archetype-picker-search::placeholder { color: var(--text-muted); opacity: 0.8; }
.mps .archetype-picker-partner { display: flex; gap: 4px; padding: 8px 8px 0; }
.mps .archetype-picker-list { margin: 0; padding: 6px; max-height: min(320px, 55vh); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
.mps .archetype-picker-list::-webkit-scrollbar { width: 8px; }
.mps .archetype-picker-list::-webkit-scrollbar-track { background: transparent; }
.mps .archetype-picker-list::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--r-pill); border: 2px solid var(--surface); }
/* Group headers are the design system's eyebrow (.t-eyebrow). */
.mps .archetype-picker-group { padding: 10px 10px 6px; font-size: 12px; line-height: 1.2; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }
.mps .archetype-picker-list > div:first-child > .archetype-picker-group { padding-top: 6px; }
.mps .archetype-picker-opt { box-sizing: border-box; display: flex; align-items: center; gap: 10px; width: 100%; min-width: 0; min-height: var(--control-h); padding: 6px 10px; border: 0; border-radius: var(--r-md); background: transparent; color: var(--text); font-family: inherit; font-size: 15px; line-height: 1.25; text-align: left; cursor: pointer; outline: none; }
.mps .archetype-picker-opt[aria-selected="true"] { background: var(--surface-2); }
.mps .archetype-picker-opt:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Leading sprites: one fixed column sized for two 22px sprites (+2px gap),
 * so a one-sprite deck's name lines up with a two-sprite deck's.
 * TODO: replace with the shared sprite-slot primitive from
 * `claude/diverging-bars` once it lands on main. */
.mps .archetype-picker-opt-sprites { flex: none; display: inline-flex; align-items: center; width: 46px; height: 22px; }
.mps .archetype-picker-opt-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mps .archetype-picker-opt-name { flex: 1 1 auto; min-width: 0; overflow-wrap: break-word; }
.mps .archetype-picker-opt[data-kind="recent"] .archetype-picker-opt-name, .mps .archetype-picker-opt[data-kind="saved"] .archetype-picker-opt-name { font-weight: 600; }
.mps .archetype-picker-opt-sub { font-size: 12px; color: var(--text-muted); }
.mps .archetype-picker-opt-meta { flex: none; margin-left: auto; font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.mps .archetype-picker-badge { flex: none; font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--accent); }
/* Saved decks carry two trailing labels (Latest + format); stacked in one
 * column so the title keeps its width on a 360px phone instead of
 * breaking mid-word. */
.mps .archetype-picker-opt[data-kind="saved"] { display: grid; grid-template-columns: 46px minmax(0, 1fr) auto; column-gap: 10px; row-gap: 2px; align-content: center; }
.mps .archetype-picker-opt[data-kind="saved"] > .archetype-picker-opt-sprites, .mps .archetype-picker-opt[data-kind="saved"] > .archetype-picker-opt-main { grid-row: span 2; }
.mps .archetype-picker-opt[data-kind="saved"] > .archetype-picker-badge, .mps .archetype-picker-opt[data-kind="saved"] > .archetype-picker-opt-meta { grid-column: 3; justify-self: end; margin-left: 0; }
.mps .archetype-picker-opt[data-kind="saved"] > .archetype-picker-badge { align-self: end; }
.mps .archetype-picker-opt[data-kind="saved"] > .archetype-picker-badge + .archetype-picker-opt-meta { align-self: start; }
.mps .archetype-picker-opt[data-kind="saved"]:not(:has(> .archetype-picker-badge)) > .archetype-picker-opt-meta { grid-row: 1 / span 2; }
.mps .archetype-picker-empty { padding: 12px 10px; font-size: 14px; color: var(--text-muted); }

/* ---- Select (components/beta/Select.tsx): the trigger is a .sel (same
 * box as .input); the panel is portalled to <body> and positioned fixed
 * under the trigger, or a bottom sheet on phones. */
.mps .sel { display: flex; align-items: center; gap: 10px; text-align: left; cursor: pointer; }
.mps .sel:disabled { cursor: not-allowed; }
.mps .sel-value { flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 8px; }
.mps .sel-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mps .sel-placeholder { color: var(--text-muted); }
.mps .sel-icon { display: inline-flex; align-items: center; flex: none; }
.mps .sel-chev { flex: none; color: var(--text-muted); transition: transform 120ms ease; }
.mps .sel[aria-expanded="true"] .sel-chev { transform: rotate(180deg); }
.mps .sel-inline { width: auto; max-width: 100%; align-self: flex-start; }
.mps .sel-panel { position: fixed; z-index: 1000; box-sizing: border-box; margin: 0; padding: 6px; list-style: none; overflow-y: auto; overscroll-behavior: contain; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--e2); color: var(--text); font-family: var(--font-body); font-size: 15px; }
.mps .sel-opt { box-sizing: border-box; display: flex; align-items: center; gap: 10px; min-height: var(--control-h); padding: 6px 10px; border-radius: var(--r-md); cursor: pointer; }
.mps .sel-opt[data-active="true"] { background: var(--surface-2); }
.mps .sel-opt[aria-selected="true"] { font-weight: 600; }
.mps .sel-opt[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
.mps .sel-opt-main { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mps .sel-opt-main > span:first-child { overflow-wrap: anywhere; }
.mps .sel-opt-desc { font-size: 12px; font-weight: 400; color: var(--text-muted); }
.mps .sel-check { flex: none; color: var(--accent); visibility: hidden; }
.mps .sel-opt[aria-selected="true"] .sel-check { visibility: visible; }
.mps .sel-scrim { position: fixed; inset: 0; z-index: 999; background: var(--scrim); }
.mps .sel-panel.is-sheet { left: 0; right: 0; bottom: 0; top: auto; width: auto; border-radius: var(--r-xl) var(--r-xl) 0 0; padding: 8px 8px calc(8px + env(safe-area-inset-bottom, 0px)); box-shadow: var(--e3); }
.mps .sel-sheet-head { display: flex; align-items: center; justify-content: center; padding: 4px 0 8px; }
.mps .focus-ring { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ===================================================================
 * 11. Note tags and lines
 * =================================================================== */

.mps .tag { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 12px; border-radius: var(--r-sm); border: 1px solid var(--border); background: var(--surface); color: var(--text); font-family: inherit; font-size: 13px; font-weight: 500; cursor: pointer; white-space: nowrap; }
.mps .tag.on, .mps .tag[aria-pressed="true"] { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 600; }
.mps .tag-static { min-height: 24px; padding: 0 8px; font-size: 12px; background: var(--surface-2); border-color: transparent; color: var(--text-muted); cursor: default; }
.mps .line-note { padding: 10px 12px; border-radius: var(--r-md); background: var(--surface-2); font-size: 14px; }
.mps .line-chip { display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 12px; border-radius: var(--r-md); border: 1px dashed var(--border-strong); background: transparent; color: var(--text); font-family: inherit; font-size: 13px; font-weight: 500; cursor: pointer; text-align: left; }
.mps .line-chip.on, .mps .line-chip[aria-pressed="true"] { border-style: solid; border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.mps .line-chip .line-rec { font-family: var(--font-mono); font-size: 12px; color: var(--text-muted); white-space: nowrap; }

/* ===================================================================
 * 12. Avatars
 * =================================================================== */

.mps .avatar { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; background: var(--accent-soft); color: var(--accent); font-size: 12px; font-weight: 700; flex: none; overflow: hidden; object-fit: cover; }
/* A Pokémon sprite as the avatar: pixel art, fills the circle. */
.mps .avatar .avatar-sprite { display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; }
.mps .avatar .avatar-sprite img { width: 118%; height: 118%; object-fit: contain; image-rendering: pixelated; }
.mps .avatar > img, .mps .avatar > video { width: 100%; height: 100%; object-fit: cover; display: block; }
.mps .avatar-stack { display: inline-flex; }
.mps .avatar-stack > .avatar { border: 2px solid var(--bg); margin-left: -8px; }
.mps .avatar-stack > .avatar:first-child { margin-left: 0; }

/* ===================================================================
 * 13. Tables, bars, heat
 * =================================================================== */

.mps table.tbl { width: 100%; border-collapse: collapse; font-size: 14px; }
.mps .tbl th { text-align: left; padding: 8px 12px; font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); border-bottom: 1px solid var(--border); }
.mps .tbl td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
/* Inside a padded card the outer cells add no inset of their own. */
.mps .tbl tr > :first-child { padding-left: 0; }
.mps .tbl tr > :last-child { padding-right: 0; }
.mps .tbl .num { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.mps .bar { position: relative; height: 8px; border-radius: 4px; background: var(--surface-2); overflow: hidden; }
.mps .bar > i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 4px; background: var(--text-muted); display: block; }
.mps .bar-accent > i { background: var(--accent); }
.mps .wr { position: relative; height: 10px; border-radius: 5px; background: var(--surface-2); }
.mps .wr::after { content: ""; position: absolute; left: 50%; top: -3px; bottom: -3px; width: 1px; background: var(--border-strong); }
.mps .wr > i { position: absolute; top: 0; bottom: 0; display: block; border-radius: 5px; }
.mps .wr > .up { left: 50%; background: var(--match-win, var(--win-solid)); }
.mps .wr > .down { right: 50%; background: var(--match-loss, var(--loss-solid)); }
.mps .heat { display: flex; align-items: center; justify-content: center; border-radius: 6px; font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--heat-ink); background: var(--heat-0); }
.mps .heat-n3 { background: var(--heat-n3); }
.mps .heat-n2 { background: var(--heat-n2); }
.mps .heat-n1 { background: var(--heat-n1); }
.mps .heat-p1 { background: var(--heat-p1); }
.mps .heat-p2 { background: var(--heat-p2); }
.mps .heat-p3 { background: var(--heat-p3); }
.mps .heat-thin { background: transparent; border: 1px dashed var(--border-strong); color: var(--text-muted); font-weight: 400; }

/* ===================================================================
 * 14. Overlays, empty, toast, decklist
 * =================================================================== */

.mps .sheet { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-xl); box-shadow: var(--e3); }
.mps .sheet-m { background: var(--surface); border-radius: var(--r-xl) var(--r-xl) 0 0; box-shadow: var(--e3); }
.mps .grabber { display: block; width: 40px; height: 4px; border-radius: 2px; background: var(--border-strong); align-self: center; }
.mps .empty { display: flex; flex-direction: column; gap: 12px; padding: var(--card-pad); border-radius: var(--r-lg); border: 1px dashed var(--border-strong); background: transparent; }
.mps .toast { display: inline-flex; align-items: center; gap: 12px; min-height: 48px; padding: 0 16px; border-radius: var(--r-md); background: var(--text); color: var(--bg); font-size: 14px; font-weight: 500; box-shadow: var(--e2); }
.mps .toast a, .mps .toast button { color: inherit; font-weight: 700; background: none; border: 0; text-decoration: underline; cursor: pointer; font-family: inherit; }
.mps .decklist { font-family: var(--font-mono); font-size: 13px; line-height: 1.6; white-space: pre; padding: 12px var(--card-pad); border-radius: var(--r-md); background: var(--surface-2); color: var(--text); overflow-x: auto; }

/* ===================================================================
 * 15. Page frame
 *    .page: the design's content column (max 1280, 28/32 padding; 16 on
 *    phones). Page agents may use it or their own grid.
 * =================================================================== */

.mps .page { width: 100%; max-width: 1280px; margin: 0 auto; padding: 28px var(--gutter); display: flex; flex-direction: column; gap: 20px; min-width: 0; }
@media (max-width: 1023px) { .mps .page { padding: 16px var(--gutter); gap: 16px; } }

/* Join strip: the signed-out "keep your own record like this" footer bar
 * (Nav-Mobile board, screen 4). Pages render it; the shell does not. */
.mps .join-strip { display: flex; flex-direction: column; gap: 10px; padding: 14px var(--gutter) 18px; background: var(--surface); border-top: 1px solid var(--border); }
@media (max-width: 1023px) { .mps .join-strip { position: sticky; bottom: 0; z-index: 40; padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px)); } }

/* ===================================================================
 * 16. Shell: top bar, menus, tab bar
 *    ≥1024: .nav-top (64px) with the five destinations, search, the
 *    primary action, the bell and the avatar. Below 1024 the same header
 *    slims to the .nav-m shape (56px: wordmark, search icon, bell,
 *    avatar) and the destinations + primary action move to the tab bar.
 * =================================================================== */

.mps .nav-top { position: sticky; top: 0; z-index: 50; display: flex; align-items: center; gap: 24px; height: calc(64px + env(safe-area-inset-top, 0px)); padding: env(safe-area-inset-top, 0px) max(var(--gutter), env(safe-area-inset-right, 0px)) 0 max(var(--gutter), env(safe-area-inset-left, 0px)); background: var(--surface); border-bottom: 1px solid var(--border); flex: none; min-width: 0; }
.mps .nav-links { display: flex; align-items: center; gap: 4px; min-width: 0; }
.mps .nav-link { display: inline-flex; align-items: center; height: 40px; padding: 0 14px; border-radius: var(--r-md); color: var(--text-muted); font-weight: 600; font-size: 14px; text-decoration: none; }
.mps .nav-link:hover { color: var(--text); text-decoration: none; }
.mps .nav-link.on, .mps .nav-link[aria-current="page"] { color: var(--text); background: var(--surface-2); }
.mps .nav-spacer { flex: 1 1 0; min-width: 0; }
.mps .nav-end { display: flex; align-items: center; gap: 8px; flex: none; }
.mps .nav-top .btn { min-height: 40px; }
.mps .nav-top .btn-icon { width: 40px; }
.mps .nav-top .btn-sm { min-height: 36px; }
.mps .nav-m { display: flex; align-items: center; gap: 12px; height: 56px; padding: 0 var(--gutter); background: var(--surface); border-bottom: 1px solid var(--border); flex: none; }

/* Search: the 260px field on desktop (200 at 1280), an icon on phones. */
.mps .nav-search { position: relative; flex: none; }
.mps .nav-search-box { display: flex; align-items: center; gap: 8px; width: 260px; height: 40px; padding: 0 12px; border-radius: var(--r-md); background: var(--surface-2); color: var(--text-muted); }
.mps .nav-search-box:focus-within { outline: 2px solid var(--accent); outline-offset: 1px; }
.mps .nav-search-box input { border: 0; background: transparent; outline: 0; width: 100%; min-width: 0; text-overflow: ellipsis; font-family: inherit; font-size: 14px; color: var(--text); }
.mps .nav-search-box input::placeholder { color: var(--text-muted); }
.mps .nav-search-box input::-webkit-search-cancel-button { display: none; }
/* Omni search panel (NavSearch): one listbox of grouped options. Hangs
 * off the field's right edge on desktop (the field sits at the bar's end),
 * wider than the field, and scrolls inside itself. */
.mps .nav-search-results { position: absolute; top: calc(100% + 6px); right: 0; width: 400px; max-width: calc(100vw - 32px); max-height: min(70vh, 560px); overflow-y: auto; overscroll-behavior: contain; margin: 0; padding: 6px; z-index: 60; }
.mps .nav-search-group + .nav-search-group { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--border); }
.mps .nav-search-group-label { padding: 8px 10px 4px; font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-muted); }
.mps .nav-search-opt > a, .mps .nav-search-opt > button { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 44px; padding: 6px 10px; border: 0; border-radius: var(--r-md); background: transparent; color: var(--text); text-align: left; text-decoration: none; font: inherit; font-size: 14px; cursor: pointer; }
.mps .nav-search-opt.on > a, .mps .nav-search-opt.on > button { background: var(--surface-2); text-decoration: none; }
.mps .nav-search-ico { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: var(--r-sm); background: var(--surface-2); color: var(--text-muted); }
.mps .nav-search-opt.on .nav-search-ico { background: var(--surface); }
.mps .nav-search-sprite { width: 28px; height: 28px; object-fit: contain; image-rendering: pixelated; }
.mps .nav-search-text { display: flex; flex-direction: column; min-width: 0; }
.mps .nav-search-title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mps .nav-search-text small { color: var(--text-muted); font-weight: 400; font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mps .nav-search-empty { margin: 0; padding: 12px 10px; color: var(--text-muted); font-size: 14px; }
.mps .nav-search-kbd { flex: none; display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 5px; border: 1px solid var(--border); border-radius: var(--r-sm); font-family: inherit; font-size: 11px; color: var(--text-muted); }
.mps .nav-search-box:focus-within .nav-search-kbd { display: none; }
.mps .nav-search-toggle { display: none; }
.mps .nav-search-sheet { display: none; }
@media (max-width: 1279px) { .mps .nav-search-box { width: 200px; } }

/* Popovers (bell, avatar, primary-action arrow) are <details> so they
 * work before hydration; PopoverShell closes them on navigation, outside
 * click and Escape. */
.mps .popover-root { position: relative; flex: none; }
.mps .popover-root > summary { list-style: none; position: relative; }
.mps .popover-root > summary::-webkit-details-marker { display: none; }
.mps .popover-panel { position: absolute; top: calc(100% + 8px); right: 0; width: var(--panel-w, 300px); z-index: 60; display: flex; flex-direction: column; gap: 2px; padding: 8px; max-height: calc(100vh - 88px); overflow-y: auto; }
.mps .mi { display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 0 12px; border-radius: var(--r-md); color: var(--text); text-decoration: none; font-family: inherit; font-weight: 500; font-size: 14px; background: transparent; border: 0; cursor: pointer; text-align: left; width: 100%; }
.mps .mi:hover, .mps .mi.hl, .mps .mi:focus-visible { background: var(--surface-2); text-decoration: none; }
.mps .mi:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.mps .mi > svg { color: var(--text-muted); flex: none; }
.mps .mi-main { display: flex; flex-direction: column; min-width: 0; }
.mps .mi-main > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mps .mi-row { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 0 12px; }
.mps .popover-panel > .divider { margin: 6px 0; }

/* Notification items */
.mps .nt { display: flex; gap: 12px; padding: 12px; border-radius: var(--r-md); color: var(--text); text-decoration: none; min-width: 0; }
.mps .nt.unread { background: var(--accent-soft); }
.mps .nt-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 0; font-size: 13px; line-height: 1.4; overflow-wrap: anywhere; }
.mps .nt-body a { color: var(--text); font-weight: 600; }
.mps .nt-time { flex: none; font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.mps .udot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: none; margin-top: 6px; }
.mps .rdot { width: 8px; height: 8px; flex: none; }
.mps .ico { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: var(--r-md); background: var(--surface-2); color: var(--text-muted); flex: none; }
.mps .bell { position: relative; }
.mps .bell-count { position: absolute; top: 4px; right: 4px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--accent); color: var(--accent-ink); font-size: 10px; font-weight: 700; line-height: 1; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.mps .popover-root[open] > summary.btn-ghost { background: var(--surface-2); }

/* Phone tab bar: Home, Log, the centre button, Events, Meta — five equal
 * slots, 22px icon over an 11px label; the centre is a 52×34 accent puck. */
.mps .tabbar { display: flex; align-items: stretch; height: 68px; padding: 6px 8px 10px; gap: 2px; background: var(--surface); border-top: 1px solid var(--border); flex: none; }
.mps .tab { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; border-radius: var(--r-md); color: var(--text-muted); font-size: 11px; font-weight: 600; text-decoration: none; }
.mps .tab:hover { text-decoration: none; color: var(--text); }
.mps .tab > span { letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.mps .tab.on, .mps .tab[aria-current="page"] { color: var(--text); }
.mps .tab-primary { color: var(--accent-ink); }
.mps .tab-primary > .tab-puck { display: flex; align-items: center; justify-content: center; gap: 4px; width: 52px; height: 34px; border-radius: var(--r-pill); background: var(--accent); color: var(--accent-ink); font-family: var(--font-mono); font-size: 13px; font-weight: 700; }
.mps .tab-primary > span:last-child { color: var(--text); }

/* Segmented controls whose selected background glides (GlideSeg): the
 * rules live in globals.css, so they hold on every page and in stories. */

/* The site shell (components/beta/shell): which pieces show where. */
.mps .site-nav .nav-wordmark-glyph { flex: none; }
.mps .wordmark-poke { color: var(--poke-ink); }
/* The wordmark is a way Home too (beside the Home link / tab): give
 * it a hit area, a hover wash and a visible keyboard focus ring. */
.mps .site-nav > .wordmark { margin-left: -8px; padding: 6px 8px; border-radius: var(--r-md); min-height: 44px; transition: background-color 120ms ease; }
.mps .site-nav > .wordmark:hover { background: var(--surface-2); }
.mps .site-nav > .wordmark:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; background: var(--surface-2); }
.mps .site-nav > .wordmark[aria-current="page"] { background: transparent; }
/* Its spin (idle turn, hover, loading) is driven by BrandPokeball.tsx so
 * it can ease out instead of snapping back when a CSS animation ends. */

.mps .site-tabbar { display: none; }
.mps .nav-top .nav-phone-only { display: none; }
@media (max-width: 1023px) {
  .mps .nav-top { gap: 12px; height: calc(56px + env(safe-area-inset-top, 0px)); padding: env(safe-area-inset-top, 0px) max(var(--gutter), env(safe-area-inset-right, 0px)) 0 max(var(--gutter), env(safe-area-inset-left, 0px)); }
  .mps .nav-top .nav-links { display: none; }
  .mps .nav-top .nav-search-box { display: none; }
  .mps .nav-top .nav-search-toggle { display: inline-flex; }
  .mps .nav-top.is-tabbed .nav-primary { display: none; }
  .mps .nav-top .nav-desktop-only { display: none; }
  .mps .nav-top .nav-phone-only { display: inline-flex; }
  .mps .nav-top .nav-signin { min-height: 36px; padding: 0 12px; font-size: 13px; border-radius: var(--r-sm); }
  .mps .nav-top .wordmark { font-size: 11px; }
  .mps .nav-top .btn-icon { width: 44px; min-height: 44px; }
  .mps .nav-end { gap: 4px; }
  /* Phone popovers and the search sheet hang off the sticky header (its
   * containing block), never over it or the beta banner, and stop above
   * the tab bar. --nav-bottom is the header's bottom edge in the viewport,
   * measured when they open (beta/nav-measure.ts). */
  .mps .nav-top .popover-root { position: static; }
  .mps .nav-top .popover-panel,
  .mps .nav-search-sheet[data-open="true"] {
    position: absolute; top: calc(100% + 8px); left: 8px; right: 8px; width: auto; z-index: 60;
    max-height: calc(100dvh - var(--nav-bottom, 56px) - var(--app-bottom-inset, 0px) - 24px);
    overflow-y: auto;
  }
  /* Signed-in bars always sit over the tab bar, even before body.mps-tabbed
   * has supplied the inset (Storybook, a streamed first paint). */
  .mps .nav-top.is-tabbed .popover-panel,
  .mps .nav-top.is-tabbed .nav-search-sheet[data-open="true"] {
    max-height: calc(100dvh - var(--nav-bottom, 56px) - var(--app-bottom-inset, calc(68px + env(safe-area-inset-bottom, 0px))) - 24px);
  }
  .mps .nav-search-sheet[data-open="true"] { display: block; padding: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); box-shadow: var(--e2); }
  .mps .nav-search-sheet .nav-search-box { display: flex; width: 100%; height: 44px; }
  .mps .nav-search-sheet .nav-search-results { position: static; width: auto; max-width: none; max-height: none; overflow: visible; margin-top: 8px; padding: 0; border: 0; box-shadow: none; }

  .mps.mps-tabbed { --app-bottom-inset: calc(68px + env(safe-area-inset-bottom, 0px)); padding-bottom: var(--app-bottom-inset); }
  .mps .site-tabbar { display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 55; height: var(--app-bottom-inset, 68px); padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }
  /* Never move the bar with a transform (no script "correction" either).
   * When iOS WebKit keeps a stale visual viewport after the keyboard closes,
   * it draws fixed elements up by the slack AND draws nothing of them below
   * the stale viewport's bottom; translating the bar back down (#674) put
   * most of it in that undrawn band, so it vanished (bug 84ba437e). */
  /* The tab bar steps aside while a sheet is open or the trainer is typing.
   * With the keyboard up, iOS can carry fixed bars up above it, where the
   * bar sat over the round report sheet and the field being filled. */
  .mps.mps-tabbed:has(.sheet-backdrop) .site-tabbar,
  .mps.mps-tabbed:has(:is(input:not([type="checkbox"], [type="radio"], [type="button"], [type="submit"], [type="reset"], [type="range"], [type="color"], [type="file"], [type="image"]), textarea, select, [contenteditable="true"]):focus) .site-tabbar { display: none; }
}
/* Narrow phones: every label ("Log a game" the longest) fits a fifth of 360px. */
@media (max-width: 389px) {
  .mps .tab > span { font-size: 10px; letter-spacing: -0.02em; }
  .mps .tabbar { padding-left: max(4px, env(safe-area-inset-left, 0px)); padding-right: max(4px, env(safe-area-inset-right, 0px)); gap: 0; }
}
@media (max-width: 339px) {
  .mps .nav-top .wordmark-text { display: none; }
}

/* Notifications hint (components/shell/PushHint.tsx): one line in flow just
 * under the top bar, so it never covers content or the phone tab bar.
 * Side padding clears the notch in landscape. */
.mps .push-hint { padding: 8px max(var(--gutter), env(safe-area-inset-right, 0px)) 8px max(var(--gutter), env(safe-area-inset-left, 0px)); background: var(--accent-soft); color: var(--text); border-bottom: 1px solid var(--border); font-size: 14px; line-height: 1.35; }
.mps .push-hint > * { max-width: calc(1280px - 2 * var(--gutter)); margin-left: auto; margin-right: auto; }
.mps .push-hint-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.mps .push-hint-icon { display: inline-flex; flex: none; color: var(--accent); }
.mps .push-hint-text { flex: 1 1 auto; min-width: 0; margin: 0; overflow-wrap: anywhere; }
.mps .push-hint-x { margin-right: -6px; color: var(--text-muted); }
.mps .push-hint-steps { margin-top: 8px; margin-bottom: 2px; padding-left: 52px; display: grid; gap: 4px; font-size: 13px; color: var(--text-muted); }
.mps .push-hint-steps strong { color: var(--text); }
.mps .push-hint-note { margin-top: 6px; margin-bottom: 0; padding-left: 28px; font-size: 13px; color: var(--text-muted); }
@media (max-width: 599px) {
  .mps .push-hint { font-size: 13px; }
  .mps .push-hint-row { gap: 8px; }
  .mps .push-hint-icon { display: none; }
  .mps .push-hint-steps { padding-left: 20px; }
  .mps .push-hint-note { padding-left: 0; }
}

/* /edit competitive pages on beta: no section sidebar (the top nav and tab
 * bar cover it), so the content takes the design's page column. */
.mps .competitive-shell--beta { display: block; width: 100%; max-width: 1280px; margin: 0 auto; padding: 20px var(--gutter) 80px; }
@media (min-width: 1024px) { .mps .competitive-shell--beta { padding-top: 28px; } }

/* ===================================================================
 * 17. Route enter: skeleton → content
 *    Each beta page's root carries .mps-enter (HomeView's main.rl, BtRoot,
 *    the events/meta module roots, My decks, My meta). When a route's
 *    content replaces its loading skeleton (loading.tsx or an in-page
 *    <Suspense>), that root is a freshly inserted element, so this
 *    animation runs once: opacity only (no layout shift), 120ms ease-out.
 *    It does NOT re-run on a client re-render or router.refresh() — React
 *    keeps the same element, and a CSS animation only starts when an
 *    element starts being rendered. (Next's hidden back/forward cache
 *    un-hides a page with display, which replays it: that's a navigation
 *    too.) Skeleton roots don't carry the class, so they appear at once.
 *    Reduced motion: no animation at all.
 * =================================================================== */

@keyframes mps-enter { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: no-preference) {
  .mps .mps-enter { animation: mps-enter 120ms ease-out; }
}

/* <html> background for Safari 26's toolbar tint (see the note above
 * `html { background-color }` in globals.css): Safari samples <body> first
 * and falls back to <html>, and the overscroll area paints <html>. The
 * tokens live on body.mps, so <html> would otherwise keep the classic --bg.
 * Same three theme states as the token blocks; SCORECARD_TOKENS bg values
 * (tests/unit/theme-color.test.ts checks they match). */
html:has(> body.mps) { background-color: #f6f5f2; }
:root[data-theme="dark"]:has(> body.mps) { background-color: #141318; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):has(> body.mps) { background-color: #141318; }
}
