@xmesh/system-design 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/README.md +472 -0
  2. package/assets/brand-lockup-dark.svg +9 -0
  3. package/assets/brand-lockup-light.svg +9 -0
  4. package/assets/brand-mark.svg +9 -0
  5. package/colors_and_type.css +11 -0
  6. package/dist/lit/components/alert/index.css +201 -0
  7. package/dist/lit/components/alert/index.d.ts +25 -0
  8. package/dist/lit/components/alert/index.js +191 -0
  9. package/dist/lit/components/app-bar/index.css +80 -0
  10. package/dist/lit/components/app-bar/index.d.ts +19 -0
  11. package/dist/lit/components/app-bar/index.js +120 -0
  12. package/dist/lit/components/artifact/index.css +166 -0
  13. package/dist/lit/components/artifact/index.d.ts +37 -0
  14. package/dist/lit/components/artifact/index.js +294 -0
  15. package/dist/lit/components/autocomplete/index.css +171 -0
  16. package/dist/lit/components/autocomplete/index.d.ts +47 -0
  17. package/dist/lit/components/autocomplete/index.js +404 -0
  18. package/dist/lit/components/avatar/index.css +62 -0
  19. package/dist/lit/components/avatar/index.d.ts +19 -0
  20. package/dist/lit/components/avatar/index.js +112 -0
  21. package/dist/lit/components/avatar-group/index.css +60 -0
  22. package/dist/lit/components/avatar-group/index.d.ts +19 -0
  23. package/dist/lit/components/avatar-group/index.js +97 -0
  24. package/dist/lit/components/badge/index.css +72 -0
  25. package/dist/lit/components/badge/index.d.ts +18 -0
  26. package/dist/lit/components/badge/index.js +115 -0
  27. package/dist/lit/components/brand-mark/index.css +109 -0
  28. package/dist/lit/components/brand-mark/index.d.ts +24 -0
  29. package/dist/lit/components/brand-mark/index.js +116 -0
  30. package/dist/lit/components/breadcrumbs/index.css +91 -0
  31. package/dist/lit/components/breadcrumbs/index.d.ts +19 -0
  32. package/dist/lit/components/breadcrumbs/index.js +104 -0
  33. package/dist/lit/components/bubble/index.css +182 -0
  34. package/dist/lit/components/bubble/index.d.ts +72 -0
  35. package/dist/lit/components/bubble/index.js +617 -0
  36. package/dist/lit/components/button/index.css +342 -0
  37. package/dist/lit/components/button/index.d.ts +32 -0
  38. package/dist/lit/components/button/index.js +202 -0
  39. package/dist/lit/components/card/index.css +99 -0
  40. package/dist/lit/components/card/index.d.ts +20 -0
  41. package/dist/lit/components/card/index.js +133 -0
  42. package/dist/lit/components/chat/index.css +292 -0
  43. package/dist/lit/components/chat/index.d.ts +74 -0
  44. package/dist/lit/components/chat/index.js +589 -0
  45. package/dist/lit/components/checkbox/index.css +126 -0
  46. package/dist/lit/components/checkbox/index.d.ts +21 -0
  47. package/dist/lit/components/checkbox/index.js +138 -0
  48. package/dist/lit/components/chip/index.css +145 -0
  49. package/dist/lit/components/chip/index.d.ts +30 -0
  50. package/dist/lit/components/chip/index.js +230 -0
  51. package/dist/lit/components/chip-group/index.css +19 -0
  52. package/dist/lit/components/chip-group/index.d.ts +24 -0
  53. package/dist/lit/components/chip-group/index.js +171 -0
  54. package/dist/lit/components/code/index.css +42 -0
  55. package/dist/lit/components/code/index.d.ts +12 -0
  56. package/dist/lit/components/code/index.js +68 -0
  57. package/dist/lit/components/composer/index.css +548 -0
  58. package/dist/lit/components/composer/index.d.ts +67 -0
  59. package/dist/lit/components/composer/index.js +713 -0
  60. package/dist/lit/components/data-table/index.css +166 -0
  61. package/dist/lit/components/data-table/index.d.ts +55 -0
  62. package/dist/lit/components/data-table/index.js +390 -0
  63. package/dist/lit/components/dialog/index.css +124 -0
  64. package/dist/lit/components/dialog/index.d.ts +24 -0
  65. package/dist/lit/components/dialog/index.js +199 -0
  66. package/dist/lit/components/divider/index.css +27 -0
  67. package/dist/lit/components/divider/index.d.ts +13 -0
  68. package/dist/lit/components/divider/index.js +67 -0
  69. package/dist/lit/components/empty-state/index.css +69 -0
  70. package/dist/lit/components/empty-state/index.d.ts +21 -0
  71. package/dist/lit/components/empty-state/index.js +123 -0
  72. package/dist/lit/components/expansion-panel/index.css +120 -0
  73. package/dist/lit/components/expansion-panel/index.d.ts +22 -0
  74. package/dist/lit/components/expansion-panel/index.js +174 -0
  75. package/dist/lit/components/field/index.css +223 -0
  76. package/dist/lit/components/field/index.d.ts +106 -0
  77. package/dist/lit/components/field/index.js +388 -0
  78. package/dist/lit/components/file-input/index.css +257 -0
  79. package/dist/lit/components/file-input/index.d.ts +30 -0
  80. package/dist/lit/components/file-input/index.js +298 -0
  81. package/dist/lit/components/form/index.css +29 -0
  82. package/dist/lit/components/form/index.d.ts +38 -0
  83. package/dist/lit/components/form/index.js +192 -0
  84. package/dist/lit/components/grid/index.css +53 -0
  85. package/dist/lit/components/grid/index.d.ts +14 -0
  86. package/dist/lit/components/grid/index.js +82 -0
  87. package/dist/lit/components/kbd/index.css +35 -0
  88. package/dist/lit/components/kbd/index.d.ts +11 -0
  89. package/dist/lit/components/kbd/index.js +43 -0
  90. package/dist/lit/components/list/index.css +15 -0
  91. package/dist/lit/components/list/index.d.ts +28 -0
  92. package/dist/lit/components/list/index.js +188 -0
  93. package/dist/lit/components/list-item/index.css +119 -0
  94. package/dist/lit/components/list-item/index.d.ts +20 -0
  95. package/dist/lit/components/list-item/index.js +127 -0
  96. package/dist/lit/components/menu/index.css +94 -0
  97. package/dist/lit/components/menu/index.d.ts +47 -0
  98. package/dist/lit/components/menu/index.js +386 -0
  99. package/dist/lit/components/navigation-drawer/index.css +114 -0
  100. package/dist/lit/components/navigation-drawer/index.d.ts +29 -0
  101. package/dist/lit/components/navigation-drawer/index.js +218 -0
  102. package/dist/lit/components/overlay/index.css +171 -0
  103. package/dist/lit/components/overlay/index.d.ts +65 -0
  104. package/dist/lit/components/overlay/index.js +566 -0
  105. package/dist/lit/components/pagination/index.css +102 -0
  106. package/dist/lit/components/pagination/index.d.ts +22 -0
  107. package/dist/lit/components/pagination/index.js +184 -0
  108. package/dist/lit/components/primitives/index.css +504 -0
  109. package/dist/lit/components/primitives/index.d.ts +25 -0
  110. package/dist/lit/components/primitives/index.js +283 -0
  111. package/dist/lit/components/progress/index.css +143 -0
  112. package/dist/lit/components/progress/index.d.ts +23 -0
  113. package/dist/lit/components/progress/index.js +180 -0
  114. package/dist/lit/components/radio-group/index.css +178 -0
  115. package/dist/lit/components/radio-group/index.d.ts +35 -0
  116. package/dist/lit/components/radio-group/index.js +292 -0
  117. package/dist/lit/components/select/index.css +151 -0
  118. package/dist/lit/components/select/index.d.ts +50 -0
  119. package/dist/lit/components/select/index.js +390 -0
  120. package/dist/lit/components/sidebar-item/index.css +133 -0
  121. package/dist/lit/components/sidebar-item/index.d.ts +20 -0
  122. package/dist/lit/components/sidebar-item/index.js +105 -0
  123. package/dist/lit/components/skeleton/index.css +81 -0
  124. package/dist/lit/components/skeleton/index.d.ts +19 -0
  125. package/dist/lit/components/skeleton/index.js +119 -0
  126. package/dist/lit/components/slider/index.css +171 -0
  127. package/dist/lit/components/slider/index.d.ts +36 -0
  128. package/dist/lit/components/slider/index.js +302 -0
  129. package/dist/lit/components/snackbar/index.css +279 -0
  130. package/dist/lit/components/snackbar/index.d.ts +33 -0
  131. package/dist/lit/components/snackbar/index.js +195 -0
  132. package/dist/lit/components/stack/index.css +41 -0
  133. package/dist/lit/components/stack/index.d.ts +20 -0
  134. package/dist/lit/components/stack/index.js +103 -0
  135. package/dist/lit/components/switch/index.css +126 -0
  136. package/dist/lit/components/switch/index.d.ts +17 -0
  137. package/dist/lit/components/switch/index.js +116 -0
  138. package/dist/lit/components/table/index.css +85 -0
  139. package/dist/lit/components/table/index.d.ts +25 -0
  140. package/dist/lit/components/table/index.js +139 -0
  141. package/dist/lit/components/tabs/index.css +116 -0
  142. package/dist/lit/components/tabs/index.d.ts +49 -0
  143. package/dist/lit/components/tabs/index.js +320 -0
  144. package/dist/lit/components/text-field/index.css +90 -0
  145. package/dist/lit/components/text-field/index.d.ts +17 -0
  146. package/dist/lit/components/text-field/index.js +101 -0
  147. package/dist/lit/components/textarea/index.css +55 -0
  148. package/dist/lit/components/textarea/index.d.ts +26 -0
  149. package/dist/lit/components/textarea/index.js +124 -0
  150. package/dist/lit/components/tooltip/index.css +37 -0
  151. package/dist/lit/components/tooltip/index.d.ts +31 -0
  152. package/dist/lit/components/tooltip/index.js +196 -0
  153. package/dist/lit/components/validation/index.css +386 -0
  154. package/dist/lit/components/validation/index.d.ts +45 -0
  155. package/dist/lit/components/validation/index.js +318 -0
  156. package/dist/lit/index.d.ts +50 -0
  157. package/dist/lit/index.js +59 -0
  158. package/package.json +81 -0
  159. package/styles/README.md +346 -0
  160. package/styles/_elevation.css +24 -0
  161. package/styles/_fonts.css +6 -0
  162. package/styles/_layout.css +37 -0
  163. package/styles/_primitives.css +154 -0
  164. package/styles/_scroll.css +75 -0
  165. package/styles/_semantic.css +146 -0
  166. package/styles/_space.css +61 -0
  167. package/styles/_type.css +139 -0
  168. package/styles/_xmesh-extensions.css +232 -0
  169. package/styles/index.css +44 -0
  170. package/styles/md3/_color.css +102 -0
  171. package/styles/md3/_elevation.css +26 -0
  172. package/styles/md3/_motion.css +35 -0
  173. package/styles/md3/_shape.css +22 -0
  174. package/styles/md3/_state.css +22 -0
  175. package/styles/md3/_type.css +111 -0
