@twoux/ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/LICENSE.md +61 -0
  2. package/LICENSES/Apache-2.0.txt +202 -0
  3. package/NOTICE.md +64 -0
  4. package/SHADCN-DIFF.md +228 -0
  5. package/agent/AGENTS.md +358 -0
  6. package/agent/docs-md/accessibility.md +49 -0
  7. package/agent/docs-md/action-catalogue.md +81 -0
  8. package/agent/docs-md/actions.md +74 -0
  9. package/agent/docs-md/agent-activity-log.md +70 -0
  10. package/agent/docs-md/agent-permissions.md +82 -0
  11. package/agent/docs-md/agent-run.md +90 -0
  12. package/agent/docs-md/agents-on-behalf.md +74 -0
  13. package/agent/docs-md/ai-column.md +85 -0
  14. package/agent/docs-md/ai-origin-label.md +70 -0
  15. package/agent/docs-md/announcing-features.md +73 -0
  16. package/agent/docs-md/answer-actions.md +81 -0
  17. package/agent/docs-md/app-shell.md +114 -0
  18. package/agent/docs-md/artifact-card.md +89 -0
  19. package/agent/docs-md/ask-on-screen.md +72 -0
  20. package/agent/docs-md/assistant-page.md +100 -0
  21. package/agent/docs-md/assistant-panel.md +142 -0
  22. package/agent/docs-md/avatar.md +82 -0
  23. package/agent/docs-md/banner.md +106 -0
  24. package/agent/docs-md/board.md +163 -0
  25. package/agent/docs-md/breadcrumb.md +89 -0
  26. package/agent/docs-md/breakdown-table.md +97 -0
  27. package/agent/docs-md/bulk-action-bar.md +112 -0
  28. package/agent/docs-md/button.md +293 -0
  29. package/agent/docs-md/card.md +115 -0
  30. package/agent/docs-md/change-list.md +99 -0
  31. package/agent/docs-md/change-request.md +166 -0
  32. package/agent/docs-md/chart-area.md +87 -0
  33. package/agent/docs-md/chart-bar.md +100 -0
  34. package/agent/docs-md/chart-box-plot.md +88 -0
  35. package/agent/docs-md/chart-bullet.md +89 -0
  36. package/agent/docs-md/chart-candlestick.md +112 -0
  37. package/agent/docs-md/chart-card-line.md +120 -0
  38. package/agent/docs-md/chart-donut.md +90 -0
  39. package/agent/docs-md/chart-drill-down.md +72 -0
  40. package/agent/docs-md/chart-funnel.md +71 -0
  41. package/agent/docs-md/chart-heatmap.md +76 -0
  42. package/agent/docs-md/chart-histogram.md +81 -0
  43. package/agent/docs-md/chart-map.md +165 -0
  44. package/agent/docs-md/chart-mixed.md +88 -0
  45. package/agent/docs-md/chart-price.md +92 -0
  46. package/agent/docs-md/chart-radial-bars.md +109 -0
  47. package/agent/docs-md/chart-radial-lines.md +111 -0
  48. package/agent/docs-md/chart-sankey.md +104 -0
  49. package/agent/docs-md/chart-scatter.md +87 -0
  50. package/agent/docs-md/chart-share-bar.md +89 -0
  51. package/agent/docs-md/chart-treemap.md +98 -0
  52. package/agent/docs-md/chart-waterfall.md +93 -0
  53. package/agent/docs-md/checkbox.md +131 -0
  54. package/agent/docs-md/choosing-selection-control.md +71 -0
  55. package/agent/docs-md/citations-sources.md +79 -0
  56. package/agent/docs-md/citing-sources.md +63 -0
  57. package/agent/docs-md/clarify-before-acting.md +69 -0
  58. package/agent/docs-md/clarifying-question.md +92 -0
  59. package/agent/docs-md/code-block.md +174 -0
  60. package/agent/docs-md/colours.md +87 -0
  61. package/agent/docs-md/columns-menu.md +140 -0
  62. package/agent/docs-md/combobox.md +161 -0
  63. package/agent/docs-md/command-palette.md +126 -0
  64. package/agent/docs-md/confidence-note.md +87 -0
  65. package/agent/docs-md/configurable-dashboard.md +76 -0
  66. package/agent/docs-md/confirmation-dialog.md +93 -0
  67. package/agent/docs-md/connected-tools.md +80 -0
  68. package/agent/docs-md/connector-picker.md +127 -0
  69. package/agent/docs-md/consistency.md +53 -0
  70. package/agent/docs-md/content-density.md +61 -0
  71. package/agent/docs-md/conversation-history.md +78 -0
  72. package/agent/docs-md/create-record.md +80 -0
  73. package/agent/docs-md/csv-import.md +88 -0
  74. package/agent/docs-md/dashboard-items.md +78 -0
  75. package/agent/docs-md/data-export.md +61 -0
  76. package/agent/docs-md/data-grid.md +137 -0
  77. package/agent/docs-md/data-vis-colours.md +76 -0
  78. package/agent/docs-md/data-visualisation.md +76 -0
  79. package/agent/docs-md/date-picker.md +178 -0
  80. package/agent/docs-md/delete-record.md +75 -0
  81. package/agent/docs-md/dense-table.md +495 -0
  82. package/agent/docs-md/design-tokens.md +53 -0
  83. package/agent/docs-md/disabled-read-only.md +75 -0
  84. package/agent/docs-md/drag-and-drop.md +74 -0
  85. package/agent/docs-md/dropdown-menu.md +137 -0
  86. package/agent/docs-md/edit-record.md +73 -0
  87. package/agent/docs-md/empty-loading-error.md +78 -0
  88. package/agent/docs-md/empty-state.md +128 -0
  89. package/agent/docs-md/error-messages.md +75 -0
  90. package/agent/docs-md/error-state.md +123 -0
  91. package/agent/docs-md/export-menu.md +86 -0
  92. package/agent/docs-md/feedback-prompt.md +88 -0
  93. package/agent/docs-md/field-mapping.md +78 -0
  94. package/agent/docs-md/file-drop.md +110 -0
  95. package/agent/docs-md/filter-bar.md +138 -0
  96. package/agent/docs-md/filter-panel.md +103 -0
  97. package/agent/docs-md/filtering-search.md +79 -0
  98. package/agent/docs-md/follow-ups-starters.md +79 -0
  99. package/agent/docs-md/form-validation.md +95 -0
  100. package/agent/docs-md/generated-columns.md +65 -0
  101. package/agent/docs-md/generated-drafts-files.md +71 -0
  102. package/agent/docs-md/grouped-list.md +89 -0
  103. package/agent/docs-md/guide-cue.md +170 -0
  104. package/agent/docs-md/help-panel.md +103 -0
  105. package/agent/docs-md/help-system.md +74 -0
  106. package/agent/docs-md/iconography.md +49 -0
  107. package/agent/docs-md/inbox.md +108 -0
  108. package/agent/docs-md/inline-editing-validation.md +80 -0
  109. package/agent/docs-md/inline-input-in-answer.md +70 -0
  110. package/agent/docs-md/items-palette.md +116 -0
  111. package/agent/docs-md/keyboard-model.md +47 -0
  112. package/agent/docs-md/keyboard-navigation.md +68 -0
  113. package/agent/docs-md/keyboard-shortcut-hint.md +87 -0
  114. package/agent/docs-md/keyboard-shortcut-sheet.md +90 -0
  115. package/agent/docs-md/labelling-ai-output.md +66 -0
  116. package/agent/docs-md/layout.md +47 -0
  117. package/agent/docs-md/list-table.md +254 -0
  118. package/agent/docs-md/loading-skeleton.md +91 -0
  119. package/agent/docs-md/managing-agents.md +71 -0
  120. package/agent/docs-md/message-composer.md +105 -0
  121. package/agent/docs-md/migrating.md +49 -0
  122. package/agent/docs-md/motion.md +93 -0
  123. package/agent/docs-md/navigation.md +76 -0
  124. package/agent/docs-md/notification-channels.md +65 -0
  125. package/agent/docs-md/notifications-decision.md +100 -0
  126. package/agent/docs-md/onboarding-step.md +114 -0
  127. package/agent/docs-md/order-book.md +108 -0
  128. package/agent/docs-md/page-header.md +96 -0
  129. package/agent/docs-md/pagination.md +88 -0
  130. package/agent/docs-md/pane-layout.md +105 -0
  131. package/agent/docs-md/period-comparison.md +66 -0
  132. package/agent/docs-md/plan-card.md +120 -0
  133. package/agent/docs-md/popover-rules.md +88 -0
  134. package/agent/docs-md/prompt-editor.md +90 -0
  135. package/agent/docs-md/propose-apply.md +65 -0
  136. package/agent/docs-md/provider-logo.md +97 -0
  137. package/agent/docs-md/radio.md +83 -0
  138. package/agent/docs-md/ranked-list.md +102 -0
  139. package/agent/docs-md/reasoning-progress.md +72 -0
  140. package/agent/docs-md/record-detail.md +71 -0
  141. package/agent/docs-md/regenerating-answers.md +70 -0
  142. package/agent/docs-md/run-status-bar.md +94 -0
  143. package/agent/docs-md/saved-tasks-schedules.md +63 -0
  144. package/agent/docs-md/saved-views.md +149 -0
  145. package/agent/docs-md/saving-views.md +68 -0
  146. package/agent/docs-md/scheduler.md +258 -0
  147. package/agent/docs-md/secondary-panels.md +72 -0
  148. package/agent/docs-md/segmented-control.md +88 -0
  149. package/agent/docs-md/selection-bulk-actions.md +70 -0
  150. package/agent/docs-md/separator.md +75 -0
  151. package/agent/docs-md/setup-checklist.md +92 -0
  152. package/agent/docs-md/shape-elevation.md +55 -0
  153. package/agent/docs-md/sheet-grid.md +211 -0
  154. package/agent/docs-md/side-panel.md +134 -0
  155. package/agent/docs-md/sign-in.md +114 -0
  156. package/agent/docs-md/spacing.md +55 -0
  157. package/agent/docs-md/split-button.md +100 -0
  158. package/agent/docs-md/stat-compare.md +82 -0
  159. package/agent/docs-md/static-dashboard.md +75 -0
  160. package/agent/docs-md/status-badge.md +140 -0
  161. package/agent/docs-md/step-card.md +75 -0
  162. package/agent/docs-md/stepper.md +92 -0
  163. package/agent/docs-md/suggested-changes.md +91 -0
  164. package/agent/docs-md/switch.md +78 -0
  165. package/agent/docs-md/table-settings.md +81 -0
  166. package/agent/docs-md/tabs.md +85 -0
  167. package/agent/docs-md/tag-input.md +108 -0
  168. package/agent/docs-md/tag.md +79 -0
  169. package/agent/docs-md/task-builder.md +87 -0
  170. package/agent/docs-md/team-instructions.md +72 -0
  171. package/agent/docs-md/templates-gallery.md +85 -0
  172. package/agent/docs-md/text-input.md +160 -0
  173. package/agent/docs-md/thinking-steps.md +89 -0
  174. package/agent/docs-md/timeline.md +189 -0
  175. package/agent/docs-md/timestamp.md +84 -0
  176. package/agent/docs-md/timestamps.md +70 -0
  177. package/agent/docs-md/toast.md +117 -0
  178. package/agent/docs-md/tooltip.md +90 -0
  179. package/agent/docs-md/typography.md +62 -0
  180. package/agent/docs-md/undo-destructive.md +66 -0
  181. package/agent/docs-md/unsaved-changes.md +71 -0
  182. package/agent/docs-md/usage-meter.md +80 -0
  183. package/agent/docs-md/user-feedback.md +71 -0
  184. package/agent/docs-md/voice-and-tone.md +60 -0
  185. package/agent/docs-md/why-choice.md +93 -0
  186. package/agent/docs-md/workspace-onboarding.md +74 -0
  187. package/agent/docs-md/writing.md +48 -0
  188. package/agent/llms-full.txt +18369 -0
  189. package/agent/llms.txt +198 -0
  190. package/agent/skills/twoux-audit/SKILL.md +49 -0
  191. package/agent/skills/twoux-build/SKILL.md +39 -0
  192. package/agent/skills/twoux-design/SKILL.md +54 -0
  193. package/agent/skills/twoux-write/SKILL.md +32 -0
  194. package/bin/check.mjs +123 -0
  195. package/bin/docs.mjs +24 -0
  196. package/bin/guard.mjs +27 -0
  197. package/bin/init.mjs +113 -0
  198. package/bin/knowledge.mjs +87 -0
  199. package/bin/mcp.mjs +116 -0
  200. package/bin/theme.mjs +168 -0
  201. package/bin/twoux.mjs +25 -0
  202. package/package.json +80 -3
  203. package/registry/jobs.json +1028 -0
  204. package/registry/palette.json +770 -0
  205. package/registry/rules.json +913 -0
  206. package/src/components/agent-review.tsx +364 -0
  207. package/src/components/ai-basics.tsx +212 -0
  208. package/src/components/ai-work.tsx +304 -0
  209. package/src/components/ai.tsx +227 -0
  210. package/src/components/alert-dialog.tsx +203 -0
  211. package/src/components/alert.tsx +86 -0
  212. package/src/components/avatar.tsx +114 -0
  213. package/src/components/badge.tsx +59 -0
  214. package/src/components/board.tsx +397 -0
  215. package/src/components/breadcrumb.tsx +114 -0
  216. package/src/components/button-group.tsx +90 -0
  217. package/src/components/button.tsx +109 -0
  218. package/src/components/calendar.tsx +247 -0
  219. package/src/components/card.tsx +102 -0
  220. package/src/components/chart-map.tsx +336 -0
  221. package/src/components/charts-more.tsx +1331 -0
  222. package/src/components/charts-radial.tsx +328 -0
  223. package/src/components/charts.tsx +390 -0
  224. package/src/components/checkbox.tsx +40 -0
  225. package/src/components/code.tsx +139 -0
  226. package/src/components/collapsible.tsx +37 -0
  227. package/src/components/combobox.tsx +339 -0
  228. package/src/components/command-extras.tsx +11 -0
  229. package/src/components/command.tsx +196 -0
  230. package/src/components/data-grid.tsx +213 -0
  231. package/src/components/data-table.tsx +334 -0
  232. package/src/components/data-views.tsx +740 -0
  233. package/src/components/date-picker.tsx +686 -0
  234. package/src/components/dense-table.tsx +207 -0
  235. package/src/components/dialog.tsx +162 -0
  236. package/src/components/dropdown-menu.tsx +264 -0
  237. package/src/components/empty.tsx +114 -0
  238. package/src/components/feedback-prompt.tsx +80 -0
  239. package/src/components/field.tsx +254 -0
  240. package/src/components/fields.tsx +112 -0
  241. package/src/components/flow.tsx +840 -0
  242. package/src/components/guide-cue.tsx +273 -0
  243. package/src/components/inbox.tsx +113 -0
  244. package/src/components/input-group.tsx +176 -0
  245. package/src/components/input.tsx +26 -0
  246. package/src/components/kbd.tsx +34 -0
  247. package/src/components/label.tsx +27 -0
  248. package/src/components/labels.tsx +176 -0
  249. package/src/components/motion.tsx +136 -0
  250. package/src/components/onboarding.tsx +454 -0
  251. package/src/components/order-book.tsx +185 -0
  252. package/src/components/pane-layout.tsx +417 -0
  253. package/src/components/popover.tsx +96 -0
  254. package/src/components/provider-logos.data.ts +49 -0
  255. package/src/components/radio-group.tsx +52 -0
  256. package/src/components/scheduler.tsx +997 -0
  257. package/src/components/segmented-control.tsx +28 -0
  258. package/src/components/select.tsx +195 -0
  259. package/src/components/separator.tsx +31 -0
  260. package/src/components/sheet.tsx +148 -0
  261. package/src/components/shell.tsx +426 -0
  262. package/src/components/shortcut-sheet.tsx +83 -0
  263. package/src/components/skeleton.tsx +18 -0
  264. package/src/components/sonner.tsx +107 -0
  265. package/src/components/spinner.tsx +13 -0
  266. package/src/components/split-button.tsx +58 -0
  267. package/src/components/stepper.tsx +78 -0
  268. package/src/components/switch.tsx +43 -0
  269. package/src/components/table.tsx +126 -0
  270. package/src/components/tabs.tsx +118 -0
  271. package/src/components/tag-input.tsx +253 -0
  272. package/src/components/textarea.tsx +21 -0
  273. package/src/components/theme.tsx +80 -0
  274. package/src/components/timeline.tsx +408 -0
  275. package/src/components/toggle-group.tsx +87 -0
  276. package/src/components/toggle.tsx +54 -0
  277. package/src/components/tooltip.tsx +65 -0
  278. package/src/components/workspace-actions.tsx +294 -0
  279. package/src/components/workspace-import.tsx +465 -0
  280. package/src/components/workspace.tsx +1884 -0
  281. package/src/index.ts +80 -0
  282. package/src/lib/active-indicator.tsx +53 -0
  283. package/src/lib/chart-kit.tsx +72 -0
  284. package/src/lib/cn.ts +6 -0
  285. package/src/lib/shortcuts.tsx +61 -0
  286. package/src/lib/workspace.tsx +10 -0
  287. package/src/shadcn/alert-dialog.tsx +196 -0
  288. package/src/shadcn/alert.tsx +65 -0
  289. package/src/shadcn/avatar.tsx +108 -0
  290. package/src/shadcn/badge.tsx +47 -0
  291. package/src/shadcn/breadcrumb.tsx +108 -0
  292. package/src/shadcn/button-group.tsx +83 -0
  293. package/src/shadcn/button.tsx +63 -0
  294. package/src/shadcn/calendar.tsx +220 -0
  295. package/src/shadcn/card.tsx +91 -0
  296. package/src/shadcn/checkbox.tsx +31 -0
  297. package/src/shadcn/collapsible.tsx +33 -0
  298. package/src/shadcn/command.tsx +184 -0
  299. package/src/shadcn/dialog.tsx +158 -0
  300. package/src/shadcn/dropdown-menu.tsx +256 -0
  301. package/src/shadcn/empty.tsx +103 -0
  302. package/src/shadcn/field.tsx +248 -0
  303. package/src/shadcn/input-group.tsx +170 -0
  304. package/src/shadcn/input.tsx +20 -0
  305. package/src/shadcn/kbd.tsx +28 -0
  306. package/src/shadcn/label.tsx +23 -0
  307. package/src/shadcn/popover.tsx +88 -0
  308. package/src/shadcn/radio-group.tsx +44 -0
  309. package/src/shadcn/select.tsx +189 -0
  310. package/src/shadcn/separator.tsx +27 -0
  311. package/src/shadcn/sheet.tsx +142 -0
  312. package/src/shadcn/skeleton.tsx +13 -0
  313. package/src/shadcn/sonner.tsx +40 -0
  314. package/src/shadcn/switch.tsx +34 -0
  315. package/src/shadcn/table.tsx +115 -0
  316. package/src/shadcn/tabs.tsx +90 -0
  317. package/src/shadcn/textarea.tsx +17 -0
  318. package/src/shadcn/toggle-group.tsx +83 -0
  319. package/src/shadcn/toggle.tsx +46 -0
  320. package/src/shadcn/tooltip.tsx +56 -0
  321. package/src/styles/palette.css +127 -0
  322. package/src/styles/theme.css +35 -0
  323. package/src/styles/twoux.css +236 -0
  324. package/theme.json +14 -0
  325. package/README.md +0 -3
