@nadicodeai/ui 0.1.1 → 0.3.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.
Files changed (91) hide show
  1. package/AGENTS.md +9 -4
  2. package/README.md +41 -7
  3. package/dist/components/action-band.d.ts.map +1 -1
  4. package/dist/components/action-band.js +2 -1
  5. package/dist/components/agent-message.d.ts +2 -1
  6. package/dist/components/agent-message.d.ts.map +1 -1
  7. package/dist/components/agent-message.js +14 -21
  8. package/dist/components/agent-thread.d.ts.map +1 -1
  9. package/dist/components/agent-thread.js +3 -10
  10. package/dist/components/ai-elements/code-block.d.ts +8 -1
  11. package/dist/components/ai-elements/code-block.d.ts.map +1 -1
  12. package/dist/components/ai-elements/code-block.js +77 -19
  13. package/dist/components/ai-elements/model-selector.d.ts +1 -1
  14. package/dist/components/ai-elements/model-selector.d.ts.map +1 -1
  15. package/dist/components/ai-elements/open-in-chat.d.ts +0 -2
  16. package/dist/components/ai-elements/open-in-chat.d.ts.map +1 -1
  17. package/dist/components/ai-elements/open-in-chat.js +7 -29
  18. package/dist/components/alert-dialog.js +1 -1
  19. package/dist/components/alert.js +1 -1
  20. package/dist/components/automation-section.d.ts.map +1 -1
  21. package/dist/components/automation-section.js +38 -43
  22. package/dist/components/benefits-bento.js +1 -1
  23. package/dist/components/bento.d.ts +2 -2
  24. package/dist/components/bento.d.ts.map +1 -1
  25. package/dist/components/bento.js +4 -3
  26. package/dist/components/button.js +5 -5
  27. package/dist/components/card.js +1 -1
  28. package/dist/components/chart.d.ts +5 -1
  29. package/dist/components/chart.d.ts.map +1 -1
  30. package/dist/components/chart.js +23 -4
  31. package/dist/components/demo-surface.d.ts +10 -2
  32. package/dist/components/demo-surface.d.ts.map +1 -1
  33. package/dist/components/demo-surface.js +9 -2
  34. package/dist/components/dialog.js +1 -1
  35. package/dist/components/faq.d.ts +6 -5
  36. package/dist/components/faq.d.ts.map +1 -1
  37. package/dist/components/faq.js +8 -6
  38. package/dist/components/files-preview.d.ts.map +1 -1
  39. package/dist/components/files-preview.js +8 -17
  40. package/dist/components/hero-split.d.ts.map +1 -1
  41. package/dist/components/hero-split.js +3 -2
  42. package/dist/components/input.js +1 -1
  43. package/dist/components/installer-shell.d.ts.map +1 -1
  44. package/dist/components/installer-shell.js +9 -12
  45. package/dist/components/logo-band.d.ts.map +1 -1
  46. package/dist/components/logo-band.js +2 -3
  47. package/dist/components/pricing.d.ts.map +1 -1
  48. package/dist/components/pricing.js +5 -3
  49. package/dist/components/seam-grid.d.ts +30 -0
  50. package/dist/components/seam-grid.d.ts.map +1 -0
  51. package/dist/components/seam-grid.js +30 -0
  52. package/dist/components/section-intro.js +1 -1
  53. package/dist/components/select.js +1 -1
  54. package/dist/components/shift-band.d.ts.map +1 -1
  55. package/dist/components/shift-band.js +2 -1
  56. package/dist/components/sonner.d.ts +1 -1
  57. package/dist/components/sonner.d.ts.map +1 -1
  58. package/dist/components/sonner.js +2 -2
  59. package/dist/components/state-notice.d.ts +13 -0
  60. package/dist/components/state-notice.d.ts.map +1 -0
  61. package/dist/components/state-notice.js +8 -0
  62. package/dist/components/stats-band.d.ts.map +1 -1
  63. package/dist/components/stats-band.js +4 -5
  64. package/dist/components/testimonials.d.ts.map +1 -1
  65. package/dist/components/testimonials.js +3 -4
  66. package/dist/components/textarea.js +1 -1
  67. package/dist/components/theme-mode-switcher.d.ts +17 -0
  68. package/dist/components/theme-mode-switcher.d.ts.map +1 -0
  69. package/dist/components/theme-mode-switcher.js +24 -0
  70. package/dist/components/use-case-bento.d.ts +4 -2
  71. package/dist/components/use-case-bento.d.ts.map +1 -1
  72. package/dist/components/use-case-bento.js +3 -3
  73. package/dist/components/watch-it-work-band.d.ts +3 -2
  74. package/dist/components/watch-it-work-band.d.ts.map +1 -1
  75. package/dist/components/watch-it-work-band.js +4 -4
  76. package/dist/index.d.ts +3 -0
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +3 -0
  79. package/dist/lib/agent-work-state.d.ts +36 -0
  80. package/dist/lib/agent-work-state.d.ts.map +1 -0
  81. package/dist/lib/agent-work-state.js +36 -0
  82. package/dist/lib/seam.d.ts +29 -0
  83. package/dist/lib/seam.d.ts.map +1 -0
  84. package/dist/lib/seam.js +30 -0
  85. package/dist/lib/theme-mode.d.ts +4 -0
  86. package/dist/lib/theme-mode.d.ts.map +1 -0
  87. package/dist/lib/theme-mode.js +4 -0
  88. package/dist/styles/globals.css +131 -117
  89. package/docs/agents/nadicodeai-ui.md +22 -0
  90. package/package.json +9 -3
  91. package/skills/nadicodeai-ui/SKILL.md +2 -1
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Internal seam for the `AgentWorkState` presentation contract.
3
+ *
4
+ * This module is the ONE place a work state's icon, ARIA `role`, and
5
+ * busy/motion signal are decided. Every caller (`agent-message.tsx`,
6
+ * `agent-thread.tsx`, `state-notice.tsx`) reads `statePresentation` instead
7
+ * of keeping its own copy of the icon table or the role/busy rule, so a
8
+ * future state's presentation rule has exactly one place to be added or
9
+ * fixed.
10
+ *
11
+ * This is NOT part of the public package surface. It has no `exports`
12
+ * subpath, matching `agent-attachment.ts` and `seam.ts` in this directory.
13
+ *
14
+ * Dependency direction is one-way: components import this module; this
15
+ * module never imports a component (no cycle).
16
+ */
17
+ import { AlertTriangleIcon, ClockIcon, FileWarningIcon, LoaderCircleIcon, RefreshCwIcon, ShieldXIcon, } from "lucide-react";
18
+ const presentationByState = {
19
+ fatal: { busy: false, icon: FileWarningIcon, role: "alert" },
20
+ interrupted: { busy: false, icon: AlertTriangleIcon, role: "status" },
21
+ "permission-denied": { busy: false, icon: ShieldXIcon, role: "alert" },
22
+ queued: { busy: false, icon: ClockIcon, role: "status" },
23
+ retryable: { busy: false, icon: RefreshCwIcon, role: "status" },
24
+ streaming: { busy: true, icon: LoaderCircleIcon, role: "status" },
25
+ };
26
+ /**
27
+ * statePresentation is the single source of truth for a presentable
28
+ * `AgentWorkState`'s icon, ARIA `role`, and busy/motion signal. Icon values
29
+ * reproduce `agent-message.tsx`'s `stateMeta` and `agent-thread.tsx`'s
30
+ * `threadStateDefaults` (confirmed byte-identical icon-for-icon); `role`
31
+ * and `busy` reproduce `state-notice.tsx`'s inline rules verbatim.
32
+ */
33
+ function statePresentation(state) {
34
+ return presentationByState[state];
35
+ }
36
+ export { statePresentation };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Internal seam helper for the "gap-as-seam" grid mechanics.
3
+ *
4
+ * This module is the ONE place the ink seam `color-mix(...)` string lives, so a
5
+ * typo can no longer silently break one band's seam while the others stay
6
+ * correct. `SeamGrid` (the public primitive) and the `logo-band` grid owner both
7
+ * derive their seam colour from `seamSurfaceClass` here.
8
+ *
9
+ * SINGLE-OWNER SEAM: a `grid` with `gap-px` lets the panel paint one hairline at
10
+ * every cell boundary while borderless, square-cornered cells fill on top, so no
11
+ * coordinate ever carries two lines. The seam COLOUR is the only thing that flips
12
+ * with `surface`: canvas paints the brand `line` via `bg-border`; ink mixes the
13
+ * line toward the ink role so the seam stays a seam and never changes weight.
14
+ * Token-only; no `dark:` styling.
15
+ *
16
+ * This is NOT part of the public package surface. It has no `exports` subpath, so
17
+ * consumers couple to the `SeamGrid` component contract rather than to the exact
18
+ * arbitrary Tailwind class string. Keep it that way.
19
+ */
20
+ type SeamSurface = "canvas" | "ink";
21
+ /**
22
+ * seamSurfaceClass is the single source for the seam colour class. Internal code
23
+ * reaches for this (or `SeamGrid`, which wraps it) instead of hand-copying the ink
24
+ * `color-mix(...)` string into another grid owner.
25
+ */
26
+ declare function seamSurfaceClass(surface: SeamSurface): string;
27
+ export { seamSurfaceClass };
28
+ export type { SeamSurface };
29
+ //# sourceMappingURL=seam.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seam.d.ts","sourceRoot":"","sources":["../../src/lib/seam.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,KAAK,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAA;AAEnC;;;;GAIG;AACH,iBAAS,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAItD;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAA;AAC3B,YAAY,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Internal seam helper for the "gap-as-seam" grid mechanics.
3
+ *
4
+ * This module is the ONE place the ink seam `color-mix(...)` string lives, so a
5
+ * typo can no longer silently break one band's seam while the others stay
6
+ * correct. `SeamGrid` (the public primitive) and the `logo-band` grid owner both
7
+ * derive their seam colour from `seamSurfaceClass` here.
8
+ *
9
+ * SINGLE-OWNER SEAM: a `grid` with `gap-px` lets the panel paint one hairline at
10
+ * every cell boundary while borderless, square-cornered cells fill on top, so no
11
+ * coordinate ever carries two lines. The seam COLOUR is the only thing that flips
12
+ * with `surface`: canvas paints the brand `line` via `bg-border`; ink mixes the
13
+ * line toward the ink role so the seam stays a seam and never changes weight.
14
+ * Token-only; no `dark:` styling.
15
+ *
16
+ * This is NOT part of the public package surface. It has no `exports` subpath, so
17
+ * consumers couple to the `SeamGrid` component contract rather than to the exact
18
+ * arbitrary Tailwind class string. Keep it that way.
19
+ */
20
+ /**
21
+ * seamSurfaceClass is the single source for the seam colour class. Internal code
22
+ * reaches for this (or `SeamGrid`, which wraps it) instead of hand-copying the ink
23
+ * `color-mix(...)` string into another grid owner.
24
+ */
25
+ function seamSurfaceClass(surface) {
26
+ return surface === "ink"
27
+ ? "bg-[color-mix(in_srgb,var(--nc-line)_40%,var(--nc-ink))]"
28
+ : "bg-border";
29
+ }
30
+ export { seamSurfaceClass };
@@ -0,0 +1,4 @@
1
+ export declare const themeModes: readonly ["light", "dark", "system"];
2
+ export type ThemeMode = (typeof themeModes)[number];
3
+ export declare function isThemeMode(value: string | undefined): value is ThemeMode;
4
+ //# sourceMappingURL=theme-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-mode.d.ts","sourceRoot":"","sources":["../../src/lib/theme-mode.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,sCAAuC,CAAA;AAE9D,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,SAAS,CAEzE"}
@@ -0,0 +1,4 @@
1
+ export const themeModes = ["light", "dark", "system"];
2
+ export function isThemeMode(value) {
3
+ return typeof value === "string" && themeModes.includes(value);
4
+ }
@@ -1,20 +1,18 @@
1
1
  /*
2
2
  * @nadicodeai/ui — Tailwind v4 + shadcn entry stylesheet.
3
3
  *
4
- * Import order is load-bearing: Tailwind first, then the design-system token
5
- * bridge (the brand @theme + the :root shadcn role map, generated from
6
- * DESIGN.md by Style Dictionary — ADR 0006). The @theme inline block below
4
+ * Import order is load-bearing: Tailwind first, then the design-system theme
5
+ * bridge (the brand @theme + the :root/.dark shadcn role maps, generated from
6
+ * DESIGN.md by Style Dictionary). The @theme inline block below
7
7
  * lifts semantic role vars into Tailwind's --color-* utility namespace so
8
8
  * shadcn utilities (bg-background, text-foreground, border-border, …) resolve
9
9
  * to brand tokens.
10
10
  *
11
- * Dark readiness is selector remapping only: :root and .dark assign shadcn
12
- * roles and package-local product aliases from generated --nc-* tokens or from
13
- * semantic roles. Product aliases intentionally live here, not in DESIGN.md:
14
- * their --nc-* names are package-local declarations, while source tokens remain
15
- * the generated --nc-* declarations imported above. Components consume those
16
- * roles/aliases and do not carry raw palette utilities or dark: utility classes.
17
- * DESIGN.md remains the only source of literal values.
11
+ * Standard shadcn roles are generated by @nadicodeai/design-system. This file
12
+ * keeps package-local product aliases only; their --nc-* names are package-local
13
+ * declarations, while source values remain generated tokens or semantic roles.
14
+ * Components consume those roles/aliases and do not carry raw palette utilities
15
+ * or dark: utility classes. DESIGN.md remains the only source of literal values.
18
16
  */
