/* 文心 · 万形 complete kit
   Generated by scripts/build-css.mjs. Unminified by decision. */
/* 文心 · 万形 — the whole kit.
   Import this for everything, or cherry-pick the parts you need.
   Form-level tokens are opt-in: add kit/tokens/forms/fN-*.css alongside. */
/* source: kit/layers.css */
/* Cascade layers, in order of increasing precedence.
   Declared once, here, so that later files never fight over specificity.

   The important consequence: markdown/ can use loose descendant selectors
   (it styles HTML it did not author) without ever outranking a component,
   and a form layer can always win over everything above it. wx.site is last: it
   is the documentation shell, and must never be what a consumer inherits. */
@layer wx.reset, wx.tokens, wx.base, wx.components, wx.patterns,
       wx.markdown, wx.charts, wx.form, wx.site;

@layer wx.tokens {
/* source: kit/tokens/core.css */
:root {
  /* Only a hint until the reader chooses. The explicit overrides live beside
     the dark palette in dark.css: once [data-theme] is set, the UA must paint
     form controls, scrollbars and the caret to match the page, not the OS.
     Without them a light page on a dark OS renders bare <input> with a dark
     field and inherits dark ink onto it — 1.02:1, and a 2px UA border. */
  color-scheme: light dark;

  --color-bg-warm:    #F2F0EB;
  --color-bg-base:    #FAFAF8;
  --color-bg-pure:    #FFFFFF;
  --color-bg-subtle:  #F0EDE7;

  --color-text-primary:   #3A3837;
  /* Four text tiers, each perceptibly distinct (dL* >= 11) and each safe for
     body-size text on bg-warm. Field evidence introduced #706D68 independently
     on zopiya.com and the blog; the older pale greys measured 1.54-3.23:1.
     `muted` and `tertiary` were retired in D-20: once every tier had to clear
     AA, they collapsed to within dL* 2 of `functional` and named nothing. */
  --color-text-secondary:  #55524E;
  --color-text-functional: #706D68;
  --color-text-heading:   #2C2B29;

  /* Accent used sparingly — max 2 occurrences per page (excluding active icons) */
  --color-accent:        #8B3525;
  --color-accent-hover:  #A84030;
  --color-accent-subtle: #F5E8E5;
  --color-on-accent:     #FFFFFF;

  /* Semantic colors — required by criterion C-6 and the accessibility floor.
     NOT part of the accent budget; must always be paired with a text label,
     never carrying meaning by color alone. Warm-earth, low saturation.
     Mutually distinguishable: minimum pairwise dE = 28 (accent <-> danger). */
  --color-danger:         #5C1F2F;  /* oxblood  10.90:1 on bg-warm */
  --color-danger-subtle:  #F2E8EB;
  --color-warning:        #7D5E12;  /* ochre     5.30:1 */
  --color-warning-subtle: #F2EFE8;
  --color-success:        #4F6B3A;  /* moss      5.27:1 */
  --color-success-subtle: #ECF2E8;

  /* Overlay scrim — the vellum dimmed, never neutral black. */
  --color-scrim: rgb(26 24 22 / 0.55);

  --color-border-subtle: #E5E1DA;
  --color-border-strong: #C8C3BA;

  --color-link:       #3A3837;
  --color-link-hover: #8B3525;
  --color-focus:      #8B3525;

  /* Latin fonts self-hosted; CJK falls back to system fonts:
     iOS/macOS → PingFang/Songti, Windows → Microsoft YaHei/SimSun,
     Android/Linux → Noto CJK */
  --font-display: "Lora", "Noto Serif SC", "Source Han Serif SC", "Songti SC",
    "SimSun", serif;
  --font-body:    "EB Garamond", "Noto Serif SC", "Source Han Serif SC",
    "Songti SC", "SimSun", serif;
  --font-ui:      system-ui, -apple-system, "PingFang SC", "Hiragino Sans GB",
    "Microsoft YaHei", "Noto Sans SC", sans-serif;
  --font-mono:    "JetBrains Mono", "Fira Code", "Cascadia Code", ui-monospace,
    monospace;

  --text-xs:   0.694rem;
  --text-sm:   0.833rem;
  --text-base: 1rem;
  --text-md:   1.0625rem;
  --text-lg:   1.25rem;
  --text-xl:   1.5rem;
  --text-2xl:  1.875rem;
  --text-3xl:  2.25rem;
  --text-4xl:  3rem;
  --text-5xl:  4.5rem;
  --text-code: 0.875em;   /* relative to surrounding text */

  --leading-tight:   1.25;
  --leading-snug:    1.45;
  --leading-normal:  1.6;
  --leading-relaxed: 1.85;
  --leading-loose:   2.0;

  --tracking-tight:   -0.02em;
  --tracking-normal:   0;
  --tracking-wide:     0.05em;
  --tracking-wider:    0.15em;
  --tracking-chinese:  0.1em;

  --space-1:  4px;  --space-2:  8px;  --space-3:  12px;
  --space-4:  16px; --space-5:  20px; --space-6:  24px;
  --space-8:  32px; --space-10: 40px; --space-12: 48px;
  --space-16: 64px; --space-24: 96px; --space-32: 128px;

  --width-article:  clamp(520px, 55vw, 640px);
  --width-content:  clamp(620px, 65vw, 760px);
  --width-showcase: clamp(700px, 72vw, 920px);
  --padding-page-x: clamp(20px, 5vw, 72px);

  --radius-none: 0;
  --radius-sm:   2px;
  --radius-md:   4px;
  --radius-full: 9999px;

  /* The 1.5px mark stroke is one of the system's signature constraints.
     Tokenised so it can be audited rather than only described in prose. */
  --stroke-hairline: 1px;
  --stroke-mark:     1.5px;

  --icon-sm: 16px;
  --icon-md: 20px;
  --icon-lg: 24px;

  --duration-instant: 80ms;
  --duration-fast:   180ms;
  --duration-base:   260ms;
  --duration-slow:   420ms;
  --duration-crawl:  600ms;
  --ease-default: cubic-bezier(0.25, 0.1, 0.25, 1);
  --ease-out:     cubic-bezier(0, 0, 0.2, 1);
  --ease-in:      cubic-bezier(0.4, 0, 1, 1);
  /* ease-in-out is reserved for the brand mark's breathing loop — nothing else */
  --ease-in-out:  cubic-bezier(0.42, 0, 0.58, 1);
  --duration-breath: 4000ms;

  /* Stagger delays at 60ms intervals, covering up to 8 items */
  --stagger-1: 60ms;
  --stagger-2: 120ms;
  --stagger-3: 180ms;
  --stagger-4: 240ms;
  --stagger-5: 300ms;
  --stagger-6: 360ms;
  --stagger-7: 420ms;
  --stagger-8: 480ms;
}
}
@layer wx.tokens {
/* source: kit/tokens/dark.css */
/* ============================================================
   Dark mode · 夜晚的羊皮纸 Night Vellum
   ------------------------------------------------------------
   core.css declares `color-scheme: light dark` but for a long time
   defined no dark values at all — the system promised dark mode and
   never delivered it. These values were rescued from the old example
   token file and re-derived where they failed to meet AA.

   Not a simple inversion: the ground is warm dark (#1A1816), not black,
   and the text is warm ivory (#E8E3DC), not white. Hue and saturation are
   preserved across modes; only lightness is lifted, so a color stays
   recognisably itself in either mode (criterion M-9).

   Both switches are supported, and each wins in its own direction:
   the media query respects the OS, the attribute overrides it.
   ============================================================ */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg-warm:   #1A1816;
    --color-bg-base:   #201E1B;
    --color-bg-pure:   #242220;
    --color-bg-subtle: #2A2724;

    --color-text-heading:   #F0EBE3;
    --color-text-primary:   #E8E3DC;
    --color-text-secondary:  #B5AFA6;
    --color-text-functional: #8A857D;

    /* #C4533E was the rescued value; it measures 3.92:1 on this ground and
       fails AA for body-size text. Lifted to 4.54:1 at the same hue. */
    --color-accent:        #CF5F4A;
    --color-accent-hover:  #DE7059;
    --color-accent-subtle: #2E1A16;
    --color-on-accent:     #1A1816;

    --color-danger:         #C6697E;
    --color-danger-subtle:  #2B171C;
    --color-warning:        #B3871A;
    --color-warning-subtle: #2B2517;
    --color-success:        #739B53;
    --color-success-subtle: #202B17;

    --color-scrim: rgb(10 9 8 / 0.65);
    --color-border-subtle: #2E2B27;
    --color-border-strong: #403C37;

    --color-link:       #E8E3DC;
    --color-link-hover: #CF5F4A;
    --color-focus:      #CF5F4A;
  }
}

[data-theme="dark"] {
  --color-bg-warm:   #1A1816;
  --color-bg-base:   #201E1B;
  --color-bg-pure:   #242220;
  --color-bg-subtle: #2A2724;

  --color-text-heading:   #F0EBE3;
  --color-text-primary:   #E8E3DC;
  --color-text-secondary:  #B5AFA6;
  --color-text-functional: #8A857D;

  --color-accent:        #CF5F4A;
  --color-accent-hover:  #DE7059;
  --color-accent-subtle: #2E1A16;
  --color-on-accent:     #1A1816;

  --color-danger:         #C6697E;
  --color-danger-subtle:  #2B171C;
  --color-warning:        #B3871A;
  --color-warning-subtle: #2B2517;
  --color-success:        #739B53;
  --color-success-subtle: #202B17;

  --color-scrim: rgb(10 9 8 / 0.65);
  --color-border-subtle: #2E2B27;
  --color-border-strong: #403C37;

  --color-link:       #E8E3DC;
  --color-link-hover: #CF5F4A;
  --color-focus:      #CF5F4A;
}

/* The UA paints what :root declares, not what the page painted. When the
   reader has chosen a theme, that choice has to reach the form controls,
   scrollbars and caret too — otherwise a light page on a dark OS hands you a
   dark <input> under dark ink. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }
}
@layer wx.tokens {
/* source: kit/tokens/dense.css */
/* Optional density preset. It changes only spacing variables and is inert until
   a consumer opts in, so core.css remains the single source of default values. */
@layer wx.tokens {
  :root[data-density="dense"], .wx-density--dense {
    --space-2: 6px;
    --space-3: 8px;
    --space-4: 12px;
    --space-5: 16px;
    --space-6: 20px;
    --space-8: 24px;
    --space-10: 32px;
    --space-12: 40px;
    --space-16: 52px;
    --space-24: 76px;
    --space-32: 100px;
  }
}
}

/* source: kit/base/fonts.css */
/* Self-hosted. No third-party font CDN — criterion M-6 (sustainability) and
   M-8 (font performance), and it is what makes F4/F7 print output reproducible
   offline. Variable weight ranges satisfy M-3; unicode-range subsetting keeps
   Latin files small and lets CJK fall through to system fonts. */
