/* RateClimbs design system: "Spruce & Ember".
 *
 * Direction: a phone held in one hand at an evening session. Dark, but
 * forest instead of black: deep spruce surfaces, chalk-white ink, one warm
 * ember accent (#ff7a3d) for primary actions. The light theme is "chalk",
 * the same family on warm off-white. The UI palette stays muted so the hold
 * colours in photos and tape chips carry the colour. Display type is
 * Bricolage Grotesque (headings, grades, gym initials, wordmark), body type
 * Manrope; both self-hosted (CSP font-src 'self'), sentence case.
 * Shape: cards 18px, inputs 14px, primary buttons 16px, chips and grade
 * badges are pills. Every tap target is at least 44px; primary actions sit
 * low on the screen, within thumb reach, above a bottom tab bar.
 *
 * Theme: light tokens are the :root default. Dark tokens apply when the
 * system is dark (unless the visitor forced light) or when the visitor
 * forced dark: <html data-theme="light|dark">, set before first paint by
 * js/theme-boot.js from the Me screen's Appearance choice.
 *
 * Contrast ratios in comments are WCAG 2 ratios against the named token.
 *
 * Sections: fonts, tokens, base, layout shell, tab bar, controls, climb
 * pieces (chip, grade, tri-bar, stars), sheet, toast, empty state, static
 * pages.
 */

/* ── Fonts (latin subset, variable weight; SIL OFL, see fonts/<family>/OFL.txt) ── */

@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/fonts/bricolage-grotesque/bricolage-grotesque-latin-wght-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/fonts/manrope/manrope-latin-wght-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Tokens ── */

:root {
  color-scheme: light dark;

  /* Surfaces and ink (light, "chalk"). */
  --bg: #f4efe6;
  --surface: #fffdf9;
  --surface-2: #e9e2d6;
  --ink: #0b1f1a; /* 15.0:1 on --bg */
  --ink-2: #2f4a42; /* 8.4:1 on --bg, 7.5:1 on --surface-2 */
  --ink-3: #4e6b62; /* 5.1:1 on --bg, 5.7:1 on --surface, 4.5:1 on --surface-2 */
  --line: #d9d0c2;
  --scrim: rgba(7, 22, 18, 0.5);

  /* Accent: ember fill for primary actions; --accent-text passes 4.5:1 as text. */
  --accent: #ff7a3d;
  --accent-ink: #0b1f1a; /* 6.6:1 on --accent */
  --accent-text: #a8421a; /* 5.3:1 on --bg, 4.7:1 on --surface-2 (#b4461a was 4.3:1 there) */
  --accent-soft: rgba(255, 122, 61, 0.16);
  /* Focus ring: 3:1 against the page in both themes (4.8:1 on --bg). */
  --focus: var(--accent-text);
  /* Accent text on an --ink background (toast actions): 7.9:1 on #0b1f1a. */
  --accent-on-ink: #ff9466;

  /* Grade verdicts. Fills, and text versions that pass 4.5:1. */
  --soft: #2e9c86;
  --correct: #6e8c83;
  --hard: #f2a541;
  --danger: #c0352e; /* 4.8:1 on --bg */
  --soft-text: #1d6e5e; /* 5.3:1 on --bg */
  --hard-text: #8f5a00; /* 5.1:1 on --bg */
  /* Text on a filled verdict (vote buttons): 5.1:1 soft, 4.7:1 correct, 8.4:1 hard. */
  --verdict-ink: #0b1f1a;

  /* Brand: the "Climbs" of the wordmark. 6.8:1 on --bg, 7.7:1 on
   * --surface, 6.0:1 on --surface-2. */
  --brand-green: #245c49;
  /* The mark's sticker edge (behind its navy outline): none on light. */
  --mark-edge: transparent;

  /* Graphics (WCAG 1.4.11, 3:1): rating stars, tri-bar and diverging-bar
   * segments, legend dots. Light ratios are against --surface-2, the
   * darkest light background, so --bg and --surface pass by more. */
  --star: #c4501a; /* 3.6:1 (the #ff7a3d fill was 2.6:1 on --surface) */
  --star-off: #72857e; /* 3.0:1 (--line was 1.3:1) */
  --soft-fill: #1f8571; /* 3.5:1 (--soft #2e9c86 was 2.6:1) */
  --correct-fill: #5f7c73; /* 3.5:1 */
  --hard-fill: #ad6a06; /* 3.4:1 (--hard #f2a541 was 1.6:1) */

  /* Hold tape colours (chips match the tape gyms actually use). */
  --hold-red: #e53935;
  --hold-orange: #fb8c00;
  --hold-yellow: #fdd835;
  --hold-green: #43a047;
  --hold-blue: #1e88e5;
  --hold-purple: #8e24aa;
  --hold-pink: #f06292;
  --hold-black: #1b1b1b;
  --hold-white: #fafafa;
  --hold-grey: #9e9e9e;
  --hold-teal: #00897b;
  --hold-lime: #8bc34a;
  --hold-brown: #795548;
  --hold-tan: #d2b48c;
  --hold-navy: #1a2a6c;
  --hold-magenta: #d6007e;
  --hold-maroon: #7b1e2b;
  --hold-neon: #c6ff00; /* fluorescent yellow-green tape */

  /* Type: Manrope for reading, Bricolage Grotesque for display. A 1.2
   * scale; tabular figures for grades. */
  --font: 'Manrope', system-ui, -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --font-display: 'Bricolage Grotesque', 'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --fs-xs: 0.75rem;
  --fs-sm: 0.875rem;
  --fs-md: 1rem;
  --fs-lg: 1.25rem;
  --fs-xl: 1.5rem;
  --fs-2xl: 2.125rem;

  /* Space (4px base), radius, size. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --r-sm: 8px;
  --r-md: 14px; /* inputs, rows, small tiles */
  --r-lg: 20px;
  --r-card: 18px;
  --r-btn: 16px; /* primary buttons */
  --r-sheet: 28px;
  --r-pill: 999px;
  --tap: 44px;
  --tabbar-h: 64px;
  --topbar-h: 52px;
  --max-w: 640px;

  --shadow-sheet: 0 -8px 32px rgba(7, 22, 18, 0.18);
  --shadow-toast: 0 6px 24px rgba(7, 22, 18, 0.22);
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Dark (the hero theme). The same block twice: once for a dark system
 * without a forced light choice, once for a forced dark choice. Keep the
 * two in sync. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg: #0b1f1a;
    --surface: #13302a;
    --surface-2: #1b3b34;
    --ink: #f4efe6; /* 15.0:1 on --bg, 10.7:1 on --surface-2 */
    --ink-2: #c4d3cd; /* 11.1:1 on --bg, 7.9:1 on --surface-2 */
    --ink-3: #9db5ac; /* 7.9:1 on --bg, 5.6:1 on --surface-2 */
    --line: #23463d;
    --scrim: rgba(3, 10, 8, 0.66);
    --accent-text: #ff9466; /* 7.9:1 on --bg, 5.6:1 on --surface-2 */
    --accent-soft: rgba(255, 122, 61, 0.18);
    --accent-on-ink: #a8421a; /* 5.3:1 on #f4efe6 */
    --focus: var(--accent); /* 6.6:1 on --bg, 5.5:1 on --surface */
    --soft: #8fd6c1;
    --hard: #f2a541;
    --hold-black: #0a0a0a;
    --danger: #ff6b62; /* 6.2:1 on --bg, 5.1:1 on --surface */
    --soft-text: #8fd6c1; /* 10.3:1 on --bg */
    --hard-text: #f2a541; /* 8.4:1 on --bg */
    --star: #ff7a3d; /* 4.7:1 on --surface-2, 5.5:1 on --surface */
    --star-off: #6e8c83; /* 3.3:1 on --surface-2, 3.9:1 on --surface (--line was 1.3:1) */
    --soft-fill: #8fd6c1; /* 7.3:1 on --surface-2 */
    --correct-fill: #6e8c83; /* 3.3:1 on --surface-2 */
    --hard-fill: #f2a541; /* 5.9:1 on --surface-2 */
    --brand-green: #6fb08f; /* 6.8:1 on --bg, 5.6:1 on --surface, 4.8:1 on --surface-2 */
    --mark-edge: #f4efe6; /* cream: the navy outline #0b222a is 1.0:1 on --bg, cream 15.0:1 */
    --shadow-sheet: 0 -8px 32px rgba(0, 0, 0, 0.5);
    --shadow-toast: 0 6px 24px rgba(0, 0, 0, 0.5);
  }
}