19
17
  @import "tailwindcss";
20
18
  @import "@nadicodeai/design-system/tailwind/theme.css";
@@ -22,9 +20,10 @@
22
20
  @import "@xyflow/react/dist/style.css";
23
21
 
24
22
  /*
25
- * Tailwind v4's dark: variant defaults to an OS media query. Keep it class
26
- * gated so a consuming app must opt in with a .dark ancestor. Shared components
27
- * still do not ship dark: utilities; the semantic remap below carries dark mode.
23
+ * Tailwind v4's dark: variant defaults to an OS media query. Match shadcn's
24
+ * class strategy so apps can drive light/dark/system from the root `.dark`
25
+ * class, usually through next-themes. Shared components still do not ship
26
+ * dark: color utilities; semantic role remaps carry dark mode.
28
27
  */
29
28
  @custom-variant dark (&:where(.dark, .dark *));
30
29
 
@@ -74,40 +73,6 @@
74
73
  }
75
74
 
76
75
  :root {
77
- --radius: var(--nc-rounded-md);
78
- --background: var(--nc-canvas);
79
- --foreground: var(--nc-ink);
80
- --card: var(--nc-canvas);
81
- --card-foreground: var(--nc-ink);
82
- --popover: var(--nc-canvas);
83
- --popover-foreground: var(--nc-ink);
84
- --primary: var(--nc-primary);
85
- --primary-foreground: var(--nc-on-primary);
86
- --secondary: var(--nc-canvas-soft);
87
- --secondary-foreground: var(--nc-ink);
88
- --muted: var(--nc-canvas-soft);
89
- --muted-foreground: var(--nc-muted);
90
- --accent: var(--nc-canvas-soft-2);
91
- --accent-foreground: var(--nc-ink);
92
- --destructive: var(--nc-error);
93
- --destructive-foreground: var(--nc-on-primary);
94
- --border: var(--nc-line);
95
- --input: var(--nc-line);
96
- --ring: var(--nc-link);
97
- --chart-1: var(--nc-link);
98
- --chart-2: var(--nc-cyan);
99
- --chart-3: var(--nc-flag-red);
100
- --chart-4: var(--nc-gradient-ship-end);
101
- --chart-5: var(--nc-error);
102
- --sidebar: var(--nc-canvas-soft);
103
- --sidebar-foreground: var(--nc-ink);
104
- --sidebar-primary: var(--nc-primary);
105
- --sidebar-primary-foreground: var(--nc-on-primary);
106
- --sidebar-accent: var(--nc-canvas-soft-2);
107
- --sidebar-accent-foreground: var(--nc-ink);
108
- --sidebar-border: var(--nc-line);
109
- --sidebar-ring: var(--nc-link);
110
-
111
76
  --nc-app-surface: var(--background);
112
77
  --nc-app-surface-chrome: var(--sidebar);
113
78
  --nc-app-surface-sidebar: var(--sidebar);
@@ -137,7 +102,7 @@
137
102
  --nc-chat-artifact-surface: var(--popover);
138
103
  --nc-chat-inline-ref-surface: var(--nc-link-bg-soft);
139
104
  --nc-chat-directive-command: var(--nc-link);
140
- --nc-chat-directive-skill: var(--nc-cyan-deep);
105
+ --nc-chat-directive-skill: var(--nc-info);
141
106
  --nc-chat-directive-theme: var(--nc-flag-red);
142
107
  --nc-composer-surface: var(--popover);
143
108
  --nc-composer-foreground: var(--popover-foreground);
@@ -174,15 +139,18 @@
174
139
  --nc-diff-file-header: var(--muted-foreground);
175
140
  --nc-code-surface: var(--nc-ink);
176
141
  --nc-code-border: var(--nc-body);
177
- --nc-code-token-keyword: var(--nc-cyan);
142
+ /* cyan family retired per Italia color contract §6 (design-system). keyword
143
+ and terminal cyan roles repoint to info (blue-cobalto-700); function gets
144
+ a deeper blue-cobalto step so it stays visually distinct from keyword. */
145
+ --nc-code-token-keyword: var(--nc-info);
178
146
  --nc-code-token-string: var(--nc-success);
179
147
  --nc-code-token-comment: var(--nc-cross);
180
- --nc-code-token-function: var(--nc-cyan-deep);
148
+ --nc-code-token-function: var(--nc-blue-cobalto-900);
181
149
 
182
150
  --nc-terminal-bg: var(--nc-ink);
183
151
  --nc-terminal-fg: var(--nc-on-primary);
184
152
  --nc-terminal-muted: var(--nc-cross);
185
- --nc-terminal-cursor: var(--nc-cyan);
153
+ --nc-terminal-cursor: var(--nc-info);
186
154
  --nc-terminal-selection-bg: var(--nc-link-deep);
187
155
  --nc-terminal-ansi-black: var(--nc-ink);
188
156
  --nc-terminal-ansi-red: var(--nc-error);
@@ -190,15 +158,15 @@
190
158
  --nc-terminal-ansi-yellow: var(--nc-warning);
191
159
  --nc-terminal-ansi-blue: var(--nc-link);
192
160
  --nc-terminal-ansi-magenta: var(--nc-flag-red);
193
- --nc-terminal-ansi-cyan: var(--nc-cyan);
161
+ --nc-terminal-ansi-cyan: var(--nc-info);
194
162
  --nc-terminal-ansi-white: var(--nc-on-primary);
195
163
  --nc-terminal-ansi-bright-black: var(--nc-body);
196
164
  --nc-terminal-ansi-bright-red: var(--nc-error-soft);
197
- --nc-terminal-ansi-bright-green: var(--nc-cyan-soft);
165
+ --nc-terminal-ansi-bright-green: var(--nc-green-italia-400);
198
166
  --nc-terminal-ansi-bright-yellow: var(--nc-warning-soft);
199
- --nc-terminal-ansi-bright-blue: var(--nc-cyan);
167
+ --nc-terminal-ansi-bright-blue: var(--nc-info);
200
168
  --nc-terminal-ansi-bright-magenta: var(--nc-flag-red);
201
- --nc-terminal-ansi-bright-cyan: var(--nc-cyan-soft);
169
+ --nc-terminal-ansi-bright-cyan: var(--nc-blue-cobalto-200);
202
170
  --nc-terminal-ansi-bright-white: var(--nc-on-primary);
203
171
 
204
172
  --nc-model-provider-surface: var(--muted);
@@ -217,40 +185,6 @@
217
185
  }