@layer wx.base {
  @font-face {
    font-family: "EB Garamond";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("../base/fonts/eb-garamond-latin.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: "EB Garamond";
    font-style: italic;
    font-weight: 400 700;
    font-display: swap;
    src: url("../base/fonts/eb-garamond-latin-italic.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: "Lora";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("../base/fonts/lora-latin.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: "Lora";
    font-style: italic;
    font-weight: 400 700;
    font-display: swap;
    src: url("../base/fonts/lora-latin-italic.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: "JetBrains Mono";
    font-style: normal;
    font-weight: 400 500;
    font-display: swap;
    src: url("../base/fonts/jetbrains-mono-latin.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;
  }
}
/* source: kit/base/reset.css */
/* A small reset. Not normalize.css — this system needs the browser's defaults
   removed in a few specific places, not every difference flattened. */
@layer wx.reset {
  *, *::before, *::after { box-sizing: border-box; }

  html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

  body, h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ol, ul {
    margin: 0;
    padding: 0;
  }

  /* Lists lose their markers only when they carry a class — an unstyled <ul>
     in prose should still look like a list. */
  ul[class], ol[class] { list-style: none; }

  img, picture, svg, video, canvas {
    display: block;
    max-width: 100%;
    height: auto;
  }

  /* Embedded frames and players have intrinsic sizes that ignore their column
     and push the page sideways. They need the same ceiling as an image. */
  iframe, audio, embed, object { max-width: 100%; }
  audio { width: 100%; }

  /* <fieldset>'s default is a 2px groove — a forbidden.md violation the
     browser ships. The group is drawn by wx-form, not by the element. */
  fieldset { margin: 0; padding: 0; border: 0; min-width: 0; }
  legend { padding: 0; }

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

  button { background: none; border: 0; }

  table { border-collapse: collapse; border-spacing: 0; }

  /* Sensible hyphenation and wrapping for mixed CJK/Latin text. */
  p, li, dd, blockquote, figcaption { overflow-wrap: break-word; }
}
/* source: kit/base/typography.css */
/* The typographic ground: what a page looks like with zero classes.
   If a bare <h1> or <p> would be wrong without a rule, the rule belongs here. */
@layer wx.base {
  html { font-size: 100%; }

  body {
    background: var(--color-bg-warm);
    color: var(--color-text-primary);
    font-family: var(--font-body);
    font-size: var(--text-md);
    line-height: var(--leading-relaxed);
    font-synthesis-weight: none;
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
  }

  /* Headings are display-serif and set tighter than body — the scale does the
     work, not weight. Criterion P-4: contrast must serve hierarchy. */
  h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    color: var(--color-text-heading);
    line-height: var(--leading-tight);
    font-weight: 600;
    text-wrap: balance;
  }
  h1 { font-size: var(--text-4xl); letter-spacing: var(--tracking-tight); }
  h2 { font-size: var(--text-2xl); }
  h3 { font-size: var(--text-xl); }
  h4 { font-size: var(--text-lg); }
  h5 { font-size: var(--text-md); }
  h6 {
    font-size: var(--text-sm);
    font-family: var(--font-ui);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--color-text-secondary);
  }

  /* Vertical rhythm. The reset zeroes every margin, so without this a bare
     <h2> sits flush against the paragraph above it — which is precisely the
     kind of thing base/ exists to prevent. Space above a heading is much
     larger than below it: the gap belongs to the section it opens, and that
     proximity is what groups a heading with its own text (P-2). */
  h1 { margin-block: 0 var(--space-5); }
  h2 { margin-block: var(--space-12) var(--space-4); }
  h3 { margin-block: var(--space-10) var(--space-3); }
  h4, h5, h6 { margin-block: var(--space-8) var(--space-2); }
  h1:first-child, h2:first-child, h3:first-child,
  h4:first-child, h5:first-child, h6:first-child { margin-block-start: 0; }

  p, ul, ol, dl, blockquote, pre, figure, table { margin-block: 0 var(--space-5); }
  :is(p, ul, ol, dl, blockquote, pre, figure, table):last-child { margin-block-end: 0; }

  /* CJK wants looser tracking at display sizes; :lang() keeps it off Latin. */
  :lang(zh) h1, :lang(zh) h2 { letter-spacing: var(--tracking-chinese); }

  p { text-wrap: pretty; }

  /* Links carry no underline in body text — they sit at body color and reveal
     themselves on hover. In pure navigation they may rely on color alone. */
  a {
    color: var(--color-link);
    text-decoration: none;
    transition: color var(--duration-fast) var(--ease-default);
  }
  a:hover { color: var(--color-link-hover); }

  /* Prose links are the exception: inside running text an underline appears on
     hover, so the link is not signalled by color alone (forbidden.md). */
  p > a, li > a, dd > a {
    text-decoration: underline;
    text-decoration-thickness: var(--stroke-hairline);
    text-underline-offset: 0.18em;
    text-decoration-color: var(--color-border-strong);
  }
  p > a:hover, li > a:hover, dd > a:hover {
    text-decoration-color: currentColor;
  }

  strong, b { font-weight: 600; color: var(--color-text-heading); }

  /* Italic is discouraged for CJK emphasis (G2) — fall back to weight. */
  /* Chinese has no true italic. The browser synthesises an oblique that reads
     as a rendering fault, so every element whose default is italic gets the
     same treatment — this rule used to cover em alone, and i / cite / dfn /
     var / address trigger exactly the same defect. */
  :lang(zh) :is(em, i, cite, dfn, var) { font-style: normal; font-weight: 600; }
  address { font-style: normal; }

  /* ---- The rest of the inline family ---------------------------------- */

  /* The browser default is #ff0. Nothing else on the page is that saturated. */
  mark {
    padding-inline: 0.15em;
    background: var(--color-accent-subtle);
    color: var(--color-text-primary);
  }

  s, del { text-decoration-line: line-through; text-decoration-thickness: from-font; }
  ins { text-decoration: underline; text-decoration-color: var(--color-success); }
  /* <u> is discouraged precisely because it imitates a link; the docs say so
     rather than the CSS pretending otherwise with a decorative substitute. */
  u { text-decoration: underline; }

  /* Superscripts must not open the line they sit in. */
  sub, sup { font-size: 0.75em; line-height: 0; position: relative; vertical-align: baseline; }
  sup { inset-block-start: -0.5em; }
  sub { inset-block-start: 0.25em; }

  /* A title is hover-only, so touch readers never see it. The dotted rule at
     least marks that something is there to look up. */
  abbr[title] { text-decoration: underline dotted; text-underline-offset: 0.18em; cursor: help; }

  /* The browser picks quotes from lang; Chinese wants corner brackets, and the
     nested pair differs from the Latin one. */
  q { quotes: "\201C" "\201D" "\2018" "\2019"; }
  :lang(zh) q { quotes: "\300C" "\300D" "\300E" "\300F"; }

  /* Ruby carries pinyin and zhuyin — a Chinese-first system cannot leave it
     at the browser default. */
  ruby { ruby-position: over; }
  rt { font-size: 0.5em; color: var(--color-text-secondary); }
  rp { display: none; }

  small { font-size: var(--text-sm); color: var(--color-text-secondary); }

  code, kbd, samp, pre {
    font-family: var(--font-mono);
    font-size: var(--text-code);
  }

  hr {
    border: 0;
    border-top: var(--stroke-hairline) solid var(--color-border-subtle);
    margin-block: var(--space-12);
  }

  blockquote { color: var(--color-text-secondary); }

  ul, ol { padding-inline-start: var(--space-6); }
  li { margin-block: var(--space-2); }

  figcaption {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
    margin-top: var(--space-3);
  }

  ::selection {
    background: var(--color-accent-subtle);
    color: var(--color-text-heading);
  }

  /* ---- Bare tables ----------------------------------------------------- */
  /* Zero-class markup still has to be readable: this is the same shape
     .wx-md table draws, so a renderer's <table> and a hand-written one do not
     disagree. wx-table adds density and alignment on top. */
  th, td { padding: var(--space-3); padding-inline-start: 0; text-align: start; vertical-align: baseline; }
  thead th { font-weight: 600; color: var(--color-text-heading); border-block-end: var(--stroke-hairline) solid var(--color-border-strong); }
  tbody td, tbody th { border-block-end: var(--stroke-hairline) solid var(--color-border-subtle); }
  tfoot td, tfoot th { border-block-start: var(--stroke-hairline) solid var(--color-border-strong); font-weight: 600; }
  caption { margin-block-end: var(--space-3); color: var(--color-text-secondary); text-align: start; }

  /* ---- Disclosure ------------------------------------------------------ */
  summary { cursor: pointer; }
  summary:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
}
/* source: kit/base/a11y.css */
/* The accessibility floor — layer one of the two-track rule. Unconditional in
   every form and both tracks. Nothing here is a stylistic preference. */
@layer wx.base {
  /* Keyboard-only focus. Never removed, never zeroed. */
  /* Zero-class checkboxes, radios and ranges paint in the platform blue.
     wx-check and wx-radio already settle this per component; a Markdown task
     list or a raw form should not have to opt in. */
  :root { accent-color: var(--color-accent); }

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

  /* Visible only to screen readers. */
  .wx-sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* Skip link — hidden until focused, then it must be plainly visible. */
  .wx-skip {
    position: absolute;
    inset-inline-start: var(--space-4);
    inset-block-start: calc(-1 * var(--space-16));
    z-index: 100;
    padding: var(--space-3) var(--space-5);
    background: var(--color-bg-pure);
    color: var(--color-text-heading);
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    transition: inset-block-start var(--duration-fast) var(--ease-out);
  }
  .wx-skip:focus { inset-block-start: var(--space-4); }

  /* Touch targets. WCAG 2.2 §2.5.8 floor for pointer input; forms that need a
     larger minimum raise it via --touch-target-min. */
  @media (pointer: coarse) {
    a, button, [role="button"], input, select, summary {
      min-height: var(--touch-target-min, 24px);
      min-width: var(--touch-target-min, 24px);
    }
  }

  [hidden] { display: none !important; }

  /* Windows High Contrast / forced-colors. Do not freeze warm-earth token
     colors there: system colors preserve the user's contrast contract. */
  @media (forced-colors: active) {
    :root { forced-color-adjust: auto; }
    /* Zero-class checkboxes, radios and ranges paint in the platform blue.
     wx-check and wx-radio already settle this per component; a Markdown task
     list or a raw form should not have to opt in. */
  :root { accent-color: var(--color-accent); }

  :focus-visible { outline-color: Highlight; }
    a { color: LinkText; text-decoration: underline; }
    .wx-btn, .wx-input, .wx-select, .wx-number, .wx-search input,
    .wx-upload, .wx-dropdown__item, .wx-pagination__link {
      border-color: ButtonText;
      color: ButtonText;
      background: Canvas;
    }
    .wx-btn--primary, .wx-btn--danger { forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight; }
    .wx-note, .wx-alert, .wx-modal, .wx-drawer, .wx-popover__panel { border-color: CanvasText; background: Canvas; color: CanvasText; }
  }
}
/* source: kit/base/motion.css */
/* Motion. The intensity level is a runtime switch, not a claim in a document:
   declare data-motion on <html> and the level is structurally enforced.

   E8  print stillness  — no animation, no transition, no hover/focus motion
   E9-0 still water     — necessary state feedback only, no entrance animation
   E9-1 spring rain     — light entrances, hover, theme switch  (default)
   E9-2 faint ripple    — one ceremonial focal animation

   See spec/soul/motion.md. */
@layer wx.base {
  @keyframes wx-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
  }
  @keyframes wx-fade-up {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
  }
  /* The only decorative loop the system permits, and only for the brand mark. */
  @keyframes wx-breathe {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.6; }
  }

  .wx-reveal {
    animation: wx-fade-up var(--duration-slow) var(--ease-out) both;
  }
  .wx-reveal[data-stagger="1"] { animation-delay: var(--stagger-1); }
  .wx-reveal[data-stagger="2"] { animation-delay: var(--stagger-2); }
  .wx-reveal[data-stagger="3"] { animation-delay: var(--stagger-3); }
  .wx-reveal[data-stagger="4"] { animation-delay: var(--stagger-4); }
  .wx-reveal[data-stagger="5"] { animation-delay: var(--stagger-5); }
  .wx-reveal[data-stagger="6"] { animation-delay: var(--stagger-6); }
  .wx-reveal[data-stagger="7"] { animation-delay: var(--stagger-7); }
  .wx-reveal[data-stagger="8"] { animation-delay: var(--stagger-8); }

  /* Scroll reveal. The hidden state is applied by reveal.js, never in markup —
     if the script fails to load, the content is simply visible, rather than
     permanently invisible. */
  [data-reveal-pending] { opacity: 0; }

  /* Still water: state feedback survives, entrances do not. */
  [data-motion="E9-0"] .wx-reveal { animation: none; }

  /* Print stillness. F4 cannot have motion even by accident. */
  [data-motion="E8"] *,
  [data-motion="E8"] *::before,
  [data-motion="E8"] *::after {
    animation: none !important;
    transition: none !important;
  }

  /* Reduced motion removes decoration, never information: state feedback and
     focus indication survive at near-zero duration (criterion A-3). */
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }
}
/* source: kit/base/layout.css */
/* Layout primitives. These must work in every form, including the ones with no
   viewport at all (print, poster, slides) — so nothing here depends on hover,
   scroll, or a browser chrome. */
@layer wx.base {
  .wx-page {
    background: var(--color-bg-warm);
    padding-inline: var(--padding-page-x);
  }

  .wx-container       { margin-inline: auto; max-width: var(--width-content); }
  .wx-container--article  { max-width: var(--width-article); }
  .wx-container--content  { max-width: var(--width-content); }
  .wx-container--showcase { max-width: var(--width-showcase); }

  /* Vertical rhythm as a primitive, so components never hand-roll margins. */
  .wx-stack > * + * { margin-block-start: var(--space-6); }
  .wx-stack--tight > * + * { margin-block-start: var(--space-3); }
  .wx-stack--loose > * + * { margin-block-start: var(--space-12); }

  /* The hairline rule. This is the system's primary structural device — it is
     what replaces the card. */
  .wx-rule {
    border: 0;
    border-top: var(--stroke-hairline) solid var(--color-border-subtle);
    margin: 0;
  }
  .wx-rule--strong { border-top-color: var(--color-border-strong); }
  .wx-rule--short  { width: 40px; }

  .wx-spread {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-4);
  }

  /* Intrinsic columns — auto-fit + minmax rather than fixed counts (M-7). */
  .wx-cols {
    display: grid;
    gap: var(--space-8);
    grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  }
  .wx-cols--2 { grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr)); }
  .wx-cols--3 { grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); }

  /* Optical line length. Latin wants 60–75 characters, CJK 30–40 (P-5). */
  .wx-measure { max-width: 68ch; }
  :lang(zh) .wx-measure { max-width: 36em; }

  /* Cluster — a wrapping row of related items with a shared gap. The
     horizontal counterpart of wx-stack; replaces ad-hoc margin on tags,
     buttons, and meta rows. */
  .wx-cluster {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
  }
  .wx-cluster--tight { gap: var(--space-2); }
  .wx-cluster--loose { gap: var(--space-6); }
}
/* source: kit/base/print.css */
/* Applies whenever anything is printed, not only in F4. A web page sent to a
   printer should still behave. F4 additionally sets data-motion="E8". */
@layer wx.base {
  @media print {
    :root {
      --color-bg-warm: #FFFFFF;
      --color-bg-base: #FFFFFF;
      --color-bg-pure: #FFFFFF;
      --color-text-primary: #000000;
      --color-text-heading: #000000;
    }

    body { background: #FFFFFF; }

    /* Never break a heading off from what it introduces. */
    h1, h2, h3, h4, h5, h6 { break-after: avoid-page; }
    p, blockquote, figure, table { break-inside: avoid; }

    /* Orphans and widows are a typographic minimum, not a nicety. */
    p { orphans: 3; widows: 3; }

    /* Reveal link targets that the reader cannot click. */
    a[href^="http"]::after {
      content: " (" attr(href) ")";
      font-size: var(--text-xs);
      color: var(--color-text-secondary);
      word-break: break-all;
    }

    .wx-nav, .wx-sidebar, .wx-toc, .wx-pager, .wx-skip { display: none; }
  }
}

/* source: kit/components/index.css */
/* All v1 components. Import after kit/base. */
/* source: kit/components/entry.css */
/* Entry 条目 — the sanctioned replacement for the card.
   No border box, no shadow, no fill. Grouping comes from spacing, and where
   spacing alone is not enough, from a single top rule.

   Whitespace *is* the grouping signal: the gestalt principle of proximity does
   the work a box would do, without adding a visual object to the page. A box
   outsources grouping to a border; spacing solves it directly. */
@layer wx.components {
  .wx-entry { display: block; }

  .wx-entry + .wx-entry { margin-block-start: var(--space-12); }

  .wx-entry--ruled + .wx-entry--ruled {
    margin-block-start: var(--space-8);
    padding-block-start: var(--space-8);
    border-top: var(--stroke-hairline) solid var(--color-border-subtle);
  }

  .wx-entry__title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    line-height: var(--leading-snug);
    color: var(--color-text-heading);
    margin-block-end: var(--space-2);
  }
  .wx-entry__title > a { color: inherit; }
  .wx-entry__title > a:hover { color: var(--color-accent); }

  .wx-entry__desc {
    color: var(--color-text-secondary);
    margin-block-end: var(--space-3);
  }

  .wx-entry__meta {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }
}
/* source: kit/components/content.css */
/* Editorial content components. This category has no equivalent in a product
   component library, and it is the one this system needs most. */
