@conscia-labs/design-system 1.0.3 → 1.1.2

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/AGENT_GUIDE.md ADDED
@@ -0,0 +1,213 @@
1
+ # Conscia Design System: Agent Guide
2
+
3
+ This file is the compact, version-matched contract for coding agents working in
4
+ an application that has `@conscia-labs/design-system` installed. Read the
5
+ installed copy before changing application UI. The installed package version is
6
+ authoritative when this guide differs from documentation on `main`.
7
+
8
+ ## Start here
9
+
10
+ 1. Inspect the application's existing shell, global stylesheet, routing, and
11
+ nearby design-system usage before editing.
12
+ 2. Reuse a public Conscia pattern when one matches the workflow. Use primitives
13
+ when the application genuinely needs a composition the package does not own.
14
+ 3. Import only public exports. Do not reach into `dist` or package internals.
15
+ 4. Preserve the application's routing, authentication, permissions, data,
16
+ mutations, validation, and business behavior.
17
+ 5. Verify the affected UI at desktop and mobile sizes, including keyboard and
18
+ visible focus behavior for interactive changes.
19
+
20
+ Live examples and component guidance:
21
+ <https://conscia-labs.github.io/design-system/>
22
+
23
+ Machine-readable component inventory:
24
+ <https://conscia-labs.github.io/design-system/agent-manifest.json>
25
+
26
+ ## Installation contract
27
+
28
+ Tailwind CSS v4 applications import these styles once from their global CSS:
29
+
30
+ ```css
31
+ @import "tailwindcss";
32
+ @import "@conscia-labs/design-system/tailwind.css";
33
+ ```
34
+
35
+ Do not add another `@source` for the package. The published stylesheet already
36
+ contains the package-relative source declaration.
37
+
38
+ Applications that do not run Tailwind use the complete precompiled bundle:
39
+
40
+ ```css
41
+ @import "@conscia-labs/design-system/standalone.css";
42
+ ```
43
+
44
+ Never import `standalone.css` in a Tailwind application. Its preflight and
45
+ utilities would compete with the application's generated CSS.
46
+
47
+ Set shared preferences on the document root:
48
+
49
+ ```tsx
50
+ <html
51
+ lang="en"
52
+ data-appearance="system"
53
+ data-density="comfortable"
54
+ suppressHydrationWarning
55
+ >
56
+ ```
57
+
58
+ Supported appearance values are `light`, `dark`, and `system`. Supported
59
+ density values are `comfortable`, `compact`, and `operational`.
60
+
61
+ ## Non-negotiable boundaries
62
+
63
+ - Do not copy design-system components into the application.
64
+ - Do not install `@base-ui/react`, `@radix-ui/*`, or copied shadcn components
65
+ when the design system already provides the behavior.
66
+ - Do not use the removed `asChild` API. Use the documented `render` prop for
67
+ custom-host composition.
68
+ - Do not use legacy utilities such as `bg-primary`, `bg-muted`, `border-input`,
69
+ or their associated legacy variables. Use Conscia semantic roles.
70
+ - Do not reach into package implementation files or depend on Base UI details.
71
+ - Do not add application z-index workarounds for supported overlays before
72
+ checking the documented `modal` behavior.
73
+ - Do not encode status using color alone. Retain meaningful text, labels, or
74
+ icons.
75
+
76
+ ## Choose the highest useful level
77
+
78
+ ### Patterns
79
+
80
+ Prefer patterns for recurring product workflows:
81
+
82
+ - Application chrome: `AppShell`, `AppHeader`, `AppSidebar`, `MainRegion`,
83
+ `PageFrame`, and `SidebarNavigation`.
84
+ - Page composition: `PageHeader`, `PageToolbar`, `ResourceSummary`, and
85
+ `DetailSection`.
86
+ - Data-heavy collections: `DataTable`, `EntityTable`, `InventorySurface`, and
87
+ `PaginationControls`.
88
+ - Operational dashboards: `MetricCard`, `MetricBand`, `DataPanel`,
89
+ `AttentionList`, and `ActivityList`.
90
+ - States and feedback: `StateView`, `ErrorState`, `LoadingRows`,
91
+ `ConfirmationDialog`, `CommandPalette`, and `FilterBar`.
92
+ - Multi-rail workspaces: the `Workbench*` family.
93
+
94
+ ### Primitives
95
+
96
+ Use primitives for application-specific compositions: `Button`, `Card`,
97
+ `Field`, `Input`, `Select`, `SearchableSelect`, `Dialog`, `Sheet`, `Popover`,
98
+ `Tabs`, `Table`, `Badge`, `Alert`, `Toast`, and related anatomy exports.
99
+
100
+ Consult `agent-manifest.json` for the complete public runtime inventory and the
101
+ playground route for each family.
102
+
103
+ ## Frequent decisions
104
+
105
+ - Use `Table` for semantic table anatomy. Use `DataTable` for sorting,
106
+ selection, column definitions, responsive rows, or pagination.
107
+ - Use `Tabs` for layered content or mode switching. Use `NavigationTabs` for
108
+ route-backed destinations.
109
+ - Use `Select` for a short, familiar list. Use `SearchableSelect` for longer
110
+ lists that users need to filter.
111
+ - Use `LoadingButton` for asynchronous actions so layout, disabled state, and
112
+ `aria-busy` remain consistent.
113
+ - Use `ConfirmationDialog` or `AlertDialog` only for consequential decisions.
114
+ - Use `operational` density for information-heavy administration, inventory,
115
+ and workspace surfaces. Keep `comfortable` for general-purpose product UI.
116
+
117
+ ## Composition examples
118
+
119
+ Use fields as the unit of form layout and accessible help/error content:
120
+
121
+ ```tsx
122
+ import {
123
+ Button,
124
+ Field,
125
+ FieldDescription,
126
+ FieldLabel,
127
+ Input,
128
+ } from "@conscia-labs/design-system";
129
+
130
+ <form className="grid gap-5">
131
+ <Field>
132
+ <FieldLabel htmlFor="connection-name">Name</FieldLabel>
133
+ <Input id="connection-name" name="name" />
134
+ <FieldDescription>Use a name operators will recognize.</FieldDescription>
135
+ </Field>
136
+ <Button type="submit">Create connection</Button>
137
+ </form>;
138
+ ```
139
+
140
+ Keep popup controls non-modal when nested inside a modal surface:
141
+
142
+ ```tsx
143
+ <Dialog open={open} onOpenChange={setOpen}>
144
+ <DialogContent>
145
+ <DialogBody>
146
+ <FormSelect modal={false} name="vendor" options={vendorOptions} />
147
+ <SearchableSelect
148
+ modal={false}
149
+ name="model"
150
+ options={modelOptions}
151
+ onValueChange={setModel}
152
+ />
153
+ </DialogBody>
154
+ </DialogContent>
155
+ </Dialog>
156
+ ```
157
+
158
+ Prefer the integrated global header for new application shells:
159
+
160
+ ```tsx
161
+ <AppShell headerLayout="integrated">
162
+ <AppHeader>
163
+ <AppHeaderStart>
164
+ <SidebarTrigger />
165
+ {productIdentity}
166
+ </AppHeaderStart>
167
+ <AppHeaderSearch>{globalSearch}</AppHeaderSearch>
168
+ <AppHeaderActions>{accountActions}</AppHeaderActions>
169
+ </AppHeader>
170
+ <AppSidebar variant="auto">
171
+ <AppSidebarContent>{navigation}</AppSidebarContent>
172
+ </AppSidebar>
173
+ <MainRegion>{children}</MainRegion>
174
+ </AppShell>
175
+ ```
176
+
177
+ ## Styling
178
+
179
+ Use semantic tokens and utilities rather than palette colors:
180
+
181
+ - Surfaces: `canvas`, `surface`, `surface-raised`, `surface-muted`, and
182
+ `surface-floating`.
183
+ - Text: `text-primary`, `text-secondary`, `text-supporting`, and `text-muted`.
184
+ - Actions and selection: `action-*` and `selection-*`.
185
+ - Status: `information-*`, `success-*`, `warning-*`, and `danger-*`.
186
+ - Neutral structure: `border-subtle`, `control-border`, and shared radius,
187
+ spacing, type, elevation, and focus tokens.
188
+
189
+ Use `className` for layout and local composition. Override semantic variables
190
+ only when the product intentionally changes a system-level decision. Avoid
191
+ component descendant selectors.
192
+
193
+ ## Accessibility ownership
194
+
195
+ The package provides component-level keyboard behavior, focus management, and
196
+ semantic structure. The application remains responsible for:
197
+
198
+ - Meaningful labels and accessible names.
199
+ - Heading order and page landmarks.
200
+ - Form validation messages and their relationships.
201
+ - Alternative text.
202
+ - Route state such as `aria-current`.
203
+ - Complete keyboard-accessible business workflows.
204
+
205
+ ## Verification
206
+
207
+ Use the consuming application's own commands. At minimum, run its typecheck and
208
+ tests for behavior changes, then inspect the affected route in light and dark
209
+ appearance at desktop and mobile sizes. For interactive changes, exercise the
210
+ keyboard path, focus return, disabled or pending state, and any nested overlay.
211
+
212
+ For migration work, use the versioned migration guide linked from the package
213
+ README. Do not infer compatibility from old shadcn or Radix usage.
package/README.md CHANGED
@@ -6,7 +6,7 @@ The shared React component library for building clear, consistent, and accessibl
6
6
 
