@nadicodeai/design-system 0.5.2 → 0.6.0
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/AGENTS.md +9 -10
- package/DESIGN.md +116 -16
- package/README.md +1 -1
- package/dist/css/components/approval-gate.css +2 -2
- package/dist/css/primitives.css +5 -5
- package/dist/css/tokens.generated.css +42 -0
- package/dist/tailwind/nadicode.tailwind.json +36 -1
- package/dist/tailwind/nadicode.theme.css +82 -11
- package/dist/tokens/nadicode.dtcg.json +356 -1
- package/package.json +2 -2
package/AGENTS.md
CHANGED
|
@@ -14,7 +14,7 @@ Plain imperatives are the default. The few hard prohibitions below use `never`/`
|
|
|
14
14
|
- Preserve approved `DESIGN.md` token and component families unless the user explicitly approves a palette/component migration. Website/kernel CSS is implementation evidence, not the complete palette authority; never delete tokens because current prototypes do not use them or because `@google/design.md lint` reports them as unused.
|
|
15
15
|
- Name implemented grids, components, modules, and page elements as NadicodeAI-owned primitives; source brands such as Vercel or Attio may appear only in reference notes, never in component names, CSS comments, `data-module` values, or public-facing contracts.
|
|
16
16
|
- Calculate page grids, module spans, seams, borders, and element placement from explicit grid math; never hand-place visual structure by eye.
|
|
17
|
-
- Author CSS-bundle work as a reusable design-system component architecture first, not as showcase/page-specific code. The design-system CSS lives in `src/css/` (`tokens.generated` [built from `DESIGN.md`] + `tokens.local` [hand-authored] / `reset`/`foundation`/`motion`/`layout`/`primitives` + `components/*`, mirrored to `dist/css/` and exported as `@nadicodeai/design-system/css`). Since the Tailwind+shadcn migration (ADR 0007) the bundle ships only framework-agnostic brand/display CSS components: the cascade is `@layer tokens, reset, foundation, motion, layout, primitives, components;` (no `sections` layer), and `components/*` holds the agent-chat CSS component family, the run-state `state-tag` family, and `image` — the generic marketing/SaaS component CSS and the whole `sections/*` layer retired to React shadcn components in `@nadicodeai/ui`. The delivery tiers map to real authoring homes: tokens → `tokens.generated`/`tokens.local`; page grammar → `layout.css`; CSS primitives/components → `primitives.css` + `components/*`; specimens → `examples/`. Contracted CSS components are paired with `DESIGN.md components:` entries; the three named CSS-internal components are deliberate no-token exceptions. Pages, site-specific page assemblies, and the standard/interactive/section UI belong to consuming surfaces (`../website/`, `../portal/`, sibling Nadia apps) and to the React package (`@nadicodeai/ui`), not this package. Study current source HTML/CSS for approved external references before implementing similar NadicodeAI primitives, then adapt the structure into NadicodeAI-owned tokens, primitives, and components. Specimen HTML demonstrates only already-defined primitives/components; it never invents component geometry, seams, borders, fillers, heights, or responsive behavior inline. The generated token layer (`tokens.generated.css`) and the Tailwind adapter (`nadicode.theme.css`) are emitted by Style Dictionary (`scripts/sd/`, driven from `scripts/build.ts`) as a complete projection of the `@google/design.md` export — never an allowlist or subset; responsive `@media` switching and composed/`calc` vars live in `layout.css`/`tokens.local.css` and reference emitted `--nc-*` tokens only, while the `.nc-type-*` utility classes live in `foundation.css`. Emitted-but-unreferenced tokens are intentional (the contract drives emission, not consumption), and the generated Tailwind adapter owns standard shadcn role maps for both `:root` and `.dark` using generated `--color-*`/`--radius-*` references, plus a small set of `--nc-*` remaps in the `.dark` block (the `state-*`, `selection-*`, and `cross` families → their `--nc-dark-*` counterparts) so design-system CSS components that read those raw brand tokens directly flip on the dark console; `@nadicodeai/ui/globals.css` keeps the Tailwind role bridge plus UI-local product aliases. Correctness is enforced by export-derived structural parity (`tests/token-structural-parity.test.ts` for the `--nc-*` layer; the per-token `@theme` value loops and light/dark role-integrity checks in `tests/tailwind-v4-theme.test.ts` for the adapter), the narrowed two-way parity between `DESIGN.md` component YAML/prose and the retained CSS component surface (`tests/components-yaml-matches-css.test.ts`, ADR 0007 D4), plus consumer discipline (`tests/consumer-css-discipline.test.ts`), not a byte snapshot (ADR 0006 supersedes ADR 0005 D1–D3/D5; ADR 0008 supersedes ADR 0005 D4).
|
|
17
|
+
- Author CSS-bundle work as a reusable design-system component architecture first, not as showcase/page-specific code. The design-system CSS lives in `src/css/` (`tokens.generated` [built from `DESIGN.md`] + `tokens.local` [hand-authored] / `reset`/`foundation`/`motion`/`layout`/`primitives` + `components/*`, mirrored to `dist/css/` and exported as `@nadicodeai/design-system/css`). Since the Tailwind+shadcn migration (ADR 0007) the bundle ships only framework-agnostic brand/display CSS components: the cascade is `@layer tokens, reset, foundation, motion, layout, primitives, components;` (no `sections` layer), and `components/*` holds the agent-chat CSS component family, the run-state `state-tag` family, and `image` — the generic marketing/SaaS component CSS and the whole `sections/*` layer retired to React shadcn components in `@nadicodeai/ui`. The delivery tiers map to real authoring homes: tokens → `tokens.generated`/`tokens.local`; page grammar → `layout.css`; CSS primitives/components → `primitives.css` + `components/*`; specimens → `examples/`. Contracted CSS components are paired with `DESIGN.md components:` entries; the three named CSS-internal components are deliberate no-token exceptions. Pages, site-specific page assemblies, and the standard/interactive/section UI belong to consuming surfaces (`../website/`, `../portal/`, sibling Nadia apps) and to the React package (`@nadicodeai/ui`), not this package. Study current source HTML/CSS for approved external references before implementing similar NadicodeAI primitives, then adapt the structure into NadicodeAI-owned tokens, primitives, and components. Specimen HTML demonstrates only already-defined primitives/components; it never invents component geometry, seams, borders, fillers, heights, or responsive behavior inline. The generated token layer (`tokens.generated.css`) and the Tailwind adapter (`nadicode.theme.css`) are emitted by Style Dictionary (`scripts/sd/`, driven from `scripts/build.ts`) as a complete projection of the `@google/design.md` export — never an allowlist or subset; responsive `@media` switching and composed/`calc` vars live in `layout.css`/`tokens.local.css` and reference emitted `--nc-*` tokens only, while the `.nc-type-*` utility classes live in `foundation.css`. Emitted-but-unreferenced tokens are intentional (the contract drives emission, not consumption), and the generated Tailwind adapter owns standard shadcn role maps for both `:root` and `.dark` using generated `--color-*`/`--radius-*` references, plus a small set of `--nc-*` remaps in the `.dark` block (the `state-*`, `selection-*`, and `cross` families → their `--nc-dark-*` counterparts) so design-system CSS components that read those raw brand tokens directly flip on the dark console; `@nadicodeai/ui/globals.css` keeps the Tailwind role bridge plus UI-local product aliases. Correctness is enforced by export-derived structural parity (`tests/guards/token-structural-parity.test.ts` for the `--nc-*` layer; the per-token `@theme` value loops and light/dark role-integrity checks in `tests/guards/tailwind-v4-theme.test.ts` for the adapter), the narrowed two-way parity between `DESIGN.md` component YAML/prose and the retained CSS component surface (`tests/guards/components-yaml-matches-css.test.ts`, ADR 0007 D4), plus consumer discipline (`tests/guards/consumer-css-discipline.test.ts`), not a byte snapshot (ADR 0006 supersedes ADR 0005 D1–D3/D5; ADR 0008 supersedes ADR 0005 D4).
|
|
18
18
|
- Follow a source-first reference workflow for external visual references: inspect live/source DOM, stylesheet/CSSOM rules, inline styles, custom properties, computed styles, grid tracks, spans, seam ownership, colors, heights, and breakpoints before writing NadicodeAI code. Screenshots are verification evidence only after implementation; never use them as the source for authoring structure, geometry, or CSS.
|
|
19
19
|
- Never derive reusable kernel geometry from screenshots, eyeballing, one-off browser coordinates, or local patch experiments. Browser measurements may verify an implementation after the source CSS/DOM model is understood, but they do not replace reading the source rules that create the behavior.
|
|
20
20
|
- Map every imported visual behavior to either `DESIGN.md`, an existing kernel token/primitive, or an explicit user-approved change before implementation. If the reference leaves a required decision open, or if `DESIGN.md` does not decide it, ask before coding the missing decision, including height/row span, surface color, visual payload, content slots, crosshair placement, and responsive behavior.
|
|
@@ -32,21 +32,21 @@ Generated-artifact and runtime-JS prohibitions live in the Forbidden Patterns ta
|
|
|
32
32
|
- Treat `dist/tokens/nadicode.dtcg.json` and `dist/tailwind/nadicode.tailwind.json` as generated, tracked consumer artifacts.
|
|
33
33
|
- Treat `src/assets/` as the source for exported brand SVG assets.
|
|
34
34
|
- Treat `dist/icons/` as a generated icon set baked from the pinned `lucide-static` dependency by `npm run generate:icons` (also run inside `npm run build`) and exported via `./icons/*`; regenerate by bumping `lucide-static`, never hand-edit.
|
|
35
|
-
-
|
|
35
|
+
- The `design-canvas/` prototypes that `src/css/motion.css`, `src/js/chat-autoplay.js`, and `tests/guards/chat-showcase.test.ts` re-express are deleted from the tree; git history retains them under docs/experiments/design-canvas/. The kernel CSS and its tests are the living expression — never reconstruct the prototypes as a build, runtime component surface, or normative brand contract.
|
|
36
36
|
- Any change to package-consumed output (`DESIGN.md`, generated tokens, CSS bundle, Tailwind theme output, package exports, assets, package docs, or agent instructions) must end with an explicit npm release decision before handoff — enforced by the pre-push release gate: bump the version (merge then auto-publishes; see `../docs/agents/npm-publishing.md`) or mark a commit `[no-publish]`. If the change should reach external consumers, bump `@nadicodeai/design-system` and run `npm pack --dry-run -w @nadicodeai/design-system`. When `@nadicodeai/ui` consumes the changed output, publish `@nadicodeai/design-system` first, then bump/update/publish `@nadicodeai/ui`. Never claim the package is shipped to npm until `npm view @nadicodeai/design-system version` reports the intended version.
|
|
37
37
|
|
|
38
38
|
## Task Routing
|
|
39
39
|
|
|
40
40
|
| Task | Read first | Then read | Verify |
|
|
41
41
|
| --- | --- | --- | --- |
|
|
42
|
-
| Design token, contract, or token-pipeline change | `DESIGN.md`, `scripts/sd/config.ts`, `scripts/sd/transforms.ts`, `scripts/sd/format-token-layer.ts`, `scripts/sd/format-tailwind-v4-theme.ts` | `npm exec -- design.md spec`, `scripts/build.ts`, `tests/token-structural-parity.test.ts`, `tests/consumer-css-discipline.test.ts`, `tests/tailwind-v4-theme.test.ts` | `npm run lint:design && npm run build && npm run test` |
|
|
43
|
-
| Kernel geometry or component work | `DESIGN.md` Layout and Components | `src/css/index.css`, `src/css/layout.css`, `src/css/primitives.css`, `src/css/components/*.css`, `src/css/motion.css`, `tests/kernel-css-architecture.test.ts`, `tests/kernel-rendered-geometry.test.ts` | from design-system/: `npx vitest run tests/kernel-css-architecture.test.ts tests/kernel-rendered-geometry.test.ts` |
|
|
44
|
-
| CSS component or `examples/` specimen work | `DESIGN.md` Layout and Components | `src/css/components/`, `examples/`, `../skills/nadicodeai-brand-copy/SKILL.md`, `../skills/nadicodeai-brand-copy/references/writing-craft.md`, `../skills/nadicodeai-brand-copy/references/brand-voice-profile.md`, `../skills/nadicodeai-brand-copy/references/voice-examples.md` | `npm run test -- tests/examples-package-coherence.test.ts` |
|
|
45
|
-
| Package consumption or export surface | `README.md` | `package.json`, `scripts/build.ts`, `dist/tailwind/`, `dist/tokens/` | `npm run build && npm run test -- tests/build-produces-exports.test.ts tests/tailwind-v4-theme.test.ts` |
|
|
42
|
+
| Design token, contract, or token-pipeline change | `DESIGN.md`, `scripts/sd/config.ts`, `scripts/sd/transforms.ts`, `scripts/sd/format-token-layer.ts`, `scripts/sd/format-tailwind-v4-theme.ts` | `npm exec --package=@google/design.md -- design.md spec`, `scripts/build.ts`, `tests/guards/token-structural-parity.test.ts`, `tests/guards/consumer-css-discipline.test.ts`, `tests/guards/tailwind-v4-theme.test.ts` | `npm run lint:design && npm run build && npm run test` |
|
|
43
|
+
| Kernel geometry or component work | `DESIGN.md` Layout and Components | `src/css/index.css`, `src/css/layout.css`, `src/css/primitives.css`, `src/css/components/*.css`, `src/css/motion.css`, `tests/guards/kernel-css-architecture.test.ts`, `tests/guards/kernel-rendered-geometry.test.ts` | from design-system/: `npx vitest run tests/guards/kernel-css-architecture.test.ts tests/guards/kernel-rendered-geometry.test.ts` |
|
|
44
|
+
| CSS component or `examples/` specimen work | `DESIGN.md` Layout and Components | `src/css/components/`, `examples/`, `../skills/nadicodeai-brand-copy/SKILL.md`, `../skills/nadicodeai-brand-copy/references/writing-craft.md`, `../skills/nadicodeai-brand-copy/references/brand-voice-profile.md`, `../skills/nadicodeai-brand-copy/references/voice-examples.md` | `npm run test -- tests/guards/examples-package-coherence.test.ts` |
|
|
45
|
+
| Package consumption or export surface | `README.md` | `package.json`, `scripts/build.ts`, `dist/tailwind/`, `dist/tokens/` | `npm run build && npm run test -- tests/guards/build-produces-exports.test.ts tests/guards/tailwind-v4-theme.test.ts` |
|
|
46
46
|
|
|
47
47
|
## DESIGN.md Authoring
|
|
48
48
|
|
|
49
|
-
- Check `npm exec -- design.md spec` before adding or changing YAML front matter fields.
|
|
49
|
+
- Check `npm exec --package=@google/design.md -- design.md spec` before adding or changing YAML front matter fields.
|
|
50
50
|
- Put exact reusable values in YAML when they should export through `npm run build`: colors, typography, rounded, spacing, and component fields listed by the current spec.
|
|
51
51
|
- Put application guidance in prose when it describes how to use values: borders, gradients, grid placement, motion, state behavior, responsive composition, markup shape, and accessibility.
|
|
52
52
|
- Keep component identity paired inside `## Components`: every named YAML `components:` entry needs a matching Markdown `**\`component-name\`**` entry in the Components section, and every Markdown component entry in that section needs a matching YAML `components:` entry. YAML carries machine-readable component style hooks; Markdown carries usage, variants, constraints, and judgment.
|
|
@@ -89,7 +89,7 @@ Before claiming work complete (from this directory, or with `-w design-system` f
|
|
|
89
89
|
npm run lint:design && npm run build && npm run test
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
-
`npm run test` MUST stay browser-free: browser-driven tests live in `tests
|
|
92
|
+
`npm run test` MUST stay browser-free: browser-driven tests live in `tests/visual/*.visual.ts` (outside the default `*.test.ts` glob) and run only via `npm run test:visual`. Never add a browser test to the default suite — parallel headless sessions inside the gate are what orphaned Chrome and hung it; that is the real constraint, not `agent-browser` itself.
|
|
93
93
|
|
|
94
94
|
For a visual check, agents use the workspace-local `agent-browser` package (`npm exec -w design-system -- agent-browser ...` from the repo root, or `npm exec -- agent-browser ...` from this directory): open the rendered page, save a screenshot into the ignored evidence folder (`../tmp/visual-evidence/`), inspect it, confirm it looks right, and **close the session** so no Chrome daemon is left running. Run these checks **sequentially, one page at a time** — never as a parallel suite. The repo-level `agent-browser.json` and this directory's `agent-browser.json` set the idle timeout for ad hoc commands, but explicit close is still required. The screenshots persist in `../tmp/visual-evidence/` as evidence for the operator to review.
|
|
95
95
|
|
|
@@ -104,11 +104,10 @@ For a visual check, agents use the workspace-local `agent-browser` package (`npm
|
|
|
104
104
|
| `scripts/build.ts` | Exports DTCG + Tailwind tokens from `DESIGN.md`, runs the Style Dictionary build for the CSS token layer + Tailwind v4 theme, generates the icon set, then mirrors `dist/css` |
|
|
105
105
|
| `scripts/sd/` | Style Dictionary build: `config.ts` (entrypoints), `transforms.ts` (`name/nc`/`color/nc-hex`/`dimension/nc-px` + FORK-A line-height), `format-token-layer.ts` (OUTPUT 1), `format-tailwind-v4-theme.ts` (OUTPUT 2). See ADR 0006 |
|
|
106
106
|
| `scripts/generate-icons.ts` | Bakes the NadicodeAI icon set into `dist/icons/` from the pinned `lucide-static` dependency |
|
|
107
|
-
| `tests/` | Vitest gate
|
|
107
|
+
| `tests/` | Vitest suites, foldered per ADR 0011: `guards/` (the package-spanning gate — design lint, build exports, accepted repo-local validators), `visual/` (opt-in browser suite), `global-setup.ts`. Unit tests for build modules sit beside them in `scripts/` |
|
|
108
108
|
| `agent-browser.json` | Project-level timeout defaults for workspace-local `agent-browser` visual checks |
|
|
109
109
|
| `src/assets/` | Package logo SVG exports |
|
|
110
110
|
| `dist/` | Generated token exports tracked for package consumers |
|
|
111
111
|
| `dist/icons/` | Generated Lucide-derived icon set, exported via `./icons/*` |
|
|
112
112
|
| `../docs/adr/` | Decision records (ADR 0005/0006 govern the token pipeline) |
|
|
113
|
-
| `../docs/experiments/` | Archived `design-canvas/` prototype source-of-record for the kernel chat motion and CSS components |
|
|
114
113
|
| `src/css/motion.css` | The brand motion contract: register, the four moves, craft rules, banned moves — read before any animation work |
|
package/DESIGN.md
CHANGED
|
@@ -3,13 +3,17 @@ version: alpha
|
|
|
3
3
|
name: NadicodeAI Design System
|
|
4
4
|
description: >-
|
|
5
5
|
Reusable design-system contract for NadicodeAI: engineered page geometry,
|
|
6
|
-
neutral high-contrast surfaces, AI-agent work artifacts,
|
|
7
|
-
12-column/10-column composition
|
|
8
|
-
|
|
6
|
+
neutral high-contrast product surfaces, AI-agent work artifacts, strict
|
|
7
|
+
12-column/10-column public-page composition, and the package token exports
|
|
8
|
+
shared by every NadicodeAI interface.
|
|
9
9
|
|
|
10
10
|
colors:
|
|
11
11
|
primary: "#008c45"
|
|
12
12
|
on-primary: "#ffffff"
|
|
13
|
+
action: "#007a3c"
|
|
14
|
+
action-foreground: "#ffffff"
|
|
15
|
+
action-hover: "#00602f"
|
|
16
|
+
action-active: "#00301a"
|
|
13
17
|
ink: "#171717"
|
|
14
18
|
body: "#4d4d4d"
|
|
15
19
|
muted: "#888888"
|
|
@@ -17,8 +21,11 @@ colors:
|
|
|
17
21
|
canvas-soft: "#fafafa"
|
|
18
22
|
canvas-soft-2: "#f5f5f5"
|
|
19
23
|
line: "#e5e5e5"
|
|
24
|
+
input: "#8f8f8f"
|
|
20
25
|
seam: "#e4e7ec"
|
|
21
26
|
cross: "#a1a1a1"
|
|
27
|
+
focus-ring: "#007a3c"
|
|
28
|
+
scrim: "#171717"
|
|
22
29
|
link: "#007a3c"
|
|
23
30
|
link-deep: "#00602f"
|
|
24
31
|
link-bg-soft: "#d9f6e4"
|
|
@@ -104,6 +111,14 @@ colors:
|
|
|
104
111
|
chart-4: "#cd212a"
|
|
105
112
|
chart-5: "#00838f"
|
|
106
113
|
chart-6: "#6f42c1"
|
|
114
|
+
chart-seq-1: "#7d99f2"
|
|
115
|
+
chart-seq-2: "#4f6ae6"
|
|
116
|
+
chart-seq-3: "#2743d8"
|
|
117
|
+
chart-seq-4: "#1d33ad"
|
|
118
|
+
chart-seq-5: "#16277f"
|
|
119
|
+
chart-div-warm: "#d98800"
|
|
120
|
+
chart-div-mid: "#8f8f8f"
|
|
121
|
+
chart-div-cool: "#7d99f2"
|
|
107
122
|
dark-canvas: "#0a0a0a"
|
|
108
123
|
dark-canvas-soft: "#171717"
|
|
109
124
|
dark-canvas-soft-2: "#262626"
|
|
@@ -115,9 +130,15 @@ colors:
|
|
|
115
130
|
dark-seam: "#1f1f1f"
|
|
116
131
|
dark-primary: "#ededed"
|
|
117
132
|
dark-on-primary: "#0a0a0a"
|
|
133
|
+
dark-action: "#ededed"
|
|
134
|
+
dark-action-foreground: "#0a0a0a"
|
|
135
|
+
dark-action-hover: "#d4d4d4"
|
|
136
|
+
dark-action-active: "#a3a3a3"
|
|
118
137
|
dark-link: "#9fe6bc"
|
|
119
138
|
dark-link-deep: "#c3f0d4"
|
|
120
139
|
dark-link-bg-soft: "#00301a"
|
|
140
|
+
dark-focus-ring: "#9fe6bc"
|
|
141
|
+
dark-scrim: "#f5f5f5"
|
|
121
142
|
dark-error: "#f7b3b5"
|
|
122
143
|
dark-error-soft: "#4a000e"
|
|
123
144
|
dark-error-deep: "#fad3d4"
|
|
@@ -142,6 +163,14 @@ colors:
|
|
|
142
163
|
dark-chart-4: "#f28085"
|
|
143
164
|
dark-chart-5: "#33d1cb"
|
|
144
165
|
dark-chart-6: "#9575cd"
|
|
166
|
+
dark-chart-seq-1: "#4f6ae6"
|
|
167
|
+
dark-chart-seq-2: "#7d99f2"
|
|
168
|
+
dark-chart-seq-3: "#a9befa"
|
|
169
|
+
dark-chart-seq-4: "#cdd9fd"
|
|
170
|
+
dark-chart-seq-5: "#eef2ff"
|
|
171
|
+
dark-chart-div-warm: "#ffd97d"
|
|
172
|
+
dark-chart-div-mid: "#e6e6e6"
|
|
173
|
+
dark-chart-div-cool: "#cdd9fd"
|
|
145
174
|
|
|
146
175
|
typography:
|
|
147
176
|
display-xl:
|
|
@@ -254,6 +283,8 @@ rounded:
|
|
|
254
283
|
md: 6px
|
|
255
284
|
lg: 8px
|
|
256
285
|
xl: 10px
|
|
286
|
+
2xl: 12px
|
|
287
|
+
3xl: 16px
|
|
257
288
|
pill-sm: 64px
|
|
258
289
|
pill: 100px
|
|
259
290
|
full: 9999px
|
|
@@ -273,6 +304,10 @@ spacing:
|
|
|
273
304
|
6xl: 128px
|
|
274
305
|
section: 192px
|
|
275
306
|
guide: 1px
|
|
307
|
+
focus-ring-width: 3px
|
|
308
|
+
control-height: 32px
|
|
309
|
+
control-padding-inline: 10px
|
|
310
|
+
touch-target: 44px
|
|
276
311
|
page-pad: 24px
|
|
277
312
|
page-max-mobile: 448px
|
|
278
313
|
page-max-tablet: 624px
|
|
@@ -353,7 +388,7 @@ components:
|
|
|
353
388
|
backgroundColor: "{colors.canvas-soft}"
|
|
354
389
|
textColor: "{colors.body}"
|
|
355
390
|
typography: "{typography.caption}"
|
|
356
|
-
rounded: "{rounded.
|
|
391
|
+
rounded: "{rounded.md}"
|
|
357
392
|
padding: "0px {spacing.xs}"
|
|
358
393
|
filter-chip:
|
|
359
394
|
backgroundColor: "{colors.canvas-soft}"
|
|
@@ -486,9 +521,12 @@ Backgrounds are `{colors.background-100}` (page default, white) and `{colors.bac
|
|
|
486
521
|
|
|
487
522
|
### Semantic roles (functional tier)
|
|
488
523
|
|
|
489
|
-
- **Primary** (`{colors.primary}` = `green-italia-700`):
|
|
490
|
-
- **
|
|
491
|
-
- **
|
|
524
|
+
- **Primary brand anchor** (`{colors.primary}` = `green-italia-700`): identity marks and non-text brand accents. It is not the text-bearing action surface; normal-size white text on this green does not clear AA.
|
|
525
|
+
- **Action** (`{colors.action}`, `{colors.action-foreground}`, `{colors.action-hover}`, `{colors.action-active}`): the text-bearing primary-control family. Shadcn `primary` roles map here rather than to the brand anchor. Dark mode uses the corresponding `dark-action-*` roles.
|
|
526
|
+
- **Canvas / Line / Input / Cross / Seam** (`{colors.canvas}`, `{colors.line}`, `{colors.input}`, `{colors.cross}`, `{colors.seam}`): white content cells, the universal decorative 1 px divider, the stronger resting-control boundary, the stronger gray for marks and crosshair markers, and the dashed connector guide. `{colors.line}` owns ordinary seams; `{colors.input}` owns fields and other interactive boundaries that must clear the 3:1 non-text contrast floor. Never darken a decorative border locally to make it behave like a control.
|
|
527
|
+
- **Body / Muted** (`{colors.body}`, `{colors.muted}`): `{colors.body}` is readable supporting copy; `{colors.muted}` is restricted to disabled, inactive, and placeholder content. Do not use muted text for ordinary descriptions, labels, or help text.
|
|
528
|
+
- **Focus ring** (`{colors.focus-ring}` / `{colors.dark-focus-ring}`): the full-opacity `{spacing.focus-ring-width}` keyboard-focus indicator with no offset. It is independent of the resting border and clears the 3:1 non-text contrast floor against the adjacent canvas.
|
|
529
|
+
- **Scrim** (`{colors.scrim}` / `{colors.dark-scrim}`): the semantic modal-overlay foreground. Its opacity is the generated material token declared in `Elevation & Depth`; it is never combined with backdrop blur.
|
|
492
530
|
- **Link** (`{colors.link}` = `green-italia-800`, `{colors.link-deep}` = `green-italia-900`, `{colors.link-bg-soft}` = `green-italia-200`): inline links, navigational accents, and approved/example proof states. Intentionally green, keeping the Italian signal without turning the interface into flag decoration.
|
|
493
531
|
- **Semantic feedback** (`{colors.success}`, `{colors.error}` + `{colors.error-soft}`/`{colors.error-deep}`, `{colors.warning}` + `{colors.warning-soft}`/`{colors.warning-deep}`, `{colors.info}`): validation, caution, approval, and operational feedback. `success` uses `green-italia-700`; `error` uses `red-italia-800` with soft/deep on `red-italia-200`/`red-italia-900`; `warning` uses `amber-600` with soft/deep on `amber-200`/`amber-900`; `info` (`blue-cobalto-700`) is the new informational role.
|
|
494
532
|
- **Accent** (`{colors.accent}` = `red-italia-700`): UI highlights, badges, and selected markers. Flag red is now an active accent — the former "decoration-only" restriction on flag red is retired. Do not conflate this functional Italia `accent` with the identically-named shadcn surface role `accent`: the latter is a neutral (mapped to `{colors.canvas-soft-2}` in light and `{colors.dark-canvas-soft-2}` in dark) and carries no flag-red hue despite the shared word.
|
|
@@ -517,12 +555,43 @@ Four campo rules govern their use:
|
|
|
517
555
|
|
|
518
556
|
### Dark primitives
|
|
519
557
|
|
|
520
|
-
**Dark Primitives** (`{colors.dark-canvas}`, `{colors.dark-ink}`, `{colors.dark-line}`, and siblings) are the source tokens for the generated shadcn `.dark` role map — mode-bearing primitives, not a separate palette; consuming apps opt in by applying a `.dark` ancestor through their runtime theme provider. The dark neutrals (`dark-canvas`, `dark-canvas-soft`, `dark-canvas-soft-2`, `dark-ink`, `dark-body`, `dark-muted`, `dark-line`, `dark-input`, `dark-seam`, `dark-primary`, `dark-on-primary`) are true neutrals: each is a pure gray (equal channels) so the interface carries no ambient tint, and they step in clear elevation planes (`dark-canvas` → `dark-canvas-soft` → `dark-canvas-soft-2`). `dark-input` is the resting
|
|
558
|
+
**Dark Primitives** (`{colors.dark-canvas}`, `{colors.dark-ink}`, `{colors.dark-line}`, and siblings) are the source tokens for the generated shadcn `.dark` role map — mode-bearing primitives, not a separate palette; consuming apps opt in by applying a `.dark` ancestor through their runtime theme provider. The dark neutrals (`dark-canvas`, `dark-canvas-soft`, `dark-canvas-soft-2`, `dark-ink`, `dark-body`, `dark-muted`, `dark-line`, `dark-input`, `dark-seam`, `dark-primary`, `dark-on-primary`, `dark-action`, `dark-action-foreground`, `dark-action-hover`, `dark-action-active`, and `dark-scrim`) are true neutrals: each is a pure gray (equal channels) so the interface carries no ambient tint, and they step in clear elevation planes (`dark-canvas` → `dark-canvas-soft` → `dark-canvas-soft-2`). `dark-input` is the resting-control boundary, held one gray brighter than the decorative `dark-line` border so a field edge clears non-text contrast before `{colors.dark-focus-ring}` appears. Chroma lives only in the intentional accents: the dark semantic ramps ride the same Italia scales as their light counterparts, moved to lighter steps where they are text-bearing — `dark-link`/`dark-link-deep` on `green-italia-400`/`green-italia-300`, `dark-error`/`dark-error-deep` on `red-italia-400`/`red-italia-300`, `dark-warning`/`dark-warning-deep` on `amber-400`/`amber-300`, with the `*-soft` tinted grounds on each scale's `1000` step, plus `dark-success` on `green-italia-500` for the positive-feedback green. The `dark-state-*` workflow family is not a text role; it preserves the matching ready/running/review/blocked/complete rail colors for 3 px state accents while text stays on neutral foreground roles. The remaining dark-ramp members stay true-neutral: `dark-selection-bg`/`dark-selection-fg` invert the light selection, `dark-scrim` supplies the modal foreground, and `dark-cross` is the visible mark gray, brighter than the decorative `dark-line`. Never reintroduce hue into the neutral set.
|
|
521
559
|
|
|
522
560
|
This grayscale-only discipline is not dark-specific: it governs the whole generated shadcn surface-role bridge in both the light `:root` and dark `.dark` maps. The surface-role family — `background`, `card`, `popover`, `muted`, `secondary`, the `sidebar` roles and their `-foreground`/`-border` variants, plus `border` and `input` — resolves only to pure grays (equal channels) in both themes; hue in the role bridge is reserved for `primary`, `destructive`, and the focus rings (`ring`/`sidebar-ring`). In dark product shells, `background`, `card`, `popover`, and `sidebar` share `{colors.dark-canvas}` so page chrome, cards, tables, overlays, and nav rails read as one black console. `muted`, `secondary`, and `accent` retain the `dark-canvas-soft` steps for small interaction states such as hover, selected rows, keycaps, and inline controls. Large product surfaces never take a tinted or soft-panel fill by default.
|
|
523
561
|
|
|
524
562
|
Do not delete a color because the current website kernel does not consume it. Prototype usage is not palette authority; removals require an explicit palette migration decision.
|
|
525
563
|
|
|
564
|
+
## Data Visualization
|
|
565
|
+
|
|
566
|
+
### Entity-color assignment
|
|
567
|
+
|
|
568
|
+
- **Entity-color assignment**: categorical hues (`{colors.chart-1}`…`{colors.chart-6}`) assign in fixed order to entities per page context, and the assignment follows the entity identity, never rank, sort position, or array index. One assignment map exists per surface; a filter or re-sort never repaints the entities that remain on screen. Beyond six entities, fold the tail into a single neutral "other" slot (`{colors.muted}` register), never a seventh hue.
|
|
569
|
+
|
|
570
|
+
### Sequential ramp and diverging pair
|
|
571
|
+
|
|
572
|
+
- **Sequential ramp** (`{colors.chart-seq-1}`…`{colors.chart-seq-5}`, light→dark on the `blue-cobalto` scale: `chart-seq-1` on `blue-cobalto-500`, `chart-seq-2` on `blue-cobalto-600`, `chart-seq-3` on `blue-cobalto-700`, `chart-seq-4` on `blue-cobalto-800`, `chart-seq-5` on `blue-cobalto-900`): ordered magnitude on one hue, never nominal categories, never a rainbow. `{colors.dark-chart-seq-1}`…`{colors.dark-chart-seq-5}` remap in the `.dark` scope like the categorical set, anchor flipped so `dark-chart-seq-1` is the dimmest step (`blue-cobalto-600`) and `dark-chart-seq-5` the brightest (`blue-cobalto-100`), each clearing the 3:1 WCAG 1.4.11 data-mark floor against `{colors.dark-canvas}`.
|
|
573
|
+
- **Diverging pair** (`{colors.chart-div-warm}` on `amber-700`, `{colors.chart-div-mid}` on `gray-700`, `{colors.chart-div-cool}` on `blue-cobalto-500`; dark counterparts `{colors.dark-chart-div-warm}` on `amber-400`, `{colors.dark-chart-div-mid}` on `gray-300`, `{colors.dark-chart-div-cool}` on `blue-cobalto-300`, remapped in the `.dark` scope the same way): the warm and cool poles carry the sign, the neutral midpoint never carries hue. Meter tracks use a lighter step of the same ramp as their fill.
|
|
574
|
+
|
|
575
|
+
### Meter and bullet grammar
|
|
576
|
+
|
|
577
|
+
- **Meter and bullet grammar**: cap and included-usage bars carry a positional threshold tick at the product-configured warning fraction (80% is the common default; the fraction is a consumer input, never a constant of this contract) and a cap tick at 100%. Overflow renders as a distinct segment continuing past the cap tick, never clamped away. Severity state tokens (`{colors.state-*}`) reinforce position, never act as the sole signal. The current value reads at the bar tip. Every meter carries an accessible name, and its `aria` values clamp to the meter maximum.
|
|
578
|
+
|
|
579
|
+
### Mark specs
|
|
580
|
+
|
|
581
|
+
- **Mark specs**: bars and columns run at most 24px thick with 4px rounded data-ends anchored square at the baseline. Stacked segments and adjacent marks keep a 2px surface gap, one consistent gap width per chart. Lines run at least 2px with round joins and caps; point markers run at least 8px with a 2px surface ring. Area fills read as a light wash (roughly 10% opacity) under a full-strength line. Gridlines and axes are recessive 1px solid hairlines one step off the surface, never dashed. Chart text always carries ink tokens (`{colors.ink}`, `{colors.muted}`), never the series color. Marks render in real pixel space; a chart never scales its viewBox non-uniformly.
|
|
582
|
+
|
|
583
|
+
### Delta and trend encoding
|
|
584
|
+
|
|
585
|
+
- **Delta and trend encoding**: a change reads as a direction glyph (▲ ▼) plus a tone token, never bare signed text and never color alone. Tone follows direction crossed with whether up is good in that context. Sparklines normalize against a meaningful baseline, never the visible min-max span alone.
|
|
586
|
+
|
|
587
|
+
### Legends and labels
|
|
588
|
+
|
|
589
|
+
- **Legends and labels**: at two or more series, every series is identified — up to four series prefer direct labels, which then replace the legend; beyond four, or whenever direct labels are not feasible, a legend is required (ink-token text beside a color swatch; text never wears the series color). A single series is titled, not legended. Every chart names a table alternative. Tooltips enhance a chart and never gate a value.
|
|
590
|
+
|
|
591
|
+
### Texture fallback
|
|
592
|
+
|
|
593
|
+
- **Texture fallback**: under forced-colors, print, or an accessibility setting, series distinguish by one directional line texture at 45 or 135 degrees (tone-on-tone, a darker step of the fill's own ramp), ordered with magnitude on value scales, with the arm angle carrying the diverging sign. Texture is never on by default. The two brand-locked categorical pairs (`chart-2`/`chart-4`, `chart-1`/`chart-6`) always require redundant encoding, never hue alone, restating the Chart categoricals distinguishability rule.
|
|
594
|
+
|
|
526
595
|
## Typography
|
|
527
596
|
|
|
528
597
|
Geist Sans carries all narrative and interface copy. Geist Mono is reserved for eyebrows, labels, status tags, code, traces, and small technical metadata.
|
|
@@ -634,19 +703,46 @@ These live helpers are part of the kept page-grammar layout layer. They are not
|
|
|
634
703
|
|
|
635
704
|
## Elevation & Depth
|
|
636
705
|
|
|
637
|
-
NadicodeAI website depth is flat and architectural. Hairlines, contrast, dotted fields, diagonal fills, and dark action bands create hierarchy.
|
|
706
|
+
NadicodeAI website depth is flat and architectural. Hairlines, contrast, dotted fields, diagonal fills, and dark action bands create hierarchy. The public website does not use floating card stacks as its main structure; the page frame and row grid remain dominant.
|
|
707
|
+
|
|
708
|
+
Product UI uses explicit material roles. Resting content surfaces use no shadow; hierarchy comes from one owned border, spacing, and surface contrast. Shadows identify genuinely floating UI only. The same low-opacity black shadow stacks are used in light and dark themes so elevation does not change character between modes.
|
|
709
|
+
|
|
710
|
+
The Google design schema does not define elevation or opacity groups. These declarations are therefore the authored material-token source inside this contract. The build reads this block strictly, emits generated `--nc-*` hooks, and maps Tailwind's named opacity and shadow utilities to them; consumers never repeat these values.
|
|
711
|
+
|
|
712
|
+
```css material-tokens
|
|
713
|
+
--nc-material-scrim-opacity: 10%;
|
|
714
|
+
--nc-material-shadow-tooltip: 0 1px 1px rgb(0 0 0 / 2%), 0 4px 8px rgb(0 0 0 / 4%);
|
|
715
|
+
--nc-material-shadow-menu: 0 1px 1px rgb(0 0 0 / 2%), 0 4px 8px -4px rgb(0 0 0 / 4%), 0 16px 24px -8px rgb(0 0 0 / 6%);
|
|
716
|
+
--nc-material-shadow-dialog: 0 1px 1px rgb(0 0 0 / 2%), 0 8px 16px -4px rgb(0 0 0 / 4%), 0 24px 32px -8px rgb(0 0 0 / 6%);
|
|
717
|
+
--nc-material-shadow-sheet: 0 2px 2px rgb(0 0 0 / 4%), 0 8px 16px -4px rgb(0 0 0 / 4%);
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
| Material role | Border / radius | Elevation | Internal spacing |
|
|
721
|
+
| --- | --- | --- | --- |
|
|
722
|
+
| Resting content surface | 1 px `{colors.line}` / `{colors.dark-line}`; `{rounded.md}` (6 px) | none | 24 px, or 16 px only for an explicitly compact surface |
|
|
723
|
+
| Resting control | 1 px `{colors.input}` / `{colors.dark-input}`; `{rounded.md}` (6 px) | none | `{spacing.control-padding-inline}` inline; `{spacing.xs}` block for textareas; minimum height `{spacing.control-height}` |
|
|
724
|
+
| Tooltip | 1 px `{colors.line}` / `{colors.dark-line}`; `{rounded.md}` (6 px) | tooltip shadow | 6 px block / 12 px inline |
|
|
725
|
+
| Menu | 1 px `{colors.line}` / `{colors.dark-line}`; `{rounded.2xl}` (12 px) | menu shadow | 4 px |
|
|
726
|
+
| Popover | 1 px `{colors.line}` / `{colors.dark-line}`; `{rounded.2xl}` (12 px) | menu shadow | 10 px |
|
|
727
|
+
| Dialog | 1 px `{colors.line}` / `{colors.dark-line}`; `{rounded.2xl}` (12 px) | dialog shadow | 24 px body / 16 px footer |
|
|
728
|
+
| Inset sheet | 1 px `{colors.line}` / `{colors.dark-line}`; `{rounded.3xl}` (16 px) | sheet shadow | 12 px outer inset / 24 px sections |
|
|
729
|
+
| Takeover | 1 px `{colors.line}` / `{colors.dark-line}`; `{rounded.3xl}` (16 px) | dialog shadow | 24 px |
|
|
730
|
+
|
|
731
|
+
Modal overlays use `{colors.scrim}` / `{colors.dark-scrim}` at the generated `scrim` opacity with no blur. Focus is not elevation: controls use a full-opacity `{spacing.focus-ring-width}` `{colors.focus-ring}` / `{colors.dark-focus-ring}` ring with no offset. Avoid nested decorative borders: one container owns containment, while child groups use spacing, headings, or dividers only when those dividers clarify structure.
|
|
638
732
|
|
|
639
|
-
|
|
733
|
+
On coarse or non-hover input capability, every interactive target is at least 44 × 44 px at every viewport width. A compact visual mark such as a checkbox or radio stays compact while its label or hit area supplies the target size. Fine, hover-capable pointers may use the compact control scale.
|
|
640
734
|
|
|
641
735
|
## Shapes
|
|
642
736
|
|
|
643
|
-
Corners are restrained.
|
|
737
|
+
Corners are restrained and assigned by material role.
|
|
644
738
|
|
|
645
739
|
- Use `{rounded.none}` for page rows, frame edges, grid cells, and structural modules.
|
|
646
|
-
- Use `{rounded.
|
|
647
|
-
- Use `{rounded.
|
|
740
|
+
- Use `{rounded.md}` (6 px) for resting content surfaces, controls, buttons, chips, status tags, tooltips, chat bubbles, and small artifacts.
|
|
741
|
+
- Use `{rounded.2xl}` (12 px) for menus, popovers, and dialogs.
|
|
742
|
+
- Use `{rounded.3xl}` (16 px) for inset sheets and takeovers.
|
|
743
|
+
- Use `{rounded.full}` only for intrinsically circular identity/avatar chrome and compact control marks whose geometry is inherently round or pill-shaped. It never turns a content surface, button, badge, or navigation item into a pill by default.
|
|
648
744
|
|
|
649
|
-
|
|
745
|
+
Public page-grammar cells are not cards and remain square because their parent frame supplies the visual system. Product cards are resting content surfaces and use the 6 px role above; they do not gain thicker borders, nested frames, or a shadow merely because they contain grouped settings.
|
|
650
746
|
|
|
651
747
|
## Components
|
|
652
748
|
|
|
@@ -656,7 +752,7 @@ Component entries are grouped by design-system family so the decision model stay
|
|
|
656
752
|
|
|
657
753
|
Interface CSS components provide small metadata, label, and link chrome. They inherit NadicodeAI tokens and stay subordinate to the page grammar; they must not create independent layout systems or repair structural seams. The generic interactive controls (navigation, buttons, inputs, footer chrome, the marketing card/code/pricing/proof surfaces, the standard sections) ship as React shadcn components from `@nadicodeai/ui`; this contract keeps only the brand/display CSS components and primitives that belong in the framework-agnostic package.
|
|
658
754
|
|
|
659
|
-
Interactive CSS components must expose a visible `:focus-visible` state using the
|
|
755
|
+
Interactive CSS components must expose a visible `:focus-visible` state using the `{spacing.focus-ring-width}` full-opacity `{colors.focus-ring}` / `{colors.dark-focus-ring}` role with no offset. Do not remove outlines without that contrast-safe equivalent.
|
|
660
756
|
|
|
661
757
|
**`label-mono`** — mono eyebrow/label text for section labels and low-priority metadata.
|
|
662
758
|
|
|
@@ -690,7 +786,7 @@ Agentic work surfaces are the NadicodeAI-specific layer. They show people and ag
|
|
|
690
786
|
|
|
691
787
|
**`tool-call-trace`** — compact code/trace row. Use only when tool use is relevant to the explanation.
|
|
692
788
|
|
|
693
|
-
State-tag variants share the same
|
|
789
|
+
State-tag variants share the same compact rectangular shape at `{typography.caption-mono}` and differentiate by a 3 px colored `border-left` consuming the matching `{colors.state-*}` token. Shape carries meaning; color carries variant. State is never conveyed through swatches, dots, pulses, breathing animations, or loading spinners.
|
|
694
790
|
|
|
695
791
|
**`state-tag-ready`** — workflow state tag for work that is ready or waiting to start. Uses `{colors.state-ready}` for the left edge.
|
|
696
792
|
|
|
@@ -722,6 +818,8 @@ State-tag variants share the same shape — a compact rectangular pill at `{typo
|
|
|
722
818
|
- Do keep centered content in the 10-column `active-lane` while preserving visible ownership of columns 1 and 12.
|
|
723
819
|
- Do use `side-fill`, guide strips, or component-owned fillers whenever content does not occupy the outer columns.
|
|
724
820
|
- Do use `{spacing.guide}` and `{colors.line}` for ordinary seams.
|
|
821
|
+
- Do use `{colors.input}` / `{colors.dark-input}` for resting control boundaries and the dedicated focus-ring roles for keyboard focus.
|
|
822
|
+
- Do use exactly one material role per container: resting surfaces are border-only; menus, popovers, dialogs, sheets, and takeovers use their specified floating treatment.
|
|
725
823
|
- Do tune line visibility by changing `{colors.line}` at the token contract, then rebuilding generated exports.
|
|
726
824
|
- Do use `{colors.cross}` for crosshair color while keeping crosshair weight equal to `{spacing.guide}`.
|
|
727
825
|
- Do use fixed height tokens for default component/specimen height and let content grow only when required.
|
|
@@ -736,6 +834,8 @@ State-tag variants share the same shape — a compact rectangular pill at `{typo
|
|
|
736
834
|
- Don't create naked centered 10-column sections without visible ownership of columns 1 and 12.
|
|
737
835
|
- Don't draw the same seam from two adjacent elements.
|
|
738
836
|
- Don't add borders inside cells to fix visual seams; fix the owner layer.
|
|
837
|
+
- Don't use a 1 px decorative line as an input boundary, or locally increase card border weight to manufacture hierarchy.
|
|
838
|
+
- Don't stack borders around nested groups, add shadows to resting cards, or blur modal scrims.
|
|
739
839
|
- Don't tune seam contrast with local opacity, raw colors, or component-specific border colors.
|
|
740
840
|
- Don't use viewport-scaled typography.
|
|
741
841
|
- Don't use negative letter spacing in the website kernel.
|
package/README.md
CHANGED
|
@@ -120,4 +120,4 @@ For motion, the package ships exactly one optional, vanilla, dependency-free enh
|
|
|
120
120
|
|
|
121
121
|
Use the monorepo's `brand/brand-book/` for NadicodeAI story, positioning, buyer, promise, method, use cases, technology story, trust doctrine, identity, voice, visual direction, sales behavior, language, and boundaries.
|
|
122
122
|
|
|
123
|
-
The
|
|
123
|
+
The `design-canvas/` prototypes the kernel re-expresses (chat motion and component prototypes) are deleted from the tree; git history retains them under `docs/experiments/design-canvas/`. They are not package runtime or current brand canon.
|
package/dist/css/primitives.css
CHANGED
|
@@ -305,8 +305,8 @@
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
.nc-filter-chip:focus-visible {
|
|
308
|
-
outline:
|
|
309
|
-
outline-offset:
|
|
308
|
+
outline: var(--nc-focus-ring-width) solid var(--nc-focus-ring);
|
|
309
|
+
outline-offset: 0;
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
/* nc-link-inline — the inline body link style (DESIGN.md link-inline). It reads
|
|
@@ -332,9 +332,9 @@
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
.nc-link-inline:focus-visible {
|
|
335
|
-
outline:
|
|
336
|
-
outline-offset:
|
|
337
|
-
border-radius: var(--nc-rounded-
|
|
335
|
+
outline: var(--nc-focus-ring-width) solid var(--nc-focus-ring);
|
|
336
|
+
outline-offset: 0;
|
|
337
|
+
border-radius: var(--nc-rounded-md);
|
|
338
338
|
}
|
|
339
339
|
|
|
340
340
|
/* nc-label-mono — the mono eyebrow/kicker for section labels and low-priority
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
/* Colors */
|
|
8
8
|
--nc-primary: #008c45;
|
|
9
9
|
--nc-on-primary: #ffffff;
|
|
10
|
+
--nc-action: #007a3c;
|
|
11
|
+
--nc-action-foreground: #ffffff;
|
|
12
|
+
--nc-action-hover: #00602f;
|
|
13
|
+
--nc-action-active: #00301a;
|
|
10
14
|
--nc-ink: #171717;
|
|
11
15
|
--nc-body: #4d4d4d;
|
|
12
16
|
--nc-muted: #888888;
|
|
@@ -14,8 +18,11 @@
|
|
|
14
18
|
--nc-canvas-soft: #fafafa;
|
|
15
19
|
--nc-canvas-soft-2: #f5f5f5;
|
|
16
20
|
--nc-line: #e5e5e5;
|
|
21
|
+
--nc-input: #8f8f8f;
|
|
17
22
|
--nc-seam: #e4e7ec;
|
|
18
23
|
--nc-cross: #a1a1a1;
|
|
24
|
+
--nc-focus-ring: #007a3c;
|
|
25
|
+
--nc-scrim: #171717;
|
|
19
26
|
--nc-link: #007a3c;
|
|
20
27
|
--nc-link-deep: #00602f;
|
|
21
28
|
--nc-link-bg-soft: #d9f6e4;
|
|
@@ -101,6 +108,14 @@
|
|
|
101
108
|
--nc-chart-4: #cd212a;
|
|
102
109
|
--nc-chart-5: #00838f;
|
|
103
110
|
--nc-chart-6: #6f42c1;
|
|
111
|
+
--nc-chart-seq-1: #7d99f2;
|
|
112
|
+
--nc-chart-seq-2: #4f6ae6;
|
|
113
|
+
--nc-chart-seq-3: #2743d8;
|
|
114
|
+
--nc-chart-seq-4: #1d33ad;
|
|
115
|
+
--nc-chart-seq-5: #16277f;
|
|
116
|
+
--nc-chart-div-warm: #d98800;
|
|
117
|
+
--nc-chart-div-mid: #8f8f8f;
|
|
118
|
+
--nc-chart-div-cool: #7d99f2;
|
|
104
119
|
--nc-dark-canvas: #0a0a0a;
|
|
105
120
|
--nc-dark-canvas-soft: #171717;
|
|
106
121
|
--nc-dark-canvas-soft-2: #262626;
|
|
@@ -112,9 +127,15 @@
|
|
|
112
127
|
--nc-dark-seam: #1f1f1f;
|
|
113
128
|
--nc-dark-primary: #ededed;
|
|
114
129
|
--nc-dark-on-primary: #0a0a0a;
|
|
130
|
+
--nc-dark-action: #ededed;
|
|
131
|
+
--nc-dark-action-foreground: #0a0a0a;
|
|
132
|
+
--nc-dark-action-hover: #d4d4d4;
|
|
133
|
+
--nc-dark-action-active: #a3a3a3;
|
|
115
134
|
--nc-dark-link: #9fe6bc;
|
|
116
135
|
--nc-dark-link-deep: #c3f0d4;
|
|
117
136
|
--nc-dark-link-bg-soft: #00301a;
|
|
137
|
+
--nc-dark-focus-ring: #9fe6bc;
|
|
138
|
+
--nc-dark-scrim: #f5f5f5;
|
|
118
139
|
--nc-dark-error: #f7b3b5;
|
|
119
140
|
--nc-dark-error-soft: #4a000e;
|
|
120
141
|
--nc-dark-error-deep: #fad3d4;
|
|
@@ -139,6 +160,14 @@
|
|
|
139
160
|
--nc-dark-chart-4: #f28085;
|
|
140
161
|
--nc-dark-chart-5: #33d1cb;
|
|
141
162
|
--nc-dark-chart-6: #9575cd;
|
|
163
|
+
--nc-dark-chart-seq-1: #4f6ae6;
|
|
164
|
+
--nc-dark-chart-seq-2: #7d99f2;
|
|
165
|
+
--nc-dark-chart-seq-3: #a9befa;
|
|
166
|
+
--nc-dark-chart-seq-4: #cdd9fd;
|
|
167
|
+
--nc-dark-chart-seq-5: #eef2ff;
|
|
168
|
+
--nc-dark-chart-div-warm: #ffd97d;
|
|
169
|
+
--nc-dark-chart-div-mid: #e6e6e6;
|
|
170
|
+
--nc-dark-chart-div-cool: #cdd9fd;
|
|
142
171
|
|
|
143
172
|
/* Spacing */
|
|
144
173
|
--nc-xxs: 4px;
|
|
@@ -155,6 +184,10 @@
|
|
|
155
184
|
--nc-6xl: 128px;
|
|
156
185
|
--nc-section: 192px;
|
|
157
186
|
--nc-guide: 1px;
|
|
187
|
+
--nc-focus-ring-width: 3px;
|
|
188
|
+
--nc-control-height: 32px;
|
|
189
|
+
--nc-control-padding-inline: 10px;
|
|
190
|
+
--nc-touch-target: 44px;
|
|
158
191
|
--nc-page-pad: 24px;
|
|
159
192
|
--nc-page-max-mobile: 448px;
|
|
160
193
|
--nc-page-max-tablet: 624px;
|
|
@@ -209,6 +242,8 @@
|
|
|
209
242
|
--nc-rounded-md: 6px;
|
|
210
243
|
--nc-rounded-lg: 8px;
|
|
211
244
|
--nc-rounded-xl: 10px;
|
|
245
|
+
--nc-rounded-2xl: 12px;
|
|
246
|
+
--nc-rounded-3xl: 16px;
|
|
212
247
|
--nc-rounded-pill-sm: 64px;
|
|
213
248
|
--nc-rounded-pill: 100px;
|
|
214
249
|
--nc-rounded-full: 9999px;
|
|
@@ -299,4 +334,11 @@
|
|
|
299
334
|
--nc-type-button-lg-font-weight: 500;
|
|
300
335
|
--nc-type-button-lg-line-height: 24px;
|
|
301
336
|
--nc-type-button-lg-letter-spacing: 0px;
|
|
337
|
+
|
|
338
|
+
/* Material opacity and shadows (strictly parsed from DESIGN.md prose) */
|
|
339
|
+
--nc-material-scrim-opacity: 10%;
|
|
340
|
+
--nc-material-shadow-tooltip: 0 1px 1px rgb(0 0 0 / 2%), 0 4px 8px rgb(0 0 0 / 4%);
|
|
341
|
+
--nc-material-shadow-menu: 0 1px 1px rgb(0 0 0 / 2%), 0 4px 8px -4px rgb(0 0 0 / 4%), 0 16px 24px -8px rgb(0 0 0 / 6%);
|
|
342
|
+
--nc-material-shadow-dialog: 0 1px 1px rgb(0 0 0 / 2%), 0 8px 16px -4px rgb(0 0 0 / 4%), 0 24px 32px -8px rgb(0 0 0 / 6%);
|
|
343
|
+
--nc-material-shadow-sheet: 0 2px 2px rgb(0 0 0 / 4%), 0 8px 16px -4px rgb(0 0 0 / 4%);
|
|
302
344
|
}
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
"colors": {
|
|
5
5
|
"primary": "#008c45",
|
|
6
6
|
"on-primary": "#ffffff",
|
|
7
|
+
"action": "#007a3c",
|
|
8
|
+
"action-foreground": "#ffffff",
|
|
9
|
+
"action-hover": "#00602f",
|
|
10
|
+
"action-active": "#00301a",
|
|
7
11
|
"ink": "#171717",
|
|
8
12
|
"body": "#4d4d4d",
|
|
9
13
|
"muted": "#888888",
|
|
@@ -11,8 +15,11 @@
|
|
|
11
15
|
"canvas-soft": "#fafafa",
|
|
12
16
|
"canvas-soft-2": "#f5f5f5",
|
|
13
17
|
"line": "#e5e5e5",
|
|
18
|
+
"input": "#8f8f8f",
|
|
14
19
|
"seam": "#e4e7ec",
|
|
15
20
|
"cross": "#a1a1a1",
|
|
21
|
+
"focus-ring": "#007a3c",
|
|
22
|
+
"scrim": "#171717",
|
|
16
23
|
"link": "#007a3c",
|
|
17
24
|
"link-deep": "#00602f",
|
|
18
25
|
"link-bg-soft": "#d9f6e4",
|
|
@@ -98,6 +105,14 @@
|
|
|
98
105
|
"chart-4": "#cd212a",
|
|
99
106
|
"chart-5": "#00838f",
|
|
100
107
|
"chart-6": "#6f42c1",
|
|
108
|
+
"chart-seq-1": "#7d99f2",
|
|
109
|
+
"chart-seq-2": "#4f6ae6",
|
|
110
|
+
"chart-seq-3": "#2743d8",
|
|
111
|
+
"chart-seq-4": "#1d33ad",
|
|
112
|
+
"chart-seq-5": "#16277f",
|
|
113
|
+
"chart-div-warm": "#d98800",
|
|
114
|
+
"chart-div-mid": "#8f8f8f",
|
|
115
|
+
"chart-div-cool": "#7d99f2",
|
|
101
116
|
"dark-canvas": "#0a0a0a",
|
|
102
117
|
"dark-canvas-soft": "#171717",
|
|
103
118
|
"dark-canvas-soft-2": "#262626",
|
|
@@ -109,9 +124,15 @@
|
|
|
109
124
|
"dark-seam": "#1f1f1f",
|
|
110
125
|
"dark-primary": "#ededed",
|
|
111
126
|
"dark-on-primary": "#0a0a0a",
|
|
127
|
+
"dark-action": "#ededed",
|
|
128
|
+
"dark-action-foreground": "#0a0a0a",
|
|
129
|
+
"dark-action-hover": "#d4d4d4",
|
|
130
|
+
"dark-action-active": "#a3a3a3",
|
|
112
131
|
"dark-link": "#9fe6bc",
|
|
113
132
|
"dark-link-deep": "#c3f0d4",
|
|
114
133
|
"dark-link-bg-soft": "#00301a",
|
|
134
|
+
"dark-focus-ring": "#9fe6bc",
|
|
135
|
+
"dark-scrim": "#f5f5f5",
|
|
115
136
|
"dark-error": "#f7b3b5",
|
|
116
137
|
"dark-error-soft": "#4a000e",
|
|
117
138
|
"dark-error-deep": "#fad3d4",
|
|
@@ -135,7 +156,15 @@
|
|
|
135
156
|
"dark-chart-3": "#ffd97d",
|
|
136
157
|
"dark-chart-4": "#f28085",
|
|
137
158
|
"dark-chart-5": "#33d1cb",
|
|
138
|
-
"dark-chart-6": "#9575cd"
|
|
159
|
+
"dark-chart-6": "#9575cd",
|
|
160
|
+
"dark-chart-seq-1": "#4f6ae6",
|
|
161
|
+
"dark-chart-seq-2": "#7d99f2",
|
|
162
|
+
"dark-chart-seq-3": "#a9befa",
|
|
163
|
+
"dark-chart-seq-4": "#cdd9fd",
|
|
164
|
+
"dark-chart-seq-5": "#eef2ff",
|
|
165
|
+
"dark-chart-div-warm": "#ffd97d",
|
|
166
|
+
"dark-chart-div-mid": "#e6e6e6",
|
|
167
|
+
"dark-chart-div-cool": "#cdd9fd"
|
|
139
168
|
},
|
|
140
169
|
"fontFamily": {
|
|
141
170
|
"display-xl": [
|
|
@@ -335,6 +364,8 @@
|
|
|
335
364
|
"md": "6px",
|
|
336
365
|
"lg": "8px",
|
|
337
366
|
"xl": "10px",
|
|
367
|
+
"2xl": "12px",
|
|
368
|
+
"3xl": "16px",
|
|
338
369
|
"pill-sm": "64px",
|
|
339
370
|
"pill": "100px",
|
|
340
371
|
"full": "9999px"
|
|
@@ -354,6 +385,10 @@
|
|
|
354
385
|
"6xl": "128px",
|
|
355
386
|
"section": "192px",
|
|
356
387
|
"guide": "1px",
|
|
388
|
+
"focus-ring-width": "3px",
|
|
389
|
+
"control-height": "32px",
|
|
390
|
+
"control-padding-inline": "10px",
|
|
391
|
+
"touch-target": "44px",
|
|
357
392
|
"page-pad": "24px",
|
|
358
393
|
"page-max-mobile": "448px",
|
|
359
394
|
"page-max-tablet": "624px",
|
|
@@ -10,19 +10,22 @@
|
|
|
10
10
|
--card-foreground: var(--color-ink);
|
|
11
11
|
--popover: var(--color-canvas);
|
|
12
12
|
--popover-foreground: var(--color-ink);
|
|
13
|
-
--primary: var(--color-
|
|
14
|
-
--primary-foreground: var(--color-
|
|
13
|
+
--primary: var(--color-action);
|
|
14
|
+
--primary-foreground: var(--color-action-foreground);
|
|
15
|
+
--primary-hover: var(--color-action-hover);
|
|
16
|
+
--primary-active: var(--color-action-active);
|
|
15
17
|
--secondary: var(--color-canvas-soft);
|
|
16
18
|
--secondary-foreground: var(--color-ink);
|
|
17
19
|
--muted: var(--color-canvas-soft);
|
|
18
|
-
--muted-foreground: var(--color-
|
|
20
|
+
--muted-foreground: var(--color-body);
|
|
19
21
|
--accent: var(--color-canvas-soft-2);
|
|
20
22
|
--accent-foreground: var(--color-ink);
|
|
21
23
|
--destructive: var(--color-error);
|
|
22
24
|
--destructive-foreground: var(--color-on-primary);
|
|
23
25
|
--border: var(--color-line);
|
|
24
|
-
--input: var(--color-
|
|
25
|
-
--ring: var(--color-
|
|
26
|
+
--input: var(--color-nadicode-input);
|
|
27
|
+
--ring: var(--color-focus-ring);
|
|
28
|
+
--scrim: var(--color-nadicode-scrim);
|
|
26
29
|
--chart-1: var(--color-nadicode-chart-1);
|
|
27
30
|
--chart-2: var(--color-nadicode-chart-2);
|
|
28
31
|
--chart-3: var(--color-nadicode-chart-3);
|
|
@@ -35,7 +38,7 @@
|
|
|
35
38
|
--sidebar-accent: var(--color-canvas-soft-2);
|
|
36
39
|
--sidebar-accent-foreground: var(--color-ink);
|
|
37
40
|
--sidebar-border: var(--color-line);
|
|
38
|
-
--sidebar-ring: var(--color-
|
|
41
|
+
--sidebar-ring: var(--color-focus-ring);
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
.dark {
|
|
@@ -46,19 +49,22 @@
|
|
|
46
49
|
--card-foreground: var(--color-dark-ink);
|
|
47
50
|
--popover: var(--color-dark-canvas);
|
|
48
51
|
--popover-foreground: var(--color-dark-ink);
|
|
49
|
-
--primary: var(--color-dark-
|
|
50
|
-
--primary-foreground: var(--color-dark-
|
|
52
|
+
--primary: var(--color-dark-action);
|
|
53
|
+
--primary-foreground: var(--color-dark-action-foreground);
|
|
54
|
+
--primary-hover: var(--color-dark-action-hover);
|
|
55
|
+
--primary-active: var(--color-dark-action-active);
|
|
51
56
|
--secondary: var(--color-dark-canvas-soft);
|
|
52
57
|
--secondary-foreground: var(--color-dark-ink);
|
|
53
58
|
--muted: var(--color-dark-canvas-soft);
|
|
54
|
-
--muted-foreground: var(--color-dark-
|
|
59
|
+
--muted-foreground: var(--color-dark-body);
|
|
55
60
|
--accent: var(--color-dark-canvas-soft-2);
|
|
56
61
|
--accent-foreground: var(--color-dark-ink);
|
|
57
62
|
--destructive: var(--color-dark-error);
|
|
58
63
|
--destructive-foreground: var(--color-dark-on-primary);
|
|
59
64
|
--border: var(--color-dark-line);
|
|
60
65
|
--input: var(--color-dark-input);
|
|
61
|
-
--ring: var(--color-dark-
|
|
66
|
+
--ring: var(--color-dark-focus-ring);
|
|
67
|
+
--scrim: var(--color-dark-scrim);
|
|
62
68
|
--chart-1: var(--color-dark-chart-1);
|
|
63
69
|
--chart-2: var(--color-dark-chart-2);
|
|
64
70
|
--chart-3: var(--color-dark-chart-3);
|
|
@@ -71,10 +77,17 @@
|
|
|
71
77
|
--sidebar-accent: var(--color-dark-canvas-soft-2);
|
|
72
78
|
--sidebar-accent-foreground: var(--color-dark-ink);
|
|
73
79
|
--sidebar-border: var(--color-dark-line);
|
|
74
|
-
--sidebar-ring: var(--color-dark-
|
|
80
|
+
--sidebar-ring: var(--color-dark-focus-ring);
|
|
75
81
|
}
|
|
76
82
|
|
|
77
83
|
:root.dark {
|
|
84
|
+
--nc-action: var(--nc-dark-action);
|
|
85
|
+
--nc-action-foreground: var(--nc-dark-action-foreground);
|
|
86
|
+
--nc-action-hover: var(--nc-dark-action-hover);
|
|
87
|
+
--nc-action-active: var(--nc-dark-action-active);
|
|
88
|
+
--nc-input: var(--nc-dark-input);
|
|
89
|
+
--nc-focus-ring: var(--nc-dark-focus-ring);
|
|
90
|
+
--nc-scrim: var(--nc-dark-scrim);
|
|
78
91
|
--nc-state-ready: var(--nc-dark-state-ready);
|
|
79
92
|
--nc-state-running: var(--nc-dark-state-running);
|
|
80
93
|
--nc-state-review: var(--nc-dark-state-review);
|
|
@@ -89,6 +102,14 @@
|
|
|
89
102
|
--nc-chart-4: var(--nc-dark-chart-4);
|
|
90
103
|
--nc-chart-5: var(--nc-dark-chart-5);
|
|
91
104
|
--nc-chart-6: var(--nc-dark-chart-6);
|
|
105
|
+
--nc-chart-seq-1: var(--nc-dark-chart-seq-1);
|
|
106
|
+
--nc-chart-seq-2: var(--nc-dark-chart-seq-2);
|
|
107
|
+
--nc-chart-seq-3: var(--nc-dark-chart-seq-3);
|
|
108
|
+
--nc-chart-seq-4: var(--nc-dark-chart-seq-4);
|
|
109
|
+
--nc-chart-seq-5: var(--nc-dark-chart-seq-5);
|
|
110
|
+
--nc-chart-div-warm: var(--nc-dark-chart-div-warm);
|
|
111
|
+
--nc-chart-div-mid: var(--nc-dark-chart-div-mid);
|
|
112
|
+
--nc-chart-div-cool: var(--nc-dark-chart-div-cool);
|
|
92
113
|
}
|
|
93
114
|
|
|
94
115
|
:root {
|
|
@@ -106,6 +127,10 @@
|
|
|
106
127
|
--nadicode-spacing-6xl: var(--spacing-nadicode-6xl);
|
|
107
128
|
--nadicode-spacing-section: var(--spacing-nadicode-section);
|
|
108
129
|
--nadicode-spacing-guide: var(--spacing-nadicode-guide);
|
|
130
|
+
--nadicode-spacing-focus-ring-width: var(--spacing-nadicode-focus-ring-width);
|
|
131
|
+
--nadicode-spacing-control-height: var(--spacing-nadicode-control-height);
|
|
132
|
+
--nadicode-spacing-control-padding-inline: var(--spacing-nadicode-control-padding-inline);
|
|
133
|
+
--nadicode-spacing-touch-target: var(--spacing-nadicode-touch-target);
|
|
109
134
|
--nadicode-spacing-page-pad: var(--spacing-nadicode-page-pad);
|
|
110
135
|
--nadicode-spacing-page-max-mobile: var(--spacing-nadicode-page-max-mobile);
|
|
111
136
|
--nadicode-spacing-page-max-tablet: var(--spacing-nadicode-page-max-tablet);
|
|
@@ -158,6 +183,10 @@
|
|
|
158
183
|
@theme {
|
|
159
184
|
--color-primary: #008c45;
|
|
160
185
|
--color-on-primary: #ffffff;
|
|
186
|
+
--color-action: #007a3c;
|
|
187
|
+
--color-action-foreground: #ffffff;
|
|
188
|
+
--color-action-hover: #00602f;
|
|
189
|
+
--color-action-active: #00301a;
|
|
161
190
|
--color-ink: #171717;
|
|
162
191
|
--color-body: #4d4d4d;
|
|
163
192
|
--color-muted: #888888;
|
|
@@ -165,8 +194,11 @@
|
|
|
165
194
|
--color-canvas-soft: #fafafa;
|
|
166
195
|
--color-canvas-soft-2: #f5f5f5;
|
|
167
196
|
--color-line: #e5e5e5;
|
|
197
|
+
--color-input: #8f8f8f;
|
|
168
198
|
--color-seam: #e4e7ec;
|
|
169
199
|
--color-cross: #a1a1a1;
|
|
200
|
+
--color-focus-ring: #007a3c;
|
|
201
|
+
--color-scrim: #171717;
|
|
170
202
|
--color-link: #007a3c;
|
|
171
203
|
--color-link-deep: #00602f;
|
|
172
204
|
--color-link-bg-soft: #d9f6e4;
|
|
@@ -252,6 +284,14 @@
|
|
|
252
284
|
--color-chart-4: #cd212a;
|
|
253
285
|
--color-chart-5: #00838f;
|
|
254
286
|
--color-chart-6: #6f42c1;
|
|
287
|
+
--color-chart-seq-1: #7d99f2;
|
|
288
|
+
--color-chart-seq-2: #4f6ae6;
|
|
289
|
+
--color-chart-seq-3: #2743d8;
|
|
290
|
+
--color-chart-seq-4: #1d33ad;
|
|
291
|
+
--color-chart-seq-5: #16277f;
|
|
292
|
+
--color-chart-div-warm: #d98800;
|
|
293
|
+
--color-chart-div-mid: #8f8f8f;
|
|
294
|
+
--color-chart-div-cool: #7d99f2;
|
|
255
295
|
--color-dark-canvas: #0a0a0a;
|
|
256
296
|
--color-dark-canvas-soft: #171717;
|
|
257
297
|
--color-dark-canvas-soft-2: #262626;
|
|
@@ -263,9 +303,15 @@
|
|
|
263
303
|
--color-dark-seam: #1f1f1f;
|
|
264
304
|
--color-dark-primary: #ededed;
|
|
265
305
|
--color-dark-on-primary: #0a0a0a;
|
|
306
|
+
--color-dark-action: #ededed;
|
|
307
|
+
--color-dark-action-foreground: #0a0a0a;
|
|
308
|
+
--color-dark-action-hover: #d4d4d4;
|
|
309
|
+
--color-dark-action-active: #a3a3a3;
|
|
266
310
|
--color-dark-link: #9fe6bc;
|
|
267
311
|
--color-dark-link-deep: #c3f0d4;
|
|
268
312
|
--color-dark-link-bg-soft: #00301a;
|
|
313
|
+
--color-dark-focus-ring: #9fe6bc;
|
|
314
|
+
--color-dark-scrim: #f5f5f5;
|
|
269
315
|
--color-dark-error: #f7b3b5;
|
|
270
316
|
--color-dark-error-soft: #4a000e;
|
|
271
317
|
--color-dark-error-deep: #fad3d4;
|
|
@@ -290,8 +336,18 @@
|
|
|
290
336
|
--color-dark-chart-4: #f28085;
|
|
291
337
|
--color-dark-chart-5: #33d1cb;
|
|
292
338
|
--color-dark-chart-6: #9575cd;
|
|
339
|
+
--color-dark-chart-seq-1: #4f6ae6;
|
|
340
|
+
--color-dark-chart-seq-2: #7d99f2;
|
|
341
|
+
--color-dark-chart-seq-3: #a9befa;
|
|
342
|
+
--color-dark-chart-seq-4: #cdd9fd;
|
|
343
|
+
--color-dark-chart-seq-5: #eef2ff;
|
|
344
|
+
--color-dark-chart-div-warm: #ffd97d;
|
|
345
|
+
--color-dark-chart-div-mid: #e6e6e6;
|
|
346
|
+
--color-dark-chart-div-cool: #cdd9fd;
|
|
347
|
+
--color-nadicode-input: #8f8f8f;
|
|
293
348
|
--color-nadicode-muted: #888888;
|
|
294
349
|
--color-nadicode-primary: #008c45;
|
|
350
|
+
--color-nadicode-scrim: #171717;
|
|
295
351
|
--color-nadicode-chart-1: #2743d8;
|
|
296
352
|
--color-nadicode-chart-2: #008c45;
|
|
297
353
|
--color-nadicode-chart-3: #f5a623;
|
|
@@ -439,9 +495,17 @@
|
|
|
439
495
|
--radius-md: 6px;
|
|
440
496
|
--radius-lg: 8px;
|
|
441
497
|
--radius-xl: 10px;
|
|
498
|
+
--radius-2xl: 12px;
|
|
499
|
+
--radius-3xl: 16px;
|
|
442
500
|
--radius-pill-sm: 64px;
|
|
443
501
|
--radius-pill: 100px;
|
|
444
502
|
--radius-full: 9999px;
|
|
503
|
+
--ring-width-focus: var(--spacing-nadicode-focus-ring-width);
|
|
504
|
+
--opacity-scrim: var(--nc-material-scrim-opacity);
|
|
505
|
+
--shadow-tooltip: var(--nc-material-shadow-tooltip);
|
|
506
|
+
--shadow-menu: var(--nc-material-shadow-menu);
|
|
507
|
+
--shadow-dialog: var(--nc-material-shadow-dialog);
|
|
508
|
+
--shadow-sheet: var(--nc-material-shadow-sheet);
|
|
445
509
|
--spacing-nadicode-xxs: 4px;
|
|
446
510
|
--spacing-nadicode-filter-chip-gap: 6px;
|
|
447
511
|
--spacing-nadicode-xs: 8px;
|
|
@@ -456,6 +520,10 @@
|
|
|
456
520
|
--spacing-nadicode-6xl: 128px;
|
|
457
521
|
--spacing-nadicode-section: 192px;
|
|
458
522
|
--spacing-nadicode-guide: 1px;
|
|
523
|
+
--spacing-nadicode-focus-ring-width: 3px;
|
|
524
|
+
--spacing-nadicode-control-height: 32px;
|
|
525
|
+
--spacing-nadicode-control-padding-inline: 10px;
|
|
526
|
+
--spacing-nadicode-touch-target: 44px;
|
|
459
527
|
--spacing-nadicode-page-pad: 24px;
|
|
460
528
|
--spacing-nadicode-page-max-mobile: 448px;
|
|
461
529
|
--spacing-nadicode-page-max-tablet: 624px;
|
|
@@ -502,4 +570,7 @@
|
|
|
502
570
|
--spacing-nadicode-h-bento-strip: 20px;
|
|
503
571
|
--spacing-nadicode-filter-chip-height: 28px;
|
|
504
572
|
--spacing-nadicode-filter-chip-icon: 14px;
|
|
573
|
+
--spacing-control-height: var(--spacing-nadicode-control-height);
|
|
574
|
+
--spacing-control-padding-inline: var(--spacing-nadicode-control-padding-inline);
|
|
575
|
+
--spacing-touch-target: var(--spacing-nadicode-touch-target);
|
|
505
576
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://www.designtokens.org/schemas/2025.10/format.json",
|
|
3
|
-
"$description": "Reusable design-system contract for NadicodeAI: engineered page geometry, neutral high-contrast surfaces, AI-agent work artifacts,
|
|
3
|
+
"$description": "Reusable design-system contract for NadicodeAI: engineered page geometry, neutral high-contrast product surfaces, AI-agent work artifacts, strict 12-column/10-column public-page composition, and the package token exports shared by every NadicodeAI interface.",
|
|
4
4
|
"nadicode": {
|
|
5
5
|
"color": {
|
|
6
6
|
"$type": "color",
|
|
@@ -26,6 +26,50 @@
|
|
|
26
26
|
"hex": "#ffffff"
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
|
+
"action": {
|
|
30
|
+
"$value": {
|
|
31
|
+
"colorSpace": "srgb",
|
|
32
|
+
"components": [
|
|
33
|
+
0,
|
|
34
|
+
0.478,
|
|
35
|
+
0.235
|
|
36
|
+
],
|
|
37
|
+
"hex": "#007a3c"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"action-foreground": {
|
|
41
|
+
"$value": {
|
|
42
|
+
"colorSpace": "srgb",
|
|
43
|
+
"components": [
|
|
44
|
+
1,
|
|
45
|
+
1,
|
|
46
|
+
1
|
|
47
|
+
],
|
|
48
|
+
"hex": "#ffffff"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"action-hover": {
|
|
52
|
+
"$value": {
|
|
53
|
+
"colorSpace": "srgb",
|
|
54
|
+
"components": [
|
|
55
|
+
0,
|
|
56
|
+
0.376,
|
|
57
|
+
0.184
|
|
58
|
+
],
|
|
59
|
+
"hex": "#00602f"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"action-active": {
|
|
63
|
+
"$value": {
|
|
64
|
+
"colorSpace": "srgb",
|
|
65
|
+
"components": [
|
|
66
|
+
0,
|
|
67
|
+
0.188,
|
|
68
|
+
0.102
|
|
69
|
+
],
|
|
70
|
+
"hex": "#00301a"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
29
73
|
"ink": {
|
|
30
74
|
"$value": {
|
|
31
75
|
"colorSpace": "srgb",
|
|
@@ -103,6 +147,17 @@
|
|
|
103
147
|
"hex": "#e5e5e5"
|
|
104
148
|
}
|
|
105
149
|
},
|
|
150
|
+
"input": {
|
|
151
|
+
"$value": {
|
|
152
|
+
"colorSpace": "srgb",
|
|
153
|
+
"components": [
|
|
154
|
+
0.561,
|
|
155
|
+
0.561,
|
|
156
|
+
0.561
|
|
157
|
+
],
|
|
158
|
+
"hex": "#8f8f8f"
|
|
159
|
+
}
|
|
160
|
+
},
|
|
106
161
|
"seam": {
|
|
107
162
|
"$value": {
|
|
108
163
|
"colorSpace": "srgb",
|
|
@@ -125,6 +180,28 @@
|
|
|
125
180
|
"hex": "#a1a1a1"
|
|
126
181
|
}
|
|
127
182
|
},
|
|
183
|
+
"focus-ring": {
|
|
184
|
+
"$value": {
|
|
185
|
+
"colorSpace": "srgb",
|
|
186
|
+
"components": [
|
|
187
|
+
0,
|
|
188
|
+
0.478,
|
|
189
|
+
0.235
|
|
190
|
+
],
|
|
191
|
+
"hex": "#007a3c"
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
"scrim": {
|
|
195
|
+
"$value": {
|
|
196
|
+
"colorSpace": "srgb",
|
|
197
|
+
"components": [
|
|
198
|
+
0.09,
|
|
199
|
+
0.09,
|
|
200
|
+
0.09
|
|
201
|
+
],
|
|
202
|
+
"hex": "#171717"
|
|
203
|
+
}
|
|
204
|
+
},
|
|
128
205
|
"link": {
|
|
129
206
|
"$value": {
|
|
130
207
|
"colorSpace": "srgb",
|
|
@@ -1060,6 +1137,94 @@
|
|
|
1060
1137
|
"hex": "#6f42c1"
|
|
1061
1138
|
}
|
|
1062
1139
|
},
|
|
1140
|
+
"chart-seq-1": {
|
|
1141
|
+
"$value": {
|
|
1142
|
+
"colorSpace": "srgb",
|
|
1143
|
+
"components": [
|
|
1144
|
+
0.49,
|
|
1145
|
+
0.6,
|
|
1146
|
+
0.949
|
|
1147
|
+
],
|
|
1148
|
+
"hex": "#7d99f2"
|
|
1149
|
+
}
|
|
1150
|
+
},
|
|
1151
|
+
"chart-seq-2": {
|
|
1152
|
+
"$value": {
|
|
1153
|
+
"colorSpace": "srgb",
|
|
1154
|
+
"components": [
|
|
1155
|
+
0.31,
|
|
1156
|
+
0.416,
|
|
1157
|
+
0.902
|
|
1158
|
+
],
|
|
1159
|
+
"hex": "#4f6ae6"
|
|
1160
|
+
}
|
|
1161
|
+
},
|
|
1162
|
+
"chart-seq-3": {
|
|
1163
|
+
"$value": {
|
|
1164
|
+
"colorSpace": "srgb",
|
|
1165
|
+
"components": [
|
|
1166
|
+
0.153,
|
|
1167
|
+
0.263,
|
|
1168
|
+
0.847
|
|
1169
|
+
],
|
|
1170
|
+
"hex": "#2743d8"
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
"chart-seq-4": {
|
|
1174
|
+
"$value": {
|
|
1175
|
+
"colorSpace": "srgb",
|
|
1176
|
+
"components": [
|
|
1177
|
+
0.114,
|
|
1178
|
+
0.2,
|
|
1179
|
+
0.678
|
|
1180
|
+
],
|
|
1181
|
+
"hex": "#1d33ad"
|
|
1182
|
+
}
|
|
1183
|
+
},
|
|
1184
|
+
"chart-seq-5": {
|
|
1185
|
+
"$value": {
|
|
1186
|
+
"colorSpace": "srgb",
|
|
1187
|
+
"components": [
|
|
1188
|
+
0.086,
|
|
1189
|
+
0.153,
|
|
1190
|
+
0.498
|
|
1191
|
+
],
|
|
1192
|
+
"hex": "#16277f"
|
|
1193
|
+
}
|
|
1194
|
+
},
|
|
1195
|
+
"chart-div-warm": {
|
|
1196
|
+
"$value": {
|
|
1197
|
+
"colorSpace": "srgb",
|
|
1198
|
+
"components": [
|
|
1199
|
+
0.851,
|
|
1200
|
+
0.533,
|
|
1201
|
+
0
|
|
1202
|
+
],
|
|
1203
|
+
"hex": "#d98800"
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1206
|
+
"chart-div-mid": {
|
|
1207
|
+
"$value": {
|
|
1208
|
+
"colorSpace": "srgb",
|
|
1209
|
+
"components": [
|
|
1210
|
+
0.561,
|
|
1211
|
+
0.561,
|
|
1212
|
+
0.561
|
|
1213
|
+
],
|
|
1214
|
+
"hex": "#8f8f8f"
|
|
1215
|
+
}
|
|
1216
|
+
},
|
|
1217
|
+
"chart-div-cool": {
|
|
1218
|
+
"$value": {
|
|
1219
|
+
"colorSpace": "srgb",
|
|
1220
|
+
"components": [
|
|
1221
|
+
0.49,
|
|
1222
|
+
0.6,
|
|
1223
|
+
0.949
|
|
1224
|
+
],
|
|
1225
|
+
"hex": "#7d99f2"
|
|
1226
|
+
}
|
|
1227
|
+
},
|
|
1063
1228
|
"dark-canvas": {
|
|
1064
1229
|
"$value": {
|
|
1065
1230
|
"colorSpace": "srgb",
|
|
@@ -1181,6 +1346,50 @@
|
|
|
1181
1346
|
"hex": "#0a0a0a"
|
|
1182
1347
|
}
|
|
1183
1348
|
},
|
|
1349
|
+
"dark-action": {
|
|
1350
|
+
"$value": {
|
|
1351
|
+
"colorSpace": "srgb",
|
|
1352
|
+
"components": [
|
|
1353
|
+
0.929,
|
|
1354
|
+
0.929,
|
|
1355
|
+
0.929
|
|
1356
|
+
],
|
|
1357
|
+
"hex": "#ededed"
|
|
1358
|
+
}
|
|
1359
|
+
},
|
|
1360
|
+
"dark-action-foreground": {
|
|
1361
|
+
"$value": {
|
|
1362
|
+
"colorSpace": "srgb",
|
|
1363
|
+
"components": [
|
|
1364
|
+
0.039,
|
|
1365
|
+
0.039,
|
|
1366
|
+
0.039
|
|
1367
|
+
],
|
|
1368
|
+
"hex": "#0a0a0a"
|
|
1369
|
+
}
|
|
1370
|
+
},
|
|
1371
|
+
"dark-action-hover": {
|
|
1372
|
+
"$value": {
|
|
1373
|
+
"colorSpace": "srgb",
|
|
1374
|
+
"components": [
|
|
1375
|
+
0.831,
|
|
1376
|
+
0.831,
|
|
1377
|
+
0.831
|
|
1378
|
+
],
|
|
1379
|
+
"hex": "#d4d4d4"
|
|
1380
|
+
}
|
|
1381
|
+
},
|
|
1382
|
+
"dark-action-active": {
|
|
1383
|
+
"$value": {
|
|
1384
|
+
"colorSpace": "srgb",
|
|
1385
|
+
"components": [
|
|
1386
|
+
0.639,
|
|
1387
|
+
0.639,
|
|
1388
|
+
0.639
|
|
1389
|
+
],
|
|
1390
|
+
"hex": "#a3a3a3"
|
|
1391
|
+
}
|
|
1392
|
+
},
|
|
1184
1393
|
"dark-link": {
|
|
1185
1394
|
"$value": {
|
|
1186
1395
|
"colorSpace": "srgb",
|
|
@@ -1214,6 +1423,28 @@
|
|
|
1214
1423
|
"hex": "#00301a"
|
|
1215
1424
|
}
|
|
1216
1425
|
},
|
|
1426
|
+
"dark-focus-ring": {
|
|
1427
|
+
"$value": {
|
|
1428
|
+
"colorSpace": "srgb",
|
|
1429
|
+
"components": [
|
|
1430
|
+
0.624,
|
|
1431
|
+
0.902,
|
|
1432
|
+
0.737
|
|
1433
|
+
],
|
|
1434
|
+
"hex": "#9fe6bc"
|
|
1435
|
+
}
|
|
1436
|
+
},
|
|
1437
|
+
"dark-scrim": {
|
|
1438
|
+
"$value": {
|
|
1439
|
+
"colorSpace": "srgb",
|
|
1440
|
+
"components": [
|
|
1441
|
+
0.961,
|
|
1442
|
+
0.961,
|
|
1443
|
+
0.961
|
|
1444
|
+
],
|
|
1445
|
+
"hex": "#f5f5f5"
|
|
1446
|
+
}
|
|
1447
|
+
},
|
|
1217
1448
|
"dark-error": {
|
|
1218
1449
|
"$value": {
|
|
1219
1450
|
"colorSpace": "srgb",
|
|
@@ -1477,6 +1708,94 @@
|
|
|
1477
1708
|
],
|
|
1478
1709
|
"hex": "#9575cd"
|
|
1479
1710
|
}
|
|
1711
|
+
},
|
|
1712
|
+
"dark-chart-seq-1": {
|
|
1713
|
+
"$value": {
|
|
1714
|
+
"colorSpace": "srgb",
|
|
1715
|
+
"components": [
|
|
1716
|
+
0.31,
|
|
1717
|
+
0.416,
|
|
1718
|
+
0.902
|
|
1719
|
+
],
|
|
1720
|
+
"hex": "#4f6ae6"
|
|
1721
|
+
}
|
|
1722
|
+
},
|
|
1723
|
+
"dark-chart-seq-2": {
|
|
1724
|
+
"$value": {
|
|
1725
|
+
"colorSpace": "srgb",
|
|
1726
|
+
"components": [
|
|
1727
|
+
0.49,
|
|
1728
|
+
0.6,
|
|
1729
|
+
0.949
|
|
1730
|
+
],
|
|
1731
|
+
"hex": "#7d99f2"
|
|
1732
|
+
}
|
|
1733
|
+
},
|
|
1734
|
+
"dark-chart-seq-3": {
|
|
1735
|
+
"$value": {
|
|
1736
|
+
"colorSpace": "srgb",
|
|
1737
|
+
"components": [
|
|
1738
|
+
0.663,
|
|
1739
|
+
0.745,
|
|
1740
|
+
0.98
|
|
1741
|
+
],
|
|
1742
|
+
"hex": "#a9befa"
|
|
1743
|
+
}
|
|
1744
|
+
},
|
|
1745
|
+
"dark-chart-seq-4": {
|
|
1746
|
+
"$value": {
|
|
1747
|
+
"colorSpace": "srgb",
|
|
1748
|
+
"components": [
|
|
1749
|
+
0.804,
|
|
1750
|
+
0.851,
|
|
1751
|
+
0.992
|
|
1752
|
+
],
|
|
1753
|
+
"hex": "#cdd9fd"
|
|
1754
|
+
}
|
|
1755
|
+
},
|
|
1756
|
+
"dark-chart-seq-5": {
|
|
1757
|
+
"$value": {
|
|
1758
|
+
"colorSpace": "srgb",
|
|
1759
|
+
"components": [
|
|
1760
|
+
0.933,
|
|
1761
|
+
0.949,
|
|
1762
|
+
1
|
|
1763
|
+
],
|
|
1764
|
+
"hex": "#eef2ff"
|
|
1765
|
+
}
|
|
1766
|
+
},
|
|
1767
|
+
"dark-chart-div-warm": {
|
|
1768
|
+
"$value": {
|
|
1769
|
+
"colorSpace": "srgb",
|
|
1770
|
+
"components": [
|
|
1771
|
+
1,
|
|
1772
|
+
0.851,
|
|
1773
|
+
0.49
|
|
1774
|
+
],
|
|
1775
|
+
"hex": "#ffd97d"
|
|
1776
|
+
}
|
|
1777
|
+
},
|
|
1778
|
+
"dark-chart-div-mid": {
|
|
1779
|
+
"$value": {
|
|
1780
|
+
"colorSpace": "srgb",
|
|
1781
|
+
"components": [
|
|
1782
|
+
0.902,
|
|
1783
|
+
0.902,
|
|
1784
|
+
0.902
|
|
1785
|
+
],
|
|
1786
|
+
"hex": "#e6e6e6"
|
|
1787
|
+
}
|
|
1788
|
+
},
|
|
1789
|
+
"dark-chart-div-cool": {
|
|
1790
|
+
"$value": {
|
|
1791
|
+
"colorSpace": "srgb",
|
|
1792
|
+
"components": [
|
|
1793
|
+
0.804,
|
|
1794
|
+
0.851,
|
|
1795
|
+
0.992
|
|
1796
|
+
],
|
|
1797
|
+
"hex": "#cdd9fd"
|
|
1798
|
+
}
|
|
1480
1799
|
}
|
|
1481
1800
|
},
|
|
1482
1801
|
"spacing": {
|
|
@@ -1565,6 +1884,30 @@
|
|
|
1565
1884
|
"unit": "px"
|
|
1566
1885
|
}
|
|
1567
1886
|
},
|
|
1887
|
+
"focus-ring-width": {
|
|
1888
|
+
"$value": {
|
|
1889
|
+
"value": 3,
|
|
1890
|
+
"unit": "px"
|
|
1891
|
+
}
|
|
1892
|
+
},
|
|
1893
|
+
"control-height": {
|
|
1894
|
+
"$value": {
|
|
1895
|
+
"value": 32,
|
|
1896
|
+
"unit": "px"
|
|
1897
|
+
}
|
|
1898
|
+
},
|
|
1899
|
+
"control-padding-inline": {
|
|
1900
|
+
"$value": {
|
|
1901
|
+
"value": 10,
|
|
1902
|
+
"unit": "px"
|
|
1903
|
+
}
|
|
1904
|
+
},
|
|
1905
|
+
"touch-target": {
|
|
1906
|
+
"$value": {
|
|
1907
|
+
"value": 44,
|
|
1908
|
+
"unit": "px"
|
|
1909
|
+
}
|
|
1910
|
+
},
|
|
1568
1911
|
"page-pad": {
|
|
1569
1912
|
"$value": {
|
|
1570
1913
|
"value": 24,
|
|
@@ -1880,6 +2223,18 @@
|
|
|
1880
2223
|
"unit": "px"
|
|
1881
2224
|
}
|
|
1882
2225
|
},
|
|
2226
|
+
"2xl": {
|
|
2227
|
+
"$value": {
|
|
2228
|
+
"value": 12,
|
|
2229
|
+
"unit": "px"
|
|
2230
|
+
}
|
|
2231
|
+
},
|
|
2232
|
+
"3xl": {
|
|
2233
|
+
"$value": {
|
|
2234
|
+
"value": 16,
|
|
2235
|
+
"unit": "px"
|
|
2236
|
+
}
|
|
2237
|
+
},
|
|
1883
2238
|
"pill-sm": {
|
|
1884
2239
|
"$value": {
|
|
1885
2240
|
"value": 64,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nadicodeai/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"build": "tsx scripts/build.ts",
|
|
46
46
|
"generate:icons": "tsx scripts/generate-icons.ts",
|
|
47
47
|
"generate:favicons": "tsx scripts/generate-favicons.ts",
|
|
48
|
-
"lint:design": "
|
|
48
|
+
"lint:design": "design.md lint DESIGN.md",
|
|
49
49
|
"test": "vitest run",
|
|
50
50
|
"test:visual": "vitest run --config vitest.visual.config.ts",
|
|
51
51
|
"prepublishOnly": "npm run build"
|