:root[data-theme='dark'] {
  --bg: #0b1f1a;
  --surface: #13302a;
  --surface-2: #1b3b34;
  --ink: #f4efe6;
  --ink-2: #c4d3cd;
  --ink-3: #9db5ac;
  --line: #23463d;
  --scrim: rgba(3, 10, 8, 0.66);
  --accent-text: #ff9466;
  --accent-soft: rgba(255, 122, 61, 0.18);
  --accent-on-ink: #a8421a;
  --focus: var(--accent);
  --soft: #8fd6c1;
  --hard: #f2a541;
  --hold-black: #0a0a0a;
  --danger: #ff6b62;
  --soft-text: #8fd6c1;
  --hard-text: #f2a541;
  --star: #ff7a3d; /* 4.7:1 on --surface-2, 5.5:1 on --surface */
  --star-off: #6e8c83; /* 3.3:1 on --surface-2, 3.9:1 on --surface (--line was 1.3:1) */
  --soft-fill: #8fd6c1; /* 7.3:1 on --surface-2 */
  --correct-fill: #6e8c83; /* 3.3:1 on --surface-2 */
  --hard-fill: #f2a541; /* 5.9:1 on --surface-2 */
  --brand-green: #6fb08f; /* 6.8:1 on --bg, 5.6:1 on --surface, 4.8:1 on --surface-2 */
  --mark-edge: #f4efe6; /* cream: the navy outline #0b222a is 1.0:1 on --bg, cream 15.0:1 */
  --shadow-sheet: 0 -8px 32px rgba(0, 0, 0, 0.5);
  --shadow-toast: 0 6px 24px rgba(0, 0, 0, 0.5);
}

/* A forced choice also sets the UA's colour scheme (form controls,
 * scrollbars); "system" keeps `light dark` from above. */
:root[data-theme='light'] {
  color-scheme: light;
}

:root[data-theme='dark'] {
  color-scheme: dark;
}

/* ── Themes ── */

/* Me → Appearance → Theme: <html data-palette="…">, set before first paint
 * by js/theme-boot.js (Chalk, the default, is the tokens above and has no
 * attribute). Each theme overrides only surface, ink, line and accent
 * tokens; hold, vote and star colours stay. A theme's light block comes
 * after the Chalk dark blocks with the same specificity, so its dark blocks
 * must set every token its light block sets (test/theme-contrast.test.js
 * checks that, the two dark blocks' parity, and every ratio below). */

/* Granite: cool slate greys, a safety-yellow accent. */
:root[data-palette='granite'] {
  --bg: #eceff2;
  --surface: #fbfcfd;
  --surface-2: #e2e6eb;
  --ink: #10171f; /* 15.6:1 on --bg, 14.4:1 on --surface-2 */
  --ink-2: #323c47; /* 9.7:1 on --bg, 10.9:1 on --surface, 8.9:1 on --surface-2 */
  --ink-3: #4e5965; /* 6.2:1 on --bg, 7.0:1 on --surface, 5.7:1 on --surface-2 */
  --line: #d2d8df;
  --accent: #ffc21a;
  --accent-ink: #10171f; /* 11.2:1 on --accent */
  --accent-text: #7a5200; /* 6.0:1 on --bg, 6.7:1 on --surface, 5.5:1 on --surface-2 */
  --accent-soft: rgba(255, 194, 26, 0.2);
  --accent-on-ink: #ffc21a; /* 11.2:1 on --ink (toast actions) */
}

@media (prefers-color-scheme: dark) {
  :root[data-palette='granite']:not([data-theme='light']) {
    --bg: #13171b;
    --surface: #1c2227;
    --surface-2: #252c33;
    --ink: #eceff2; /* 15.6:1 on --bg, 12.2:1 on --surface-2 */
    --ink-2: #c3cad2; /* 10.9:1 on --bg, 9.7:1 on --surface, 8.5:1 on --surface-2 */
    --ink-3: #9ba5b0; /* 7.2:1 on --bg, 6.4:1 on --surface, 5.7:1 on --surface-2 */
    --line: #2f3740;
    --accent: #ffc21a;
    --accent-ink: #10171f; /* 11.2:1 on --accent */
    --accent-text: #ffcf4d; /* 12.2:1 on --bg, 10.9:1 on --surface, 9.6:1 on --surface-2 */
    --accent-soft: rgba(255, 194, 26, 0.16);
    --accent-on-ink: #7a5200; /* 6.0:1 on --ink (toast actions) */
  }
}

