@nadicodeai/design-system 0.12.0 → 0.14.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 CHANGED
@@ -21,6 +21,7 @@ Handoff gate: `npm run lint:design && npm run lint && npm run build && npm run t
21
21
  | Shared design-language terms | `CONTEXT.md` |
22
22
  | Colors, tokens, typography, layout doctrine, seam ownership, component semantics | `DESIGN.md` (read it before stating any of these) |
23
23
  | CSS layers, token pipeline, dark remaps, generated outputs, their guards | `DESIGN.md` "CSS Architecture & Token Pipeline"; decision history in `../docs/adr/` |
24
+ | Motion direction and runtime | `DESIGN.md` "Motion", `src/css/motion.css`, then `../skills/nadicodeai-product-design/references/motion-craft.md` for agent procedure |
24
25
  | Package exports | `package.json` (guard: `tests/guards/build-produces-exports.test.ts`) |
25
26
  | Static or non-React consumption | `README.md` |
26
27
  | React consumption | `../@nadicodeai/ui/docs/consuming-cross-repo.md` |
@@ -40,4 +41,4 @@ Handoff gate: `npm run lint:design && npm run lint && npm run build && npm run t
40
41
  - External references are source-first: read live DOM/CSSOM rules before authoring; screenshots verify, they never author. Map every imported behavior to `DESIGN.md` or an explicit user approval, ask when the contract leaves a decision open, and never import reference mood, polarity, decoration, or animation uninvited. Stop and re-read source before a second visual patch to the same component.
41
42
  - Name everything as NadicodeAI-owned primitives; source brands (Vercel, Attio) appear only in reference notes, never in names, comments, or contracts.
42
43
  - Any change to package-consumed output ends with an explicit release decision, a version bump or a `[no-publish]` commit marker (enforced by the pre-push release gate; procedure: `../docs/internal/npm-publishing.md`).
43
- - The deleted `design-canvas/` prototypes live only in git history. `src/css/motion.css` preserves current runtime transitions and animations, while `src/js/chat-autoplay.js` is the single allowed runtime JS enhancer; never reconstruct the prototypes or add a second runtime JS surface.
44
+ - The deleted `design-canvas/` prototypes live only in git history. `src/css/motion.css` owns shared runtime motion primitives, while `src/js/chat-autoplay.js` is the single allowed runtime JS enhancer; never reconstruct the prototypes or add a second runtime JS surface.
package/DESIGN.md CHANGED
@@ -8,24 +8,24 @@ description: >-
8
8
  shared by every NadicodeAI interface.
9
9
 
10
10
  colors:
11
- primary: "#00a85a"
12
- on-primary: "#0f0e0b"
13
- action: "#00a85a"
14
- action-foreground: "#0f0e0b"
15
- action-hover: "#009d54"
16
- action-active: "#009550"
17
- ink: "#0f0e0b"
18
- body: "#3d3c38"
19
- muted: "#74726b"
11
+ primary: "#007a3c"
12
+ on-primary: "#ffffff"
13
+ action: "#007a3c"
14
+ action-foreground: "#ffffff"
15
+ action-hover: "#00602f"
16
+ action-active: "#00301a"
17
+ ink: "#111111"
18
+ body: "#444444"
19
+ muted: "#6b6b6b"
20
20
  canvas: "#ffffff"
21
- canvas-soft: "#f7f7f4"
22
- canvas-soft-2: "#efefe9"
23
- line: "#e6e6e0"
24
- input: "#74726d"
25
- seam: "#d8d8d0"
26
- cross: "#97958b"
21
+ canvas-soft: "#fafafa"
22
+ canvas-soft-2: "#f5f5f5"
23
+ line: "#e5e5e5"
24
+ input: "#757575"
25
+ seam: "#d4d4d4"
26
+ cross: "#999999"
27
27
  focus-ring: "#00713d"
28
- scrim: "#0f0e0b"
28
+ scrim: "#111111"
29
29
  link: "#00713d"
30
30
  link-deep: "#00522c"
31
31
  link-bg-soft: "#c6efd9"
@@ -41,24 +41,24 @@ colors:
41
41
  warning-soft: "#fff3d1"
42
42
  warning-deep: "#7a5800"
