@conscia-labs/design-system 1.1.2 → 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,1016 +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.1.2` 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
178
- ```
179
-
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.
184
-
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";
19
+ pnpm add @conscia-labs/design-system
210
20
  ```
211
21
 
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
22
+ The package requires React 19 and React DOM 19. Tailwind CSS 4 is optional for
23
+ consumers that use the Tailwind integration.
216
24
 
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() {
285
- 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>
312
- );
313
- }
314
- ```
315
-
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:
320
-
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
- ```
331
-
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
- AppHeader,
357
- AppHeaderActions,
358
- AppHeaderSearch,
359
- AppHeaderStart,
360
- AppShell,
361
- AppSidebar,
362
- AppSidebarContent,
363
- MainRegion,
364
- PageContent,
365
- PageFrame,
366
- PageHeader,
367
- SidebarNavigation,
368
- SidebarTrigger,
369
- } from "@conscia-labs/design-system";
370
-
371
- export function ProductShell({
372
- navigation,
373
- children,
374
- }: {
375
- navigation: React.ReactNode;
376
- children: React.ReactNode;
377
- }) {
378
- return (
379
- <AppShell headerLayout="integrated">
380
- <AppHeader>
381
- <AppHeaderStart>
382
- <SidebarTrigger />
383
- {/* Brand and product/workspace context */}
384
- </AppHeaderStart>
385
- <AppHeaderSearch mobileTrigger={mobileSearchTrigger}>
386
- {globalSearch}
387
- </AppHeaderSearch>
388
- <AppHeaderActions>{accountActions}</AppHeaderActions>
389
- </AppHeader>
390
-
391
- <AppSidebar>
392
- <AppSidebarContent>{navigation}</AppSidebarContent>
393
- </AppSidebar>
394
-
395
- <MainRegion>
396
- <PageFrame width="wide">
397
- <PageContent>
398
- <PageHeader
399
- title="Connections"
400
- description="Manage provider connections and their availability."
401
- />
402
- {children}
403
- </PageContent>
404
- </PageFrame>
405
- </MainRegion>
406
- </AppShell>
407
- );
408
- }
409
- ```
410
-
411
- `AppHeader` is the preferred global chrome: it spans the viewport while the
412
- sidebar begins below it. The historical `TopBar` plus `AppSidebarHeader`
413
- composition remains supported through the default `headerLayout="split"` for
414
- existing v1 consumers.
415
-
416
- Use static groups for normal application navigation:
417
-
418
- ```tsx
419
- const entries = [
420
- {
421
- type: "group",
422
- id: "delivery",
423
- label: "Delivery metrics",
424
- items: [
425
- { id: "/dashboard", label: "Dashboard", icon: <LayoutDashboard /> },
426
- { id: "/reporting", label: "Reporting", icon: <FileText /> },
427
- ],
428
- },
429
- ] satisfies SidebarNavigationEntry[];
430
-
431
- <SidebarNavigation entries={entries} renderLink={renderLink} />;
432
- ```
433
-
434
- Static labels organize the information architecture without becoming controls.
435
- Only use `type: "submenu"` when destinations form a genuine nested hierarchy
436
- or the section is unusually long. Untyped sections retain their historical
437
- collapsible behavior for compatibility, but new code should always choose an
438
- explicit type.
439
-
440
- ## Building an operational dashboard
441
-
442
- Use `MetricCard` for a metric with direction, sentiment, benchmark, and optional
443
- visualization. Direction and sentiment are deliberately independent: lower
444
- lead time is a downward but positive change.
445
-
446
- ```tsx
447
- <MetricCard
448
- label="Lead time for changes"
449
- description="First commit to production"
450
- value="18.6"
451
- unit="hours"
452
- trend={
453
- <MetricTrend
454
- direction="down"
455
- sentiment="positive"
456
- value="22%"
457
- accessibleLabel="Down 22 percent, a positive change"
458
- />
459
- }
460
- visualization={<ProductChart />}
461
- visualizationSummary="Lead time is lower at the end of the period."
462
- />
463
- ```
464
-
465
- `DataPanel` provides flush panel anatomy for charts and divided rows;
466
- `AttentionList` represents persistent operational findings without announcing
467
- them as live alerts. `ActivityItem` accepts `leading` and `trailing` slots for
468
- status markers and structured metadata. The package supplies chart and trend
469
- tokens but intentionally does not bundle a charting library or dashboard grid.
470
-
471
- ## Building a workbench surface
472
-
473
- Workbench patterns provide a reusable composition for applications that need
474
- global navigation, a contextual rail, a primary work area, and an inspector.
475
- They own the shell geometry, responsive rail behavior, resource-row rhythm,
476
- and inspector hierarchy; the host application supplies its routes, data, and
477
- actions.
478
-
479
- ```tsx
480
- import {
481
- ResourceRow,
482
- ResourceRowContent,
483
- ResourceRowIcon,
484
- ResourceRowMeta,
485
- ResourceRowTitle,
486
- WorkbenchInspector,
487
- WorkbenchInspectorSection,
488
- WorkbenchMain,
489
- WorkbenchRail,
490
- WorkbenchSection,
491
- WorkbenchSectionHeader,
492
- WorkbenchShell,
493
- } from "@conscia-labs/design-system";
494
-
495
- export function WorkspaceSurface({ children }: { children: React.ReactNode }) {
38
+ export function ConnectionForm() {
496
39
  return (
497
- <WorkbenchShell data-density="operational">
498
- <WorkbenchRail variant="global">Global navigation</WorkbenchRail>
499
- <WorkbenchRail variant="secondary">Contextual navigation</WorkbenchRail>
500
- <WorkbenchMain>
501
- <WorkbenchSection>
502
- <WorkbenchSectionHeader title="Recent conversations" metadata="12" />
503
- <ResourceRow as="a" href="/conversations/1">
504
- <ResourceRowIcon aria-hidden="true" />
505
- <ResourceRowContent>
506
- <ResourceRowTitle>Project brief</ResourceRowTitle>
507
- <ResourceRowMeta>Updated just now</ResourceRowMeta>
508
- </ResourceRowContent>
509
- </ResourceRow>
510
- </WorkbenchSection>
511
- {children}
512
- </WorkbenchMain>
513
- <WorkbenchInspector>
514
- <WorkbenchInspectorSection label="Details">
515
- {/* Product-owned metadata and actions */}
516
- </WorkbenchInspectorSection>
517
- </WorkbenchInspector>
518
- </WorkbenchShell>
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>
519
48
  );
520
49
  }
521
50
  ```
