/*
  Mercury LMS — token sheet (mercury.lms.3, epic 25)

  What this is
    vize's docs design ("Editorial Flyer Theme") adapted onto Mercury's semantic
    token NAMES, which @fiberfx/ui's components read. Mercury's token system is
    not forked: every name below that ui already defines is re-bound in place;
    names ui does not have carry the --lms- prefix. Colour tokens keep ui's
    shape, a space-separated RGB triple used as rgb(var(--x)) (an alpha scrim is
    "r g b / a"). Light is the default theme, as in vize.

  Sources (read 2026-11-04)
    Mercury  fiberfx/ui/src/styles/tokens.css
               :87-300   :root, .light-theme, .dark-theme  (semantic tokens, fonts, radii)
               :306-362  .dark-theme                        (dark scales, scrims, ring)
               :368-375  html, body paint bg/fg/font from the tokens
               :442      ::selection reads --iris-5 (a scale, so re-bound by a rule here)
             fiberfx/ui/src/styles/mercury.css — call sites that decide each role:
               inputs draw their boundary with --border-primary (:69, :98, :126, :159)
               focus = inset --border-focus + 0 0 0 3px --ring-focus (:72, :195, :220)
               checked / primary / tab-active fills use --bg-brand (:35, :197, :218, :451)
               Link and eyebrow text use --fg-brand (:521, :613)
    vize     /Users/jonny/dev/github/vize/docs/vite.config.ts:107-134 (colors :107, darkColors :119, fonts :131)
               light primary #121212, hover #333333, bg #e2ded2, alt #d8d4ca,
               muted #5a5750, border #c6c2b6; dark bg #141414, alt #1a1a1a,
               text #e8e4dc, muted #8a8780, border #1e1e1e;
               sans "Helvetica Neue" + CJK stack, mono JetBrains Mono
             /Users/jonny/dev/github/vize/docs/theme/style.css
               :136 sidebar padding · :152 nav section · :164-172 nav title (mono label)
               :174-182 nav link · :195/:201 hover / active = alt 58% / 70%
               :258-282 hero name + lede · :366-382 h1 / h2 / h3
               :385-394 inline code · :396-414 code block + light syntax palette
               :424-433 code text size · :489-507 dark code block + palette
               :636-648 table · :674-726 square system (every radius 0)
               :740 mobile gutter · :799-803 mobile hero · :875-879 link underline
               :960 measure 68ch · :1039 author avatar stays round (999px)
             /Users/jonny/dev/github/vize/docs/theme/navigation.css — focus outline
               2px offset 2px (summary.nav-title:focus-visible)

  Code-block colour: vite.config.ts names codeBackground #1a1a1a / #0f0f0f, but
  style.css:410 and :499 override it with !important (light: alt 58% over bg,
  dark #211f1e). The rendered value is the one adopted here.

  Decided deviations (mercury.lms.3, not reopened here)
    - No three.js background shader (CDN, style.css shader.css / vein.js): a CSS-only
      "paper" ground instead, --lms-ground-image (a faint grain on --bg-primary).
    - No Google-hosted JetBrains Mono: the mono face stays Mercury's self-hosted
      DM Mono (fiberfx/ui/src/styles/fonts), in --font-secondary, ui's mono token.
    - The Helvetica Neue stack is adopted (system fonts, zero bytes).
    - Accent = the mx logo's "x" blue, #3574F0 light / #548AF7 dark, for non-text
      and focus only (--bg-active, --border-focus, --border-active, --ring-focus,
      selection tint). Links, brand text and checked controls stay ink.
    - Contrast fixes against vize's own values (each measured in contrast.md):
        dark border #1e1e1e on #141414 is 1.11:1   -> raised (decorative >= 1.5)
        light border #c6c2b6 on #e2ded2 is 1.32:1  -> raised the same way
        input boundaries (--border-primary)        -> >= 3:1 in both themes
        Mercury's light status text (green-11 ... indigo-11) is 3.2-4.5:1 on the
        darker paper                                -> darkened to >= 4.5:1
        dark muted #8a8780 drops below 4.5:1 on a hovered/pressed row
                                                    -> dark text lifted to vize's
                                                       own nav mixes
        --ring-focus is opaque (ui uses alpha 0.4): an alpha ring over paper
        falls below 3:1.
    - --radius-full stays 9999px: it encodes shape (switch track, slider, the
      "circle" icon button, avatars), not corner rounding; vize keeps its avatar
      round too (style.css:1039). Every other radius token is 0.

  Selector strategy
    ui declares these tokens three times, on :root, on .light-theme and on
    .dark-theme (each specificity 0,1,0), and @fiberfx/content wraps a rendered
    page in .light-theme or .dark-theme (fiberfx/content/src/render.tsx:80), so a
    rebinding on :root alone loses to ui's block on that wrapper. Put .lms on
    <html> (preferred: index.html already puts .dark-theme there) or on <body>:
      LIGHT  :is(html, body).lms           (0,1,1) beats :root / .light-theme
             .lms .light-theme             (0,2,0) beats ui's .light-theme on a wrapper
      DARK   :is(html, body).lms.dark-theme (0,2,1) beats the LIGHT root rule
             .dark-theme > body.lms        (0,2,1) .dark-theme on <html>, .lms on <body>
             .lms .dark-theme              (0,2,0) beats ui's .dark-theme on a wrapper
    Every rule wins by specificity, not by load order, so this sheet may load
    before or after ui's. LIGHT and DARK set the same colour names (tokens.check.py
    fails otherwise), because the LIGHT root rule also matches html.dark-theme.
    Theme-independent tokens go on the root and on both wrappers, as ui re-declares
    fonts and radii on each wrapper too.

  Scale steps (kan-squad review, CRS0RniRkX1sfo)
    ui's own CSS reads some scale steps directly, so a semantic rebinding alone leaves
    those pairs on Mercury's near-white assumptions. tokens.check.py derives every
    color/background pair from every .css file under fiberfx/ui/src; this sheet re-binds the
    steps those pairs need, in both themes:
      -9 solids  .mx-al__badge and the calendar's selected day put --fg-on-brand (paper
                 in light, #141414 in dark) on --iris-9 / --mx-cal-accent (every -9);
                 .mx-code--solid and .mx-btn--danger put --slate-1 on them.
      -11 text   .mx-code--soft (-11 on -9 / 0.12) and .mx-collapsible (-11 on -3).
      --slate-12 ui reads it directly in exactly three rules, all "ink on caution
                 orange": .mx-alt--warning .mx-alt__icon, .mx-badge--caution,
                 .mx-code--accent-orange.mx-code--solid (and --fg-on-caution is
                 var(--slate-12)). Every other slate-12 consumer is re-bound above. ui's
                 dark theme flips slate-12 to light, so those rules put light ink on vivid
                 orange (2.56:1), and the calendar puts the opposite ink on the same
                 --orange-9. Here slate-12 is the caution ink: paper on a darkened orange
                 in light, #141414 on ui's vivid orange in dark. A ui fix (the three rules
                 reading --fg-on-caution) would let this rebinding go.

  Breakpoint (not a token: var() cannot appear in a media query): vize switches
  to its mobile layout at max-width 768px / min-width 769px (style.css:728, :127).

  Values marked "assumed" have no source in vize's repository: ox-content's
  default theme supplies --octc-sidebar-width and --octc-header-height, and it is
  not installed there (no node_modules), so those sizes are chosen, not copied.

  Check: python3 -I sites/mercury/theme/tokens.check.py   (exit 0 = every pair passes)
*/