218
186
 
219
187
  .dark {
220
- --radius: var(--nc-rounded-md);
221
- --background: var(--nc-ink);
222
- --foreground: var(--nc-on-primary);
223
- --card: var(--nc-primary);
224
- --card-foreground: var(--nc-on-primary);
225
- --popover: var(--nc-primary);
226
- --popover-foreground: var(--nc-on-primary);
227
- --primary: var(--nc-on-primary);
228
- --primary-foreground: var(--nc-ink);
229
- --secondary: var(--nc-body);
230
- --secondary-foreground: var(--nc-on-primary);
231
- --muted: var(--nc-body);
232
- --muted-foreground: var(--nc-cross);
233
- --accent: var(--nc-body);
234
- --accent-foreground: var(--nc-on-primary);
235
- --destructive: var(--nc-error);
236
- --destructive-foreground: var(--nc-on-primary);
237
- --border: var(--nc-body);
238
- --input: var(--nc-body);
239
- --ring: var(--nc-cyan);
240
- --chart-1: var(--nc-cyan);
241
- --chart-2: var(--nc-link-bg-soft);
242
- --chart-3: var(--nc-warning);
243
- --chart-4: var(--nc-flag-red);
244
- --chart-5: var(--nc-link);
245
- --sidebar: var(--nc-primary);
246
- --sidebar-foreground: var(--nc-on-primary);
247
- --sidebar-primary: var(--nc-cyan);
248
- --sidebar-primary-foreground: var(--nc-ink);
249
- --sidebar-accent: var(--nc-body);
250
- --sidebar-accent-foreground: var(--nc-on-primary);
251
- --sidebar-border: var(--nc-body);
252
- --sidebar-ring: var(--nc-cyan);
253
-
254
188
  --nc-app-surface: var(--background);
255
189
  --nc-app-surface-chrome: var(--sidebar);
256
190
  --nc-app-surface-sidebar: var(--sidebar);
@@ -266,7 +200,7 @@
266
200
  --nc-app-text-secondary: var(--nc-cross);
267
201
  --nc-app-text-tertiary: var(--muted-foreground);
268
202
  --nc-app-text-inverse: var(--primary-foreground);
269
- --nc-app-text-link: var(--nc-cyan-soft);
203
+ --nc-app-text-link: var(--nc-dark-cyan-soft);
270
204
  --nc-app-text-code: var(--nc-on-primary);
271
205
  --nc-app-text-placeholder: var(--nc-cross);
272
206
  --nc-app-text-disabled: var(--nc-body);
@@ -279,8 +213,8 @@
279
213
  --nc-chat-reasoning-surface: var(--accent);
280
214
  --nc-chat-artifact-surface: var(--popover);
281
215
  --nc-chat-inline-ref-surface: var(--nc-link-deep);
282
- --nc-chat-directive-command: var(--nc-cyan);
283
- --nc-chat-directive-skill: var(--nc-cyan-soft);
216
+ --nc-chat-directive-command: var(--nc-dark-cyan);
217
+ --nc-chat-directive-skill: var(--nc-dark-cyan-soft);
284
218
  --nc-chat-directive-theme: var(--nc-warning);
285
219
  --nc-composer-surface: var(--popover);
286
220
  --nc-composer-foreground: var(--popover-foreground);
@@ -288,70 +222,77 @@
288
222
  --nc-composer-ring: var(--ring);
289
223
 
290
224
  --nc-tool-pending: var(--nc-warning);
291
- --nc-tool-running: var(--nc-cyan);
292
- --nc-tool-success: var(--nc-cyan-soft);
225
+ --nc-tool-running: var(--nc-dark-cyan);
226
+ --nc-tool-success: var(--nc-dark-cyan-soft);
293
227
  --nc-tool-warning: var(--nc-warning);
294
228
  --nc-tool-error: var(--nc-error-soft);
295
229
  --nc-tool-muted: var(--nc-cross);
296
- --nc-tool-approval-run: var(--nc-cyan-deep);
230
+ --nc-tool-approval-run: var(--nc-dark-cyan-deep);
297
231
  --nc-tool-approval-deny: var(--nc-error-soft);
298
- --nc-tool-approval-session: var(--nc-cyan);
299
- --nc-tool-approval-always: var(--nc-cyan-soft);
232
+ --nc-tool-approval-session: var(--nc-dark-cyan);
233
+ --nc-tool-approval-always: var(--nc-dark-cyan-soft);
300
234
 
301
- --nc-status-info: var(--nc-cyan);
302
- --nc-status-success: var(--nc-cyan-soft);
235
+ --nc-status-info: var(--nc-dark-cyan);
236
+ --nc-status-success: var(--nc-dark-cyan-soft);
303
237
  --nc-status-warning: var(--nc-warning);
304
238
  --nc-status-error: var(--nc-error-soft);
305
239
  --nc-status-paused: var(--nc-cross);
306
- --nc-status-running: var(--nc-cyan);
240
+ --nc-status-running: var(--nc-dark-cyan);
307
241
  --nc-status-blocked: var(--nc-error-soft);
308
- --nc-status-complete: var(--nc-cyan-soft);
242
+ --nc-status-complete: var(--nc-dark-cyan-soft);
309
243
  --nc-status-offline: var(--nc-cross);
310
- --nc-status-online: var(--nc-cyan-soft);
244
+ --nc-status-online: var(--nc-dark-cyan-soft);
311
245
 
312
246
  --nc-diff-added-line: var(--nc-link-deep);
313
- --nc-diff-added-word: var(--nc-cyan-soft);
247
+ --nc-diff-added-word: var(--nc-dark-cyan-soft);
314
248
  --nc-diff-removed-line: var(--nc-error-deep);
315
249
  --nc-diff-removed-word: var(--nc-error-soft);
316
250
  --nc-diff-hunk: var(--muted);
317
251
  --nc-diff-file-header: var(--muted-foreground);
318
- --nc-code-surface: var(--nc-primary);
252
+ /* --nc-primary is now green-700 (Italia contract §4); code/terminal chrome
253
+ must stay near-black in dark mode too, so repoint to --nc-ink instead of
254
+ letting the code surface render green. */
255
+ --nc-code-surface: var(--nc-ink);
319
256
  --nc-code-border: var(--nc-body);
320
- --nc-code-token-keyword: var(--nc-cyan);
321
- --nc-code-token-string: var(--nc-cyan-soft);
257
+ /* cyan family retired per Italia color contract §6. dark-cyan/-soft/-deep
258
+ were kept unchanged in DESIGN.md specifically for this dark-mode "electric"
259
+ accent role, so repoint here rather than to info (which is the light-mode
260
+ replacement) to preserve the existing dark-theme look. */
261
+ --nc-code-token-keyword: var(--nc-dark-cyan);
262
+ --nc-code-token-string: var(--nc-dark-cyan-soft);
322
263
  --nc-code-token-comment: var(--nc-cross);
323
- --nc-code-token-function: var(--nc-cyan-soft);
264
+ --nc-code-token-function: var(--nc-dark-cyan-soft);
324
265
 
325
- --nc-terminal-bg: var(--nc-primary);
266
+ --nc-terminal-bg: var(--nc-ink);
326
267
  --nc-terminal-fg: var(--nc-on-primary);
327
268
  --nc-terminal-muted: var(--nc-cross);
328
- --nc-terminal-cursor: var(--nc-cyan);
269
+ --nc-terminal-cursor: var(--nc-dark-cyan);
329
270
  --nc-terminal-selection-bg: var(--nc-link-deep);
330
271
  --nc-terminal-ansi-black: var(--nc-body);
331
272
  --nc-terminal-ansi-red: var(--nc-error-soft);
332
- --nc-terminal-ansi-green: var(--nc-cyan-soft);
273
+ --nc-terminal-ansi-green: var(--nc-dark-cyan-soft);
333
274
  --nc-terminal-ansi-yellow: var(--nc-warning);
334
- --nc-terminal-ansi-blue: var(--nc-cyan);
275
+ --nc-terminal-ansi-blue: var(--nc-dark-cyan);
335
276
  --nc-terminal-ansi-magenta: var(--nc-flag-red);
336
- --nc-terminal-ansi-cyan: var(--nc-cyan-soft);
277
+ --nc-terminal-ansi-cyan: var(--nc-dark-cyan-soft);
337
278
  --nc-terminal-ansi-white: var(--nc-on-primary);
338
279
  --nc-terminal-ansi-bright-black: var(--nc-cross);
339
280
  --nc-terminal-ansi-bright-red: var(--nc-error-soft);
340
- --nc-terminal-ansi-bright-green: var(--nc-cyan-soft);
281
+ --nc-terminal-ansi-bright-green: var(--nc-dark-cyan-soft);
341
282
  --nc-terminal-ansi-bright-yellow: var(--nc-warning-soft);
342
- --nc-terminal-ansi-bright-blue: var(--nc-cyan);
283
+ --nc-terminal-ansi-bright-blue: var(--nc-dark-cyan);
343
284
  --nc-terminal-ansi-bright-magenta: var(--nc-flag-red);
344
- --nc-terminal-ansi-bright-cyan: var(--nc-cyan-soft);
285
+ --nc-terminal-ansi-bright-cyan: var(--nc-dark-cyan-soft);
345
286
  --nc-terminal-ansi-bright-white: var(--nc-on-primary);
346
287
 
347
288
  --nc-model-provider-surface: var(--muted);
348
289
  --nc-model-capability-surface: var(--accent);
349
- --nc-model-capability-border: var(--nc-cyan);
290
+ --nc-model-capability-border: var(--nc-dark-cyan);
350
291
  --nc-model-context-meter: var(--nc-warning);
351
292
  --nc-model-cost-warning: var(--nc-warning);
352
293
  --nc-model-rate-limit: var(--nc-error-soft);
353
294
 
354
- --nc-plugin-permission-safe: var(--nc-cyan-soft);
295
+ --nc-plugin-permission-safe: var(--nc-dark-cyan-soft);
355
296
  --nc-plugin-permission-review: var(--nc-warning);
356
297
  --nc-plugin-permission-risk: var(--nc-flag-red);
357
298
  --nc-plugin-permission-denied: var(--nc-error-soft);
@@ -359,4 +300,77 @@
359
300
  --nc-plugin-permission-foreground: var(--foreground);
360
301
  }