@layer wx.components {
  /* Eyebrow — the small uppercase line above a title. */
  .wx-eyebrow {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--color-text-secondary);
  }

  /* Lede — the opening paragraph, set larger than body. */
  .wx-lede {
    font-size: var(--text-lg);
    line-height: var(--leading-normal);
    color: var(--color-text-secondary);
  }

  /* Attribution block — the canonical short rule, name, then metadata. */
  .wx-attr { margin-block-start: var(--space-16); }
  .wx-attr::before {
    content: "";
    display: block;
    width: 40px;
    border-top: var(--stroke-hairline) solid var(--color-border-strong);
    margin-block-end: var(--space-4);
  }
  .wx-attr__name {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-primary);
  }
  .wx-attr__meta {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }

  /* Footnote reference and list. */
  .wx-fn {
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    vertical-align: super;
    line-height: 1;
    color: var(--color-accent);
    text-decoration: none;
    padding-inline: 0.15em;
  }
  .wx-fn-list {
    margin-block-start: var(--space-16);
    padding-block-start: var(--space-6);
    border-top: var(--stroke-hairline) solid var(--color-border-subtle);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
  }

  .wx-cite {
    font-style: normal;
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }

  /* Drop cap — the opening gesture of a long read. Applied to the first
     paragraph only, and suppressed on narrow canvases where a three-line
     cap would eat the measure. */
  .wx-dropcap::first-letter {
    float: inline-start;
    margin-inline-end: var(--space-2);
    padding-block-start: 0.08em;
    font-family: var(--font-display);
    font-size: 3.2em;
    line-height: 0.82;
    color: var(--color-text-heading);
  }
  @media (max-width: 30rem) {
    .wx-dropcap::first-letter { float: none; margin: 0; font-size: inherit; line-height: inherit; }
  }
}
/* source: kit/components/quote.css */
/* Two different things that both look like quotations, kept apart on purpose:
   a blockquote is someone else's words inside your argument; a pull quote is
   your own words, lifted out for rhythm. Conflating them is why so many pages
   have quotation marks that mean nothing. */
@layer wx.components {
  .wx-quote {
    padding-inline-start: var(--space-6);
    border-inline-start: var(--stroke-hairline) solid var(--color-border-strong);
    color: var(--color-text-secondary);
  }
  .wx-quote__attribution {
    display: block;
    margin-block-start: var(--space-3);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }

  /* Pull quote — a visual anchor, not a citation. No quotation marks, no rule;
     it earns attention through scale and surrounding whitespace alone. */
  .wx-pullquote {
    margin-block: var(--space-12);
    font-family: var(--font-display);
    font-size: var(--text-xl);
    line-height: var(--leading-snug);
    color: var(--color-text-heading);
    text-wrap: balance;
  }
  .wx-pullquote__label {
    display: block;
    margin-block-end: var(--space-3);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--color-text-functional);
  }
}
/* source: kit/components/table.css */
/* Horizontal rules only. No outer frame, no vertical lines, no zebra striping —
   the eye tracks a row perfectly well without them, and each added line is one
   more thing between the reader and the data. */
@layer wx.components {
  .wx-table {
    width: 100%;
    font-size: var(--text-sm);
    text-align: start;
  }
  .wx-table caption {
    caption-side: top;
    text-align: start;
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
    padding-block-end: var(--space-3);
  }
  .wx-table th {
    font-weight: 600;
    color: var(--color-text-heading);
    text-align: start;
    border-bottom: var(--stroke-hairline) solid var(--color-border-strong);
  }
  .wx-table td {
    border-bottom: var(--stroke-hairline) solid var(--color-border-subtle);
  }
  .wx-table th,
  .wx-table td {
    padding: var(--space-3);
    padding-inline-start: 0;
    vertical-align: baseline;
  }
  .wx-table td:last-child,
  .wx-table th:last-child { padding-inline-end: 0; }

  /* Numeric columns align on the decimal and use lining figures. */
  .wx-table__num {
    text-align: end;
    font-variant-numeric: tabular-nums;
  }

  /* Wide tables scroll inside their own container rather than pushing the page
     sideways. Use this wrapper only when a table may overflow, and mark that
     wrapper tabindex="0" role="region" with an accessible name so keyboard
     users can intentionally enter and scroll it. */
  .wx-table-scroll {
    overflow-x: auto;
    scrollbar-width: thin;
  }
}
/* source: kit/components/list.css */
@layer wx.components {
  .wx-list { list-style: none; padding: 0; margin: 0; }

  .wx-list--ruled > li + li {
    margin-block-start: var(--space-4);
    padding-block-start: var(--space-4);
    border-top: var(--stroke-hairline) solid var(--color-border-subtle);
  }

  /* Description list — used heavily in specs and brand pages. */
  .wx-desc { display: grid; gap: var(--space-3) var(--space-6); }
  @media (min-width: 640px) {
    .wx-desc { grid-template-columns: minmax(8rem, 14rem) 1fr; }
  }
  .wx-desc dt {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
  }
  .wx-desc dd { margin: 0; }

  /* Grouped surface — APPLICATION TRACK ONLY.
     An iOS grouped list is a genuine platform idiom, not a lapse. It is a
     bounded, declared exception: it uses a border, never a shadow, and any
     output using it must declare "f2-grouped-surface" in allowedDeviations.
     See spec/tracks.md and spec/DECISIONS.md D-4. */
  .wx-list--grouped {
    background: var(--color-bg-pure);
    border: var(--stroke-hairline) solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
  }
  .wx-list--grouped > li {
    margin: 0;
    padding: var(--space-4);
    min-height: var(--touch-target-min, 48px);
    display: flex;
    align-items: center;
  }
  .wx-list--grouped > li + li {
    border-top: var(--stroke-hairline) solid var(--color-border-subtle);
  }
}
/* source: kit/components/tag.css */
@layer wx.components {
  .wx-tag {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 2px var(--space-3);
    border: var(--stroke-hairline) solid var(--color-border-subtle);
    border-radius: var(--radius-sm);
    background: none;
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    letter-spacing: var(--tracking-wide);
    color: var(--color-text-secondary);
    text-decoration: none;
  }
  a.wx-tag:hover,
  button.wx-tag:hover {
    border-color: var(--color-accent);
    color: var(--color-accent);
  }

  /* Badge — a count, not a decoration. Numerals are tabular so a column of
     badges does not jitter. Never colour-only: the number is the meaning. */
  .wx-badge {
    display: inline-block;
    min-inline-size: var(--space-5);
    padding: 0 var(--space-2);
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-full);
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    line-height: var(--space-5);
    text-align: center;
    color: var(--color-text-functional);
  }
  .wx-badge--accent { border-color: var(--color-accent); color: var(--color-accent); }

  /* Status — a dot plus a word. The dot alone would breach the
     colour-is-not-information rule, so the label is part of the component
     rather than an option. */
  .wx-status {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
  }
  .wx-status::before {
    content: "";
    flex: none;
    inline-size: var(--space-2);
    block-size: var(--space-2);
    border-radius: var(--radius-full);
    background: currentColor;
    translate: 0 -0.1em;
  }
  .wx-status--live    { color: var(--color-success); }
  .wx-status--warn    { color: var(--color-warning); }
  .wx-status--down    { color: var(--color-danger); }
  .wx-status--idle    { color: var(--color-text-functional); }

  /* One tag on a page may carry the accent — the single item the reader is
     meant to notice. It spends one of the two accent occurrences the page
     is allowed, so a page full of accent tags is a page with no accent. */
  .wx-tag--accent {
    border-color: var(--color-accent);
    color: var(--color-accent);
  }
}
/* source: kit/components/stat.css */
/* A single number that carries an argument. Large serif figure, quiet label —
   the inverse of a dashboard tile, which shouts the label and shrinks the number. */
@layer wx.components {
  .wx-stat__value {
    display: block;
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    line-height: var(--leading-tight);
    color: var(--color-text-heading);
    font-variant-numeric: tabular-nums lining-nums;
  }
  .wx-stat__label {
    display: block;
    margin-block-start: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--color-text-secondary);
  }
  .wx-stat__note {
    display: block;
    margin-block-start: var(--space-1);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }
}
/* source: kit/components/figure.css */
@layer wx.components {
  .wx-figure { margin-block: var(--space-8); }
  .wx-figure img,
  .wx-figure svg { width: 100%; }
  .wx-figure__caption {
    margin-block-start: var(--space-3);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
  }
  /* Numbered figures — F9 requires every figure to be numbered and referenced. */
  .wx-figure__number {
    font-variant-numeric: tabular-nums;
    color: var(--color-text-functional);
    margin-inline-end: var(--space-2);
  }
}
/* source: kit/components/seal.css */
/* The brand mark. The single most cross-form component in the system —
   it appeared in six of the nine reference examples.

   Its breathing loop is the one decorative animation the system permits, and
   only at E9-2. Everywhere else it is static. */
@layer wx.components {
  .wx-seal {
    display: inline-block;
    inline-size: var(--brand-mark-size, 8px);
    block-size: var(--brand-mark-size, 8px);
    background: var(--brand-mark-color, var(--color-accent));
    vertical-align: baseline;
  }

  [data-motion="E9-2"] .wx-seal--breathing {
    animation: wx-breathe var(--duration-breath) var(--ease-in-out) infinite;
  }

  @media (max-width: 640px) {
    .wx-seal { inline-size: 6px; block-size: 6px; }
  }

  /* Header size. The mark scales with the brand name beside it, not with the
     body text, so the larger square is a variant rather than an em unit. */
  .wx-seal--lg { inline-size: 12px; block-size: 12px; }
}
/* source: kit/components/button.css */
/* Outline by default. --primary is reserved for one real data-entry submission
   or feedback closure; application-track task advance may use that one slot.
   Editorial navigation CTAs and ordinary jumps use --text. */
@layer wx.components {
  .wx-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-6);
    min-height: var(--touch-target-min, 24px);
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--color-text-primary);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    letter-spacing: var(--tracking-wide);
    text-decoration: none;
    cursor: pointer;
    transition: color var(--duration-fast) var(--ease-default),
                border-color var(--duration-fast) var(--ease-default);
  }
  .wx-btn:hover {
    color: var(--color-accent);
    border-color: var(--color-accent);
  }

  /* Filled only for a genuine submission or feedback closure, or for the
     single direct task-advance on an application page. D-type editorial
     landing navigation is checked by page audit; other pages follow track review. */
  .wx-btn--primary {
    background: var(--color-accent);
    border-color: var(--color-accent);
    color: var(--color-on-accent);
  }
  .wx-btn--primary:hover {
    background: var(--color-accent-hover);
    border-color: var(--color-accent-hover);
    color: var(--color-on-accent);
  }

  /* Text button — the preferred CTA. "Explore more ->" beats a box. */
  .wx-btn--text {
    padding-inline: 0;
    border-color: transparent;
    color: var(--color-text-primary);
  }
  .wx-btn--text:hover { border-color: transparent; color: var(--color-accent); }

  .wx-btn--danger { border-color: var(--color-danger); color: var(--color-danger); }
  .wx-btn--danger:hover {
    background: var(--color-danger);
    border-color: var(--color-danger);
    color: var(--color-on-accent);
  }

  .wx-btn[disabled] {
    color: var(--color-text-functional);
    border-color: var(--color-border-subtle);
    cursor: not-allowed;
  }
  .wx-btn--primary[disabled] {
    background: var(--color-border-subtle);
    color: var(--color-text-functional);
  }
}
/* source: kit/components/field.css */
/* Data entry follows mainstream convention in BOTH tracks — layer three of the
   arbitration rule. A form is a form: an error that does not look like an error
   is not restraint, it is a failure. */
@layer wx.components {
  .wx-input,
  .wx-select,
  textarea.wx-input {
    inline-size: 100%;
    padding: var(--space-3) var(--space-4);
    min-height: var(--touch-target-min, 24px);
    border: var(--stroke-hairline) solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    background: var(--color-bg-pure);
    color: var(--color-text-primary);
    font-family: var(--font-ui);
    font-size: var(--text-base);
    transition: border-color var(--duration-fast) var(--ease-default);
  }
  .wx-input::placeholder { color: var(--color-text-functional); }
  .wx-input:hover, .wx-select:hover { border-color: var(--color-border-strong); }
  textarea.wx-input { min-height: 6em; resize: vertical; }

  /* Native select only — a custom dropdown is a keyboard and screen-reader
     liability that this system has no reason to take on.

     The chevron is drawn with rotated borders on a wrapper rather than with a
     gradient: gradients are forbidden, and this way the mark inherits both
     currentColor and the 1.5px stroke token. */
  .wx-select-wrap { position: relative; display: block; }
  .wx-select { appearance: none; padding-inline-end: var(--space-10); }
  .wx-select-wrap::after {
    content: "";
    position: absolute;
    inset-inline-end: var(--space-4);
    inset-block-start: 50%;
    inline-size: 7px;
    block-size: 7px;
    border-inline-end: var(--stroke-mark) solid var(--color-text-secondary);
    border-block-end: var(--stroke-mark) solid var(--color-text-secondary);
    transform: translateY(-70%) rotate(45deg);
    pointer-events: none;
  }

  .wx-field { display: block; }
  .wx-field + .wx-field { margin-block-start: var(--space-6); }

  .wx-field__label {
    display: block;
    margin-block-end: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
  }
  /* Required is marked with a word, never with a color or a bare asterisk. */
  .wx-field__required {
    margin-inline-start: var(--space-2);
    color: var(--color-text-functional);
    font-size: var(--text-xs);
  }

  .wx-field__hint {
    display: block;
    margin-block-start: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }

  /* Error state carries colour AND text AND a border change — never colour
     alone, which would be invisible to a colour-blind reader. */
  .wx-field__error {
    display: block;
    margin-block-start: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-danger);
  }
  .wx-input[aria-invalid="true"],
  .wx-select[aria-invalid="true"] {
    border-color: var(--color-danger);
    border-width: var(--stroke-mark);
  }

  /* Checkbox and radio — 1.5px stroke box, accent only when checked. */
  .wx-check,
  .wx-radio {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    font-family: var(--font-ui);
    font-size: var(--text-base);
    cursor: pointer;
    min-height: var(--touch-target-min, 24px);
  }
  .wx-check input,
  .wx-radio input { inline-size: 1rem; block-size: 1rem; accent-color: var(--color-accent); }
}
/* source: kit/components/note.css */
/* Admonitions. Feedback follows convention in both tracks (arbitration layer
   three). A 2px accent rule on the leading edge plus a very pale wash — not a
   card, not an icon-in-a-rounded-box.

   Every level pairs its colour with a text label. The label is not decorative:
   it is what makes the level perceivable without colour vision. */
