/* playscbw design system — shared verbatim by Vite and Rails/Propshaft.
 * Own all visual decisions here. Consumers own layout and behavior, never another palette.
 * Plain CSS custom properties are also Tailwind v4's runtime theme API. See README.md. */
@font-face {
  font-family: 'SC Display'; font-style: normal; font-weight: 100 900; font-display: swap;
  src: url("/assets/fonts/oxanium-92a7f628.woff2") format('woff2');
}
@font-face {
  font-family: 'SC Text'; font-style: normal; font-weight: 200 900; font-display: swap;
  src: url("/assets/fonts/source-sans-3-1e0f9d50.woff2") format('woff2');
}
/* The in-game console's pixel text. Brood War's own bitmap fonts ship encrypted and are not ours
 * to redistribute, so the console has its own: SC Console (1-px strokes, capitals 7 px, 11 px em, so
 * `font-size: 11px` is one font pixel per CSS pixel) and SC Console Block (the big rounded numbers
 * of an empty queue slot, 17 px). Both are original designs, generated by tools/pixel_fonts.py.
 * Cyrillic and Greek, which SC Console does not draw, come from DotGothic16 (SIL OFL 1.1). */
@font-face {
  font-family: 'SC Console'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/assets/fonts/sc-console-b39d9cdd.woff2") format('woff2');
}
@font-face {
  font-family: 'SC Console Block'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/assets/fonts/sc-console-block-3c4097e4.woff2") format('woff2');
}
@font-face {
  font-family: 'SC Pixel'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("/assets/fonts/dotgothic16-d726b384.woff2") format('woff2'); unicode-range: U+0370-04FF;
}