43
43
  flag-red: "#d3302f"
44
- selection-bg: "#0f0e0b"
45
- selection-fg: "#f7f7f4"
44
+ selection-bg: "#111111"
45
+ selection-fg: "#fafafa"
46
46
  navigation-selection-bg: "#1e3cff"
47
47
  navigation-selection-fg: "#ffffff"
48
48
  navigation-selection-hover: "#1735df"
49
- state-ready: "#74726b"
49
+ state-ready: "#6b6b6b"
50
50
  state-running: "#1e3cff"
51
51
  state-review: "#ffc220"
52
52
  state-blocked: "#d3302f"
53
53
  state-complete: "#00a85a"
54
54
  background-100: "#ffffff"
55
- background-200: "#f7f7f4"
55
+ background-200: "#fafafa"
56
56
  campo-verde: "#00a85a"
57
57
  campo-rosso: "#d3302f"
58
58
  campo-arancio: "#ff5a1f"
59
59
  campo-giallo: "#ffc220"
60
60
  campo-cobalto: "#1e3cff"
61
- campo-inchiostro: "#0f0e0b"
61
+ campo-inchiostro: "#111111"
62
62
  campo-bianco: "#ffffff"
63
63
  chart-1: "#1e3cff"
64
64
  chart-2: "#00a85a"
@@ -72,28 +72,28 @@ colors:
72
72
  chart-seq-4: "#1d33ad"
73
73
  chart-seq-5: "#16277f"
74
74
  chart-div-warm: "#e0a600"
75
- chart-div-mid: "#74726b"
75
+ chart-div-mid: "#6b6b6b"
76
76
  chart-div-cool: "#4d6bff"
77
- dark-canvas: "#0f0f0d"
78
- dark-canvas-soft: "#171714"
79
- dark-canvas-soft-2: "#20201b"
80
- dark-ink: "#f2f2ee"
81
- dark-body: "#cac9c3"
82
- dark-muted: "#8f8d84"
83
- dark-line: "#2a2a26"
84
- dark-input: "#696863"
85
- dark-seam: "#20201b"
77
+ dark-canvas: "#0a0a0a"
78
+ dark-canvas-soft: "#111111"
79
+ dark-canvas-soft-2: "#1a1a1a"
80
+ dark-ink: "#ededed"
81
+ dark-body: "#c7c7c7"
82
+ dark-muted: "#8f8f8f"
83
+ dark-line: "#262626"
84
+ dark-input: "#696969"
85
+ dark-seam: "#1a1a1a"
86
86
  dark-primary: "#2fd584"
87
- dark-on-primary: "#0f0f0d"
87
+ dark-on-primary: "#0a0a0a"
88
88
  dark-action: "#2fd584"
89
- dark-action-foreground: "#0f0f0d"
89
+ dark-action-foreground: "#0a0a0a"
90
90
  dark-action-hover: "#4ecf8c"
91
91
  dark-action-active: "#17bd68"
92
92
  dark-link: "#4ecf8c"
93
93
  dark-link-deep: "#93e3b8"
94
94
  dark-link-bg-soft: "#00351c"
95
95
  dark-focus-ring: "#4ecf8c"
96
- dark-scrim: "#f2f2ee"
96
+ dark-scrim: "#ededed"
97
97
  dark-error: "#f5a3a1"
98
98
  dark-error-soft: "#380a09"
99
99
  dark-error-deep: "#fbcccb"
@@ -107,17 +107,17 @@ colors:
107
107
  dark-cyan-soft: "#7ee8de"
108
108
  dark-cyan-deep: "#1f9e9a"
109
109
  dark-success: "#17bd68"
110
- dark-state-ready: "#74726b"
110
+ dark-state-ready: "#757575"
111
111
  dark-state-running: "#4d6bff"
112
112
  dark-state-review: "#ffc220"
113
113
  dark-state-blocked: "#d3302f"
114
114
  dark-state-complete: "#00a85a"
115
- dark-selection-bg: "#f2f2ee"
116
- dark-selection-fg: "#0f0f0d"
115
+ dark-selection-bg: "#ededed"
116
+ dark-selection-fg: "#0a0a0a"
117
117
  dark-navigation-selection-bg: "#2743d8"
