@vadimcomanescu/nadicode-design-system 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/.agents/skills/seed/SKILL.md +9 -8
  2. package/.agents/skills/seed/contract.md +10 -4
  3. package/.agents/skills/seed/recipes/agency-home.md +5 -5
  4. package/.agents/skills/seed/recipes/auth.md +3 -3
  5. package/.agents/skills/seed/recipes/blog-content.md +2 -2
  6. package/.agents/skills/seed/recipes/company-about.md +3 -3
  7. package/.agents/skills/seed/recipes/company-contact.md +3 -3
  8. package/.agents/skills/seed/recipes/digital-workers.md +3 -3
  9. package/.agents/skills/seed/recipes/marketing-landing.md +8 -8
  10. package/.agents/skills/seed/recipes/marketing-shell.md +4 -4
  11. package/.agents/skills/seed/recipes/navigation-shell.md +3 -2
  12. package/.agents/skills/seed/recipes/pricing.md +4 -4
  13. package/.agents/skills/seed/recipes/service-detail.md +3 -3
  14. package/dist/catalog/components.js +4 -4
  15. package/dist/{chunk-7A2RXKGH.js → chunk-GJ557DGH.js} +1 -1
  16. package/dist/{chunk-7XLZCXUL.js → chunk-K4U67BVG.js} +1 -1
  17. package/dist/{chunk-TUJZMJXW.js → chunk-LK2L3C7D.js} +1 -1
  18. package/dist/{chunk-DSMGCFMJ.js → chunk-POFFOUQW.js} +2 -5
  19. package/dist/components/blocks/HeroBlock.js +2 -2
  20. package/dist/components/page-kits/LandingPageKit.js +3 -3
  21. package/dist/components/page-kits/ServiceSuitePageKit.js +3 -3
  22. package/dist/components/ui/AvatarUpload.js +1 -1
  23. package/dist/components/ui/MouseEffect.js +1 -1
  24. package/eslint-rules/nadicode/config.js +1 -0
  25. package/eslint-rules/nadicode/index.js +2 -0
  26. package/eslint-rules/nadicode/rules/__tests__/require-catalog-import.test.js +111 -0
  27. package/eslint-rules/nadicode/rules/require-catalog-import.js +59 -0
  28. package/package.json +1 -337
@@ -20,7 +20,7 @@ Consumer scaffold contract: brand customization stays palette-only unless the ta
20
20
 
21
21
  ## Component Discovery
22
22
 
23
- The catalog (`./catalog` and `./catalog/components` subpath exports) is the single surface for discovering and consuming Seed components.
23
+ The catalog (`./catalog` and `./catalog/components` subpath exports) is the single surface for discovering and consuming Seed blocks and page-kits.
24
24
 