:root[data-palette='granite'][data-theme='dark'] {
  --bg: #13171b;
  --surface: #1c2227;
  --surface-2: #252c33;
  --ink: #eceff2; /* 15.6:1 on --bg, 12.2:1 on --surface-2 */
  --ink-2: #c3cad2; /* 10.9:1 on --bg, 9.7:1 on --surface, 8.5:1 on --surface-2 */
  --ink-3: #9ba5b0; /* 7.2:1 on --bg, 6.4:1 on --surface, 5.7:1 on --surface-2 */
  --line: #2f3740;
  --accent: #ffc21a;
  --accent-ink: #10171f; /* 11.2:1 on --accent */
  --accent-text: #ffcf4d; /* 12.2:1 on --bg, 10.9:1 on --surface, 9.6:1 on --surface-2 */
  --accent-soft: rgba(255, 194, 26, 0.16);
  --accent-on-ink: #7a5200; /* 6.0:1 on --ink (toast actions) */
}

/* Ocean: sea-glass blues, a sky-blue accent. */
:root[data-palette='ocean'] {
  --bg: #e9f1f8;
  --surface: #f9fcff;
  --surface-2: #dde8f2;
  --ink: #0a1b2c; /* 15.3:1 on --bg, 14.0:1 on --surface-2 */
  --ink-2: #2a4258; /* 9.1:1 on --bg, 10.1:1 on --surface, 8.4:1 on --surface-2 */
  --ink-3: #486279; /* 5.6:1 on --bg, 6.2:1 on --surface, 5.1:1 on --surface-2 */
  --line: #cad8e5;
  --accent: #4da3ff;
  --accent-ink: #0a1b2c; /* 6.6:1 on --accent */
  --accent-text: #14569f; /* 6.4:1 on --bg, 7.1:1 on --surface, 5.9:1 on --surface-2 */
  --accent-soft: rgba(77, 163, 255, 0.18);
  --accent-on-ink: #7cbcff; /* 8.7:1 on --ink (toast actions) */
}

@media (prefers-color-scheme: dark) {
  :root[data-palette='ocean']:not([data-theme='light']) {
    --bg: #0a1826;
    --surface: #112437;
    --surface-2: #182f47;
    --ink: #e9f1f8; /* 15.7:1 on --bg, 12.0:1 on --surface-2 */
    --ink-2: #bfd0df; /* 11.4:1 on --bg, 10.0:1 on --surface, 8.7:1 on --surface-2 */
    --ink-3: #94abc1; /* 7.6:1 on --bg, 6.7:1 on --surface, 5.8:1 on --surface-2 */
    --line: #1f3a56;
    --accent: #4da3ff;
    --accent-ink: #0a1b2c; /* 6.6:1 on --accent */
    --accent-text: #7cbcff; /* 9.0:1 on --bg, 7.9:1 on --surface, 6.8:1 on --surface-2 */
    --accent-soft: rgba(77, 163, 255, 0.18);
    --accent-on-ink: #14569f; /* 6.4:1 on --ink (toast actions) */
  }
}

:root[data-palette='ocean'][data-theme='dark'] {
  --bg: #0a1826;
  --surface: #112437;
  --surface-2: #182f47;
  --ink: #e9f1f8; /* 15.7:1 on --bg, 12.0:1 on --surface-2 */
  --ink-2: #bfd0df; /* 11.4:1 on --bg, 10.0:1 on --surface, 8.7:1 on --surface-2 */
  --ink-3: #94abc1; /* 7.6:1 on --bg, 6.7:1 on --surface, 5.8:1 on --surface-2 */
  --line: #1f3a56;
  --accent: #4da3ff;
  --accent-ink: #0a1b2c; /* 6.6:1 on --accent */
  --accent-text: #7cbcff; /* 9.0:1 on --bg, 7.9:1 on --surface, 6.8:1 on --surface-2 */
  --accent-soft: rgba(77, 163, 255, 0.18);
  --accent-on-ink: #14569f; /* 6.4:1 on --ink (toast actions) */
}

/* Forest: moss and fern greens, a pine accent. */
:root[data-palette='forest'] {
  --bg: #ecf1e8;
  --surface: #fbfdf9;
  --surface-2: #e0e8da;
  --ink: #0f1f12; /* 14.9:1 on --bg, 13.7:1 on --surface-2 */
  --ink-2: #2f4633; /* 9.0:1 on --bg, 10.0:1 on --surface, 8.2:1 on --surface-2 */
  --ink-3: #4a6450; /* 5.7:1 on --bg, 6.4:1 on --surface, 5.2:1 on --surface-2 */
  --line: #cfdac8;
  --accent: #1f7a4c;
  --accent-ink: #ffffff; /* 5.3:1 on --accent */
  --accent-text: #1c6b43; /* 5.7:1 on --bg, 6.3:1 on --surface, 5.2:1 on --surface-2 */
  --accent-soft: rgba(31, 122, 76, 0.16);
  --accent-on-ink: #7fd6a6; /* 9.9:1 on --ink (toast actions) */
}

@media (prefers-color-scheme: dark) {
  :root[data-palette='forest']:not([data-theme='light']) {
    --bg: #111a10;
    --surface: #1a2618;
    --surface-2: #223120;
    --ink: #ecf1e8; /* 15.5:1 on --bg, 12.0:1 on --surface-2 */
    --ink-2: #c4d2c2; /* 11.3:1 on --bg, 10.0:1 on --surface, 8.7:1 on --surface-2 */
    --ink-3: #9db39b; /* 7.9:1 on --bg, 7.0:1 on --surface, 6.1:1 on --surface-2 */
    --line: #2b3d29;
    --accent: #5cc48f;
    --accent-ink: #0f1f12; /* 8.0:1 on --accent */
    --accent-text: #7fd6a6; /* 10.2:1 on --bg, 9.0:1 on --surface, 7.9:1 on --surface-2 */
    --accent-soft: rgba(92, 196, 143, 0.18);
    --accent-on-ink: #1c6b43; /* 5.7:1 on --ink (toast actions) */
  }
}

