@ternent/core 0.0.1

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 (313) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +17 -0
  3. package/.github/workflows/deploy-armour.yml +42 -0
  4. package/.github/workflows/deploy-identity.yml +42 -0
  5. package/.github/workflows/deploy-seal.yml +42 -0
  6. package/.github/workflows/deploy-ui.yml +42 -0
  7. package/.github/workflows/deploy-utils.yml +42 -0
  8. package/.github/workflows/release-create.yml +59 -0
  9. package/.github/workflows/release-publish.yml +54 -0
  10. package/.nvmrc +1 -0
  11. package/.ops/publish.mjs +31 -0
  12. package/package.json +16 -0
  13. package/packages/README.md +0 -0
  14. package/packages/armour/CHANGELOG.md +66 -0
  15. package/packages/armour/CLAUDE.md +8 -0
  16. package/packages/armour/README.md +103 -0
  17. package/packages/armour/SPEC.md +92 -0
  18. package/packages/armour/package.json +45 -0
  19. package/packages/armour/src/constants.ts +5 -0
  20. package/packages/armour/src/deps.d.ts +56 -0
  21. package/packages/armour/src/errors.ts +172 -0
  22. package/packages/armour/src/files.ts +73 -0
  23. package/packages/armour/src/identity.ts +72 -0
  24. package/packages/armour/src/index.ts +56 -0
  25. package/packages/armour/src/init.ts +10 -0
  26. package/packages/armour/src/passphrase.ts +33 -0
  27. package/packages/armour/src/recipients.ts +73 -0
  28. package/packages/armour/src/text.ts +68 -0
  29. package/packages/armour/src/types.ts +93 -0
  30. package/packages/armour/test/armour.test.ts +270 -0
  31. package/packages/armour/tsconfig.build.json +12 -0
  32. package/packages/armour/tsconfig.json +12 -0
  33. package/packages/armour/vite.config.ts +29 -0
  34. package/packages/concord/CHANGELOG.md +83 -0
  35. package/packages/concord/CLAUDE.md +9 -0
  36. package/packages/concord/README.md +146 -0
  37. package/packages/concord/SPEC.md +287 -0
  38. package/packages/concord/package.json +51 -0
  39. package/packages/concord/src/app.ts +717 -0
  40. package/packages/concord/src/errors.ts +9 -0
  41. package/packages/concord/src/index.ts +20 -0
  42. package/packages/concord/src/types.ts +127 -0
  43. package/packages/concord/test/concord.test.ts +978 -0
  44. package/packages/concord/tsconfig.json +12 -0
  45. package/packages/concord/vite.browser.config.ts +27 -0
  46. package/packages/concord/vite.config.ts +35 -0
  47. package/packages/concord/vite.config.ts.timestamp-1774262297922-ffd76e35ea668.mjs +83 -0
  48. package/packages/identity/CHANGELOG.md +47 -0
  49. package/packages/identity/README.md +236 -0
  50. package/packages/identity/package.json +41 -0
  51. package/packages/identity/src/index.ts +538 -0
  52. package/packages/identity/test/identity.test.ts +172 -0
  53. package/packages/identity/tsconfig.build.json +12 -0
  54. package/packages/identity/vite.config.ts +17 -0
  55. package/packages/ledger/CHANGELOG.md +69 -0
  56. package/packages/ledger/CLAUDE.md +9 -0
  57. package/packages/ledger/SPEC.md +304 -0
  58. package/packages/ledger/package.json +48 -0
  59. package/packages/ledger/src/index.ts +2 -0
  60. package/packages/ledger/src/ledger.ts +1286 -0
  61. package/packages/ledger/src/seal-cli.d.ts +25 -0
  62. package/packages/ledger/src/types.ts +294 -0
  63. package/packages/ledger/test/ledger.test.ts +838 -0
  64. package/packages/ledger/tsconfig.json +12 -0
  65. package/packages/ledger/vite.browser.config.ts +27 -0
  66. package/packages/ledger/vite.config.ts +39 -0
  67. package/packages/seal/CHANGELOG.md +137 -0
  68. package/packages/seal/CLAUDE.md +8 -0
  69. package/packages/seal/README.md +258 -0
  70. package/packages/seal/bin/seal +6 -0
  71. package/packages/seal/package.json +59 -0
  72. package/packages/seal/src/artifact.ts +380 -0
  73. package/packages/seal/src/cli.ts +372 -0
  74. package/packages/seal/src/commands/identity.ts +52 -0
  75. package/packages/seal/src/commands/manifest.ts +71 -0
  76. package/packages/seal/src/commands/publicKey.ts +7 -0
  77. package/packages/seal/src/commands/sign.ts +56 -0
  78. package/packages/seal/src/commands/verify.ts +54 -0
  79. package/packages/seal/src/crypto.ts +85 -0
  80. package/packages/seal/src/errors.ts +88 -0
  81. package/packages/seal/src/index.ts +5 -0
  82. package/packages/seal/src/manifest.ts +114 -0
  83. package/packages/seal/src/node.ts +18 -0
  84. package/packages/seal/src/proof.ts +344 -0
  85. package/packages/seal/test/artifact.test.ts +86 -0
  86. package/packages/seal/test/cli.test.ts +208 -0
  87. package/packages/seal/test/crypto.test.ts +21 -0
  88. package/packages/seal/test/manifest.test.ts +32 -0
  89. package/packages/seal/test/proof.test.ts +60 -0
  90. package/packages/seal/tsconfig.json +12 -0
  91. package/packages/seal/vite.config.ts +54 -0
  92. package/packages/ui/CHANGELOG.md +393 -0
  93. package/packages/ui/README.md +57 -0
  94. package/packages/ui/jsconfig.json +19 -0
  95. package/packages/ui/package.json +64 -0
  96. package/packages/ui/scripts/check-tokens.js +56 -0
  97. package/packages/ui/scripts/generate-theme-css.mjs +85 -0
  98. package/packages/ui/src/design-system/base.css +8 -0
  99. package/packages/ui/src/design-system/docs/ACCESSIBILITY_RULES.md +186 -0
  100. package/packages/ui/src/design-system/docs/AI_SYSTEM.md +281 -0
  101. package/packages/ui/src/design-system/docs/PATTERN_RULES.md +83 -0
  102. package/packages/ui/src/design-system/docs/PRIMITIVE_RULES.md +258 -0
  103. package/packages/ui/src/design-system/docs/TOKEN_RULES.md +235 -0
  104. package/packages/ui/src/design-system/docs/VISUAL_DIRECTION.md +68 -0
  105. package/packages/ui/src/design-system/foundation.js +420 -0
  106. package/packages/ui/src/design-system/tokens.css +140 -0
  107. package/packages/ui/src/design-system/tokens.js +327 -0
  108. package/packages/ui/src/design-system/utils.js +246 -0
  109. package/packages/ui/src/main.js +4 -0
  110. package/packages/ui/src/patterns/FeatureCard/FeatureCard.spec.md +24 -0
  111. package/packages/ui/src/patterns/FeatureCard/FeatureCard.types.ts +8 -0
  112. package/packages/ui/src/patterns/FeatureCard/FeatureCard.vue +175 -0
  113. package/packages/ui/src/patterns/FormField/FormField.spec.md +65 -0
  114. package/packages/ui/src/patterns/FormField/FormField.types.ts +11 -0
  115. package/packages/ui/src/patterns/FormField/FormField.vue +87 -0
  116. package/packages/ui/src/patterns/IdentityGlyph/IdentityGlyph.vue +61 -0
  117. package/packages/ui/src/patterns/IdentityGlyph/IdentityHandle.vue +58 -0
  118. package/packages/ui/src/patterns/IdentityGlyph/identityGlyph.types.ts +36 -0
  119. package/packages/ui/src/patterns/IdentityGlyph/identityGlyph.utils.ts +585 -0
  120. package/packages/ui/src/patterns/IdentityGlyph/index.ts +5 -0
  121. package/packages/ui/src/patterns/KeyValueList/KeyValueList.spec.md +28 -0
  122. package/packages/ui/src/patterns/KeyValueList/KeyValueList.types.ts +16 -0
  123. package/packages/ui/src/patterns/KeyValueList/KeyValueList.vue +50 -0
  124. package/packages/ui/src/patterns/LandingPage/LandingIcon.vue +90 -0
  125. package/packages/ui/src/patterns/LandingPage/LandingPage.spec.md +24 -0
  126. package/packages/ui/src/patterns/LandingPage/LandingPage.types.ts +212 -0
  127. package/packages/ui/src/patterns/LandingPage/LandingPage.vue +599 -0
  128. package/packages/ui/src/patterns/ListWorkspaceLayout/ListWorkspaceLayout.test.ts +33 -0
  129. package/packages/ui/src/patterns/ListWorkspaceLayout/ListWorkspaceLayout.vue +44 -0
  130. package/packages/ui/src/patterns/Logo/Logo.spec.md +22 -0
  131. package/packages/ui/src/patterns/Logo/Logo.vue +160 -0
  132. package/packages/ui/src/patterns/PageSurface/PageSurface.spec.md +15 -0
  133. package/packages/ui/src/patterns/PageSurface/PageSurface.vue +85 -0
  134. package/packages/ui/src/patterns/PanelChrome/PanelChrome.spec.md +39 -0
  135. package/packages/ui/src/patterns/PanelChrome/PanelChrome.types.ts +1 -0
  136. package/packages/ui/src/patterns/PanelChrome/PanelChrome.vue +187 -0
  137. package/packages/ui/src/patterns/PreviewPanel/PreviewPanel.spec.md +31 -0
  138. package/packages/ui/src/patterns/PreviewPanel/PreviewPanel.types.ts +23 -0
  139. package/packages/ui/src/patterns/PreviewPanel/PreviewPanel.vue +354 -0
  140. package/packages/ui/src/patterns/RecordList/RecordList.spec.md +35 -0
  141. package/packages/ui/src/patterns/RecordList/RecordList.test.ts +42 -0
  142. package/packages/ui/src/patterns/RecordList/RecordList.types.ts +9 -0
  143. package/packages/ui/src/patterns/RecordList/RecordList.utils.ts +5 -0
  144. package/packages/ui/src/patterns/RecordList/RecordList.vue +134 -0
  145. package/packages/ui/src/patterns/SectionClarifier/SectionClarifier.vue +85 -0
  146. package/packages/ui/src/patterns/SectionIntro/SectionIntro.spec.md +25 -0
  147. package/packages/ui/src/patterns/SectionIntro/SectionIntro.types.ts +7 -0
  148. package/packages/ui/src/patterns/SectionIntro/SectionIntro.vue +141 -0
  149. package/packages/ui/src/patterns/SidebarNav/SidebarNav.spec.md +34 -0
  150. package/packages/ui/src/patterns/SidebarNav/SidebarNav.types.ts +17 -0
  151. package/packages/ui/src/patterns/SidebarNav/SidebarNav.vue +110 -0
  152. package/packages/ui/src/patterns/SplitView/SplitView.spec.md +28 -0
  153. package/packages/ui/src/patterns/SplitView/SplitView.test.ts +22 -0
  154. package/packages/ui/src/patterns/SplitView/SplitView.types.ts +3 -0
  155. package/packages/ui/src/patterns/SplitView/SplitView.utils.ts +13 -0
  156. package/packages/ui/src/patterns/SplitView/SplitView.vue +39 -0
  157. package/packages/ui/src/patterns/StepList/StepList.spec.md +15 -0
  158. package/packages/ui/src/patterns/StepList/StepList.types.ts +4 -0
  159. package/packages/ui/src/patterns/StepList/StepList.vue +91 -0
  160. package/packages/ui/src/patterns/Verification/VerificationBadge.vue +97 -0
  161. package/packages/ui/src/patterns/Verification/VerificationComponents.test.ts +153 -0
  162. package/packages/ui/src/patterns/Verification/VerificationDetailsPanel.vue +270 -0
  163. package/packages/ui/src/patterns/Verification/VerificationSummary.vue +171 -0
  164. package/packages/ui/src/patterns/Verification/index.ts +6 -0
  165. package/packages/ui/src/patterns/Verification/verification.types.ts +8 -0
  166. package/packages/ui/src/patterns/Verification/verification.utils.test.ts +37 -0
  167. package/packages/ui/src/patterns/Verification/verification.utils.ts +75 -0
  168. package/packages/ui/src/patterns/index.ts +25 -0
  169. package/packages/ui/src/primitives/Accordian/Accordian.vue +11 -0
  170. package/packages/ui/src/primitives/Accordian/AccordianItem.vue +14 -0
  171. package/packages/ui/src/primitives/Accordion/Accordion.props.ts +21 -0
  172. package/packages/ui/src/primitives/Accordion/Accordion.spec.md +50 -0
  173. package/packages/ui/src/primitives/Accordion/Accordion.types.ts +4 -0
  174. package/packages/ui/src/primitives/Accordion/Accordion.variants.ts +12 -0
  175. package/packages/ui/src/primitives/Accordion/Accordion.vue +71 -0
  176. package/packages/ui/src/primitives/Accordion/AccordionItem.props.ts +14 -0
  177. package/packages/ui/src/primitives/Accordion/AccordionItem.vue +40 -0
  178. package/packages/ui/src/primitives/Badge/Badge.props.ts +17 -0
  179. package/packages/ui/src/primitives/Badge/Badge.spec.md +17 -0
  180. package/packages/ui/src/primitives/Badge/Badge.types.ts +15 -0
  181. package/packages/ui/src/primitives/Badge/Badge.variants.ts +48 -0
  182. package/packages/ui/src/primitives/Badge/Badge.vue +31 -0
  183. package/packages/ui/src/primitives/Button/Button.props.ts +29 -0
  184. package/packages/ui/src/primitives/Button/Button.spec.md +139 -0
  185. package/packages/ui/src/primitives/Button/Button.types.ts +19 -0
  186. package/packages/ui/src/primitives/Button/Button.variants.ts +72 -0
  187. package/packages/ui/src/primitives/Button/Button.vue +90 -0
  188. package/packages/ui/src/primitives/Card/Card.props.ts +17 -0
  189. package/packages/ui/src/primitives/Card/Card.spec.md +29 -0
  190. package/packages/ui/src/primitives/Card/Card.types.ts +12 -0
  191. package/packages/ui/src/primitives/Card/Card.variants.ts +27 -0
  192. package/packages/ui/src/primitives/Card/Card.vue +37 -0
  193. package/packages/ui/src/primitives/Checkbox/Checkbox.props.ts +21 -0
  194. package/packages/ui/src/primitives/Checkbox/Checkbox.spec.md +51 -0
  195. package/packages/ui/src/primitives/Checkbox/Checkbox.types.ts +4 -0
  196. package/packages/ui/src/primitives/Checkbox/Checkbox.variants.ts +34 -0
  197. package/packages/ui/src/primitives/Checkbox/Checkbox.vue +92 -0
  198. package/packages/ui/src/primitives/Dialog/Dialog.props.ts +29 -0
  199. package/packages/ui/src/primitives/Dialog/Dialog.spec.md +52 -0
  200. package/packages/ui/src/primitives/Dialog/Dialog.types.ts +3 -0
  201. package/packages/ui/src/primitives/Dialog/Dialog.variants.ts +27 -0
  202. package/packages/ui/src/primitives/Dialog/Dialog.vue +78 -0
  203. package/packages/ui/src/primitives/Drawer/Drawer.props.ts +33 -0
  204. package/packages/ui/src/primitives/Drawer/Drawer.spec.md +50 -0
  205. package/packages/ui/src/primitives/Drawer/Drawer.types.ts +5 -0
  206. package/packages/ui/src/primitives/Drawer/Drawer.variants.ts +35 -0
  207. package/packages/ui/src/primitives/Drawer/Drawer.vue +88 -0
  208. package/packages/ui/src/primitives/FieldMessage/FieldMessage.props.ts +17 -0
  209. package/packages/ui/src/primitives/FieldMessage/FieldMessage.spec.md +35 -0
  210. package/packages/ui/src/primitives/FieldMessage/FieldMessage.types.ts +5 -0
  211. package/packages/ui/src/primitives/FieldMessage/FieldMessage.variants.ts +14 -0
  212. package/packages/ui/src/primitives/FieldMessage/FieldMessage.vue +40 -0
  213. package/packages/ui/src/primitives/FileInput/FileInput.props.ts +41 -0
  214. package/packages/ui/src/primitives/FileInput/FileInput.types.ts +6 -0
  215. package/packages/ui/src/primitives/FileInput/FileInput.variants.ts +46 -0
  216. package/packages/ui/src/primitives/FileInput/FileInput.vue +163 -0
  217. package/packages/ui/src/primitives/Input/Input.props.ts +29 -0
  218. package/packages/ui/src/primitives/Input/Input.spec.md +79 -0
  219. package/packages/ui/src/primitives/Input/Input.types.ts +13 -0
  220. package/packages/ui/src/primitives/Input/Input.variants.ts +54 -0
  221. package/packages/ui/src/primitives/Input/Input.vue +99 -0
  222. package/packages/ui/src/primitives/Label/Label.props.ts +25 -0
  223. package/packages/ui/src/primitives/Label/Label.spec.md +31 -0
  224. package/packages/ui/src/primitives/Label/Label.types.ts +3 -0
  225. package/packages/ui/src/primitives/Label/Label.variants.ts +17 -0
  226. package/packages/ui/src/primitives/Label/Label.vue +38 -0
  227. package/packages/ui/src/primitives/Menu/Menu.props.ts +17 -0
  228. package/packages/ui/src/primitives/Menu/Menu.spec.md +38 -0
  229. package/packages/ui/src/primitives/Menu/Menu.types.ts +10 -0
  230. package/packages/ui/src/primitives/Menu/Menu.variants.ts +10 -0
  231. package/packages/ui/src/primitives/Menu/Menu.vue +57 -0
  232. package/packages/ui/src/primitives/Popover/Popover.props.ts +25 -0
  233. package/packages/ui/src/primitives/Popover/Popover.spec.md +49 -0
  234. package/packages/ui/src/primitives/Popover/Popover.types.ts +3 -0
  235. package/packages/ui/src/primitives/Popover/Popover.variants.ts +18 -0
  236. package/packages/ui/src/primitives/Popover/Popover.vue +74 -0
  237. package/packages/ui/src/primitives/RadioGroup/RadioGroup.props.ts +29 -0
  238. package/packages/ui/src/primitives/RadioGroup/RadioGroup.spec.md +50 -0
  239. package/packages/ui/src/primitives/RadioGroup/RadioGroup.types.ts +12 -0
  240. package/packages/ui/src/primitives/RadioGroup/RadioGroup.variants.ts +48 -0
  241. package/packages/ui/src/primitives/RadioGroup/RadioGroup.vue +87 -0
  242. package/packages/ui/src/primitives/Separator/Separator.props.ts +9 -0
  243. package/packages/ui/src/primitives/Separator/Separator.spec.md +15 -0
  244. package/packages/ui/src/primitives/Separator/Separator.types.ts +3 -0
  245. package/packages/ui/src/primitives/Separator/Separator.variants.ts +8 -0
  246. package/packages/ui/src/primitives/Separator/Separator.vue +23 -0
  247. package/packages/ui/src/primitives/Skeleton/Skeleton.props.ts +21 -0
  248. package/packages/ui/src/primitives/Skeleton/Skeleton.spec.md +18 -0
  249. package/packages/ui/src/primitives/Skeleton/Skeleton.types.ts +5 -0
  250. package/packages/ui/src/primitives/Skeleton/Skeleton.variants.ts +18 -0
  251. package/packages/ui/src/primitives/Skeleton/Skeleton.vue +37 -0
  252. package/packages/ui/src/primitives/Spinner/Spinner.props.ts +13 -0
  253. package/packages/ui/src/primitives/Spinner/Spinner.spec.md +16 -0
  254. package/packages/ui/src/primitives/Spinner/Spinner.types.ts +5 -0
  255. package/packages/ui/src/primitives/Spinner/Spinner.variants.ts +15 -0
  256. package/packages/ui/src/primitives/Spinner/Spinner.vue +33 -0
  257. package/packages/ui/src/primitives/SplitButton/SplitButton.vue +108 -0
  258. package/packages/ui/src/primitives/Switch/Switch.props.ts +21 -0
  259. package/packages/ui/src/primitives/Switch/Switch.spec.md +49 -0
  260. package/packages/ui/src/primitives/Switch/Switch.types.ts +3 -0
  261. package/packages/ui/src/primitives/Switch/Switch.variants.ts +34 -0
  262. package/packages/ui/src/primitives/Switch/Switch.vue +71 -0
  263. package/packages/ui/src/primitives/Tabs/Tabs.props.ts +25 -0
  264. package/packages/ui/src/primitives/Tabs/Tabs.spec.md +48 -0
  265. package/packages/ui/src/primitives/Tabs/Tabs.types.ts +11 -0
  266. package/packages/ui/src/primitives/Tabs/Tabs.variants.ts +28 -0
  267. package/packages/ui/src/primitives/Tabs/Tabs.vue +59 -0
  268. package/packages/ui/src/primitives/Textarea/Textarea.props.ts +33 -0
  269. package/packages/ui/src/primitives/Textarea/Textarea.spec.md +59 -0
  270. package/packages/ui/src/primitives/Textarea/Textarea.types.ts +5 -0
  271. package/packages/ui/src/primitives/Textarea/Textarea.variants.ts +27 -0
  272. package/packages/ui/src/primitives/Textarea/Textarea.vue +74 -0
  273. package/packages/ui/src/primitives/Tooltip/Tooltip.props.ts +21 -0
  274. package/packages/ui/src/primitives/Tooltip/Tooltip.spec.md +45 -0
  275. package/packages/ui/src/primitives/Tooltip/Tooltip.types.ts +3 -0
  276. package/packages/ui/src/primitives/Tooltip/Tooltip.variants.ts +4 -0
  277. package/packages/ui/src/primitives/Tooltip/Tooltip.vue +31 -0
  278. package/packages/ui/src/primitives/TreeView/TreeView.types.ts +10 -0
  279. package/packages/ui/src/primitives/TreeView/TreeView.vue +113 -0
  280. package/packages/ui/src/primitives/TreeView/TreeViewNode.vue +190 -0
  281. package/packages/ui/src/primitives/index.ts +29 -0
  282. package/packages/ui/src/style.css +7 -0
  283. package/packages/ui/src/style.js +1 -0
  284. package/packages/ui/src/themes/armour.css +147 -0
  285. package/packages/ui/src/themes/aurora.css +147 -0
  286. package/packages/ui/src/themes/citrine-ash.css +147 -0
  287. package/packages/ui/src/themes/concord.css +147 -0
  288. package/packages/ui/src/themes/garnet-honey.css +147 -0
  289. package/packages/ui/src/themes/harbor-rose.css +147 -0
  290. package/packages/ui/src/themes/ledger.css +147 -0
  291. package/packages/ui/src/themes/neon-noir.css +74 -0
  292. package/packages/ui/src/themes/obsidian-iris.css +147 -0
  293. package/packages/ui/src/themes/pixpax.css +147 -0
  294. package/packages/ui/src/themes/print.css +147 -0
  295. package/packages/ui/src/themes/prism.css +147 -0
  296. package/packages/ui/src/themes/proof.css +145 -0
  297. package/packages/ui/src/themes/semanticThemeContract.js +2256 -0
  298. package/packages/ui/src/themes/spruce-ink.css +147 -0
  299. package/packages/ui/src/themes/sunset.css +147 -0
  300. package/packages/ui/tailwind.config.js +64 -0
  301. package/packages/ui/vite.config.js +35 -0
  302. package/packages/ui/vite.config.js.timestamp-1780697224943-89fbc929987bc.mjs +38 -0
  303. package/packages/utils/CHANGELOG.md +111 -0
  304. package/packages/utils/README.md +3 -0
  305. package/packages/utils/package.json +46 -0
  306. package/packages/utils/src/index.test.js +39 -0
  307. package/packages/utils/src/index.ts +289 -0
  308. package/packages/utils/tsconfig.build.json +12 -0
  309. package/packages/utils/vite.config.js +28 -0
  310. package/pnpm-workspace.yaml +8 -0
  311. package/scripts/vite/package-lib-config.ts +59 -0
  312. package/tsconfig.json +24 -0
  313. package/tsconfig.node.json +9 -0