118
- dark-navigation-selection-fg: "#f2f2ee"
118
+ dark-navigation-selection-fg: "#ededed"
119
119
  dark-navigation-selection-hover: "#3552e6"
120
- dark-cross: "#565349"
120
+ dark-cross: "#555555"
121
121
  dark-chart-1: "#4d6bff"
122
122
  dark-chart-2: "#00a85a"
123
123
  dark-chart-3: "#ffd866"
@@ -130,7 +130,7 @@ colors:
130
130
  dark-chart-seq-4: "#cdd9fd"
131
131
  dark-chart-seq-5: "#eef2ff"
132
132
  dark-chart-div-warm: "#ffd866"
133
- dark-chart-div-mid: "#e6e6e0"
133
+ dark-chart-div-mid: "#e5e5e5"
134
134
  dark-chart-div-cool: "#b3c1ff"
135
135
 
136
136
  typography:
@@ -337,12 +337,12 @@ The kernel is the reusable implementation layer. `DESIGN.md` defines the reusabl
337
337
 
338
338
  The colour system is two families that never mix. The **functional tier** — the semantic role tokens plus the chart series — drives every product and interface state. The **brand tier** — the campi — paints marketing and identity surfaces only. A functional role is never a poster field, and a campo is never a UI state.
339
339
 
340
- Every value a role needs is carried by the role token itself; there are no ten-step scale families to reference. Two neutral page grounds sit under the roles below: `{colors.background-100}` (page default, white) and `{colors.background-200}` (soft, used sparingly). The neutral spine — `{colors.ink}`, `{colors.body}`, `{colors.muted}`, `{colors.canvas}`, `{colors.canvas-soft}`, `{colors.canvas-soft-2}`, `{colors.line}`, `{colors.seam}` — is warm and low-chroma (OKLCH chroma 0.01), not equal-channel gray, so surfaces read as paper rather than cold screen while staying achromatic enough that no hue paints an app surface. Colours are authored as sRGB hex here and emitted as `oklch()` in the generated CSS.
340
+ Every value a role needs is carried by the role token itself; there are no ten-step scale families to reference. Two neutral page grounds sit under the roles below: `{colors.background-100}` (page default, white) and `{colors.background-200}` (soft, used sparingly). The neutral spine — `{colors.ink}`, `{colors.body}`, `{colors.muted}`, `{colors.canvas}`, `{colors.canvas-soft}`, `{colors.canvas-soft-2}`, `{colors.line}`, `{colors.seam}` — is strictly achromatic: every neutral is an equal-channel gray (OKLCH chroma 0) in both themes. The five campi are cross-spectrum equals, so any neutral bias would flatter one field and dirty another; hue arrives full-strength through the chromatic roles or not at all, and no tint ever paints an app surface. Colours are authored as sRGB hex here and emitted as `oklch()` in the generated CSS.
341
341
 
342
342
  ### Semantic roles (functional tier)
343
343
 
344
- - **Primary brand anchor** (`{colors.primary}` = verde `#00a85a`): identity marks and brand accents. Text on the verde field is ink (`{colors.on-primary}`), never white normal-size white does not clear AA on the brighter verde, ink clears it comfortably.
345
- - **Action** (`{colors.action}` = verde, `{colors.action-foreground}` = ink, `{colors.action-hover}`, `{colors.action-active}`): the primary-control family — an ink label on the verde field. The shadcn `primary` roles map here. Dark mode uses the `dark-action-*` roles, a brightened verde that clears the dark canvas, still ink-labelled.
344
+ - **Primary brand anchor** (`{colors.primary}` = deep verde `#007a3c`): identity marks and brand accents in UI. Text on the deep verde field is white (`{colors.on-primary}`), which clears AA comfortably at this depth; the brighter campo verde `#00a85a` stays the imagery-tier anchor and never carries normal-size white text.
345
+ - **Action** (`{colors.action}` = deep verde, `{colors.action-foreground}` = white, `{colors.action-hover}`, `{colors.action-active}`): the primary-control family — a white label on the deep verde field, hover and active stepping darker. The shadcn `primary` roles map here. Dark mode uses the `dark-action-*` roles, a brightened verde that clears the dark canvas and carries a near-black label.
346
346
  - **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 resting-control boundary, the stronger mark/crosshair gray, and the dashed connector guide. `{colors.line}` owns ordinary seams and is deliberately quiet — a decorative hairline, not held to a non-text contrast floor. `{colors.input}` owns fields and other interactive boundaries and clears the 3:1 non-text floor against its canvas. Never darken a decorative border locally to make it behave like a control.