/* ---- Theme-independent: type families, radii, LMS layout and type scale ---- */
:is(html, body).lms,
.lms .light-theme,
.lms .dark-theme {
  /* Type families — Mercury names. --font-secondary is ui's mono (code, kbd). */
  --font-primary:   "Helvetica Neue", Helvetica, Arial, "Noto Sans CJK JP", "Hiragino Kaku Gothic ProN", "Yu Gothic", system-ui, sans-serif;
  --font-secondary: "DM Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --font-display:   "Helvetica Neue", Helvetica, Arial, "Noto Sans CJK JP", "Hiragino Kaku Gothic ProN", "Yu Gothic", system-ui, sans-serif;

  /* Radii — the square system (style.css:674-726). --radius-full kept, see header. */
  --radius-2:  0;
  --radius-4:  0;
  --radius-6:  0;
  --radius-8:  0;
  --radius-12: 0;
  --radius-16: 0;
  --radius-20: 0;
  --radius-24: 0;
  --radius-32: 0;

  /* LMS layout */
  --lms-header-height:       3.5rem;                       /* assumed */
  --lms-sidebar-width:       17rem;                        /* assumed */
  --lms-toc-width:           14rem;                        /* assumed */
  --lms-content-max-width:   48rem;                        /* assumed */
  --lms-measure:             68ch;                         /* style.css:960 */
  --lms-gutter:              clamp(1rem, 4vw, 4rem);       /* 4vw: style.css:251; clamp assumed */
  --lms-gutter-mobile:       0.75rem;                      /* style.css:740 */
  --lms-sidebar-padding:     1.2rem 1.1rem 1.6rem;         /* style.css:136 */
  --lms-nav-section-padding: 0.85rem 0;                    /* style.css:152 */
  --lms-nav-link-padding:    0.4rem 0.65rem 0.4rem 0.95rem; /* style.css:178 */
  --lms-rule-width:          1px;
  --lms-focus-outline-width:  2px;                         /* navigation.css summary:focus-visible */
  --lms-focus-outline-offset: 2px;
  --lms-link-underline-offset:    0.16em;                  /* style.css:877 */
  --lms-link-underline-thickness: 0.08em;                  /* style.css:878 */

  /* LMS type scale (vize). Body and small reuse Mercury's scale steps. */
  --lms-type-hero-size:     clamp(6rem, 20vw, 20rem);      /* style.css:261 */
  --lms-type-hero-tracking: -0.06em;                       /* :262 */
  --lms-type-hero-leading:  0.88;                          /* :263 */
  --lms-type-hero-weight:   700;                           /* :260 */
  --lms-type-hero-mobile-size:     clamp(4.5rem, 29vw, 7.6rem); /* :801 */
  --lms-type-hero-mobile-tracking: -0.07em;                /* :802 */
  --lms-type-hero-mobile-leading:  0.86;                   /* :803 */
  --lms-type-lede-size:     clamp(1.2rem, 2.4vw, 1.75rem); /* :275 */
  --lms-type-lede-tracking: -0.02em;                       /* :277 */
  --lms-type-lede-leading:  1.4;                           /* :278 */
  --lms-type-lede-weight:   500;                           /* :276 */
  --lms-type-h1-size:     2rem;                            /* :368 */
  --lms-type-h1-tracking: -0.04em;                         /* :369 */
  --lms-type-h1-weight:   700;                             /* :367 */
  --lms-type-h2-size:     1.375rem;                        /* :374 */
  --lms-type-h2-tracking: -0.02em;                         /* :375 */
  --lms-type-h2-weight:   600;                             /* :373 */
  --lms-type-h3-size:     1.125rem;                        /* assumed: vize sets weight + tracking only */
  --lms-type-h3-tracking: -0.01em;                         /* :381 */
  --lms-type-h3-weight:   600;                             /* :380 */
  --lms-type-body-size:    var(--text-body-400-size);      /* Mercury 16px/24px */
  --lms-type-body-leading: var(--text-body-400-lh);
  --lms-type-small-size:   0.8125rem;                      /* :592 footer, :332 buttons */
  --lms-type-nav-size:     0.84rem;                        /* :181 */
  --lms-type-nav-leading:  1.35;                           /* :182 */
  --lms-type-mono-label-size:     0.66rem;                 /* :169 nav title */
  --lms-type-mono-label-tracking: 0.12em;                  /* :171 */
  --lms-type-mono-label-weight:   600;                     /* :170 */
  --lms-type-table-head-size:     0.75rem;                 /* :646 */
  --lms-type-table-head-tracking: 0.06em;                  /* :647 */
  --lms-type-code-block-size:    0.84rem;                  /* :431 */
  --lms-type-code-block-leading: 1.58;                     /* :432 */
  --lms-type-code-inline-size:   0.88em;                   /* :392 */
}