25
25
  **Discovery** (server-safe, read this to learn what's available):
26
26
  ```ts
@@ -36,13 +36,15 @@ import { seedComponents } from "@vadimcomanescu/nadicode-design-system/catalog/c
36
36
 
37
37
  Usage:
38
38
  ```tsx
39
- const { LoginBlock, Button, Card } = seedComponents
39
+ const { LoginBlock, DashboardPageKit } = seedComponents
40
40
  <LoginBlock onSubmit={handleLogin} />
41
41
  ```
42
42
 
43
- Do not import from individual subpath exports. Do not browse package exports. The catalog is the single source of truth.
43
+ **Blocks and page-kits** are imported exclusively from `seedComponents`. Do not import them via individual subpath exports (ADR 0009). The ESLint rule `nadicode/require-catalog-import` enforces this at lint time.
44
44
 
45
- The ESLint rule `nadicode/no-raw-recharts-import` and related rules enforce correct import paths at lint time. See the ESLint Rule Reference in `contract.md`.
45
+ **UI primitives** (Button, Heading, Input, etc.), icons, charts, and effects are imported via individual subpath exports. They are not registered in the catalog.
46
+
47
+ See the full Import Rules in `contract.md`.
46
48
 
47
49
  The derived references under `references/components.md` and `references/blocks.md` are generated from the catalog. Any repo `Path` column there is a maintainer source path, not a consumer import path.
48
50
 
@@ -345,10 +347,9 @@ Content widths, vertical rhythm, responsive contracts: `references/composition.m
345
347
  Compound component for multi-column sortable boards (project boards, runs views, pipelines).
346
348
 
347
349
  ```tsx
348
- import {
349
- KanbanBoard, KanbanColumn, KanbanColumnHeader,
350
- KanbanItem, KanbanHandle,
351
- } from '@vadimcomanescu/nadicode-design-system/kanban-board'
350
+ import { seedComponents } from "@vadimcomanescu/nadicode-design-system/catalog/components"
351
+ const { KanbanBoard: kanban } = seedComponents
352
+ const { KanbanBoard, KanbanColumn, KanbanColumnHeader, KanbanItem, KanbanHandle } = kanban
352
353
  import type { KanbanColumnState, KanbanMoveMeta } from '@vadimcomanescu/nadicode-design-system/kanban-board'
353
354
  ```
354
355
 
@@ -21,9 +21,15 @@ import { seedComponents } from "@vadimcomanescu/nadicode-design-system/catalog/c
21
21
 
22
22
  ## Import Rules
23
23
 
24
- 1. Import Seed primitives, blocks, charts, icons, and text effects from `@vadimcomanescu/nadicode-design-system/*` subpaths. Do not vendor or recreate DS runtime files inside the scaffold.
25
- 2. Never import icons from `lucide-react` directly. Import from `@vadimcomanescu/nadicode-design-system/icons` or the matching `@vadimcomanescu/nadicode-design-system/icons/<name>` subpath.
26
- 3. If a needed primitive is missing, stop and report it. Do not invent ad-hoc replacements.
24
+ 1. **Blocks and page-kits**: import from `seedComponents` via `@vadimcomanescu/nadicode-design-system/catalog/components`. No individual subpath imports for blocks or page-kits.
25
+ ```ts
26
+ import { seedComponents } from "@vadimcomanescu/nadicode-design-system/catalog/components"
27
+ const { LoginBlock, DashboardPageKit } = seedComponents
28
+ ```
29
+ 2. **UI primitives, charts, effects, text-effects**: import via individual subpath exports (e.g., `@vadimcomanescu/nadicode-design-system/button`, `@vadimcomanescu/nadicode-design-system/charts`). These are not in the catalog.
30
+ 3. **Icons**: import from `@vadimcomanescu/nadicode-design-system/icons` or the matching `@vadimcomanescu/nadicode-design-system/icons/<name>` subpath. Never import from `lucide-react` directly.
31
+ 4. **Infrastructure** (tokens.css, tailwind preset, eslint-plugin, theme-provider, messages, test, lib/*): import via subpath exports. These are configuration wiring, not component consumption.
32
+ 5. Do not vendor or recreate DS runtime files inside the scaffold. If a needed primitive is missing, stop and report it. Do not invent ad-hoc replacements.
27
33
 
28
34
  ## Token Rules
29
35
 
@@ -69,7 +75,7 @@ import { seedComponents } from "@vadimcomanescu/nadicode-design-system/catalog/c
69
75
  24. Dashboard KPI cards must use `MetricCard`, not ad-hoc Card + value compositions.
70
76
  25. Chart components must not be rendered without an empty-data guard (`data.length > 0` or `ChartCard`).
71
77
  26. Chart color configs must use `var(--color-chart-N)` tokens, never hex/rgb/hsl literals.
72
- 27. Import chart primitives from `@vadimcomanescu/nadicode-design-system/charts` or the matching `@vadimcomanescu/nadicode-design-system/charts/<chart-name>` subpath. Do not import `recharts` directly into scaffold app code.
78
+ 27. Import chart primitives from `@vadimcomanescu/nadicode-design-system/charts` or the matching `@vadimcomanescu/nadicode-design-system/charts/<chart-name>` subpath (charts are UI primitives, not catalog items). Do not import `recharts` directly into scaffold app code.
73
79
 
74
80
  ## ESLint Rule Reference
75
81
 
@@ -231,15 +231,15 @@ REDUCED MOTION: All items visible immediately, opacity 0->1 in 10ms
231
231
 
232
232
  | Component | Import Path | Purpose |
233
233
  |-----------|-------------|---------|
234
- | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/header-block` | Site navigation |
235
- | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/footer-block` | Site footer |
234
+ | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site navigation |
235
+ | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site footer |
236
236
  | `Button` | `@vadimcomanescu/nadicode-design-system/button` | CTAs |
237
237
  | `Badge` | `@vadimcomanescu/nadicode-design-system/badge` | Hero tag |
238
238
  | `Typography` | `@vadimcomanescu/nadicode-design-system/typography` | Headings, body text |
239
239
  | `ScrollFadeIn` | `@vadimcomanescu/nadicode-design-system/scroll-fade-in` | Below-fold animations |
240
- | `ProcessFlowBlock` | `@vadimcomanescu/nadicode-design-system/process-flow-block` | How-we-work process |
241
- | `FeatureGridBlock` | `@vadimcomanescu/nadicode-design-system/feature-grid-block` | Services grid |
242
- | `StatsMarketingBlock` | `@vadimcomanescu/nadicode-design-system/stats-marketing-block` | Outcome metrics (ROI, time saved) |
240
+ | `ProcessFlowBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | How-we-work process |
241
+ | `FeatureGridBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Services grid |
242
+ | `StatsMarketingBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Outcome metrics (ROI, time saved) |
243
243
 
244
244
  ### Allowed (optional)
245
245
 
@@ -167,9 +167,9 @@ REDUCED MOTION: Card and all children visible immediately
167
167
 
168
168
  | Component | Import Path | Purpose |
169
169
  |-----------|-------------|---------|
170
- | `AuthLayout` | `@vadimcomanescu/nadicode-design-system/auth-layout` | Split-screen wrapper |
171
- | `LoginBlock` | `@vadimcomanescu/nadicode-design-system/login-block` | Pre-built login form |
172
- | `SignUpBlock` | `@vadimcomanescu/nadicode-design-system/sign-up-block` | Pre-built signup form |
170
+ | `AuthLayout` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Split-screen wrapper |
171
+ | `LoginBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Pre-built login form |
172
+ | `SignUpBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Pre-built signup form |
173
173
  | `Card` | `@vadimcomanescu/nadicode-design-system/card` | Auth card container |
174
174
  | `Input` | `@vadimcomanescu/nadicode-design-system/input` | Email, name fields |
175
175
  | `PasswordInput` | `@vadimcomanescu/nadicode-design-system/password-input` | Password with toggle |
@@ -233,8 +233,8 @@ REDUCED MOTION: All items visible immediately
233
233
  | `Pagination` | `@vadimcomanescu/nadicode-design-system/pagination` | Blog index pages |
234
234
  | `Separator` | `@vadimcomanescu/nadicode-design-system/separator` | Content dividers |
235
235
  | `Select` | `@vadimcomanescu/nadicode-design-system/select` | Category filter |
236
- | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/header-block` | Site navigation |
237
- | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/footer-block` | Site footer |
236
+ | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site navigation |
237
+ | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site footer |
238
238
  | `ScrollFadeIn` | `@vadimcomanescu/nadicode-design-system/scroll-fade-in` | Below-fold animations |
239
239
  | `Button` | `@vadimcomanescu/nadicode-design-system/button` | Share, read more |
240
240
 
@@ -200,13 +200,13 @@ REDUCED MOTION: All items visible immediately, opacity 0->1 in 10ms
200
200
 
201
201
  | Component | Import Path | Purpose |
202
202
  |-----------|-------------|---------|
203
- | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/header-block` | Site navigation |
204
- | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/footer-block` | Site footer |
203
+ | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site navigation |
204
+ | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site footer |
205
205
  | `Button` | `@vadimcomanescu/nadicode-design-system/button` | CTAs |
206
206
  | `Badge` | `@vadimcomanescu/nadicode-design-system/badge` | Hero tag |
207
207
  | `Typography` | `@vadimcomanescu/nadicode-design-system/typography` | Headings, body text |
208
208
  | `ScrollFadeIn` | `@vadimcomanescu/nadicode-design-system/scroll-fade-in` | Below-fold animations |
209
- | `TeamBlock` | `@vadimcomanescu/nadicode-design-system/team-block` | Team member grid |
209
+ | `TeamBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Team member grid |
210
210
 
211
211
  ### Allowed (optional)
212
212
 
@@ -157,11 +157,11 @@ REDUCED MOTION: All items visible immediately, opacity 0->1 in 10ms
157
157
 
158
158
  | Component | Import Path | Purpose |
159
159
  |-----------|-------------|---------|
160
- | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/header-block` | Site navigation |
161
- | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/footer-block` | Site footer |
160
+ | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site navigation |
161
+ | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site footer |
162
162
  | `Button` | `@vadimcomanescu/nadicode-design-system/button` | CTAs and form submit |
163
163
  | `ScrollFadeIn` | `@vadimcomanescu/nadicode-design-system/scroll-fade-in` | Below-fold animations |
164
- | `ContactBlock` | `@vadimcomanescu/nadicode-design-system/contact-block` | Contact form + company info |
164
+ | `ContactBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Contact form + company info |
165
165
 
166
166
  ### Allowed (optional)
167
167
 
@@ -237,13 +237,13 @@ REDUCED MOTION: All items visible immediately, opacity 0->1 in 10ms
237
237
 
238
238
  | Component | Import Path | Purpose |
239
239
  |-----------|-------------|---------|
240
- | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/header-block` | Site navigation |
241
- | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/footer-block` | Site footer |
240
+ | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site navigation |
241
+ | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site footer |
242
242
  | `Button` | `@vadimcomanescu/nadicode-design-system/button` | CTAs |
243
243
  | `Badge` | `@vadimcomanescu/nadicode-design-system/badge` | Hero tag |
244
244
  | `Typography` | `@vadimcomanescu/nadicode-design-system/typography` | Headings, body text |
245
245
  | `ScrollFadeIn` | `@vadimcomanescu/nadicode-design-system/scroll-fade-in` | Below-fold animations |
246
- | `AgentProfileGridBlock` | `@vadimcomanescu/nadicode-design-system/agent-profile-grid-block` | Agent profile cards grid |
246
+ | `AgentProfileGridBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Agent profile cards grid |
247
247
 
248
248
  ### Allowed (optional)
249
249
 
@@ -212,17 +212,17 @@ REDUCED MOTION: All items visible immediately, opacity 0->1 in 10ms
212
212
 
213
213
  | Component | Import Path | Purpose |
214
214
  |-----------|-------------|---------|
215
- | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/header-block` | Site navigation |
216
- | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/footer-block` | Site footer |
215
+ | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site navigation |
216
+ | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site footer |
217
217
  | `Button` | `@vadimcomanescu/nadicode-design-system/button` | CTAs |
218
218
  | `Badge` | `@vadimcomanescu/nadicode-design-system/badge` | Announcement tag |
219
219
  | `Typography` | `@vadimcomanescu/nadicode-design-system/typography` | Headings, body text |
220
- | `FeatureBlock` / `FeatureGridBlock` | `@vadimcomanescu/nadicode-design-system/feature*` | Feature showcase |
221
- | `FAQBlock` | `@vadimcomanescu/nadicode-design-system/faq-block` | FAQ accordion |
222
- | `CallToActionBlock` | `@vadimcomanescu/nadicode-design-system/call-to-action-block` | Final CTA |
223
- | `TestimonialsBlock` | `@vadimcomanescu/nadicode-design-system/testimonials-block` | Social proof |
224
- | `LogoCloud` | `@vadimcomanescu/nadicode-design-system/logo-cloud` | Partner logos |
225
- | `StatsMarketingBlock` | `@vadimcomanescu/nadicode-design-system/stats-marketing-block` | Key metrics |
220
+ | `FeatureBlock` / `FeatureGridBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Feature showcase |
221
+ | `FAQBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | FAQ accordion |
222
+ | `CallToActionBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Final CTA |
223
+ | `TestimonialsBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Social proof |
224
+ | `LogoCloud` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Partner logos |
225
+ | `StatsMarketingBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Key metrics |
226
226
  | `ScrollFadeIn` | `@vadimcomanescu/nadicode-design-system/scroll-fade-in` | Below-fold animations |
227
227
  | `ShaderBackground` | `@vadimcomanescu/nadicode-design-system/shader-background` | Hero background |
228
228
 
@@ -35,8 +35,8 @@ Shared marketing layout providing scroll-aware header, main content area, and fo
35
35
  ### 1. Layout Shell
36
36
 
37
37
  ```tsx
38
- import { HeaderBlock } from '@vadimcomanescu/nadicode-design-system/header-block'
39
- import { FooterBlock } from '@vadimcomanescu/nadicode-design-system/footer-block'
38
+ import { seedComponents } from '@vadimcomanescu/nadicode-design-system/catalog/components'
39
+ const { HeaderBlock, FooterBlock } = seedComponents
40
40
 
41
41
  const navLinks = [
42
42
  { name: 'Services', href: '/services' },
@@ -86,8 +86,8 @@ REDUCED MOTION: Header visible immediately, no blur transition
86
86
 
87
87
  | Component | Import Path | Purpose |
88
88
  |-----------|-------------|---------|
89
- | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/header-block` | Site navigation with glass blur |
90
- | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/footer-block` | Site footer |
89
+ | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site navigation with glass blur |
90
+ | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site footer |
91
91
 
92
92
  ### Allowed (optional)
93
93
 
@@ -75,7 +75,8 @@ import {
75
75
  SidebarMenuSubItem,
76
76
  SidebarMenuSubButton,
77
77
  } from '@vadimcomanescu/nadicode-design-system/sidebar'
78
- import { NavUser } from '@vadimcomanescu/nadicode-design-system/nav-user'
78
+ import { seedComponents } from '@vadimcomanescu/nadicode-design-system/catalog/components'
79
+ const { NavUser } = seedComponents
79
80
  import { AppBreadcrumb } from '@/components/blocks/AppBreadcrumb'
80
81
  import { AppSearch } from '@/components/blocks/AppSearch'
81
82
  import { WorkspaceSwitcher } from '@/components/blocks/WorkspaceSwitcher'
@@ -704,7 +705,7 @@ REDUCED MOTION: All transitions instant
704
705
  | Component | Import Path | Purpose |
705
706
  |-----------|-------------|---------|
706
707
  | `Sidebar` (full system) | `@vadimcomanescu/nadicode-design-system/sidebar` | App sidebar with all subcomponents |
707
- | `NavUser` | `@vadimcomanescu/nadicode-design-system/nav-user` | User menu in sidebar footer |
708
+ | `NavUser` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | User menu in sidebar footer |
708
709
  | `AppBreadcrumb` | Consumer block (see Section 2) | Route-aware breadcrumb |
709
710
  | `AppSearch` | Consumer block (see Section 3) | Cmd+K search palette |
710
711
  | `WorkspaceSwitcher` | Consumer block (see Section 7) | Org/workspace picker |
@@ -195,10 +195,10 @@ REDUCED MOTION: All items visible immediately
195
195
  | `Switch` | `@vadimcomanescu/nadicode-design-system/switch` | Billing toggle |
196
196
  | `Typography` | `@vadimcomanescu/nadicode-design-system/typography` | Headings, descriptions |
197
197
  | `Separator` | `@vadimcomanescu/nadicode-design-system/separator` | Plan card divider |
198
- | `FAQBlock` | `@vadimcomanescu/nadicode-design-system/faq-block` | FAQ section |
199
- | `CallToActionBlock` | `@vadimcomanescu/nadicode-design-system/call-to-action-block` | Final CTA |
200
- | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/header-block` | Navigation |
201
- | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/footer-block` | Footer |
198
+ | `FAQBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | FAQ section |
199
+ | `CallToActionBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Final CTA |
200
+ | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Navigation |
201
+ | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Footer |
202
202
  | `ScrollFadeIn` | `@vadimcomanescu/nadicode-design-system/scroll-fade-in` | Below-fold animation |
203
203
  | `CountingNumber` | `@vadimcomanescu/nadicode-design-system/text-effects/counting-number` | Price animation on toggle |
204
204
 
@@ -225,13 +225,13 @@ REDUCED MOTION: All items visible immediately, opacity 0->1 in 10ms
225
225
 
226
226
  | Component | Import Path | Purpose |
227
227
  |-----------|-------------|---------|
228
- | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/header-block` | Site navigation |
229
- | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/footer-block` | Site footer |
228
+ | `HeaderBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site navigation |
229
+ | `FooterBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Site footer |
230
230
  | `Button` | `@vadimcomanescu/nadicode-design-system/button` | CTAs |
231
231
  | `Badge` | `@vadimcomanescu/nadicode-design-system/badge` | Category tag |
232
232
  | `Typography` | `@vadimcomanescu/nadicode-design-system/typography` | Headings, body text |
233
233
  | `ScrollFadeIn` | `@vadimcomanescu/nadicode-design-system/scroll-fade-in` | Below-fold animations |
234
- | `FeatureGridBlock` | `@vadimcomanescu/nadicode-design-system/feature-grid-block` | Product/service showcase |
234
+ | `FeatureGridBlock` | `@vadimcomanescu/nadicode-design-system/catalog/components` via `seedComponents` | Product/service showcase |
235
235
 
236
236
  ### Allowed (optional)
237
237
 
@@ -7,14 +7,14 @@ import { PricingPageKit } from '../chunk-RMGDDOCD.js';
7
7
  import { ProfileSettingsPageKit } from '../chunk-MGSGCARB.js';
8
8
  import { RecoveryPageKit } from '../chunk-BRCBJ3S4.js';
9
9
  import { ResetPageKit } from '../chunk-LP6ZZYOQ.js';
10
- import { ServiceSuitePageKit } from '../chunk-7XLZCXUL.js';
10
+ import { ServiceSuitePageKit } from '../chunk-K4U67BVG.js';
11
11
  import { SettingsPageKit } from '../chunk-RKQPU75I.js';
12
12
  import { SignupPageKit } from '../chunk-BRICSLHJ.js';
13
13
  import { SuccessPageKit } from '../chunk-3U56FXYC.js';
14
14
  import { DashboardPageKit } from '../chunk-C33GUEDY.js';
15
15
  import { ErrorPageKit } from '../chunk-HPTHS7SX.js';
16
16
  import { KanbanBoardPageKit } from '../chunk-25BOZMXA.js';
17
- import { LandingPageKit } from '../chunk-TUJZMJXW.js';
17
+ import { LandingPageKit } from '../chunk-LK2L3C7D.js';
18
18
  import { LoginPageKit } from '../chunk-Z2WION42.js';
19
19
  import { OnboardingPageKit } from '../chunk-BYEHHZZN.js';
20
20
  import { AccountLockedPageKit } from '../chunk-DNJEVMDY.js';
@@ -52,7 +52,7 @@ import { PasswordRecoveryBlock } from '../chunk-5PZ4VR2D.js';
52
52
  import { PricingBlock } from '../chunk-VNNAL4A6.js';
53
53
  import '../chunk-DARC2ACH.js';
54
54
  import { GalleryBlock } from '../chunk-FTGFOK6T.js';
55
- import { HeroBlock } from '../chunk-7A2RXKGH.js';
55
+ import { HeroBlock } from '../chunk-GJ557DGH.js';
56
56
  import { HeroSectionBlock } from '../chunk-ALA6OM7K.js';
57
57
  import '../chunk-QQOWC53X.js';
58
58
  import { HeaderBlock } from '../chunk-WOYBVPXK.js';
@@ -182,7 +182,7 @@ import '../chunk-D4NC7WX5.js';
182
182
  import '../chunk-5UESKK6S.js';
183
183
  import '../chunk-NAAU5IWU.js';
184
184
  import '../chunk-4S326Z3D.js';
185
- import '../chunk-DSMGCFMJ.js';
185
+ import '../chunk-POFFOUQW.js';
186
186
  import '../chunk-GJUR6HT3.js';
187
187
  import '../chunk-7KIDDF3I.js';
188
188
  import '../chunk-4GSFNJAJ.js';
@@ -3,7 +3,7 @@ import { AnimatedGradientText } from './chunk-XZ3A33GP.js';
3
3
  import { Heading } from './chunk-WI547C47.js';
4
4
  import { siteConfig } from './chunk-A7NUWD76.js';
5
5
  import { Card, CardHeader, CardContent } from './chunk-AH6YSYYT.js';
6
- import { MouseGlow } from './chunk-DSMGCFMJ.js';
6
+ import { MouseGlow } from './chunk-POFFOUQW.js';
7
7
  import { Button } from './chunk-7KIDDF3I.js';
8
8
  import { m, heroStagger } from './chunk-PD2YEH3H.js';
9
9
  import { ZapIcon } from './chunk-FLF5AMNO.js';
@@ -2,7 +2,7 @@ import { MarketingShellPageKit } from './chunk-Z233ZQZE.js';
2
2
  import { TeamBlock } from './chunk-VBZQ4DBE.js';
3
3
  import { TestimonialsBlock } from './chunk-FV2G6SAF.js';
4
4
  import { ProcessFlowBlock } from './chunk-HZERHGBT.js';
5
- import { HeroBlock } from './chunk-7A2RXKGH.js';
5
+ import { HeroBlock } from './chunk-GJ557DGH.js';
6
6
  import { FAQBlock } from './chunk-NEHCPO53.js';
7
7
  import { FeatureBlock } from './chunk-HJ3A2YNO.js';
8
8
  import { CallToActionBlock } from './chunk-GJPTPLCQ.js';
@@ -3,7 +3,7 @@ import { SocialProofBlock } from './chunk-C7WHMSF3.js';
3
3
  import { StatsMarketingBlock } from './chunk-QIHA7S3A.js';
4
4
  import { NewsletterBlock } from './chunk-K7NQ6ZAW.js';
5
5
  import { PricingBlock } from './chunk-VNNAL4A6.js';
6
- import { HeroBlock } from './chunk-7A2RXKGH.js';
6
+ import { HeroBlock } from './chunk-GJ557DGH.js';
7
7
  import { FAQBlock } from './chunk-NEHCPO53.js';
8
8
  import { FeatureBlock } from './chunk-HJ3A2YNO.js';
9
9
  import { CallToActionBlock } from './chunk-GJPTPLCQ.js';
@@ -5,10 +5,7 @@ import { createPortal } from 'react-dom';
5
5
  import { useReducedMotion, useMotionValue, useMotionTemplate } from 'motion/react';
6
6
  import { jsxs, jsx } from 'react/jsx-runtime';
7
7
 
8
- function getAccentColor() {
9
- if (typeof window === "undefined") return "10 158 111";
10
- return getComputedStyle(document.documentElement).getPropertyValue("--color-accent").trim() || "10 158 111";
11
- }
8
+ var CSS_ACCENT_095 = "rgb(var(--color-accent) / 0.95)";
12
9
  function MouseGlow({
13
10
  className,
14
11
  dotColor = "rgba(255, 255, 255, 0.5)",
@@ -20,7 +17,7 @@ function MouseGlow({
20
17
  const containerRef = React.useRef(null);
21
18
  const overlayRef = React.useRef(null);
22
19
  const [mounted, setMounted] = React.useState(false);
23
- const resolvedOverlayColor = overlayColor ?? `rgba(${getAccentColor().replace(/ /g, ", ")}, 0.95)`;
20
+ const resolvedOverlayColor = overlayColor ?? CSS_ACCENT_095;
24
21
  React.useEffect(() => {
25
22
  setMounted(true);
26
23
  const handleMouseMove = (e) => {
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- export { HeroBlock } from '../../chunk-7A2RXKGH.js';
2
+ export { HeroBlock } from '../../chunk-GJ557DGH.js';
3
3
  import '../../chunk-G5EO22OR.js';
4
4
  import '../../chunk-OHX2LFAH.js';
5
5
  import '../../chunk-SGI25ZJ6.js';
@@ -14,7 +14,7 @@ import '../../chunk-4O6L5YWT.js';
14
14
  import '../../chunk-WI547C47.js';
15
15
  import '../../chunk-A7NUWD76.js';
16
16
  import '../../chunk-AH6YSYYT.js';
17
- import '../../chunk-DSMGCFMJ.js';
17
+ import '../../chunk-POFFOUQW.js';
18
18
  import '../../chunk-7KIDDF3I.js';
19
19
  import '../../chunk-PD2YEH3H.js';
20
20
  import '../../chunk-CRY67BIF.js';
@@ -1,11 +1,11 @@
1
- export { LandingPageKit } from '../../chunk-TUJZMJXW.js';
1
+ export { LandingPageKit } from '../../chunk-LK2L3C7D.js';
2
2
  import '../../chunk-Z233ZQZE.js';
3
3
  import '../../chunk-C7WHMSF3.js';
4
4
  import '../../chunk-QIHA7S3A.js';
5
5
  import '../../chunk-K7NQ6ZAW.js';
6
6
  import '../../chunk-VNNAL4A6.js';
7
7
  import '../../chunk-DARC2ACH.js';
8
- import '../../chunk-7A2RXKGH.js';
8
+ import '../../chunk-GJ557DGH.js';
9
9
  import '../../chunk-QQOWC53X.js';
10
10
  import '../../chunk-WOYBVPXK.js';
11
11
  import '../../chunk-NEHCPO53.js';
@@ -38,7 +38,7 @@ import '../../chunk-LIBXYD5Q.js';
38
38
  import '../../chunk-I23DDSU7.js';
39
39
  import '../../chunk-AH6YSYYT.js';
40
40
  import '../../chunk-NAAU5IWU.js';
41
- import '../../chunk-DSMGCFMJ.js';
41
+ import '../../chunk-POFFOUQW.js';
42
42
  import '../../chunk-7KIDDF3I.js';
43
43
  import '../../chunk-6FOHUNXR.js';
44
44
  import '../../chunk-PD2YEH3H.js';
@@ -1,9 +1,9 @@
1
- export { ServiceSuitePageKit } from '../../chunk-7XLZCXUL.js';
1
+ export { ServiceSuitePageKit } from '../../chunk-K4U67BVG.js';
2
2
  import '../../chunk-Z233ZQZE.js';
3
3
  import '../../chunk-VBZQ4DBE.js';
4
4
  import '../../chunk-FV2G6SAF.js';
5
5
  import '../../chunk-HZERHGBT.js';
6
- import '../../chunk-7A2RXKGH.js';
6
+ import '../../chunk-GJ557DGH.js';
7
7
  import '../../chunk-QQOWC53X.js';
8
8
  import '../../chunk-WOYBVPXK.js';
9
9
  import '../../chunk-NEHCPO53.js';
@@ -33,7 +33,7 @@ import '../../chunk-LIBXYD5Q.js';
33
33
  import '../../chunk-I23DDSU7.js';
34
34
  import '../../chunk-AH6YSYYT.js';
35
35
  import '../../chunk-NAAU5IWU.js';
36
- import '../../chunk-DSMGCFMJ.js';
36
+ import '../../chunk-POFFOUQW.js';
37
37
  import '../../chunk-7KIDDF3I.js';
38
38
  import '../../chunk-6FOHUNXR.js';
39
39
  import '../../chunk-PD2YEH3H.js';
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { MouseSpotlight } from '../../chunk-DSMGCFMJ.js';
2
+ import { MouseSpotlight } from '../../chunk-POFFOUQW.js';
3
3
  import '../../chunk-PD2YEH3H.js';
4
4
  import '../../chunk-CRY67BIF.js';
5
5
  import '../../chunk-HJC6U46F.js';
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- export { MouseGlow, MouseSpotlight } from '../../chunk-DSMGCFMJ.js';
2
+ export { MouseGlow, MouseSpotlight } from '../../chunk-POFFOUQW.js';
3
3
  import '../../chunk-PD2YEH3H.js';
4
4
  import '../../chunk-CRY67BIF.js';
5
5
  import '../../chunk-HJC6U46F.js';
@@ -83,6 +83,7 @@ export const nadicodeRules = {
83
83
  "nadicode/no-handcoded-empty-state": "error",
84
84
  "nadicode/no-handcoded-field": "error",
85
85
  "nadicode/require-catalog-component": "error",
86
+ "nadicode/require-catalog-import": "error",
86
87
  };
87
88
 
88
89
  function normalizePattern(pattern) {
@@ -70,6 +70,7 @@ import noHandcodedHeading from "./rules/no-handcoded-heading.js";
70
70
  import noHandcodedEmptyState from "./rules/no-handcoded-empty-state.js";
71
71
  import noHandcodedField from "./rules/no-handcoded-field.js";
72
72
  import requireCatalogComponent from "./rules/require-catalog-component.js";
73
+ import requireCatalogImport from "./rules/require-catalog-import.js";
73
74
 
74
75
  export { nadicodeRules, createAllowlistOverrides } from "./config.js";
75
76
 
@@ -147,5 +148,6 @@ export const nadicodePlugin = {
147
148
  "no-handcoded-empty-state": noHandcodedEmptyState,
148
149
  "no-handcoded-field": noHandcodedField,
149
150
  "require-catalog-component": requireCatalogComponent,
151
+ "require-catalog-import": requireCatalogImport,
150
152
  },
151
153
  };
@@ -0,0 +1,111 @@
1
+ import { RuleTester } from "eslint";
2
+ import { describe } from "vitest";
3
+
4
+ import rule from "../require-catalog-import.js";
5
+
6
+ const tester = new RuleTester({
7
+ languageOptions: {
8
+ ecmaVersion: "latest",
9
+ sourceType: "module",
10
+ },
11
+ });
12
+
13
+ describe("require-catalog-import", () => {
14
+ tester.run("require-catalog-import", rule, {
15
+ valid: [
16
+ // Catalog import (correct pattern)
17
+ {
18
+ code: "import { seedComponents } from '@/catalog/components';",
19
+ filename: "/repo/src/app/page.tsx",
20
+ },
21
+ // UI primitive (not a block/page-kit)
22
+ {
23
+ code: "import { Button } from '@/components/ui/Button';",
24
+ filename: "/repo/src/app/page.tsx",
25
+ },
26
+ // Type-only imports are allowed (importKind === "type"), but require TS parser to test.
27
+ // Verified in production via TypeScript ESLint config.
28
+ // Test files are exempt
29
+ {
30
+ code: "import { HeroBlock } from '@/components/blocks/HeroBlock';",
31
+ filename: "/repo/src/components/blocks/__tests__/HeroBlock.test.tsx",
32
+ },
33
+ {
34
+ code: "import { HeroBlock } from '../../blocks/HeroBlock';",
35
+ filename: "/repo/src/components/blocks/HeroBlock.spec.tsx",
36
+ },
37
+ // Catalog barrel itself is exempt
38
+ {
39
+ code: "import { HeroBlock } from '@/components/blocks/HeroBlock';",
40
+ filename: "/repo/src/catalog/components.tsx",
41
+ },
42
+ // Block source files are exempt (internal composition)
43
+ {
44
+ code: "import { AuthLayout } from '../blocks/AuthLayout';",
45
+ filename: "/repo/src/components/blocks/LoginBlock.tsx",
46
+ },
47
+ // Page-kit source files are exempt
48
+ {
49
+ code: "import { HeaderBlock } from '../blocks/HeaderBlock';",
50
+ filename: "/repo/src/components/page-kits/LandingPageKit.tsx",
51
+ },
52
+ ],
53
+ invalid: [
54
+ // Direct block import via absolute alias
55
+ {
56
+ code: "import { HeroBlock } from '@/components/blocks/HeroBlock';",
57
+ filename: "/repo/src/app/page.tsx",
58
+ errors: [
59
+ {
60
+ message:
61
+ "Import 'HeroBlock' from '@/catalog/components' via seedComponents. Direct block/page-kit imports are not allowed (ADR 0009).",
62
+ },
63
+ ],
64
+ },
65
+ // Direct page-kit import via absolute alias
66
+ {
67
+ code: "import { LandingPageKit } from '@/components/page-kits/LandingPageKit';",
68
+ filename: "/repo/src/app/page.tsx",
69
+ errors: [
70
+ {
71
+ message:
72
+ "Import 'LandingPageKit' from '@/catalog/components' via seedComponents. Direct block/page-kit imports are not allowed (ADR 0009).",
73
+ },
74
+ ],
75
+ },
76
+ // Relative block import from pages directory
77
+ {
78
+ code: "import { HeroBlock } from '../../blocks/HeroBlock';",
79
+ filename: "/repo/src/components/pages/showcase/BlocksShowcase.tsx",
80
+ errors: [
81
+ {
82
+ message:
83
+ "Import 'HeroBlock' from '@/catalog/components' via seedComponents. Direct block/page-kit imports are not allowed (ADR 0009).",
84
+ },
85
+ ],
86
+ },
87
+ // Relative block import (one level up)
88
+ {
89
+ code: "import { FooterBlock } from '../blocks/FooterBlock';",
90
+ filename: "/repo/src/components/pages/LandingPage.tsx",
91
+ errors: [
92
+ {
93
+ message:
94
+ "Import 'FooterBlock' from '@/catalog/components' via seedComponents. Direct block/page-kit imports are not allowed (ADR 0009).",
95
+ },
96
+ ],
97
+ },
98
+ // Nested block path (e.g., blocks/user/InviteUserModal)
99
+ {
100
+ code: "import { InviteUserModal } from '../../blocks/user/InviteUserModal';",
101
+ filename: "/repo/src/components/pages/settings/TeamPage.tsx",
102
+ errors: [
103
+ {
104
+ message:
105
+ "Import 'InviteUserModal' from '@/catalog/components' via seedComponents. Direct block/page-kit imports are not allowed (ADR 0009).",
106
+ },
107
+ ],
108
+ },
109
+ ],
110
+ });
111
+ });