:root {
  --sc-void: #030609;
  --sc-bg: #080e17;
  --sc-panel: #101e2c;
  --sc-raised: #1c3246;
  --sc-edge: #3c607b;
  --sc-edge-bright: #739ab7;
  --sc-ink: #cce1ff;
  --sc-muted: #99abc0;
  /* The one select caret (a chevron in --sc-muted): drawn by the select rule below, so every
   * <select> in both halves points down in the same place. */
  --sc-select-caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%2399abc0' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5.5 7.75 4.5 4.5 4.5-4.5'/%3E%3C/svg%3E");
  --sc-ice: #99ccff;
  --sc-gold: #ffdd99;
  --sc-gold-edge: #9d7942;
  --sc-gold-well: #302719;
  --sc-danger: #f59586;
  --sc-success: #9bcf85;
  --sc-shield: #7cc4ff;
  --sc-energy: #c084fc;
  --sc-mineral: #29b6ff;   /* mineral fields on the match map: the minimap's blue, saturated past every seat colour */
  --sc-gas: #3ee06b;       /* vespene geysers: the minimap's green, likewise */
  --sc-white: #fff;
  --sc-black: #000;
  --sc-font-body: 'SC Text', 'Noto Sans', 'Noto Sans CJK KR', 'Noto Sans CJK JP', 'Noto Sans CJK SC', system-ui, sans-serif;
  --sc-font-display: 'SC Display', var(--sc-font-body);
  --sc-font-mono: ui-monospace, SFMono-Regular, Consolas, monospace;
  --sc-font-pixel: 'SC Console', 'SC Pixel', var(--sc-font-body);
  --sc-font-pixel-block: 'SC Console Block', var(--sc-font-pixel); /* digits only */
  --sc-space-1: 4px;
  --sc-space-2: 8px;
  --sc-space-3: 12px;
  --sc-space-4: 16px;
  --sc-space-6: 24px;
  --sc-space-8: 32px;
  --sc-space-12: 48px;
  --sc-radius: 2px;
  --sc-control-height: 44px;
  /* The site's one width: the navbar, the footer and every page's content share this column —
   * the content at most --sc-page-content wide, never closer than --sc-page-gutter to the
   * viewport's edge. `.sc-container` is its only consumer; nothing else sets a page width. */
  --sc-page-content: 1432px;
  --sc-page-gutter: 24px;
  --sc-fast: 140ms;
  --sc-shadow: 0 20px 80px #000a;
  --sc-bevel: inset 0 1px 0 #ffffff26, inset 0 0 0 3px #0003, inset 0 -2px 0 #0008;
  --sc-metal: repeating-linear-gradient(0deg, #ffffff02 0 1px, transparent 1px 4px), linear-gradient(115deg, #ffffff04, transparent 45%), linear-gradient(var(--sc-panel), var(--sc-bg));
  --sc-backdrop: radial-gradient(ellipse at 50% -20%, #37699a40, transparent 65%),
    radial-gradient(1px 1px at 17% 21%, #b9d7f980 95%, transparent),
    radial-gradient(1px 1px at 79% 37%, #b9d7f950 95%, transparent),
    radial-gradient(1px 1px at 38% 73%, #b9d7f940 95%, transparent), var(--sc-bg);
  /* Race identity, wherever a RACE is named rather than a seat: the strategy articles, the race
   * cards, a player's race in a list. Stated once here — they used to be re-pointed at the first
   * three seat colours further down the file, which tied the identity of a race to a palette whose
   * whole job is telling two players in one game apart. */
  --sc-race-terran: #7dc8ff;
  --sc-race-protoss: #efd36b;
  --sc-race-zerg: #c49cff;
  --sc-terran-edge: #64717b; --sc-terran-glow: #c3b25d; --sc-terran-panel: #20262b;
  --sc-zerg-edge: #80503b; --sc-zerg-glow: #cba666; --sc-zerg-panel: #30201e;
  --sc-protoss-edge: #b3a554; --sc-protoss-glow: #69baff; --sc-protoss-panel: #072745;
  /* Art surfaces: the ground behind compositions and the shade laid over artwork. The artwork
   * is dark in every theme, so these deliberately have no light-theme override. */
  --sc-ground: #07101b;
  --sc-shade: #040c17;
  --sc-scrim: #02060dde;
  /* Seat colours for charts, maps and player summaries (seat index 0–7). Their only job is to tell
   * the sides of ONE game apart, at a glance, anywhere on the page. They sit where the rest of
   * this palette sits — light, three quarters saturated, at home on the navy — because a neon pair
   * reads as a warning, not as two players; what separates them is hue, not loudness.
   * The first two are the duel and they are the oldest pair in the genre: green for the first
   * player, red for the second. The green is a LIME, pulled away from the geyser green the minimap
   * owns (--sc-gas), which a straight spring green would have been mistaken for on every map.
   * They are deliberately a step apart in LIGHTNESS as well as hue (the green is the lighter of
   * the two), because red and green is the one pair eight per cent of men cannot separate — where
   * that matters the page never leans on colour alone: the result chip is filled with a check or
   * outlined with a cross, the map tells things apart by shape, and momentum writes each side's
   * name on its own half of the chart.
   * Three colours are spoken for and none of these may be mistaken for them: the minimap's mineral
   * blue (--sc-mineral) and geyser green (--sc-gas) — which is why seat 1 is a LIME green, pulled
   * clear of the geysers a straight spring green would have sat among on every map — and the gold
   * this product spends on its calls to action (--sc-gold). The sky blue that used to be seat 0
   * now sits at the end, where a game needs eight seats before it is drawn beside a crystal
   * field. */
  --sc-player-0: #a9f06a; --sc-player-1: #f04a4a; --sc-player-2: #cd8bfa; --sc-player-3: #7ad9c8;
  --sc-player-4: #ded18f; --sc-player-5: #b9a6ff; --sc-player-6: #a4dc91; --sc-player-7: #7dc8ff;
  /* Scrollbars. Defined as tokens so a surface that wants a heavier or quieter bar overrides
   * these on itself rather than restating the rule; both follow the theme through --sc-edge. */
  --sc-scroll-thumb: var(--sc-edge);
  --sc-scroll-track: transparent;
}

/* Scroll areas follow the palette everywhere — the game's modals and tables, and every Rails
 * page — from this one declaration. Both properties INHERIT, so putting them on :root reaches
 * every scroll container in both halves; there is no class for a surface to remember, and a
 * surface that wants a different bar sets --sc-scroll-thumb/-track on itself.
 * :root rather than html[data-sc-platform] deliberately: that attribute is a Rails layout hook
 * (the game never sets it), and this has to reach the game too.
 * The standard properties rather than ::-webkit-scrollbar: Chrome ignores those pseudo-elements
 * as soon as scrollbar-color is set, so shipping both would mean two treatments drifting apart
 * for no gain. Support matches the floor this file already assumes with :has() and color-mix(). */
:root {
  scrollbar-width: thin;
  scrollbar-color: var(--sc-scroll-thumb) var(--sc-scroll-track);
}

/* An explicit existing light preference remains usable, in the same blue/gold system.
 * The default web experience is dark; native still follows the system preference. */
html[data-sc-platform][data-theme='light'] {
  --sc-bg: #e5edf4; --sc-void: #f6f9fc; --sc-panel: #d6e2ec; --sc-raised: #c1d4e3;
  --sc-ink: #142b42; --sc-muted: #435f76; --sc-edge: #839eaf; --sc-edge-bright: #526f87;
  --sc-select-caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23435f76' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5.5 7.75 4.5 4.5 4.5-4.5'/%3E%3C/svg%3E");
  --sc-ice: #245785; --sc-gold: #725018; --sc-gold-well: #f2e2bb;
  --sc-danger: #9c3528; --sc-success: #37642c;
}

/* Legacy Tailwind utilities resolve to the SAME tokens, including template-owned views.
 * Keep aliases here rather than copying a second theme into the Rails application. */
html[data-sc-platform][data-theme] {
  --font-sans: var(--sc-font-body);
  --font-serif: var(--sc-font-display);
  --font-mono: var(--sc-font-mono);
  --color-white: var(--sc-panel); --color-black: var(--sc-ink);
  --color-gray-50: var(--sc-bg); --color-gray-100: var(--sc-raised);
  --color-gray-200: var(--sc-edge); --color-gray-300: var(--sc-edge-bright);
  --color-gray-400: var(--sc-muted); --color-gray-500: var(--sc-muted);
  --color-gray-600: var(--sc-muted); --color-gray-700: var(--sc-ink);
  --color-gray-800: var(--sc-ink); --color-gray-900: var(--sc-ink); --color-gray-950: var(--sc-ink);
  --color-slate-50: var(--color-gray-50); --color-slate-100: var(--color-gray-100); --color-slate-200: var(--color-gray-200); --color-slate-300: var(--color-gray-300); --color-slate-400: var(--color-gray-400); --color-slate-500: var(--color-gray-500); --color-slate-600: var(--color-gray-600); --color-slate-700: var(--color-gray-700); --color-slate-800: var(--color-gray-800); --color-slate-900: var(--color-gray-900); --color-slate-950: var(--color-gray-950);
  --color-zinc-50: var(--color-gray-50); --color-zinc-100: var(--color-gray-100); --color-zinc-200: var(--color-gray-200); --color-zinc-300: var(--color-gray-300); --color-zinc-400: var(--color-gray-400); --color-zinc-500: var(--color-gray-500); --color-zinc-600: var(--color-gray-600); --color-zinc-700: var(--color-gray-700); --color-zinc-800: var(--color-gray-800); --color-zinc-900: var(--color-gray-900); --color-zinc-950: var(--color-gray-950);
  --color-neutral-50: var(--color-gray-50); --color-neutral-100: var(--color-gray-100); --color-neutral-200: var(--color-gray-200); --color-neutral-300: var(--color-gray-300); --color-neutral-400: var(--color-gray-400); --color-neutral-500: var(--color-gray-500); --color-neutral-600: var(--color-gray-600); --color-neutral-700: var(--color-gray-700); --color-neutral-800: var(--color-gray-800); --color-neutral-900: var(--color-gray-900); --color-neutral-950: var(--color-gray-950);
  --color-stone-50: var(--color-gray-50); --color-stone-100: var(--color-gray-100); --color-stone-200: var(--color-gray-200); --color-stone-300: var(--color-gray-300); --color-stone-400: var(--color-gray-400); --color-stone-500: var(--color-gray-500); --color-stone-600: var(--color-gray-600); --color-stone-700: var(--color-gray-700); --color-stone-800: var(--color-gray-800); --color-stone-900: var(--color-gray-900); --color-stone-950: var(--color-gray-950);
  --color-blue-50: var(--sc-panel); --color-blue-100: var(--sc-raised); --color-blue-200: var(--sc-edge); --color-blue-300: var(--sc-edge); --color-blue-400: var(--sc-ice); --color-blue-500: var(--sc-ice); --color-blue-600: var(--sc-ice); --color-blue-700: var(--sc-ice); --color-blue-800: var(--sc-ice); --color-blue-900: var(--sc-ice); --color-blue-950: var(--sc-ice);
  --color-sky-50: var(--sc-panel); --color-sky-100: var(--sc-raised); --color-sky-200: var(--sc-edge); --color-sky-300: var(--sc-edge); --color-sky-400: var(--sc-ice); --color-sky-500: var(--sc-ice); --color-sky-600: var(--sc-ice); --color-sky-700: var(--sc-ice); --color-sky-800: var(--sc-ice); --color-sky-900: var(--sc-ice); --color-sky-950: var(--sc-ice);
  --color-cyan-50: var(--sc-panel); --color-cyan-100: var(--sc-raised); --color-cyan-200: var(--sc-edge); --color-cyan-300: var(--sc-edge); --color-cyan-400: var(--sc-ice); --color-cyan-500: var(--sc-ice); --color-cyan-600: var(--sc-ice); --color-cyan-700: var(--sc-ice); --color-cyan-800: var(--sc-ice); --color-cyan-900: var(--sc-ice); --color-cyan-950: var(--sc-ice);
  --color-indigo-50: var(--sc-panel); --color-indigo-100: var(--sc-raised); --color-indigo-200: var(--sc-edge); --color-indigo-300: var(--sc-edge); --color-indigo-400: var(--sc-ice); --color-indigo-500: var(--sc-ice); --color-indigo-600: var(--sc-ice); --color-indigo-700: var(--sc-ice); --color-indigo-800: var(--sc-ice); --color-indigo-900: var(--sc-ice); --color-indigo-950: var(--sc-ice);
  --color-violet-50: var(--sc-panel); --color-violet-100: var(--sc-raised); --color-violet-200: var(--sc-edge); --color-violet-300: var(--sc-edge); --color-violet-400: var(--sc-ice); --color-violet-500: var(--sc-ice); --color-violet-600: var(--sc-ice); --color-violet-700: var(--sc-ice); --color-violet-800: var(--sc-ice); --color-violet-900: var(--sc-ice); --color-violet-950: var(--sc-ice);
  --color-purple-50: var(--sc-panel); --color-purple-100: var(--sc-raised); --color-purple-200: var(--sc-edge); --color-purple-300: var(--sc-edge); --color-purple-400: var(--sc-ice); --color-purple-500: var(--sc-ice); --color-purple-600: var(--sc-ice); --color-purple-700: var(--sc-ice); --color-purple-800: var(--sc-ice); --color-purple-900: var(--sc-ice); --color-purple-950: var(--sc-ice);
  --color-fuchsia-50: var(--sc-panel); --color-fuchsia-100: var(--sc-raised); --color-fuchsia-200: var(--sc-edge); --color-fuchsia-300: var(--sc-edge); --color-fuchsia-400: var(--sc-ice); --color-fuchsia-500: var(--sc-ice); --color-fuchsia-600: var(--sc-ice); --color-fuchsia-700: var(--sc-ice); --color-fuchsia-800: var(--sc-ice); --color-fuchsia-900: var(--sc-ice); --color-fuchsia-950: var(--sc-ice);
  --color-pink-50: var(--sc-panel); --color-pink-100: var(--sc-raised); --color-pink-200: var(--sc-edge); --color-pink-300: var(--sc-edge); --color-pink-400: var(--sc-ice); --color-pink-500: var(--sc-ice); --color-pink-600: var(--sc-ice); --color-pink-700: var(--sc-ice); --color-pink-800: var(--sc-ice); --color-pink-900: var(--sc-ice); --color-pink-950: var(--sc-ice);
  --color-orange-50: var(--sc-panel); --color-orange-100: var(--sc-raised); --color-orange-200: var(--sc-edge); --color-orange-300: var(--sc-edge); --color-orange-400: var(--sc-gold); --color-orange-500: var(--sc-gold); --color-orange-600: var(--sc-gold); --color-orange-700: var(--sc-gold); --color-orange-800: var(--sc-gold); --color-orange-900: var(--sc-gold); --color-orange-950: var(--sc-gold);
  --color-amber-50: var(--sc-panel); --color-amber-100: var(--sc-raised); --color-amber-200: var(--sc-edge); --color-amber-300: var(--sc-edge); --color-amber-400: var(--sc-gold); --color-amber-500: var(--sc-gold); --color-amber-600: var(--sc-gold); --color-amber-700: var(--sc-gold); --color-amber-800: var(--sc-gold); --color-amber-900: var(--sc-gold); --color-amber-950: var(--sc-gold);
  --color-yellow-50: var(--sc-panel); --color-yellow-100: var(--sc-raised); --color-yellow-200: var(--sc-edge); --color-yellow-300: var(--sc-edge); --color-yellow-400: var(--sc-gold); --color-yellow-500: var(--sc-gold); --color-yellow-600: var(--sc-gold); --color-yellow-700: var(--sc-gold); --color-yellow-800: var(--sc-gold); --color-yellow-900: var(--sc-gold); --color-yellow-950: var(--sc-gold);
  --color-red-50: var(--sc-panel); --color-red-100: var(--sc-raised); --color-red-200: var(--sc-edge); --color-red-300: var(--sc-edge); --color-red-400: var(--sc-danger); --color-red-500: var(--sc-danger); --color-red-600: var(--sc-danger); --color-red-700: var(--sc-danger); --color-red-800: var(--sc-danger); --color-red-900: var(--sc-danger); --color-red-950: var(--sc-danger);
  --color-rose-50: var(--sc-panel); --color-rose-100: var(--sc-raised); --color-rose-200: var(--sc-edge); --color-rose-300: var(--sc-edge); --color-rose-400: var(--sc-danger); --color-rose-500: var(--sc-danger); --color-rose-600: var(--sc-danger); --color-rose-700: var(--sc-danger); --color-rose-800: var(--sc-danger); --color-rose-900: var(--sc-danger); --color-rose-950: var(--sc-danger);
  --color-green-50: var(--sc-panel); --color-green-100: var(--sc-raised); --color-green-200: var(--sc-edge); --color-green-300: var(--sc-edge); --color-green-400: var(--sc-success); --color-green-500: var(--sc-success); --color-green-600: var(--sc-success); --color-green-700: var(--sc-success); --color-green-800: var(--sc-success); --color-green-900: var(--sc-success); --color-green-950: var(--sc-success);
  --color-emerald-50: var(--sc-panel); --color-emerald-100: var(--sc-raised); --color-emerald-200: var(--sc-edge); --color-emerald-300: var(--sc-edge); --color-emerald-400: var(--sc-success); --color-emerald-500: var(--sc-success); --color-emerald-600: var(--sc-success); --color-emerald-700: var(--sc-success); --color-emerald-800: var(--sc-success); --color-emerald-900: var(--sc-success); --color-emerald-950: var(--sc-success);
  --color-lime-50: var(--sc-panel); --color-lime-100: var(--sc-raised); --color-lime-200: var(--sc-edge); --color-lime-300: var(--sc-edge); --color-lime-400: var(--sc-success); --color-lime-500: var(--sc-success); --color-lime-600: var(--sc-success); --color-lime-700: var(--sc-success); --color-lime-800: var(--sc-success); --color-lime-900: var(--sc-success); --color-lime-950: var(--sc-success);
  --color-teal-50: var(--sc-panel); --color-teal-100: var(--sc-raised); --color-teal-200: var(--sc-edge); --color-teal-300: var(--sc-edge); --color-teal-400: var(--sc-success); --color-teal-500: var(--sc-success); --color-teal-600: var(--sc-success); --color-teal-700: var(--sc-success); --color-teal-800: var(--sc-success); --color-teal-900: var(--sc-success); --color-teal-950: var(--sc-success);
  --radius-sm: var(--sc-radius); --radius-md: var(--sc-radius); --radius-lg: var(--sc-radius); --radius-xl: var(--sc-radius); --radius-2xl: var(--sc-radius); --radius-3xl: var(--sc-radius);
}

/* Components. sc-ui opts a form/popup into the shared primitives; the battlefield's
 * original command-card art deliberately does not inherit generic form-button sizes. */
.sc-ui, .sc-surface, .sc-backdrop { color: var(--sc-ink); font-family: var(--sc-font-body); }
.sc-backdrop { background: var(--sc-backdrop); }
.sc-surface, .sc-ui :where(dialog, [role='dialog']) {
  border: 1px solid var(--sc-edge); border-radius: var(--sc-radius);
  background: var(--sc-metal); box-shadow: var(--sc-shadow), var(--sc-bevel);
}
.sc-ui :where(h1, h2, h3, h4), .sc-heading {
  font-family: var(--sc-font-display); font-weight: 600; line-height: 1.2;
  color: var(--sc-ink); letter-spacing: .025em;
}
.sc-ui :where(h1), .sc-heading { font-size: clamp(24px, 3vw, 36px); }
.sc-ui :where(h2) { font-size: 22px; }
.sc-ui :where(h3) { font-size: 16px; }
.sc-brand {
  display: block; font: 700 clamp(28px, 5vw, 56px)/1.1 var(--sc-font-display);
  letter-spacing: .06em; color: var(--sc-ink);
  text-shadow: 0 2px 0 var(--sc-black), 0 0 32px color-mix(in srgb, var(--sc-ice) 24%, transparent);
}
.sc-brand.sc-brand-small { font-size: 20px; }
.sc-kicker { font: 500 11px/1.5 var(--sc-font-display); letter-spacing: .2em; text-transform: uppercase; color: var(--sc-gold); }
/* The default link — ice, gold under the pointer — in a cascade layer of its own, because it is
 * a default: anything that styles a link on purpose must win over it. Unlayered, it beat every
 * layered rule that coloured a link (all of the Rails host's Tailwind), whatever that rule's
 * specificity — `:where()` alone cannot make a rule lose to a layer. A host with layers of its own
 * declares where `sc-defaults` sits (Rails puts it under its components); with none, it simply
 * sits under everything unlayered, which is where a default belongs. */
@layer sc-defaults {
  .sc-ui :where(a) { color: var(--sc-ice); text-underline-offset: 4px; }
  .sc-ui :where(a:hover) { color: var(--sc-gold); }
}
.sc-ui :where(button, input, select, textarea) { font: inherit; }
.sc-ui :where(button, input[type='submit'], input[type='button']), .sc-button {
  align-items: center; justify-content: center; gap: var(--sc-space-2);
  min-height: var(--sc-control-height); padding: 10px 20px;
  border: 1px solid var(--sc-edge); border-radius: var(--sc-radius);
  background: var(--sc-metal); box-shadow: var(--sc-bevel); color: var(--sc-ink);
  font: 600 13px/1.3 var(--sc-font-display); letter-spacing: .045em; text-decoration: none;
  cursor: pointer; transition: border-color var(--sc-fast), color var(--sc-fast), background-color var(--sc-fast);
}
.sc-ui :where(button:hover, input[type='submit']:hover), .sc-button:hover {
  color: var(--sc-gold); border-color: var(--sc-gold-edge); background-color: var(--sc-raised);
}
.sc-button { display: inline-flex; }
.sc-button.sc-primary, .sc-ui :where(button.primary, input[type='submit'], .menu-resume, .lobby-play) {
  color: var(--sc-gold); border-color: var(--sc-gold-edge);
  background: linear-gradient(#ffffff09, transparent), var(--sc-gold-well);
}
.sc-ui :where(.menu-surrender, [data-tone='danger']) { color: var(--sc-danger); }
.sc-ui :where(button:disabled, input:disabled, select:disabled) { opacity: .45; cursor: default; }
.sc-ui :where(input:not([type='checkbox'], [type='radio'], [type='range'], [type='submit'], [type='button']), select, textarea), .sc-field {
  min-width: 0; max-width: 100%; min-height: var(--sc-control-height); padding: 9px 12px;
  border: 1px solid var(--sc-edge); border-radius: var(--sc-radius);
  background: var(--sc-void); color: var(--sc-ink); box-shadow: inset 0 2px 5px #0004;
}
/* THE select: the field above, with its native arrow replaced by the design system's caret in
 * its own gutter — the browser's arrow sat against the border, a different glyph per platform. A
 * list box (multiple / size) keeps its native look: it has no arrow to draw. */
.sc-ui :where(select:not([multiple], [size])), select.sc-field {
  appearance: none; -webkit-appearance: none;
  padding-right: 40px; cursor: pointer;
  background-image: var(--sc-select-caret); background-repeat: no-repeat;
  background-position: right 12px center; background-size: 18px 18px;
}
.sc-ui :where(select:not([multiple], [size]):hover), select.sc-field:hover { border-color: var(--sc-edge-bright); }
.sc-ui :where(input::placeholder, textarea::placeholder) { color: var(--sc-muted); }
.sc-ui :where(input[type='checkbox'], input[type='radio']) { width: 18px; height: 18px; accent-color: var(--sc-gold); }
/* Safari draws its own slider and ignores `accent-color` on a range, so a volume control came
 * out with a grey knob and no visible track on the dark panels. Every engine draws the same
 * control instead: a dark capsule, a muted gold fill and a gold knob ringed in the panel colour.
 * WebKit has no track-progress pseudo-element, so the fill is the thumb's own shadow, clipped by
 * the track's `overflow`; the knob fits inside the track's height so the clip never eats it. */
.sc-ui :where(input[type='range']) {
  width: 100%; min-width: 0; height: 28px; padding: 0; cursor: pointer;
  appearance: none; -webkit-appearance: none; background: transparent;
}
.sc-ui input[type='range']::-webkit-slider-runnable-track {
  height: 16px; border-radius: 8px; background: var(--sc-void); border: 1px solid var(--sc-edge); overflow: hidden;
}
.sc-ui input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; box-sizing: border-box;
  width: 16px; height: 16px; border-radius: 50%; background: var(--sc-gold); border: 3px solid var(--sc-void);
  box-shadow: -100vw 0 0 100vw color-mix(in srgb, var(--sc-gold) 45%, transparent);
}
.sc-ui input[type='range']::-moz-range-track {
  height: 16px; border-radius: 8px; background: var(--sc-void); border: 1px solid var(--sc-edge);
}
.sc-ui input[type='range']::-moz-range-progress {
  height: 16px; border-radius: 8px 0 0 8px; background: color-mix(in srgb, var(--sc-gold) 45%, transparent);
}
.sc-ui input[type='range']::-moz-range-thumb {
  box-sizing: border-box; width: 16px; height: 16px; border-radius: 50%; background: var(--sc-gold); border: 3px solid var(--sc-void);
}
.sc-ui input[type='range']:focus-visible::-webkit-slider-thumb { border-color: var(--sc-edge-bright); }
.sc-ui input[type='range']:focus-visible::-moz-range-thumb { border-color: var(--sc-edge-bright); }
.sc-ui :where(label) { color: var(--sc-muted); font-size: 14px; }
.sc-ui :where(:focus-visible), .sc-button:focus-visible {
  outline: 2px solid var(--sc-gold); outline-offset: 3px;
}
svg.sc-icon { width: 20px; height: 20px; flex-shrink: 0; }
.sc-ui svg[fill='none'] { stroke-linecap: square; stroke-linejoin: miter; }
svg.sc-icon { fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: square; stroke-linejoin: miter; }
.sc-ui :where(kbd) { font: 12px var(--sc-font-mono); color: var(--sc-gold); }
.sc-keycaps kbd {
  display: inline-flex; align-items: center; justify-content: center; min-width: 30px; min-height: 30px;
  padding: 4px 8px; border: 1px solid var(--sc-edge-bright); border-bottom-width: 3px;
  border-radius: 3px; color: var(--sc-ink); background: var(--sc-metal); box-shadow: inset 0 1px #ffffff20;
  font: 500 12px/1.3 var(--sc-font-mono); white-space: nowrap;
}
.sc-keycaps .key-combination { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
/* Inline hint next to running text: the cap should read as a key, not as a button. */
.sc-keycaps-small kbd { min-width: 0; min-height: 0; padding: 1px 5px; border-bottom-width: 2px; font-size: 10px; line-height: 1.4; }
.sc-keycaps .key-separator { color: var(--sc-muted); font-size: 11px; }
.sc-ui :where(summary) { cursor: pointer; color: var(--sc-ice); padding: 12px 0; }
.sc-section { margin: 0; padding: var(--sc-space-4); border: 1px solid var(--sc-edge); background: var(--sc-void); min-width: 0; }
.sc-section > legend { padding: 0 var(--sc-space-2); color: var(--sc-ice); font: 500 12px var(--sc-font-display); letter-spacing: .06em; }
.sc-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--sc-space-3); }
.sc-progress {
  appearance: none; display: block; width: 100%; height: 12px; padding: 2px; overflow: hidden;
  border: 1px solid var(--sc-edge); border-radius: 0; background: var(--sc-void);
}
.sc-progress::-webkit-progress-bar { background: var(--sc-void); }
.sc-progress::-webkit-progress-value { background: linear-gradient(var(--sc-ink), var(--sc-ice)); transition: width var(--sc-fast); }
.sc-progress::-moz-progress-bar { background: linear-gradient(var(--sc-ink), var(--sc-ice)); }
/* `sc-progress-live`: work is happening but its pace is unknown. The track carries a travelling
 * sheen and the filled part is striped and lit at its leading edge, so a bar that is between
 * reports still reads as moving rather than stuck. Reduced motion stills all of it. */
.sc-progress-live { background-image: linear-gradient(90deg, transparent, color-mix(in srgb, var(--sc-ice) 22%, transparent), transparent); background-size: 45% 100%; background-repeat: no-repeat; animation: sc-progress-scan 1.8s linear infinite; }
.sc-progress-live::-webkit-progress-bar { background: transparent; }
.sc-progress-live::-webkit-progress-value {
  background-image: repeating-linear-gradient(115deg, #ffffff1f 0 10px, transparent 10px 20px), linear-gradient(var(--sc-ink), var(--sc-ice));
  background-size: 40px 100%, auto; box-shadow: 6px 0 14px color-mix(in srgb, var(--sc-ice) 65%, transparent);
  animation: sc-progress-stripes .7s linear infinite;
}
.sc-progress-live::-moz-progress-bar {
  background-image: repeating-linear-gradient(115deg, #ffffff1f 0 10px, transparent 10px 20px), linear-gradient(var(--sc-ink), var(--sc-ice));
  background-size: 40px 100%, auto; animation: sc-progress-stripes .7s linear infinite;
}
@keyframes sc-progress-stripes { to { background-position: 40px 0, 0 0; } }
@keyframes sc-progress-scan { from { background-position: -50% 0; } to { background-position: 150% 0; } }
/* Rotating ring: something on screen is always turning while the game loads. */
.sc-spinner {
  display: block; width: 26px; height: 26px; border: 2px solid color-mix(in srgb, var(--sc-edge) 70%, transparent);
  border-top-color: var(--sc-ice); border-radius: 50%; animation: sc-spin 900ms linear infinite;
}
.sc-spinner-small { width: 14px; height: 14px; border-width: 1.5px; }
@keyframes sc-spin { to { transform: rotate(360deg); } }

/* Modal. ONE dialog treatment and structure for the whole product — the game's menus, help,
 * pause and result screens and the platform's dialogs all use it (web/src/ui/modal.ts owns the
 * behaviour). Structure: .sc-modal > .sc-modal-head / .sc-modal-body / .sc-modal-foot, with the
 * body the only scrolling part, so headings and actions stay put. A dialog whose only child is a
 * form puts the column on the form instead. */
.sc-modal {
  min-width: 0; width: min(680px, calc(100% - 32px)); max-width: none; max-height: calc(100dvh - 32px);
  margin: auto; padding: 0; overflow: hidden; color: var(--sc-ink); font-size: 15px;
  border: 1px solid var(--sc-edge); border-radius: var(--sc-radius);
  background: var(--sc-metal); box-shadow: var(--sc-shadow), var(--sc-bevel);
}
/* A column, not a grid: WebKit gives an open dialog that is a grid container its max-height
 * instead of the height of its content, which left every modal a full-height panel in Safari —
 * the paused notice, with one short line in it, most visibly. Flex sizes to content everywhere,
 * and the body is still the one part that takes the leftover room and scrolls. */
.sc-modal[open], .sc-modal[open] > form:only-child { display: flex; flex-direction: column; min-height: 0; }
.sc-modal[open] > form:only-child { flex: 1 1 auto; }
.sc-modal-head { flex: none; padding: 24px 28px 20px; border-bottom: 1px solid var(--sc-edge); }
.sc-modal-head :where(h1, h2) { margin: 0; }
.sc-modal-body { flex: 1 1 auto; min-height: 0; padding: 24px 28px; overflow-y: auto; overscroll-behavior: contain; scroll-padding: 20px; }
.sc-modal-foot { flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--sc-space-3); padding: 16px 28px; border-top: 1px solid var(--sc-edge); background: var(--sc-panel); }
.sc-modal-wide { width: min(1180px, calc(100% - 40px)); }
/* Alert: one short, unmissable statement (the paused game), centred in the viewport. */
.sc-modal-alert { width: min(560px, calc(100% - 32px)); text-align: center; }
.sc-modal-alert .sc-modal-body { display: grid; justify-items: center; gap: 12px; padding: 40px 32px 32px; }
.sc-modal-alert .sc-display { --sc-display-size: clamp(34px, 6vw, 52px); color: var(--sc-gold); }
.sc-modal-alert p { margin: 0; color: var(--sc-muted); font-size: 14px; }
/* A disclosure that reads as the control it is (the surrender confirmation). */
/* Beats `.sc-ui :where(summary)`, which would otherwise strip the button's padding. */
summary.sc-button { display: inline-flex; list-style: none; padding: 10px 20px; }
summary.sc-button::-webkit-details-marker { display: none; }
.sc-button[data-tone='danger'] { color: var(--sc-danger); border-color: color-mix(in srgb, var(--sc-danger) 55%, var(--sc-edge)); }
.sc-button[data-tone='danger']:hover { color: var(--sc-danger); border-color: var(--sc-danger); background-color: color-mix(in srgb, var(--sc-danger) 12%, transparent); }

/* Rails adapter: only semantic mappings/structure. All colors, fonts and treatments above
 * are shared with the game. Template classes are supported without editing railsfast/. */
/* The scheme is declared on the ROOT, not only on the body: the browser reads it before any of
 * our paint, so scrollbars, form controls and the canvas behind the page follow the theme, and
 * anything that asks a page whether it is already dark — Chrome's auto-dark, an extension that
 * inverts colours — gets an answer instead of a guess. The body keeps its own for older paths. */
html[data-sc-platform] { color-scheme: dark; background: var(--sc-bg); }
html[data-sc-platform][data-theme='light'] { color-scheme: light; }
html[data-sc-platform] body.sc-ui { color-scheme: dark; color: var(--sc-ink); background: var(--sc-backdrop); font-family: var(--sc-font-body); }
html[data-sc-platform][data-theme='light'] body.sc-ui { color-scheme: light; }
html[data-sc-platform] .sc-ui :is(.bg-white, [role='dialog']) { background: var(--sc-metal); border-color: var(--sc-edge); }
html[data-sc-platform] .sc-ui :is(.bg-black, .bg-gray-900, .bg-gray-950) { background: var(--sc-gold-well); color: var(--sc-gold); border-color: var(--sc-gold-edge); }
html[data-sc-platform] .sc-ui :is(button, [type='submit']) { border-radius: var(--sc-radius); }
html[data-sc-platform] .sc-ui .sc-primary { background: linear-gradient(#ffffff09, transparent), var(--sc-gold-well); color: var(--sc-gold); border-color: var(--sc-gold-edge); }
html[data-sc-platform] .sc-ui :is(.text-white, .text-black) { color: var(--sc-ink); }
html[data-sc-platform] .sc-ui :is(.bg-black, .bg-gray-900, .bg-gray-950).text-white { color: var(--sc-gold); }
html[data-sc-platform] .sc-ui :is(input, select, textarea):not([type='checkbox'], [type='radio'], [type='range'], [type='submit']) { background-color: var(--sc-void); color: var(--sc-ink); border-color: var(--sc-edge); }
.sc-site-nav { position: relative; z-index: 30; width: 100%; border-bottom: 1px solid var(--sc-edge); background: var(--sc-metal); box-shadow: var(--sc-bevel); }
.sc-site-nav > div:first-child { min-height: 72px; }
.sc-site-nav .sc-brand { font-size: 20px; letter-spacing: .08em; }
.sc-site-nav nav { font-family: var(--sc-font-display); }
.sc-site-nav button:has(svg):not(:has(span)) { padding: 8px; min-width: 44px; }
.sc-launch { width: min(960px, 100%); margin: auto; padding: clamp(32px, 7vw, 88px) 24px; }
.sc-launch > header { text-align: center; margin-bottom: 40px; }
.sc-launch > header h1 { margin: 24px 0 12px; }
.sc-launch > header p { color: var(--sc-muted); max-width: 560px; margin-inline: auto; font-size: 18px; }
.sc-launch form { padding: clamp(20px, 4vw, 40px); gap: 24px; }
.sc-launch form label { gap: 8px; }
.sc-launch form input[type='submit'] { width: 100%; margin-top: 8px; }
.sc-launch-links { display: flex; justify-content: center; gap: 32px; margin-top: 28px; font-family: var(--sc-font-display); font-size: 13px; }

/* One question, one card. Not the launch shell: a wizard asking a single thing should read as a
 * dialog the size of its content, not as a landing page with a form lost in the middle of it.
 * The card is capped at a readable measure and sits a little above centre, where the eye is. */
.sc-onboarding { width: min(460px, 100%); margin: 0 auto; padding: clamp(28px, 6vh, 56px) 20px; display: grid; align-content: center; min-height: min(72vh, 680px); }
.sc-onboarding > header { text-align: center; margin-bottom: 22px; }
.sc-onboarding > header h1 { margin: 10px 0 8px; font-size: clamp(22px, 4vw, 28px); }
.sc-onboarding-lead { color: var(--sc-muted); font-size: 14px; line-height: 1.6; margin: 0; }
.sc-onboarding form { padding: 22px; gap: 18px; }
.sc-onboarding form label { gap: 7px; }
/* 16px is the threshold below which iOS zooms the page when a field takes focus. */
.sc-onboarding :is(input, select) { font-size: 16px; }
.sc-onboarding input[type='submit'] { width: 100%; margin-top: 4px; }
/* The answer to "is this name free?", as it arrives: silent until there is something to say. */
.sc-handle-status { min-height: 1.3em; font-size: 12px; line-height: 1.3; }
.sc-handle-status[data-state='free'] { color: var(--sc-success); }
.sc-handle-status[data-state='taken'], .sc-handle-status[data-state='invalid'] { color: var(--sc-danger); }

/* Four small primitives every surface uses — the game's menus and score screen as much as the
 * platform's pages. The pages themselves (the match record, profiles, the directories) are
 * Rails-only and are styled entirely in that host's Tailwind layer — see the note beside the
 * strategy articles below for why "entirely" is the word that matters. */
.sc-muted { color:var(--sc-muted); font-size:13px; line-height:1.7; }
.sc-badge { display:inline-block; border:1px solid var(--sc-edge); padding:3px 7px; color:var(--sc-gold); font:12px var(--sc-font-mono); }
.sc-result { font:13px var(--sc-font-display); text-transform:uppercase; letter-spacing:.08em; color:var(--sc-result, var(--sc-muted)); }
.sc-back { font:12px var(--sc-font-display); letter-spacing:.08em; }
/* THE table. Every list in the product is one of these: rooms, players, ladder, match history,
 * the profile's tables and the game's score screen. Rows are quiet and wide, headings are small
 * caps, numbers are tabular, and the phone layout (each row becomes a card of labelled pairs) is
 * built in rather than opted into — a cell carries its column name in a `.sc-cell-label`.
 * Columns declare themselves: `data-numeric` right-aligns, `data-cell="primary"` is the row's
 * subject (it spans the card), `.sc-table-action` holds the row's control. */
.sc-table-scroll { overflow-x:auto; margin:16px 0; overscroll-behavior-x:contain; }
.sc-table { width:100%; border-collapse:collapse; font-size:13px; font-variant-numeric:tabular-nums; }
.sc-table :is(th,td) { padding:13px 14px; border-bottom:1px solid color-mix(in srgb,var(--sc-edge) 50%,transparent); text-align:left; vertical-align:middle; }
.sc-table thead :is(th,td) { padding-block:11px; color:var(--sc-muted); background:var(--sc-void); border-bottom-color:var(--sc-edge); font:500 11px/1.4 var(--sc-font-display); letter-spacing:.14em; text-transform:uppercase; white-space:nowrap; }
.sc-table tbody tr:last-child :is(th,td) { border-bottom:0; }
.sc-table tbody tr:hover { background:color-mix(in srgb,var(--sc-raised) 45%,transparent); }
.sc-table :is(th,td)[data-numeric] { text-align:right; white-space:nowrap; }
.sc-table :is(th,td).sc-table-action { text-align:right; white-space:nowrap; width:1%; }
.sc-table :is(th,td).sc-table-rank { width:1%; color:var(--sc-muted); font:12px var(--sc-font-mono); }
.sc-table .sc-table-group { color:var(--sc-gold); background:var(--sc-void); text-transform:uppercase; letter-spacing:.08em; font-size:11px; }
.sc-table-empty { padding:44px 20px; text-align:center; color:var(--sc-muted); }
/* A second line under a cell's main value: the room code, a timestamp, a seat's race. */
.sc-cell-sub { display:block; margin-top:3px; color:var(--sc-muted); font-size:11px; }
.sc-cell-label { display:none; }
/* `sc-table-wide` opts out of the card layout for a table that is not one-row-per-thing (the
 * match page's metric × player grid): it keeps scrolling sideways instead. */

/* The player, wherever a player appears: a list row, a seat, a score screen. Avatar is optional
 * (initials until one is uploaded), and the meta line carries flag, race and rating. */
.sc-player { display:flex; align-items:center; gap:10px; min-width:0; }
.sc-player-avatar { flex:none; width:30px; height:30px; border-radius:50%; display:grid; place-items:center; overflow:hidden; border:1px solid var(--sc-edge); background:var(--sc-void); color:var(--sc-muted); font:600 12px/1 var(--sc-font-display); }
.sc-player-avatar img { width:100%; height:100%; object-fit:cover; }
.sc-player[data-race] .sc-player-avatar { border-color:var(--sc-race); }
.sc-player[data-race='zerg'] { --sc-race:var(--sc-race-zerg); }
.sc-player[data-race='terran'] { --sc-race:var(--sc-race-terran); }
.sc-player[data-race='protoss'] { --sc-race:var(--sc-race-protoss); }
.sc-player-body { min-width:0; display:grid; gap:2px; }
.sc-player-name { color:var(--sc-ink); font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
a.sc-player-name:hover { color:var(--sc-gold); }
.sc-player-meta { display:flex; align-items:center; gap:8px; color:var(--sc-muted); font-size:11px; line-height:1.3; }
.sc-player-flag { font-size:13px; line-height:1; }
.sc-player-rating { font:12px/1 var(--sc-font-mono); color:var(--sc-ice); }
.sc-player-race { color:var(--sc-race,var(--sc-muted)); }
.sc-player-you { color:var(--sc-gold); }
.sc-table thead th.sc-table-seat { color:var(--sc-seat); }
.match-upload-status { margin:16px 0 0; color:var(--sc-muted); font-size:12px; line-height:1.6; text-align:center; }
.match-upload-status a { color:var(--sc-ice); text-decoration:underline; }

/* One result tone. The client's local outcome (victory/defeat) and Rails' seat result (win/loss)
 * are the same fact in two vocabularies, mapped once by GameResultReport::OUTCOMES. Gold stays
 * the call-to-action colour; a result is never gold. */
:where(.sector-result) { --sc-result: var(--sc-ink); }
:where([data-result='victory'], [data-result='win']) { --sc-result: var(--sc-success); }
:where([data-result='defeat'], [data-result='loss']) { --sc-result: var(--sc-danger); }

/* Display headline shared by the landing hero, the signup art panel and the result screen. */
.sc-display {
  font-family: var(--sc-font-display); font-weight: 600; font-size: var(--sc-display-size, clamp(38px, 5.2vw, 72px));
  line-height: 1.12; letter-spacing: -.035em; overflow-wrap: anywhere;
}

/* Full-bleed artwork behind a panel. The consumer sets --sc-art (and optionally --sc-art-small)
 * to url()s resolved from art.json; the shade and the small-screen switch live here. */
.sc-art-backdrop {
  --sc-art-current: var(--sc-art);
  background: linear-gradient(color-mix(in srgb, var(--sc-shade) 65%, transparent), color-mix(in srgb, var(--sc-shade) 85%, transparent)),
    var(--sc-art-current) center / cover, var(--sc-bg);
}

/* THE page column (see --sc-page-content): the navbar's row, the footer's and every page's. */
.sc-container { width:min(var(--sc-page-content), calc(100% - 2 * var(--sc-page-gutter))); margin-inline:auto; }
.sector-intro { max-width:510px; font-size:19px; line-height:1.7; color:var(--sc-ice); }
.sector-actions { display:flex; align-items:center; flex-wrap:wrap; gap:14px; margin-top:30px; }
.sector-cta { min-height:54px; min-width:180px; justify-content:space-between; gap:32px; }
.sector-footnote { font-size:12px; color:var(--sc-muted); margin-top:16px; }
.sector-directory h1:not(.sc-display) { font-size:clamp(26px,3vw,40px); line-height:1.2; margin:14px 0; }
/* The landing's race cards and the whole game-setup surface (the new-game dialog, /g/new) are
 * Rails-only — the game renders none of them — and live in Tailwind, in the host's
 * app/assets/tailwind/application.css, against the tokens above. See design/README.md. */
.sector-checks { list-style:none; padding:0; margin:24px 0 30px; }
.sector-checks li { position:relative; padding-left:24px; margin:16px 0; color:var(--sc-ice); font-size:14px; line-height:1.6; }
.sector-checks li:before { content:'◆'; position:absolute; left:0; color:var(--sc-gold); font-size:9px; top:4px; }
/* One dialog scrim for every modal: game menus, the landing's new-game dialog, the result. */
dialog.sc-surface::backdrop, .sc-modal::backdrop { background:var(--sc-scrim); backdrop-filter:blur(8px); }

/* Two-column art compositions (signup page, game result): a framed ground with an art panel —
 * portrait from art.json under the shared shade, copy anchored to the bottom. */
.sector-signup-layout,.sector-result { border:1px solid var(--sc-edge); background:var(--sc-ground); }
.sector-art-panel { position:relative; min-height:720px; overflow:hidden; }
.sector-art-panel>img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:50% 10%; }
.sector-art-panel>div { position:relative; height:100%; padding:40px; display:flex; flex-direction:column; justify-content:end; background:linear-gradient(0deg,var(--sc-shade) 2%,color-mix(in srgb,var(--sc-shade) 93%,transparent) 50%,color-mix(in srgb,var(--sc-shade) 19%,transparent)); }
.sector-signup-layout { --sc-display-size:36px; display:grid; grid-template-columns:1fr 1fr; width:min(1180px,calc(100% - 48px)); margin:48px auto; }
.sector-signup-layout .sector-art-panel h2 { margin:12px 0; }
.sector-signup-layout .sector-art-panel li :is(b,span) { display:block; }
.sector-signup-layout .sector-art-panel li span { font-size:13px; color:var(--sc-muted); }
.sector-signup-form { padding:24px; align-self:center; min-width:0; }
.sector-signup-form>.sc-surface { border:0; background:none; box-shadow:none; }
.sector-signup-heading h1 { font-size:28px; line-height:1.3; margin:12px 0; }
.sector-signup-heading>p:last-child { color:var(--sc-muted); font-size:14px; line-height:1.7; margin-bottom:28px; }
.sector-directory { padding-block:48px 80px; min-height:65vh; }

/* Game result (victory/defeat/draw): the art composition with the local race's portrait and a
 * display headline in the result tone, beside the ledger table and the landing's call to action. */
.sector-result { --sc-display-size:clamp(34px,4.2vw,60px); grid-template-columns:minmax(280px,.75fr) 2fr; grid-template-rows:minmax(0,1fr) auto; width:min(1180px,calc(100% - 40px)); max-width:none; max-height:calc(100dvh - 40px); margin:auto; padding:0; overflow:auto; border-top:2px solid var(--sc-result); box-shadow:var(--sc-shadow); }
.sector-result[open] { display:grid; grid-template-rows:minmax(0,1fr) auto; }
.sector-result .sector-art-panel { grid-row:1 / -1; min-height:clamp(360px,62dvh,620px); }
.sector-result .sector-art-panel>div { padding:32px; }
.sector-result[data-result='defeat'] .sector-art-panel>img { filter:saturate(.35) brightness(.75); }
.sector-result h1 { margin:12px 0 14px; color:var(--sc-result); }
.sector-result .sector-intro { margin:0; font-size:17px; font-variant-numeric:tabular-nums; }
.sector-result .sector-footnote { margin:6px 0 0; }
.sector-result-body { display:flex; flex-direction:column; min-width:0; padding:32px 32px 0; background:inherit; }
.sector-result-body>.sc-kicker { margin:0 0 8px; }
.sector-result .sc-table-scroll { margin:0 0 24px; }
/* The score header wraps between words, and splits one only where the language allows: a fixed
 * layout with `overflow-wrap:anywhere` divided the columns equally and then broke whatever did
 * not fit, so STRUCTURES read "STRUCT URES" and MINERALS read "MINERA LS". Automatic layout gives
 * every column its longest word instead (the English set still fits the panel exactly), and a
 * language whose words are longer hyphenates against the document's `lang` rather than breaking
 * mid-word. Phones get the card layout below, so none of this reaches them. */
.sector-result .sc-table { table-layout:auto; }
.sector-result .sc-table :is(th,td) { padding:12px 6px; white-space:normal; }
/* Tighter than the design system's display tracking, and a narrower name column: the score header
 * is eleven columns of caps in a fixed-width panel, and .14em spent about a tenth of the row on
 * air, which is what pushed English into hyphenating at all. */
.sector-result .sc-table thead th { hyphens:auto; letter-spacing:.04em; }
.sector-result .sc-table tbody td { white-space:nowrap; }
.sector-result .sc-table thead th { font-size:11px; line-height:1.35; vertical-align:bottom; }
.sector-result .sc-table th:first-child { width:clamp(96px,8vw,128px); padding-left:12px; }
.sector-result tbody th>span { display:block; }
.sector-result tbody th>small { display:block; margin-top:3px; color:var(--sc-muted); font-size:11px; font-weight:400; }
.sector-result td>strong { font-weight:500; }
.sector-result tr[data-local='true'] { background:color-mix(in srgb,var(--sc-result) 7%,transparent); box-shadow:inset 2px 0 var(--sc-result); }
.sector-result tr[data-local='true'] th>span { color:var(--sc-result); }
.sector-result .sector-actions { position:sticky; bottom:0; justify-content:flex-end; margin:auto -32px 0; padding:20px 32px; border-top:1px solid var(--sc-edge); background:inherit; }
.sector-result>.match-upload-status { grid-column:-2; margin:0; padding:0 32px 16px; text-align:right; }

/* Breakpoints: 1024px (two-column compositions stack), 760px (phones), 500px tall (landscape
 * phones). These are the only widths in this file; tests/unit/ui/design-system.test.ts checks. */
@media (max-width:1024px) {
  /* On a phone the card starts near the top: the keyboard takes the bottom half the moment
   * the field has focus, and a centred band would push the question under it. */
  .sc-onboarding { min-height:auto; padding:24px 16px 40px; }
  .sc-onboarding > header { margin-bottom:18px; }
  .sc-onboarding form { padding:18px; }
  .sector-result { grid-template-columns:1fr; grid-template-rows:none; }
  .sector-result .sector-art-panel { grid-row:auto; min-height:260px; }
  .sector-result .sector-art-panel>img { object-position:50% 25%; }
  .sector-result .sector-art-panel>div { padding:24px; }
  .sector-result>.match-upload-status { text-align:center; }
}
@media (max-width:760px) {
  :root { --sc-page-gutter: 16px; }
  .sc-ui :where(button, input[type='submit']), .sc-button { padding-inline: 14px; }
  .sc-section { padding: var(--sc-space-4); }
  .sc-launch { padding: 32px 16px; }
  .sc-launch > header { margin-bottom: 24px; }
  .sc-art-backdrop { --sc-art-current: var(--sc-art-small, var(--sc-art)); }

  .sc-table :is(th,td) { padding:11px 10px; }

  .sc-table:not(.sc-table-wide) { display:block; }
  .sc-table:not(.sc-table-wide) tbody { display:block; }
  .sc-table:not(.sc-table-wide) thead { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); }
  .sc-table:not(.sc-table-wide) tbody tr { display:grid; grid-template-columns:1fr 1fr; margin-bottom:12px; border:1px solid var(--sc-edge); }
  .sc-table:not(.sc-table-wide) tbody tr:last-child { margin-bottom:0; }
  .sc-table:not(.sc-table-wide) tbody :is(th,td):is(:first-child,[data-cell='primary']) { grid-column:1 / -1; width:auto; padding:12px 14px; background:var(--sc-void); font-size:14px; }
  .sc-table:not(.sc-table-wide) tbody tr:last-child :is(th,td) { border-bottom:1px solid color-mix(in srgb,var(--sc-edge) 50%,transparent); }
  .sc-table:not(.sc-table-wide) tbody td { display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px; text-align:left; }
  .sc-table:not(.sc-table-wide) tbody td.sc-table-action { grid-column:1 / -1; justify-content:stretch; }
  .sc-table:not(.sc-table-wide) .sc-cell-label { display:block; color:var(--sc-muted); font-size:11px; line-height:1.3; }

  .sector-signup-layout { grid-template-columns:1fr; width:calc(100% - 24px); margin:20px auto; }
  .sector-signup-layout .sector-art-panel { min-height:440px; }
  .sector-signup-layout .sector-art-panel>div { padding:24px; }
  .sector-signup-form { padding:4px; }

  .sector-result { width:calc(100% - 24px); max-height:calc(100dvh - 24px); }
  .sector-result .sector-art-panel { min-height:200px; }
  .sector-result .sector-art-panel>div { padding:20px 16px; }
  .sector-result-body { padding:20px 16px 0; }
  .sector-result tr[data-local='true'] { border-color:var(--sc-result); box-shadow:none; }
  .sector-result .sector-actions { gap:8px; margin-inline:-16px; padding:14px 16px; }
  .sector-result .sector-actions>button { flex:1 1 0; padding-inline:8px; }
  .sector-result .sector-actions>.sector-cta { flex-basis:100%; order:-1; min-width:0; }
}
@media (max-height:500px) {
  .sector-result .sector-art-panel { min-height:0; }
  .sector-result .sector-art-panel>div { padding-block:14px; }
  .sector-result { --sc-display-size:28px; }
  .sector-result h1 { margin:4px 0; }
  .sector-result .sector-footnote { display:none; }
  .sector-result-body { padding-top:16px; }
  .sector-result .sector-actions { padding-block:12px; }
}
@media (prefers-reduced-motion: reduce) {
  .sc-ui *, .sc-progress::-webkit-progress-value, .sc-progress-live, .sc-progress-live::-webkit-progress-value, .sc-progress-live::-moz-progress-bar { transition: none !important; animation: none !important; }
}
/* The room form's view setting (Rails games/new): three plain choices, no art. */

/* Rails-only shared bits the profile block used to hold. A default shown before its value exists
 * reads complete, never as if it were loading: grey, dimmed (docs/PLAYER-STATS.md). The forms
 * (profile settings, onboarding) and their error list. The profile page itself is styled in the
 * host's Tailwind layer (playscbw-web app/assets/tailwind/application.css). */
.sc-placeholder { color:var(--sc-muted); opacity:.6; }
.sc-form label { display:grid; gap:6px; }
.sc-form label > span { font-size:12px; text-transform:uppercase; letter-spacing:.08em; color:var(--sc-muted); }
.sc-form input, .sc-form select { min-height:var(--sc-control-height); }
.sc-errors { margin:0; padding:12px 16px; list-style:none; border:1px solid var(--sc-danger); color:var(--sc-danger); font-size:13px; }



/* Strategy articles (Rails /guides): the why leads, then the checklist, the build, the
 * research and army, the scouting forks, counters, mistakes and a note per level. Icons are the
 * strategy-icons collection, or a monogram slot of the same footprint until each lands. */
.sc-icon { width:40px; height:40px; flex:none; border-radius:4px; object-fit:cover; }
/* The slot that stands in until a slug's artwork exists. It is not a blank: StrategyIcon knows
 * what the slug is, so the slot carries its race as colour and its kind as shape — a building is
 * square-shouldered, a unit is cut at the corner, research is round, an upgrade is a chevron.
 * That is enough for a build order to be scanned by silhouette before any icon is drawn. */
.sc-icon-slot { display:inline-grid; place-items:center; width:40px; height:40px; flex:none; border:1px solid var(--sc-edge); background:var(--sc-void); color:var(--sc-muted); font:600 12px var(--sc-font-mono); letter-spacing:.04em; }
.sc-icon-slot[data-race] { border-color:color-mix(in srgb,var(--sc-seat) 55%,var(--sc-edge)); color:var(--sc-seat); background:color-mix(in srgb,var(--sc-seat) 9%,var(--sc-void)); }
.sc-icon-slot[data-kind='unit'] { clip-path:polygon(0 0,100% 0,100% 72%,72% 100%,0 100%); }
.sc-icon-slot[data-kind='research'] { border-radius:50%; }
.sc-icon-slot[data-kind='upgrade'] { clip-path:polygon(50% 0,100% 26%,100% 100%,0 100%,0 26%); }
/* The strategy pages (/guides and every article) are Rails-only and styled entirely in
 * that host's Tailwind layer — app/assets/tailwind/application.css, `.strategy-*`, `.build-*`
 * — against the tokens above. Entirely, not partly: Tailwind emits into `@layer`, this file is
 * unlayered, and unlayered CSS wins over layered whatever the order, so a page split across
 * the two has its Tailwind rules silently overridden. */