361
302
 
303
+ [data-nc-code-block-body] {
304
+ background-color: var(--shiki-code-block-light-bg, var(--background));
305
+ color: var(--shiki-code-block-light-fg, var(--foreground));
306
+ }
307
+
308
+ .dark [data-nc-code-block-body] {
309
+ background-color: var(
310
+ --shiki-code-block-dark-bg,
311
+ var(--shiki-code-block-light-bg, var(--background))
312
+ );
313
+ color: var(
314
+ --shiki-code-block-dark-fg,
315
+ var(--shiki-code-block-light-fg, var(--foreground))
316
+ );
317
+ }
318
+
319
+ [data-nc-code-token] {
320
+ background-color: var(--shiki-code-token-light-bg, transparent);
321
+ color: var(--shiki-code-token-light-color, var(--foreground));
322
+ font-style: var(--shiki-code-token-light-font-style, normal);
323
+ font-weight: var(--shiki-code-token-light-font-weight, normal);
324
+ text-decoration: var(--shiki-code-token-light-text-decoration, none);
325
+ }
326
+
327
+ .dark [data-nc-code-token] {
328
+ background-color: var(
329
+ --shiki-code-token-dark-bg,
330
+ var(--shiki-code-token-light-bg, transparent)
331
+ );
332
+ color: var(
333
+ --shiki-code-token-dark-color,
334
+ var(--shiki-code-token-light-color, var(--foreground))
335
+ );
336
+ font-style: var(
337
+ --shiki-code-token-dark-font-style,
338
+ var(--shiki-code-token-light-font-style, normal)
339
+ );
340
+ font-weight: var(
341
+ --shiki-code-token-dark-font-weight,
342
+ var(--shiki-code-token-light-font-weight, normal)
343
+ );
344
+ text-decoration: var(
345
+ --shiki-code-token-dark-text-decoration,
346
+ var(--shiki-code-token-light-text-decoration, none)
347
+ );
348
+ }
349
+
350
+ .toaster [data-sonner-toast][data-styled="true"] [data-description] {
351
+ color: var(--muted-foreground);
352
+ }
353
+
354
+ .toaster [data-sonner-toast][data-styled="true"] [data-button] {
355
+ background: var(--popover-foreground);
356
+ color: var(--popover);
357
+ }
358
+
359
+ .toaster [data-sonner-toast][data-styled="true"] [data-cancel] {
360
+ background: var(--muted);
361
+ color: var(--popover-foreground);
362
+ }
363
+
364
+ .toaster [data-sonner-toast][data-styled="true"] [data-close-button] {
365
+ background: var(--popover);
366
+ border-color: var(--border);
367
+ color: var(--popover-foreground);
368
+ }
369
+
370
+ .toaster [data-sonner-toast][data-styled="true"] [data-close-button]:hover {
371
+ background: var(--accent);
372
+ border-color: var(--border);
373
+ color: var(--accent-foreground);
374
+ }
375
+
362
376
  @source "../components";