:root[data-palette='forest'][data-theme='dark'] {
  --bg: #111a10;
  --surface: #1a2618;
  --surface-2: #223120;
  --ink: #ecf1e8; /* 15.5:1 on --bg, 12.0:1 on --surface-2 */
  --ink-2: #c4d2c2; /* 11.3:1 on --bg, 10.0:1 on --surface, 8.7:1 on --surface-2 */
  --ink-3: #9db39b; /* 7.9:1 on --bg, 7.0:1 on --surface, 6.1:1 on --surface-2 */
  --line: #2b3d29;
  --accent: #5cc48f;
  --accent-ink: #0f1f12; /* 8.0:1 on --accent */
  --accent-text: #7fd6a6; /* 10.2:1 on --bg, 9.0:1 on --surface, 7.9:1 on --surface-2 */
  --accent-soft: rgba(92, 196, 143, 0.18);
  --accent-on-ink: #1c6b43; /* 5.7:1 on --ink (toast actions) */
}

/* Sunset: peach and rose, a dusk-violet accent. */
:root[data-palette='sunset'] {
  --bg: #fbede7;
  --surface: #fffaf7;
  --surface-2: #f2e0d8;
  --ink: #2a1018; /* 15.5:1 on --bg, 13.9:1 on --surface-2 */
  --ink-2: #55303a; /* 9.8:1 on --bg, 10.8:1 on --surface, 8.8:1 on --surface-2 */
  --ink-3: #7a4b55; /* 6.2:1 on --bg, 6.8:1 on --surface, 5.5:1 on --surface-2 */
  --line: #e9cfc6;
  --accent: #6a45d6;
  --accent-ink: #ffffff; /* 6.1:1 on --accent */
  --accent-text: #5b36c4; /* 6.6:1 on --bg, 7.3:1 on --surface, 5.9:1 on --surface-2 */
  --accent-soft: rgba(106, 69, 214, 0.14);
  --accent-on-ink: #c4b0ff; /* 9.3:1 on --ink (toast actions) */
}

@media (prefers-color-scheme: dark) {
  :root[data-palette='sunset']:not([data-theme='light']) {
    --bg: #1f1216;
    --surface: #2a1a1f;
    --surface-2: #352228;
    --ink: #fbede7; /* 15.9:1 on --bg, 13.0:1 on --surface-2 */
    --ink-2: #e3c9c3; /* 11.6:1 on --bg, 10.6:1 on --surface, 9.5:1 on --surface-2 */
    --ink-3: #c4a2a2; /* 7.8:1 on --bg, 7.1:1 on --surface, 6.4:1 on --surface-2 */
    --line: #432c33;
    --accent: #b49cff;
    --accent-ink: #1f1216; /* 7.9:1 on --accent */
    --accent-text: #c4b0ff; /* 9.5:1 on --bg, 8.7:1 on --surface, 7.8:1 on --surface-2 */
    --accent-soft: rgba(180, 156, 255, 0.18);
    --accent-on-ink: #5b36c4; /* 6.6:1 on --ink (toast actions) */
  }
}

:root[data-palette='sunset'][data-theme='dark'] {
  --bg: #1f1216;
  --surface: #2a1a1f;
  --surface-2: #352228;
  --ink: #fbede7; /* 15.9:1 on --bg, 13.0:1 on --surface-2 */
  --ink-2: #e3c9c3; /* 11.6:1 on --bg, 10.6:1 on --surface, 9.5:1 on --surface-2 */
  --ink-3: #c4a2a2; /* 7.8:1 on --bg, 7.1:1 on --surface, 6.4:1 on --surface-2 */
  --line: #432c33;
  --accent: #b49cff;
  --accent-ink: #1f1216; /* 7.9:1 on --accent */
  --accent-text: #c4b0ff; /* 9.5:1 on --bg, 8.7:1 on --surface, 7.8:1 on --surface-2 */
  --accent-soft: rgba(180, 156, 255, 0.18);
  --accent-on-ink: #5b36c4; /* 6.6:1 on --ink (toast actions) */
}

/* Midnight: near-black dark (kind to OLED screens), pale grey light, an ice-cyan accent. */
:root[data-palette='midnight'] {
  --bg: #efeff1;
  --surface: #ffffff;
  --surface-2: #e5e5e8;
  --ink: #0a0a0c; /* 17.2:1 on --bg, 15.7:1 on --surface-2 */
  --ink-2: #303036; /* 11.4:1 on --bg, 13.1:1 on --surface, 10.4:1 on --surface-2 */
  --ink-3: #54545d; /* 6.5:1 on --bg, 7.5:1 on --surface, 6.0:1 on --surface-2 */
  --line: #d5d5da;
  --accent: #1fb0c8;
  --accent-ink: #0a0a0c; /* 7.6:1 on --accent */
  --accent-text: #0a6474; /* 5.9:1 on --bg, 6.8:1 on --surface, 5.4:1 on --surface-2 */
  --accent-soft: rgba(31, 176, 200, 0.16);
  --accent-on-ink: #5fd8ea; /* 11.8:1 on --ink (toast actions) */
}

@media (prefers-color-scheme: dark) {
  :root[data-palette='midnight']:not([data-theme='light']) {
    --bg: #050506;
    --surface: #111114;
    --surface-2: #1a1a1e;
    --ink: #efeff1; /* 17.7:1 on --bg, 15.1:1 on --surface-2 */
    --ink-2: #c8c8cd; /* 12.2:1 on --bg, 11.3:1 on --surface, 10.4:1 on --surface-2 */
    --ink-3: #9c9ca6; /* 7.5:1 on --bg, 6.9:1 on --surface, 6.4:1 on --surface-2 */
    --line: #26262c;
    --accent: #4fd1e5;
    --accent-ink: #050506; /* 11.2:1 on --accent */
    --accent-text: #6fdcec; /* 12.7:1 on --bg, 11.8:1 on --surface, 10.8:1 on --surface-2 */
    --accent-soft: rgba(79, 209, 229, 0.16);
    --accent-on-ink: #0a6474; /* 5.9:1 on --ink (toast actions) */
  }
}

:root[data-palette='midnight'][data-theme='dark'] {
  --bg: #050506;
  --surface: #111114;
  --surface-2: #1a1a1e;
  --ink: #efeff1; /* 17.7:1 on --bg, 15.1:1 on --surface-2 */
  --ink-2: #c8c8cd; /* 12.2:1 on --bg, 11.3:1 on --surface, 10.4:1 on --surface-2 */
  --ink-3: #9c9ca6; /* 7.5:1 on --bg, 6.9:1 on --surface, 6.4:1 on --surface-2 */
  --line: #26262c;
  --accent: #4fd1e5;
  --accent-ink: #050506; /* 11.2:1 on --accent */
  --accent-text: #6fdcec; /* 12.7:1 on --bg, 11.8:1 on --surface, 10.8:1 on --surface-2 */
  --accent-soft: rgba(79, 209, 229, 0.16);
  --accent-on-ink: #0a6474; /* 5.9:1 on --ink (toast actions) */
}