@layer wx.components {
  .wx-note {
    padding: var(--space-4) var(--space-5);
    border-inline-start: var(--stroke-mark) solid var(--color-border-strong);
    background: var(--color-bg-subtle);
  }
  .wx-note__title {
    display: block;
    margin-block-end: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--color-text-secondary);
  }
  .wx-note > :last-child { margin-block-end: 0; }

  .wx-note--info  { border-inline-start-color: var(--color-text-secondary); }
  .wx-note--info  .wx-note__title { color: var(--color-text-secondary); }

  .wx-note--tip     { border-inline-start-color: var(--color-success); background: var(--color-success-subtle); }
  .wx-note--tip     .wx-note__title { color: var(--color-success); }

  .wx-note--warn    { border-inline-start-color: var(--color-warning); background: var(--color-warning-subtle); }
  .wx-note--warn    .wx-note__title { color: var(--color-warning); }

  .wx-note--danger  { border-inline-start-color: var(--color-danger); background: var(--color-danger-subtle); }
  .wx-note--danger  .wx-note__title { color: var(--color-danger); }

  /* Alert — an inline message about the current action, not a document aside. */
  .wx-alert {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border: var(--stroke-hairline) solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-alert--danger  { border-color: var(--color-danger);  color: var(--color-danger); }
  .wx-alert--warn    { border-color: var(--color-warning); color: var(--color-warning); }
  .wx-alert--success { border-color: var(--color-success); color: var(--color-success); }

  /* Empty state — words and one ghost action. Deliberately no illustration. */
  .wx-empty {
    padding-block: var(--space-16);
    text-align: center;
    color: var(--color-text-secondary);
  }
  .wx-empty__title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    color: var(--color-text-heading);
    margin-block-end: var(--space-3);
  }
}
/* source: kit/components/nav.css */
@layer wx.components {
  .wx-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-6);
    min-height: var(--header-height, 64px);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-nav__brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-text-heading);
    text-decoration: none;
  }
  .wx-nav__list { display: flex; gap: var(--space-6); list-style: none; margin: 0; padding: 0; }
  .wx-nav__link {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--touch-target-min, 24px);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--color-text-secondary);
    text-decoration: none;
  }
  .wx-nav__link:hover { color: var(--color-text-primary); }
  /* Current page is marked in the accessibility tree first, and styled from it. */
  .wx-nav__link[aria-current] { color: var(--color-text-primary); }

  .wx-crumbs {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
  }
  .wx-crumbs ol { display: flex; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; }
  .wx-crumbs li::before { content: "/"; margin-inline: var(--space-2) var(--space-1); color: var(--color-text-functional); }
  .wx-crumbs a {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--touch-target-min, 24px);
    color: inherit;
    text-decoration: none;
  }
  .wx-crumbs a:hover { color: var(--color-accent); }
  .wx-crumbs [aria-current] { color: var(--color-text-primary); }

  .wx-pager {
    display: flex;
    justify-content: space-between;
    gap: var(--space-6);
    margin-block-start: var(--space-16);
    padding-block-start: var(--space-6);
    border-top: var(--stroke-hairline) solid var(--color-border-subtle);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-pager a { color: var(--color-text-secondary); text-decoration: none; }
  .wx-pager a:hover { color: var(--color-accent); }
  .wx-pager__label { display: block; font-size: var(--text-xs); color: var(--color-text-functional); }
}
/* source: kit/components/sidebar.css */
/* F6's defining component. On narrow screens a JS-wired sidebar becomes a
   drawer; without that script it remains a normal readable column. The open
   state lives on the element as a data attribute, never as a class, so the
   JS toggling it also has to set aria-expanded on the trigger. */
@layer wx.components {
  .wx-sidebar {
    inline-size: var(--sidebar-width, 240px);
    flex: 0 0 auto;
    padding-block: var(--space-6);
    padding-inline-end: var(--space-4);
    border-inline-end: var(--stroke-hairline) solid var(--color-border-subtle);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-sidebar__group + .wx-sidebar__group { margin-block-start: var(--space-6); }
  .wx-sidebar__heading {
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    font-size: var(--text-xs);
    color: var(--color-text-functional);
    margin-block-end: var(--space-2);
  }
  .wx-sidebar__list { list-style: none; margin: 0; padding: 0; }
  .wx-sidebar__link {
    display: block;
    padding-block: var(--space-2);
    padding-inline: var(--space-3) 0;
    border-inline-start: var(--stroke-mark) solid transparent;
    color: var(--color-text-secondary);
    text-decoration: none;
    transition: color var(--duration-fast) var(--ease-default);
  }
  .wx-sidebar__link:hover { color: var(--color-text-primary); }
  .wx-sidebar__link[aria-current] {
    color: var(--color-accent);
    border-inline-start-color: var(--color-accent);
  }

  @media (max-width: 1024px) {
    .wx-sidebar[data-wx-disclosure-ready] {
      --wx-sidebar-shift: -100%;
      position: fixed;
      inset-block: 0;
      inset-inline-start: 0;
      z-index: 20;
      inline-size: min(320px, 85vw);
      padding-inline: var(--space-5);
      background: var(--color-bg-base);
      transform: translateX(var(--wx-sidebar-shift));
      transition: transform var(--duration-slow) var(--ease-out);
      overflow-y: auto;
    }
    .wx-sidebar[data-wx-disclosure-ready]:dir(rtl) { --wx-sidebar-shift: 100%; }
    .wx-sidebar[data-wx-disclosure-ready][data-open] { transform: none; }
  }
}
/* source: kit/components/toc.css */
/* Table of contents with scroll spy. The active entry is marked with
   aria-current by the script; the styling follows from that, so the visual
   state and the accessibility tree cannot drift apart. */
@layer wx.components {
  .wx-toc {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-toc__heading {
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    font-size: var(--text-xs);
    color: var(--color-text-functional);
    margin-block-end: var(--space-3);
  }
  .wx-toc__list { list-style: none; margin: 0; padding: 0; }
  .wx-toc__list .wx-toc__list { padding-inline-start: var(--space-4); }
  .wx-toc__link {
    display: block;
    padding-block: var(--space-1);
    color: var(--color-text-functional);
    text-decoration: none;
  }
  .wx-toc__link:hover { color: var(--color-text-primary); }
  .wx-toc__link[aria-current] { color: var(--color-accent); }

  @media (min-width: 1280px) {
    .wx-toc--sticky { position: sticky; top: var(--space-8); }
  }
}
/* source: kit/components/code.css */
/* Code you authored — <pre class="wx-code">. Code a Markdown renderer emitted
   is styled by kit/markdown/, with descendant selectors, because you do not
   control its class attribute. Same look, different selector strategy;
   conflating the two is how a design system rots. */
@layer wx.components {
  code:not(pre code) {
    padding: 0.1em 0.35em;
    border-radius: var(--radius-sm);
    background: var(--color-bg-subtle);
    font-size: var(--text-code);
  }

  .wx-code {
    border: var(--stroke-hairline) solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    background: var(--code-bg);
    overflow: hidden;
  }
  .wx-code__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-2) var(--space-4);
    border-bottom: var(--stroke-hairline) solid var(--color-border-subtle);
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-text-functional);
  }
  .wx-code__copy {
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
    padding: var(--space-1) var(--space-2);
  }
  .wx-code__copy:hover { color: var(--color-accent); }
  .wx-code__body {
    margin: 0;
    padding: var(--space-4);
    overflow-x: auto;
    line-height: var(--leading-normal);
  }
  .wx-code__body code { background: none; padding: 0; }

  /* Keyboard key. Sized in em so it rides whatever text it sits in. */
  .wx-kbd {
    display: inline-block;
    padding: 0.1em 0.45em;
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-bg-subtle);
    font-family: var(--font-mono);
    font-size: var(--text-code);
    line-height: 1.4;
    color: var(--color-text-primary);
    white-space: nowrap;
  }
}
/* source: kit/components/timeline.css */
/* v2 · Timeline. Field-tested by note.zopiya.com: the rail gives a long feed
   continuity without enclosing entries in cards. No gradient fade caps. */
@layer wx.components {
  .wx-timeline {
    list-style: none;
    padding: 0;
    margin: 0;
  }

  .wx-timeline__item {
    display: grid;
    grid-template-columns: var(--space-5) minmax(0, 1fr);
    gap: var(--space-4);
    position: relative;
  }

  .wx-timeline__item::before {
    content: "";
    grid-column: 1;
    grid-row: 1;
    justify-self: center;
    inline-size: var(--stroke-hairline);
    block-size: 100%;
    background: var(--color-border-strong);
  }

  .wx-timeline__item:last-child::before { block-size: var(--space-2); }

  .wx-timeline__dot {
    position: absolute;
    inset-block-start: var(--space-1);
    inset-inline-start: calc((var(--space-5) - 9px) / 2);
    inline-size: 9px;
    block-size: 9px;
    border: var(--stroke-mark) solid var(--color-text-functional);
    border-radius: var(--radius-full);
    background: var(--color-bg-warm);
  }

  .wx-timeline__item[aria-current="true"] .wx-timeline__dot {
    border-color: var(--color-accent);
    background: var(--color-accent);
  }

  .wx-timeline__content {
    grid-column: 2;
    padding-block-end: var(--space-10);
    min-width: 0;
  }
}
/* source: kit/components/tabs.css */
/* v2 · Tabs. State is inseparable from the accessibility tree. */
@layer wx.components {
  .wx-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-6);
    border-block-end: var(--stroke-hairline) solid var(--color-border-subtle);
  }

  .wx-tabs [role="tab"] {
    min-block-size: 24px;
    padding-block: var(--space-2);
    color: var(--color-text-functional);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    border: 0;
    border-block-end: var(--stroke-mark) solid transparent;
    background: transparent;
    cursor: pointer;
  }

  .wx-tabs [role="tab"][aria-selected="true"] {
    color: var(--color-text-heading);
    border-block-end-color: var(--color-accent);
  }

  [role="tabpanel"][hidden] { display: none; }
}
/* source: kit/components/search.css */
/* v2 · Search. A semantic wrapper around the existing field/input primitives. */
@layer wx.components {
  .wx-search {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    border-block-end: var(--stroke-hairline) solid var(--color-border-strong);
  }

  .wx-search:focus-within { border-block-end-color: var(--color-accent); }

  /* Search is an input component too: an error keeps its semantic border even
     while focused, alongside the linked error text. */
  .wx-search:has(.wx-search__input[aria-invalid="true"]) {
    border-block-end-color: var(--color-danger);
    border-block-end-width: var(--stroke-mark);
  }

  .wx-search__input {
    flex: 1 1 auto;
    min-inline-size: 0;
    min-block-size: 44px;
    padding-block: var(--space-2);
    border: 0;
    background: transparent;
  }

  .wx-search__input:focus-visible { outline-offset: -2px; }
  .wx-search__status { color: var(--color-text-functional); font-size: var(--text-sm); }
}
/* source: kit/components/collapse.css */
/* v2 · Collapse. Native details/summary supplies keyboard and open state. */
@layer wx.components {
  .wx-collapse {
    border-block-start: var(--stroke-hairline) solid var(--color-border-subtle);
  }

  .wx-collapse > summary {
    min-block-size: 44px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    cursor: pointer;
    color: var(--color-text-heading);
  }

  .wx-collapse > summary::after { content: "+"; color: var(--color-text-functional); }
  .wx-collapse[open] > summary::after { content: "−"; }
  .wx-collapse__body { padding-block: 0 var(--space-6); }
}
/* source: kit/components/switch.css */
/* v2 · Switch [application track]. Use role=switch + aria-checked; never an
   .is-on class. The filled track is a control affordance, not a card surface. */
@layer wx.components {
  .wx-switch {
    --wx-switch-shift: var(--space-4);
    inline-size: 44px;
    block-size: 24px;
    padding: 2px;
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-full);
    background: transparent;
    cursor: pointer;
  }

  .wx-switch::before {
    content: "";
    display: block;
    inline-size: 18px;
    block-size: 18px;
    border-radius: var(--radius-full);
    background: var(--color-text-functional);
    transition: transform var(--duration-fast) var(--ease-out);
  }

  .wx-switch[aria-checked="true"] { border-color: var(--color-accent); }
  .wx-switch[aria-checked="true"]::before {
    background: var(--color-accent);
    transform: translateX(var(--wx-switch-shift));
  }
  .wx-switch:dir(rtl) { --wx-switch-shift: calc(-1 * var(--space-4)); }
}
/* source: kit/components/marginal.css */
/* v2 · Marginal note for the right rail used by documentation and reports. */
@layer wx.components {
  .wx-marginal {
    color: var(--color-text-functional);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    line-height: var(--leading-normal);
    border-inline-start: var(--stroke-hairline) solid var(--color-border-subtle);
    padding-inline-start: var(--space-4);
  }
}
/* source: kit/components/overlay.css */
/* Overlays — modal, drawer, toast.

   These are the one place the no-container rule genuinely bends, and the
   bend is principled rather than convenient (see DECISIONS D-21). An overlay
   that does not read as a separate surface is a usability failure, not a
   restrained one: the reader cannot tell what is dismissible and what is the
   page. Arbitration layer one (basic usability) and layer three (feedback
   follows convention) both point the same way.

   What we do NOT borrow from convention: no shadow, no gradient, no radius
   beyond --radius-md. Separation is carried by a hairline edge and a warm
   backdrop, which is the same vocabulary the rest of the system uses.

   All three use native <dialog>/aria-live so focus handling, Esc, and
   announcement come from the platform rather than from us. */
@layer wx.components {

  /* ---- Modal --------------------------------------------------------- */
  .wx-modal {
    inline-size: min(32rem, calc(100vw - var(--space-8)));
    padding: var(--space-8);
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-bg-pure);
    color: var(--color-text-primary);
  }
  .wx-modal::backdrop {
    /* Warm, not neutral black — the vellum dimmed, same as dark mode. */
    background: var(--color-scrim);
  }
  .wx-modal__title {
    margin-block: 0 var(--space-3);
    font-family: var(--font-display);
    font-size: var(--text-xl);
    color: var(--color-text-heading);
  }
  .wx-modal__body > :last-child { margin-block-end: 0; }
  .wx-modal__actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
    margin-block-start: var(--space-6);
  }

  /* ---- Drawer -------------------------------------------------------- */
  .wx-drawer {
    --wx-drawer-shift: var(--space-4);
    inline-size: min(22rem, calc(100vw - var(--space-12)));
    max-inline-size: none;
    block-size: 100%;
    max-block-size: none;
    margin-block: 0;
    margin-inline: auto 0;           /* anchored to the inline end */
    padding: var(--space-6);
    border: 0;
    border-inline-start: var(--stroke-hairline) solid var(--color-border-strong);
    background: var(--color-bg-base);
    color: var(--color-text-primary);
  }
  .wx-drawer:dir(rtl) { --wx-drawer-shift: calc(-1 * var(--space-4)); }
  .wx-drawer::backdrop { background: var(--color-scrim); }
  .wx-drawer__header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-4);
    margin-block-end: var(--space-6);
    padding-block-end: var(--space-3);
    border-block-end: var(--stroke-hairline) solid var(--color-border-subtle);
  }

  /* ---- Toast --------------------------------------------------------- */
  /* overlay.js creates the region before the first message; toasts are
     appended into it. An empty region costs nothing and gives aria-live
     somewhere stable to observe. */
  .wx-toast__region {
    position: fixed;
    inset-block-end: var(--space-6);
    inset-inline: var(--space-6);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    pointer-events: none;
    z-index: 50;
  }
  .wx-toast {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    max-inline-size: 30rem;
    padding: var(--space-3) var(--space-5);
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-bg-pure);
    color: var(--color-text-primary);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    pointer-events: auto;
  }
  /* Semantic level is carried by the leading rule AND the label inside —
     never by the colour alone. */
  .wx-toast__label {
    flex: none;
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--color-text-functional);
  }
  .wx-toast--success { border-inline-start: var(--stroke-mark) solid var(--color-success); }
  .wx-toast--success .wx-toast__label { color: var(--color-success); }
  .wx-toast--warn    { border-inline-start: var(--stroke-mark) solid var(--color-warning); }
  .wx-toast--warn    .wx-toast__label { color: var(--color-warning); }
  .wx-toast--danger  { border-inline-start: var(--stroke-mark) solid var(--color-danger); }
  .wx-toast--danger  .wx-toast__label { color: var(--color-danger); }

  /* ---- Entrance ------------------------------------------------------ */
  @media (prefers-reduced-motion: no-preference) {
    .wx-modal[open],
    .wx-toast { animation: wx-overlay-rise var(--duration-base) var(--ease-out) both; }
    .wx-drawer[open] { animation: wx-drawer-in var(--duration-base) var(--ease-out) both; }
  }
  @keyframes wx-overlay-rise {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
  }
  @keyframes wx-drawer-in {
    from { opacity: 0; transform: translateX(var(--wx-drawer-shift)); }
    to   { opacity: 1; transform: none; }
  }
}
/* source: kit/components/progress.css */
/* Progress and meter — quantity as ink, never as a spinning ornament.

   The system forbids spinners, so there is no indeterminate variant here.
   A <progress> with no value renders as a plain rule and the surrounding
   text is expected to say what is happening ("正在导出…"). That is a
   deliberate constraint: an indeterminate bar communicates nothing a
   sentence cannot, and it moves forever, which the motion spec forbids.

   The bare elements are matched alongside the classes. <progress> and <meter>
   paint themselves in the platform accent — a blue and a green belonging to no
   palette here — and correcting that needs the vendor pseudo-elements. Putting
   the bare selectors in base/ would mean a second copy of that knowledge, so
   the one file that knows ::-webkit-progress-value owns both. */