347
347
  - **Body / Muted** (`{colors.body}`, `{colors.muted}`): `{colors.body}` is readable supporting copy and clears AA on canvas; `{colors.muted}` is restricted to disabled, inactive, and placeholder content. Do not use muted text for ordinary descriptions, labels, or help text.
348
348
  - **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 floor against the adjacent canvas.
@@ -566,6 +566,10 @@ Corners are restrained and assigned by material role.
566
566
 
567
567
  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.
568
568
 
569
+ ## Motion
570
+
571
+ Motion clarifies state, feedback, hierarchy, or continuity; it does not decorate routine work. Repeated interactions stay fast and quiet, while rare explanatory moments may be more expressive. Motion preserves meaning when movement is reduced.
572
+
569
573
  ## Components
570
574
 
571
575
  This section is the semantic catalog for framework-agnostic components. Exact reusable values stay in the token maps above; CSS owns component composition. Page grammar and composition semantics live in `## Layout`, while React components and reusable sections live in `@nadicodeai/ui`.
@@ -1,6 +1,6 @@
1
1
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160" role="img" aria-label="NadicodeAI mark">
2
2
  <clipPath id="mark-overlap"><rect x="58" y="84" width="26" height="26"/></clipPath>
3
3
  <rect fill="none" stroke="currentColor" stroke-width="10" x="42" y="50" width="46" height="46" rx="13"/>
4
- <rect fill="none" stroke="var(--nc-primary, #00a85a)" stroke-width="10" x="72" y="64" width="46" height="46" rx="13"/>
4
+ <rect fill="none" stroke="var(--nc-primary, #007a3c)" stroke-width="10" x="72" y="64" width="46" height="46" rx="13"/>
5
5
  <rect fill="none" stroke="currentColor" stroke-width="10" x="42" y="50" width="46" height="46" rx="13" clip-path="url(#mark-overlap)"/>
6
6
  </svg>