/* ---- LIGHT (default) ---- */
:is(html, body).lms,
.lms .light-theme {
  color-scheme: light;

  /* LMS accent: the mx logo's "x" blue — non-text and focus only */
  --lms-accent: 53 116 240;                 /* #3574F0 */

  /* Surfaces */
  --bg-primary:         226 222 210;        /* #e2ded2 vize background */
  --bg-secondary:       222 218 207;        /* #dedacf alt 38% over bg (style.css:390) */
  --bg-tertiary:        220 216 205;        /* #dcd8cd alt 58% over bg = code block (:410) */
  --bg-elevated:        226 222 210;        /* popover / modal: the paper, set off by its border */
  --bg-inverse:          18  18  18;        /* #121212 vize primary */
  --bg-inverse-hover:    51  51  51;        /* #333333 vize primaryHover */
  --bg-inverse-pressed:  74  72  68;        /* #4a4844 */
  --bg-disabled:        216 212 202;        /* #d8d4ca vize alt */

  /* Scrims: vize tints with its alt paper, not with ink (style.css:195, :201) */
  --bg-hover:    216 212 202 / 0.58;
  --bg-pressed:  216 212 202 / 1;
  --bg-selected: 216 212 202 / 0.70;
  --bg-backdrop:  18  18  18 / 0.56;
  --bg-overlay:   18  18  18 / 0.32;

  /* Brand = ink: vize's primary action is text-coloured (style.css:325-327) */
  --bg-brand:          18  18  18;
  --bg-brand-hover:    51  51  51;
  --bg-brand-pressed:  74  72  68;
  --bg-brand-subtle:  216 212 202;          /* #d8d4ca */
  --bg-brand-muted:   207 203 192;          /* #cfcbc0 */

  /* Active = accent (fills, never text) */
  --bg-active:        var(--lms-accent);
  --bg-active-hover:   48 101 207;          /* accent 85% over ink */
  --bg-active-subtle: 202 207 214;          /* accent 14% over paper */

  /* Foregrounds */
  --fg-primary:     18  18  18;             /* #121212 */
  --fg-secondary:   80  77  71;             /* #504d47 muted 86% + text (nav title, style.css:167) */
  --fg-tertiary:    90  87  80;             /* #5a5750 vize textMuted */
  --fg-disabled:   148 144 135;             /* exempt from contrast (disabled) */
  --fg-inverse:    226 222 210;
  --fg-on-brand:   226 222 210;
  --fg-on-active:  255 255 255;             /* glyphs on the accent (>= 3:1); no text on accent */
  --fg-brand:        18  18  18;            /* links and brand text stay ink */
  --fg-brand-hover:  51  51  51;
  --fg-active:       18  18  18;
  --fg-link:         18  18  18;
  --fg-link-hover:   51  51  51;
  --fg-link-visited: 18  18  18;
  /* Status text: ui's own mapping onto the -11 steps, re-bound below */
  --fg-positive:   var(--green-11);
  --fg-negative:   var(--red-11);
  --fg-caution:    var(--orange-11);
  --fg-discovery:  var(--plum-11);
  --fg-info:       var(--indigo-11);

  /* Scale steps ui's CSS reads directly (see "Scale steps" in the header).
     -9: paper (--fg-on-brand) and white (--slate-1) on it >= 4.5:1;
     -11: on its -3 tint, on its -9 / 0.12 tint over paper, and on every surface >= 4.5:1. */
  --green-9:    32 110  72;   --green-11:   19 100  44;
  --indigo-9:   55  88 197;   --indigo-11:  10  88 157;
  --iris-9:     83  83 195;   --iris-11:    77  73 174;
  --plum-9:    144  62 156;   --plum-11:   130  54 142;
  --red-9:     172  54  58;   --red-11:    164  34  39;
  --orange-9:  158  68  13;   --orange-11: 149  56   4;
  --slate-12:  226 222 210;   /* the ink of the three caution/orange rules: light on the darkened orange */

  /* Borders */
  --border-primary:   122 118 108;          /* #7a766c input boundary, >= 3:1 */
  --border-secondary: 177 173 161;          /* #b1ada1 decorative rule, >= 1.5:1 */
  --border-strong:     90  87  80;          /* #5a5750 vize hero-action-alt border (:343) */
  --border-disabled:  198 194 182;          /* #c6c2b6 vize border; exempt (disabled) */
  --border-focus:     var(--lms-accent);
  --border-active:    var(--lms-accent);
  --border-brand:      18  18  18;
  --border-inverse:    18  18  18;
  --ring-focus:        53 116 240 / 1;      /* opaque: an alpha ring falls below 3:1 */

  /* LMS colour tokens */
  --lms-nav-fg:          40  39  37;        /* text 70% + muted (style.css:180) */
  --lms-code-bg:         var(--bg-tertiary);
  --lms-code-fg:         36  38  43;        /* #24262b (style.css:397) */
  --lms-code-border:     var(--border-secondary);
  --lms-code-inline-bg:  var(--bg-secondary);
  --lms-code-inline-fg:  91  72  60;        /* #5b483c (:391) */
  --lms-syntax-comment:      71  73  65;    /* #474941 (:398) */
  --lms-syntax-keyword:     107   0 184;    /* #6b00b8 */
  --lms-syntax-string:        0  91  46;    /* #005b2e */
  --lms-syntax-number:      140  48   0;    /* #8c3000 */
  --lms-syntax-type:          0  87 107;    /* #00576b */
  --lms-syntax-function:      0  72 183;    /* #0048b7 */
  --lms-syntax-property:    149   0  62;    /* #95003e */
  --lms-syntax-punctuation:  64  67  74;    /* #40434a */
  --lms-selection-bg:   178 192 218;        /* accent 28% over paper */
  --lms-selection-fg:    18  18  18;
  --lms-ground-grain:    18  18  18 / 0.035;
  --lms-ground-image: radial-gradient(rgb(var(--lms-ground-grain)) 0.6px, transparent 0.9px);
  --lms-ground-size:  4px 4px;
}