@@ -87,6 +87,11 @@ Current shipped product subpaths:
87
87
  - `@nadicodeai/ui/components/plugin-slot-boundary`
88
88
  - `@nadicodeai/ui/components/settings-section`
89
89
 
90
+ `StateNotice` (`@nadicodeai/ui/components/state-notice`) is the supported
91
+ low-level state-banner primitive behind `AgentMessageStateNotice` and
92
+ `AgentThreadStateBanner`; it requires a `title` and owns the shared
93
+ `role="status"`/`role="alert"` skeleton.
94
+
90
95
  ## Product Components And Migration
91
96
 
92
97
  Product components are presentational. Use them for shared settings, shell,
@@ -112,6 +117,23 @@ Read `docs/migration/nadia-consumer-readiness.md` before migrating a consumer.
112
117
  It lists the CSS imports, public subpaths, fixture redaction rules, and readiness
113
118
  gates.
114
119
 
120
+ ## Layout Primitives
121
+
122
+ `SeamGrid` (`@nadicodeai/ui/components/seam-grid`) is a supported low-level layout
123
+ primitive: the single owner of the "gap-as-seam" grid that backs the bordered
124
+ section grids (stats band, testimonials, logo band, and siblings). It renders a
125
+ `div` with the invariant `grid gap-px` base, so borderless, square-cornered cells
126
+ paint one shared hairline seam at every boundary instead of doubling lines.
127
+
128
+ Its only seam-specific prop is `surface`: `"canvas"` (default) paints the brand
129
+ `line` via `bg-border`, and `"ink"` mixes the line toward the ink role for darker
130
+ panels; the value is also mirrored on a `data-surface` attribute. Pass
131
+ `className`, `children`, and any `div` props to keep a bespoke column map,
132
+ heights, and `data-*` attributes. Reach for `SeamGrid` and its `surface` prop
133
+ when building a new bordered grid rather than hand-copying the seam colour: the
134
+ seam class helper is an internal `src/lib/seam` detail with no public subpath
135
+ export, so nothing should couple to the raw arbitrary Tailwind class string.
136
+
115
137
  ## Forms