7
7
  > **Package:** available publicly as [`@conscia-labs/design-system`](https://www.npmjs.com/package/@conscia-labs/design-system).
8
8
  >
9
- > **Current release:** `1.0.3` is the latest stable v1 release.
9
+ > **Current release:** `1.1.2` is the latest stable v1 release.
10
10
  >
11
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).
12
12
 
@@ -353,17 +353,19 @@ The shared shell owns presentation and responsive behavior. The host application
353
353
 
354
354
  ```tsx
355
355
  import {
356
+ AppHeader,
357
+ AppHeaderActions,
358
+ AppHeaderSearch,
359
+ AppHeaderStart,
356
360
  AppShell,
357
361
  AppSidebar,
358
362
  AppSidebarContent,
359
- AppSidebarHeader,
360
363
  MainRegion,
361
364
  PageContent,
362
365
  PageFrame,
363
366
  PageHeader,
364
- ProductIdentity,
367
+ SidebarNavigation,
365
368
  SidebarTrigger,
366
- TopBar,
367
369
  } from "@conscia-labs/design-system";
368
370
 
369
371
  export function ProductShell({
@@ -374,23 +376,23 @@ export function ProductShell({
374
376
  children: React.ReactNode;
375
377
  }) {
376
378
  return (
377
- <AppShell>
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
+
378
391
  <AppSidebar>
379
- <AppSidebarHeader>
380
- <ProductIdentity
381
- label="Conscia"
382
- description="Administration"
383
- />
384
- </AppSidebarHeader>
385
392
  <AppSidebarContent>{navigation}</AppSidebarContent>
386
393
  </AppSidebar>
387
394
 
388
395
  <MainRegion>
389
- <TopBar>
390
- {/* Keep the toggle in the topbar; it must remain visible when the sidebar collapses. */}
391
- <SidebarTrigger />
392
- </TopBar>
393
-
394
396
  <PageFrame width="wide">
395
397
  <PageContent>
396
398
  <PageHeader
@@ -406,6 +408,66 @@ export function ProductShell({
406
408
  }
407
409
  ```