@layer wx.components {
  progress,
  .wx-progress,
  meter,
  .wx-meter {
    inline-size: 100%;
    block-size: var(--stroke-mark);
    appearance: none;
    border: 0;
    background: var(--color-border-subtle);
  }

  /* Firefox */
  progress,
  .wx-progress { color: var(--color-text-primary); }
  progress::-moz-progress-bar,
  .wx-progress::-moz-progress-bar { background: var(--color-text-primary); }
  meter::-moz-meter-bar,
  .wx-meter::-moz-meter-bar { background: var(--color-text-primary); }

  /* WebKit / Blink */
  progress::-webkit-progress-bar,
  .wx-progress::-webkit-progress-bar { background: var(--color-border-subtle); }
  progress::-webkit-progress-value,
  .wx-progress::-webkit-progress-value { background: var(--color-text-primary); }
  meter::-webkit-meter-bar,
  .wx-meter::-webkit-meter-bar {
    background: var(--color-border-subtle);
    border: 0;
  }
  meter::-webkit-meter-optimum-value,
  .wx-meter::-webkit-meter-optimum-value { background: var(--color-text-primary); }
  meter::-webkit-meter-suboptimum-value,
  .wx-meter::-webkit-meter-suboptimum-value { background: var(--color-warning); }
  meter::-webkit-meter-even-less-good-value,
  .wx-meter::-webkit-meter-even-less-good-value { background: var(--color-danger); }

  /* Indeterminate: hold still and say so in words. */
  progress:not([value]),
  .wx-progress:not([value]) { background: var(--color-border-subtle); }
  progress:not([value])::-webkit-progress-value,
  .wx-progress:not([value])::-webkit-progress-value { background: transparent; }

  /* The label row is the component — the bar alone is not accessible output. */
  .wx-progress-field { display: block; }
  .wx-progress-field__row {
    display: flex;
    justify-content: space-between;
    gap: var(--space-4);
    margin-block-end: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }
  .wx-progress-field__value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--color-text-primary);
  }
}
/* source: kit/components/steps.css */
/* Steps — a numbered sequence with position. Current step is marked with
   aria-current="step"; completed steps carry [data-complete]. Neither state
   is expressed by colour alone: the current step also gains weight and the
   accent rule, and completed steps are struck by a filled marker. */
@layer wx.components {
  .wx-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    counter-reset: wx-step;
  }
  .wx-steps__item {
    position: relative;
    padding-inline-start: var(--space-8);
    padding-block-end: var(--space-6);
    counter-increment: wx-step;
    color: var(--color-text-functional);
  }
  .wx-steps__item:last-child { padding-block-end: 0; }

  /* The connecting rail — one hairline, drawn between markers. */
  .wx-steps__item:not(:last-child)::before {
    content: "";
    position: absolute;
    inset-block: var(--space-6) 0;
    inset-inline-start: calc(var(--space-3) - (var(--stroke-hairline) / 2));
    border-inline-start: var(--stroke-hairline) solid var(--color-border-subtle);
  }
  .wx-steps__item::after {
    content: counter(wx-step);
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 0;
    inline-size: var(--space-6);
    block-size: var(--space-6);
    display: grid;
    place-items: center;
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-full);
    background: var(--color-bg-warm);
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    color: var(--color-text-functional);
  }
  .wx-steps__title {
    display: block;
    font-family: var(--font-ui);
    font-size: var(--text-base);
    color: var(--color-text-secondary);
  }

  .wx-steps__item[aria-current="step"] { color: var(--color-text-primary); }
  .wx-steps__item[aria-current="step"]::after {
    border-color: var(--color-accent);
    border-width: var(--stroke-mark);
    color: var(--color-accent);
  }
  .wx-steps__item[aria-current="step"] .wx-steps__title {
    color: var(--color-text-heading);
    font-weight: 600;
  }

  .wx-steps__item[data-complete]::after {
    content: "✓";
    border-color: var(--color-text-secondary);
    color: var(--color-text-secondary);
  }

  /* Horizontal variant for application-track wizards. */
  .wx-steps--row { display: flex; gap: var(--space-8); }
  .wx-steps--row .wx-steps__item { padding-block-end: 0; flex: 1; }
  .wx-steps--row .wx-steps__item:not(:last-child)::before {
    inset: var(--space-3) auto auto calc(var(--space-6) + var(--space-2));
    inline-size: calc(100% - var(--space-8));
    block-size: 0;
    border-inline-start: 0;
    border-block-start: var(--stroke-hairline) solid var(--color-border-subtle);
  }
}
/* source: kit/components/avatar.css */
/* Avatar — an image frame, not a coloured identity bubble.

   Mainstream avatars default to a saturated circle with white initials.
   That is a filled shape carrying a decorative hue, which this system does
   not have. Here the default is a square hairline frame in the seal
   tradition, initials set in the display face. The circular variant exists
   for photographs, where the crop is the point. */
@layer wx.components {
  .wx-avatar {
    --wx-avatar-size: var(--space-10);
    display: inline-grid;
    place-items: center;
    inline-size: var(--wx-avatar-size);
    block-size: var(--wx-avatar-size);
    overflow: hidden;
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-bg-subtle);
    font-family: var(--font-display);
    font-size: var(--text-sm);
    line-height: 1;
    color: var(--color-text-secondary);
    text-transform: uppercase;
    user-select: none;
  }
  .wx-avatar > img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
  }
  .wx-avatar--sm    { --wx-avatar-size: var(--space-6); font-size: var(--text-xs); }
  .wx-avatar--lg    { --wx-avatar-size: var(--space-16); font-size: var(--text-lg); }
  .wx-avatar--round { border-radius: var(--radius-full); }

  /* A stack of collaborators. Overlap is bounded so the hairlines stay
     legible rather than collapsing into a smear. */
  .wx-avatar-group { display: flex; }
  .wx-avatar-group .wx-avatar + .wx-avatar { margin-inline-start: calc(var(--space-2) * -1); }
}
/* source: kit/components/tooltip.css */
/* Tooltip — supplementary only.

   Hard rule: a tooltip may never be the sole carrier of information. It is
   unreachable on touch, invisible to print, and easy to miss. Anything a
   reader must know belongs in the text. This component exists for the
   legitimate remainder: expanding an abbreviation, naming an icon.

   Markup contract — the trigger references the bubble, so assistive tech
   announces it without depending on hover:

     <span class="wx-tooltip">
       <button aria-describedby="tt-1">…</button>
       <span class="wx-tooltip__bubble" role="tooltip" id="tt-1">…</span>
     </span> */
@layer wx.components {
  .wx-tooltip { position: relative; display: inline-flex; }
  .wx-tooltip__bubble {
    position: absolute;
    inset-block-end: calc(100% + var(--space-2));
    inset-inline-start: 50%;
    translate: -50% 0;
    z-index: 40;
    inline-size: max-content;
    max-inline-size: 18rem;
    padding: var(--space-2) var(--space-3);
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-bg-pure);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    line-height: var(--leading-snug);
    color: var(--color-text-primary);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--duration-fast) var(--ease-out),
                visibility var(--duration-fast) var(--ease-out);
  }
  /* Focus-visible, not focus: a mouse click on the trigger should not
     leave a bubble hanging. */
  .wx-tooltip:hover .wx-tooltip__bubble,
  .wx-tooltip:focus-within .wx-tooltip__bubble {
    opacity: 1;
    visibility: visible;
  }
  .wx-tooltip__bubble--end {
    inset-block-end: auto;
    inset-block-start: calc(100% + var(--space-2));
  }
}
/* source: kit/components/control.css */
/* Segmented control and toolbar — application-track grouping.

   Both are data-entry / command surfaces, so arbitration layer three applies:
   they follow convention. The concession is a grouped outline, not a filled
   pill; the selected segment is marked by an inverted ink weight and
   aria-checked, so it survives greyscale and screen readers alike. */
@layer wx.components {
  .wx-segmented {
    display: inline-flex;
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    overflow: hidden;
  }
  .wx-segmented__option {
    min-block-size: var(--space-6);
    padding: var(--space-2) var(--space-4);
    border: 0;
    background: transparent;
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
    cursor: pointer;
  }
  .wx-segmented__option + .wx-segmented__option {
    border-inline-start: var(--stroke-hairline) solid var(--color-border-strong);
  }
  .wx-segmented__option[aria-checked="true"],
  .wx-segmented__option[aria-selected="true"] {
    background: var(--color-bg-subtle);
    color: var(--color-text-heading);
    font-weight: 600;
  }

  /* Toolbar — a row of commands separated from the content it acts on by a
     single rule. role="toolbar" gives arrow-key navigation for free. */
  .wx-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    padding-block-end: var(--space-3);
    border-block-end: var(--stroke-hairline) solid var(--color-border-subtle);
  }
  .wx-toolbar__group { display: flex; align-items: center; gap: var(--space-2); }
  .wx-toolbar__spacer { flex: 1; }
}
/* source: kit/components/menu.css */
/* Menu, dropdown, and anchor — the navigation family.

   All three express current/open state through ARIA, never a class. The
   dropdown is a native <details>, so it opens without JavaScript and closes
   with Esc for free. */
@layer wx.components {

  /* ---- Menu — a vertical list of destinations ------------------------ */
  .wx-menu {
    list-style: none;
    margin: 0;
    padding: 0;
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-menu__group {
    margin-block-start: var(--space-6);
    padding-block-end: var(--space-2);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--color-text-functional);
  }
  .wx-menu__group:first-child { margin-block-start: 0; }
  .wx-menu__link {
    display: block;
    padding: var(--space-2) var(--space-3);
    border-inline-start: var(--stroke-mark) solid transparent;
    color: var(--color-text-secondary);
    text-decoration: none;
  }
  .wx-menu__link:hover { color: var(--color-text-primary); }
  .wx-menu__link[aria-current] {
    border-inline-start-color: var(--color-accent);
    color: var(--color-text-heading);
    font-weight: 600;
  }
  .wx-menu__link[aria-disabled="true"] {
    color: var(--color-text-functional);
    pointer-events: none;
  }
  /* Nested level — indented by the rail, not by a new container. */
  .wx-menu .wx-menu { margin-inline-start: var(--space-4); }

  /* ---- Dropdown — native <details>, zero JS -------------------------- */
  .wx-dropdown { position: relative; display: inline-block; }
  .wx-dropdown > summary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-primary);
    cursor: pointer;
    list-style: none;
  }
  .wx-dropdown > summary::-webkit-details-marker { display: none; }
  .wx-dropdown > summary::after {
    content: "";
    inline-size: 0.4em;
    block-size: 0.4em;
    border-inline-end: var(--stroke-hairline) solid currentColor;
    border-block-end: var(--stroke-hairline) solid currentColor;
    rotate: 45deg;
    translate: 0 -0.15em;
  }
  .wx-dropdown[open] > summary { border-color: var(--color-text-primary); }
  .wx-dropdown__menu {
    position: absolute;
    inset-block-start: calc(100% + var(--space-1));
    inset-inline-start: 0;
    z-index: 30;
    min-inline-size: 12rem;
    padding: var(--space-2) 0;
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--color-bg-pure);
    list-style: none;
    margin: 0;
  }
  .wx-dropdown__item {
    display: block;
    inline-size: 100%;
    padding: var(--space-2) var(--space-4);
    border: 0;
    background: transparent;
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-align: start;
    color: var(--color-text-primary);
    text-decoration: none;
    cursor: pointer;
  }
  .wx-dropdown__item:hover { background: var(--color-bg-subtle); }
  .wx-dropdown__item--danger { color: var(--color-danger); }
  .wx-dropdown__sep {
    margin: var(--space-2) 0;
    border: 0;
    border-block-start: var(--stroke-hairline) solid var(--color-border-subtle);
  }

  /* ---- Anchor — in-page navigation ----------------------------------- */
  .wx-anchor { font-family: var(--font-ui); font-size: var(--text-sm); }
  .wx-anchor__list { list-style: none; margin: 0; padding: 0; border-inline-start: var(--stroke-hairline) solid var(--color-border-subtle); }
  .wx-anchor__link {
    display: block;
    padding: var(--space-1) var(--space-3);
    margin-inline-start: calc(var(--stroke-hairline) * -1);
    border-inline-start: var(--stroke-mark) solid transparent;
    color: var(--color-text-functional);
    text-decoration: none;
  }
  .wx-anchor__link:hover { color: var(--color-text-primary); }
  .wx-anchor__link[aria-current] {
    border-inline-start-color: var(--color-accent);
    color: var(--color-text-heading);
  }
  .wx-anchor__list .wx-anchor__list { border: 0; }
  .wx-anchor__list .wx-anchor__link { padding-inline-start: var(--space-6); }

  /* ---- Affix — sticky without a container ---------------------------- */
  .wx-affix { position: sticky; inset-block-start: var(--space-6); }
}
/* source: kit/components/pagination.css */
/* Pagination — numbered page navigation.

   A <nav> of links, current marked with aria-current="page". The current
   page is not a filled chip: it is heavier ink plus an underline rule, so
   it survives greyscale and does not spend the accent budget. */
