@conscia-labs/design-system 1.0.3 → 1.2.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/README.md CHANGED
@@ -1,913 +1,189 @@
1
1
  # Conscia Design System
2
2
 
3
- The shared React component library for building clear, consistent, and accessible Conscia product experiences.
3
+ The shared React component library for clear, consistent, and accessible Conscia
4
+ product experiences.
4
5
 
5
- `@conscia-labs/design-system` brings Conscia’s visual foundation, reusable interface primitives, and common product patterns together in one package. It is designed for operational applications where information density, predictable interaction, and accessibility matter.
6
+ `@conscia-labs/design-system` provides semantic design tokens, reusable
7
+ primitives, and product patterns for operational applications.
6
8
 
7
9
  > **Package:** available publicly as [`@conscia-labs/design-system`](https://www.npmjs.com/package/@conscia-labs/design-system).
8
10
  >
9
- > **Current release:** `1.0.3` is the latest stable v1 release.
11
+ > **Current release:** `1.2.0` is the latest stable v1 release.
10
12
  >
11
- > **Migration:** upgrading an application to v1? Follow the [Design System v1 Migration Guide](https://github.com/conscia-labs/design-system/blob/main/docs/design-system-v1-migration.md).
13
+ > **Documentation:** browse the [live design system](https://conscia-labs.github.io/design-system/)
14
+ > for the complete component reference, examples, and usage guidance.
12
15
 
13
- ## Why this package exists
14
-
15
- Conscia products share more than colors and buttons. They share expectations about how navigation works, how data is presented, how status is communicated, and how users move through operational workflows.
16
-
17
- This package provides one executable source of truth for those decisions:
18
-
19
- ```text
20
- Foundation tokens
21
-
22
- Conscia primitives
23
-
24
- Reusable product patterns
25
-
26
- Conscia applications
27
- ```
28
-
29
- Use the design system to:
30
-
31
- - Build new Conscia product interfaces.
32
- - Keep existing products visually and behaviorally consistent.
33
- - Reuse accessible controls instead of recreating them per application.
34
- - Compose common shells, resource lists, detail views, tables, and state views.
35
- - Apply light, dark, and density preferences through shared semantic tokens.
36
-
37
- Product applications remain responsible for routing, authentication, permissions, data fetching, mutations, validation, and business-specific behavior.
38
-
39
- ## Migrating to v1.0.0
40
-
41
- Version `1.0.0` is a clean API and implementation break. Component concepts and
42
- public names remain recognizable, but Radix and shadcn implementation details
43
- are no longer part of the contract. In particular:
44
-
45
- - Replace `asChild` with the documented `render` prop where custom-host composition is required.
46
- - Replace legacy token utilities such as `bg-primary`, `bg-muted`, and `border-input` with the canonical Conscia semantic roles documented in the migration guide.
47
- - Do not add `@base-ui/react`, `@radix-ui/*`, or copied shadcn components to the application; Base UI is bundled and used internally by the design system.
48
- - Recheck dialogs, sheets, menus, selects, comboboxes, tabs, tooltips, forms, tables, and icon-only actions against the application’s keyboard and accessibility tests.
49
-
50
- The complete, agent-readable upgrade runbook is [`docs/design-system-v1-migration.md`](./docs/design-system-v1-migration.md) in this repository. You can also open the [migration guide on GitHub](https://github.com/conscia-labs/design-system/blob/main/docs/design-system-v1-migration.md). The guide is intentionally kept in the repository’s `docs/` directory rather than the npm tarball, so the GitHub link is the durable location for app owners and coding agents.
51
-
52
- ## What is included
53
-
54
- ### Foundation
55
-
56
- Semantic CSS variables for:
57
-
58
- - Light and dark appearance.
59
- - Comfortable and compact density.
60
- - Typography, spacing, radius, and elevation.
61
- - Canvas, surface, border, and text roles.
62
- - Brand, selection, information, success, warning, and danger semantics.
63
-
64
- ### Primitives
65
-
66
- Reusable Conscia-owned interface building blocks composed from native React
67
- markup and Base UI behavior where interaction complexity requires it:
68
-
69
- - Alert
70
- - AlertDialog
71
- - Avatar
72
- - Badge
73
- - Button
74
- - LoadingButton
75
- - IconButton
76
- - Card
77
- - Checkbox
78
- - Collapsible
79
- - Dialog
80
- - Dropdown menu
81
- - Field and form controls
82
- - Input and textarea
83
- - Select, FormSelect, and searchable select
84
- - Sheet
85
- - Skeleton
86
- - Switch
87
- - Table
88
- - Tabs and navigation tabs
89
- - Tooltip
90
- - Popover
91
- - Shortcut hint
92
- - Spinner
93
- - Avatar group
94
- - Filter chip
95
- - Toast provider and viewport
96
-
97
- ### Patterns
98
-
99
- Higher-level compositions for recurring product workflows:
100
-
101
- - Application shell and sidebar
102
- - Sidebar navigation
103
- - Page frame, header, and toolbar
104
- - Data table and pagination
105
- - Resource summaries and detail sections
106
- - Confirmation dialogs
107
- - Empty, loading, and error states
108
- - Activity lists and metric bands
109
- - Code blocks and value meters
110
- - Command palette
111
- - Filter bar
112
-
113
- ### Supporting interaction patterns
114
-
115
- #### Command palette
116
-
117
- `CommandPalette` accepts an explicit list of commands, filters labels and
118
- keywords, and supports keyboard navigation without a global command registry:
119
-
120
- ```tsx
121
- import { Button, CommandPalette } from "@conscia-labs/design-system";
122
-
123
- <CommandPalette
124
- items={[{ id: "settings", label: "Open settings", keywords: ["preferences"] }]}
125
- onSelect={(item) => openCommand(item.id)}
126
- trigger={<Button variant="outline">Open commands</Button>}
127
- />
128
- ```
129
-
130
- #### Toasts
131
-
132
- Toasts are opt-in. Mount one provider and viewport, then use `useToast` from a
133
- descendant component:
134
-
135
- ```tsx
136
- import {
137
- Button,
138
- ToastProvider,
139
- ToastViewport,
140
- useToast,
141
- } from "@conscia-labs/design-system";
142
-
143
- function SaveButton() {
144
- const { add } = useToast();
145
- return (
146
- <Button onClick={() => add({ title: "Saved", variant: "success" })}>
147
- Save
148
- </Button>
149
- );
150
- }
151
-
152
- function App() {
153
- return (
154
- <ToastProvider>
155
- <SaveButton />
156
- <ToastViewport />
157
- </ToastProvider>
158
- );
159
- }
160
- ```
161
-
162
- ## Quick start
163
-
164
- ### 1. Install the package
165
-
166
- For v1, install the explicit `1.0.0` range:
167
-
168
- Using pnpm:
169
-
170
- ```bash
171
- pnpm add @conscia-labs/design-system@^1.0.0
172
- ```
173
-
174
- Using npm:
16
+ ## Install
175
17
 
176
18
  ```bash
177
- npm install @conscia-labs/design-system@^1.0.0
19
+ pnpm add @conscia-labs/design-system
178
20
  ```
179
21
 
180
- The package targets React 19 and ships as modern ESM with TypeScript
181
- declarations. The supported application integration requires Tailwind CSS v4.
182
- The package declares Tailwind v4 as an optional peer so non-Tailwind consumers
183
- can use the separate standalone stylesheet without installing Tailwind.
22
+ The package requires React 19 and React DOM 19. Tailwind CSS 4 is optional for
23
+ consumers that use the Tailwind integration.
184
24
 
185
- ### 2. Load Tailwind and the design-system integration
186
-
187
- Import both once in your application’s global stylesheet:
188
-
189
- ```css
190
- @import "tailwindcss";
191
- @import "@conscia-labs/design-system/tailwind.css";
192
- ```
193
-
194
- `tailwind.css` imports the design tokens, theme registration, variants,
195
- keyframes, base rules, and bespoke component CSS. It also contains a
196
- package-relative `@source` for the published JavaScript, so the application’s
197
- Tailwind compiler generates the utilities used by both the application and the
198
- design system in one cascade. Do not add a separate `node_modules` source path.
199
-
200
- The deprecated `styles.css` export remains as a foundation-only compatibility
201
- alias. It does not contain preflight or generated utilities.
202
-
203
- ### Non-Tailwind applications
204
-
205
- Applications that do not run Tailwind can opt into the complete precompiled
206
- bundle:
207
-
208
- ```css
209
- @import "@conscia-labs/design-system/standalone.css";
210
- ```
211
-
212
- Tailwind applications must not import `standalone.css`, because its preflight
213
- and generic utilities would compete with the application’s generated CSS.
214
-
215
- ### 3. Set the root appearance and density
216
-
217
- Apply the default preferences to the root document element:
218
-
219
- ```tsx
220
- export function RootLayout({
221
- children,
222
- }: Readonly<{
223
- children: React.ReactNode;
224
- }>) {
225
- return (
226
- <html
227
- lang="en"
228
- data-appearance="system"
229
- data-density="comfortable"
230
- suppressHydrationWarning
231
- >
232
- <body>{children}</body>
233
- </html>
234
- );
235
- }
236
- ```
237
-
238
- Supported values:
239
-
240
- | Preference | Values |
241
- | --- | --- |
242
- | `data-appearance` | `light`, `dark`, `system` |
243
- | `data-density` | `comfortable`, `compact`, `operational` |
244
-
245
- Comfortable density is the default for general product interfaces. Compact density is intended for high-volume operational workflows such as inventories and data-heavy administration.
246
-
247
- Operational density is an explicit opt-in preset for interfaces that prioritize
248
- information throughput and deliberate hierarchy: admin pages, chat shells,
249
- connectors, catalogs, and Workspace-like surfaces. It tightens the shared type
250
- scale to approximately 13px body/UI text, 12px metadata, 15–16px section titles,
251
- and a 26px page title with a 650 weight, `-0.04em` tracking, and `1.08` line
252
- height. It also tightens reusable spacing and control rhythm while preserving
253
- the existing touch-target, focus-ring, color, radius, and shadow contracts.
254
-
255
- ```tsx
256
- <html data-appearance="system" data-density="operational">
257
- {/* admin, chat, catalog, connector, or workspace-like application */}
258
- </html>
259
- ```
260
-
261
- Use comfortable density for general product reading and mixed-purpose pages.
262
- Use compact density when an existing consumer already depends on its smaller
263
- layout preset. Use operational density when the interface needs Workspace-like
264
- hierarchy across shared components. Do not make 13px the global default: that
265
- would make narrative, setup, and accessibility-critical product surfaces feel
266
- compressed.
25
+ ## Quick start
267
26
 
268
- ### 4. Use a component
27
+ Import public components from the package root:
269
28
 
270
29
  ```tsx
271
30
  import {
272
31
  Button,
273
- Card,
274
- CardContent,
275
- CardDescription,
276
- CardHeader,
277
- CardTitle,
278
32
  Field,
279
33
  FieldDescription,
280
34
  FieldLabel,
281
35
  Input,
282
36
  } from "@conscia-labs/design-system";
283
37
 
284
- export function CreateConnectionCard() {
38
+ export function ConnectionForm() {
285
39
  return (
286
- <Card className="max-w-lg">
287
- <CardHeader>
288
- <CardTitle>Create connection</CardTitle>
289
- <CardDescription>
290
- Connect a provider to make its resources available to Conscia.
291
- </CardDescription>
292
- </CardHeader>
293
-
294
- <CardContent>
295
- <form className="grid gap-5">
296
- <Field>
297
- <FieldLabel htmlFor="connection-name">Name</FieldLabel>
298
- <Input
299
- id="connection-name"
300
- name="name"
301
- placeholder="Production connection"
302
- />
303
- <FieldDescription>
304
- Use a name that helps operators identify this connection.
305
- </FieldDescription>
306
- </Field>
307
-
308
- <Button type="submit">Create connection</Button>
309
- </form>
310
- </CardContent>
311
- </Card>
40
+ <form className="grid gap-5">
41
+ <Field>
42
+ <FieldLabel htmlFor="connection-name">Name</FieldLabel>
43
+ <Input id="connection-name" name="name" />
44
+ <FieldDescription>Use a name operators will recognize.</FieldDescription>
45
+ </Field>
46
+ <Button type="submit">Create connection</Button>
47
+ </form>
312
48
  );
313
49
  }
314
50
  ```
315
51
 
316
- ### Text-in-track switches
317
-
318
- Use `LabeledSwitch` when the switch state should be visible inside the control.
319
- It keeps Base UI’s switch behavior and accepts any React node for either label:
52
+ Use the [component reference](https://conscia-labs.github.io/design-system/components/)
53
+ for complete anatomy, options, states, and examples.
320
54
 
321
- ```tsx
322
- import { LabeledSwitch } from "@conscia-labs/design-system";
323
-
324
- <LabeledSwitch
325
- aria-label="Deployment status"
326
- defaultChecked
327
- onLabel="ENABLED"
328
- offLabel="DISABLED"
329
- />
330
- ```
55
+ ## Styles and preferences
331
56
 
332
- `Switch` also accepts `onLabel` and `offLabel` when a single API needs to support
333
- both the compact unlabeled style and the text-in-track style. If a label is
334
- provided without its pair, the missing label defaults to `ON` or `OFF`.
335
-
336
- ### Loading buttons
337
-
338
- Use `LoadingButton` for async actions that need stable button layout while a
339
- mutation is pending. It disables the button, sets `aria-busy`, and replaces the
340
- normal content with a small spinner and `pendingLabel`:
341
-
342
- ```tsx
343
- import { LoadingButton } from "@conscia-labs/design-system";
344
-
345
- <LoadingButton pending={saveMutation.isPending} pendingLabel="Saving…">
346
- Save changes
347
- </LoadingButton>
348
- ```
349
-
350
- ## Building an application shell
351
-
352
- The shared shell owns presentation and responsive behavior. The host application supplies routes, links, user context, and actions.
353
-
354
- ```tsx
355
- import {
356
- AppShell,
357
- AppSidebar,
358
- AppSidebarContent,
359
- AppSidebarHeader,
360
- MainRegion,
361
- PageContent,
362
- PageFrame,
363
- PageHeader,
364
- ProductIdentity,
365
- SidebarTrigger,
366
- TopBar,
367
- } from "@conscia-labs/design-system";
368
-
369
- export function ProductShell({
370
- navigation,
371
- children,
372
- }: {
373
- navigation: React.ReactNode;
374
- children: React.ReactNode;
375
- }) {
376
- return (
377
- <AppShell>
378
- <AppSidebar>
379
- <AppSidebarHeader>
380
- <ProductIdentity
381
- label="Conscia"
382
- description="Administration"
383
- />
384
- </AppSidebarHeader>
385
- <AppSidebarContent>{navigation}</AppSidebarContent>
386
- </AppSidebar>
387
-
388
- <MainRegion>
389
- <TopBar>
390
- {/* Keep the toggle in the topbar; it must remain visible when the sidebar collapses. */}
391
- <SidebarTrigger />
392
- </TopBar>
393
-
394
- <PageFrame width="wide">
395
- <PageContent>
396
- <PageHeader
397
- title="Connections"
398
- description="Manage provider connections and their availability."
399
- />
400
- {children}
401
- </PageContent>
402
- </PageFrame>
403
- </MainRegion>
404
- </AppShell>
405
- );
406
- }
407
- ```
408
-
409
- ## Building a workbench surface
410
-
411
- Workbench patterns provide a reusable composition for applications that need
412
- global navigation, a contextual rail, a primary work area, and an inspector.
413
- They own the shell geometry, responsive rail behavior, resource-row rhythm,
414
- and inspector hierarchy; the host application supplies its routes, data, and
415
- actions.
416
-
417
- ```tsx
418
- import {
419
- ResourceRow,
420
- ResourceRowContent,
421
- ResourceRowIcon,
422
- ResourceRowMeta,
423
- ResourceRowTitle,
424
- WorkbenchInspector,
425
- WorkbenchInspectorSection,
426
- WorkbenchMain,
427
- WorkbenchRail,
428
- WorkbenchSection,
429
- WorkbenchSectionHeader,
430
- WorkbenchShell,
431
- } from "@conscia-labs/design-system";
432
-
433
- export function WorkspaceSurface({ children }: { children: React.ReactNode }) {
434
- return (
435
- <WorkbenchShell data-density="operational">
436
- <WorkbenchRail variant="global">Global navigation</WorkbenchRail>
437
- <WorkbenchRail variant="secondary">Contextual navigation</WorkbenchRail>
438
- <WorkbenchMain>
439
- <WorkbenchSection>
440
- <WorkbenchSectionHeader title="Recent conversations" metadata="12" />
441
- <ResourceRow as="a" href="/conversations/1">
442
- <ResourceRowIcon aria-hidden="true" />
443
- <ResourceRowContent>
444
- <ResourceRowTitle>Project brief</ResourceRowTitle>
445
- <ResourceRowMeta>Updated just now</ResourceRowMeta>
446
- </ResourceRowContent>
447
- </ResourceRow>
448
- </WorkbenchSection>
449
- {children}
450
- </WorkbenchMain>
451
- <WorkbenchInspector>
452
- <WorkbenchInspectorSection label="Details">
453
- {/* Product-owned metadata and actions */}
454
- </WorkbenchInspectorSection>
455
- </WorkbenchInspector>
456
- </WorkbenchShell>
457
- );
458
- }
459
- ```
460
-
461
- Use `WorkbenchMobileToolbar` and `WorkbenchBackdrop` when a contextual rail
462
- needs an explicit mobile drawer trigger. Keep product-specific content styles
463
- local, but use the shared workbench tokens and row primitives instead of
464
- recreating shell widths, inspector padding, focus states, or resource-list
465
- typography.
466
-
467
- ### Typography and font loading
468
-
469
- The design system declares the open-source Source Sans 3 variable font as a
470
- runtime dependency and loads it through its CSS entry points. Consumers should
471
- import the published `tailwind.css` or `styles.css` entry and should not add a
472
- separate font download. The shared hierarchy uses a deliberate `400 / 500 /
473
- 600` weight ladder; applications should avoid replacing it with arbitrary
474
- fractional weights.
475
- Applications may override `--font-sans` only when a deliberate product-specific
476
- type decision has been made.
477
-
478
- ### Typography hierarchy
479
-
480
- Use the shared type scale by role:
481
-
482
- - `--ds-display-title` is the responsive display or welcome scale for
483
- high-level entry points.
484
- - `--ds-page-title` is for page-level headings and `PageHeader` titles.
485
- - `--ds-section-title` is for sections within a page or resource detail.
486
- - `--ds-body` is the default application body size.
487
- - `--ds-metadata` is for supporting context such as descriptions, timestamps,
488
- counts, and secondary organization text.
489
- - `--ds-menu-label-size` is intentionally compact and is reserved for menu
490
- labels and compact option descriptions, not normal body copy.
491
-
492
- Prefer these tokens over local `clamp()`, pixel, or one-off font-size values.
493
- Product-specific layout styles may still control wrapping, maximum width, or
494
- composition when the content requires it.
495
-
496
- Operational consumers can use the token-backed `ds-type-*` utilities without
497
- creating a parallel styling system:
498
-
499
- | Role | Utility | Comfortable baseline | Operational intent |
500
- | --- | --- | --- | --- |
501
- | Page/display title | `ds-type-page-title`, `ds-type-display-title` | 28px / 56px | 26px / responsive display, 650 weight, tight tracking |
502
- | Section title | `ds-type-section-title` | 17px | 16px, 650 weight, tighter line-height |
503
- | Body/UI | `ds-type-body`, `ds-type-ui` | 15px / 14px | 13px with a 1.4–1.5 rhythm |
504
- | Metadata | `ds-type-metadata` | 13px | 12px supporting context |
505
- | Menu/eyebrow | `ds-type-menu-item`, `ds-type-menu-label`, `ds-type-eyebrow` | existing compact roles | compact labels with deliberate tracking |
506
- | Controls | `ds-type-control`, `ds-type-button` | 14px | 13px, with stronger button weight |
507
-
508
- The utilities resolve through CSS custom properties, so light and dark themes
509
- retain the same semantic colors and focus behavior. Applications should use
510
- the preset and shared utilities for type/rhythm, while keeping product-specific
511
- composition, data, and layout ownership local.
512
-
513
- Sidebar section labels are intentionally smaller than navigation rows and
514
- slightly more weighted: comfortable density uses a `12px / 600 / 16px`
515
- contract with restrained tracking, while compact density reduces the size
516
- without changing the role. Keep navigation labels at the shared row size and
517
- weight them only when active.
518
-
519
- ### BrandIcon
520
-
521
- `BrandIcon` is the shared symbol-only Conscia mark. It embeds the supplied
522
- 240×240 symbol geometry so published consumers do not need to manage an asset
523
- path. The default treatment uses the existing foreground role in light mode
524
- and the existing white brand treatment in dark mode. Use it for symbol-only
525
- lockups, collapsed navigation identity, and other shared brand placements.
526
-
527
- The icon is decorative by default. Add an `aria-label` when the mark conveys
528
- meaning without adjacent text, and use `className` to control its size.
529
-
530
- ### BrandWordmark
531
-
532
- `BrandWordmark` is the shared no-tagline Conscia lockup. It embeds the supplied
533
- 496×113 vector geometry and uses `currentColor`, so applications do not need
534
- separate black and white assets or runtime asset paths. The default treatment
535
- matches `BrandIcon`: foreground in light mode and white in dark mode.
536
-
537
- The wordmark is decorative by default. Add an `aria-label` when it is the only
538
- accessible naming content, and use `className` to control its width.
539
-
540
- ```tsx
541
- <BrandWordmark aria-label="Conscia" className="w-36" />
542
- ```
543
-
544
- ### Sidebar variants and semantic surfaces
545
-
546
- `AppSidebar` keeps the historical dark treatment by default. Consumers that
547
- want the sidebar to follow the application appearance can opt into the
548
- refreshed hierarchy with `variant="auto"`; `variant="light"` is available for
549
- an explicitly light sidebar.
550
-
551
- ```tsx
552
- <AppShell>
553
- <AppSidebar variant="auto">
554
- <AppSidebarHeader>
555
- <ProductIdentity label="Conscia" description="Administration" />
556
- </AppSidebarHeader>
557
- <AppSidebarContent>{navigation}</AppSidebarContent>
558
- <AppSidebarFooter>{accountMenu}</AppSidebarFooter>
559
- </AppSidebar>
560
- </AppShell>
561
- ```
562
-
563
- The sidebar scope exposes reusable semantic roles for its canvas, header,
564
- content, hover, active, search, footer, text, icon, group label, count,
565
- border, and focus-ring roles.
566
- Use the generated utilities such as `bg-sidebar-canvas`,
567
- `bg-sidebar-hover`, `text-sidebar-primary-text`, and
568
- `text-sidebar-metadata-text` in shared or application-owned compositions.
569
-
570
- Form controls and outline buttons use `bg-surface-control`, with
571
- `bg-surface-control-hover` for the outline hover state. These semantic surfaces
572
- are intentionally theme-aware: the base uses the muted surface in light mode
573
- and the raised surface in dark mode; hover reverses that relationship so the
574
- control remains visibly interactive without introducing a new color palette.
575
-
576
- Button variants provide their foreground role explicitly: primary, secondary,
577
- destructive, outline, ghost, and link content do not depend on an ancestor's
578
- text color. The destructive variant uses the existing dark danger background
579
- and foreground pair in dark mode because the bright danger role is not suitable
580
- for white text there. Consumer classes remain the final override when a
581
- product-specific treatment is intentional.
582
-
583
- Dark mode uses a calm charcoal surface ladder rather than a pure-black canvas:
584
-
585
- | Role | Token | Dark value |
586
- | --- | --- | --- |
587
- | Application canvas | `--canvas` | `#17191c` |
588
- | Standard surface | `--surface` | `#1d2024` |
589
- | Raised surface and control | `--surface-raised` / `--surface-control` | `#24272c` |
590
- | Muted and control-hover surface | `--surface-muted` / `--surface-control-hover` | `#282b31` |
591
- | Floating surface | `--surface-floating` | `#2c2f36` |
592
- | Overlay surface | `--surface-overlay` | `#31343a` |
593
-
594
- The adjacent steps are intentionally close enough for a calm reading
595
- environment while remaining distinguishable through luminance, borders, and
596
- elevation. `--text-primary` is a soft high-priority text role (`#eff1f4`), while
597
- `--text-secondary`, `--text-supporting`, and `--text-muted` step down to
598
- `#d4d8df`, `#b3bac5`, and `#929aa7`. Use the semantic `bg-surface-*` and
599
- `text-*` utilities instead of copying these values into an application. The
600
- dark sidebar remains its established Conscia identity surface; inputs use the
601
- shared control surface and popovers/drawers use the floating or overlay roles.
602
-
603
- `SidebarSearch` owns only the trigger, expanded field, Escape handling, and
604
- focus handoff. Applications provide the query value and filtering behavior.
605
- `NavigationGroup` accepts an optional `count`; application-owned group labels
606
- can still be supplied as arbitrary React nodes. Routing, conversation rows,
607
- row actions, account menus, permissions, and appearance controls remain
608
- application-owned.
609
-
610
- The shell uses `--ds-topbar-height` as the shared chrome-height contract. The
611
- sidebar header aliases the historical `--ds-sidebar-header-height` token to the
612
- same value, so the two rails stay aligned. `TopBar` also owns shared horizontal
613
- padding through its responsive `--ds-topbar-padding-x` tokens; applications
614
- should not add a normal-use hardcoded height or padding override. Keep leading
615
- and trailing actions inside the topbar so icons and labels share the same
616
- vertical rhythm and visible focus treatment. `SidebarTrigger` should be
617
- rendered as a child of `TopBar`, never inside `AppSidebar`; the topbar remains
618
- mounted when the sidebar enters collapsed or mobile states.
619
-
620
- Sidebar section labels use the field-label size with a restrained medium weight
621
- and tracking. Navigation rows retain the shared comfortable/touch heights,
622
- while `--ds-sidebar-item-gap`, `--ds-sidebar-label-gap`, and
623
- `--ds-sidebar-group-gap` control list, label, and group rhythm. Use the shared
624
- sidebar semantic utilities for surfaces, text, icons, borders, and focus rings;
625
- keep conversation data, organization names, and product-specific row actions
626
- application-owned.
627
-
628
- For migration, replace a consuming application's light-only `--sidebar-*`
629
- root override with `variant="auto"` on its shared `AppSidebar`. Remove
630
- descendant opacity and background overrides as each shell adopts the semantic
631
- aliases. Keep product-specific selectors only where they encode behavior or
632
- content rather than shared sidebar presentation.
633
-
634
- The ownership boundary is:
635
-
636
- | Shared design system | Application-owned |
637
- | --- | --- |
638
- | Sidebar variant tokens, surface hierarchy, geometry, responsive drawer, focus states, active/hover/disabled styling, tooltips, and search affordance behavior | Routes, permissions, navigation data, query/filter state, conversation or inventory data, row actions, account/profile menus, sign-out, and product-specific persistence keys |
639
- | `NavigationGroup` keyboard expansion and `SidebarNavigation` collapsed flyouts | Group labels/content, link destinations, active-route calculation, and business-specific empty states |
640
-
641
- ## Choosing the right component
642
-
643
- ### Table or DataTable?
644
-
645
- Use `Table` for small, bounded, read-only relationships.
646
-
647
- Use `DataTable` when an operational inventory needs one or more of:
648
-
649
- - Sorting
650
- - Pagination
651
- - Row selection
652
- - Row actions
653
- - Clickable rows
654
- - Dedicated mobile rendering
655
-
656
- Applications own filters, URL state, API requests, and permissions. When data is paginated by a server, enable manual sorting and manual pagination together so a single downloaded page is never presented as a completely sorted dataset.
657
-
658
- ### Tabs or NavigationTabs?
659
-
660
- Use `Tabs` when content panels change in place without navigation.
661
-
662
- ```tsx
663
- <Tabs defaultValue="overview">
664
- <TabsList>
665
- <TabsTrigger value="overview">Overview</TabsTrigger>
666
- <TabsTrigger value="activity">Activity</TabsTrigger>
667
- </TabsList>
668
- <TabsContent value="overview">...</TabsContent>
669
- <TabsContent value="activity">...</TabsContent>
670
- </Tabs>
671
- ```
672
-
673
- Use `NavigationTabs` for route-backed sections. The active destination is represented with `aria-current="page"`.
674
-
675
- ```tsx
676
- <NavigationTabs aria-label="Connection sections">
677
- <NavigationTabsList>
678
- <NavigationTab href="/connections/123" active>
679
- Overview
680
- </NavigationTab>
681
- <NavigationTab href="/connections/123/activity">
682
- Activity
683
- </NavigationTab>
684
- </NavigationTabsList>
685
- </NavigationTabs>
686
- ```
687
-
688
- ### Select or SearchableSelect?
689
-
690
- Use `Select` for short, familiar option lists.
691
-
692
- Use `SearchableSelect` when users need to find an item in a longer list by label, description, or keywords.
693
-
694
- Both `FormSelect` and `SearchableSelect` contribute a named value to a native
695
- HTML form when their `name` prop is provided.
696
-
697
- ### Nested overlays
698
-
699
- Portaled controls can be used inside `Dialog` and `Sheet` without clipping
700
- their popup. The popup Positioner is mounted in a Base UI portal and uses the
701
- shared overlay layer hierarchy:
702
-
703
- | Layer | Components | z-index |
704
- | --- | --- | ---: |
705
- | Modal | `Dialog`, `Sheet`, `AlertDialog` | 40 |
706
- | Popup | `Select`, `Popover`, `SearchableSelect`, `DropdownMenu` | 50 |
707
- | Transient | `Toast`, `Tooltip` | 100 |
708
-
709
- Base UI `Select` is modal by default, so `FormSelect` preserves that default
710
- for backwards compatibility. Set `modal={false}` when a `Select` or
711
- `FormSelect` is nested in a modal surface so it does not add a second backdrop,
712
- focus boundary, or inert page state. `SearchableSelect` also exposes `modal`
713
- and preserves Combobox's current non-modal default:
714
-
715
- ```tsx
716
- <Dialog open={open} onOpenChange={setOpen}>
717
- <DialogContent>
718
- <DialogBody className="overflow-y-auto">
719
- <FormSelect modal={false} name="vendor" options={vendorOptions} />
720
- <SearchableSelect modal={false} name="model" options={modelOptions} onValueChange={setModel} />
721
- </DialogBody>
722
- </DialogContent>
723
- </Dialog>
724
- ```
725
-
726
- `Select`, `Popover`, and `DropdownMenu` already forward their Base UI root
727
- props, including `modal`. Use the same `modal={false}` setting for those
728
- controls when they are nested. No consuming-app z-index override or portal
729
- adapter is required.
730
-
731
- ## Semantic color
732
-
733
- Color communicates meaning rather than palette choice:
734
-
735
- | Role | Purpose |
736
- | --- | --- |
737
- | `brand` | Conscia identity and signature moments |
738
- | `brand-secondary` | Supporting brand expression |
739
- | `action-*` | Primary actions and their hover, active, foreground, and tinted-background roles |
740
- | `selection-*` | Current selection or active destination |
741
- | `information-*` | Informational messages and evidence |
742
- | `success-*` | Healthy, verified, approved, or completed states |
743
- | `warning-*` | Conditions requiring attention |
744
- | `danger-*` | Destructive actions, failures, and critical states |
745
- | `neutral-*` | Decoration and non-semantic surfaces |
746
-
747
- Do not use success styling merely because something is enabled or active. Success should communicate positive operational evidence.
748
-
749
- ## Customizing tokens
750
-
751
- Override semantic variables after importing the package stylesheet:
57
+ Tailwind CSS 4 applications import the integration once from their global
58
+ stylesheet:
752
59
 
753
60
  ```css
754
61
  @import "tailwindcss";
755
62
  @import "@conscia-labs/design-system/tailwind.css";
756
-
757
- :root {
758
- --ds-space-page: 3rem;
759
- --ds-radius-surface: 0.625rem;
760
- }
761
63
  ```
762
64
 
763
- Prefer semantic variables over component-specific descendant selectors. This keeps appearance and density behavior consistent across primitives and patterns.
764
-
765
- ## Accessibility
766
-
767
- Accessibility is part of the component contract:
768
-
769
- - Base UI-backed components provide keyboard interaction and focus management.
770
- - Route-backed navigation uses semantic links and `aria-current`.
771
- - Dialogs and sheets provide labelled modal structure.
772
- - Form controls expose native labelling and validation attributes.
773
- - Motion is reduced when the user requests `prefers-reduced-motion`.
774
- - Semantic status colors are designed to be accompanied by text, icons, or labels.
65
+ Applications that do not run Tailwind should use the precompiled bundle instead:
775
66
 
776
- Applications are still responsible for meaningful labels, heading order, form error relationships, alternative text, and accessible business workflows.
777
-
778
- ## Framework notes
67
+ ```css
68
+ @import "@conscia-labs/design-system/standalone.css";
69
+ ```
779
70
 
780
- ### Next.js
71
+ Do not import `standalone.css` in a Tailwind application. Its preflight and
72
+ utilities would compete with the application's generated CSS.
781
73
 
782
- Import the application global stylesheet from the root layout:
74
+ Set shared appearance and density preferences on the document root:
783
75
 
784
76
  ```tsx
785
- import "./globals.css";
77
+ <html
78
+ lang="en"
79
+ data-appearance="system"
80
+ data-density="comfortable"
81
+ suppressHydrationWarning
82
+ >
786
83
  ```
787
84
 
788
- The component entries are explicit client-only boundaries, while server-safe
789
- code is published separately. For example, React Server Components should
790
- import `cn` from `@conscia-labs/design-system/utils`. The package does not need
791
- `transpilePackages`; Next.js will establish a client boundary for component
792
- exports.
85
+ Appearance values are `light`, `dark`, and `system`. Density values are
86
+ `comfortable`, `compact`, and `operational`.
793
87
 
794
- ### Other React applications
88
+ Use semantic Conscia tokens and utilities rather than copying palette values
89
+ into an application. See the [foundation documentation](https://conscia-labs.github.io/design-system/foundation/)
90
+ for the token contract.
795
91
 
796
- The primitives are router-independent and can be used with Vite or other
797
- ESM-capable React build systems. Route-backed patterns accept
798
- application-supplied links rather than depending on Next.js navigation.
92
+ Conscia burgundy is the primary identity surface: pair `bg-brand` with
93
+ `text-brand-foreground`. Use `brand-accent` for blue emphasis and
94
+ `brand-supporting-*` for restrained green expression. The low-level palette
95
+ variables preserve the official colors, while semantic blue and green roles
96
+ adapt where dark-mode contrast requires it.
799
97
 
800
- ### Focused imports
801
-
802
- The root package is the simplest import path. Public subpath exports are also
803
- available when an application wants a more explicit dependency boundary:
804
-
805
- ```tsx
806
- import { Button } from "@conscia-labs/design-system/primitives";
807
- import { DataTable } from "@conscia-labs/design-system/patterns";
808
- import {
809
- applyConsciaPreferences,
810
- } from "@conscia-labs/design-system/foundation";
811
- import { cn } from "@conscia-labs/design-system/utils";
812
- ```
98
+ ## Choose the right level
813
99
 
814
- All public entry points are ESM-only.
100
+ - Use **patterns** for recurring product workflows such as application shells,
101
+ page composition, data tables, dashboards, resource details, and workbenches.
102
+ - Use **primitives** for application-specific compositions such as buttons,
103
+ fields, inputs, selects, dialogs, sheets, tabs, tables, badges, and states.
104
+ - Keep routing, authentication, permissions, data fetching, mutations, and
105
+ business-specific validation in the product application.
815
106
 
816
- ## Local development
107
+ The [pattern catalog](https://conscia-labs.github.io/design-system/patterns/),
108
+ [component catalog](https://conscia-labs.github.io/design-system/components/),
109
+ and [machine-readable inventory](https://conscia-labs.github.io/design-system/agent-manifest.json)
110
+ cover the complete public surface.
817
111
 
818
- Install dependencies:
112
+ ## Public entrypoints
819
113
 
820
- ```bash
821
- pnpm install
114
+ ```text
115
+ @conscia-labs/design-system Components and public composition
116
+ @conscia-labs/design-system/foundation Semantic tokens and foundation exports
117
+ @conscia-labs/design-system/patterns Reusable product patterns
118
+ @conscia-labs/design-system/primitives Primitive components and anatomy
119
+ @conscia-labs/design-system/utils Shared utilities
822
120
  ```
823
121
 
824
- Run the playground:
122
+ The package also exports `tailwind.css`, `standalone.css`, `foundation.css`,
123
+ `styles.css` (compatibility), `agent-guide.md`, `agent-manifest.json`, and
124
+ `package.json`.
825
125
 
826
- ```bash
827
- pnpm dev:playground
828
- ```
126
+ ## Accessibility and composition
829
127
 
830
- The playground is available at [http://localhost:3020](http://localhost:3020).
128
+ Interactive controls require an accessible name, visible focus, and keyboard
129
+ behavior appropriate to their role. Use the documented field anatomy for labels,
130
+ descriptions, and errors. When a popup is nested inside a modal surface, use the
131
+ documented `modal={false}` option where supported.
831
132
 
832
- Run the project checks:
133
+ The library uses Base UI internally for behavior-heavy components. Consumers
134
+ should import the design-system API and should not install Base UI, Radix, or
135
+ copied shadcn component source to reproduce its internals.
833
136
 
834
- ```bash
835
- pnpm lint
836
- pnpm lint:playground
837
- pnpm typecheck
838
- pnpm typecheck:playground
839
- pnpm test
840
- pnpm test:package
841
- pnpm build:playground
842
- ```
137
+ ## Upgrading to v1
843
138
 
844
- `pnpm test:package` creates the production artifacts, validates the package
845
- manifest, and imports the package through its public export map. The npm
846
- `prepack` hook runs the same gate before a tarball can be produced.
139
+ Version 1 is a clean API and implementation break. Component concepts and public
140
+ names remain recognizable, but old Radix/shadcn implementation details are not
141
+ part of the contract:
847
142
 
848
- Reusable foundation, primitive, and pattern code belongs in `src`. Fixtures and visual documentation belong in `playground`.
143
+ - Use the documented `render` prop instead of the removed `asChild` API.
144
+ - Use Conscia semantic token roles instead of legacy utilities such as
145
+ `bg-primary`, `bg-muted`, and `border-input`.
146
+ - Do not add `@base-ui/react`, `@radix-ui/*`, or copied shadcn components to the
147
+ application.
148
+ - Recheck dialogs, sheets, menus, selects, forms, tables, and icon-only actions
149
+ against the application's keyboard and accessibility tests.
849
150
 
850
- ## Releasing
151
+ Read the complete [v1 migration guide](https://github.com/conscia-labs/design-system/blob/main/docs/design-system-v1-migration.md)
152
+ for the API and application-owner runbook.
851
153
 
852
- The `1.0.0` release is the first public v1 package. Releases are published from
853
- GitHub Actions through npm trusted publishing, with the release tag required to
854
- match the version in `package.json` exactly. npm’s trusted-publishing flow
855
- provides short-lived CI authentication and provenance for the published
856
- package.
154
+ ## Agent support
857
155
 
858
- Before creating a release tag, complete the release checklist in the
859
- [migration ledger](./docs/base-ui-migration.md), finalize the
860
- [app-owner migration guide](./docs/design-system-v1-migration.md), and run the
861
- full local validation suite:
156
+ Install the package-local guidance into an application's `AGENTS.md`:
862
157
 
863
158
  ```bash
864
- pnpm lint
865
- pnpm lint:playground
866
- pnpm typecheck
867
- pnpm typecheck:playground
868
- pnpm test
869
- pnpm test:package
870
- pnpm test:consumer
871
- pnpm build:playground
872
- pnpm test:visual
159
+ pnpm exec conscia-design-system init-agents
873
160
  ```
874
161
 
875
- Then prepare and tag a release. Replace `VERSION` with the package version you
876
- are releasing:
162
+ Preview the managed block without writing a file:
877
163
 
878
164
  ```bash
879
- pnpm version VERSION --no-git-tag-version
880
- git add package.json README.md docs/base-ui-migration.md docs/design-system-v1-migration.md
881
- git commit -m "Release vVERSION"
882
- git tag -a vVERSION -m "Release vVERSION"
883
- git push origin main
884
- git push origin vVERSION
165
+ pnpm exec conscia-design-system init-agents --dry-run
885
166
  ```
886
167
 
887
- Pushing the tag starts the `npm-production` release workflow. The workflow
888
- verifies that the tag matches `package.json`, runs the release validation, and
889
- publishes the package to npm without a long-lived npm token. Because this is a
890
- scoped public package, the release configuration must retain public access;
891
- see npm’s [scoped-package publishing guidance](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
892
-
893
- ## Design-system boundaries
894
-
895
- Add something to this package when it:
896
-
897
- - Is shared by multiple Conscia products or workflows.
898
- - Encodes a reusable visual or interaction convention.
899
- - Can remain independent of product permissions, APIs, and domain state.
900
- - Has a stable, accessible public interface.
168
+ The installed [`AGENT_GUIDE.md`](https://conscia-labs.github.io/design-system/agent-guide.md)
169
+ is version-matched to the package. The live playground also publishes
170
+ [`llms.txt`](https://conscia-labs.github.io/design-system/llms.txt) and the
171
+ [agent manifest](https://conscia-labs.github.io/design-system/agent-manifest.json).
901
172
 
902
- Keep something in the product application when it:
173
+ ## Documentation and maintenance
903
174
 
904
- - Fetches or mutates product data.
905
- - Depends on route definitions or authorization rules.
906
- - Contains product-specific validation or secret handling.
907
- - Represents a one-off business workflow.
175
+ - [Live design system](https://conscia-labs.github.io/design-system/)
176
+ - [Foundation and tokens](https://conscia-labs.github.io/design-system/foundation/)
177
+ - [Component catalog](https://conscia-labs.github.io/design-system/components/)
178
+ - [Pattern catalog](https://conscia-labs.github.io/design-system/patterns/)
179
+ - [Migration guide](https://github.com/conscia-labs/design-system/blob/main/docs/design-system-v1-migration.md)
180
+ - [Changelog](https://github.com/conscia-labs/design-system/blob/main/CHANGELOG.md)
181
+ - [Contributing and releases](./CONTRIBUTING.md)
908
182
 
909
- This boundary keeps the design system reusable without turning it into a second application framework.
183
+ The repository's `playground` contains the executable documentation site. Run it
184
+ locally with `pnpm dev:playground`; the static site is published to GitHub Pages
185
+ by the version-tag release workflow.
910
186
 
911
187
  ## License
912
188
 
913
- Released under the [MIT License](./LICENSE).
189
+ MIT