408
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
+
409
471
  ## Building a workbench surface
410
472
 
411
473
  Workbench patterns provide a reusable composition for applications that need
@@ -543,17 +605,14 @@ accessible naming content, and use `className` to control its width.
543
605
 
544
606
  ### Sidebar variants and semantic surfaces
545
607
 
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.
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.
550
611
 
551
612
  ```tsx
552
- <AppShell>
613
+ <AppShell headerLayout="integrated">
614
+ <AppHeader>{/* global identity, search, and actions */}</AppHeader>
553
615
  <AppSidebar variant="auto">
554
- <AppSidebarHeader>
555
- <ProductIdentity label="Conscia" description="Administration" />
556
- </AppSidebarHeader>
557
616
  <AppSidebarContent>{navigation}</AppSidebarContent>
558
617
  <AppSidebarFooter>{accountMenu}</AppSidebarFooter>
559
618
  </AppSidebar>
@@ -607,15 +666,10 @@ can still be supplied as arbitrary React nodes. Routing, conversation rows,
607
666
  row actions, account menus, permissions, and appearance controls remain
608
667
  application-owned.
609
668
 
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.
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.
619
673
 
620
674
  Sidebar section labels use the field-label size with a restrained medium weight
621
675
  and tracking. Navigation rows retain the shared comfortable/touch heights,
@@ -636,7 +690,7 @@ The ownership boundary is:
636
690
  | Shared design system | Application-owned |
637
691
  | --- | --- |
638
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 |
639
- | `NavigationGroup` keyboard expansion and `SidebarNavigation` collapsed flyouts | Group labels/content, link destinations, active-route calculation, and business-specific empty states |
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 |
640
694
 
641
695
  ## Choosing the right component
642
696
 
@@ -813,6 +867,35 @@ import { cn } from "@conscia-labs/design-system/utils";
813
867
 
814
868
  All public entry points are ESM-only.
815
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.
878
+
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
+ ```
885
+
886
+ Preview the instructions without writing a file:
887
+
888
+ ```bash
889
+ pnpm exec conscia-design-system init-agents --dry-run
890
+ ```
891
+
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).
898
+
816
899
  ## Local development
817
900
 
818
901
  Install dependencies:
@@ -839,6 +922,7 @@ pnpm typecheck:playground
839
922
  pnpm test
840
923
  pnpm test:package
841
924
  pnpm build:playground
925
+ pnpm build:playground:static
842
926
  ```
843
927
 
844
928
  `pnpm test:package` creates the production artifacts, validates the package
@@ -849,11 +933,18 @@ Reusable foundation, primitive, and pattern code belongs in `src`. Fixtures and
849
933
 
850
934
  ## Releasing
851
935
 
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.
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.
941
+
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.
857
948
 
858
949
  Before creating a release tag, complete the release checklist in the
859
950
  [migration ledger](./docs/base-ui-migration.md), finalize the
@@ -868,27 +959,39 @@ pnpm typecheck:playground
868
959
  pnpm test
869
960
  pnpm test:package
870
961
  pnpm test:consumer
871
- pnpm build:playground
962
+ pnpm build:playground:static
872
963
  pnpm test:visual
873
964
  ```
874
965
 
875
- Then prepare and tag a release. Replace `VERSION` with the package version you
876
- are releasing:
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:
877
969
 
878
970
  ```bash
971
+ git switch dev
972
+ git pull --ff-only origin dev
973
+ git switch -c release/vVERSION
879
974
  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
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
881
978
  git commit -m "Release vVERSION"
882
- git tag -a vVERSION -m "Release vVERSION"
883
- git push origin main
884
- git push origin 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
885
985
  ```
886
986
 
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/).
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`.
892
995
 
893
996
  ## Design-system boundaries
894
997