@@ -0,0 +1,72 @@
1
+ import type { ButtonSize, ButtonVariant } from "./Button.types";
2
+
3
+ export const buttonBaseClass =
4
+ "inline-flex items-center justify-center gap-2 border border-transparent " +
5
+ "font-medium select-none whitespace-nowrap align-middle " +
6
+ "rounded-[var(--ui-radius-md)] " +
7
+ "transition-[transform,box-shadow,background-color,opacity,border-color,color] " +
8
+ "duration-[var(--ui-duration-normal)] ease-[var(--ui-ease-out)] " +
9
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-ring)]";
10
+
11
+ export const buttonStateClasses = {
12
+ interactive:
13
+ "cursor-pointer shadow-[var(--ui-shadow-sm)] " +
14
+ "hover:shadow-[var(--ui-shadow-md)] hover:translate-y-[var(--ui-lift-hover)] " +
15
+ "active:translate-y-0 active:scale-[var(--ui-scale-active)]",
16
+ disabled: "cursor-not-allowed pointer-events-none opacity-40 shadow-none",
17
+ loading: "cursor-progress pointer-events-none opacity-75 shadow-[var(--ui-shadow-sm)]",
18
+ } as const;
19
+
20
+ export const buttonVariantClasses: Record<ButtonVariant, string> = {
21
+ primary:
22
+ "bg-[var(--ui-primary)] text-[var(--ui-on-primary)] " +
23
+ "hover:bg-[var(--ui-primary-hover)] active:bg-[var(--ui-primary-active)] " +
24
+ "hover:shadow-[var(--ui-glow-primary)]",
25
+
26
+ accent:
27
+ "bg-[var(--ui-accent)] text-[var(--ui-on-accent)] " +
28
+ "hover:bg-[var(--ui-accent-hover)] active:bg-[var(--ui-accent-active)] " +
29
+ "hover:shadow-[var(--ui-glow-accent)]",
30
+
31
+ secondary:
32
+ "bg-[var(--ui-tonal-secondary)] text-[var(--ui-fg)] " +
33
+ "hover:bg-[var(--ui-tonal-secondary-hover)]",
34
+
35
+ tertiary:
36
+ "bg-[var(--ui-tonal-tertiary)] text-[var(--ui-fg)] " +
37
+ "hover:bg-[var(--ui-tonal-tertiary-hover)]",
38
+
39
+ critical:
40
+ "bg-[var(--ui-critical)] text-[var(--ui-on-critical)] " +
41
+ "hover:bg-[var(--ui-critical-hover)] active:bg-[var(--ui-critical-active)] " +
42
+ "hover:shadow-[var(--ui-glow-critical)]",
43
+
44
+ "plain-primary":
45
+ "bg-transparent text-[var(--ui-primary)] shadow-none " +
46
+ "hover:bg-[var(--ui-primary-muted)] active:bg-[var(--ui-primary-hover)] " +
47
+ "hover:shadow-none",
48
+
49
+ "plain-secondary":
50
+ "bg-transparent text-[var(--ui-fg)] opacity-80 shadow-none " +
51
+ "hover:bg-[var(--ui-surface-hover)] hover:opacity-100 hover:shadow-none",
52
+
53
+ "critical-secondary":
54
+ "bg-transparent text-[var(--ui-critical)] border-[var(--ui-critical-muted)] shadow-none " +
55
+ "hover:bg-[var(--ui-critical-muted)] active:bg-[var(--ui-critical-hover)] " +
56
+ "hover:shadow-none",
57
+ };
58
+
59
+ export const buttonSizeClasses: Record<ButtonSize, string> = {
60
+ micro: "h-7 px-2 text-xs",
61
+ xs: "h-8 px-3 text-xs",
62
+ sm: "h-9 px-4 text-sm",
63
+ md: "h-10 px-4 text-sm",
64
+ lg: "h-11 px-5 text-base",
65
+ xl: "h-12 px-6 text-base",
66
+ hero: "h-16 px-8 text-base uppercase tracking-[0.14em]",
67
+ };
68
+
69
+ export const buttonLabelClass = "inline-flex items-center gap-2";
70
+ export const buttonAdornmentClass = "inline-flex shrink-0 items-center justify-center";
71
+ export const buttonSpinnerClass =
72
+ "inline-block size-4 animate-spin rounded-full border-2 border-current border-r-transparent";
@@ -0,0 +1,90 @@
1
+ <script setup lang="ts">
2
+ import { computed, normalizeClass, useAttrs } from "vue";
3
+ import { twMerge } from "tailwind-merge";
4
+ import { buttonProps } from "./Button.props";
5
+ import {
6
+ buttonAdornmentClass,
7
+ buttonBaseClass,
8
+ buttonLabelClass,
9
+ buttonSizeClasses,
10
+ buttonSpinnerClass,
11
+ buttonStateClasses,
12
+ buttonVariantClasses,
13
+ } from "./Button.variants";
14
+
15
+ defineOptions({ inheritAttrs: false });
16
+
17
+ const emit = defineEmits<{
18
+ click: [event: MouseEvent];
19
+ }>();
20
+
21
+ const attrs = useAttrs();
22
+ const props = defineProps(buttonProps);
23
+
24
+ const isButtonElement = computed(() => props.as === "button");
25
+ const isInactive = computed(() => props.disabled || props.loading);
26
+
27
+ const stateClass = computed(() => {
28
+ if (props.loading) {
29
+ return buttonStateClasses.loading;
30
+ }
31
+
32
+ if (props.disabled) {
33
+ return buttonStateClasses.disabled;
34
+ }
35
+
36
+ return buttonStateClasses.interactive;
37
+ });
38
+
39
+ const classes = computed(() =>
40
+ twMerge(
41
+ buttonBaseClass,
42
+ stateClass.value,
43
+ buttonVariantClasses[props.variant],
44
+ buttonSizeClasses[props.size],
45
+ normalizeClass(attrs.class),
46
+ ),
47
+ );
48
+
49
+ const forwardedAttrs = computed(() => {
50
+ const { class: _class, disabled: _disabled, type: _type, ...rest } = attrs;
51
+
52
+ return rest;
53
+ });
54
+
55
+ const componentAttrs = computed(() => ({
56
+ ...forwardedAttrs.value,
57
+ type: isButtonElement.value ? props.type : undefined,
58
+ disabled: isButtonElement.value ? isInactive.value : undefined,
59
+ "aria-busy": props.loading ? "true" : undefined,
60
+ "aria-disabled": !isButtonElement.value && isInactive.value ? "true" : undefined,
61
+ tabindex: !isButtonElement.value && isInactive.value ? -1 : attrs.tabindex,
62
+ "data-loading": props.loading ? "true" : "false",
63
+ "data-disabled": isInactive.value ? "true" : "false",
64
+ }));
65
+
66
+ function handleClick(event: MouseEvent) {
67
+ if (isInactive.value) {
68
+ event.preventDefault();
69
+ event.stopPropagation();
70
+ return;
71
+ }
72
+
73
+ emit("click", event);
74
+ }
75
+ </script>
76
+
77
+ <template>
78
+ <component :is="props.as" :class="classes" v-bind="componentAttrs" @click="handleClick">
79
+ <span v-if="props.loading" :class="buttonSpinnerClass" aria-hidden="true" />
80
+ <span v-else-if="$slots.leading" :class="buttonAdornmentClass">
81
+ <slot name="leading" />
82
+ </span>
83
+ <span :class="buttonLabelClass">
84
+ <slot />
85
+ </span>
86
+ <span v-if="$slots.trailing" :class="buttonAdornmentClass">
87
+ <slot name="trailing" />
88
+ </span>
89
+ </component>
90
+ </template>
@@ -0,0 +1,17 @@
1
+ import type { PropType } from "vue";
2
+ import type { CardPadding, CardVariant } from "./Card.types";
3
+
4
+ export const cardProps = {
5
+ variant: {
6
+ type: String as PropType<CardVariant>,
7
+ default: "default",
8
+ },
9
+ padding: {
10
+ type: String as PropType<CardPadding>,
11
+ default: "md",
12
+ },
13
+ interactive: {
14
+ type: Boolean,
15
+ default: false,
16
+ },
17
+ };
@@ -0,0 +1,29 @@
1
+ # Card
2
+
3
+ ## Purpose
4
+
5
+ Generic surface primitive for grouped content.
6
+
7
+ ## Category
8
+
9
+ Primitive
10
+
11
+ ## Public API
12
+
13
+ Props:
14
+
15
+ - `variant`: `default | subtle | outline | elevated | panel`
16
+ - `padding`: `sm | md | lg`
17
+ - `interactive`: boolean
18
+
19
+ ## Variants
20
+
21
+ - `default`: standard raised surface
22
+ - `subtle`: quieter tonal surface
23
+ - `outline`: transparent structural container
24
+ - `elevated`: stronger separation for high-emphasis grouped content
25
+ - `panel`: denser tonal panel for previews, examples, and technical callouts
26
+
27
+ ## Notes
28
+
29
+ - Visual finish is token-driven and intended to support both application and marketing-style compositions without route-local styling.
@@ -0,0 +1,12 @@
1
+ export const cardVariantValues = [
2
+ "default",
3
+ "subtle",
4
+ "outline",
5
+ "elevated",
6
+ "panel",
7
+ "showcase",
8
+ ] as const;
9
+ export const cardPaddingValues = ["sm", "md", "lg"] as const;
10
+
11
+ export type CardVariant = (typeof cardVariantValues)[number];
12
+ export type CardPadding = (typeof cardPaddingValues)[number];
@@ -0,0 +1,27 @@
1
+ import type { CardPadding, CardVariant } from "./Card.types";
2
+
3
+ export const cardBaseClass =
4
+ "rounded-[var(--ui-radius-lg)] border text-[var(--ui-fg)] transition-[border-color,box-shadow,transform,background-color] " +
5
+ "duration-[var(--ui-duration-normal)] ease-[var(--ui-ease-out)]";
6
+
7
+ export const cardVariantClasses: Record<CardVariant, string> = {
8
+ default: "border-[var(--ui-border)] bg-[var(--ui-surface)] shadow-[var(--ui-shadow-sm)]",
9
+ subtle: "border-[var(--ui-border)] bg-[var(--ui-tonal-tertiary)] shadow-none",
10
+ outline: "border-[var(--ui-border)] bg-transparent shadow-none",
11
+ elevated: "border-[var(--ui-border)] bg-[var(--ui-surface)] shadow-[var(--ui-shadow-md)]",
12
+ panel: "border-[var(--ui-border)] bg-[var(--ui-tonal-secondary)] shadow-[var(--ui-shadow-md)]",
13
+ showcase:
14
+ "border-[color-mix(in_srgb,var(--ui-border)_74%,var(--ui-primary-muted))] " +
15
+ "bg-[linear-gradient(180deg,color-mix(in_srgb,var(--ui-primary)_12%,var(--ui-tonal-secondary))_0%,color-mix(in_srgb,var(--ui-bg)_84%,var(--ui-tonal-secondary))_100%)] " +
16
+ "shadow-[0_18px_48px_color-mix(in_srgb,var(--ui-primary)_14%,transparent),inset_0_1px_0_color-mix(in_srgb,var(--ui-fg)_8%,transparent)] " +
17
+ "backdrop-blur-sm",
18
+ };
19
+
20
+ export const cardPaddingClasses: Record<CardPadding, string> = {
21
+ sm: "p-4",
22
+ md: "p-6",
23
+ lg: "p-8",
24
+ };
25
+
26
+ export const cardInteractiveClass =
27
+ "cursor-pointer hover:-translate-y-[var(--ui-lift-hover)] hover:border-[var(--ui-primary-muted)] hover:shadow-[var(--ui-shadow-md)] focus-within:ring-2 focus-within:ring-[var(--ui-ring)]";
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ import { computed, normalizeClass, useAttrs } from "vue";
3
+ import { twMerge } from "tailwind-merge";
4
+ import { cardProps } from "./Card.props";
5
+ import {
6
+ cardBaseClass,
7
+ cardInteractiveClass,
8
+ cardPaddingClasses,
9
+ cardVariantClasses,
10
+ } from "./Card.variants";
11
+
12
+ defineOptions({ inheritAttrs: false });
13
+
14
+ const attrs = useAttrs();
15
+ const props = defineProps(cardProps);
16
+
17
+ const classes = computed(() =>
18
+ twMerge(
19
+ cardBaseClass,
20
+ cardVariantClasses[props.variant],
21
+ cardPaddingClasses[props.padding],
22
+ props.interactive ? cardInteractiveClass : "",
23
+ normalizeClass(attrs.class),
24
+ ),
25
+ );
26
+
27
+ const cardAttrs = computed(() => {
28
+ const { class: _class, ...rest } = attrs;
29
+ return rest;
30
+ });
31
+ </script>
32
+
33
+ <template>
34
+ <div :class="classes" v-bind="cardAttrs">
35
+ <slot />
36
+ </div>
37
+ </template>
@@ -0,0 +1,21 @@
1
+ import type { PropType } from "vue";
2
+ import type { CheckboxCheckedValue, CheckboxSize } from "./Checkbox.types";
3
+
4
+ export const checkboxProps = {
5
+ modelValue: {
6
+ type: [Boolean, String] as PropType<CheckboxCheckedValue>,
7
+ default: false,
8
+ },
9
+ size: {
10
+ type: String as PropType<CheckboxSize>,
11
+ default: "md",
12
+ },
13
+ disabled: {
14
+ type: Boolean,
15
+ default: false,
16
+ },
17
+ invalid: {
18
+ type: Boolean,
19
+ default: false,
20
+ },
21
+ };
@@ -0,0 +1,51 @@
1
+ # Checkbox
2
+
3
+ ## Purpose
4
+
5
+ Binary or indeterminate choice primitive built on Ark UI.
6
+
7
+ ## Category
8
+
9
+ Primitive
10
+
11
+ ## Public API
12
+
13
+ Props:
14
+
15
+ - `modelValue`: `boolean | "indeterminate"`
16
+ - `size`: `sm | md`
17
+ - `disabled`: boolean
18
+ - `invalid`: boolean
19
+
20
+ Slots:
21
+
22
+ - default: inline label
23
+ - `description`: supporting text below the label
24
+
25
+ Events:
26
+
27
+ - `update:modelValue`
28
+
29
+ ## States
30
+
31
+ - unchecked
32
+ - checked
33
+ - indeterminate
34
+ - focus-visible
35
+ - disabled
36
+ - invalid
37
+
38
+ ## Accessibility
39
+
40
+ - built on Ark `Checkbox.Root`
41
+ - includes hidden input for form participation
42
+ - supports keyboard interaction through Ark
43
+ - focus treatment is applied at the wrapper level with `focus-within`
44
+
45
+ ## Examples
46
+
47
+ ```vue
48
+ <Checkbox v-model="agreed">
49
+ Accept terms
50
+ </Checkbox>
51
+ ```
@@ -0,0 +1,4 @@
1
+ export const checkboxSizeValues = ["sm", "md"] as const;
2
+
3
+ export type CheckboxSize = (typeof checkboxSizeValues)[number];
4
+ export type CheckboxCheckedValue = boolean | "indeterminate";
@@ -0,0 +1,34 @@
1
+ import type { CheckboxSize } from "./Checkbox.types";
2
+
3
+ export const checkboxRootClass =
4
+ "group inline-flex w-fit items-start gap-3 rounded-[var(--ui-radius-md)] " +
5
+ "focus-within:ring-2 focus-within:ring-[var(--ui-ring)]";
6
+
7
+ export const checkboxControlBaseClass =
8
+ "inline-flex shrink-0 items-center justify-center rounded-[var(--ui-radius-sm)] border " +
9
+ "border-[var(--ui-border)] bg-[var(--ui-surface)] text-[var(--ui-on-primary)] " +
10
+ "transition-[background-color,border-color,box-shadow,color] duration-[var(--ui-duration-normal)] ease-[var(--ui-ease-out)] " +
11
+ "group-hover:border-[var(--ui-primary-muted)] " +
12
+ "data-[state=checked]:border-[var(--ui-primary)] data-[state=checked]:bg-[var(--ui-primary)] " +
13
+ "data-[state=indeterminate]:border-[var(--ui-primary)] data-[state=indeterminate]:bg-[var(--ui-primary)]";
14
+
15
+ export const checkboxControlStateClasses = {
16
+ default: "",
17
+ invalid:
18
+ "border-[var(--ui-critical)] data-[state=checked]:border-[var(--ui-critical)] data-[state=checked]:bg-[var(--ui-critical)] " +
19
+ "data-[state=indeterminate]:border-[var(--ui-critical)] data-[state=indeterminate]:bg-[var(--ui-critical)]",
20
+ disabled: "opacity-50",
21
+ } as const;
22
+
23
+ export const checkboxControlSizeClasses: Record<CheckboxSize, string> = {
24
+ sm: "mt-0.5 size-4",
25
+ md: "mt-0.5 size-5",
26
+ };
27
+
28
+ export const checkboxIndicatorSizeClasses: Record<CheckboxSize, string> = {
29
+ sm: "size-3",
30
+ md: "size-3.5",
31
+ };
32
+
33
+ export const checkboxLabelClass = "text-[var(--ui-fg)]";
34
+ export const checkboxDescriptionClass = "text-sm text-[var(--ui-fg-muted)]";
@@ -0,0 +1,92 @@
1
+ <script setup lang="ts">
2
+ import { Checkbox } from "@ark-ui/vue/checkbox";
3
+ import { computed, normalizeClass, useAttrs, useSlots } from "vue";
4
+ import { twMerge } from "tailwind-merge";
5
+ import { checkboxProps } from "./Checkbox.props";
6
+ import {
7
+ checkboxControlBaseClass,
8
+ checkboxControlSizeClasses,
9
+ checkboxControlStateClasses,
10
+ checkboxDescriptionClass,
11
+ checkboxIndicatorSizeClasses,
12
+ checkboxLabelClass,
13
+ checkboxRootClass,
14
+ } from "./Checkbox.variants";
15
+ import type { CheckboxCheckedValue } from "./Checkbox.types";
16
+
17
+ defineOptions({ inheritAttrs: false });
18
+
19
+ const emit = defineEmits<{
20
+ "update:modelValue": [value: CheckboxCheckedValue];
21
+ }>();
22
+
23
+ const attrs = useAttrs();
24
+ const slots = useSlots();
25
+ const props = defineProps(checkboxProps);
26
+
27
+ const rootClass = computed(() => twMerge(checkboxRootClass, normalizeClass(attrs.class)));
28
+
29
+ const controlClass = computed(() =>
30
+ twMerge(
31
+ checkboxControlBaseClass,
32
+ checkboxControlSizeClasses[props.size],
33
+ props.invalid ? checkboxControlStateClasses.invalid : checkboxControlStateClasses.default,
34
+ props.disabled ? checkboxControlStateClasses.disabled : "",
35
+ ),
36
+ );
37
+
38
+ const rootAttrs = computed(() => {
39
+ const { class: _class, ...rest } = attrs;
40
+ return rest;
41
+ });
42
+
43
+ function handleCheckedChange(value: CheckboxCheckedValue) {
44
+ emit("update:modelValue", value);
45
+ }
46
+ </script>
47
+
48
+ <template>
49
+ <Checkbox.Root
50
+ :checked="props.modelValue"
51
+ :disabled="props.disabled"
52
+ :invalid="props.invalid"
53
+ :class="rootClass"
54
+ v-bind="rootAttrs"
55
+ @update:checked="handleCheckedChange"
56
+ >
57
+ <Checkbox.HiddenInput />
58
+ <Checkbox.Control :class="controlClass">
59
+ <Checkbox.Context v-slot="checkboxApi">
60
+ <Checkbox.Indicator :class="checkboxIndicatorSizeClasses[props.size]">
61
+ <svg
62
+ v-if="checkboxApi.checked === 'indeterminate'"
63
+ viewBox="0 0 16 16"
64
+ fill="none"
65
+ class="size-full"
66
+ aria-hidden="true"
67
+ >
68
+ <path d="M3.5 8h9" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
69
+ </svg>
70
+ <svg v-else viewBox="0 0 16 16" fill="none" class="size-full" aria-hidden="true">
71
+ <path
72
+ d="M3.5 8.5 6.5 11.5 12.5 4.5"
73
+ stroke="currentColor"
74
+ stroke-width="2"
75
+ stroke-linecap="round"
76
+ stroke-linejoin="round"
77
+ />
78
+ </svg>
79
+ </Checkbox.Indicator>
80
+ </Checkbox.Context>
81
+ </Checkbox.Control>
82
+
83
+ <div v-if="slots.default || slots.description" class="flex flex-col gap-1">
84
+ <Checkbox.Label v-if="slots.default" :class="checkboxLabelClass">
85
+ <slot />
86
+ </Checkbox.Label>
87
+ <div v-if="slots.description" :class="checkboxDescriptionClass">
88
+ <slot name="description" />
89
+ </div>
90
+ </div>
91
+ </Checkbox.Root>
92
+ </template>
@@ -0,0 +1,29 @@
1
+ import type { PropType } from "vue";
2
+ import type { DialogSize } from "./Dialog.types";
3
+
4
+ export const dialogProps = {
5
+ title: {
6
+ type: String,
7
+ default: undefined,
8
+ },
9
+ description: {
10
+ type: String,
11
+ default: undefined,
12
+ },
13
+ size: {
14
+ type: String as PropType<DialogSize>,
15
+ default: "md",
16
+ },
17
+ showClose: {
18
+ type: Boolean,
19
+ default: true,
20
+ },
21
+ closeOnEscape: {
22
+ type: Boolean,
23
+ default: true,
24
+ },
25
+ closeOnInteractOutside: {
26
+ type: Boolean,
27
+ default: true,
28
+ },
29
+ };
@@ -0,0 +1,52 @@
1
+ # Dialog
2
+
3
+ ## Purpose
4
+
5
+ Modal overlay primitive for focused tasks and confirmation flows.
6
+
7
+ ## Category
8
+
9
+ Primitive
10
+
11
+ ## Public API
12
+
13
+ Props:
14
+
15
+ - `open` via `v-model:open`
16
+ - `title`
17
+ - `description`
18
+ - `size`: `sm | md | lg | xl`
19
+ - `showClose`
20
+ - `closeOnEscape`
21
+ - `closeOnInteractOutside`
22
+
23
+ Slots:
24
+
25
+ - `trigger`
26
+ - `header`
27
+ - default content
28
+ - `footer`
29
+
30
+ ## Accessibility
31
+
32
+ - built on Ark dialog semantics
33
+ - traps focus while open
34
+ - supports Escape and outside-interaction closing when enabled
35
+ - uses `Dialog.Title` and `Dialog.Description` when provided
36
+
37
+ ## Keyboard behavior
38
+
39
+ - focus moves into the dialog on open
40
+ - Escape closes when `closeOnEscape` is true
41
+ - close trigger is keyboard reachable
42
+
43
+ ## Example
44
+
45
+ ```vue
46
+ <Dialog v-model:open="open" title="Delete record" description="This cannot be undone.">
47
+ <template #trigger>
48
+ <Button variant="critical">Delete</Button>
49
+ </template>
50
+ Are you sure?
51
+ </Dialog>
52
+ ```
@@ -0,0 +1,3 @@
1
+ export const dialogSizeValues = ["sm", "md", "lg", "xl"] as const;
2
+
3
+ export type DialogSize = (typeof dialogSizeValues)[number];
@@ -0,0 +1,27 @@
1
+ import type { DialogSize } from "./Dialog.types";
2
+
3
+ export const dialogBackdropClass = "fixed inset-0 z-40 bg-[var(--ui-fg)]/40 backdrop-blur-sm";
4
+ export const dialogPositionerClass = "fixed inset-0 z-50 grid place-items-center p-4";
5
+ export const dialogContentBaseClass =
6
+ "w-full overflow-hidden rounded-[var(--ui-radius-lg)] border border-[var(--ui-border)] " +
7
+ "bg-[var(--ui-surface)] text-[var(--ui-fg)] shadow-[var(--ui-shadow-md)]";
8
+
9
+ export const dialogContentSizeClasses: Record<DialogSize, string> = {
10
+ sm: "max-w-md",
11
+ md: "max-w-lg",
12
+ lg: "max-w-2xl",
13
+ xl: "max-w-4xl",
14
+ };
15
+
16
+ export const dialogHeaderClass =
17
+ "flex items-start justify-between gap-4 border-b border-[var(--ui-border)] px-4 py-3";
18
+ export const dialogTitleClass = "text-base font-semibold text-[var(--ui-fg)]";
19
+ export const dialogDescriptionClass = "mt-1 text-sm text-[var(--ui-fg-muted)]";
20
+ export const dialogBodyClass = "px-4 py-4";
21
+ export const dialogFooterClass =
22
+ "flex items-center justify-end gap-3 border-t border-[var(--ui-border)] px-4 py-3";
23
+ export const dialogCloseClass =
24
+ "inline-flex size-9 items-center justify-center rounded-[var(--ui-radius-sm)] border border-[var(--ui-border)] " +
25
+ "text-[var(--ui-fg-muted)] transition-[border-color,background-color,color] duration-[var(--ui-duration-normal)] ease-[var(--ui-ease-out)] " +
26
+ "hover:border-[var(--ui-primary-muted)] hover:bg-[var(--ui-tonal-secondary)] hover:text-[var(--ui-fg)] " +
27
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-ring)]";