/* Theme swatches on the Me screen: the theme's light and dark --bg and its
 * accent (test/theme-contrast.test.js keeps them equal to the tokens). */
.theme-swatch-chalk {
  --swatch-light: #f4efe6;
  --swatch-dark: #0b1f1a;
  --swatch-accent: #ff7a3d;
}

.theme-swatch-granite {
  --swatch-light: #eceff2;
  --swatch-dark: #13171b;
  --swatch-accent: #ffc21a;
}

.theme-swatch-ocean {
  --swatch-light: #e9f1f8;
  --swatch-dark: #0a1826;
  --swatch-accent: #4da3ff;
}

.theme-swatch-forest {
  --swatch-light: #ecf1e8;
  --swatch-dark: #111a10;
  --swatch-accent: #1f7a4c;
}

.theme-swatch-sunset {
  --swatch-light: #fbede7;
  --swatch-dark: #1f1216;
  --swatch-accent: #6a45d6;
}

.theme-swatch-midnight {
  --swatch-light: #efeff1;
  --swatch-dark: #050506;
  --swatch-accent: #1fb0c8;
}

/* ── Base ── */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--ink);
  font: var(--fs-md) / 1.5 var(--font);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

h1,
h2,
h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

p {
  margin: 0;
}

a {
  color: var(--accent-text);
  text-underline-offset: 2px;
}

img {
  max-width: 100%;
  display: block;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

#app:focus {
  outline: none;
}

.muted {
  color: var(--ink-3);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.icon {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}

/* ── Layout shell ── */

#app {
  min-height: 100dvh;
  padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--s5));
}

.screen {
  max-width: var(--max-w);
  margin: 0 auto;
}

.screen-body {
  padding: var(--s4) max(var(--s4), env(safe-area-inset-left)) 0 max(var(--s4), env(safe-area-inset-right));
  display: grid;
  /* minmax(0, …): a horizontal scroller inside (the gym page's fresh-climbs
   * strip) must not widen the column to its content and scroll the page. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s4);
}

.topbar {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  gap: var(--s1);
  min-height: calc(var(--topbar-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) var(--s2) 0;
  /* 94%: text scrolling underneath stays a faint blur, never legible
   * through the title (86% let it read through). */
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid var(--line);
}