/* ---- DARK ---- */
:is(html, body).lms.dark-theme,
.dark-theme > body.lms,
.lms .dark-theme {
  color-scheme: dark;

  --lms-accent: 84 138 247;                 /* #548AF7 */

  /* Surfaces */
  --bg-primary:          20  20  20;        /* #141414 vize background */
  --bg-secondary:        26  26  26;        /* #1a1a1a vize backgroundAlt */
  --bg-tertiary:         33  31  30;        /* #211f1e vize dark code block (style.css:499) */
  --bg-elevated:         26  26  26;
  --bg-inverse:         232 228 220;        /* #e8e4dc vize dark primary */
  --bg-inverse-hover:   255 255 255;        /* #ffffff vize dark primaryHover */
  --bg-inverse-pressed: 207 202 192;        /* #cfcac0 */
  --bg-disabled:         30  30  30;

  /* Scrims: the paper ink at low alpha */
  --bg-hover:    232 228 220 / 0.05;
  --bg-pressed:  232 228 220 / 0.09;
  --bg-selected: 232 228 220 / 0.07;
  --bg-backdrop:   0   0   0 / 0.72;
  --bg-overlay:    0   0   0 / 0.48;

  /* Brand = ink, inverted */
  --bg-brand:         232 228 220;
  --bg-brand-hover:   255 255 255;
  --bg-brand-pressed: 207 202 192;
  --bg-brand-subtle:   30  30  30;
  --bg-brand-muted:    38  38  38;

  /* Active = accent */
  --bg-active:        var(--lms-accent);
  --bg-active-hover:  118 161 249;          /* accent 80% over white */
  --bg-active-subtle:  33  44  65;          /* accent 20% over #141414 */

  /* Foregrounds */
  --fg-primary:    232 228 220;             /* #e8e4dc */
  --fg-secondary:  162 159 151;             /* #a29f97 lifted: see header */
  --fg-tertiary:   151 148 141;             /* #97948d muted 86% + text (style.css:167) */
  --fg-disabled:    96  94  89;             /* exempt (disabled) */
  --fg-inverse:     20  20  20;
  --fg-on-brand:    20  20  20;
  --fg-on-active:   20  20  20;
  --fg-brand:       232 228 220;
  --fg-brand-hover: 255 255 255;
  --fg-active:      232 228 220;
  --fg-link:        232 228 220;
  --fg-link-hover:  255 255 255;
  --fg-link-visited: 232 228 220;
  /* Status text: ui's own mapping onto the -11 steps */
  --fg-positive:   var(--green-11);
  --fg-negative:   var(--red-11);
  --fg-caution:    var(--orange-11);
  --fg-discovery:  var(--plum-11);
  --fg-info:       var(--indigo-11);

  /* Scale steps: ui's dark values (tokens.css:308-343), except the three -9 solids that
     carry dark ink (--fg-on-brand, --slate-1) below 4.5:1, which are lightened. */
  --green-9:    48 164 108;   --green-11:   78 212 136;
  --indigo-9:   89 121 226;   --indigo-11: 158 177 255;   /* ui 62 99 221: 3.62 */
  --iris-9:    116 116 220;   --iris-11:   177 169 255;   /* ui 91 91 214: 3.43 / 3.51 */
  --plum-9:    180  94 194;   --plum-11:   211 131 228;   /* ui 171 74 186: 3.88 / 3.97 */
  --red-9:     229  72  77;   --red-11:    255 125 133;
  --orange-9:  247 107  21;   --orange-11: 255 160  87;
  --slate-12:   20  20  20;   /* the ink of the three caution/orange rules: dark on vivid orange */

  /* Borders */
  --border-primary:   109 107 104;          /* #6d6b68 input boundary, >= 3:1 */
  --border-secondary:  65  63  60;          /* #413f3c decorative rule (vize #1e1e1e is 1.11:1) */
  --border-strong:    138 135 128;          /* #8a8780 vize dark muted */
  --border-disabled:   40  40  40;          /* exempt (disabled) */
  --border-focus:     var(--lms-accent);
  --border-active:    var(--lms-accent);
  --border-brand:     232 228 220;
  --border-inverse:   232 228 220;
  --ring-focus:        84 138 247 / 1;

  /* LMS colour tokens */
  --lms-nav-fg:         204 200 192;        /* text 70% + muted (style.css:180) */
  --lms-code-bg:        var(--bg-tertiary);
  --lms-code-fg:        237 229 216;        /* #ede5d8 (style.css:490) */
  --lms-code-border:    var(--border-secondary);
  --lms-code-inline-bg: 238 228 212 / 0.045; /* (:505) */
  --lms-code-inline-fg: 221 208 194;        /* #ddd0c2 (:506) */
  --lms-syntax-comment:     178 163 143;    /* #b2a38f (:491) */
  --lms-syntax-keyword:     207 154 130;    /* #cf9a82 */
  --lms-syntax-string:      164 182 148;    /* #a4b694 */
  --lms-syntax-number:      207 176 122;    /* #cfb07a */
  --lms-syntax-type:        202 186 167;    /* #cabaa7 */
  --lms-syntax-function:    209 162 122;    /* #d1a27a */
  --lms-syntax-property:    211 190 160;    /* #d3bea0 */
  --lms-syntax-punctuation: 172 165 155;    /* rgba(237,228,214,.68) over #211f1e (:498) */
  --lms-selection-bg:    46  67 111;        /* accent 40% over #141414 */
  --lms-selection-fg:   232 228 220;
  --lms-ground-grain:   232 228 220 / 0.03;
  --lms-ground-image: radial-gradient(rgb(var(--lms-ground-grain)) 0.6px, transparent 0.9px);
  --lms-ground-size:  4px 4px;
}

/* ui's ::selection reads the --iris-5 scale step (tokens.css:442); re-binding a scale
   would change what "iris 5" means, so the LMS selection is a scoped rule instead. */
.lms ::selection {
  background: rgb(var(--lms-selection-bg));
  color: rgb(var(--lms-selection-fg));
}
