@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.
- package/README.md +472 -0
- package/assets/brand-lockup-dark.svg +9 -0
- package/assets/brand-lockup-light.svg +9 -0
- package/assets/brand-mark.svg +9 -0
- package/colors_and_type.css +11 -0
- package/dist/lit/components/alert/index.css +201 -0
- package/dist/lit/components/alert/index.d.ts +25 -0
- package/dist/lit/components/alert/index.js +191 -0
- package/dist/lit/components/app-bar/index.css +80 -0
- package/dist/lit/components/app-bar/index.d.ts +19 -0
- package/dist/lit/components/app-bar/index.js +120 -0
- package/dist/lit/components/artifact/index.css +166 -0
- package/dist/lit/components/artifact/index.d.ts +37 -0
- package/dist/lit/components/artifact/index.js +294 -0
- package/dist/lit/components/autocomplete/index.css +171 -0
- package/dist/lit/components/autocomplete/index.d.ts +47 -0
- package/dist/lit/components/autocomplete/index.js +404 -0
- package/dist/lit/components/avatar/index.css +62 -0
- package/dist/lit/components/avatar/index.d.ts +19 -0
- package/dist/lit/components/avatar/index.js +112 -0
- package/dist/lit/components/avatar-group/index.css +60 -0
- package/dist/lit/components/avatar-group/index.d.ts +19 -0
- package/dist/lit/components/avatar-group/index.js +97 -0
- package/dist/lit/components/badge/index.css +72 -0
- package/dist/lit/components/badge/index.d.ts +18 -0
- package/dist/lit/components/badge/index.js +115 -0
- package/dist/lit/components/brand-mark/index.css +109 -0
- package/dist/lit/components/brand-mark/index.d.ts +24 -0
- package/dist/lit/components/brand-mark/index.js +116 -0
- package/dist/lit/components/breadcrumbs/index.css +91 -0
- package/dist/lit/components/breadcrumbs/index.d.ts +19 -0
- package/dist/lit/components/breadcrumbs/index.js +104 -0
- package/dist/lit/components/bubble/index.css +182 -0
- package/dist/lit/components/bubble/index.d.ts +72 -0
- package/dist/lit/components/bubble/index.js +617 -0
- package/dist/lit/components/button/index.css +342 -0
- package/dist/lit/components/button/index.d.ts +32 -0
- package/dist/lit/components/button/index.js +202 -0
- package/dist/lit/components/card/index.css +99 -0
- package/dist/lit/components/card/index.d.ts +20 -0
- package/dist/lit/components/card/index.js +133 -0
- package/dist/lit/components/chat/index.css +292 -0
- package/dist/lit/components/chat/index.d.ts +74 -0
- package/dist/lit/components/chat/index.js +589 -0
- package/dist/lit/components/checkbox/index.css +126 -0
- package/dist/lit/components/checkbox/index.d.ts +21 -0
- package/dist/lit/components/checkbox/index.js +138 -0
- package/dist/lit/components/chip/index.css +145 -0
- package/dist/lit/components/chip/index.d.ts +30 -0
- package/dist/lit/components/chip/index.js +230 -0
- package/dist/lit/components/chip-group/index.css +19 -0
- package/dist/lit/components/chip-group/index.d.ts +24 -0
- package/dist/lit/components/chip-group/index.js +171 -0
- package/dist/lit/components/code/index.css +42 -0
- package/dist/lit/components/code/index.d.ts +12 -0
- package/dist/lit/components/code/index.js +68 -0
- package/dist/lit/components/composer/index.css +548 -0
- package/dist/lit/components/composer/index.d.ts +67 -0
- package/dist/lit/components/composer/index.js +713 -0
- package/dist/lit/components/data-table/index.css +166 -0
- package/dist/lit/components/data-table/index.d.ts +55 -0
- package/dist/lit/components/data-table/index.js +390 -0
- package/dist/lit/components/dialog/index.css +124 -0
- package/dist/lit/components/dialog/index.d.ts +24 -0
- package/dist/lit/components/dialog/index.js +199 -0
- package/dist/lit/components/divider/index.css +27 -0
- package/dist/lit/components/divider/index.d.ts +13 -0
- package/dist/lit/components/divider/index.js +67 -0
- package/dist/lit/components/empty-state/index.css +69 -0
- package/dist/lit/components/empty-state/index.d.ts +21 -0
- package/dist/lit/components/empty-state/index.js +123 -0
- package/dist/lit/components/expansion-panel/index.css +120 -0
- package/dist/lit/components/expansion-panel/index.d.ts +22 -0
- package/dist/lit/components/expansion-panel/index.js +174 -0
- package/dist/lit/components/field/index.css +223 -0
- package/dist/lit/components/field/index.d.ts +106 -0
- package/dist/lit/components/field/index.js +388 -0
- package/dist/lit/components/file-input/index.css +257 -0
- package/dist/lit/components/file-input/index.d.ts +30 -0
- package/dist/lit/components/file-input/index.js +298 -0
- package/dist/lit/components/form/index.css +29 -0
- package/dist/lit/components/form/index.d.ts +38 -0
- package/dist/lit/components/form/index.js +192 -0
- package/dist/lit/components/grid/index.css +53 -0
- package/dist/lit/components/grid/index.d.ts +14 -0
- package/dist/lit/components/grid/index.js +82 -0
- package/dist/lit/components/kbd/index.css +35 -0
- package/dist/lit/components/kbd/index.d.ts +11 -0
- package/dist/lit/components/kbd/index.js +43 -0
- package/dist/lit/components/list/index.css +15 -0
- package/dist/lit/components/list/index.d.ts +28 -0
- package/dist/lit/components/list/index.js +188 -0
- package/dist/lit/components/list-item/index.css +119 -0
- package/dist/lit/components/list-item/index.d.ts +20 -0
- package/dist/lit/components/list-item/index.js +127 -0
- package/dist/lit/components/menu/index.css +94 -0
- package/dist/lit/components/menu/index.d.ts +47 -0
- package/dist/lit/components/menu/index.js +386 -0
- package/dist/lit/components/navigation-drawer/index.css +114 -0
- package/dist/lit/components/navigation-drawer/index.d.ts +29 -0
- package/dist/lit/components/navigation-drawer/index.js +218 -0
- package/dist/lit/components/overlay/index.css +171 -0
- package/dist/lit/components/overlay/index.d.ts +65 -0
- package/dist/lit/components/overlay/index.js +566 -0
- package/dist/lit/components/pagination/index.css +102 -0
- package/dist/lit/components/pagination/index.d.ts +22 -0
- package/dist/lit/components/pagination/index.js +184 -0
- package/dist/lit/components/primitives/index.css +504 -0
- package/dist/lit/components/primitives/index.d.ts +25 -0
- package/dist/lit/components/primitives/index.js +283 -0
- package/dist/lit/components/progress/index.css +143 -0
- package/dist/lit/components/progress/index.d.ts +23 -0
- package/dist/lit/components/progress/index.js +180 -0
- package/dist/lit/components/radio-group/index.css +178 -0
- package/dist/lit/components/radio-group/index.d.ts +35 -0
- package/dist/lit/components/radio-group/index.js +292 -0
- package/dist/lit/components/select/index.css +151 -0
- package/dist/lit/components/select/index.d.ts +50 -0
- package/dist/lit/components/select/index.js +390 -0
- package/dist/lit/components/sidebar-item/index.css +133 -0
- package/dist/lit/components/sidebar-item/index.d.ts +20 -0
- package/dist/lit/components/sidebar-item/index.js +105 -0
- package/dist/lit/components/skeleton/index.css +81 -0
- package/dist/lit/components/skeleton/index.d.ts +19 -0
- package/dist/lit/components/skeleton/index.js +119 -0
- package/dist/lit/components/slider/index.css +171 -0
- package/dist/lit/components/slider/index.d.ts +36 -0
- package/dist/lit/components/slider/index.js +302 -0
- package/dist/lit/components/snackbar/index.css +279 -0
- package/dist/lit/components/snackbar/index.d.ts +33 -0
- package/dist/lit/components/snackbar/index.js +195 -0
- package/dist/lit/components/stack/index.css +41 -0
- package/dist/lit/components/stack/index.d.ts +20 -0
- package/dist/lit/components/stack/index.js +103 -0
- package/dist/lit/components/switch/index.css +126 -0
- package/dist/lit/components/switch/index.d.ts +17 -0
- package/dist/lit/components/switch/index.js +116 -0
- package/dist/lit/components/table/index.css +85 -0
- package/dist/lit/components/table/index.d.ts +25 -0
- package/dist/lit/components/table/index.js +139 -0
- package/dist/lit/components/tabs/index.css +116 -0
- package/dist/lit/components/tabs/index.d.ts +49 -0
- package/dist/lit/components/tabs/index.js +320 -0
- package/dist/lit/components/text-field/index.css +90 -0
- package/dist/lit/components/text-field/index.d.ts +17 -0
- package/dist/lit/components/text-field/index.js +101 -0
- package/dist/lit/components/textarea/index.css +55 -0
- package/dist/lit/components/textarea/index.d.ts +26 -0
- package/dist/lit/components/textarea/index.js +124 -0
- package/dist/lit/components/tooltip/index.css +37 -0
- package/dist/lit/components/tooltip/index.d.ts +31 -0
- package/dist/lit/components/tooltip/index.js +196 -0
- package/dist/lit/components/validation/index.css +386 -0
- package/dist/lit/components/validation/index.d.ts +45 -0
- package/dist/lit/components/validation/index.js +318 -0
- package/dist/lit/index.d.ts +50 -0
- package/dist/lit/index.js +59 -0
- package/package.json +81 -0
- package/styles/README.md +346 -0
- package/styles/_elevation.css +24 -0
- package/styles/_fonts.css +6 -0
- package/styles/_layout.css +37 -0
- package/styles/_primitives.css +154 -0
- package/styles/_scroll.css +75 -0
- package/styles/_semantic.css +146 -0
- package/styles/_space.css +61 -0
- package/styles/_type.css +139 -0
- package/styles/_xmesh-extensions.css +232 -0
- package/styles/index.css +44 -0
- package/styles/md3/_color.css +102 -0
- package/styles/md3/_elevation.css +26 -0
- package/styles/md3/_motion.css +35 -0
- package/styles/md3/_shape.css +22 -0
- package/styles/md3/_state.css +22 -0
- 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");
|