@layer wx.components {
  .wx-pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-pagination__list {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    list-style: none;
    margin: 0;
    padding: 0;
  }
  .wx-pagination__link {
    display: grid;
    place-items: center;
    min-inline-size: var(--space-8);
    min-block-size: var(--space-8);
    padding-inline: var(--space-2);
    border-block-end: var(--stroke-mark) solid transparent;
    color: var(--color-text-secondary);
    text-decoration: none;
    font-variant-numeric: tabular-nums;
  }
  .wx-pagination__link:hover { color: var(--color-text-primary); }
  .wx-pagination__link[aria-current="page"] {
    border-block-end-color: var(--color-text-primary);
    color: var(--color-text-heading);
    font-weight: 600;
  }
  .wx-pagination__link[aria-disabled="true"] {
    color: var(--color-text-functional);
    pointer-events: none;
  }
  .wx-pagination__ellipsis {
    min-inline-size: var(--space-6);
    text-align: center;
    color: var(--color-text-functional);
  }
  .wx-pagination__total {
    margin-inline-start: var(--space-4);
    color: var(--color-text-functional);
    font-variant-numeric: tabular-nums;
  }
}
/* source: kit/components/form.css */
/* Form layout — the structure around the fields.

   Three layouts, all built on the same wx-field: stacked (default),
   horizontal (label beside control), and inline (filters, search bars).
   Data entry follows convention in both tracks; what stays ours is the
   absence of boxes — sections are separated by a rule and whitespace. */
@layer wx.components {
  .wx-form { --wx-label-width: 8rem; }

  /* A titled group of related fields. <fieldset> for the semantics,
     stripped of the browser's default box — the legend and rule do the
     grouping, exactly as wx-entry does for content. */
  .wx-form__section {
    margin: 0;
    padding: 0;
    border: 0;
  }
  .wx-form__section + .wx-form__section { margin-block-start: var(--space-12); }
  .wx-form__legend {
    display: block;
    inline-size: 100%;
    padding: 0 0 var(--space-3);
    margin-block-end: var(--space-6);
    border-block-end: var(--stroke-hairline) solid var(--color-border-subtle);
    font-family: var(--font-display);
    font-size: var(--text-lg);
    color: var(--color-text-heading);
  }
  .wx-form__legend-hint {
    display: block;
    margin-block-start: var(--space-1);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    font-weight: 400;
    color: var(--color-text-functional);
  }

  /* Horizontal — label in a fixed column. Collapses to stacked on narrow
     canvases, because a 8rem label column and a 20rem viewport cannot both
     be honoured. */
  .wx-form--horizontal .wx-field {
    display: grid;
    grid-template-columns: var(--wx-label-width) minmax(0, 1fr);
    gap: var(--space-4);
    align-items: baseline;
  }
  .wx-form--horizontal .wx-field__label {
    margin-block-end: 0;
    text-align: end;
  }
  .wx-form--horizontal .wx-field__hint,
  .wx-form--horizontal .wx-field__error { grid-column: 2; }
  @media (max-width: 40rem) {
    .wx-form--horizontal .wx-field { grid-template-columns: minmax(0, 1fr); }
    .wx-form--horizontal .wx-field__label { text-align: start; margin-block-end: var(--space-2); }
    .wx-form--horizontal .wx-field__hint,
    .wx-form--horizontal .wx-field__error { grid-column: 1; }
  }

  /* Inline — filters and search rows. */
  .wx-form--inline {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--space-4);
  }
  .wx-form--inline .wx-field { margin-block-start: 0; flex: 1 1 12rem; }

  /* Two fields on one row (first name / last name). */
  .wx-form__row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: var(--space-4) var(--space-6);
  }
  .wx-form__row .wx-field + .wx-field { margin-block-start: 0; }

  /* Actions — separated by a rule, primary action last in reading order.
     At most one filled button per view (forbidden.md §three). */
  .wx-form__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-block-start: var(--space-10);
    padding-block-start: var(--space-6);
    border-block-start: var(--stroke-hairline) solid var(--color-border-subtle);
  }
  .wx-form__actions--end { justify-content: flex-end; }
  .wx-form__actions-note {
    flex: 1;
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }

  /* A summary of everything that failed, placed above the form and focused
     on submit. Long forms need this: an inline error 40 rows down is an
     error nobody finds. */
  .wx-form__errors {
    padding: var(--space-4) var(--space-5);
    margin-block-end: var(--space-8);
    border-inline-start: var(--stroke-mark) solid var(--color-danger);
    background: var(--color-danger-subtle);
  }
  .wx-form__errors-title {
    display: block;
    margin-block-end: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--color-danger);
  }
  .wx-form__errors ol { margin: 0; padding-inline-start: var(--space-5); font-size: var(--text-sm); }
}
/* source: kit/components/range.css */
/* Range-based controls — slider, number, and rate.

   These were previously excluded on SCOPE grounds ("tool scenarios are out
   of applicability"), not on philosophy grounds. With the scope widened to a
   full component library they come in unchanged in principle: ink, hairlines,
   no gradient fill on the track. */
@layer wx.components {

  /* ---- Slider -------------------------------------------------------- */
  /* The track is a single rule; the filled portion is NOT a gradient (those
     are forbidden) — it is a second element sized by the consumer, or simply
     omitted. A bare track plus a visible thumb reads fine and stays honest. */
  .wx-slider {
    inline-size: 100%;
    appearance: none;
    background: transparent;
    cursor: pointer;
  }
  .wx-slider::-webkit-slider-runnable-track {
    block-size: var(--stroke-mark);
    background: var(--color-border-strong);
  }
  .wx-slider::-moz-range-track {
    block-size: var(--stroke-mark);
    background: var(--color-border-strong);
  }
  .wx-slider::-moz-range-progress {
    block-size: var(--stroke-mark);
    background: var(--color-text-primary);
  }
  .wx-slider::-webkit-slider-thumb {
    appearance: none;
    inline-size: var(--space-4);
    block-size: var(--space-4);
    margin-block-start: calc((var(--space-4) - var(--stroke-mark)) / -2);
    border: var(--stroke-mark) solid var(--color-text-primary);
    border-radius: var(--radius-full);
    background: var(--color-bg-pure);
  }
  .wx-slider::-moz-range-thumb {
    inline-size: var(--space-4);
    block-size: var(--space-4);
    border: var(--stroke-mark) solid var(--color-text-primary);
    border-radius: var(--radius-full);
    background: var(--color-bg-pure);
  }
  /* The value must be readable as a number, not inferred from thumb
     position — position alone is not an accessible readout. */
  .wx-slider-field__row {
    display: flex;
    justify-content: space-between;
    gap: var(--space-4);
    margin-block-end: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }
  .wx-slider-field__value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--color-text-primary);
  }
  .wx-slider-field__scale {
    display: flex;
    justify-content: space-between;
    margin-block-start: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    color: var(--color-text-functional);
  }

  /* ---- Number input -------------------------------------------------- */
  /* Native spinners are kept: they are keyboard-reachable and localised.
     Numerals are tabular so a column of them aligns. */
  .wx-number {
    inline-size: 100%;
    max-inline-size: 12rem;
    padding: var(--space-3) var(--space-4);
    min-block-size: var(--touch-target-min, 24px);
    border: var(--stroke-hairline) solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    background: var(--color-bg-pure);
    font-family: var(--font-mono);
    font-size: var(--text-base);
    font-variant-numeric: tabular-nums;
    color: var(--color-text-primary);
  }
  .wx-number:hover { border-color: var(--color-border-strong); }
  .wx-number[aria-invalid="true"] {
    border-color: var(--color-danger);
    border-width: var(--stroke-mark);
  }

  /* ---- Rate ---------------------------------------------------------- */
  /* Marks, not icons. The ban on filled icons governs icon sets; a rating
     mark is a data mark, the same way a chart bar is. Using the ■ seal
     idiom keeps it in the system's own vocabulary, and filled-vs-hairline
     survives greyscale — the state is never carried by colour alone.

     Implemented as radio inputs in reverse DOM order so the CSS sibling
     selector can fill everything up to the checked one. */
  .wx-rate {
    /* The mark remains a compact 16px data mark. Its label owns the actual
       pointer target, so F2 can raise that target to 48px without turning a
       five-point rating into five oversized blocks. */
    --wx-rate-hit-size: var(--touch-target-min, 24px);
    display: inline-flex;
    flex-direction: row-reverse;
    justify-content: flex-end;
    /* 24px hit boxes keep the old 24px centre-to-centre rhythm: a 16px mark
       plus the original 8px gap. */
    gap: 0;
  }
  .wx-rate input {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }
  .wx-rate label {
    position: relative;
    display: grid;
    place-items: center;
    inline-size: var(--wx-rate-hit-size);
    block-size: var(--wx-rate-hit-size);
    cursor: pointer;
  }
  .wx-rate label::before {
    content: "";
    inline-size: var(--space-4);
    block-size: var(--space-4);
    border: var(--stroke-mark) solid var(--color-border-strong);
  }
  .wx-rate input:checked ~ label::before,
  .wx-rate label:hover::before,
  .wx-rate label:hover ~ label::before {
    border-color: var(--color-accent);
    background: var(--color-accent);
  }
  .wx-rate input:focus-visible + label {
    outline: var(--stroke-mark) solid var(--color-focus);
    outline-offset: 2px;
  }
}
/* source: kit/components/upload.css */
/* Upload — file input and drop zone.

   The drop zone is a four-sided dashed rectangle, which the card ban would
   normally forbid. It is allowed here for the same reason overlays are
   (DECISIONS D-21, D-23): the boundary is not decoration, it IS the
   information — it shows the reader where the droppable region ends. A drop
   target whose edge you cannot see is a usability failure. Arbitration
   layers one and three both apply.

   The concession is bounded: dashed hairline, no fill, no shadow, no radius
   beyond --radius-md. It stays a drop target and does not become a card. */
@layer wx.components {
  .wx-upload {
    display: block;
    padding: var(--space-10) var(--space-6);
    border: var(--stroke-hairline) dashed var(--color-border-strong);
    border-radius: var(--radius-md);
    background: transparent;
    text-align: center;
    font-family: var(--font-ui);
    cursor: pointer;
  }
  .wx-upload:hover,
  .wx-upload:focus-within { border-color: var(--color-text-secondary); }
  .wx-upload[data-dragover] {
    border-color: var(--color-accent);
    border-style: solid;
  }
  .wx-upload__prompt {
    display: block;
    font-size: var(--text-base);
    color: var(--color-text-primary);
  }
  .wx-upload__hint {
    display: block;
    margin-block-start: var(--space-2);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }
  /* The native input stays reachable — visually hidden, not display:none,
     so it keeps its place in the tab order. */
  .wx-upload input[type="file"] {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  /* The list of chosen files — a ruled list, not a grid of tiles. */
  .wx-upload-list {
    list-style: none;
    margin: var(--space-4) 0 0;
    padding: 0;
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-upload-list__item {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    padding-block: var(--space-3);
    border-block-start: var(--stroke-hairline) solid var(--color-border-subtle);
  }
  .wx-upload-list__name { flex: 1; color: var(--color-text-primary); }
  .wx-upload-list__size {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--color-text-functional);
  }
}
/* source: kit/components/tree.css */
/* Tree — nested disclosure, built from <ul> and <details>.

   No JavaScript and no custom roles: a nested list of <details> is already
   keyboard-navigable and announced correctly. The connecting rail is drawn
   with a border on the list, so depth is legible without indent guides
   becoming visual noise. */
@layer wx.components {
  .wx-tree,
  .wx-tree ul {
    list-style: none;
    margin: 0;
    padding: 0;
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-tree ul {
    margin-inline-start: var(--space-3);
    padding-inline-start: var(--space-3);
    border-inline-start: var(--stroke-hairline) solid var(--color-border-subtle);
  }
  .wx-tree li { padding-block: 1px; }

  .wx-tree summary {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    color: var(--color-text-secondary);
    cursor: pointer;
    list-style: none;
  }
  .wx-tree summary::-webkit-details-marker { display: none; }
  .wx-tree summary::before {
    content: "";
    flex: none;
    inline-size: 0.4em;
    block-size: 0.4em;
    border-inline-end: var(--stroke-hairline) solid currentColor;
    border-block-end: var(--stroke-hairline) solid currentColor;
    rotate: -45deg;
    transition: rotate var(--duration-fast) var(--ease-out);
  }
  .wx-tree details[open] > summary::before { rotate: 45deg; }
  .wx-tree summary:hover { color: var(--color-text-primary); }

  .wx-tree__leaf {
    display: block;
    padding: var(--space-1) var(--space-2);
    /* aligned with the summary text, past where its marker sits */
    padding-inline-start: calc(var(--space-2) + 0.4em + var(--space-2));
    color: var(--color-text-secondary);
    text-decoration: none;
  }
  .wx-tree__leaf:hover { color: var(--color-text-primary); }
  .wx-tree__leaf[aria-current] {
    color: var(--color-text-heading);
    font-weight: 600;
  }
}
/* source: kit/components/result.css */
/* Result — the whole-page outcome state: success, failure, 404, 403.

   Ant Design puts an illustration here. This system does not: the mark, a
   heading, one sentence, and at most two actions. Same reasoning as
   wx-empty — an illustration is decorative imagery, which is forbidden, and
   it delays the sentence that actually tells the reader what happened. */
@layer wx.components {
  .wx-result {
    max-inline-size: var(--width-article);
    margin-inline: auto;
    padding-block: var(--space-24);
    text-align: center;
  }
  .wx-result__mark {
    display: block;
    margin-block-end: var(--space-6);
    font-family: var(--font-mono);
    font-size: var(--text-3xl);
    line-height: 1;
    color: var(--color-text-functional);
  }
  .wx-result__title {
    margin-block: 0 var(--space-3);
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    color: var(--color-text-heading);
  }
  .wx-result__body {
    margin-block: 0;
    color: var(--color-text-secondary);
  }
  .wx-result__actions {
    display: flex;
    justify-content: center;
    gap: var(--space-3);
    margin-block-start: var(--space-8);
  }
  /* Level is carried by the mark's ink and the words, never by colour
     alone — the title states the outcome. */
  .wx-result--success .wx-result__mark { color: var(--color-success); }
  .wx-result--warn    .wx-result__mark { color: var(--color-warning); }
  .wx-result--danger  .wx-result__mark { color: var(--color-danger); }

  /* Supporting detail — a stack trace, a reference number. */
  .wx-result__detail {
    margin-block-start: var(--space-8);
    padding-block-start: var(--space-6);
    border-block-start: var(--stroke-hairline) solid var(--color-border-subtle);
    text-align: start;
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }
}
/* source: kit/components/popover.css */
/* Popover and popconfirm — anchored transient surfaces.

   Unlike wx-tooltip, a popover MAY carry information and interactive
   controls, so it must be reachable: built on <details> so it opens by
   keyboard without replacing native disclosure behaviour. Escape-to-close
   needs an explicit script. The same bounded-surface
   exception as overlays applies (D-21) — hairline edge only. */
@layer wx.components {
  .wx-popover { position: relative; display: inline-block; }
  .wx-popover > summary {
    display: inline-flex;
    cursor: pointer;
    list-style: none;
  }
  .wx-popover > summary::-webkit-details-marker { display: none; }

  .wx-popover__panel {
    position: absolute;
    inset-block-start: calc(100% + var(--space-2));
    inset-inline-start: 0;
    z-index: 40;
    inline-size: max-content;
    max-inline-size: 20rem;
    padding: var(--space-4) var(--space-5);
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-bg-pure);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-align: start;
  }
  .wx-popover__panel--end { inset-inline: auto 0; }
  .wx-popover__title {
    display: block;
    margin-block-end: var(--space-2);
    font-weight: 600;
    color: var(--color-text-heading);
  }
  .wx-popover__actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
    margin-block-start: var(--space-4);
  }
  .wx-popover__panel > :last-child { margin-block-end: 0; }
}
/* source: kit/components/calendar.css */
/* Calendar — a month grid.

   A table, because that is what it is: days are cells with row and column
   headers. Screen readers announce the weekday and week from the table
   structure, which a grid of <div>s cannot do.

   Selection is aria-pressed and today is aria-current="date" — the ring
   and the weight, not colour alone. */