116
138
 
117
139
  Use the package's shadcn form stack as one model:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nadicodeai/ui",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -23,6 +23,10 @@
23
23
  "types": "./dist/lib/utils.d.ts",
24
24
  "import": "./dist/lib/utils.js"
25
25
  },
26
+ "./lib/theme-mode": {
27
+ "types": "./dist/lib/theme-mode.d.ts",
28
+ "import": "./dist/lib/theme-mode.js"
29
+ },
26
30
  "./components/*": {
27
31
  "types": "./dist/components/*.d.ts",
28
32
  "import": "./dist/components/*.js"
@@ -37,13 +41,15 @@
37
41
  "skills"
38
42
  ],
39
43
  "scripts": {
40
- "build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/fix-dist-imports.mjs && cp -R src/styles dist/styles",
44
+ "dev": "node scripts/dev-build.mjs --watch",
45
+ "build": "rm -rf dist && tsc -p tsconfig.build.json && node scripts/fix-dist-imports.mjs && rm -rf dist/styles && cp -R src/styles dist/styles",
46
+ "build:fast": "node scripts/dev-build.mjs",
41
47
  "prepack": "npm run build",
42
48
  "test": "vitest run"
43
49
  },
44
50
  "dependencies": {
45
51
  "@base-ui/react": "^1.6.0",
46
- "@nadicodeai/design-system": "0.1.1",
52
+ "@nadicodeai/design-system": "0.2.0",
47
53
  "@radix-ui/react-use-controllable-state": "^1.2.3",
48
54
  "@rive-app/react-webgl2": "^4.29.1",
49
55
  "@streamdown/cjk": "^1.0.3",
@@ -68,7 +68,8 @@ import { AgentChat } from "@nadicodeai/ui/components/agent-chat";
68
68
  - Use token-backed shadcn utilities: `bg-background`, `text-foreground`, `border-border`, `text-muted-foreground`, `text-destructive`.
69
69
  - Use UI-local product aliases when a product role is needed: `bg-[var(--nc-app-surface)]`, `ring-[var(--nc-composer-ring)]`.
70
70
  - Use brand tokens through arbitrary values when needed: `text-[var(--nc-link-deep)]`.
71
- - Dark mode is owned by `@nadicodeai/ui/globals.css` through `:root` and `.dark` remaps of shadcn roles and UI-local product aliases. Do not add component-level `dark:` utilities, `.dark` CSS outside package globals/theme files, OS dark-mode branching, raw color literals, or raw Tailwind palette utilities.
71
+ - Dark mode uses generated design-system `:root` and `.dark` shadcn roles plus UI-local product aliases in `@nadicodeai/ui/globals.css`. Consuming apps own the runtime `.dark` class and persisted light/dark/system preference. Do not add component-level `dark:` utilities, `.dark` CSS outside package globals/theme files, OS dark-mode branching, raw color literals, or raw Tailwind palette utilities.
72
+ - Use `ThemeModeSwitcher` only as a controlled, app-agnostic control; do not import `next-themes` or app persistence into the UI package.
72
73
  - Compose app pages/screens from existing package components; extract new shared UI only after a second concrete consumer, a plan-approved shared component, or a named validation slice proves the package boundary.
73
74
  - For source maintenance, run shadcn commands with `--dry-run` before writing and do not use `--overwrite` without explicit maintainer approval.
74
75