@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
@@ -0,0 +1,83 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { type VariantProps } from "class-variance-authority"
5
+ import { cn } from "cn"
6
+ import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui"
7
+
8
+ import { toggleVariants } from "@/registry/new-york-v4/ui/toggle"
9
+
10
+ const ToggleGroupContext = React.createContext<
11
+ VariantProps<typeof toggleVariants> & {
12
+ spacing?: number
13
+ }
14
+ >({
15
+ size: "default",
16
+ variant: "default",
17
+ spacing: 0,
18
+ })
19
+
20
+ function ToggleGroup({
21
+ className,
22
+ variant,
23
+ size,
24
+ spacing = 0,
25
+ children,
26
+ ...props
27
+ }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
28
+ VariantProps<typeof toggleVariants> & {
29
+ spacing?: number
30
+ }) {
31
+ return (
32
+ <ToggleGroupPrimitive.Root
33
+ data-slot="toggle-group"
34
+ data-variant={variant}
35
+ data-size={size}
36
+ data-spacing={spacing}
37
+ style={{ "--gap": spacing } as React.CSSProperties}
38
+ className={cn(
39
+ "group/toggle-group flex w-fit items-center gap-[--spacing(var(--gap))] rounded-md data-[spacing=default]:data-[variant=outline]:shadow-xs",
40
+ className
41
+ )}
42
+ {...props}
43
+ >
44
+ <ToggleGroupContext.Provider value={{ variant, size, spacing }}>
45
+ {children}
46
+ </ToggleGroupContext.Provider>
47
+ </ToggleGroupPrimitive.Root>
48
+ )
49
+ }
50
+
51
+ function ToggleGroupItem({
52
+ className,
53
+ children,
54
+ variant,
55
+ size,
56
+ ...props
57
+ }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
58
+ VariantProps<typeof toggleVariants>) {
59
+ const context = React.useContext(ToggleGroupContext)
60
+
61
+ return (
62
+ <ToggleGroupPrimitive.Item
63
+ data-slot="toggle-group-item"
64
+ data-variant={context.variant || variant}
65
+ data-size={context.size || size}
66
+ data-spacing={context.spacing}
67
+ className={cn(
68
+ toggleVariants({
69
+ variant: context.variant || variant,
70
+ size: context.size || size,
71
+ }),
72
+ "w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10",
73
+ "data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l",
74
+ className
75
+ )}
76
+ {...props}
77
+ >
78
+ {children}
79
+ </ToggleGroupPrimitive.Item>
80
+ )
81
+ }
82
+
83
+ export { ToggleGroup, ToggleGroupItem }
@@ -0,0 +1,46 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cva, type VariantProps } from "class-variance-authority"
5
+ import { cn } from "cn"
6
+ import { Toggle as TogglePrimitive } from "radix-ui"
7
+
8
+ const toggleVariants = cva(
9
+ "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "bg-transparent",
14
+ outline:
15
+ "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
16
+ },
17
+ size: {
18
+ default: "h-9 min-w-9 px-2",
19
+ sm: "h-8 min-w-8 px-1.5",
20
+ lg: "h-10 min-w-10 px-2.5",
21
+ },
22
+ },
23
+ defaultVariants: {
24
+ variant: "default",
25
+ size: "default",
26
+ },
27
+ }
28
+ )
29
+
30
+ function Toggle({
31
+ className,
32
+ variant,
33
+ size,
34
+ ...props
35
+ }: React.ComponentProps<typeof TogglePrimitive.Root> &
36
+ VariantProps<typeof toggleVariants>) {
37
+ return (
38
+ <TogglePrimitive.Root
39
+ data-slot="toggle"
40
+ className={cn(toggleVariants({ variant, size, className }))}
41
+ {...props}
42
+ />
43
+ )
44
+ }
45
+
46
+ export { Toggle, toggleVariants }
@@ -0,0 +1,56 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { cn } from "cn"
5
+ import { Tooltip as TooltipPrimitive } from "radix-ui"
6
+
7
+ function TooltipProvider({
8
+ delayDuration = 0,
9
+ ...props
10
+ }: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
11
+ return (
12
+ <TooltipPrimitive.Provider
13
+ data-slot="tooltip-provider"
14
+ delayDuration={delayDuration}
15
+ {...props}
16
+ />
17
+ )
18
+ }
19
+
20
+ function Tooltip({
21
+ ...props
22
+ }: React.ComponentProps<typeof TooltipPrimitive.Root>) {
23
+ return <TooltipPrimitive.Root data-slot="tooltip" {...props} />
24
+ }
25
+
26
+ function TooltipTrigger({
27
+ ...props
28
+ }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
29
+ return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />
30
+ }
31
+
32
+ function TooltipContent({
33
+ className,
34
+ sideOffset = 0,
35
+ children,
36
+ ...props
37
+ }: React.ComponentProps<typeof TooltipPrimitive.Content>) {
38
+ return (
39
+ <TooltipPrimitive.Portal>
40
+ <TooltipPrimitive.Content
41
+ data-slot="tooltip-content"
42
+ sideOffset={sideOffset}
43
+ className={cn(
44
+ "z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
45
+ className
46
+ )}
47
+ {...props}
48
+ >
49
+ {children}
50
+ <TooltipPrimitive.Arrow className="z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground" />
51
+ </TooltipPrimitive.Content>
52
+ </TooltipPrimitive.Portal>
53
+ )
54
+ }
55
+
56
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
@@ -0,0 +1,127 @@
1
+ /* Generated by scripts/palette.mjs. Do not edit: change the anchors there and re-run. */
2
+ @theme static {
3
+ /* Remove Tailwind's default palette: only TwoUX colours exist, so bg-slate-500 and friends fail to build. */
4
+ --color-*: initial;
5
+ --color-white: #FFFFFF;
6
+ --color-black: #000000;
7
+
8
+ /* neutral: Surfaces, lines, text */
9
+ --color-neutral-25: #FAFAFC; /* anchor */
10
+ --color-neutral-50: #F5F5F8; /* anchor */
11
+ --color-neutral-75: #F0F0F4; /* anchor */
12
+ --color-neutral-100: #ECECF2; /* anchor */
13
+ --color-neutral-150: #E6E6EC; /* anchor */
14
+ --color-neutral-200: #D6D6DF; /* anchor */
15
+ --color-neutral-300: #B4B4C1;
16
+ --color-neutral-400: #9D9DAB;
17
+ --color-neutral-500: #868695; /* anchor */
18
+ --color-neutral-600: #656574; /* anchor */
19
+ --color-neutral-700: #474756; /* anchor */
20
+ --color-neutral-800: #33333F;
21
+ --color-neutral-900: #23232D;
22
+ --color-neutral-950: #17171F; /* anchor */
23
+
24
+ /* indigo: Accent. 600 = primary action, 700 = accent text, 50 = selection tint */
25
+ --color-indigo-50: #EEEDFD; /* anchor */
26
+ --color-indigo-100: #E8ECFF;
27
+ --color-indigo-200: #D2D8FF;
28
+ --color-indigo-300: #B2BBFF;
29
+ --color-indigo-400: #8C96FF;
30
+ --color-indigo-500: #6E70FF;
31
+ --color-indigo-600: #5753E0; /* anchor */
32
+ --color-indigo-700: #4340C4; /* anchor */
33
+ --color-indigo-800: #3A33A4;
34
+ --color-indigo-900: #2A257E;
35
+ --color-indigo-950: #1A1655;
36
+
37
+ /* blue: Data visualisation (series 7) */
38
+ --color-blue-50: #F2F7FF;
39
+ --color-blue-100: #E1EEFF;
40
+ --color-blue-200: #C4DDFF;
41
+ --color-blue-300: #97C4FF;
42
+ --color-blue-400: #5BA3FF;
43
+ --color-blue-500: #3385EA;
44
+ --color-blue-600: #2A78D6; /* anchor */
45
+ --color-blue-700: #045AB1;
46
+ --color-blue-800: #004790;
47
+ --color-blue-900: #00356F;
48
+ --color-blue-950: #00224A;
49
+
50
+ /* teal: Data visualisation (series 3) */
51
+ --color-teal-50: #EDFAF7;
52
+ --color-teal-100: #DBF3EE;
53
+ --color-teal-200: #B9E6DD;
54
+ --color-teal-300: #89D1C5;
55
+ --color-teal-400: #52B5A6;
56
+ --color-teal-500: #199B8B;
57
+ --color-teal-600: #00897B; /* anchor */
58
+ --color-teal-700: #006B60;
59
+ --color-teal-800: #00554C;
60
+ --color-teal-900: #004039;
61
+ --color-teal-950: #002A25;
62
+
63
+ /* green: Status: ok (700 generated for a smooth range, re-checked for contrast) */
64
+ --color-green-50: #E8F6EE; /* anchor */
65
+ --color-green-100: #DDF4E3;
66
+ --color-green-200: #BFE3CD; /* anchor */
67
+ --color-green-300: #93D2A5;
68
+ --color-green-400: #63B77E;
69
+ --color-green-500: #3A9C5F;
70
+ --color-green-600: #1C854A;
71
+ --color-green-700: #096F3A;
72
+ --color-green-800: #01582C;
73
+ --color-green-900: #014320;
74
+ --color-green-950: #012B13;
75
+
76
+ /* amber: Status: warn, in progress */
77
+ --color-amber-50: #FDF4E3; /* anchor */
78
+ --color-amber-100: #FAEAD5;
79
+ --color-amber-200: #F0D7A8; /* anchor */
80
+ --color-amber-300: #E4B97D;
81
+ --color-amber-400: #CD9644;
82
+ --color-amber-500: #B47801;
83
+ --color-amber-600: #A87000; /* anchor */
84
+ --color-amber-700: #965606; /* anchor */
85
+ --color-amber-800: #644100;
86
+ --color-amber-900: #4C3000;
87
+ --color-amber-950: #321E00;
88
+
89
+ /* orange: Data visualisation (series 2) */
90
+ --color-orange-50: #FFF4F0;
91
+ --color-orange-100: #FFE7DE;
92
+ --color-orange-200: #FFCEBD;
93
+ --color-orange-300: #FFA888;
94
+ --color-orange-400: #F4794A;
95
+ --color-orange-500: #E0602B; /* anchor */
96
+ --color-orange-600: #BC4200;
97
+ --color-orange-700: #9C3600;
98
+ --color-orange-800: #7E2900;
99
+ --color-orange-900: #601E00;
100
+ --color-orange-950: #401100;
101
+
102
+ /* red: Status: bad, destructive */
103
+ --color-red-50: #FCECED; /* anchor */
104
+ --color-red-100: #FFE6E4;
105
+ --color-red-200: #F1C3C6; /* anchor */
106
+ --color-red-300: #FFA5A1;
107
+ --color-red-400: #F9706F;
108
+ --color-red-500: #E1494E;
109
+ --color-red-600: #C2333B; /* anchor */
110
+ --color-red-700: #A81C2A;
111
+ --color-red-800: #88121F;
112
+ --color-red-900: #680B15;
113
+ --color-red-950: #46050B;
114
+
115
+ /* magenta: Data visualisation (series 5) */
116
+ --color-magenta-50: #FFF3F6;
117
+ --color-magenta-100: #FFE5EC;
118
+ --color-magenta-200: #FFCAD8;
119
+ --color-magenta-300: #FFA1BD;
120
+ --color-magenta-400: #EF719C;
121
+ --color-magenta-500: #D74D80;
122
+ --color-magenta-600: #CC4A7A; /* anchor */
123
+ --color-magenta-700: #9F2357;
124
+ --color-magenta-800: #811845;
125
+ --color-magenta-900: #631133;
126
+ --color-magenta-950: #420820;
127
+ }
@@ -0,0 +1,35 @@
1
+ /* Generated by twoux theme from packages/ui/theme.json (palette family "indigo"). Do not edit: change the theme file and run twoux theme. */
2
+ @theme static {
3
+ --color-brand-50: #EEEDFD;
4
+ --color-brand-100: #E8ECFF;
5
+ --color-brand-200: #D2D8FF;
6
+ --color-brand-300: #B2BBFF;
7
+ --color-brand-400: #8C96FF;
8
+ --color-brand-500: #6E70FF;
9
+ --color-brand-600: #5753E0;
10
+ --color-brand-700: #4340C4;
11
+ --color-brand-800: #3A33A4;
12
+ --color-brand-900: #2A257E;
13
+ --color-brand-950: #1A1655;
14
+
15
+ /* Primary roles, chosen by contrast */
16
+ --color-primary: var(--color-brand-600); /* 5.65:1 with white text */
17
+ --color-primary-hover: var(--color-brand-700);
18
+ --color-primary-soft: light-dark(var(--color-brand-50), color-mix(in oklab, var(--color-brand-500) 18%, #15151C)); /* selected rows, AI cell tint */
19
+ --color-primary-ink: light-dark(var(--color-brand-700), var(--color-brand-300)); /* accent text, 7.58:1 on white, 9.90:1 on dark */
20
+ --color-focus: light-dark(var(--color-primary), var(--color-brand-500)); /* focus ring: 3.91:1 on a dark hover fill */
21
+ --color-primary-foreground: var(--color-white);
22
+
23
+ /* Corners: inside a control, controls and cards, what floats */
24
+ --radius-xs: 4px;
25
+ --radius-sm: 6px;
26
+ --radius-md: 8px;
27
+ --radius-button: var(--radius-sm); /* buttons only; defaults to sm */
28
+
29
+ --font-sans: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
30
+
31
+ /* Motion: tempo scales every --duration-* token; character sets the pop */
32
+ --motion-tempo: 1;
33
+ --motion-pop-scale: 1.25;
34
+ --ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1); /* standard */
35
+ }
@@ -0,0 +1,236 @@
1
+ /*
2
+ * TwoUX tokens. The ONLY place raw values live.
3
+ * Components and apps use the Tailwind utilities these generate (bg-surface, text-ink-2, border-control, rounded-md, h-control...)
4
+ * or var(--color-*). Never a hex, px or arbitrary value elsewhere.
5
+ * Light and dark, light by default. Compact only. Each role is light-dark(light, dark); <html data-theme="dark"> or "system" switches.
6
+ * Contrast ratios are measured against --color-surface: #FFFFFF in light, #15151C in dark.
7
+ */
8
+ @import "tw-animate-css";
9
+ @import "@xyflow/react/dist/base.css" layer(base); /* Flow canvas structure only; TwoUX styles the steps, links and controls */
10
+ @import "./palette.css";
11
+ @import "./theme.css"; /* brand colour, radii, font: generated from packages/ui/theme.json */
12
+
13
+ /*
14
+ * Two layers:
15
+ * 1. Primitives (palette.css, generated): --color-indigo-600, --color-neutral-200 ... the ranges.
16
+ * 2. Roles (below): what a colour is FOR. Components use roles, never primitives,
17
+ * so a role can be re-pointed in one place and every screen follows.
18
+ * Primitives are for the docs, charts and rare one-off illustrations reviewed by design.
19
+ */
20
+ @theme static {
21
+ /* Surfaces */
22
+ --color-bg: light-dark(var(--color-neutral-50), #0E0E13); /* page and app shell */
23
+ --color-surface: light-dark(var(--color-white), #15151C); /* cards, tables, panels, popovers */
24
+ --color-surface-2: light-dark(var(--color-neutral-25), #1A1A22); /* table header, footers, quiet fills */
25
+ --color-hover: light-dark(var(--color-neutral-100), #252530); /* hover fill, skeleton base */
26
+ --color-active-row: color-mix(in oklab, var(--color-primary-soft) 55%, var(--color-surface)); /* the row being edited in a grid: you always see which record changes */
27
+ --color-selected: light-dark(var(--color-neutral-150), #2D2D39); /* hover on the app background (sidebar, top bar); selected row base */
28
+ --color-highlight: light-dark(#F2F4F8, #22222C); /* light slate: the item under the pointer or arrow keys in menus, the palette, ghost and outline buttons */
29
+
30
+ /* Lines */
31
+ --color-line: light-dark(var(--color-neutral-100), #25252F); /* dividers, table rows, card edges. Soft: never the only edge of a control */
32
+ --color-line-strong: light-dark(var(--color-neutral-150), #30303C); /* outlines that must hold on grey: secondary buttons, popovers, the canvas */
33
+ --color-input: light-dark(var(--color-neutral-200), #3A3A48); /* edge of text fields and selects. Light, with shadow-xs. Allowed because a visible label always identifies the field (WCAG 1.4.11 applies to the indicator that identifies a control) */
34
+ --color-input-hover: light-dark(var(--color-neutral-300), #4C4C5C);
35
+ --color-control: light-dark(var(--color-neutral-500), #7C7C8E); /* edge of checkboxes, radios, switches: nothing else marks them. 3.59:1 light, 4.44:1 dark (WCAG 1.4.11) */
36
+
37
+ /* Text */
38
+ --color-ink: light-dark(var(--color-neutral-950), #EDEDF3); /* primary text. 17.8:1 light, 15.6:1 dark */
39
+ --color-ink-2: light-dark(var(--color-neutral-700), #B9B9C6); /* secondary text, labels, column headers. 9.12:1 light, 9.36:1 dark */
40
+ --color-ink-3: light-dark(var(--color-neutral-600), #9191A1); /* placeholders, meta. 5.73:1 light, 5.86:1 dark */
41
+ --color-scrim: light-dark(rgb(23 23 31 / 0.2), rgb(0 0 0 / 0.6)); /* behind dialogs and sheets */
42
+
43
+ /* Accent: once per view for the main action, plus links, focus and selection */
44
+
45
+ /* shadcn/ui names, mapped to TwoUX roles. shadcn source works unchanged: bg-background, text-muted-foreground,
46
+ border-input, ring-ring, bg-accent (hover fill, shadcn's meaning) all resolve to TwoUX values. */
47
+ --color-background: var(--color-surface);
48
+ --color-foreground: var(--color-ink);
49
+ --color-card: var(--color-surface); --color-card-foreground: var(--color-ink);
50
+ --color-popover: light-dark(var(--color-surface), #1C1C25); --color-popover-foreground: var(--color-ink);
51
+ --color-secondary: var(--color-hover); --color-secondary-foreground: var(--color-ink);
52
+ --color-muted: var(--color-hover); --color-muted-foreground: var(--color-ink-3);
53
+ --color-accent: var(--color-highlight); --color-accent-foreground: var(--color-ink);
54
+ --color-destructive: var(--color-red-600); /* fill behind white text: 5.48:1 in both themes */
55
+ --color-destructive-edge: var(--color-red-400); /* invalid field edge: visible, not shouting. The message carries the error */
56
+ --color-border: var(--color-line);
57
+ --color-ring: var(--color-focus);
58
+ --color-sidebar: var(--color-bg);
59
+
60
+ /* Status: reserved for state. Never a chart series, never decoration */
61
+ /* Dark: text steps at 400 (6.5 to 7.4:1 on surface), fills mixed into the surface so they stay quiet */
62
+ --color-ok: light-dark(var(--color-green-700), var(--color-green-400)); --color-ok-bg: light-dark(var(--color-green-50), color-mix(in oklab, var(--color-green-500) 16%, #15151C)); --color-ok-line: light-dark(var(--color-green-200), color-mix(in oklab, var(--color-green-500) 40%, #15151C));
63
+ --color-warn: light-dark(var(--color-amber-700), var(--color-amber-400)); --color-warn-bg: light-dark(var(--color-amber-50), color-mix(in oklab, var(--color-amber-500) 16%, #15151C)); --color-warn-line: light-dark(var(--color-amber-200), color-mix(in oklab, var(--color-amber-500) 40%, #15151C));
64
+ --color-bad: light-dark(var(--color-red-600), var(--color-red-400)); --color-bad-bg: light-dark(var(--color-red-50), color-mix(in oklab, var(--color-red-500) 16%, #15151C)); --color-bad-line: light-dark(var(--color-red-200), color-mix(in oklab, var(--color-red-500) 40%, #15151C));
65
+ --color-neutral: light-dark(var(--color-neutral-700), #B9B9C6); --color-neutral-bg: light-dark(var(--color-neutral-75), #20202A); --color-neutral-line: light-dark(var(--color-neutral-150), #30303C);
66
+ --color-progress: light-dark(var(--color-amber-600), var(--color-amber-400)); /* in progress. 4.21:1 (was #D9A118 at 2.32:1, failed 1.4.11) */
67
+
68
+ /* Data visualisation: categorical, fixed order, never cycled. Validated per theme for lightness band, chroma,
69
+ colour-blind separation (worst adjacent ΔE 10.0 light, 9.7 dark) and >= 3:1 on the surface. Dark is its own selection
70
+ (steps 500), not a flip. c6 and c8 are tuned off-range to keep the separation; do not snap them to a step. */
71
+ --color-c1: light-dark(var(--color-indigo-600), var(--color-indigo-500)); --color-c2: var(--color-orange-500);
72
+ --color-c3: light-dark(var(--color-teal-600), var(--color-teal-500)); --color-c4: light-dark(var(--color-amber-600), var(--color-amber-500));
73
+ --color-c5: light-dark(var(--color-magenta-600), var(--color-magenta-500)); --color-c6: light-dark(#008300, #5AA62A);
74
+ --color-c7: light-dark(var(--color-blue-600), var(--color-blue-500)); --color-c8: light-dark(#D93F3E, var(--color-red-500));
75
+ /* Sequential and ordinal: one hue, more = more contrast with the surface. Light: light to dark. Dark: dark to light. */
76
+ --color-q1: light-dark(var(--color-indigo-400), var(--color-indigo-900)); --color-q2: light-dark(var(--color-indigo-500), var(--color-indigo-800));
77
+ --color-q3: light-dark(var(--color-indigo-600), var(--color-indigo-700)); --color-q4: light-dark(var(--color-indigo-800), var(--color-indigo-600));
78
+ --color-q5: light-dark(var(--color-indigo-950), var(--color-indigo-500));
79
+
80
+ /* Type: Geist for UI, Geist Mono for IDs, code and keycaps */
81
+ /* --font-sans comes from theme.css (packages/ui/theme.json) */
82
+ --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace;
83
+ --text-xs: 11px; --text-xs--line-height: 16px; /* keycaps, counts, chart ticks only */
84
+ --text-sm: 12px; --text-sm--line-height: 16px; /* meta, column headers, helper text */
85
+ --text-base: 13px; --text-base--line-height: 20px; /* body, table cells, buttons */
86
+ --text-md: 14px; --text-md--line-height: 20px;
87
+ --text-lg: 16px; --text-lg--line-height: 24px; /* section headings */
88
+ --text-xl: 20px; --text-xl--line-height: 28px; /* figures */
89
+ --text-2xl: 24px; --text-2xl--line-height: 32px; /* page titles */
90
+
91
+ /* Spacing: 4px grid. p-1 = 4px, p-2 = 8px, p-3 = 12px ... The numeric scale is for TwoUX's own components;
92
+ apps use the role utilities below (proposals/spacing-tokens.md). */
93
+ --spacing: 4px;
94
+ /* Fixed: never change, not even in a workspace. Used inside controls and small parts. */
95
+ --spacing-hair: 2px; /* icon to text nudges, keycap padding, badge inset */
96
+ --spacing-tight: 4px; /* inside a control; label to help text */
97
+ --spacing-control: 6px; /* icon to label inside buttons, menu items and badges (shadcn's value) */
98
+ --spacing-inline: 8px; /* between controls in a row; field label to input */
99
+
100
+ /* Sizes: compact density, one size set. Rows are worked out from the control they hold. */
101
+ --size-control-sm: 28px; /* small buttons, filter pills */
102
+ --size-control: 32px; /* default buttons and inputs */
103
+ --size-row: calc(var(--size-control) + 2 * var(--spacing-hair)); /* 36px: table and list rows */
104
+ --size-row-dense: var(--size-control-sm); /* 28px: size="dense", spreadsheet-like data */
105
+
106
+ /* Shape: radius by role, concentric (inner = outer - padding) */
107
+ /* --radius-xs / sm / md come from theme.css (packages/ui/theme.json) */
108
+ --radius-lg: 12px; /* marketing surfaces only */
109
+ --radius-xl: 16px; /* marketing surfaces only */
110
+
111
+ /* Elevation: always paired with a light border (border-line). The border gives the edge, the shadow gives the lift.
112
+ Flat = border only (tables, previews, dividers)
113
+ Card = border + shadow-card (cards, inputs, secondary buttons: things that sit on the page)
114
+ Float = border + shadow-pop (menus, popovers, dialogs, toasts: things above the page)
115
+ Dark: shadows barely show on a dark page, so floating layers also sit on a lighter surface (popover). */
116
+ --shadow-xs: 0 1px 2px light-dark(rgb(23 23 40 / 0.04), rgb(0 0 0 / 0.3));
117
+ --shadow-card: 0 1px 2px light-dark(rgb(23 23 40 / 0.04), rgb(0 0 0 / 0.3)), 0 1px 1px light-dark(rgb(23 23 40 / 0.02), rgb(0 0 0 / 0.2));
118
+ --shadow-raised: 0 2px 6px -1px light-dark(rgb(23 23 40 / 0.06), rgb(0 0 0 / 0.4)), 0 1px 2px light-dark(rgb(23 23 40 / 0.04), rgb(0 0 0 / 0.3));
119
+ --shadow-pop: 0 0 0 1px var(--color-line-strong), 0 8px 24px -6px light-dark(rgb(23 23 40 / 0.12), rgb(0 0 0 / 0.5)), 0 2px 6px -2px light-dark(rgb(23 23 40 / 0.06), rgb(0 0 0 / 0.4));
120
+
121
+ /* Motion: short, eased by role, never decorative. Everything stops under prefers-reduced-motion.
122
+ --motion-tempo, --motion-pop-scale and --ease-pop come from theme.json (motion.tempo, motion.character) via theme.css.
123
+ Tempo scales every duration below; loops (spinner, shimmer) and shadcn's overlay timing are not scaled. */
124
+
125
+ /* Easing by role. Arrivals and in-place changes decelerate, movement eases both ends, exits accelerate. */
126
+ --ease-standard: cubic-bezier(0.22, 1, 0.36, 1); /* state changes in place: swaps, numbers, heights, fills */
127
+ --ease-entrance: cubic-bezier(0.22, 1, 0.36, 1); /* something arriving: rise-in, fade-in, a new row of results */
128
+ --ease-move: cubic-bezier(0.4, 0, 0.2, 1); /* something moving between two places: panel push, sidebar width */
129
+ --ease-exit: cubic-bezier(0.4, 0, 1, 1); /* something leaving. Same at every character, never overshoots */
130
+ /* --ease-pop (theme.css): pops only, a count that changes. Never on layout. "crisp" removes the overshoot */
131
+ /* Earlier names, kept so existing code keeps working. Prefer the role names above. */
132
+ --ease-out: var(--ease-entrance);
133
+ --ease-in-out: var(--ease-move);
134
+ --ease-soft: var(--ease-standard);
135
+ --ease-spring: var(--ease-pop, cubic-bezier(0.34, 1.56, 0.64, 1));
136
+
137
+ /* Durations: one band per job, all scaled by tempo. Exits are shorter than entrances. */
138
+ --duration-fast: calc(120ms * var(--motion-tempo, 1)); /* hover, press, colour, small controls */
139
+ --duration-base: calc(180ms * var(--motion-tempo, 1)); /* tabs, menus, state swaps, small transforms */
140
+ --duration-move: calc(200ms * var(--motion-tempo, 1)); /* panels and layout that move: matches shadcn's sheet */
141
+ --duration-slow: calc(260ms * var(--motion-tempo, 1)); /* content swaps, height changes, progress fills */
142
+ --duration-long: calc(480ms * var(--motion-tempo, 1)); /* figures rolling to a new value. Never on something people trigger often */
143
+ --duration-exit: var(--duration-fast); /* anything leaving */
144
+
145
+ --animate-fade-in: twoux-fade-in var(--duration-base) var(--ease-entrance) both;
146
+ --animate-rise-in: twoux-rise-in var(--duration-slow) var(--ease-entrance) both;
147
+ --animate-pop-in: twoux-pop-in var(--duration-base) var(--ease-entrance) both;
148
+ --animate-fade-out: twoux-fade-out var(--duration-exit) var(--ease-exit) both;
149
+ --animate-shimmer: twoux-shimmer 1.4s linear infinite; /* loading skeleton. Loops are not scaled by tempo */
150
+ --animate-text-shimmer: twoux-text-shimmer 2s linear infinite; /* "Thinking", "Working…" */
151
+ --animate-swap-in-icon: twoux-swap-in-icon var(--duration-base) var(--ease-entrance) both;
152
+ --animate-swap-out-icon: twoux-swap-out-icon var(--duration-exit) var(--ease-exit) both;
153
+ --animate-swap-in-text: twoux-swap-in-text var(--duration-base) var(--ease-entrance) both;
154
+ --animate-swap-out-text: twoux-swap-out-text var(--duration-exit) var(--ease-exit) both;
155
+ --animate-count-pop: twoux-count-pop var(--duration-slow) var(--ease-spring);
156
+ --animate-word-in: twoux-word-in var(--duration-slow) var(--ease-entrance) both;
157
+
158
+ @keyframes twoux-fade-in { from { opacity: 0; } }
159
+ @keyframes twoux-rise-in { from { opacity: 0; transform: translateY(6px); } }
160
+ @keyframes twoux-pop-in { from { opacity: 0; transform: translateY(-4px) scale(0.98); } }
161
+ @keyframes twoux-fade-out { to { opacity: 0; } }
162
+ @keyframes twoux-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
163
+ @keyframes twoux-text-shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }
164
+ @keyframes twoux-swap-in-icon { from { opacity: 0; scale: 0.5; filter: blur(2px); } }
165
+ @keyframes twoux-swap-out-icon { to { opacity: 0; scale: 0.5; filter: blur(2px); } }
166
+ @keyframes twoux-swap-in-text { from { opacity: 0; translate: 0 4px; filter: blur(2px); } }
167
+ @keyframes twoux-swap-out-text { to { opacity: 0; translate: 0 -4px; filter: blur(2px); } }
168
+ @keyframes twoux-count-pop { 0% { scale: 1; } 40% { scale: var(--motion-pop-scale, 1.25); } 100% { scale: 1; } }
169
+ @keyframes twoux-word-in { from { opacity: 0; filter: blur(3px); } }
170
+ }
171
+
172
+ @layer base {
173
+ /* shadcn/ui expects a default border colour (from its globals.css); without it borders fall back to the text colour. */
174
+ *, ::after, ::before, ::backdrop, ::file-selector-button { border-color: var(--color-border); }
175
+ /* Light by default. <html data-theme="dark"> forces dark; data-theme="system" follows the OS. */
176
+ :root { color-scheme: light; }
177
+ :root[data-theme="dark"] { color-scheme: dark; }
178
+ :root[data-theme="system"] { color-scheme: light dark; }
179
+ body {
180
+ background: var(--color-bg);
181
+ color: var(--color-ink);
182
+ font-family: var(--font-sans);
183
+ font-size: var(--text-base);
184
+ line-height: var(--text-base--line-height);
185
+ -webkit-font-smoothing: antialiased;
186
+ }
187
+ :focus-visible {
188
+ outline: 2px solid var(--color-focus);
189
+ outline-offset: 1px;
190
+ }
191
+ @media (prefers-reduced-motion: reduce) {
192
+ *, *::before, *::after { transition-duration: 0ms !important; animation-duration: 0ms !important; }
193
+ }
194
+ }
195
+
196
+ /* Region spacing: set per layout. AppShell frame="flush" marks its canvas data-density="workspace", which takes out
197
+ gaps and frames between regions; nothing inside a control changes. Utilities: gap-group, p-region, px-page,
198
+ pt-page-top, gap-region-gap. */
199
+ @theme inline {
200
+ --spacing-group: var(--sp-group);
201
+ --spacing-region: var(--sp-region);
202
+ --spacing-page: var(--sp-page);
203
+ --spacing-page-top: var(--sp-page-top);
204
+ --spacing-region-gap: var(--sp-region-gap);
205
+ }
206
+ @layer base {
207
+ :root { --sp-group: 16px; --sp-region: 16px; --sp-page: 24px; --sp-page-top: 20px; --sp-region-gap: 16px; }
208
+ [data-density="workspace"] { --sp-group: 12px; --sp-region: 8px; --sp-page: 12px; --sp-page-top: 8px; --sp-region-gap: 1px; }
209
+ /* Below 860px a workspace stacks and the page scrolls, so it takes the inset values back (page sides 16px). */
210
+ @media (max-width: 860px) {
211
+ :root, [data-density="workspace"] { --sp-group: 16px; --sp-region: 16px; --sp-page: 16px; --sp-page-top: 20px; --sp-region-gap: 16px; }
212
+ }
213
+ }
214
+
215
+ @utility h-control { height: var(--size-control); }
216
+ @utility h-control-sm { height: var(--size-control-sm); }
217
+ @utility h-row { height: var(--size-row); }
218
+ @utility h-row-dense { height: var(--size-row-dense); }
219
+ @utility tabular { font-variant-numeric: tabular-nums; }
220
+
221
+ /* Flow canvas (@xyflow/react): point its own variables at TwoUX roles. */
222
+ .react-flow {
223
+ --xy-background-color: var(--color-bg);
224
+ --xy-edge-stroke: var(--color-control);
225
+ --xy-edge-stroke-selected: var(--color-primary);
226
+ --xy-connectionline-stroke: var(--color-primary);
227
+ --xy-handle-background-color: var(--color-surface);
228
+ --xy-handle-border-color: var(--color-control);
229
+ --xy-minimap-background-color: var(--color-surface);
230
+ --xy-minimap-mask-background-color: color-mix(in oklab, var(--color-bg) 70%, transparent);
231
+ --xy-minimap-mask-stroke-color: var(--color-line-strong);
232
+ --xy-minimap-node-background-color: var(--color-line-strong);
233
+ --xy-attribution-background-color: transparent;
234
+ }
235
+ .react-flow__node:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; border-radius: var(--radius-sm); }
236
+ .react-flow__attribution a { color: var(--color-ink-3); }
package/theme.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "$comment": "The only place to change TwoUX's look. primary: a palette family (indigo, blue, teal, green...) or any #RRGGBB brand colour. radius: px for inside a control (xs), controls and cards (sm), floating layers (md); optional button: px or \"pill\". motion: tempo from 0.75 (quicker) to 1.25 (calmer) scales every duration; character \"standard\" or \"crisp\" (no overshoot on pops). Run pnpm theme after editing; it refuses colours that fail WCAG contrast and warns when the brand is close to a status colour.",
3
+ "primary": "indigo",
4
+ "radius": {
5
+ "xs": 4,
6
+ "sm": 6,
7
+ "md": 8
8
+ },
9
+ "font": "Geist",
10
+ "motion": {
11
+ "tempo": 1,
12
+ "character": "standard"
13
+ }
14
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.