@layer wx.components {
  .wx-calendar {
    inline-size: 100%;
    border-collapse: collapse;
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
  }
  .wx-calendar caption {
    padding-block-end: var(--space-4);
    font-family: var(--font-display);
    font-size: var(--text-lg);
    color: var(--color-text-heading);
    text-align: start;
  }
  .wx-calendar th {
    padding-block: var(--space-2);
    border-block-end: var(--stroke-hairline) solid var(--color-border-strong);
    font-size: var(--text-xs);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-text-functional);
  }
  .wx-calendar td {
    padding: 0;
    border-block-end: var(--stroke-hairline) solid var(--color-border-subtle);
    text-align: center;
  }
  .wx-calendar__day {
    display: grid;
    place-items: center;
    inline-size: 100%;
    min-block-size: var(--space-10);
    border: 0;
    background: transparent;
    font: inherit;
    color: var(--color-text-secondary);
    cursor: pointer;
  }
  .wx-calendar__day:hover { color: var(--color-text-primary); background: var(--color-bg-subtle); }
  .wx-calendar__day[aria-current="date"] {
    color: var(--color-text-heading);
    font-weight: 600;
    box-decoration-break: clone;
    outline: var(--stroke-hairline) solid var(--color-border-strong);
    outline-offset: -4px;
  }
  .wx-calendar__day[aria-pressed="true"] {
    outline: var(--stroke-mark) solid var(--color-accent);
    outline-offset: -4px;
    color: var(--color-text-heading);
    font-weight: 600;
  }
  .wx-calendar__day[disabled] { color: var(--color-text-functional); cursor: default; }
  .wx-calendar__day[disabled]:hover { background: transparent; }
}
/* source: kit/components/gallery.css */
/* Gallery — the honest replacement for a carousel.

   A carousel that advances on its own is a looping animation that moves
   content the reader is trying to read: forbidden twice over. What is
   legitimate is a horizontally scrollable strip the reader drives — native
   scroll, snap points, keyboard-reachable, and it degrades to a plain
   overflowing row everywhere.

   No arrows overlaying the content: the scrollbar and swipe are the
   affordance, and the strip is announced as a labelled region. */
@layer wx.components {
  .wx-gallery {
    display: flex;
    gap: var(--space-4);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--padding-page-x);
    padding-block-end: var(--space-4);
    overscroll-behavior-x: contain;
  }
  .wx-gallery__item {
    flex: 0 0 min(28rem, 80%);
    scroll-snap-align: start;
  }
  /* A gallery item can itself be a Figure. Its caption still belongs to that
     image, but gallery items sit in one horizontal rhythm rather than adding
     the standalone Figure's vertical outer margin. */
  .wx-gallery__item.wx-figure { margin-block: 0; }
  .wx-gallery__item img { inline-size: 100%; block-size: auto; }
  .wx-gallery__caption {
    margin-block-start: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
  }

  /* Image — content imagery with an intrinsic ratio reserved, so the page
     does not reflow when it loads. Decorative imagery is forbidden; every
     image here is expected to carry meaning and an alt. */
  .wx-image {
    /* Component-scoped token: the consumer overrides the ratio per image. */
    --wx-image-ratio: 16 / 9;
    display: block;
    inline-size: 100%;
    block-size: auto;
    background: var(--color-bg-subtle);
  }
  .wx-image--ratio {
    aspect-ratio: var(--wx-image-ratio);
    object-fit: cover;
  }
}
/* source: kit/components/advanced-entry.css */
/* Native-first advanced entry. These components deliberately use the browser's
   own picker and datalist behaviour: a component library must not replace
   mature platform interactions with a decorative imitation. */
@layer wx.components {
  .wx-input.wx-autocomplete,
  .wx-input.wx-date-picker,
  .wx-input.wx-time-picker {
    cursor: text;
  }
  .wx-input.wx-date-picker,
  .wx-input.wx-time-picker { font-variant-numeric: tabular-nums; }

  /* Popconfirm is a decision, not a modal: native details keeps the trigger
     keyboard-operable. Escape-to-close is not a native details guarantee;
     products that require it add an explicit script. */
  .wx-popconfirm { position: relative; display: inline-block; }
  .wx-popconfirm > summary { display: inline-flex; cursor: pointer; list-style: none; }
  .wx-popconfirm > summary::-webkit-details-marker { display: none; }
  .wx-popconfirm__panel {
    position: absolute;
    inset-block-start: calc(100% + var(--space-2));
    inset-inline-start: 0;
    z-index: 40;
    inline-size: max-content;
    max-inline-size: 20rem;
    padding: var(--space-4) var(--space-5);
    border: var(--stroke-hairline) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-bg-pure);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-align: start;
  }
  .wx-popconfirm__panel > :last-child { margin-block-end: 0; }
}
/* source: kit/patterns/index.css */
/* Five page archetypes A-E. These are layout skeletons, not components: they
   arrange regions while components keep owning their local appearance. */
@layer wx.patterns {
  .wx-reading {
    --wx-reading-width: var(--width-article);
    width: min(100%, var(--wx-reading-width));
    margin-inline: auto;
  }
  .wx-reading__header { margin-block-end: var(--space-12); }
  .wx-reading__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    margin-block-start: var(--space-4);
    color: var(--color-text-functional);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }

  .wx-listing {
    width: min(100%, var(--width-content));
    margin-inline: auto;
  }
  .wx-listing__header { margin-block-end: var(--space-12); }
  .wx-listing__items > * + * { margin-block-start: var(--space-10); }

  .wx-showcase {
    width: min(100%, var(--width-showcase));
    margin-inline: auto;
  }
  .wx-showcase__intro { margin-block-end: var(--space-16); }
  .wx-showcase__timeline { display: grid; gap: var(--space-8); }

  /* One screen, one idea. dvh rather than vh: on mobile the address bar makes
     vh taller than the actual screen, so a "full height" hero overflows.

     A hero at exactly 100dvh shows nothing of what follows, so it must carry
     an explicit scroll cue — the earlier 88dvh let a sliver peek instead,
     which is a weaker signal that also costs the reader a screenful. */
  .wx-landing__hero {
    min-block-size: 100dvh;
    display: grid;
    align-content: center;
    gap: var(--space-6);
    padding-block: var(--space-24);
  }
  .wx-landing__hero > * { max-width: var(--width-showcase); }
  .wx-landing__sections > * + * { margin-block-start: var(--space-24); }
  .wx-landing__cue { margin-block: var(--space-16) 0; font-family: var(--font-ui); color: var(--color-text-functional); }

  .wx-tool {
    width: min(100%, var(--width-content));
    margin-inline: auto;
  }
  .wx-tool__header { margin-block-end: var(--space-8); }
  .wx-tool__input { margin-block-end: var(--space-6); }
  .wx-tool__query-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-4);
    align-items: stretch;
  }
  .wx-tool__query-row > .wx-btn { align-self: stretch; }
  .wx-tool__status {
    margin-block: var(--space-4);
    color: var(--color-text-functional);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
  }
  .wx-tool__result {
    border-block-start: var(--stroke-hairline) solid var(--color-border-subtle);
    padding-block-start: var(--space-8);
  }

  @media (min-width: 760px) {
    .wx-showcase__timeline > * {
      display: grid;
      grid-template-columns: minmax(120px, 0.28fr) minmax(0, 1fr);
      gap: var(--space-8);
    }
  }

  @media (max-width: 40rem) {
    .wx-tool__query-row { grid-template-columns: minmax(0, 1fr); }
    .wx-tool__query-row > .wx-btn { inline-size: 100%; }
  }
}
/* source: kit/markdown/index.css */
/* source: kit/markdown/markdown.css */
/* Markdown prose — .wx-md
   ---------------------------------------------------------------------------
   This file styles HTML you did NOT author: whatever a Markdown renderer
   emitted. That is the entire reason it exists as a separate layer.

   kit/components/code.css styles <pre class="wx-code"> that you wrote.
   This file styles `.wx-md pre > code` that a renderer produced. Same look,
   different selector strategy — you control the class attribute in one case and
   not the other. Conflating them is how a design system rots.

   Because wx.markdown sits above wx.components in the cascade order declared in
   layers.css, these loose descendant selectors never outrank a real component,
   and a form layer can still override everything here.
   --------------------------------------------------------------------------- */
@layer wx.markdown {
  .wx-md {
    font-family: var(--font-body);
    font-size: var(--text-md);
    line-height: var(--leading-relaxed);
    color: var(--color-text-primary);
  }

  /* Keep punctuation from starting or ending a Chinese line where the stricter
     CJK rules forbid it. Other languages keep their browser defaults. */
  .wx-md:lang(zh) { line-break: strict; }

  /* Vertical rhythm. Set once here rather than on every element, so that any
     tag the renderer happens to emit still lands on the scale. */
  .wx-md > * + * { margin-block-start: var(--space-6); }

  .wx-md > h2 { margin-block-start: var(--space-16); }
  .wx-md > h3 { margin-block-start: var(--space-12); }
  .wx-md > h4,
  .wx-md > h5,
  .wx-md > h6 { margin-block-start: var(--space-8); }

  .wx-md h1, .wx-md h2, .wx-md h3,
  .wx-md h4, .wx-md h5, .wx-md h6 { scroll-margin-block-start: var(--space-16); }

  /* Heading anchors: present in the DOM for deep linking, invisible until the
     heading is hovered or the link itself is focused. Never hidden from
     assistive tech — it carries an aria-label. */
  .wx-md .heading-anchor {
    margin-inline-start: var(--space-3);
    color: var(--color-text-functional);
    text-decoration: none;
    opacity: 0;
    transition: opacity var(--duration-fast) var(--ease-default);
  }
  .wx-md :is(h2, h3, h4):hover .heading-anchor,
  .wx-md .heading-anchor:focus-visible { opacity: 1; }

  /* A renderer can put prose links outside p/li/dd — notably in captions and
     table cells. Keep those links visible without spending the accent color. */
  .wx-md :is(figcaption, th, td) a:not([class^="wx-"]):not([class*=" wx-"]) {
    text-decoration: underline;
    text-decoration-thickness: var(--stroke-hairline);
    text-underline-offset: 0.18em;
    text-decoration-color: var(--color-border-strong);
  }
  .wx-md :is(figcaption, th, td) a:not([class^="wx-"]):not([class*=" wx-"]):hover {
    text-decoration-color: currentColor;
  }

  .wx-md ul, .wx-md ol { padding-inline-start: var(--space-6); }
  .wx-md li + li { margin-block-start: var(--space-2); }
  .wx-md li > ul, .wx-md li > ol { margin-block-start: var(--space-2); }

  /* Blockquote — someone else's words inside your argument. */
  .wx-md blockquote {
    padding-inline-start: var(--space-6);
    border-inline-start: var(--stroke-hairline) solid var(--color-border-strong);
    color: var(--color-text-secondary);
  }
  .wx-md blockquote blockquote {
    margin-block-start: var(--space-4);
    padding-inline-start: var(--space-4);
    border-inline-start-color: var(--color-border-subtle);
  }

  .wx-md hr {
    border: 0;
    border-top: var(--stroke-hairline) solid var(--color-border-subtle);
    margin-block: var(--space-16);
  }

  /* Tables: same treatment as wx-table — horizontal rules only. */
  .wx-md table {
    width: 100%;
    font-size: var(--text-sm);
    border-collapse: collapse;
  }
  .wx-md thead th {
    text-align: start;
    font-weight: 600;
    color: var(--color-text-heading);
    border-bottom: var(--stroke-hairline) solid var(--color-border-strong);
  }
  .wx-md td { border-bottom: var(--stroke-hairline) solid var(--color-border-subtle); }
  .wx-md th, .wx-md td {
    padding: var(--space-3);
    padding-inline-start: 0;
    vertical-align: baseline;
  }
  /* A wide table gets its own scroll container rather than widening the page. */
  .wx-md .table-scroll { overflow-x: auto; }

  /* Figures. A renderer that emits <figure> gets a caption; a bare <img> does
     not, and should not be forced into one. */
  .wx-md figure { margin-block: var(--space-8); }
  .wx-md figure img { width: 100%; }
  .wx-md figcaption {
    margin-block-start: var(--space-3);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
  }
  .wx-md img { max-width: 100%; height: auto; }

  /* Inline code and code blocks. */
  .wx-md :not(pre) > code {
    padding: 0.1em 0.35em;
    border-radius: var(--radius-sm);
    background: var(--color-bg-subtle);
    font-family: var(--font-mono);
    font-size: var(--text-code);
  }
  .wx-md pre {
    padding: var(--space-4);
    border: var(--stroke-hairline) solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    background: var(--code-bg);
    overflow-x: auto;
    line-height: var(--leading-normal);
  }
  .wx-md pre > code {
    font-family: var(--font-mono);
    font-size: var(--text-code);
    background: none;
    padding: 0;
  }

  /* Footnotes, as emitted by most Markdown processors. */
  .wx-md .footnotes {
    margin-block-start: var(--space-16);
    padding-block-start: var(--space-6);
    border-top: var(--stroke-hairline) solid var(--color-border-subtle);
    font-size: var(--text-sm);
    color: var(--color-text-secondary);
  }
  .wx-md :is(a.footnote-ref, .footnote-ref > a, [data-footnote-ref], sup > a) {
    color: var(--color-accent);
    text-decoration: underline;
    text-decoration-thickness: var(--stroke-hairline);
    text-underline-offset: 0.18em;
  }
  .wx-md :is(.footnote-backref, .data-footnote-backref, [data-footnote-backref]) {
    margin-inline-start: var(--space-1);
    color: var(--color-text-functional);
    text-decoration: underline;
    text-decoration-thickness: var(--stroke-hairline);
    text-underline-offset: 0.18em;
  }
  /* remark/rehype emits this unprefixed helper for its accessible section
     label. Keep the alias scoped to rendered Markdown. */
  .wx-md .sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* Task lists. */
  .wx-md .task-list-item { list-style: none; margin-inline-start: calc(-1 * var(--space-6)); }
  .wx-md .task-list-item input { margin-inline-end: var(--space-2); accent-color: var(--color-accent); }

  /* Definition lists. */
  .wx-md dt { font-weight: 600; color: var(--color-text-heading); }
  .wx-md dd { margin-inline-start: var(--space-6); color: var(--color-text-secondary); }

  /* Inline HTML disclosures are common in Markdown pipelines. Style only bare
     details so a real wx-collapse or popover keeps its component contract. */
  .wx-md details:not([class]) {
    padding-block: var(--space-3);
    border-block-start: var(--stroke-hairline) solid var(--color-border-subtle);
  }
  .wx-md details:not([class]) > summary {
    font-family: var(--font-ui);
    font-weight: 600;
    color: var(--color-text-heading);
  }
  .wx-md details:not([class]) > summary::marker { color: var(--color-text-functional); }
  .wx-md details:not([class])[open] > summary { margin-block-end: var(--space-3); }

  /* CJK: no italic emphasis — weight instead (criterion G2). */
  .wx-md :lang(zh) em { font-style: normal; font-weight: 600; }

  /* Reading measure. Latin 60–75 characters, CJK 30–40 (criterion P-5). */
  .wx-md--measured { max-width: 68ch; }
  .wx-md--measured:lang(zh) { max-width: 36em; }
}
/* source: kit/markdown/syntax.css */
/* Syntax highlighting — warm, narrow, and recessed only as far as AA allows.
   ---------------------------------------------------------------------------
   Most themes use six saturated hues to separate token types. This one uses
   four closely-related warm tones plus the body ink, because a code block in an
   essay is still prose: the reader is reading it, not scanning it for a bug.

   "Recessed" has a floor. Comments and punctuation were once #9A948D and
   #888580 — 2.87:1 and 3.52:1 against the code ground, failing AA in both
   themes. A comment is the part of a code block most often read as prose, so
   it is the last thing that may fade out. Both now sit just above 4.5:1, and
   the code ground moved from bg-subtle to bg-base to buy that headroom back
   for the block's own metadata row.

   Class names follow Prism/highlight.js conventions so that either can be
   dropped in without a mapping layer.
   --------------------------------------------------------------------------- */