@media (prefers-reduced-transparency: reduce) {
  .topbar {
    background: var(--bg);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* Test site (js/test-site.js): a strip above every screen, stuck to the top
 * and taking the notch's inset, so the top bar sticks just below it
 * (--test-banner-h, measured) without its own inset. Ink on --bg swaps in
 * dark mode: 15.0:1 both ways. */
.test-site-banner {
  position: sticky;
  top: 0;
  z-index: 11;
  padding: calc(env(safe-area-inset-top) + var(--s1)) max(var(--s4), env(safe-area-inset-right)) var(--s1) max(var(--s4), env(safe-area-inset-left));
  background: var(--ink);
  color: var(--bg);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-align: center;
}

.test-site-banner p {
  margin: 0;
}

.test-site-banner a {
  color: inherit;
  font-weight: 800;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.is-test-site .topbar {
  top: var(--test-banner-h, 0px);
  min-height: var(--topbar-h);
  padding-top: 0;
}

.is-test-site .home-hero {
  padding-top: var(--hero-gap);
}

.topbar-title {
  flex: 1;
  min-width: 0;
  padding: 0 var(--s2);
  font-size: var(--fs-lg);
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: var(--tap);
  height: var(--tap);
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

.icon-btn:active {
  background: var(--surface-2);
}

/* Home: the one screen with a hero, set low and left like a title card. */
.home-hero {
  /* Below the notch's inset; on the test site the banner takes the inset. */
  --hero-gap: 56px;
  padding: calc(env(safe-area-inset-top) + var(--hero-gap)) var(--s4) var(--s5);
  display: grid;
  gap: var(--s3);
  justify-items: start;
}

/* The brand: the RateClimbs mountain mark beside the wordmark, "Rate" in
 * ink and "Climbs" in --brand-green (js/brand.js). */
.brand {
  display: flex;
  align-items: center;
  gap: var(--s3);
}

/* viewBox 504 x 398. */
.brand-mark {
  width: 72px;
  height: 57px;
  flex: none;
}

/* The sticker edge behind the outline: cream on dark, nothing on light. */
.brand-mark-edge {
  fill: var(--mark-edge);
  stroke: var(--mark-edge);
  stroke-width: 28;
  stroke-linejoin: round;
}

.home-title {
  font-size: 2.25rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
}

.wordmark-climbs {
  color: var(--brand-green);
}

.home-lede {
  font-size: var(--fs-lg);
  line-height: 1.4;
  color: var(--ink-2);
  max-width: 30ch;
}

.legal-links {
  display: flex;
  gap: var(--s2);
  font-size: var(--fs-sm);
}

.legal-links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 var(--s2);
  color: var(--ink-3);
}

.noscript {
  padding: var(--s5) var(--s4);
}

/* ── Tab bar ── */

.tabbar {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 20;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  align-items: center;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  /* On wide screens the five tabs stay within the content column. */
  padding: 0 max(var(--s2), env(safe-area-inset-right), calc((100% - var(--max-w)) / 2)) env(safe-area-inset-bottom) max(var(--s2), env(safe-area-inset-left), calc((100% - var(--max-w)) / 2));
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(18px);
  backdrop-filter: saturate(1.4) blur(18px);
  border-top: 1px solid var(--line);
}

.tab {
  display: grid;
  justify-items: center;
  align-content: center;
  gap: 2px;
  height: var(--tabbar-h);
  color: var(--ink-3);
  text-decoration: none;
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
}

/* Share is a button (an action), dressed like the link tabs. */
button.tab {
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-3);
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: 600;
  cursor: pointer;
}

/* Full ink, like Add: it should be obvious, never mistaken for disabled. */
.tab-share {
  color: var(--ink);
}

.tab[aria-current='page'] {
  color: var(--ink);
}

.tab[aria-current='page'] .tab-icon {
  background: var(--surface-2);
}

.tab-icon {
  display: grid;
  place-items: center;
  width: min(52px, 100%);
  height: 30px;
  border-radius: 15px;
  transition: background-color 160ms var(--ease);
}

/* Add is the one action people come for: it gets the accent. */
.tab-add .tab-icon,
.tab-add[aria-current='page'] .tab-icon {
  background: var(--accent);
  color: var(--accent-ink);
}

.tab-add .icon {
  stroke-width: 2.6;
}

.tab-add {
  color: var(--ink);
}

/* ── Controls ── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: var(--tap);
  padding: 0 var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--ink);
  font-weight: 650;
  text-decoration: none;
  cursor: pointer;
  transition: transform 120ms var(--ease), background-color 120ms var(--ease);
}

.btn:active {
  transform: scale(0.97);
}

.btn:disabled,
.btn[aria-disabled='true'] {
  opacity: 0.5;
  pointer-events: none;
}

.btn-primary {
  min-height: 52px;
  border-color: transparent;
  border-radius: var(--r-btn);
  font-weight: 700;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 1.0625rem;
}

.btn-quiet {
  border-color: transparent;
  background: transparent;
  color: var(--ink-2);
}

.btn-block {
  width: 100%;
}

/* ── Climb pieces ── */

/* Hold colour: a torn strip of setting tape. */
.chip {
  display: inline-block;
  width: 30px;
  height: 14px;
  flex: none;
  background: var(--chip-color, var(--hold-grey));
  clip-path: polygon(0 8%, 6% 0, 12% 10%, 100% 0, 94% 50%, 100% 100%, 8% 92%, 0 100%, 5% 50%);
  transform: rotate(-4deg);
}

.chip[data-color='red'] { --chip-color: var(--hold-red); }
.chip[data-color='orange'] { --chip-color: var(--hold-orange); }
.chip[data-color='yellow'] { --chip-color: var(--hold-yellow); }
.chip[data-color='green'] { --chip-color: var(--hold-green); }
.chip[data-color='blue'] { --chip-color: var(--hold-blue); }
.chip[data-color='purple'] { --chip-color: var(--hold-purple); }
.chip[data-color='pink'] { --chip-color: var(--hold-pink); }
.chip[data-color='grey'] { --chip-color: var(--hold-grey); }
.chip[data-color='teal'] { --chip-color: var(--hold-teal); }
.chip[data-color='lime'] { --chip-color: var(--hold-lime); }
.chip[data-color='brown'] { --chip-color: var(--hold-brown); }
.chip[data-color='tan'] { --chip-color: var(--hold-tan); }
.chip[data-color='magenta'] { --chip-color: var(--hold-magenta); }
.chip[data-color='neon'] { --chip-color: var(--hold-neon); }
.chip[data-color='black'] { --chip-color: var(--hold-black); }
.chip[data-color='white'] { --chip-color: var(--hold-white); }
.chip[data-color='navy'] { --chip-color: var(--hold-navy); }
.chip[data-color='maroon'] { --chip-color: var(--hold-maroon); }

/* Black, navy and maroon tape vanish on the dark theme, white on the light
 * one, and a custom colour could be anything. They get a grey outline that
 * follows the torn shape: the chip is the outline and an inset
 * pseudo-element with the same clip is the tape (--chip-color; a custom
 * colour sets it inline). */
.chip[data-color='black'],
.chip[data-color='white'],
.chip[data-color='navy'],
.chip[data-color='maroon'],
.chip.chip-custom {
  position: relative;
  background: #8a9098;
}

.chip[data-color='black']::after,
.chip[data-color='white']::after,
.chip[data-color='navy']::after,
.chip[data-color='maroon']::after,
.chip.chip-custom::after {
  content: '';
  position: absolute;
  inset: 1.5px;
  clip-path: inherit;
  background: var(--chip-color);
}

/* The Custom… swatch before a colour is picked: a colour wheel. */
.chip.chip-wheel {
  background: conic-gradient(var(--hold-red), var(--hold-yellow), var(--hold-green), var(--hold-teal), var(--hold-blue), var(--hold-purple), var(--hold-magenta), var(--hold-red));
}

.grade {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s1);
  padding: 2px 9px;
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--bg);
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  line-height: 1.3;
}

.grade-main {
  font-size: var(--fs-md);
  font-weight: 800;
  letter-spacing: -0.01em;
}

.grade-orig {
  font-size: var(--fs-xs);
  font-weight: 600;
  opacity: 0.7;
}

.tri-wrap {
  display: inline-flex;
  min-width: 48px;
}

.tri {
  flex: 1;
  display: flex;
  gap: 2px;
  height: 6px;
  min-width: 48px;
  border-radius: 3px;
  overflow: hidden;
  background: var(--surface-2);
}

.tri-seg {
  flex-basis: 0;
  min-width: 4px;
}

.tri-soft { background: var(--soft-fill); }
.tri-correct { background: var(--correct-fill); }
.tri-hard { background: var(--hard-fill); }

.stars {
  position: relative;
  display: inline-block;
  font-size: var(--fs-sm);
  line-height: 1;
  letter-spacing: 1px;
  white-space: nowrap;
}

.stars-track {
  color: var(--star-off);
}

.stars-fill {
  position: absolute;
  inset: 0 auto 0 0;
  overflow: hidden;
  color: var(--star);
}

.stars-none {
  color: var(--ink-3);
  letter-spacing: 0;
}

/* ── Sheet ── */

.sheet {
  width: 100%;
  max-width: var(--max-w);
  max-height: 92dvh;
  margin: auto auto 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  overflow: visible;
  animation: sheet-in 280ms var(--ease);
}

.sheet::backdrop {
  background: var(--scrim);
  animation: fade-in 280ms var(--ease);
}

.sheet.is-closing {
  animation: sheet-out 220ms ease-in forwards;
}

.sheet.is-closing::backdrop {
  animation: fade-out 220ms ease-in forwards;
}

.sheet-body {
  max-height: 92dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 var(--s4) calc(var(--s5) + env(safe-area-inset-bottom));
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  background: var(--surface);
  box-shadow: var(--shadow-sheet);
}

.sheet-grip {
  display: grid;
  place-items: center;
  height: 28px;
  margin: 0 calc(-1 * var(--s4));
  cursor: grab;
  touch-action: none;
}

.sheet-grip::before {
  content: '';
  width: 40px;
  height: 5px;
  border-radius: 3px;
  background: var(--line);
}

.sheet-title {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 800;
  margin-bottom: var(--s2);
}