package/README.md ADDED
@@ -0,0 +1,472 @@
1
+ # xmesh Design System
2
+
3
+ A design system extracted from the **xmesh chat** product — a desktop AI-chat
4
+ shell with smart routing, agent traces, and a settings drawer for editing
5
+ agent definitions. The system is built around a **warm dark canvas with white
6
+ card surfaces** and a **coral accent** (`#cc785c`, ~40°), theme-flippable to a cream-light
7
+ mode.
8
+
9
+ Strict editing rules live in **[POLICIES.md](./POLICIES.md)**. The visual
10
+ target — palette, type, surface ramp, voice, anti-patterns — is documented
11
+ in this file (sections **CONTENT FUNDAMENTALS**, **VISUAL FOUNDATIONS**,
12
+ **ICONOGRAPHY** below); the token catalogue with one-line roles per token is
13
+ in **[`styles/README.md`](styles/README.md)**.
14
+
15
+ ## Sources
16
+
17
+ This system was built from the following materials:
18
+
19
+ | Source | Path / link | Notes |
20
+ | --- | --- | --- |
21
+ | Source codebase | `sergeytkachenko/langgraph_smart_routing` (GitHub) | LangGraph-based smart-routing agent platform |
22
+ | Existing docs / system | `docs/desing-system/` (in repo, in the original tree — note the typo `desing`) | Tokens, themes, components, preview canvas |
23
+ | Chat composition components | `packages/shared/components/chat/latest/` | Live composer / sidebar / message list |
24
+ | Reference screenshot | `docs/desing-system/uploads/chat_desired_styles.jpg` | Canonical composer styling |
25
+
26
+ The original `docs/desing-system/` folder (with its typo) lives in the source
27
+ repo only — it is **not** carried into this repo. This design-system folder is
28
+ the **published + cleaned** version, now migrated to **canonical Material
29
+ Design 3** at the role tier (`--md-sys-color-*`, `--md-sys-typescale-*`,
30
+ `--md-sys-shape-corner-*`, `--md-sys-elevation-level*`, `--md-sys-motion-*`).
31
+ xmesh-specific concepts that have no MD3 home (mono typescale, categorical
32
+ badges, paper artboard, snackbar scrim, drawer shadow, focus ring) live
33
+ under the `--xm-*` namespace. Spacing stays as the xmesh `--s-N` 4px
34
+ primitive scale (MD3 has no spacing scale). The legacy `--c-*` / `--t-*` /
35
+ `--r-*` / `--e-*` / `--m-*` namespaces survive in `styles/_semantic.css`
36
+ etc. as transitional aliases that delete in the lockdown phase. Primitives
37
+ (`--x-*`) feed the MD3 layer once and are not referenced from components.
38
+
39
+ ## Index
40
+
41
+ | File / folder | Purpose |
42
+ | --- | --- |
43
+ | `styles/` | The real token system, split by responsibility (`_primitives.css`, `_semantic.css`, `_type.css`, `_space.css`, `_elevation.css`, `_fonts.css`, `_scroll.css`), wired by `styles/index.css`. Token catalogue in `styles/README.md`. |
44
+ | `colors_and_type.css` | Back-compat shim — only does `@import "./styles/index.css"`. Kept so older HTML keeps working. |
45
+ | `assets/` | Brand mark + lockups (SVG only). |
46
+ | `fonts/` | Intentionally empty — Inter and JetBrains Mono pull from Google Fonts via `_fonts.css`. |
47
+ | `lit/components/` | One folder per component, each with `index.css` + `index.ts`: `artifact`, `brand-mark`, `bubble`, `button`, `chat`, `composer`, `primitives`, `sidebar-item`, `snackbar`, `validation`. TS is the canonical source. Each component exposes a custom element named `xm-<name>`. `lit/components/types/` holds shared `.d.ts` shims (Lit-from-esm.sh re-export). |
48
+ | `lit/preview/` | Cards rendered on the **Design System** tab (one concept each). Loads `card.css` for the page scaffold, `_shell.{css,js}` for the page chrome and `xmesh.mount()` helper, and `theme-toggle.js` for dark/light persistence. |
49
+ | `lit/build/` | Compiled `.js`, mirrors `lit/components/`. Git-ignored — produced by `tsc`. Previews `<script type="module">`-load from here. |
50
+ | `scripts/` | Lint/check scripts (`check-tokens.sh`, `check-structure.sh`, `check-previews.sh`, `check-bem.sh`, plus the `check.sh` wrapper) and `screenshot.mjs` (Playwright). |
51
+ | `package.json` | npm scripts: `serve` (tsc-watch + http-server), `build:lit` / `watch:lit`, `screenshot` / `shoot-all`, `check[:tokens\|:structure\|:previews\|:bem]`. Runtime devDeps: `typescript`, `npm-run-all`, `lit` (types only), `playwright`, `http-server`. |
52
+ | `SKILL.md` | Agent-skill manifest, makes this package usable as a Claude Code skill. |
53
+
54
+ > **Earlier React port removed.** Until recently this repo also shipped a React port at `components/` + `preview/` (JSX-as-canonical-source, no build step). Commits `91da854` (split into `react/` + `lit/`), `6f68d05` (move React side to `legacy-react/`), and `4b2d9ba` (delete `legacy-react/`) retired it. References below to JSX components are historical context only — the live tree is `lit/`.
55
+
56
+ ---
57
+
58
+ ## Use this in another site
59
+
60
+ Two ways to consume, depending on what you need: the **tokens only** (any
61
+ site), or the **tokens + Lit components** as the npm package
62
+ `@xmesh/system-design` (bundler-based projects).
63
+
64
+ ### Tokens only (any site)
65
+
66
+ The public entry point is **`styles/index.css`**. It pulls in fonts,
67
+ primitives, semantic tokens, type, spacing, elevation, and the legacy
68
+ shim — everything a consuming site needs.
69
+
70
+ ```css
71
+ /* in your site's global CSS */
72
+ @import "path/to/xmesh-system-design/styles/index.css";
73
+
74
+ :root { /* default = dark theme */ }
75
+ :root[data-theme="light"] { /* set on <html> to flip */ }
76
+ ```
77
+
78
+ Reference only the documented tiers:
79
+
80
+ | Tier | Prefix | What it is |
81
+ | --- | --- | --- |
82
+ | Color (MD3) | `--md-sys-color-*` | Surface ramp, on-* roles, primary/secondary/error, outline. Canonical Material Design 3. |
83
+ | Color (xmesh ext) | `--xm-color-*`, `--xm-method-*`, `--xm-ext-*` | Categorical badges, paper, on-surface third tier, primary-pressed. Non-MD3 concepts. |
84
+ | Type | `--md-sys-typescale-*` | 15 MD3 type roles × 5 sub-tokens. Composite shorthands `--t-*` for legacy callsites. |
85
+ | Radius | `--md-sys-shape-corner-*` | `extra-small`, `small`, `button`, `medium`, `large`, `extra-large`, `full` |
86
+ | Spacing | `--s-1` … `--s-12` | 4px-base scale (xmesh primitive — MD3 has no spacing scale). |
87
+ | Elevation | `--md-sys-elevation-level0..5` | Shadows. xmesh-specific drawer/snackbar/focus-ring under `--xm-*`. |
88
+ | Motion | `--md-sys-motion-duration-*` / `-easing-*` | MD3 duration scale + 7 easing curves. |
89
+
90
+ **Never reference `--x-*`** — those are primitives, used by `_semantic.css`
91
+ internally. Components and consuming sites use the semantic tier.
92
+
93
+ The full token catalogue with one-line roles is in **[`styles/README.md`](styles/README.md)**.
94
+
95
+ ### Tokens + Lit components (npm package)
96
+
97
+ To consume the actual `<xm-*>` components in a **bundler-based** project
98
+ (Vite / webpack 5), install the published package and the `lit` peer:
99
+
100
+ ```bash
101
+ npm install @xmesh/system-design lit
102
+ ```
103
+
104
+ The package ships the prebuilt ESM bundle (`dist/lit/`, co-located CSS, and
105
+ `.d.ts`) — it's built at publish time, so there's nothing to compile on
106
+ install. Then, once at app root:
107
+
108
+ ```ts
109
+ import "@xmesh/system-design/styles"; // tokens → :root (required, once, before first paint)
110
+ import "@xmesh/system-design/lit"; // registers every <xm-*> element
111
+ document.documentElement.dataset.theme = "dark"; // or "light"
112
+ // or tree-shaken: import "@xmesh/system-design/lit/button";
113
+ ```
114
+
115
+ ```html
116
+ <xm-button variant="primary">Send</xm-button>
117
+ ```
118
+
119
+ The full consumer guide (subpath imports, TypeScript types, version pinning,
120
+ the reserved `./react` slot) is in **[`lit/README.md`](lit/README.md)**; the
121
+ rationale and the build/distribution decisions are in
122
+ **[ADR 0004](docs/adr/0004-bundler-consumable-component-library.md)** (now
123
+ superseded by **[ADR 0007](docs/adr/0007-distribute-via-npm-package.md)**).
124
+
125
+ ### Visual feedback for Claude Code
126
+
127
+ `npm run screenshot <preview.html>` renders any preview in dark + light
128
+ themes via Playwright and writes PNGs to `screenshots/`. Claude Code's
129
+ `Read` tool can open those PNGs directly. Use `npm run shoot-all` to
130
+ regenerate every preview's screenshot set.
131
+
132
+ `npm run check` runs four deterministic guards (see `scripts/`):
133
+
134
+ - **`check:tokens`** — `lit/components/*/index.css` for raw hex / `oklch()` /
135
+ `rgb()` / `hsl()` literals, `--x-*` primitive references that bypass the
136
+ semantic tier, and the deleted legacy `--p-*` / `--s-{surface,…}-*`
137
+ aliases.
138
+ - **`check:structure`** — every component is `lit/components/<name>/index.{css,ts}`,
139
+ no other `.css` / `.ts` siblings in the same folder, with
140
+ `lit/components/types/` exempt for the shared Lit-CDN `.d.ts` shim.
141
+ - **`check:previews`** — every `lit/preview/*.html` imports `card.css` and
142
+ `theme-toggle.js`, and no `<link>` / `<script>` URL uses `?v=*`
143
+ cache-busting (POLICIES.md rule 12a).
144
+ - **`check:bem`** — strict BEM in `lit/components/*/index.css`: `block`,
145
+ `block__element`, `block--modifier`; state classes (`.is-*`, `.has-*`)
146
+ must combine with a block; no bare tag selectors; no cross-block
147
+ descendant chains except those allow-listed in `scripts/check-bem.sh`.
148
+
149
+ Each sub-check is also runnable individually:
150
+ `npm run check:tokens` / `:structure` / `:previews` / `:bem`. Run
151
+ `npm run check` before committing.
152
+
153
+ The strict rules enforced by these checks (and the manual ones that
154
+ aren't) are documented in **[POLICIES.md](./POLICIES.md)**.
155
+
156
+ ---
157
+
158
+ ## Brand at a glance
159
+
160
+ xmesh is a **single-product desktop chat** for an AI agent platform. It feels
161
+ like a sturdy, opinionated tool: a craftsman's terminal more than a SaaS
162
+ landing page. The mood is **warm, not cool** (coral accent, oklch hues
163
+ biased toward 40–80°), **dense, not airy** (small type, tight gutters, lots of
164
+ hairline borders), and **functional, not decorative** (no gradients, no
165
+ illustrations, almost no emoji).
166
+
167
+ Two themes ship: **dark** (default — warm desaturated near-black canvas with
168
+ lifted dark cards) and **light** (cream canvas with white cards and dark ink).
169
+ The card stack follows the theme rather than staying white in both ([ADR 0006](./docs/adr/0006-theme-aware-card-stack-surface.md)).
170
+ A `black` theme is referenced in the source for AMOLED contexts.
171
+
172
+ ---
173
+
174
+ ## CONTENT FUNDAMENTALS
175
+
176
+ ### Voice
177
+
178
+ - **Direct and operational.** Copy describes what the surface does or what
179
+ state it is in, not how the user should feel. Examples from the source:
180
+ - File picker hint: `"Choose file or drop here"` / `"YAML or JSON · up to
181
+ 200 KB"`
182
+ - Composer footer: `"Enter to send · Shift+Enter for new line"`
183
+ - Counter: `"4127 / 5000"` (raw numbers, no "characters used:")
184
+ - Processing state: `"Routing query through Planning Path…"`
185
+ - Stop hint: `"Click ▢ to cancel current request"`
186
+
187
+ - **System-as-narrator, not assistant.** Status strings describe the system in
188
+ third person — `"Routing query through Planning Path…"`, not _"I'll route
189
+ this for you."_
190
+
191
+ - **Validation titles are blunt nouns.** From `lit/components/validation/index.ts`
192
+ (the `VALIDATION_TITLE` export): `"File too large"`, `"Wrong file type"`,
193
+ `"Couldn't parse file"`, `"Unexpected structure"`, `"Empty file"`,
194
+ `"Read error"`. No exclamation marks, no apologies, no "Oops!".
195
+
196
+ ### Casing
197
+
198
+ - **Sentence case** for everything. UI labels, buttons, headings, drawer
199
+ titles — all sentence case. `"New chat"`, `"Cancel current request"`,
200
+ `"Routing query through Planning Path…"`. Title Case is reserved for
201
+ proper nouns (`"Planning Path"`, `"REST"`, `"GraphQL"`).
202
+
203
+ - **Caps for tech identifiers**: `YAML`, `JSON`, `REST`, `GraphQL`, `KB`.
204
+
205
+ - **No ALL-CAPS as styling.** The eyebrow type ramp uses uppercase + tracked
206
+ letter-spacing, but the underlying string in source is sentence case.
207
+
208
+ ### Pronouns
209
+
210
+ - **Imperative, no I/you** in inline copy. _"Choose file or drop here"_, not
211
+ _"You can choose…"_. The product never says "I".
212
+ - **Second-person ("you") only in long help/empty-state body copy** — kept
213
+ rare.
214
+
215
+ ### Typography of copy
216
+
217
+ - **Numbers + units side by side**: `"412 KB"`, `"200 KB"`, `"4127 / 5000"`.
218
+ Use a normal space between number and unit.
219
+ - **Keyboard hints**: `Enter`, `Shift+Enter`, `⌘K` — rendered as small kbd
220
+ pills, not bracketed.
221
+ - **Middots (`·`) separate inline metadata**: `"Enter to send · Shift+Enter
222
+ for new line"`, `"8.4 KB · 4 agents, 12 tools"`. Em-dashes (`—`) join
223
+ clauses inside a single string.
224
+ - **Ellipsis is a single character** (`…`), not three dots. Used at the end
225
+ of pending state strings.
226
+
227
+ ### Emoji & emotional tone
228
+
229
+ - **No emoji in product UI.** The brand mark is geometric. The composer's
230
+ send button is an arrow glyph; the stop button is a filled square. Status
231
+ uses small dot indicators, not emoji.
232
+ - **Tone is matter-of-fact.** Errors describe the failure with the data
233
+ (`"File is 412 KB. Maximum allowed size is 200 KB."`) instead of softening
234
+ it. No "oops" / "uh-oh" / smiley — but also no scolding.
235
+
236
+ ### Vibe summary
237
+
238
+ If xmesh copy were a person it would be a **senior infra engineer leaving a
239
+ helpful comment in a PR**: short, technical, no fluff, occasionally dry, never
240
+ cute.
241
+
242
+ ---
243
+
244
+ ## VISUAL FOUNDATIONS
245
+
246
+ ### Color
247
+
248
+ - **Two surface families** — the **`surface`** desk (`--md-sys-color-surface`,
249
+ warm near-black `oklch(0.21 0.003 60)` in dark, cream in light) and the
250
+ **`inverse-surface`** card stack. The card stack is theme-following
251
+ ([ADR 0006](./docs/adr/0006-theme-aware-card-stack-surface.md)): a lifted dark
252
+ surface in dark theme, white in light. Every component sits on exactly one.
253
+ Sidebar + chat list ride `surface`; cards, drawers, popovers, composer field
254
+ ride `inverse-surface`. Container tiers
255
+ (`surface-container-{lowest,low,…,highest}`) step the desk up for hover,
256
+ raised chrome, dialog elevation.
257
+ - **Single accent: coral**, hue ~40°, `#cc785c` (oklch `0.62 0.110 40`),
258
+ exposed as `--md-sys-color-primary`. Used for primary buttons, focus
259
+ rings, the brand mark, the character counter when near limit, and the
260
+ user-message bubble in light theme. Never used for decoration; always
261
+ functional.
262
+ - **No saturated brand color.** No blues, no purples, no neon greens. The
263
+ only saturated hues are the **categorical badge sets** — HTTP-method
264
+ pills (`GET` ~220°, `POST` ~145°, `PUT` ~70°, `DELETE` ~25°,
265
+ `PATCH` ~290°) and file-extension pills (`YAML` ~70°, `JSON` ~145°).
266
+ These signal *category*, not *severity*. There is no status-pastel
267
+ family any more: severity (errors / warnings / info / success) is
268
+ communicated by icon shape + label, not by color.
269
+ - **Hue discipline.** Almost everything sits between `45°–80°` (warm) or
270
+ exact neutrals. Cool hues only appear in the categorical badge sets
271
+ noted above.
272
+
273
+ ### Type
274
+
275
+ - **Inter** for UI, with `font-feature-settings: "ss01", "cv11"` enabled (the
276
+ alternate-1 and stylistic-set 1 keep numbers and capital `i` distinguishable
277
+ in dense lists).
278
+ - **JetBrains Mono** for code, file paths, JSON pointers, error rules, char
279
+ counters when shown as raw values.
280
+ - **Three weights only**: 400 (body), 500 (medium — labels, chips), 600
281
+ (semibold — titles and button text). 700 used sparingly; never italic.
282
+ - **Tight scale**: body is 14px, small is 12px, eyebrow is 11px. Display only
283
+ goes up to ~34px (`h1`); the chat product itself rarely uses anything over
284
+ 18px. Letter-spacing is **negative** above 18px (`-0.01em` to `-0.02em`)
285
+ and zero below.
286
+
287
+ ### Spacing & layout
288
+
289
+ - **4px base grid** (`--s-1` through `--s-12`). Most chrome lives at 12–24px;
290
+ card padding is `22px 24px 14px` for headers, `14px 24px 18px` for footers.
291
+ - **Three-column shell**: 280px sidebar, 1fr chat, optional drawer slides
292
+ over the right edge of the chat pane (absolute-positioned overlay, not a
293
+ third grid column).
294
+ - **Compact mode** collapses sidebar to a 60px icon rail. **Drawer-in-narrow**
295
+ hides the sidebar entirely (used for the trace-drawer demo).
296
+ - **Hairline borders** (1px, low-saturation) do most of the separation work.
297
+ Cards rely on subtle inner-line shadow + tiny outer drop, not heavy
298
+ elevation.
299
+
300
+ ### Backgrounds
301
+
302
+ - **No imagery, no full-bleed photos, no patterns.** The canvas is a flat
303
+ warm-near-black; the surface is flat white. The only "texture" is the
304
+ optional dot-grid on the design-canvas wrapper (`--s-dc-grid`), which sits
305
+ outside the chat product itself.
306
+ - **No gradients in product UI.** A single intentional gradient appears in
307
+ the snackbar overlay (`--c-snk-overlay` / `-strong` / `-soft` three-stop
308
+ vertical fade) because GPU blur was rejected.
309
+
310
+ ### Animation & easing
311
+
312
+ - **Fast, restrained, almost-no-bounce.** The base timing is **120–160ms**
313
+ with `ease`. Hover transitions on chrome are 120ms; theme-swap fade is
314
+ 220ms. There are no spring/bounce easings, no scale-up reveals, no
315
+ attention-grabbing motion.
316
+ - **Reduced motion**: `*::-webkit-scrollbar-thumb { transition: none; }`
317
+ under `prefers-reduced-motion` — the source explicitly cuts thumb
318
+ transitions for that audience.
319
+ - **Status indicators** use a slow pulsing dot (the `…` in the
320
+ thinking-status row), not spinners.
321
+
322
+ ### Hover & press states
323
+
324
+ - **Hover**: warm up the surface by one step. Sidebar items go from
325
+ `--c-sidebar` to `--c-sidebar-hover`. Buttons darken from `--c-accent` to
326
+ `--c-accent-strong`. Borders gain `--c-border-strong` on hover. **No
327
+ brightness/filter tricks**, always real token swaps.
328
+ - **Press / pressed**: inset shadow `--e-pressed` (very subtle inner top
329
+ line), no scale change. The "active" sidebar chat item also picks up
330
+ `inset 0 0 0 1px var(--c-border-canvas)` to read as pinned.
331
+ - **Focus**: `box-shadow: var(--e-focus-ring)` — a 3px halo of
332
+ `--c-accent-soft`. Outlines are removed in favor of this.
333
+
334
+ ### Borders, radii, corners
335
+
336
+ - **Radii**: `8px` chip / `10px` field+button / `14px` card / `999px` pill.
337
+ No 0-radius hard corners, no 20px+ pillowy radii. Buttons and inputs share
338
+ `10px` so they snap together.
339
+ - **Borders are 1px, hairline.** 2px borders only appear in **focus rings**
340
+ and the drag-active state of artboards on the design-canvas chrome
341
+ (`--s-dc-shadow-card-drag` adds a 2px accent ring).
342
+
343
+ ### Shadow / elevation system
344
+
345
+ Six layers, semantic names:
346
+
347
+ | Token | Used for |
348
+ | --- | --- |
349
+ | `--e-subtle` | Inline chips, file rows |
350
+ | `--e-subtle-md` | Slightly raised badges |
351
+ | `--e-card` | The composer / drawers (combo: 1px brightening top edge + soft 24px drop) |
352
+ | `--e-popover` | Menus, tooltips |
353
+ | `--e-popover-strong` | Modals |
354
+ | `--e-snackbar` | Snackbar card (top inner highlight + 18px + 4px stack) |
355
+ | `--e-drawer` | Right-side slide-in trace drawer (left-cast shadow `-16px 0 40px`) |
356
+ | `--e-pressed` / `--e-pressed-soft` | Inset top line for pressed/active rows |
357
+ | `--e-focus-ring` | 3px halo of `--c-accent-soft` |
358
+
359
+ **Inner shadows** are reserved for pressed states and the card top edge
360
+ (brightening line). **No shadows on the canvas itself**; the canvas is the
361
+ ground.
362
+
363
+ ### Transparency & blur
364
+
365
+ - **Blur is avoided.** The snackbar overlay explicitly chose a vertical
366
+ gradient over `backdrop-filter` for performance; this is documented in the
367
+ source comment.
368
+ - **Transparency** appears in: focus rings (3px alpha halo), scrollbar thumbs
369
+ (alpha-on-canvas), shadow stacks. Solid surfaces are otherwise solid.
370
+
371
+ ### Imagery
372
+
373
+ - **There is no imagery.** No photos, no illustrations, no animated
374
+ avatars. The only visuals are: the brand glyph, monochrome line icons, and
375
+ flat color fills.
376
+
377
+ ### Card anatomy
378
+
379
+ A typical card (composer, drawer, modal) uses:
380
+
381
+ - `background: var(--c-card)` (the theme-following card-stack surface)
382
+ - `border: 1px solid var(--c-border-subtle)` (hairline)
383
+ - `border-radius: var(--r-card)` (14px)
384
+ - `box-shadow: var(--e-card)` (combo top-line + soft drop)
385
+ - `padding: 22px 24px 14px` (header) / `14px 24px 18px` (footer)
386
+ - Header / footer are separated by `1px solid var(--c-border-subtle)` rather
387
+ than padding alone.
388
+
389
+ ---
390
+
391
+ ## ICONOGRAPHY
392
+
393
+ ### Approach
394
+
395
+ xmesh uses **inline SVG line icons drawn at 16–24px** with `stroke-width`
396
+ between `1.8` and `2.4`, `currentColor` strokes, and rounded line caps. They
397
+ are defined inline inside the Lit primitives module (`lit/components/primitives/index.ts`
398
+ exports an `<xm-icon>` shell plus 16 named icon elements; per-component icon
399
+ sets — e.g. validation's status glyphs — live alongside their owning
400
+ component) — there is **no icon font, no sprite sheet, no external icon
401
+ library bundled with the product**.
402
+
403
+ The visual character matches the **Lucide / Feather** family: minimal, evenly
404
+ weighted, no fills, slightly geometric. We have substituted **Lucide via
405
+ unpkg CDN** in the UI kit so designs can use the full set without each icon
406
+ needing to be hand-drawn. _Flagged: this is a substitution; the production
407
+ app draws each icon inline._
408
+
409
+ ### Specific patterns observed in source
410
+
411
+ - **`<xm-icon size="..." stroke-width="1.8">`** is the canonical wrapper.
412
+ Children are `<path>` / `<circle>` / `<rect>` with the
413
+ `stroke="currentColor" fill="none"` defaults applied by the wrapper.
414
+ - **Common icons**: alert (circle + ! line), close (X), copy (stacked
415
+ rectangles), upload (arrow + tray), check (single polyline), chevrons,
416
+ search, plus, settings gear.
417
+ - **No emoji**. Anywhere. Not in chat-list dot indicators, not in error
418
+ states, not in empty states.
419
+ - **Unicode glyphs are used sparingly** as inline marks: `…` (ellipsis at end
420
+ of progress strings), `·` (middot in inline metadata), `→` and `↑` for
421
+ send arrows when geometry is simple. The send button in the reference
422
+ screenshot is a real `↑` arrow.
423
+
424
+ ### Logo & brand mark
425
+
426
+ The **brand mark** in the sidebar is a 32×32 rounded-square chip with a
427
+ geometric glyph stroked in `--c-accent-ink`, sitting on a soft
428
+ `--c-accent-soft` fill. The wordmark is `Inter 600` at `16px`,
429
+ `letter-spacing: -0.01em`. We have an SVG of this in `assets/brand-mark.svg`;
430
+ treat it as the canonical lockup.
431
+
432
+ ### File-format badges
433
+
434
+ A small set of branded uppercase chips appears next to file names:
435
+
436
+ | Token pair | Use |
437
+ | --- | --- |
438
+ | `--c-ext-yml-bg` / `--c-ext-yml-ink` | `YML` / `YAML` files |
439
+ | `--c-ext-json-bg` / `--c-ext-json-ink` | `JSON` files |
440
+
441
+ These are used by `<xm-file-validation-block>` and any list of
442
+ agent-definition files. Add new ones by following the same `_bg` / `_ink`
443
+ pattern (warm hue, low chroma in dark, pastel-on-white in light).
444
+
445
+ ### HTTP method badges
446
+
447
+ Pre-themed pill backgrounds for `GET` / `POST` / `PUT` / `PATCH` / `DELETE`
448
+ exist (`--c-method-*-bg` / `-ink`); used in trace-drawer rows for tool calls
449
+ that hit external APIs.
450
+
451
+ ---
452
+
453
+ ## CAVEATS
454
+
455
+ - **Font files**: the source repo references Inter and JetBrains Mono as
456
+ `font-family` strings only — there are no `.woff2` files committed. The
457
+ design system pulls them from **Google Fonts** at runtime. If you need an
458
+ offline build, drop the `.woff2` files into `/fonts/` and replace the
459
+ `@import` in `styles/_fonts.css` with `@font-face` blocks.
460
+ - **Iconography**: the production app inlines its own SVGs. References to a
461
+ Lucide CDN substitution apply to the source repo's UI kit only — this repo
462
+ ships no UI kit and no CDN icon dependency. Inline SVG line icons (Lucide
463
+ style) when adding new components.
464
+ - **No imagery / illustrations** were found in the source — none have been
465
+ invented.
466
+ - **`docs/desing-system` (sic)**: the original folder name has a typo and
467
+ exists only in the source repo (`sergeytkachenko/langgraph_smart_routing`).
468
+ It is **not** present in this repo; references to it here are for
469
+ provenance only.
470
+ - **No `ui_kits/` or `slides/` here.** The source repo had a wired chat UI
471
+ kit; this published system intentionally ships only tokens, components,
472
+ and previews. If you need a full-app shell, fork from the source repo.
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 32" width="140" height="32" aria-label="xmesh">
2
+ <rect x="0" y="0" width="32" height="32" rx="8" fill="oklch(0.78 0.060 70)"></rect>
3
+ <g fill="none" stroke="oklch(0.28 0.04 60)" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
4
+ <path d="M16 7 L24 16 L16 25 L8 16 Z"></path>
5
+ <path d="M11 11 L21 11 L21 21 L11 21 Z"></path>
6
+ <circle cx="16" cy="16" r="1.4" fill="oklch(0.28 0.04 60)"></circle>
7
+ </g>
8
+ <text x="44" y="22" font-family="Inter, system-ui, sans-serif" font-size="18" font-weight="600" letter-spacing="-0.01em" fill="oklch(0.92 0.005 70)">xmesh</text>
9
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 32" width="140" height="32" aria-label="xmesh">
2
+ <rect x="0" y="0" width="32" height="32" rx="8" fill="oklch(0.78 0.060 70)"></rect>
3
+ <g fill="none" stroke="oklch(0.28 0.04 60)" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
4
+ <path d="M16 7 L24 16 L16 25 L8 16 Z"></path>
5
+ <path d="M11 11 L21 11 L21 21 L11 21 Z"></path>
6
+ <circle cx="16" cy="16" r="1.4" fill="oklch(0.28 0.04 60)"></circle>
7
+ </g>
8
+ <text x="44" y="22" font-family="Inter, system-ui, sans-serif" font-size="18" font-weight="600" letter-spacing="-0.01em" fill="oklch(0.22 0.01 60)">xmesh</text>
9
+ </svg>
@@ -0,0 +1,9 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32" aria-label="xmesh">
2
+ <rect x="0" y="0" width="32" height="32" rx="8" fill="oklch(0.78 0.060 70)"></rect>
3
+
4
+ <g fill="none" stroke="oklch(0.28 0.04 60)" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
5
+ <path d="M16 7 L24 16 L16 25 L8 16 Z"></path>
6
+ <path d="M11 11 L21 11 L21 21 L11 21 Z"></path>
7
+ <circle cx="16" cy="16" r="1.4" fill="oklch(0.28 0.04 60)"></circle>
8
+ </g>
9
+ </svg>
@@ -0,0 +1,11 @@
1
+ /* ============================================================
2
+ xmesh Design System — colors_and_type.css
3
+
4
+ Back-compat entry point. The system is now split across
5
+ styles/*.css for clarity; this file just re-exports
6
+ styles/index.css so anything importing the old path keeps
7
+ working.
8
+
9
+ For new code, prefer: @import "styles/index.css";
10
+ ============================================================ */
11
+ @import url("./styles/index.css");