package/agent/llms.txt ADDED
@@ -0,0 +1,198 @@
1
+ # TwoUX
2
+
3
+ > Engineering-first design system for complex, data-intensive B2B applications built with AI coding agents: data tables, visualisations, drill-down workflows and command-centre dashboards. TwoUX AI Knowledge: which component and pattern fits each job, and why. Same job, same component, same tokens, same behaviour. Read AGENTS.md first.
4
+
5
+ - [Rules for AI coding agents](AGENTS.md)
6
+ - [Tokens](packages/ui/src/styles/twoux.css)
7
+ - [Job to component registry](packages/ui/registry/jobs.json)
8
+
9
+ ## Foundation
10
+
11
+ - [Colours](docs-md/colours.md): TwoUX is a mostly neutral interface, light by default with a dark theme people can choose. Colour is spent on two things only: the one accent that marks the main action and current selection, and three reserved status families. Every colour is applied through a role token, never a hex value.
12
+ - [Data visualisation colours](docs-md/data-vis-colours.md): One categorical palette of eight colours in a fixed order, one single-hue ordinal ramp of five steps, and a hard rule that status colours never become a series. Validated on white (#ffffff) with an OKLab and colour vision deficiency (CVD) simulator; every colour reaches at least 3:1.
13
+ - [Typography](docs-md/typography.md): Geist for interface text, Geist Mono for IDs, keys and code. A seven-step scale from 11px to 24px with 13px as the default, tuned for dense tables. Numbers in columns use tabular figures.
14
+ - [Spacing](docs-md/spacing.md): Spacing sits on a 4px grid with 2px for fine detail. Space shows relationship: closer means related. Apps use role utilities: fixed ones inside controls that never change, and region ones between parts that tighten by themselves in a workspace.
15
+ - [Content density](docs-md/content-density.md): TwoUX ships one density: compact. Controls are 28 or 32px high and table rows 36px. Spacing that protects reading and pointing is kept, so compact never means cramped targets. Tool pages that pass three tests use workspace density: the same sizes with the chrome and gaps taken out.
16
+ - [Layout](docs-md/layout.md): One app shell for the whole product: a 224px side navigation on the grey --bg, and an inset white canvas where the work happens. Record details open in a side panel that overlays by default and can push the list aside. Below 860px the shell collapses to one column.
17
+ - [Iconography](docs-md/iconography.md): One line icon set, 16px with a 1.7 stroke in currentColor, and a fixed meaning for every icon. An icon that means one thing in one place means that thing everywhere.
18
+ - [Shape and elevation](docs-md/shape-elevation.md): Four radii, each tied to a role, and two shadows. The page is flat; only layers that float above it (menus, popovers, toasts, dialogs) get a real shadow.
19
+ - [Motion](docs-md/motion.md): Motion in TwoUX shows what changed and where it went: 120 to 260ms, eased by role, exits shorter than entrances, and nothing moves when people ask for reduced motion. It never decorates.
20
+ - [Design tokens](docs-md/design-tokens.md): Tokens are the only way a visual value enters TwoUX. They are named for their job, defined once in :root, and consumed by components. Raw hex, px and ms values in product code are bugs.
21
+ - [Consistency](docs-md/consistency.md): TwoUX's first rule: the same job gets the same component, the same token and the same behaviour, on every screen, whether a designer, an engineer or a language model wrote the code. Consistency is what makes a dense product learnable.
22
+ - [Accessibility](docs-md/accessibility.md): TwoUX targets WCAG 2.2 level AA on every component and view. Keyboard is a first-class input, focus is always visible and always managed, and single-key shortcuts can be turned off.
23
+ - [Writing](docs-md/writing.md): TwoUX speaks plain UK English. Buttons start with a verb, everything is in sentence case, and every message says what happened and what to do next. AI is described by what it does, never as smart or magic. How the copy should sound is set in Voice and tone.
24
+ - [Voice and tone](docs-md/voice-and-tone.md): TwoUX sounds like a capable colleague who knows the data: precise, calm, candid and respectful of people's expertise. The voice is the same on every screen and in the assistant. The tone moves with the moment, from strictly practical in an error to one sentence warmer when someone is starting out or has just finished.
25
+ - [Keyboard model](docs-md/keyboard-model.md): TwoUX is built to be driven from the keyboard. ⌘K runs any command, ⌘J opens the assistant, ? shows every shortcut, J and K move through lists, and Esc always closes the innermost layer first.
26
+ - [Migrating an existing app](docs-md/migrating.md): Move an existing product onto TwoUX one screen at a time, keeping its brand and the way it already works. Primitives come over quietly behind the app's own names; the change people notice comes from rebuilding composites and page flows on TwoUX patterns.
27
+
28
+ ## Components
29
+
30
+ - [Button](docs-md/button.md): Starts an action on the current page, such as saving, exporting or opening a menu.
31
+ - [Split button](docs-md/split-button.md): A button joined to a chevron: the button runs the usual action (Import data), the chevron opens its variants (Import all, Import selection).
32
+ - [Text input](docs-md/text-input.md): Lets people type a single line of text, such as a job title, a salary or a search term.
33
+ - [Date picker](docs-md/date-picker.md): Enter a calendar date, or a range of dates, by typing it or choosing it on a calendar: a closing date, a start date, a reporting period.
34
+ - [Combobox](docs-md/combobox.md): Pick one or several values from a long list by typing a few letters, and add a missing one without leaving the form: a location, skills, an owner.
35
+ - [Tag input](docs-md/tag-input.md): Enter several short values that don't come from a list, typed or pasted, and see at once which are wrong: email addresses to invite, allowed domains, keywords.
36
+ - [Form validation](docs-md/form-validation.md): Tells people which fields need fixing and how, at the field and in a summary at the top on submit.
37
+ - [Checkbox](docs-md/checkbox.md): Lets people choose any number of options, or confirm one setting that is applied when they save.
38
+ - [Radio](docs-md/radio.md): Lets people choose exactly one option from a short, visible list in a form.
39
+ - [Switch](docs-md/switch.md): Turns one setting on or off with immediate effect, without a Save button.
40
+ - [Status badge](docs-md/status-badge.md): Shows the system state of a record, such as Live, Draft or Closed early, in one short word or phrase.
41
+ - [Tag](docs-md/tag.md): Labels a record with a category people chose, such as Design, Hybrid or Graduate scheme.
42
+ - [Tabs (underline)](docs-md/tabs.md): Splits one record or page into sections such as Overview, Candidates and Activity, one visible at a time.
43
+ - [Segmented control](docs-md/segmented-control.md): Switches between two or three views or settings of the same content, such as All, Active and Backlog.
44
+ - [Dropdown menu](docs-md/dropdown-menu.md): Opens a short list of actions or options from a button, with optional groups and one level of submenus.
45
+ - [Tooltip](docs-md/tooltip.md): Shows a short, non-essential label or hint on hover or focus, such as an icon button's name and its shortcut.
46
+ - [Keyboard shortcut hint](docs-md/keyboard-shortcut-hint.md): Prints the key or keys that run an action, on its button, menu item or tooltip, so people learn shortcuts by using the product.
47
+ - [Avatar and avatar stack](docs-md/avatar.md): Shows who owns or is linked to a record, as a photo or initials, and several people as an overlapping stack with +N.
48
+ - [Popover rules](docs-md/popover-rules.md): Shared behaviour for every floating layer (menus, filters, snooze, selectors): one open at a time and never cut off.
49
+ - [Sign in](docs-md/sign-in.md): Provider buttons first, then email. Single sign-on is found from the email domain, and an email link means no password to remember.
50
+ - [File drop](docs-md/file-drop.md): Drop a file or choose one. Accepted types and the size limit show before choosing, and a preview replaces the icon once a file is picked.
51
+ - [Connector picker](docs-md/connector-picker.md): Search and connect outside services. Each row says what connecting lets the product do, and a dialog explains the access before anything is shared.
52
+ - [Code block](docs-md/code-block.md): Shows code, commands, IDs or log output exactly as written, so people can read and copy it. Inline Code marks a token inside a sentence.
53
+ - [Card](docs-md/card.md): A white container that groups one object or one task, such as a settings section, a sign-in form or a summary, with an optional header, actions and footer.
54
+ - [Separator](docs-md/separator.md): A thin line that divides groups of content or menu items. With a label, it separates two ways of doing the same thing, such as “or”.
55
+ - [Timestamp](docs-md/timestamp.md): One component for every date and time in the product: relative or absolute display, the exact value on hover and focus, and an optional "by" source.
56
+ - [Provider logo](docs-md/provider-logo.md): The official mark of a service people sign in with or connect, shown unaltered on a white tile beside the service's name.
57
+ - [Toast](docs-md/toast.md): A short, non-blocking confirmation of something the person just did, with Undo when the action can be reversed.
58
+ - [Banner (inline alert)](docs-md/banner.md): A persistent message inside the page about a condition that affects what the person is looking at, with at most one action.
59
+ - [Confirmation dialog](docs-md/confirmation-dialog.md): A modal question before an irreversible or high-impact action, stating the consequence and offering the safe option first.
60
+ - [Empty state](docs-md/empty-state.md): What a list, table or panel shows when it loaded correctly but has nothing to show, with the next step.
61
+ - [Loading skeleton](docs-md/loading-skeleton.md): Grey placeholder rows that keep the table or panel's shape while data loads.
62
+ - [Error state (failed to load)](docs-md/error-state.md): Shown in place of a region that failed to load: what failed, that nothing was lost, and Try again.
63
+ - [Side panel (drawer)](docs-md/side-panel.md): A panel on the right that shows the selected row's detail beside the table, in push (default) or overlay mode; 440px by default and resizable from 360px to half the canvas in push mode.
64
+ - [Command palette (⌘K)](docs-md/command-palette.md): A searchable list of actions and destinations, scoped to the current selection, opened with ⌘K from anywhere.
65
+ - [Shortcut sheet (?)](docs-md/keyboard-shortcut-sheet.md): A panel listing every shortcut by task, opened with ?, which also holds the switch to turn single-key shortcuts off.
66
+ - [Inbox (triage)](docs-md/inbox.md): The one place for things that need the person, shown as a list beside the selected item's detail, cleared by doing, marking done or snoozing.
67
+ - [Notifications vs inbox vs toast](docs-md/notifications-decision.md): The rule for where a message goes: toast for your own action, banner for a condition on this page, inbox for anything that needs you later, activity for the rest.
68
+ - [App shell and sidebar navigation](docs-md/app-shell.md): The frame of every screen: a tinted left sidebar for navigation and an inset white canvas with a top bar for breadcrumb, Ask and search.
69
+ - [Pane layout](docs-md/pane-layout.md): A workspace that fills the screen with columns of panes people resize with splitters and rearrange by dragging, for tool pages such as trading screens and editors where everything has to stay in view.
70
+ - [Breadcrumb](docs-md/breadcrumb.md): A short trail in the top bar showing where the page sits in the hierarchy, ending with the current page.
71
+ - [Page header](docs-md/page-header.md): The page title on the left and its actions on the right, with exactly one primary action per view.
72
+ - [Stepper](docs-md/stepper.md): A vertical list of numbered steps for a task done in order, such as setting up a workspace or publishing a listing, showing what is done, what is current and what is left.
73
+ - [Setup checklist](docs-md/setup-checklist.md): A short list in the sidebar of the few things that make the product useful, with progress shown as "2 of 4".
74
+ - [Onboarding step](docs-md/onboarding-step.md): One step of first-run setup on a plain page: why we ask, the fields, which step this is, and Back, Skip and Continue.
75
+ - [Help panel](docs-md/help-panel.md): Read-only help in the right-hand panel slot, opened from an Info link next to a heading or label, with the topic heading, short guidance and Learn more links.
76
+ - [Feedback prompt](docs-md/feedback-prompt.md): A small "Was this helpful?" block with Yes and No buttons, a thank you once voted, and an optional short follow-up form.
77
+ - [Usage meter](docs-md/usage-meter.md): Credits or seats used against a limit, when it resets, and what used them. An upgrade link appears only near the limit.
78
+ - [Guide cue](docs-md/guide-cue.md): A short guide of one to three popovers that point at the real controls for a task, opened only when the person asks to be shown.
79
+ - [List table](docs-md/list-table.md): A read-mostly table for scanning and triaging records such as listings or candidates, with a sticky header, sortable columns, J and K row focus and checkbox selection.
80
+ - [Dense table](docs-md/dense-table.md): The List table at 28px rows for spreadsheet-like data, such as a life-cycle inventory or a product library, with group rows, row numbers with a row menu, a filter row, in-cell buttons and frozen first columns.
81
+ - [Data grid](docs-md/data-grid.md): An editable, spreadsheet-like grid for enriching and exporting many columns, with pinned columns, cell-by-cell keyboard navigation, a totals row and AI-generated columns.
82
+ - [Filter pills and filter bar](docs-md/filter-bar.md): Filters applied from one button in the toolbar and shown as segmented chips on their own row: each reads as a sentence, values apply as soon as they are ticked, and the row appears only while something is filtered.
83
+ - [Filter panel](docs-md/filter-panel.md): A side panel of collapsible filter sections for searches with many fields, with live counts per option and a main action that says how many rows it will act on.
84
+ - [Saved views](docs-md/saved-views.md): Named, reusable combinations of filters, sort order and column choices, also kept in the URL so a link reproduces the view.
85
+ - [Bulk action bar](docs-md/bulk-action-bar.md): A grey band directly above the table while rows are selected: the actions that apply to every selected row, the count and Clear selection.
86
+ - [Pagination and counts](docs-md/pagination.md): The footer that says which rows are showing and how many exist ("1–100 of 1,262"), with previous and next controls and the selection count.
87
+ - [Grouped list](docs-md/grouped-list.md): A compact list of records split under group headers (such as candidates by stage), each header showing its count.
88
+ - [Export menu](docs-md/export-menu.md): One Export menu per table: options first (only visible columns, include AI columns), then file formats, then copy to clipboard.
89
+ - [Board and board item](docs-md/board.md): A dashboard grid of self-contained items, such as charts, stats and lists, that people can reorder, resize and remove to build the overview they need.
90
+ - [Stat card with comparison](docs-md/stat-compare.md): One number that matters, with its change against a named previous period shown by arrow, sign and colour, and an optional faint previous-period line.
91
+ - [Line chart card](docs-md/chart-card-line.md): A card that shows how one or more series change over time, with a title, period controls, a Chart or Table switch, direct labels, a shared crosshair tooltip and a source footer.
92
+ - [Bar chart](docs-md/chart-bar.md): Vertical bars from a zero baseline for comparing amounts per period or category, with the latest bar labelled and an incomplete period shown lighter.
93
+ - [Heatmap](docs-md/chart-heatmap.md): A grid of two dimensions (such as team by weekday) shaded in one hue from light to dark, with every cell showing its number and a legend under the grid.
94
+ - [Funnel](docs-md/chart-funnel.md): Horizontal bars for ordered stages (views, applies, interviews, offers) that show each stage's count and its rate from the stage before, darkest to lightest.
95
+ - [Breakdown table](docs-md/breakdown-table.md): A table under a chart that splits its figure by team, location or owner, with current and previous periods side by side and change in both units.
96
+ - [Stacked area chart](docs-md/chart-area.md): Two or more series stacked over time, so the top edge is the total and each band is one part of it, such as applications per week split by source.
97
+ - [Bar and line chart](docs-md/chart-mixed.md): One bar series with one to three lines on the same y-axis and unit, such as weekly applications as bars and their four-week average as a line.
98
+ - [Donut chart](docs-md/chart-donut.md): Two to five parts of one total at a single moment, with the total in the centre and every segment labelled with its count and share. Most of the time a bar chart is better.
99
+ - [Scatter chart](docs-md/chart-scatter.md): One dot per record placed by two measures, such as each live listing by advertised salary and applications, for spotting relationships and outliers.
100
+ - [Items palette](docs-md/items-palette.md): A searchable list, in a side panel beside a configurable dashboard, of the items a person can add, each with a title, a short description, its type and an Add to dashboard button.
101
+ - [Share bar](docs-md/chart-share-bar.md): One whole split into up to six parts in a single horizontal bar, with each part's name and share in a legend above. Smaller parts fold into a grey Other.
102
+ - [Ranked list](docs-md/ranked-list.md): Ranked rows with a series dot or icon, name, value and change, optionally a sparkline. Beside a stacked chart it is the chart's legend; each row links to the record.
103
+ - [Change list](docs-md/change-list.md): Ticker rows for indices, prices or rates: name and code, value with unit, change by arrow, sign and colour, an optional sparkline, and a See all link.
104
+ - [Price chart](docs-md/chart-price.md): One price over a session: a line with a light wash, the last value tagged on the right axis, the previous close as a dashed reference, a live dot, and an axis that says when it does not start at zero.
105
+ - [Waterfall chart](docs-md/chart-waterfall.md): How an opening amount becomes a closing amount: each increase and decrease floats from the running total, joined by connectors, with totals in grey from zero.
106
+ - [Bullet chart](docs-md/chart-bullet.md): Actual against target for a few measures: a thin bar over grey qualitative bands with the target as a dark tick, in a fraction of a gauge's space.
107
+ - [Treemap](docs-md/chart-treemap.md): Parts of a total as nested rectangles sized by value: squarified so tiles stay readable, names only where they fit, and the tail folded into Other after 12 tiles.
108
+ - [Sankey chart](docs-md/chart-sankey.md): Flows from left to right across two or three columns, such as traffic sources to pages to outcomes. Link width shows value; hover or focus highlights a path.
109
+ - [Histogram](docs-md/chart-histogram.md): How values spread: touching columns, one per equal bin, counted on one axis, with an optional dashed marker such as the median.
110
+ - [Box plot](docs-md/chart-box-plot.md): Distributions of several groups on one axis: a box for the middle half, a line for the median, whiskers to 1.5 times the IQR and dots for outliers.
111
+ - [Candlestick chart](docs-md/chart-candlestick.md): Open, high, low and close per period for a price. Up candles are hollow and down candles filled, in two categorical colours, or green and red on trading screens; volume is its own chart below.
112
+ - [Order book](docs-md/order-book.md): Resting sell and buy orders either side of the spread, each with a bar for the running total, so people see where the price is likely to meet resistance and can pick a price to trade at.
113
+ - [Map chart](docs-md/chart-map.md): Regions shaded by a rate in five steps of one hue, or circles sized by an amount at places. For questions where location itself matters; missing regions are hatched and labelled No data.
114
+ - [Timeline](docs-md/timeline.md): Scheduled work across a few tracks on one time ruler, such as releases and maintenance per service or hiring campaigns per team. Spans and instants, a labelled Now line, four zoom levels; selecting an event opens it in the side panel.
115
+ - [Radial bars](docs-md/chart-radial-bars.md): One to four small concentric rings, each the share of a fixed limit such as seats, credits or storage, with used of limit always written beside them. Never actual against target: that stays the bullet chart.
116
+ - [Radial lines](docs-md/chart-radial-lines.md): A line chart wrapped round a circle for cyclical periods (hour of day, day of week, month), so the last period runs into the first. One to three series, values from zero, gaps for missing data.
117
+ - [Scheduler](docs-md/scheduler.md): Interviews, shifts or bookings on a day, week or month grid, with people or rooms as resources. Click a free time to add, click an event to open it, and drag, use the keyboard or the event menu to move it. Below 768px it becomes an agenda list.
118
+ - [Sheet grid](docs-md/sheet-grid.md): A spreadsheet of records with typed columns, a menu per column, row numbers and a status row for computed columns, and Excel and Google Sheets keys: select ranges, copy and paste to and from either, fill, clear and undo. size="dense" gives 28px rows for spreadsheet-like data.
119
+ - [Columns menu](docs-md/columns-menu.md): A menu that shows, hides and reorders the columns of a sheet or list table, with search, Show all and Hide all, type icons and eye toggles, plus wrapping and rows per page on list tables. Changes apply at once.
120
+ - [Run status bar](docs-md/run-status-bar.md): The bottom bar of a sheet: Table up to date, or how far the run is with a meter, the credits spent so far and Stop; run history; and Auto-run with its cost per row.
121
+ - [Field mapping](docs-md/field-mapping.md): A list of target fields, each with the source column that fills it: required fields marked, type mismatches warned in words, and other source columns skipped or created as new columns. Used by imports and, later, automations.
122
+ - [CSV import](docs-md/csv-import.md): A two-step dialog: choose a CSV file, its delimiter and header row; then match columns, read the problems before importing, preview the first 20 rows with problem cells marked, and import with the count on the button.
123
+ - [Action catalogue](docs-md/action-catalogue.md): A searchable list, in the side panel, of actions that add a column: look-ups from other services, AI, formulas and exports, each with a one-line description and its cost per row. Choosing one opens a short set-up with the estimated total.
124
+ - [Table settings](docs-md/table-settings.md): Settings for one table in the side panel: how duplicates are handled with the consequence written out, deleting empty rows, and sharing as a template with who can use it. Saved with Save; closing with changes asks first.
125
+ - [Assistant side panel](docs-md/assistant-panel.md): A side panel, opened with ⌘J, where people ask about the records on screen and get answers grounded in the current selection and filters.
126
+ - [Assistant page](docs-md/assistant-page.md): The same conversation opened as a full page, with Answer and Records tabs and a Sources panel listing every record the answer used.
127
+ - [Message composer](docs-md/message-composer.md): The message box with context chips, a + menu, @ mentions, / saved tasks, typeahead completions and the Quick or Thorough answer mode.
128
+ - [Thinking and steps](docs-md/thinking-steps.md): A row that shows what the assistant is doing in words with a running timer, then collapses to "Thought for 2.1s · 4 steps" and expands on request.
129
+ - [Clarifying question card](docs-md/clarifying-question.md): A card docked above the message box that asks up to three questions with recommended defaults when the answer would change the result.
130
+ - [Suggested changes](docs-md/suggested-changes.md): A proposal card listing each change with a checkbox and before and after, applied with one button and undoable afterwards.
131
+ - [Step card](docs-md/step-card.md): The proposal turns into a step card while changes apply: each change shows a spinner then a check, with an "N / M" counter, and the table updates row by row.
132
+ - [Follow-ups and starters](docs-md/follow-ups-starters.md): Follow-ups continue an answer as muted rows under a "Follow-ups" label; starters appear only in the empty state as suggested tasks based on what is on screen.
133
+ - [Citations and sources](docs-md/citations-sources.md): Record IDs inline in answers that open the record, plus a Sources panel on the full page listing every record and file the answer used.
134
+ - [AI origin label](docs-md/ai-origin-label.md): One small mark and short text on generated content, such as "Assistant · from your workspace data". No sparkle on every button and no separate AI colour.
135
+ - [AI column](docs-md/ai-column.md): A generated table column that fills one row at a time, cites each row, shows when it was written and never overwrites real data.
136
+ - [Task builder](docs-md/task-builder.md): Repeated tasks written as a sentence with editable slots that reuse filter values, with Run blocked until every required slot is filled.
137
+ - [Agent permissions](docs-md/agent-permissions.md): Per-action access set in plain words with three levels, Off, Ask first and Allow, grouped into Read and Change.
138
+ - [Agent run timeline](docs-md/agent-run.md): The steps of an agent run with state in shape and colour, the filter each step used, a highlighted waiting step and Stop always visible.
139
+ - [Connected tools](docs-md/connected-tools.md): Outside tools listed in the + menu and settings, each with a detail card saying what it can read and change, where data is stored and who connected it.
140
+ - [Team instructions and files](docs-md/team-instructions.md): Shared instructions and files set once for the workspace, visible and editable, and named in the assistant's empty state and citations when used.
141
+ - [Previous conversations](docs-md/conversation-history.md): A searchable list opened from the clock in the panel bar: scheduled tasks first, then recent conversations, with a dot for a new answer and "Needs you" for one waiting.
142
+ - [Templates gallery](docs-md/templates-gallery.md): A dialog with categories on the left, search on top and cards that say what each template does and which tools it uses; picking one opens it as a draft task.
143
+ - [Prompt editor with fields](docs-md/prompt-editor.md): An editor where row fields and team files are removable chips, inputs and outputs are listed with types, and the prompt is tested on a few rows before running on the whole table.
144
+ - [Answer actions](docs-md/answer-actions.md): The row under every answer: origin label on the left, then Copy, Helpful, Not helpful, Regenerate and a More menu. Always visible, never only on hover.
145
+ - [Generated file card](docs-md/artifact-card.md): A compact card under an answer for one thing the assistant made: name, type and size, origin label, and up to two actions with the rest in a More menu.
146
+ - [Plan preview](docs-md/plan-card.md): The plan an agent shows before a multi-step or costly run: numbered steps people can remove, risky steps marked in words, and nothing running until it is approved.
147
+ - [Change review](docs-md/change-request.md): The review queue for changes an agent proposes to records, procedures, prompts, tools or another agent: the reason, the diff, and test results, approved or rejected by a person.
148
+ - [Confidence note](docs-md/confidence-note.md): A short note beside agent output that says, in words, what the agent is unsure about, why, and the safer option or the way to check.
149
+ - [Why this choice](docs-md/why-choice.md): A small Why? control beside a choice an agent made. On demand, it names the deciding factors and the options that lost, then offers Change this or Keep it.
150
+
151
+ ## Patterns
152
+
153
+ - [Filtering and search](docs-md/filtering-search.md): Narrow a list to the rows that matter with filter pills that apply as you tick, show counts, and live in the URL.
154
+ - [Saved views](docs-md/saving-views.md): Store a filtered, sorted, column-chosen list under a name so people and teams return to it in one click.
155
+ - [Selection and bulk actions](docs-md/selection-bulk-actions.md): Pick rows with X or checkboxes, then act on all of them from one bar above the table that says how many rows it will touch.
156
+ - [Inline editing and validation](docs-md/inline-editing-validation.md): Edit values where they are shown, check each field when the person leaves it, and summarise every problem on submit.
157
+ - [Empty, loading and error states](docs-md/empty-loading-error.md): One rule set for the three states every view has before or instead of data: loading, nothing to show, and failed.
158
+ - [Undo and destructive actions](docs-md/undo-destructive.md): Decide between Undo after the fact and a confirmation before it, using one test: can the action be reversed, and who else does it reach?
159
+ - [Notifications: inbox, bell, toast or email digest](docs-md/notification-channels.md): Route every message by one question: does it need this person to act? Things that need you go to the Inbox; your own results go in a toast; nothing gets a separate bell list.
160
+ - [Record detail: side panel, overlay or full page](docs-md/record-detail.md): Open a record in a side panel that pushes the list by default, overlay it on narrow or wide-content pages, and go to the full page for deep work.
161
+ - [Keyboard-first navigation](docs-md/keyboard-navigation.md): Every action has a key shown on its button. J/K move, Enter opens, Esc steps back one layer at a time, ⌘K runs anything, ⌘J asks the assistant.
162
+ - [Data export](docs-md/data-export.md): One Export menu on every table: choose what to include first, then the format, then copy instead of download if you want.
163
+ - [Comparison over time](docs-md/period-comparison.md): Every headline number says what it compares against: this period vs the previous period of the same length, with arrow, sign and colour.
164
+ - [Onboarding to an empty workspace](docs-md/workspace-onboarding.md): A new workspace shows a short setup checklist in the sidebar and empty states that each offer one way in: create, import or start from a template.
165
+ - [Ask about what's on screen](docs-md/ask-on-screen.md): ⌘J or Ask opens the assistant beside the data with the current selection and filters as removable context chips, so the scope of every answer is visible.
166
+ - [Propose, then apply](docs-md/propose-apply.md): The assistant never edits on its own: it lists suggested changes with checkboxes, the person applies them in one step, each change shows its progress, and Undo reverses all of it.
167
+ - [Showing reasoning and progress](docs-md/reasoning-progress.md): While working, say the current step in words with a running timer and a Stop; when done, collapse to "Thought for 2.1s · 4 steps" that opens on request.
168
+ - [Clarifying before acting](docs-md/clarify-before-acting.md): When the answer would change the result, ask with a question card above the composer: options with a recommended default, number keys, Skip and Next.
169
+ - [Citing sources](docs-md/citing-sources.md): Every claim in an answer links to the record it came from by ID; clicking opens the record in the side panel, and the full page lists every record used.
170
+ - [Labelling AI output](docs-md/labelling-ai-output.md): Mark generated content with one small origin mark next to it. No AI colour, no sparkle on every button, no "AI-powered" copy.
171
+ - [Agents acting on your behalf](docs-md/agents-on-behalf.md): Agents work within permissions set per action (Off, Ask first, Allow), show every run as a list of steps, stop to wait for you through the Inbox, and can always be stopped.
172
+ - [Generated table columns and enrichment](docs-md/generated-columns.md): Add an AI column, test it on three rows, see the cost per row, then run it with progress and Stop. Each cell shows its own state and cites its record.
173
+ - [Saved tasks and schedules](docs-md/saved-tasks-schedules.md): Turn repeated requests into a task sentence with editable slots, test it once, then save it and optionally run it on a schedule.
174
+ - [Data visualisation](docs-md/data-visualisation.md): Start from the question the person is asking, pick the one chart that answers it, give it a noun title, units and a period, and ship it with a table view and its four states.
175
+ - [Chart drill-down](docs-md/chart-drill-down.md): Select a point on a chart to see what makes it up, then narrow the chart or the whole page to that point, with every applied filter shown as a pill you can remove.
176
+ - [Static dashboard](docs-md/static-dashboard.md): A fixed overview page where the team sees the same items in the same order, most important first, answering the day's questions at a glance.
177
+ - [Configurable dashboard](docs-md/configurable-dashboard.md): A personal overview where each person adds, removes, moves and resizes items on a board, with an items palette to add from, a saved layout and a reset to the default.
178
+ - [Dashboard items](docs-md/dashboard-items.md): The catalogue of item types a dashboard is built from, such as key metrics, charts, short lists, alerts, quick links, getting started and feature news, and what each one should contain.
179
+ - [Regenerating an answer](docs-md/regenerating-answers.md): Regenerate reruns the same question with the same context and replaces the latest answer, keeping the earlier version one step away. It never touches changes already applied.
180
+ - [Generated drafts and files](docs-md/generated-drafts-files.md): Show what the assistant makes (a job description, a CSV, a chart) as a card under the answer. Short things are read and copied in place; long drafts open on the assistant page. Anything that would change a record goes through Suggested changes.
181
+ - [Asking for details inside the answer](docs-md/inline-input-in-answer.md): When the assistant knows what to do but needs a few values to do it, it asks with a short form card in the thread, prefilled from context. Submitting the form produces a proposal, not a change.
182
+ - [Agent activity log](docs-md/agent-activity-log.md): A chronological list of what agents and the assistant did across runs: time, an icon with a word for the outcome, a past-tense label that links to the run or message, grouped by day.
183
+ - [Managing agents](docs-md/managing-agents.md): One Agents page lists every agent with its source, what it does, whether it is on and where it may act. People turn agents on and off with Undo, edit scope in the side panel, and agents are never switched off or deleted without someone choosing to.
184
+ - [Disabled and read-only states](docs-md/disabled-read-only.md): Show an action as unavailable only when the person can do something about it, say why in one sentence, and show values they can't change as read-only rather than greyed out.
185
+ - [Drag and drop](docs-md/drag-and-drop.md): Dragging is a shortcut, never the only way: every drag in TwoUX has a keyboard path and a menu path that do the same thing.
186
+ - [Error messages](docs-md/error-messages.md): Put every error where it happened, at the smallest scope that contains it, and say what went wrong and what to do next in plain words.
187
+ - [Contextual help](docs-md/help-system.md): Answer "what is this, why does it matter, how do I choose" in three steps of depth: the words on the screen, a help panel opened from an Info link, and a help centre article in a new tab.
188
+ - [Secondary panels: which right-hand panel](docs-md/secondary-panels.md): TwoUX has one right-hand panel slot. Record detail, the assistant, help and filters each have a clear job, only one is open at a time, and none is ever required to finish a task.
189
+ - [Collecting product feedback](docs-md/user-feedback.md): Ask "Was this helpful?" in a quiet spot after people have read or used something, record the Yes or No straight away, then offer one short optional question.
190
+ - [Unsaved changes](docs-md/unsaved-changes.md): Don't let people lose work by accident: save drafts of long text automatically, and ask before discarding a changed form only when there really are changes.
191
+ - [Timestamps](docs-md/timestamps.md): Show when things happened as relative time in lists ("3 hours ago"), the exact date and time on hover and in record details, and always say what the time refers to and who caused it.
192
+ - [Page actions and row actions](docs-md/actions.md): Actions that affect the page or many records sit in the page header or the bulk action bar; one or two frequent actions also sit on each row, and every row action is reachable from the selection too.
193
+ - [Choosing a selection control](docs-md/choosing-selection-control.md): Pick the control from three questions: one choice or many, how many options, and does it apply at once or on Save.
194
+ - [Creating a record: dialog, single page or steps](docs-md/create-record.md): Pick the creation surface by how much people must decide: a small dialog for a name or two, one page for most records, steps only for long or high-stakes set-ups. Fill everything else with visible defaults.
195
+ - [Editing a record: inline, section or whole page](docs-md/edit-record.md): Change one value where it is shown, one section in place, or many linked settings on an edit page that mirrors the create form. Every saved edit can be undone.
196
+ - [Deleting records](docs-md/delete-record.md): Deleting moves records to Deleted with Undo. Only permanent or cascading deletes ask first, and only the rare, severe ones ask people to type the name.
197
+ - [Navigation: what goes in the sidebar and the top bar](docs-md/navigation.md): The sidebar holds where you can go and the few things you always need; the top bar holds where you are and what this page does. Records never become sidebar items.
198
+ - [Announcing new and beta features](docs-md/announcing-features.md): Mark new or beta things where people meet them, with a small text label that opens a short explanation. Keep a What's new list for the rest. Never use toasts or banners for announcements.
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: twoux-audit
3
+ description: Audit a screen, flow or whole app against TwoUX, propose fixes and apply the ones the person approves. Works on three kinds of app - one built with @twoux/ui (drift, wrong component, missing states, broken patterns), one not built with TwoUX (TwoUX's principles met with the app's own components and brand), and one moving onto TwoUX (a step-by-step migration plan). Every finding cites the TwoUX page behind it. Use when someone asks to audit, review, improve, clean up, "make consistent", refactor or migrate UI, even if they don't mention TwoUX.
4
+ ---
5
+
6
+ # TwoUX audit
7
+
8
+ TwoUX's rules, job table and pages are the authority: `node_modules/@twoux/ui/agent/AGENTS.md` and `node_modules/@twoux/ui/agent/docs-md/<id>.md` (inside the TwoUX repo: `AGENTS.md` and `docs-md/`). Read AGENTS.md first.
9
+
10
+ ## 1. Mode and scope
11
+ Pick the mode from the project, and say which one you chose:
12
+ - **TwoUX app:** `@twoux/ui` is a dependency and the screens use it. Every rule applies.
13
+ - **Principles:** the app is not built with TwoUX and the person isn't moving it onto TwoUX (`twoux init --principles` writes this into AGENTS.md). Only rules not marked **TwoUX only** apply. Fixes use the app's own components, tokens and brand; never bring in TwoUX components piece by piece, and never impose TwoUX's look.
14
+ - **Migrate:** the person wants to move the app onto TwoUX. Follow `docs-md/migrating.md`.
15
+
16
+ Then agree the scope: which screens or files, and whether to report only or also fix. Default: report first, fix after the person agrees.
17
+
18
+ ## 2. Mechanical check
19
+ - TwoUX app: `npx twoux check <paths>` (TwoUX repo: `pnpm twoux-check <paths>`). Every error is a finding.
20
+ - Principles: `npx twoux check --principles <paths>`, which runs only the checks that hold outside TwoUX (copy tone).
21
+ - Migrate: also measure the app: React and Tailwind versions, CSS variable names shared with TwoUX (primary, border, muted, radius, font…), raw Tailwind colour classes (count by file), components whose names match TwoUX's (Button, Badge, Tabs, Dialog…), and the app's composites (filter chips, cards, panels, dialogs) with the TwoUX job each one does.
22
+
23
+ ## 3. Read the screen as a person would
24
+ For each region, ask:
25
+ - **Job:** what is the person trying to do here? Find the job in the AGENTS.md job table. In a TwoUX app, is the component the one TwoUX names? In principles mode, does the app's component behave the way that TwoUX component does (a record opens beside the list, not in a modal or a new page)?
26
+ - **Pattern:** does a TwoUX pattern cover this flow (filtering, bulk actions, create, edit, delete, record detail, propose then apply, dashboards, errors, disabled and read-only, help, feedback)? Read its page and check every step. Patterns are principles: they hold in any app.
27
+ - **States:** loading (skeleton for tables), empty (no data vs no results), error in place with Try again, disabled with a reason vs read-only, unsaved changes.
28
+ - **Actions:** one primary per view; destructive actions confirm only when Undo can't fix them; every action keyboard-reachable with its shortcut shown.
29
+ - **Content:** read `docs-md/writing.md` and `docs-md/voice-and-tone.md`; they override any general UX writing or design skill. UK English, sentence case, verb-first labels; errors say what happened and what to do next; the tone fits the moment; no humour, apology, please, exclamation mark, celebration, "we" or words from the cut list; assistant text in the same voice. Every `tone` warning is a finding.
30
+ - **Craft:** reading order follows the job; hierarchy from size, weight and position; groups visible through spacing; edges aligned; none of the lazy defaults in `node_modules/@twoux/ui/agent/skills/twoux-design/SKILL.md` step 3. Render the screen at 1280, 768 and 320px in light and dark when you can.
31
+ - **AI:** proposals before changes, origin label, citations, no automated decisions about people.
32
+ - **Accessibility:** WCAG 2.2 AA: contrast, 24px targets, visible focus, names, status not by colour alone, reflow at 320px.
33
+
34
+ In principles mode, if the app's own design system deliberately does something differently from a TwoUX principle, report it as a conflict for the person to decide, not as a defect.
35
+
36
+ ## 4. Propose
37
+ Group findings by severity: **Blocks people** (accessibility failures, data loss risk, wrong destructive behaviour), **Drift** (wrong component, restyles, raw values, broken patterns), **Polish**. For each: where (file:line or region), what is wrong, the proposed change, and the page that backs it (`docs-md/<id>.md`, which carries the sources). Never cite a rule that isn't in TwoUX's files, and in principles mode never cite a **TwoUX only** rule.
38
+
39
+ In migrate mode, the proposal is the plan from `docs-md/migrating.md` in order (platform, init, theme, token owners, raw colours, adapters, codemod, screen by screen, CI), filled in with what you measured: which tokens collide, how many raw classes, which adapters, which screens first and why.
40
+
41
+ Number the proposals so the person can approve them by number.
42
+
43
+ ## 5. Apply what was approved
44
+ - Apply only the approved items, one screen or one migration step at a time, each small enough to review.
45
+ - TwoUX app: fix with TwoUX components and props, in app code only. Never edit `@twoux/ui` or `packages/ui`; if TwoUX lacks something, use the closest component and tell the person what is missing.
46
+ - Principles: fix with the app's own components and tokens, keeping its brand and its existing flows where they already work. Change behaviour, structure and words, not the look: an element you rebuild (a toast that gains role="status" and Undo, a modal that becomes a side panel) keeps the colours, shape and type it had, or takes them from the app's nearest existing element. Before finishing, compare every class you changed on a surface people see; if a colour, radius or font changed and no finding required it, put it back.
47
+ - Migrate: follow the step's instructions in `docs-md/migrating.md`; run the app's tests after each step and report what failed and why.
48
+ - Verify before reporting, using the project's own scripts (package.json): type-check, run the tests, and render each changed screen (start the dev server and open it in a browser or with Playwright) at 1280 and 320px. Try the states you fixed: empty, no results, an error, Undo, keyboard only. If a step can't run (no script, no browser), install nothing new; say which step didn't run and what still needs a look.
49
+ - Re-run the check from step 2 and list what changed, what was verified and how, what was left and why.
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: twoux-build
3
+ description: Build a new page, feature, layout or interaction with TwoUX so it matches the system without drift. Maps the request to TwoUX jobs and patterns, picks components by job, covers every state, and checks the result. Use whenever someone asks to build, add, create or design UI (a page, table, form, dashboard, settings section, AI feature) in a project that uses @twoux/ui.
4
+ ---
5
+
6
+ # TwoUX build
7
+
8
+ TwoUX's rules, job table and pages are the authority: `node_modules/@twoux/ui/agent/AGENTS.md` and `node_modules/@twoux/ui/agent/docs-md/<id>.md` (inside the TwoUX repo: `AGENTS.md` and `docs-md/`). Read AGENTS.md first.
9
+
10
+ ## 1. Understand the job
11
+ Restate the request as jobs people do ("narrow the candidates list", "move several candidates to the next stage", "see hiring health at a glance"). If the request bundles several, list them.
12
+
13
+ ## 2. Find the pattern, then the components
14
+ - Look for a TwoUX pattern that covers the flow (patterns are listed in AGENTS.md and docs-md). Follow its steps in order.
15
+ - For each job, use the component the job table names. Read its page: When to use, When not to use, Behaviour, Accessibility, Keyboard, API.
16
+ - If something is missing or only planned, use the closest existing component and tell the person. Never build a local version, a lookalike or a partial one.
17
+
18
+ ## 3. Plan before code
19
+ Write a short plan for the person: layout (regions in reading order), components per region, the states each region has (loading, empty, no results, error, disabled or read-only), keyboard shortcuts, and which sources back the main decisions. Ask only about decisions that are theirs (data, scope); decide UI questions from TwoUX.
20
+
21
+ ## 4. Build
22
+ - Import everything from `@twoux/ui`. Use variants and sizes, not classes, to change a component. Layout classes (grid, flex, gap, width, margin) are yours.
23
+ - Tokens only: no hex, no arbitrary values, no inline styles (a CSS variable for data-driven values is allowed).
24
+ - To change the brand, corners or font, edit `twoux.theme.json` and run `npx twoux theme`. Never restyle per page.
25
+ - One primary action per view.
26
+
27
+ ## 5. Write the copy
28
+ Read `docs-md/writing.md` and `docs-md/voice-and-tone.md` before writing any label, message or empty state. They override any general UX writing or design skill where the two differ.
29
+ - For each message, name the moment and its tone from the tone map: inform (default, errors and warnings), empower (decisions and confirmations), encourage (stuck or partly done), motivate (only when someone is starting), satisfy (routine: past tense, a count, Undo).
30
+ - Voice stays the same everywhere: precise, calm, candid, respectful of expertise. UK English, sentence case, verb-first labels.
31
+ - Errors say what happened and what to do next. No apology, please, exclamation mark, joke or celebration, and no "we": state the event.
32
+ - Cut the words listed in voice-and-tone: just, simply, easy, seamless, smart, magic, AI-powered, successfully…
33
+ - Assistant text uses the same voice: the answer first, no greeting, "I" only for what it did.
34
+
35
+ ## 6. Finish the layout
36
+ For a new page, layout or dashboard, run `/twoux-design` on the result (outside Claude Code, follow `node_modules/@twoux/ui/agent/skills/twoux-design/SKILL.md`): lay out from the job, refuse the lazy defaults, render and check at several widths in light and dark. Correct components are not yet good UI.
37
+
38
+ ## 7. Check
39
+ Run `npx twoux check` and fix every error and every `tone` warning. Check reflow at 320px and keyboard use (Tab order, shortcuts, focus return). Report what you built, the states covered, anything you chose not to do and why, and anything TwoUX doesn't have yet.
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: twoux-design
3
+ description: Make a new or existing TwoUX screen good UI, not just correct UI. Plans the layout from the job, sets hierarchy with TwoUX's own type, spacing and elevation, refuses the lazy defaults (nested cards, card grids as page structure, eyebrow labels, decoration), then renders the screen and checks spacing, alignment, contrast, states, real content and reflow in light and dark. Use when building a new page, layout or dashboard, after /twoux-build has chosen the components, or when someone asks to polish, tidy, refine or "make it look good" in a project that uses @twoux/ui.
4
+ ---
5
+
6
+ # TwoUX design
7
+
8
+ Good UI in TwoUX comes from the job, the hierarchy and the finish, never from a new look. TwoUX already decided the palette, type, radius, density, motion and components; this skill makes a screen use them well. It overrides any general design skill that asks for a new palette, a display font, a signature visual move, a hero or extra motion.
9
+
10
+ The authority is `node_modules/@twoux/ui/agent/AGENTS.md` and the pages in `node_modules/@twoux/ui/agent/docs-md/` (inside the TwoUX repo: `AGENTS.md` and `docs-md/`). Read `layout.md`, `spacing.md`, `typography.md`, `shape-elevation.md`, `content-density.md` and `voice-and-tone.md` before step 2.
11
+
12
+ ## 1. Lay out from the job
13
+ - Write the screen's job in one sentence and what people read first, second and third. That order is the layout's order.
14
+ - Use the one app shell (`layout.md`): top bar, PageHeader with one primary action, then content. Record detail opens in the side panel, never a modal or a new layout.
15
+ - Pick the main region by the work: a table or list to scan and act, a form in Card sections to create or edit, a dashboard pattern (`static-dashboard.md`, `dashboard-items.md`) to answer questions at a glance. The main region gets the most width; supporting regions are narrower and quieter.
16
+ - Everything on the screen earns its place by answering the job. Remove what doesn't before styling what's left.
17
+
18
+ ## 2. Set the hierarchy with TwoUX, not with new styles
19
+ - One h1, in PageHeader. Section headings from the heading scale. Hierarchy comes from size, weight and position, not colour.
20
+ - Group by proximity first: 4 to 8px inside a group, 16px or more between groups, the same gap between items of the same kind, more space above a heading than below it. Spacing comes from components and their props, not typed values.
21
+ - Separate with TwoUX's three elevations (flat, card, float) and the grey fill (`bg-surface-2`) only for quiet supporting groups. Tint only when it means something (selection, do, don't, status).
22
+ - One left edge per column: labels, headings, table text and buttons line up. Numbers in columns use tabular figures.
23
+ - Reading text (descriptions, assistant answers) stays near 80 characters wide; tables and dashboards use the full width.
24
+
25
+ ## 3. Refuse the lazy defaults
26
+ These look finished but make a screen worse. If one seems needed, the job usually calls for a different component.
27
+ - Cards as the page's structure, or a grid of same-size cards with an icon, heading and text. Use a table, a list or sections. Never put a card inside a card.
28
+ - A small label or kicker above a heading, and section numbers (01, 02) unless the order itself matters.
29
+ - A row of big numbers opening every page. Stat cards belong only where the numbers are the point, with a comparison (`stat-compare.md`).
30
+ - A modal for something that needs neither interruption nor protected focus.
31
+ - Coloured side borders on cards, rows or callouts; status belongs in a Badge or Banner.
32
+ - Gradients, glass, glows, gradient text, decorative illustrations, emoji or Unicode glyphs as icons, monospace used for looks rather than for IDs, code and keys.
33
+ - Motion that decorates. Use only TwoUX's helpers (Swap, Count, AnimateHeight…) where something changed.
34
+ - Sparklines, rings or charts used as filler where a number or a word would do.
35
+
36
+ ## 4. Render and check
37
+ Build with `/twoux-build`, then look at the result. If you can run the app and a browser (a dev server plus Playwright, the browser tool or screenshots), capture the screen at 1280, 1024, 768 and 320px wide, in light and dark. Check the render, not the intention:
38
+ - **Spacing and alignment:** groups read as groups; same-kind gaps are equal; edges line up; nothing nudged with outside margins.
39
+ - **Hierarchy:** with the text blurred, the first thing the eye lands on is the most important thing; one primary button.
40
+ - **Contrast:** text 4.5:1, control edges and meaningful icons 3:1, in both themes.
41
+ - **Real content:** long names, empty values, zero, one and many, large numbers, long translations. Nothing truncates without a tooltip or wraps badly.
42
+ - **States:** loading (skeleton), empty, no results, error with Try again, disabled with a reason, read-only. Each in place, in its own region.
43
+ - **Keyboard:** visible focus on every control, sensible Tab order, shortcuts shown, focus returns after panels and dialogs close.
44
+ - **Reflow:** at 320px nothing scrolls sideways except tables, code and charts inside their own box; navigation collapses behind its button.
45
+ - **Copy:** each message fits its moment in `voice-and-tone.md`.
46
+
47
+ If you can't render, say so plainly, check the source against the same list, and name what still needs a look in a browser.
48
+
49
+ ## 5. Fix and report
50
+ - Fix with layout classes, component props and composition in app code. Never restyle a component or edit `@twoux/ui`; if the screen needs something TwoUX lacks, use the closest component and tell the person what is missing.
51
+ - Run `npx twoux check` and fix every error and `tone` warning.
52
+ - Report: the job and reading order you designed for, what you removed or refused and why, which widths and themes you rendered, and anything you couldn't verify.
53
+
54
+ Craft checks in steps 3 and 4 are adapted from Impeccable's craft floor (github.com/pbakaus/impeccable, Apache 2.0), rewritten for TwoUX's fixed tokens and components.
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: twoux-write
3
+ description: Write, rewrite or review interface copy the TwoUX way: labels, buttons, errors, empty states, toasts, confirmations, onboarding, help text, assistant text and translation files. Names the moment, picks the tone for it, rewrites each string and shows before and after. Use whenever someone asks to write, fix, review or tidy UI text, error messages or strings in a project that uses @twoux/ui or follows its principles, even if they don't mention TwoUX. Overrides general UX writing skills in these projects.
4
+ ---
5
+
6
+ # TwoUX write
7
+
8
+ The authority is `node_modules/@twoux/ui/agent/docs-md/writing.md` and `voice-and-tone.md` (inside the TwoUX repo: `docs-md/`). Read both first. Where a general UX writing skill or habit disagrees with them (saying "we", celebrating success, adding warmth with exclamation marks), TwoUX wins.
9
+
10
+ ## 1. Collect the strings
11
+ List every string in scope with where it appears (file:line or component) and what the person is doing at that moment. For translation files, take every language together; never change one language alone.
12
+
13
+ ## 2. Name the moment, then the tone
14
+ For each string, write the moment in a few words, then its tone from `voice-and-tone.md`:
15
+ - **Inform**, the default: errors, warnings, statuses, caveats. What happened, what it affects, what to do next.
16
+ - **Empower**, at a decision: the consequence and the choices, said plainly. Say before an action if it can't be undone.
17
+ - **Encourage**, when work is stuck or partly done: how much is done, what is left, one way forward.
18
+ - **Motivate**, only when someone is starting: what it lets them do, as an outcome.
19
+ - **Satisfy**, for routine work: past tense, a count, Undo. Nothing more.
20
+
21
+ If the person asks for a different tone ("make it fun", "friendly and welcoming"), keep the TwoUX voice and say how you read the request: friendly means plain and useful, not cheerful.
22
+
23
+ ## 3. Rewrite
24
+ - Voice everywhere: precise, calm, candid, respectful of expertise. UK English, sentence case, verb-first buttons that name the action.
25
+ - Address the person as "you". The product never says "we" or "I"; state the event ("Listing not saved"). The assistant says "I" only for what it did.
26
+ - No apology, please, exclamation mark, joke, emoji or celebration. Cut just, simply, easy, seamless, smart, magic, AI-powered, successfully.
27
+ - Same thing, same word: reuse the product's terms. Don't rename a product term without the person's approval.
28
+ - Keep numbers and names as variables so translators can reorder them; write whole sentences, not joined fragments.
29
+ - Dates and times come from the Timestamp component (in an app not built with TwoUX, its own date component), never hand-written formats.
30
+
31
+ ## 4. Show, then apply
32
+ Show a table: where, moment and tone, before, after, and why (one short reason). Apply only what the person approves, unless they asked you to go ahead. Then run `npx twoux check` (`--principles` in an app not built with TwoUX) and fix every `tone` warning.
package/bin/check.mjs ADDED
@@ -0,0 +1,123 @@
1
+ // twoux check: catches the drift TwoUX exists to stop, in app code and in TwoUX itself.
2
+ // twoux check [--base <git ref>] [--app-only] [--principles] [--check-links] [paths...] (run from the project root; default path: src)
3
+ // --principles: for an app not built with TwoUX; runs only the checks that hold outside it (copy tone).
4
+ // Errors fail the run (exit 1). Warnings are printed for review.
5
+ import { execSync } from "node:child_process";
6
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
7
+ import { join, relative } from "node:path";
8
+
9
+ const pkg = new URL("..", import.meta.url).pathname; // the installed @twoux/ui package
10
+ const root = process.cwd(); // the project being checked
11
+ const inTwoUXRepo = existsSync(join(root, "packages/ui/bin/check.mjs"));
12
+ const args = process.argv.slice(2);
13
+ const baseAt = args.indexOf("--base");
14
+ const base = baseAt >= 0 ? args.splice(baseAt, 2)[1] : "HEAD";
15
+ const appOnly = args.includes("--app-only");
16
+ const checkLinks = args.includes("--check-links"); // open every proposal link (needs network)
17
+ if (checkLinks) args.splice(args.indexOf("--check-links"), 1);
18
+ if (appOnly) args.splice(args.indexOf("--app-only"), 1); // skip the "TwoUX was edited" check (maintainers)
19
+ const principles = args.includes("--principles"); // app not built with TwoUX: skip token, import and restyle checks
20
+ if (principles) args.splice(args.indexOf("--principles"), 1);
21
+ const PRINCIPLE_RULES = new Set(["tone"]);
22
+ const roots = args.length ? args : [existsSync(join(root, "apps/playground/src")) ? "apps/playground/src" : "src"];
23
+
24
+ // Names exported by @twoux/ui: an app file that defines one of these is a local copy.
25
+ const index = readFileSync(join(pkg, "src/index.ts"), "utf8");
26
+ const exported = new Set();
27
+ for (const m of index.matchAll(/from "\.\/components\/([\w-]+)"/g)) {
28
+ const src = readFileSync(join(pkg, `src/components/${m[1]}.tsx`), "utf8");
29
+ for (const e of src.matchAll(/export\s+(?:function|const)\s+([A-Z]\w+)/g)) exported.add(e[1]);
30
+ for (const e of src.matchAll(/export\s*\{([^}]+)\}/g)) for (const n of e[1].split(",")) { const name = n.trim().split(/\s+as\s+/).pop(); if (/^[A-Z]/.test(name)) exported.add(name); }
31
+ }
32
+
33
+
34
+ const RULES = [
35
+ { level: "error", id: "raw-colour", re: /#[0-9a-fA-F]{3,8}\b(?![\w-])|\b(?:rgba?|hsla?|oklch|oklab)\(/g, msg: "Raw colour. Use a role token (bg-surface, text-ink-2, border-line…) or change the brand in the theme file (twoux.theme.json)." },
36
+ { level: "error", id: "arbitrary-value", re: /(?<![\w-])(?!(?:[\w-]*:)*(?:has|data|aria|group-[\w-]+|peer-[\w-]+|supports|not|in|nth|grid-cols|grid-rows|col-span|row-span|grid-areas)-\[)(?:[\w-]+:)*[\w-]+-\[(?!--)[^\]\s]+\]/g, msg: "Arbitrary Tailwind value. Use a token step (p-3, rounded-sm, text-base, h-control…). Grid templates and variant selectors are allowed." },
37
+ { level: "error", id: "inline-style", re: /\bstyle=\{\{(?!\s*["']--[\w-]+["']\s*:)/g, msg: "Inline style. Use TwoUX utilities. Data-driven values (a bar width) may pass one CSS variable: style={{ \"--w\": \"30%\" }} with w-(--w)." },
38
+ { level: "error", id: "bypass-import", re: /from\s+["'](?:radix-ui|@radix-ui\/[\w-]+|cmdk|sonner|vaul|@\/components\/ui\/[\w-]+|[./]+packages\/ui\/src\/(?:shadcn|components)\/[\w-]+)["']/g, msg: "Imports a primitive directly. Import from @twoux/ui, where the tailored version lives." },
39
+ { level: "warn", id: "palette-step", re: /\b(?:bg|text|border|ring|fill|stroke|from|to|via)-(?:neutral|indigo|blue|teal|green|amber|orange|red|magenta|brand)-\d{2,3}\b/g, msg: "Palette step in product code. Use a role (primary, ok, warn, bad, ink, line…); steps are for charts and reviewed illustrations." },
40
+ { level: "warn", id: "tone", re: /["'`>][^"'`<>{}]*?\b(?:Oops|Whoops|Uh-oh|Woohoo|Yay|Hooray|Awesome|[Ss]uccessfully|AI-powered|Sorry|[Pp]lease|We)\b/g, msg: "Copy off the TwoUX voice. Say what happened and what to do next, with no apology, please, \"we\", hype or celebration. See Voice and tone." },
41
+ { level: "warn", id: "raw-spacing", re: /(?<![\w-])(?:[\w-]+:)*(?:p|px|py|pt|pb|pl|pr|ps|pe|m|mx|my|mt|mb|ml|mr|gap|gap-x|gap-y|space-x|space-y)-(?!0(?![.\d]))\d+(?:\.5)?(?![\w.-])/g, msg: "Numeric spacing in app code. Use a role: inside a control gap-hair (2px), gap-tight (4px), gap-control (6px), gap-inline (8px); between parts gap-group; inside a card, pane or panel p-region; page sides px-page, top pt-page-top. Region roles tighten by themselves in a workspace (AppShell frame=\"flush\")." },
42
+ { level: "warn", id: "raw-control", re: /<(button|input|select|textarea)\b(?![^>]*type=["'](?:hidden|file)["'])/g, msg: "Raw control. Use Button, Input/TextField, Checkbox, Switch… from @twoux/ui." },
43
+ ];
44
+
45
+ const files = [];
46
+ const walk = (p) => {
47
+ if (!existsSync(p)) return;
48
+ if (statSync(p).isDirectory()) { for (const f of readdirSync(p)) if (f !== "node_modules" && !f.startsWith(".")) walk(join(p, f)); }
49
+ else if (/\.(tsx?|jsx?|css)$/.test(p)) files.push(p);
50
+ };
51
+ for (const r of roots) walk(join(root, r));
52
+
53
+ const findings = [];
54
+ for (const f of files) {
55
+ const text = readFileSync(f, "utf8");
56
+ // Theme CSS written by `twoux theme` holds the palette on purpose.
57
+ if (/^\/\* Generated by twoux theme/.test(text)) continue;
58
+ const lines = text.split("\n");
59
+ const rel = relative(root, f);
60
+ // File-level opt-out for one rule, with a reason: // twoux-check-disable raw-colour: code sample text
61
+ const disabled = new Set([...text.matchAll(/twoux-check-disable\s+([\w-]+)/g)].map((m) => m[1]));
62
+ lines.forEach((line, i) => {
63
+ if (/twoux-check-ignore/.test(line)) return;
64
+ for (const r of RULES) if (!disabled.has(r.id) && (!principles || PRINCIPLE_RULES.has(r.id))) for (const m of line.matchAll(r.re)) findings.push({ level: r.level, id: r.id, where: `${rel}:${i + 1}`, hit: m[0].slice(0, 40), msg: r.msg });
65
+ });
66
+ if (!principles) for (const m of text.matchAll(/(?:export\s+)?(?:function|const)\s+([A-Z]\w+)\s*[=(]/g)) {
67
+ if (exported.has(m[1])) findings.push({ level: "error", id: "local-copy", where: `${rel}:${text.slice(0, m.index).split("\n").length}`, hit: m[1], msg: `Defines ${m[1]}, which @twoux/ui already exports. Import it instead of rebuilding it.` });
68
+ }
69
+
70
+ }
71
+
72
+ // Restyling a TwoUX control on one page: padding, height, radius, type size or weight passed through className.
73
+ // Layout classes (margin, width, flex, grid, order) are fine; the control's own look is not.
74
+ const CONTROL = /(Button|Item|Input|Textarea|Badge|Trigger|Toggle|Checkbox|Switch|Kbd|Segment|Radio|Tab|Field)$/;
75
+ const RESTYLE = /(?:^|\s)(?:[\w-]+:)*(?:p[xytrbl]?-\d|h-\d|min-h-\d|size-\d|rounded(?:-[a-z]+)?\b|text-(?:xs|sm|base|md|lg|xl|2xl)\b|font-(?:normal|medium|semibold|bold)\b|leading-|tracking-)/;
76
+ for (const f of files) {
77
+ if (principles || !/\.(tsx|jsx)$/.test(f)) continue;
78
+ const text = readFileSync(f, "utf8");
79
+ if (/twoux-check-disable\s+local-restyle/.test(text)) continue;
80
+ for (const m of text.matchAll(/<([A-Z]\w*)\b[^<>]*?className=(?:"([^"]*)"|\{`([^`]*)`\}|\{"([^"]*)"\})/g)) {
81
+ const [name, cls] = [m[1], m[2] ?? m[3] ?? m[4] ?? ""];
82
+ if (!exported.has(name) || !CONTROL.test(name)) continue;
83
+ const hit = cls.split(/\s+/).find((c) => RESTYLE.test(` ${c}`));
84
+ if (hit) findings.push({ level: "error", id: "local-restyle", where: `${relative(root, f)}:${text.slice(0, m.index).split("\n").length}`, hit: `${name} ${hit}`, msg: `Restyles ${name} on one page. Use its variant and size props; to change it everywhere, change the theme file (twoux.theme.json).` });
85
+ }
86
+ }
87
+
88
+ // Proposals must cite at least two linked sources.
89
+ const propDir = join(root, "proposals");
90
+ if (existsSync(propDir)) for (const p of readdirSync(propDir)) {
91
+ if (!p.endsWith(".md") || p === "TEMPLATE.md") continue;
92
+ const text = readFileSync(join(propDir, p), "utf8");
93
+ const sources = (text.split(/^## Sources/m)[1] ?? "").split(/^## /m)[0];
94
+ const links = sources.match(/https?:\/\/[^\s)>\]]+/g) ?? [];
95
+ if (checkLinks) for (const url of links) {
96
+ try {
97
+ const res = await fetch(url, { redirect: "follow", signal: AbortSignal.timeout(10000), headers: { "user-agent": "twoux-check" } });
98
+ if (res.status >= 400) findings.push({ level: "error", id: "dead-link", where: `proposals/${p}`, hit: `${res.status} ${url}`, msg: "This source link doesn't open. Replace it with a working page." });
99
+ } catch (e) { findings.push({ level: "warn", id: "link-unreachable", where: `proposals/${p}`, hit: url, msg: `Couldn't reach this link (${e.name}). Check it by hand.` }); }
100
+ }
101
+ if (links.length < 2) findings.push({ level: "error", id: "proposal-sources", where: `proposals/${p}`, hit: `${links.length} links`, msg: "A proposal needs at least two linked sources under ## Sources (design systems, WAI-ARIA APG, WCAG, usability research). Check each link opens." });
102
+ }
103
+
104
+ // Changes to TwoUX itself. theme.json (and the theme.css it generates) is the one sanctioned way to change the look.
105
+ let changed = [];
106
+ if (!appOnly && inTwoUXRepo) try {
107
+ const out = execSync(`git -C "${root}" diff --name-only ${base} -- packages/ui && git -C "${root}" ls-files --others --exclude-standard -- packages/ui`, { encoding: "utf8" });
108
+ changed = out.split("\n").filter(Boolean).filter((p) => !/packages\/ui\/(theme\.json|src\/styles\/theme\.css)$/.test(p));
109
+ } catch { /* not a git checkout */ }
110
+ for (const p of changed) findings.push({ level: "error", id: "edited-twoux", where: p, hit: "", msg: `TwoUX itself was changed since ${base}. Don't edit @twoux/ui from app work: use props or composition instead (see AGENTS.md).` });
111
+
112
+ const errors = findings.filter((f) => f.level === "error");
113
+ const warns = findings.filter((f) => f.level === "warn");
114
+ const show = (list, label) => {
115
+ if (!list.length) return;
116
+ console.log(`\n${label} (${list.length})`);
117
+ for (const f of list) console.log(` ${f.where} ${f.id}${f.hit ? ` ${f.hit}` : ""}\n ${f.msg}`);
118
+ };
119
+ console.log(`twoux check: ${files.length} files in ${roots.join(", ")}${inTwoUXRepo && !appOnly ? `; TwoUX changes since ${base}: ${changed.length}` : ""}`);
120
+ show(errors, "Errors");
121
+ show(warns, "Warnings");
122
+ if (!findings.length) console.log("No problems found.");
123
+ process.exit(errors.length ? 1 : 0);
package/bin/docs.mjs ADDED
@@ -0,0 +1,24 @@
1
+ // twoux docs [id] [--kind component|pattern|foundation] list every page, or print one
2
+ // twoux find "<job>" which component or pattern fits a job
3
+ import { findJob, formatList, formatMatches, getDoc, rules } from "./knowledge.mjs";
4
+
5
+ const [cmd, ...rest] = process.argv.slice(2);
6
+ const kindAt = rest.indexOf("--kind");
7
+ const kind = kindAt >= 0 ? rest.splice(kindAt, 2)[1] : undefined;
8
+ const arg = rest.join(" ").trim();
9
+
10
+ if (cmd === "find") {
11
+ if (!arg) { console.log('Usage: twoux find "<job>" for example: twoux find "confirm a permanent delete"'); process.exit(1); }
12
+ console.log(formatMatches(findJob(arg)));
13
+ } else if (!arg) {
14
+ console.log(`${formatList(kind)}\n\nPrint a page: twoux docs <id>. Every rule: twoux docs rules.`);
15
+ } else if (arg === "rules" || arg === "agents") {
16
+ console.log(rules());
17
+ } else {
18
+ const doc = getDoc(arg);
19
+ if (!doc) {
20
+ console.error(`No page called "${arg}". Closest jobs:\n\n${formatMatches(findJob(arg, 3))}`);
21
+ process.exit(1);
22
+ }
23
+ console.log(doc.text);
24
+ }
package/bin/guard.mjs ADDED
@@ -0,0 +1,27 @@
1
+ // Claude Code PreToolUse hook: stops agents editing TwoUX itself during app work.
2
+ // Allowed: the theme file (twoux.theme.json in an app, packages/ui/theme.json in the TwoUX repo). Maintainers: TWOUX_MAINTAINER=1.
3
+ let raw = "";
4
+ process.stdin.on("data", (d) => (raw += d));
5
+ process.stdin.on("end", () => {
6
+ if (process.env.TWOUX_MAINTAINER === "1") process.exit(0);
7
+ let input = {};
8
+ try { input = JSON.parse(raw); } catch { process.exit(0); }
9
+ const tool = input.tool_name ?? "";
10
+ const ti = input.tool_input ?? {};
11
+ const PROTECTED = /(^|\/)(packages\/ui\/(src|registry)\/|node_modules\/@twoux\/)/;
12
+ const ALLOWED = /packages\/ui\/theme\.json$/;
13
+ let target = "";
14
+ if (/^(Edit|Write|MultiEdit|NotebookEdit)$/.test(tool)) target = ti.file_path ?? ti.notebook_path ?? "";
15
+ else if (tool === "Bash") {
16
+ const cmd = ti.command ?? "";
17
+ if (/(sed\s+-i|perl\s+-[a-z]*i|>\s*\S|\btee\b|\bmv\b|\bcp\b|\brm\b|\btruncate\b|writeFile)/.test(cmd)) target = (cmd.match(/\S*(packages\/ui\/(src|registry)\/|node_modules\/@twoux\/)\S*/) ?? [""])[0];
18
+ }
19
+ if (!target || ALLOWED.test(target) || !PROTECTED.test(target)) process.exit(0);
20
+ process.stderr.write(
21
+ `Blocked: ${target} is part of TwoUX (@twoux/ui), which app work must not change.\n` +
22
+ "- To change colours, corners or font for the whole product: edit twoux.theme.json (in the TwoUX repo: packages/ui/theme.json) and run twoux theme.\n" +
23
+ "- To change a component's behaviour: use its props or compose it in app code.\n" +
24
+ "- If TwoUX is missing something: use the closest component and tell the person what is missing.\n",
25
+ );
26
+ process.exit(2);
27
+ });