.sheet-actions {
  display: grid;
  gap: var(--s2);
  margin-top: var(--s5);
}

@keyframes sheet-in {
  from { transform: translateY(100%); }
}

@keyframes sheet-out {
  to { transform: translateY(100%); }
}

@keyframes fade-in {
  from { opacity: 0; }
}

@keyframes fade-out {
  to { opacity: 0; }
}

/* Install hint. */
.install {
  display: grid;
  gap: var(--s3);
  padding-top: var(--s2);
}

.install-icon {
  width: 64px;
  height: 64px;
  border-radius: 16px;
}

.install-steps {
  margin: 0;
  padding-left: 1.4em;
  display: grid;
  gap: var(--s2);
  font-size: 1.0625rem;
}

.install-share {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-weight: 650;
  vertical-align: bottom;
}

.install-share .icon {
  width: 20px;
  height: 20px;
  color: #0a84ff;
}

/* ── Toast ── */

.toast-region {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--s3));
  z-index: 30;
  display: grid;
  justify-items: center;
  padding: 0 var(--s4);
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  max-width: 480px;
  min-height: 48px;
  padding: var(--s1) var(--s1) var(--s1) var(--s4);
  border-radius: var(--r-md);
  background: var(--ink);
  color: var(--bg);
  box-shadow: var(--shadow-toast);
  font-weight: 550;
  pointer-events: auto;
  animation: toast-in 220ms var(--ease);
}

.toast.is-leaving {
  animation: fade-out 200ms ease-in forwards;
}

.toast-text {
  flex: 1;
  padding: var(--s2) 0;
}

.toast-action {
  min-height: var(--tap);
  padding: 0 var(--s4);
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--accent-on-ink);
  font-weight: 750;
  cursor: pointer;
}

@keyframes toast-in {
  from { transform: translateY(12px); opacity: 0; }
}

/* ── Empty state ── */

.empty {
  display: grid;
  gap: var(--s2);
  justify-items: start;
  padding: var(--s5) var(--s4);
  border: 1.5px dashed var(--line);
  border-radius: var(--r-card);
}

.empty-title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 700;
}

.empty-body {
  color: var(--ink-2);
  max-width: 40ch;
}

.empty .btn {
  margin-top: var(--s2);
}

/* ── Static pages (about, privacy, offline) ── */

.doc {
  max-width: 68ch;
  margin: 0 auto;
  padding: calc(env(safe-area-inset-top) + var(--s5)) var(--s4) calc(env(safe-area-inset-bottom) + var(--s6));
}

.doc h1 {
  font-size: var(--fs-2xl);
  font-weight: 800;
  letter-spacing: -0.03em;
  margin: var(--s4) 0 var(--s3);
}

.doc h2 {
  font-size: var(--fs-lg);
  font-weight: 700;
  margin: var(--s6) 0 var(--s2);
}

.doc p,
.doc li {
  color: var(--ink-2);
  line-height: 1.6;
}

.doc p + p {
  margin-top: var(--s3);
}

.doc ul {
  padding-left: 1.2em;
  display: grid;
  gap: var(--s3);
}

.doc strong {
  color: var(--ink);
}

.doc-lede {
  font-size: var(--fs-lg);
  line-height: 1.45;
}

.doc-back {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-weight: 600;
}

.doc-foot {
  margin-top: var(--s6);
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
  font-size: var(--fs-sm);
}

/* ── Settings groups and form fields (Me, admin) ── */

.group {
  display: grid;
  gap: var(--s3);
  padding: var(--s4);
  border-radius: var(--r-card);
  background: var(--surface);
  border: 1px solid var(--line);
}

.group-title {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 750;
}

/* A group that folds shut (screen.js foldable): the title is the tap
   target, with the browser's triangle beside it. Shut, only the title row. */
.group-fold:not([open]) {
  gap: 0;
}

.group-fold-summary {
  cursor: pointer;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: var(--s2);
  list-style: none;
}

.group-fold-summary::-webkit-details-marker {
  display: none;
}

.group-fold-summary::before {
  content: '▸';
  font-size: 1.4em;
  line-height: 1;
  color: var(--ink-2);
  transition: transform 0.15s ease;
}

.group-fold[open] > .group-fold-summary::before {
  transform: rotate(90deg);
}

@media (prefers-reduced-motion: reduce) {
  .group-fold-summary::before {
    transition: none;
  }
}

/* Focused by script (admin, after the last row goes): no ring for a tap. */
.group-title[tabindex='-1']:focus:not(:focus-visible) {
  outline: none;
}

.group-text {
  color: var(--ink-2);
  max-width: 60ch;
}

.group-actions {
  display: flex;
  justify-content: flex-end;
}

.field {
  display: grid;
  gap: var(--s1);
}

.field-label {
  padding: 0;
  font-size: var(--fs-sm);
  font-weight: 650;
  color: var(--ink-2);
}

.field-row {
  display: flex;
  gap: var(--s2);
}

.field-input {
  flex: 1;
  min-width: 0;
  min-height: var(--tap);
  padding: 0 var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--bg);
  font-size: var(--fs-md);
}

.field-error {
  color: var(--danger);
  font-size: var(--fs-sm);
}

.field-error:empty {
  display: none;
}

/* Segmented choice: radio inputs drawn as a row of pills. */
.seg {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
  display: grid;
  gap: var(--s1);
}

.seg-options {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}

.seg-option {
  position: relative;
  cursor: pointer;
}

.seg-input {
  position: absolute;
  opacity: 0;
  inset: 0;
  margin: 0;
  cursor: pointer;
}

.seg-label {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  min-height: var(--tap);
  padding: var(--s1) var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--bg);
  font-weight: 650;
  line-height: 1.2;
}