522
51
 
523
- Use `WorkbenchMobileToolbar` and `WorkbenchBackdrop` when a contextual rail
524
- needs an explicit mobile drawer trigger. Keep product-specific content styles
525
- local, but use the shared workbench tokens and row primitives instead of
526
- recreating shell widths, inspector padding, focus states, or resource-list
527
- typography.
528
-
529
- ### Typography and font loading
530
-
531
- The design system declares the open-source Source Sans 3 variable font as a
532
- runtime dependency and loads it through its CSS entry points. Consumers should
533
- import the published `tailwind.css` or `styles.css` entry and should not add a
534
- separate font download. The shared hierarchy uses a deliberate `400 / 500 /
535
- 600` weight ladder; applications should avoid replacing it with arbitrary
536
- fractional weights.
537
- Applications may override `--font-sans` only when a deliberate product-specific
538
- type decision has been made.
539
-
540
- ### Typography hierarchy
541
-
542
- Use the shared type scale by role:
543
-
544
- - `--ds-display-title` is the responsive display or welcome scale for
545
- high-level entry points.
546
- - `--ds-page-title` is for page-level headings and `PageHeader` titles.
547
- - `--ds-section-title` is for sections within a page or resource detail.
548
- - `--ds-body` is the default application body size.
549
- - `--ds-metadata` is for supporting context such as descriptions, timestamps,
550
- counts, and secondary organization text.
551
- - `--ds-menu-label-size` is intentionally compact and is reserved for menu
552
- labels and compact option descriptions, not normal body copy.
553
-
554
- Prefer these tokens over local `clamp()`, pixel, or one-off font-size values.
555
- Product-specific layout styles may still control wrapping, maximum width, or
556
- composition when the content requires it.
557
-
558
- Operational consumers can use the token-backed `ds-type-*` utilities without
559
- creating a parallel styling system:
560
-
561
- | Role | Utility | Comfortable baseline | Operational intent |
562
- | --- | --- | --- | --- |
563
- | Page/display title | `ds-type-page-title`, `ds-type-display-title` | 28px / 56px | 26px / responsive display, 650 weight, tight tracking |
564
- | Section title | `ds-type-section-title` | 17px | 16px, 650 weight, tighter line-height |
565
- | Body/UI | `ds-type-body`, `ds-type-ui` | 15px / 14px | 13px with a 1.4–1.5 rhythm |
566
- | Metadata | `ds-type-metadata` | 13px | 12px supporting context |
567
- | Menu/eyebrow | `ds-type-menu-item`, `ds-type-menu-label`, `ds-type-eyebrow` | existing compact roles | compact labels with deliberate tracking |
568
- | Controls | `ds-type-control`, `ds-type-button` | 14px | 13px, with stronger button weight |
569
-
570
- The utilities resolve through CSS custom properties, so light and dark themes
571
- retain the same semantic colors and focus behavior. Applications should use
572
- the preset and shared utilities for type/rhythm, while keeping product-specific
573
- composition, data, and layout ownership local.
574
-
575
- Sidebar section labels are intentionally smaller than navigation rows and
576
- slightly more weighted: comfortable density uses a `12px / 600 / 16px`
577
- contract with restrained tracking, while compact density reduces the size
578
- without changing the role. Keep navigation labels at the shared row size and
579
- weight them only when active.
580
-
581
- ### BrandIcon
582
-
583
- `BrandIcon` is the shared symbol-only Conscia mark. It embeds the supplied
584
- 240×240 symbol geometry so published consumers do not need to manage an asset
585
- path. The default treatment uses the existing foreground role in light mode
586
- and the existing white brand treatment in dark mode. Use it for symbol-only
587
- lockups, collapsed navigation identity, and other shared brand placements.
588
-
589
- The icon is decorative by default. Add an `aria-label` when the mark conveys
590
- meaning without adjacent text, and use `className` to control its size.
591
-
592
- ### BrandWordmark
593
-
594
- `BrandWordmark` is the shared no-tagline Conscia lockup. It embeds the supplied
595
- 496×113 vector geometry and uses `currentColor`, so applications do not need
596
- separate black and white assets or runtime asset paths. The default treatment
597
- matches `BrandIcon`: foreground in light mode and white in dark mode.
598
-
599
- The wordmark is decorative by default. Add an `aria-label` when it is the only
600
- accessible naming content, and use `className` to control its width.
601
-
602
- ```tsx
603
- <BrandWordmark aria-label="Conscia" className="w-36" />
604
- ```
605
-
606
- ### Sidebar variants and semantic surfaces
607
-
608
- `AppSidebar` follows application appearance by default through `variant="auto"`.
609
- `variant="dark"` and `variant="light"` remain available when a product needs an
610
- explicitly fixed treatment.
611
-
612
- ```tsx
613
- <AppShell headerLayout="integrated">
614
- <AppHeader>{/* global identity, search, and actions */}</AppHeader>
615
- <AppSidebar variant="auto">
616
- <AppSidebarContent>{navigation}</AppSidebarContent>
617
- <AppSidebarFooter>{accountMenu}</AppSidebarFooter>
618
- </AppSidebar>
619
- </AppShell>
620
- ```
621
-
622
- The sidebar scope exposes reusable semantic roles for its canvas, header,
623
- content, hover, active, search, footer, text, icon, group label, count,
624
- border, and focus-ring roles.
625
- Use the generated utilities such as `bg-sidebar-canvas`,
626
- `bg-sidebar-hover`, `text-sidebar-primary-text`, and
627
- `text-sidebar-metadata-text` in shared or application-owned compositions.
628
-
629
- Form controls and outline buttons use `bg-surface-control`, with
630
- `bg-surface-control-hover` for the outline hover state. These semantic surfaces
631
- are intentionally theme-aware: the base uses the muted surface in light mode
632
- and the raised surface in dark mode; hover reverses that relationship so the
633
- control remains visibly interactive without introducing a new color palette.
634
-
635
- Button variants provide their foreground role explicitly: primary, secondary,
636
- destructive, outline, ghost, and link content do not depend on an ancestor's
637
- text color. The destructive variant uses the existing dark danger background
638
- and foreground pair in dark mode because the bright danger role is not suitable
639
- for white text there. Consumer classes remain the final override when a
640
- product-specific treatment is intentional.
641
-
642
- Dark mode uses a calm charcoal surface ladder rather than a pure-black canvas:
643
-
644
- | Role | Token | Dark value |
645
- | --- | --- | --- |
646
- | Application canvas | `--canvas` | `#17191c` |
647
- | Standard surface | `--surface` | `#1d2024` |
648
- | Raised surface and control | `--surface-raised` / `--surface-control` | `#24272c` |
649
- | Muted and control-hover surface | `--surface-muted` / `--surface-control-hover` | `#282b31` |
650
- | Floating surface | `--surface-floating` | `#2c2f36` |
651
- | Overlay surface | `--surface-overlay` | `#31343a` |
652
-
653
- The adjacent steps are intentionally close enough for a calm reading
654
- environment while remaining distinguishable through luminance, borders, and
655
- elevation. `--text-primary` is a soft high-priority text role (`#eff1f4`), while
656
- `--text-secondary`, `--text-supporting`, and `--text-muted` step down to
657
- `#d4d8df`, `#b3bac5`, and `#929aa7`. Use the semantic `bg-surface-*` and
658
- `text-*` utilities instead of copying these values into an application. The
659
- dark sidebar remains its established Conscia identity surface; inputs use the
660
- shared control surface and popovers/drawers use the floating or overlay roles.
661
-
662
- `SidebarSearch` owns only the trigger, expanded field, Escape handling, and
663
- focus handoff. Applications provide the query value and filtering behavior.
664
- `NavigationGroup` accepts an optional `count`; application-owned group labels
665
- can still be supplied as arbitrary React nodes. Routing, conversation rows,
666
- row actions, account menus, permissions, and appearance controls remain
667
- application-owned.
668
-
669
- The shell uses `--ds-topbar-height` as the shared chrome-height contract.
670
- `AppHeader` and the compatibility `TopBar` both use the responsive
671
- `--ds-topbar-padding-x` tokens. Keep `SidebarTrigger` in either header—not
672
- inside `AppSidebar`—so it remains available in collapsed and mobile states.
673
-
674
- Sidebar section labels use the field-label size with a restrained medium weight
675
- and tracking. Navigation rows retain the shared comfortable/touch heights,
676
- while `--ds-sidebar-item-gap`, `--ds-sidebar-label-gap`, and
677
- `--ds-sidebar-group-gap` control list, label, and group rhythm. Use the shared
678
- sidebar semantic utilities for surfaces, text, icons, borders, and focus rings;
679
- keep conversation data, organization names, and product-specific row actions
680
- application-owned.
681
-
682
- For migration, replace a consuming application's light-only `--sidebar-*`
683
- root override with `variant="auto"` on its shared `AppSidebar`. Remove
684
- descendant opacity and background overrides as each shell adopts the semantic
685
- aliases. Keep product-specific selectors only where they encode behavior or
686
- content rather than shared sidebar presentation.
687
-
688
- The ownership boundary is:
689
-
690
- | Shared design system | Application-owned |
691
- | --- | --- |
692
- | 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 |
693
- | Static group structure, explicit submenu expansion, collapsed flyouts, and active/hover/focus styling | Group labels/content, link destinations, active-route calculation, and business-specific empty states |
694
-
695
- ## Choosing the right component
696
-
697
- ### Table or DataTable?
698
-
699
- Use `Table` for small, bounded, read-only relationships.
700
-
701
- Use `DataTable` when an operational inventory needs one or more of:
702
-
703
- - Sorting
704
- - Pagination
705
- - Row selection
706
- - Row actions
707
- - Clickable rows
708
- - Dedicated mobile rendering
709
-
710
- 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.
711
-
712
- ### Tabs or NavigationTabs?
713
-
714
- Use `Tabs` when content panels change in place without navigation.
715
-
716
- ```tsx
717
- <Tabs defaultValue="overview">
718
- <TabsList>
719
- <TabsTrigger value="overview">Overview</TabsTrigger>
720
- <TabsTrigger value="activity">Activity</TabsTrigger>
721
- </TabsList>
722
- <TabsContent value="overview">...</TabsContent>
723
- <TabsContent value="activity">...</TabsContent>
724
- </Tabs>
725
- ```
726
-
727
- Use `NavigationTabs` for route-backed sections. The active destination is represented with `aria-current="page"`.
728
-
729
- ```tsx
730
- <NavigationTabs aria-label="Connection sections">
731
- <NavigationTabsList>
732
- <NavigationTab href="/connections/123" active>
733
- Overview
734
- </NavigationTab>
735
- <NavigationTab href="/connections/123/activity">
736
- Activity
737
- </NavigationTab>
738
- </NavigationTabsList>
739
- </NavigationTabs>
740
- ```
741
-
742
- ### Select or SearchableSelect?
743
-
744
- Use `Select` for short, familiar option lists.
745
-
746
- Use `SearchableSelect` when users need to find an item in a longer list by label, description, or keywords.
747
-
748
- Both `FormSelect` and `SearchableSelect` contribute a named value to a native
749
- HTML form when their `name` prop is provided.
750
-
751
- ### Nested overlays
752
-
753
- Portaled controls can be used inside `Dialog` and `Sheet` without clipping
754
- their popup. The popup Positioner is mounted in a Base UI portal and uses the
755
- shared overlay layer hierarchy:
756
-
757
- | Layer | Components | z-index |
758
- | --- | --- | ---: |
759
- | Modal | `Dialog`, `Sheet`, `AlertDialog` | 40 |
760
- | Popup | `Select`, `Popover`, `SearchableSelect`, `DropdownMenu` | 50 |
761
- | Transient | `Toast`, `Tooltip` | 100 |
762
-
763
- Base UI `Select` is modal by default, so `FormSelect` preserves that default
764
- for backwards compatibility. Set `modal={false}` when a `Select` or
765
- `FormSelect` is nested in a modal surface so it does not add a second backdrop,
766
- focus boundary, or inert page state. `SearchableSelect` also exposes `modal`
767
- and preserves Combobox's current non-modal default:
768
-
769
- ```tsx
770
- <Dialog open={open} onOpenChange={setOpen}>
771
- <DialogContent>
772
- <DialogBody className="overflow-y-auto">
773
- <FormSelect modal={false} name="vendor" options={vendorOptions} />
774
- <SearchableSelect modal={false} name="model" options={modelOptions} onValueChange={setModel} />
775
- </DialogBody>
776
- </DialogContent>
777
- </Dialog>
778
- ```
779
-
780
- `Select`, `Popover`, and `DropdownMenu` already forward their Base UI root
781
- props, including `modal`. Use the same `modal={false}` setting for those
782
- controls when they are nested. No consuming-app z-index override or portal
783
- adapter is required.
784
-
785
- ## Semantic color
786
-
787
- Color communicates meaning rather than palette choice:
788
-
789
- | Role | Purpose |
790
- | --- | --- |
791
- | `brand` | Conscia identity and signature moments |
792
- | `brand-secondary` | Supporting brand expression |
793
- | `action-*` | Primary actions and their hover, active, foreground, and tinted-background roles |
794
- | `selection-*` | Current selection or active destination |
795
- | `information-*` | Informational messages and evidence |
796
- | `success-*` | Healthy, verified, approved, or completed states |
797
- | `warning-*` | Conditions requiring attention |
798
- | `danger-*` | Destructive actions, failures, and critical states |
799
- | `neutral-*` | Decoration and non-semantic surfaces |
52
+ Use the [component reference](https://conscia-labs.github.io/design-system/components/)
53
+ for complete anatomy, options, states, and examples.
800
54
 
801
- Do not use success styling merely because something is enabled or active. Success should communicate positive operational evidence.
55
+ ## Styles and preferences
802
56
 
803
- ## Customizing tokens
804
-
805
- Override semantic variables after importing the package stylesheet:
57
+ Tailwind CSS 4 applications import the integration once from their global
58
+ stylesheet:
806
59
 
807
60
  ```css
808
61
  @import "tailwindcss";
809
62
  @import "@conscia-labs/design-system/tailwind.css";
810
-
811
- :root {
812
- --ds-space-page: 3rem;
813
- --ds-radius-surface: 0.625rem;
814
- }
815
63
  ```
816
64
 
817
- Prefer semantic variables over component-specific descendant selectors. This keeps appearance and density behavior consistent across primitives and patterns.
818
-
819
- ## Accessibility
820
-
821
- Accessibility is part of the component contract:
822
-
823
- - Base UI-backed components provide keyboard interaction and focus management.
824
- - Route-backed navigation uses semantic links and `aria-current`.
825
- - Dialogs and sheets provide labelled modal structure.
826
- - Form controls expose native labelling and validation attributes.
827
- - Motion is reduced when the user requests `prefers-reduced-motion`.
828
- - 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:
829
66
 
830
- Applications are still responsible for meaningful labels, heading order, form error relationships, alternative text, and accessible business workflows.
831
-
832
- ## Framework notes
833
-
834
- ### Next.js
835
-
836
- Import the application global stylesheet from the root layout:
837
-
838
- ```tsx
839
- import "./globals.css";
67
+ ```css
68
+ @import "@conscia-labs/design-system/standalone.css";
840
69
  ```
841
70
 
842
- The component entries are explicit client-only boundaries, while server-safe
843
- code is published separately. For example, React Server Components should
844
- import `cn` from `@conscia-labs/design-system/utils`. The package does not need
845
- `transpilePackages`; Next.js will establish a client boundary for component
846
- exports.
847
-
848
- ### Other React applications
849
-
850
- The primitives are router-independent and can be used with Vite or other
851
- ESM-capable React build systems. Route-backed patterns accept
852
- application-supplied links rather than depending on Next.js navigation.
71
+ Do not import `standalone.css` in a Tailwind application. Its preflight and
72
+ utilities would compete with the application's generated CSS.
853
73
 
854
- ### Focused imports
855
-
856
- The root package is the simplest import path. Public subpath exports are also
857
- available when an application wants a more explicit dependency boundary:
74
+ Set shared appearance and density preferences on the document root:
858
75
 
859
76
  ```tsx
860
- import { Button } from "@conscia-labs/design-system/primitives";
861
- import { DataTable } from "@conscia-labs/design-system/patterns";
862
- import {
863
- applyConsciaPreferences,
864
- } from "@conscia-labs/design-system/foundation";
865
- import { cn } from "@conscia-labs/design-system/utils";
77
+ <html
78
+ lang="en"
79
+ data-appearance="system"
80
+ data-density="comfortable"
81
+ suppressHydrationWarning
82
+ >
866
83
  ```
867
84
 
868
- All public entry points are ESM-only.
869
-
870
- ## Agent integration
871
-
872
- The package ships a concise [`AGENT_GUIDE.md`](./AGENT_GUIDE.md) and generated
873
- [`agent-manifest.json`](./agent-manifest.json) alongside its runtime files. The
874
- guide records the integration contract, component-selection rules, important
875
- boundaries, and verification expectations for the exact installed version. The
876
- manifest maps every public component family to its exports and live playground
877
- route.
85
+ Appearance values are `light`, `dark`, and `system`. Density values are
86
+ `comfortable`, `compact`, and `operational`.
878
87
 
879
- Add or update a managed Conscia section in a consuming repository's
880
- `AGENTS.md` after installing the package:
881
-
882
- ```bash
883
- pnpm exec conscia-design-system init-agents
884
- ```
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.
885
91
 
886
- Preview the instructions without writing a file:
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.
887
97
 
888
- ```bash
889
- pnpm exec conscia-design-system init-agents --dry-run
890
- ```
98
+ ## Choose the right level
891
99
 
892
- The initializer preserves all instructions outside its marker-delimited block,
893
- so applications can safely rerun it when upgrading. The block tells coding
894
- agents to read the package-local guide before UI work. Agents and developers can
895
- also use the [live playground](https://conscia-labs.github.io/design-system/),
896
- [`llms.txt`](https://conscia-labs.github.io/design-system/llms.txt), and the
897
- [public machine-readable inventory](https://conscia-labs.github.io/design-system/agent-manifest.json).
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.
898
106
 
899
- ## 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.
900
111
 
901
- Install dependencies:
112
+ ## Public entrypoints
902
113
 
903
- ```bash
904
- 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
905
120
  ```
906
121
 
907
- 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`.
908
125
 
909
- ```bash
910
- pnpm dev:playground
911
- ```
912
-
913
- The playground is available at [http://localhost:3020](http://localhost:3020).
126
+ ## Accessibility and composition
914
127
 
915
- Run the project checks:
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.
916
132
 
917
- ```bash
918
- pnpm lint
919
- pnpm lint:playground
920
- pnpm typecheck
921
- pnpm typecheck:playground
922
- pnpm test
923
- pnpm test:package
924
- pnpm build:playground
925
- pnpm build:playground:static
926
- ```
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.
927
136
 
928
- `pnpm test:package` creates the production artifacts, validates the package
929
- manifest, and imports the package through its public export map. The npm
930
- `prepack` hook runs the same gate before a tarball can be produced.
137
+ ## Upgrading to v1
931
138
 
932
- Reusable foundation, primitive, and pattern code belongs in `src`. Fixtures and visual documentation belong in `playground`.
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:
933
142
 
934
- ## Releasing
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.
935
150
 
936
- Development is integrated through `dev`; `main` contains released source only.
937
- Feature and fix branches target `dev`, and a release pull request is opened from
938
- `dev` to `main`. The CI workflow rejects pull requests to `main` from any other
939
- branch. See [CONTRIBUTING.md](./CONTRIBUTING.md) for the complete branch model
940
- and recommended GitHub branch rules.
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.
941
153
 
942
- Merging the release pull request runs CI but does not publish. Run `pnpm release`
943
- from the reviewed `main` commit to create and push the version tag. That single
944
- tag workflow validates the release, deploys the playground to GitHub Pages, and
945
- publishes the npm package. The tag must match the version in `package.json`
946
- exactly and point to a commit on `main`. npm’s trusted-publishing flow provides
947
- short-lived CI authentication and provenance for the published package.
154
+ ## Agent support
948
155
 
949
- Before creating a release tag, complete the release checklist in the
950
- [migration ledger](./docs/base-ui-migration.md), finalize the
951
- [app-owner migration guide](./docs/design-system-v1-migration.md), and run the
952
- full local validation suite:
156
+ Install the package-local guidance into an application's `AGENTS.md`:
953
157
 
954
158
  ```bash
955
- pnpm lint
956
- pnpm lint:playground
957
- pnpm typecheck
958
- pnpm typecheck:playground
959
- pnpm test
960
- pnpm test:package
961
- pnpm test:consumer
962
- pnpm build:playground:static
963
- pnpm test:visual
159
+ pnpm exec conscia-design-system init-agents
964
160
  ```
965
161
 
966
- Prepare the version change on a branch from `dev`, merge it into `dev`, then
967
- open and merge the release pull request from `dev` to `main`. Replace `VERSION`
968
- with the package version you are releasing:
162
+ Preview the managed block without writing a file:
969
163
 
970
164
  ```bash
971
- git switch dev
972
- git pull --ff-only origin dev
973
- git switch -c release/vVERSION
974
- pnpm version VERSION --no-git-tag-version
975
- # Update CHANGELOG.md and any release notes for VERSION.
976
- # Review the generated metadata, then stage the complete release change.
977
- git add -A
978
- git commit -m "Release vVERSION"
979
- git push -u origin release/vVERSION
980
- # Open release/vVERSION -> dev, then dev -> main pull requests.
981
-
982
- git switch main
983
- git pull --ff-only origin main
984
- pnpm release
165
+ pnpm exec conscia-design-system init-agents --dry-run
985
166
  ```
986
167
 
987
- The merge to `main` runs CI. `pnpm release` pushes the version tag and starts
988
- the release workflow, which verifies the version and branch ancestry, runs the
989
- release validation, deploys Pages, and publishes the package to npm without a
990
- long-lived npm token. Because this is a scoped public package, the release
991
- configuration must retain public access; see npm’s [scoped-package publishing guidance](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
992
-
993
- The `pnpm version` lifecycle hook refreshes the README release marker and
994
- generated agent metadata, including `agent-manifest.json` and `playground/public/llms.txt`.
995
-
996
- ## Design-system boundaries
997
-
998
- Add something to this package when it:
999
-
1000
- - Is shared by multiple Conscia products or workflows.
1001
- - Encodes a reusable visual or interaction convention.
1002
- - Can remain independent of product permissions, APIs, and domain state.
1003
- - 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).
1004
172
 
1005
- Keep something in the product application when it:
173
+ ## Documentation and maintenance
1006
174
 
1007
- - Fetches or mutates product data.
1008
- - Depends on route definitions or authorization rules.
1009
- - Contains product-specific validation or secret handling.
1010
- - 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)
1011
182
 
1012
- 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.
1013
186
 
1014
187
  ## License
1015
188
 
1016
- Released under the [MIT License](./LICENSE).
189
+ MIT