@@ -1,4 +1,4 @@
1
1
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 100" role="img" aria-label="NadicodeAI wordmark">
2
2
  <g fill="currentColor" transform="translate(0 76) scale(0.06 -0.06)"><path transform="translate(0 0)" d="M74 0L74 710L242 710L524 220L524 710L676 710L676 0L506 0L226 473L226 0Z"/><path transform="translate(706.867 0)" d="M225 -12Q142 -12 89.5 26.5Q37 65 37 134Q37 205 81.5 243.5Q126 282 213 300L386 334Q386 386 362.5 412.5Q339 439 295 439Q252 439 228 419.5Q204 400 197 362L46 369Q61 457 125.5 502.5Q190 548 295 548Q415 548 475.5 491Q536 434 536 324L536 141Q536 118 543.5 110.5Q551 103 566 103L581 103L581 0Q574 -2 558.5 -4Q543 -6 528 -6Q496 -6 468.5 5Q441 16 424 42.5Q407 69 407 118L420 108Q410 72 384.5 45Q359 18 318.5 3Q278 -12 225 -12ZM261 91Q298 91 326 105.5Q354 120 370 148Q386 176 386 214L386 240L264 214Q228 207 209.5 190.5Q191 174 191 148Q191 121 209 106Q227 91 261 91Z"/><path transform="translate(1258.133 0)" d="M257 -12Q189 -12 139.5 22.5Q90 57 63.5 119.5Q37 182 37 268Q37 354 64 416.5Q91 479 140.5 513.5Q190 548 257 548Q314 548 355.5 524.5Q397 501 418 460L418 710L568 710L568 0L425 0L422 79Q400 36 356.5 12Q313 -12 257 -12ZM306 103Q342 103 367 122Q392 141 405 177.5Q418 214 418 268Q418 323 405 359.5Q392 396 367 414.5Q342 433 306 433Q253 433 222 388.5Q191 344 191 268Q191 193 222.5 148Q254 103 306 103Z"/><path transform="translate(1844.8 0)" d="M66 0L66 536L216 536L216 0ZM63 602L63 722L218 722L218 602Z"/><path transform="translate(2082.667 0)" d="M309 -12Q227 -12 166 22.5Q105 57 71 120Q37 183 37 268Q37 353 71 415.5Q105 478 166 513Q227 548 309 548Q380 548 436.5 523Q493 498 528 451Q563 404 571 338L416 331Q409 381 380.5 406.5Q352 432 309 432Q253 432 222 389Q191 346 191 268Q191 190 222 146.5Q253 103 309 103Q352 103 381 129.5Q410 156 416 210L571 204Q564 138 529.5 89.5Q495 41 438.5 14.5Q382 -12 309 -12Z"/><path transform="translate(2636.933 0)" d="M309 -12Q227 -12 166 22.5Q105 57 71 120Q37 183 37 268Q37 353 71 415.5Q105 478 166 513Q227 548 309 548Q391 548 452 513Q513 478 547 415.5Q581 353 581 268Q581 183 547 120Q513 57 452 22.5Q391 -12 309 -12ZM309 103Q365 103 396 146.5Q427 190 427 268Q427 346 396 389.5Q365 433 309 433Q253 433 222 389.5Q191 346 191 268Q191 190 222 146.5Q253 103 309 103Z"/><path transform="translate(3211.6 0)" d="M257 -12Q189 -12 139.5 22.5Q90 57 63.5 119.5Q37 182 37 268Q37 354 64 416.5Q91 479 140.5 513.5Q190 548 257 548Q314 548 355.5 524.5Q397 501 418 460L418 710L568 710L568 0L425 0L422 79Q400 36 356.5 12Q313 -12 257 -12ZM306 103Q342 103 367 122Q392 141 405 177.5Q418 214 418 268Q418 323 405 359.5Q392 396 367 414.5Q342 433 306 433Q253 433 222 388.5Q191 344 191 268Q191 193 222.5 148Q254 103 306 103Z"/><path transform="translate(3802.267 0)" d="M307 -12Q225 -12 164.5 22.5Q104 57 70.5 120Q37 183 37 268Q37 353 70.5 415.5Q104 478 164 513Q224 548 306 548Q386 548 445 513Q504 478 536.5 413Q569 348 569 258L569 228L192 228Q195 164 226.5 133Q258 102 310 102Q348 102 373.5 118Q399 134 410 167L561 158Q540 78 472 33Q404 -12 307 -12ZM192 320L415 320Q412 379 382.5 408Q353 437 306 437Q259 437 228.5 406.5Q198 376 192 320Z"/></g>
3
- <g fill="var(--nc-primary, #00a85a)" transform="translate(259 76) scale(0.06 -0.06)"><path transform="translate(0 0)" d="M19 0L275 710L455 710L711 0L553 0L501 151L228 151L176 0ZM271 276L459 276L365 550Z"/><path transform="translate(670.467 0)" d="M74 0L74 710L226 710L226 0Z"/></g>
3
+ <g fill="var(--nc-primary, #007a3c)" transform="translate(259 76) scale(0.06 -0.06)"><path transform="translate(0 0)" d="M19 0L275 710L455 710L711 0L553 0L501 151L228 151L176 0ZM271 276L459 276L365 550Z"/><path transform="translate(670.467 0)" d="M74 0L74 710L226 710L226 0Z"/></g>
4
4
  </svg>
@@ -398,8 +398,8 @@
398
398
  if (thread.__ncAutoplayPlayer) return thread.__ncAutoplayPlayer;
399
399
  var player = new ChatThreadPlayer(thread);
400
400
  // Read the stagger token off the live thread (parity with motion.css);
401
- // fallback equals the motion.css default (160ms) if the bundle is absent.
402
- player.staggerMs = durationToken(thread, "--nc-duration-stagger", 160);
401
+ // fallback equals the motion.css default (60ms) if the bundle is absent.
402
+ player.staggerMs = durationToken(thread, "--nc-duration-stagger", 60);
403
403
  thread.__ncAutoplayPlayer = player;
404
404
  players.push(player);
405
405
  // Inject the pause/resume button unless reduced-motion is on (that path