@layer wx.markdown {
  :root {
    --code-bg:          var(--color-bg-base);
    --code-comment:     #77726D;
    --code-punctuation: #665F58;
    --code-operator:    #3A3837;
    --code-keyword:     #6B5B3E;
    --code-string:      #6B5B3E;
    --code-type:        #6B5B3E;
    --code-function:    #5C4A2F;
    --code-property:    #5C4A2F;
    --code-number:      #7A5C3A;
  }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      --code-comment:     #8C857D;
      --code-punctuation: #A9A197;
      --code-operator:    #E8E3DC;
      --code-keyword:     #C0A878;
      --code-string:      #A8B98A;
      --code-type:        #C0A878;
      --code-function:    #D6BE92;
      --code-property:    #D6BE92;
      --code-number:      #C9A57A;
    }
  }
  [data-theme="dark"] {
    --code-comment:     #8C857D;
    --code-punctuation: #A9A197;
    --code-operator:    #E8E3DC;
    --code-keyword:     #C0A878;
    --code-string:      #A8B98A;
    --code-type:        #C0A878;
    --code-function:    #D6BE92;
    --code-property:    #D6BE92;
    --code-number:      #C9A57A;
  }

  .token.comment, .token.prolog, .token.cdata,
  .hljs-comment, .hljs-quote            { color: var(--code-comment); font-style: italic; }

  .token.punctuation,
  .hljs-punctuation                     { color: var(--code-punctuation); }

  .token.operator, .token.entity, .token.url,
  .hljs-operator                        { color: var(--code-operator); }

  .token.keyword, .token.atrule, .token.rule, .token.important,
  .hljs-keyword, .hljs-selector-tag     { color: var(--code-keyword); font-weight: 500; }

  .token.string, .token.char, .token.attr-value, .token.regex,
  .hljs-string, .hljs-attr              { color: var(--code-string); }

  .token.class-name, .token.builtin, .token.symbol,
  .hljs-type, .hljs-title.class_        { color: var(--code-type); }

  .token.function, .token.selector,
  .hljs-title, .hljs-title.function_    { color: var(--code-function); }

  .token.property, .token.tag, .token.attr-name, .token.constant,
  .hljs-attribute, .hljs-name           { color: var(--code-property); }

  .token.number, .token.boolean, .token.unit,
  .hljs-number, .hljs-literal           { color: var(--code-number); }

  .token.deleted { color: var(--color-danger); }
  .token.inserted { color: var(--color-success); }

  /* No bold-italic-underline pile-up. Weight is the only extra channel used. */
  .token.italic { font-style: italic; }
  .token.bold   { font-weight: 600; }
}
/* source: kit/markdown/admonitions.css */
/* Admonitions from Markdown syntax — `:::note`, GitHub-style alerts, or
   whatever the renderer emits. Visually identical to kit/components/note.css;
   separate because here we match on renderer-produced classes rather than on
   classes we wrote ourselves. */
@layer wx.markdown {
  .wx-md :is(.admonition, .alert, .markdown-alert, blockquote.note) {
    padding: var(--space-4) var(--space-5);
    border-inline-start: var(--stroke-mark) solid var(--color-border-strong);
    background: var(--color-bg-subtle);
  }
  .wx-md :is(.admonition, .alert, .markdown-alert) > :first-child { margin-block-start: 0; }
  .wx-md :is(.admonition, .alert, .markdown-alert) > :last-child  { margin-block-end: 0; }

  .wx-md :is(.admonition-title, .alert-title, .markdown-alert-title) {
    display: block;
    margin-block-end: var(--space-2);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
  }

  .wx-md :is(.admonition.tip, .alert-tip, .markdown-alert-tip) {
    border-inline-start-color: var(--color-success);
    background: var(--color-success-subtle);
  }
  .wx-md :is(.admonition.warning, .alert-warning, .markdown-alert-warning) {
    border-inline-start-color: var(--color-warning);
    background: var(--color-warning-subtle);
  }
  .wx-md :is(.admonition.danger, .alert-danger, .markdown-alert-caution) {
    border-inline-start-color: var(--color-danger);
    background: var(--color-danger-subtle);
  }
  .wx-md :is(.admonition.note, .alert-note, .markdown-alert-note) {
    border-inline-start-color: var(--color-text-secondary);
  }

  /* Pull quote as a Markdown construct. */
  .wx-md .pull-quote {
    margin-block: var(--space-12);
    padding: 0;
    border: 0;
    font-family: var(--font-display);
    font-size: var(--text-xl);
    line-height: var(--leading-snug);
    color: var(--color-text-heading);
    text-wrap: balance;
  }
  .wx-md .pull-quote-label {
    display: block;
    margin-block-end: var(--space-3);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wider);
    color: var(--color-text-functional);
  }
  .wx-md .pull-quote-attribution {
    display: block;
    margin-block-start: var(--space-3);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    color: var(--color-text-functional);
  }
}
/* source: kit/charts/index.css */
/* source: kit/charts/palette.css */
/* Chart palette.
   ---------------------------------------------------------------------------
   Series are separated by INK, not by hue, and reinforced by stroke pattern.
   This is the decision that makes charts possible inside this system at all:
   the ban on saturated colour is not an obstacle to overcome, because hue was
   never the categorical channel here.

   Exactly one series may take the accent — the one the caption is about. A
   chart therefore spends one of the page's two accent occurrences, which the
   auditor already knows how to count.
   --------------------------------------------------------------------------- */
@layer wx.charts {
  :root {
    /* The categorical channel: five steps down the ink ramp. */
    --chart-ink-1: var(--color-text-heading);
    --chart-ink-2: var(--color-text-primary);
    --chart-ink-3: var(--color-text-secondary);
    --chart-ink-4: var(--color-text-functional);
    --chart-ink-5: var(--color-border-strong);

    /* The argument. One series, one bar, or one point. */
    --chart-accent:      var(--color-accent);
    --chart-accent-wash: var(--color-accent-subtle);

    /* The second categorical channel, so that series remain separable in
       greyscale print and for readers who cannot distinguish the ink steps. */
    --chart-dash-1: none;
    --chart-dash-2: 6 3;
    --chart-dash-3: 2 3;
    --chart-dash-4: 10 3 2 3;

    /* Geometry */
    --chart-stroke:      var(--stroke-mark);
    --chart-stroke-thin: var(--stroke-hairline);
    --chart-dot:         4px;
    --chart-baseline:    var(--color-border-subtle);

    /* Area and stacked fills are tints of ink, never a hue. */
    --chart-wash-1: color-mix(in oklab, var(--color-text-primary) 14%, transparent);
    --chart-wash-2: color-mix(in oklab, var(--color-text-primary)  8%, transparent);
    --chart-wash-3: color-mix(in oklab, var(--color-text-primary)  4%, transparent);
  }
}
/* source: kit/charts/chart.css */
/* Chart styling for hand-authored SVG.
   ---------------------------------------------------------------------------
   A Wenxin chart is a figure in an essay, not a widget on a dashboard. It is
   read once, carefully, and argues one point. The reference is a newspaper
   graphics desk, not a BI tool.
   --------------------------------------------------------------------------- */
@layer wx.charts {
  /* The frame. A bare chart is not deliverable: without a title and a stated
     unit it is not restrained, it is unfinished. */
  .wx-chart { margin-block: var(--space-12); }

  .wx-chart__title {
    font-family: var(--font-display);
    font-size: var(--text-lg);
    line-height: var(--leading-snug);
    color: var(--color-text-heading);
    text-wrap: balance;
  }
  .wx-chart__subtitle {
    margin-block-start: var(--space-1);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    color: var(--color-text-secondary);
  }
  .wx-chart__svg { display: block; width: 100%; margin-block-start: var(--space-6); }
  .wx-chart__note {
    margin-block-start: var(--space-3);
    font-size: var(--text-xs);
    color: var(--color-text-functional);
  }

  /* ---- marks --------------------------------------------------------------
     Every stroke uses non-scaling-stroke. This is what keeps the 1.5px
     signature stroke at 1.5px when the same SVG is placed on a poster: without
     it, viewBox scaling multiplies the line weight and the mark stops being
     the mark. */
  .wx-chart__svg [class*="wx-chart__"] { vector-effect: non-scaling-stroke; }

  .wx-chart__line {
    fill: none;
    stroke: var(--chart-ink-2);
    stroke-width: var(--chart-stroke);
    stroke-linejoin: round;
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
  }
  .wx-chart__line--2 { stroke: var(--chart-ink-3); stroke-dasharray: var(--chart-dash-2); }
  .wx-chart__line--3 { stroke: var(--chart-ink-4); stroke-dasharray: var(--chart-dash-3); }
  .wx-chart__line--4 { stroke: var(--chart-ink-5); stroke-dasharray: var(--chart-dash-4); }

  .wx-chart__area  { fill: var(--chart-wash-2); stroke: none; }

  .wx-chart__bar   { fill: var(--chart-ink-3); }
  .wx-chart__bar--muted { fill: var(--chart-ink-5); }

  .wx-chart__dot {
    fill: var(--chart-ink-2);
    r: var(--chart-dot);
  }

  /* The argument. One per chart. */
  .wx-chart__line--accent { stroke: var(--chart-accent); }
  .wx-chart__bar--accent,
  .wx-chart__dot--accent  { fill: var(--chart-accent); }
  .wx-chart__area--accent { fill: var(--chart-accent-wash); }

  /* ---- chrome, subtracted -------------------------------------------------
     One baseline. No gridlines, no axis box, no tick marks — the label is the
     tick. What remains is data ink. */
  .wx-chart__baseline {
    stroke: var(--chart-baseline);
    stroke-width: var(--chart-stroke-thin);
    vector-effect: non-scaling-stroke;
  }

  .wx-chart__label {
    font-family: var(--font-ui);
    font-size: 11px;
    fill: var(--color-text-functional);
  }
  /* Direct labelling at the series terminus, in the series' own colour.
     A legend forces the eye to shuttle between a key and the data; this is
     "text is the interface" applied to a chart. */
  .wx-chart__series-label {
    font-family: var(--font-ui);
    font-size: 11px;
    fill: var(--chart-ink-3);
    dominant-baseline: middle;
  }
  .wx-chart__series-label--accent { fill: var(--chart-accent); font-weight: 500; }

  .wx-chart__value {
    font-family: var(--font-ui);
    font-size: 11px;
    fill: var(--color-text-secondary);
    font-variant-numeric: tabular-nums;
  }

  /* Sparkline — inline, no frame, no axis at all. */
  .wx-sparkline {
    display: inline-block;
    inline-size: 5em;
    block-size: 1.1em;
    vertical-align: baseline;
  }
  .wx-sparkline path {
    fill: none;
    stroke: var(--chart-ink-3);
    stroke-width: var(--chart-stroke);
    vector-effect: non-scaling-stroke;
  }

  /* Bar-in-table — a column of magnitudes inside a data table. */
  .wx-bar-cell {
    display: block;
    block-size: 0.5em;
    background: var(--chart-ink-4);
  }
  .wx-bar-cell--accent { background: var(--chart-accent); }

  /* Small multiples — the sanctioned answer to "I have five series". */
  .wx-chart-grid {
    display: grid;
    gap: var(--space-6);
    grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
  }
  .wx-chart-grid .wx-chart { margin-block: 0; }
  .wx-chart-grid .wx-chart__title { font-size: var(--text-base); }

  /* Print: charts must survive greyscale. The ink ramp and dash patterns
     already carry the encoding, so nothing needs to change — which is the
     point of not encoding in hue. */
  @media print {
    .wx-chart { break-inside: avoid; }
  }
}