.seg-hint {
  font-size: var(--fs-xs);
  font-weight: 500;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.seg-input:checked + .seg-label {
  border-color: var(--ink);
  background: var(--ink);
  color: var(--bg);
}

.seg-input:checked + .seg-label .seg-hint {
  color: inherit;
  opacity: 0.75;
}

.seg-input:focus-visible + .seg-label {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.seg-compact .seg-label {
  padding: 0 var(--s3);
}

/* Me → Theme: a pill with a swatch (light | dark background, accent dot;
 * colours per theme in the Themes section). The ring is the label's own
 * text colour, so it shows on the checked (ink) pill too. */
.theme-option {
  flex-direction: row;
  align-items: center;
  gap: var(--s2);
  padding-left: var(--s2);
}

.theme-swatch {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px currentColor;
  background:
    radial-gradient(circle, var(--swatch-accent) 0 32%, transparent 34%),
    linear-gradient(135deg, var(--swatch-light) 0 50%, var(--swatch-dark) 50% 100%);
}

.btn-danger {
  border-color: transparent;
  background: transparent;
  color: var(--danger);
}

.btn-small {
  min-height: var(--tap);
  padding: 0 var(--s4);
  font-size: var(--fs-sm);
}

/* ── Notifications ── */

.push {
  display: grid;
  gap: var(--s3);
}

/* What the push is for, then its state; apart once the state has text. */
.push-status:not(:empty) {
  margin-top: var(--s2);
}

.notes {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
}

.note + .note {
  border-top: 1px solid var(--line);
}

.note-link {
  display: grid;
  gap: 2px;
  padding: var(--s3) 0 var(--s3) var(--s4);
  color: var(--ink);
  text-decoration: none;
  position: relative;
}

.note.is-unread .note-link::before {
  content: '';
  position: absolute;
  left: 0;
  top: calc(var(--s3) + 0.45em);
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
}

.note-title {
  font-weight: 650;
}

.note:not(.is-unread) .note-title {
  font-weight: 500;
  color: var(--ink-2);
}

.note-body {
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

.note-time {
  color: var(--ink-3);
  font-size: var(--fs-xs);
}

/* ── Gym feedback ── */

.fb-intro {
  color: var(--ink-2);
}

.fb-filters {
  display: grid;
  gap: var(--s3);
}

.fb-csv {
  justify-self: start;
  padding: 0;
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.fb-results {
  display: grid;
  gap: var(--s5);
}

.fb-results[aria-busy='true'] {
  opacity: 0.55;
  transition: opacity 160ms var(--ease);
}

.fb-group {
  display: grid;
  gap: var(--s2);
}

/* Columns shared by the legend and every row: grade, bar, vote count. */
.fb-legend,
.fb-row {
  display: grid;
  grid-template-columns: 4.5rem 1fr 4.25rem;
  column-gap: var(--s3);
  align-items: center;
}

.fb-legend {
  font-size: var(--fs-xs);
  font-weight: 650;
  color: var(--ink-3);
}

.fb-key {
  grid-column: 2;
  grid-row: 1;
}

.fb-key.is-soft { justify-self: start; color: var(--soft-text); }
.fb-key.is-correct { justify-self: center; }
.fb-key.is-hard { justify-self: end; color: var(--hard-text); }

.fb-rows {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
}

.fb-row {
  row-gap: 2px;
  padding: var(--s3) 0;
  border-top: 1px solid var(--line);
}

.fb-grade {
  justify-self: start;
}

.fb-count {
  justify-self: end;
  font-size: var(--fs-sm);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.fb-meta {
  grid-column: 2 / 4;
  display: flex;
  justify-content: space-between;
  gap: var(--s2);
  font-size: var(--fs-sm);
}

.fb-verdict {
  font-weight: 650;
}

.fb-verdict.is-soft { color: var(--soft-text); }
.fb-verdict.is-hard { color: var(--hard-text); }
.fb-verdict.is-pending { color: var(--ink-3); font-weight: 500; }

/* The diverging bar: two halves meeting at a centre axis. Soft grows out
 * to the left, hard to the right; "correct" straddles the axis. */
.dbar {
  display: flex;
  align-items: center;
  height: 14px;
}

.dbar-half {
  flex: 1;
  display: flex;
  height: 100%;
  background: var(--surface-2);
}

.dbar-left {
  justify-content: flex-end;
  border-radius: 7px 0 0 7px;
}

.dbar-right {
  border-radius: 0 7px 7px 0;
}

.dbar-axis {
  width: 2px;
  height: 22px;
  border-radius: 1px;
  background: var(--ink);
}

.dbar-seg {
  height: 100%;
  flex: none;
}

.dbar-soft { background: var(--soft-fill); }
.dbar-correct { background: var(--correct-fill); }
.dbar-hard { background: var(--hard-fill); }
.dbar-left .dbar-seg:first-child { border-radius: 7px 0 0 7px; }
.dbar-right .dbar-seg:last-child { border-radius: 0 7px 7px 0; }

/* Under the minimum vote count the bar is shown but quiet. */
.fb-row.is-thin .dbar-seg {
  opacity: 0.4;
}

/* ── Admin ── */

.cards,
.edits {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
}

.card {
  display: grid;
  gap: var(--s2);
  padding: var(--s4) 0;
  border-top: 1px solid var(--line);
}

.card:first-child,
.edit:first-child {
  border-top: 0;
}

.card-title {
  font-family: var(--font-display);
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--fs-lg);
  font-weight: 750;
}

.card-tag {
  padding: 1px var(--s2);
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--ink-2);
  font-size: var(--fs-xs);
  font-weight: 650;
  white-space: nowrap;
}

.facts {
  margin: 0;
  padding-left: 1.1em;
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

.card-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  font-size: var(--fs-sm);
  font-weight: 600;
}

.card-links a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
}

.card-actions {
  display: flex;
  gap: var(--s2);
}

/* A reported photo: the photo itself beside what people said about it. */
.reported-photo {
  grid-template-columns: 96px 1fr;
  gap: var(--s3);
  align-items: start;
}

.reported-photo-img {
  width: 96px;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--r-sm);
  background: var(--surface-2);
}

.reported-photo-body {
  display: grid;
  gap: var(--s2);
  min-width: 0;
}

.edit {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3) 0;
  border-top: 1px solid var(--line);
}

.edit-main {
  flex: 1;
  min-width: 0;
}

/* A row with two buttons (Possibly closed): they wrap under the text on a phone. */
.edit.has-actions {
  flex-wrap: wrap;
}

.edit-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}

.edit-what {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.edit.is-reverted .edit-what {
  color: var(--ink-3);
  text-decoration: line-through;
}

.edit-meta {
  display: flex;
  flex-wrap: wrap;
  column-gap: var(--s3);
  font-size: var(--fs-sm);
  color: var(--ink-3);
}

.confirm {
  display: grid;
  gap: var(--s2);
}

/* ── Motion preference ── */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}

/* ── Admin wall coverage: one row per gym, lowest first ── */

.coverage-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.coverage-list li + li {
  border-top: 1px solid var(--line);
}

.coverage-list a {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--ink);
  overflow-wrap: anywhere;
}
