@forte-ui/react 1.0.0-alpha.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 (304) hide show
  1. package/README.md +240 -0
  2. package/dist/Accordion-9JunkjgY.js +111 -0
  3. package/dist/Alert-Cn_WUF3L.js +183 -0
  4. package/dist/AspectRatio-gSjpTVk-.js +39 -0
  5. package/dist/Avatar-BuitDluH.js +87 -0
  6. package/dist/Badge-sArNWMre.js +33 -0
  7. package/dist/Breadcrumb-Cq7tFtMX.js +170 -0
  8. package/dist/Button-AiyKnx5I.js +42 -0
  9. package/dist/ButtonGroup-C-CrwPXP.js +54 -0
  10. package/dist/Calendar-D7Q-QJ_e.js +503 -0
  11. package/dist/Checkbox-DfNbmOed.js +56 -0
  12. package/dist/Collapsible-D8UKiGip.js +86 -0
  13. package/dist/ColorPicker-B-eCI31W.js +612 -0
  14. package/dist/Combobox-D-BN-Tvp.js +302 -0
  15. package/dist/ContextMenu-D81uDaMG.js +44 -0
  16. package/dist/DatePicker-CfkMsaI-.js +192 -0
  17. package/dist/Dialog-_n8FpFs5.js +432 -0
  18. package/dist/Drawer-DKQF3OO7.js +158 -0
  19. package/dist/Field-FLFEO70D.js +58 -0
  20. package/dist/Fieldset-CYhh71Qt.js +28 -0
  21. package/dist/Form-DVPmW9XV.js +17 -0
  22. package/dist/Input-BgGWhO2q.js +18 -0
  23. package/dist/InputGroup-DsZyDXNn.js +89 -0
  24. package/dist/Menu-CKu9xE2h.js +261 -0
  25. package/dist/Menubar-Dax027Db.js +19 -0
  26. package/dist/NavList-DGvcIoJm.js +176 -0
  27. package/dist/NavigationMenu-BayQkUUb.js +209 -0
  28. package/dist/NumberField-P55SA8T7.js +191 -0
  29. package/dist/OTPField-CjHvBNSN.js +55 -0
  30. package/dist/Popover-BXhn2Wwt.js +142 -0
  31. package/dist/PreviewCard-Dnitrky0.js +99 -0
  32. package/dist/Progress-BlomDp-X.js +81 -0
  33. package/dist/ProgressCircle-j6XBl0fk.js +112 -0
  34. package/dist/Radio-BIcX4INJ.js +37 -0
  35. package/dist/Resizable-7nJJM97e.js +609 -0
  36. package/dist/ScrollArea-CBMGJ6hh.js +83 -0
  37. package/dist/Select-BP-zvdXm.js +237 -0
  38. package/dist/Separator-DewJBzaJ.js +21 -0
  39. package/dist/Skeleton-zr6ObCCq.js +79 -0
  40. package/dist/Slider-Bh8_cti1.js +104 -0
  41. package/dist/Spinner-BF0uD4hR.js +53 -0
  42. package/dist/Switch-OBewMMvM.js +39 -0
  43. package/dist/Tabs-LgkSbPSF.js +132 -0
  44. package/dist/Textarea-CqZJL41e.js +51 -0
  45. package/dist/Toast-BWayxAcd.js +304 -0
  46. package/dist/Toggle-BrhMnkF5.js +45 -0
  47. package/dist/Toolbar-OmOVCk3i.js +88 -0
  48. package/dist/Tooltip-CI4chsRw.js +101 -0
  49. package/dist/clsx-By2n9mTe.js +16 -0
  50. package/dist/cn.d.ts +8 -0
  51. package/dist/cn.js +11 -0
  52. package/dist/components/accordion/Accordion.d.ts +117 -0
  53. package/dist/components/accordion/Accordion.js +3 -0
  54. package/dist/components/accordion/index.d.ts +2 -0
  55. package/dist/components/accordion/index.js +2 -0
  56. package/dist/components/alert/Alert.d.ts +167 -0
  57. package/dist/components/alert/Alert.js +3 -0
  58. package/dist/components/alert/index.d.ts +2 -0
  59. package/dist/components/alert/index.js +2 -0
  60. package/dist/components/aspect-ratio/AspectRatio.d.ts +128 -0
  61. package/dist/components/aspect-ratio/AspectRatio.js +3 -0
  62. package/dist/components/aspect-ratio/index.d.ts +2 -0
  63. package/dist/components/aspect-ratio/index.js +2 -0
  64. package/dist/components/avatar/Avatar.d.ts +176 -0
  65. package/dist/components/avatar/Avatar.js +3 -0
  66. package/dist/components/avatar/index.d.ts +2 -0
  67. package/dist/components/avatar/index.js +2 -0
  68. package/dist/components/badge/Badge.d.ts +117 -0
  69. package/dist/components/badge/Badge.js +3 -0
  70. package/dist/components/badge/index.d.ts +2 -0
  71. package/dist/components/badge/index.js +2 -0
  72. package/dist/components/breadcrumb/Breadcrumb.d.ts +244 -0
  73. package/dist/components/breadcrumb/Breadcrumb.js +3 -0
  74. package/dist/components/breadcrumb/index.d.ts +2 -0
  75. package/dist/components/breadcrumb/index.js +2 -0
  76. package/dist/components/button/Button.d.ts +73 -0
  77. package/dist/components/button/Button.js +3 -0
  78. package/dist/components/button/index.d.ts +2 -0
  79. package/dist/components/button/index.js +2 -0
  80. package/dist/components/button-group/ButtonGroup.d.ts +113 -0
  81. package/dist/components/button-group/ButtonGroup.js +3 -0
  82. package/dist/components/button-group/index.d.ts +2 -0
  83. package/dist/components/button-group/index.js +2 -0
  84. package/dist/components/calendar/Calendar.d.ts +201 -0
  85. package/dist/components/calendar/Calendar.js +3 -0
  86. package/dist/components/calendar/index.d.ts +2 -0
  87. package/dist/components/calendar/index.js +2 -0
  88. package/dist/components/checkbox/Checkbox.d.ts +130 -0
  89. package/dist/components/checkbox/Checkbox.js +3 -0
  90. package/dist/components/checkbox/index.d.ts +2 -0
  91. package/dist/components/checkbox/index.js +2 -0
  92. package/dist/components/collapsible/Collapsible.d.ts +91 -0
  93. package/dist/components/collapsible/Collapsible.js +3 -0
  94. package/dist/components/collapsible/index.d.ts +2 -0
  95. package/dist/components/collapsible/index.js +2 -0
  96. package/dist/components/color-picker/ColorPicker.d.ts +553 -0
  97. package/dist/components/color-picker/ColorPicker.js +4 -0
  98. package/dist/components/color-picker/color.d.ts +102 -0
  99. package/dist/components/color-picker/color.js +249 -0
  100. package/dist/components/color-picker/index.d.ts +2 -0
  101. package/dist/components/color-picker/index.js +3 -0
  102. package/dist/components/combobox/Combobox.d.ts +553 -0
  103. package/dist/components/combobox/Combobox.js +3 -0
  104. package/dist/components/combobox/index.d.ts +2 -0
  105. package/dist/components/combobox/index.js +2 -0
  106. package/dist/components/context-menu/ContextMenu.d.ts +103 -0
  107. package/dist/components/context-menu/ContextMenu.js +3 -0
  108. package/dist/components/context-menu/index.d.ts +3 -0
  109. package/dist/components/context-menu/index.js +2 -0
  110. package/dist/components/date-picker/DatePicker.d.ts +268 -0
  111. package/dist/components/date-picker/DatePicker.js +3 -0
  112. package/dist/components/date-picker/index.d.ts +2 -0
  113. package/dist/components/date-picker/index.js +2 -0
  114. package/dist/components/dialog/Dialog.d.ts +567 -0
  115. package/dist/components/dialog/Dialog.js +3 -0
  116. package/dist/components/dialog/index.d.ts +2 -0
  117. package/dist/components/dialog/index.js +2 -0
  118. package/dist/components/drawer/Drawer.d.ts +351 -0
  119. package/dist/components/drawer/Drawer.js +3 -0
  120. package/dist/components/drawer/index.d.ts +2 -0
  121. package/dist/components/drawer/index.js +2 -0
  122. package/dist/components/field/Field.d.ts +170 -0
  123. package/dist/components/field/Field.js +3 -0
  124. package/dist/components/field/index.d.ts +2 -0
  125. package/dist/components/field/index.js +2 -0
  126. package/dist/components/fieldset/Fieldset.d.ts +60 -0
  127. package/dist/components/fieldset/Fieldset.js +3 -0
  128. package/dist/components/fieldset/index.d.ts +2 -0
  129. package/dist/components/fieldset/index.js +2 -0
  130. package/dist/components/form/Form.d.ts +76 -0
  131. package/dist/components/form/Form.js +3 -0
  132. package/dist/components/form/index.d.ts +2 -0
  133. package/dist/components/form/index.js +2 -0
  134. package/dist/components/input/Input.d.ts +67 -0
  135. package/dist/components/input/Input.js +3 -0
  136. package/dist/components/input/index.d.ts +2 -0
  137. package/dist/components/input/index.js +2 -0
  138. package/dist/components/input-group/InputGroup.d.ts +214 -0
  139. package/dist/components/input-group/InputGroup.js +3 -0
  140. package/dist/components/input-group/index.d.ts +2 -0
  141. package/dist/components/input-group/index.js +2 -0
  142. package/dist/components/menu/Menu.d.ts +587 -0
  143. package/dist/components/menu/Menu.js +3 -0
  144. package/dist/components/menu/index.d.ts +2 -0
  145. package/dist/components/menu/index.js +2 -0
  146. package/dist/components/menubar/Menubar.d.ts +104 -0
  147. package/dist/components/menubar/Menubar.js +3 -0
  148. package/dist/components/menubar/index.d.ts +2 -0
  149. package/dist/components/menubar/index.js +2 -0
  150. package/dist/components/nav-list/NavList.d.ts +290 -0
  151. package/dist/components/nav-list/NavList.js +3 -0
  152. package/dist/components/nav-list/index.d.ts +2 -0
  153. package/dist/components/nav-list/index.js +2 -0
  154. package/dist/components/navigation-menu/NavigationMenu.d.ts +483 -0
  155. package/dist/components/navigation-menu/NavigationMenu.js +3 -0
  156. package/dist/components/navigation-menu/index.d.ts +2 -0
  157. package/dist/components/navigation-menu/index.js +2 -0
  158. package/dist/components/number-field/NumberField.d.ts +303 -0
  159. package/dist/components/number-field/NumberField.js +3 -0
  160. package/dist/components/number-field/index.d.ts +2 -0
  161. package/dist/components/number-field/index.js +2 -0
  162. package/dist/components/otp-field/OTPField.d.ts +206 -0
  163. package/dist/components/otp-field/OTPField.js +3 -0
  164. package/dist/components/otp-field/index.d.ts +2 -0
  165. package/dist/components/otp-field/index.js +2 -0
  166. package/dist/components/popover/Popover.d.ts +394 -0
  167. package/dist/components/popover/Popover.js +3 -0
  168. package/dist/components/popover/index.d.ts +2 -0
  169. package/dist/components/popover/index.js +2 -0
  170. package/dist/components/preview-card/PreviewCard.d.ts +307 -0
  171. package/dist/components/preview-card/PreviewCard.js +3 -0
  172. package/dist/components/preview-card/index.d.ts +2 -0
  173. package/dist/components/preview-card/index.js +2 -0
  174. package/dist/components/progress/Progress.d.ts +156 -0
  175. package/dist/components/progress/Progress.js +3 -0
  176. package/dist/components/progress/ProgressCircle.d.ts +166 -0
  177. package/dist/components/progress/ProgressCircle.js +3 -0
  178. package/dist/components/progress/index.d.ts +4 -0
  179. package/dist/components/progress/index.js +3 -0
  180. package/dist/components/radio/Radio.d.ts +144 -0
  181. package/dist/components/radio/Radio.js +3 -0
  182. package/dist/components/radio/index.d.ts +2 -0
  183. package/dist/components/radio/index.js +2 -0
  184. package/dist/components/resizable/Resizable.d.ts +211 -0
  185. package/dist/components/resizable/Resizable.js +3 -0
  186. package/dist/components/resizable/index.d.ts +2 -0
  187. package/dist/components/resizable/index.js +2 -0
  188. package/dist/components/scroll-area/ScrollArea.d.ts +113 -0
  189. package/dist/components/scroll-area/ScrollArea.js +3 -0
  190. package/dist/components/scroll-area/index.d.ts +2 -0
  191. package/dist/components/scroll-area/index.js +2 -0
  192. package/dist/components/select/Select.d.ts +345 -0
  193. package/dist/components/select/Select.js +3 -0
  194. package/dist/components/select/index.d.ts +2 -0
  195. package/dist/components/select/index.js +2 -0
  196. package/dist/components/separator/Separator.d.ts +75 -0
  197. package/dist/components/separator/Separator.js +3 -0
  198. package/dist/components/separator/index.d.ts +2 -0
  199. package/dist/components/separator/index.js +2 -0
  200. package/dist/components/skeleton/Skeleton.d.ts +169 -0
  201. package/dist/components/skeleton/Skeleton.js +3 -0
  202. package/dist/components/skeleton/index.d.ts +2 -0
  203. package/dist/components/skeleton/index.js +2 -0
  204. package/dist/components/slider/Slider.d.ts +208 -0
  205. package/dist/components/slider/Slider.js +3 -0
  206. package/dist/components/slider/index.d.ts +2 -0
  207. package/dist/components/slider/index.js +2 -0
  208. package/dist/components/spinner/Spinner.d.ts +92 -0
  209. package/dist/components/spinner/Spinner.js +3 -0
  210. package/dist/components/spinner/index.d.ts +2 -0
  211. package/dist/components/spinner/index.js +2 -0
  212. package/dist/components/switch/Switch.d.ts +80 -0
  213. package/dist/components/switch/Switch.js +3 -0
  214. package/dist/components/switch/index.d.ts +2 -0
  215. package/dist/components/switch/index.js +2 -0
  216. package/dist/components/tabs/Tabs.d.ts +125 -0
  217. package/dist/components/tabs/Tabs.js +3 -0
  218. package/dist/components/tabs/index.d.ts +2 -0
  219. package/dist/components/tabs/index.js +2 -0
  220. package/dist/components/textarea/Textarea.d.ts +119 -0
  221. package/dist/components/textarea/Textarea.js +3 -0
  222. package/dist/components/textarea/index.d.ts +2 -0
  223. package/dist/components/textarea/index.js +2 -0
  224. package/dist/components/toast/Toast.d.ts +517 -0
  225. package/dist/components/toast/Toast.js +3 -0
  226. package/dist/components/toast/index.d.ts +2 -0
  227. package/dist/components/toast/index.js +2 -0
  228. package/dist/components/toggle/Toggle.d.ts +171 -0
  229. package/dist/components/toggle/Toggle.js +3 -0
  230. package/dist/components/toggle/index.d.ts +2 -0
  231. package/dist/components/toggle/index.js +2 -0
  232. package/dist/components/toolbar/Toolbar.d.ts +318 -0
  233. package/dist/components/toolbar/Toolbar.js +3 -0
  234. package/dist/components/toolbar/index.d.ts +2 -0
  235. package/dist/components/toolbar/index.js +2 -0
  236. package/dist/components/tooltip/Tooltip.d.ts +361 -0
  237. package/dist/components/tooltip/Tooltip.js +3 -0
  238. package/dist/components/tooltip/index.d.ts +2 -0
  239. package/dist/components/tooltip/index.js +2 -0
  240. package/dist/index.d.ts +92 -0
  241. package/dist/index.js +86 -0
  242. package/dist/styles/Accordion.css +1 -0
  243. package/dist/styles/Alert.css +1 -0
  244. package/dist/styles/AspectRatio.css +1 -0
  245. package/dist/styles/Avatar.css +1 -0
  246. package/dist/styles/Badge.css +1 -0
  247. package/dist/styles/Breadcrumb.css +1 -0
  248. package/dist/styles/Button.css +1 -0
  249. package/dist/styles/ButtonGroup.css +1 -0
  250. package/dist/styles/Calendar.css +1 -0
  251. package/dist/styles/Checkbox.css +1 -0
  252. package/dist/styles/Collapsible.css +1 -0
  253. package/dist/styles/ColorPicker.css +1 -0
  254. package/dist/styles/Combobox.css +1 -0
  255. package/dist/styles/ContextMenu.css +1 -0
  256. package/dist/styles/DatePicker.css +1 -0
  257. package/dist/styles/Dialog.css +1 -0
  258. package/dist/styles/Drawer.css +1 -0
  259. package/dist/styles/Field.css +1 -0
  260. package/dist/styles/Fieldset.css +1 -0
  261. package/dist/styles/Form.css +1 -0
  262. package/dist/styles/Input.css +1 -0
  263. package/dist/styles/InputGroup.css +1 -0
  264. package/dist/styles/Menu.css +1 -0
  265. package/dist/styles/Menubar.css +1 -0
  266. package/dist/styles/NavList.css +1 -0
  267. package/dist/styles/NavigationMenu.css +1 -0
  268. package/dist/styles/NumberField.css +1 -0
  269. package/dist/styles/OTPField.css +1 -0
  270. package/dist/styles/Popover.css +1 -0
  271. package/dist/styles/PreviewCard.css +1 -0
  272. package/dist/styles/Progress.css +1 -0
  273. package/dist/styles/ProgressCircle.css +1 -0
  274. package/dist/styles/Radio.css +1 -0
  275. package/dist/styles/Resizable.css +1 -0
  276. package/dist/styles/ScrollArea.css +1 -0
  277. package/dist/styles/Select.css +1 -0
  278. package/dist/styles/Separator.css +1 -0
  279. package/dist/styles/Skeleton.css +1 -0
  280. package/dist/styles/Slider.css +1 -0
  281. package/dist/styles/Spinner.css +1 -0
  282. package/dist/styles/Switch.css +1 -0
  283. package/dist/styles/Tabs.css +1 -0
  284. package/dist/styles/Textarea.css +1 -0
  285. package/dist/styles/Toast.css +1 -0
  286. package/dist/styles/Toggle.css +1 -0
  287. package/dist/styles/Toolbar.css +1 -0
  288. package/dist/styles/Tooltip.css +1 -0
  289. package/dist/styles/a11y.css +119 -0
  290. package/dist/styles/layers.css +39 -0
  291. package/dist/styles/motion.css +194 -0
  292. package/dist/styles/patterns.css +236 -0
  293. package/dist/styles/properties.css +62 -0
  294. package/dist/styles/reset.css +11 -0
  295. package/dist/styles/tailwind.css +281 -0
  296. package/dist/styles/theme.css +57 -0
  297. package/dist/styles/tokens.color.css +223 -0
  298. package/dist/styles/tokens.css +460 -0
  299. package/dist/tailwind-merge.d.ts +52 -0
  300. package/dist/tailwind-merge.js +52 -0
  301. package/docs-data/props.json +8047 -0
  302. package/docs-data/theming.json +9600 -0
  303. package/docs-data/tokens.json +4070 -0
  304. package/package.json +78 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Reusable pattern classes.
3
+ *
4
+ * These are plain global class names (not CSS Modules) because components and
5
+ * consumers both need to apply them, and because the forced-colors rules below
6
+ * have to reach every surface the library renders.
7
+ */
8
+ @layer forte.patterns {
9
+ /* ------------------------------------------------------------------------
10
+ * Focus ring
11
+ *
12
+ * `outline` carries the ring rather than `box-shadow` because outline
13
+ * follows border-radius, honours outline-offset, is not clipped by an
14
+ * ancestor's overflow:hidden, and — decisively — survives forced-colors
15
+ * mode, where box-shadow is forced to `none`. The box-shadow here only
16
+ * fills the offset gap with the contrasting second tone.
17
+ * --------------------------------------------------------------------- */
18
+ .forte-focus-ring:focus-visible,
19
+ .forte-focus-ring-within:has(:focus-visible) {
20
+ outline: var(--forte-focus-ring-width) solid var(--forte-focus-ring-inner);
21
+ outline-offset: var(--forte-focus-ring-offset);
22
+ box-shadow: 0 0 0 var(--forte-focus-ring-offset) var(--forte-focus-ring-outer);
23
+ }
24
+
25
+ /* `.forte-focus-ring-within` is a statement that the WRAPPER rings on behalf of
26
+ * whatever inside it holds focus — Slider's and ColorPicker's thumbs over
27
+ * their hidden inputs, NumberField's group over its text field. So that inner
28
+ * element must not draw the UA's own ring on top, or the control wears two.
29
+ *
30
+ * The `:not()` is what keeps this from also silencing a nested part that
31
+ * legitimately rings ITSELF (NumberField's steppers sit inside its group and
32
+ * carry `.forte-focus-ring`). Written as an exclusion rather than left to
33
+ * document order because this rule and `.forte-focus-ring:focus-visible` below
34
+ * are both (0,2,0): disjoint sets settle it, a tie would not. `:where()`
35
+ * keeps the exclusion itself out of the specificity.
36
+ *
37
+ * This replaces the `outline: none` each such component used to restate. */
38
+ .forte-focus-ring-within
39
+ :where(:not(.forte-focus-ring, .forte-focus-ring-within)):focus-visible {
40
+ outline: none;
41
+ }
42
+
43
+ /* Inside a clipping context — list rows, tab strips, select items — an
44
+ * outward ring would be cut off. Invert it. */
45
+ .forte-focus-ring[data-focus-inset]:focus-visible {
46
+ outline-offset: calc(-1 * var(--forte-focus-ring-width) - 1px);
47
+ box-shadow: inset 0 0 0
48
+ calc(var(--forte-focus-ring-width) + var(--forte-focus-ring-offset))
49
+ var(--forte-focus-ring-outer);
50
+ }
51
+
52
+ /* SC 2.4.11 Focus Not Obscured: keep a focused control from scrolling to
53
+ * rest underneath sticky chrome. Apps should also set scroll-padding-block
54
+ * on their scroll container to match their header height. */
55
+ :where(.forte-focus-ring, .forte-focus-ring-within) {
56
+ scroll-margin: var(--forte-space-5, 1.5rem);
57
+ }
58
+
59
+ /* ------------------------------------------------------------------------
60
+ * Hit target — SC 2.5.8 (24x24 minimum)
61
+ * Grows the interactive area without changing the visual box.
62
+ * --------------------------------------------------------------------- */
63
+ .forte-target {
64
+ position: relative;
65
+ }
66
+
67
+ .forte-target::after {
68
+ content: "";
69
+ position: absolute;
70
+ inset: 50% auto auto 50%;
71
+ translate: -50% -50%;
72
+ width: max(100%, var(--forte-target-min));
73
+ height: max(100%, var(--forte-target-min));
74
+ }
75
+
76
+ /* ------------------------------------------------------------------------
77
+ * Scrim
78
+ * --------------------------------------------------------------------- */
79
+ .forte-scrim {
80
+ position: fixed;
81
+ inset: 0;
82
+ background-color: var(--forte-scrim-color);
83
+ transition: opacity var(--forte-duration-fast) var(--forte-ease-standard);
84
+ }
85
+
86
+ .forte-scrim[data-starting-style],
87
+ .forte-scrim[data-ending-style] {
88
+ opacity: 0;
89
+ }
90
+
91
+ @supports (backdrop-filter: blur(1px)) {
92
+ @media (prefers-reduced-transparency: no-preference) and (prefers-contrast: no-preference) {
93
+ .forte-scrim {
94
+ backdrop-filter: blur(var(--forte-scrim-blur));
95
+ }
96
+ }
97
+ }
98
+
99
+ /* ------------------------------------------------------------------------
100
+ * Floating surface
101
+ *
102
+ * The transparent border is deliberate and load-bearing. `transparent` is
103
+ * NOT preserved in forced-colors mode — it is replaced with a system colour.
104
+ * So a border that is invisible normally becomes the visible boundary that
105
+ * keeps a popup from dissolving into the page once shadows are stripped.
106
+ * --------------------------------------------------------------------- */
107
+ .forte-hc-surface {
108
+ border: 1px solid transparent;
109
+ }
110
+
111
+ .forte-icon {
112
+ fill: currentColor;
113
+ stroke: currentColor;
114
+ }
115
+
116
+ /* ------------------------------------------------------------------------
117
+ * Visually hidden, still announced.
118
+ *
119
+ * `display: none` and `visibility: hidden` remove content from the
120
+ * accessibility tree as well as from paint, which is the opposite of what
121
+ * is wanted here. The clip-path + 1px box technique keeps the text in the
122
+ * tree. `white-space: nowrap` prevents a long string collapsing to one
123
+ * character per line, which some screen readers then read letter by letter.
124
+ * --------------------------------------------------------------------- */
125
+ .forte-visually-hidden:not(:focus-within) {
126
+ position: absolute;
127
+ width: 1px;
128
+ height: 1px;
129
+ margin: -1px;
130
+ padding: 0;
131
+ overflow: hidden;
132
+ clip-path: inset(50%);
133
+ white-space: nowrap;
134
+ border: 0;
135
+ }
136
+
137
+ /* Opt out only where colour IS the information — a swatch, a chart key.
138
+ * This also disables the automatic text backplate, so anything inside must
139
+ * supply its own contrast and its own boundary. */
140
+ .forte-preserve-color {
141
+ forced-color-adjust: none;
142
+ border: 1px solid CanvasText;
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Accessibility overrides.
148
+ *
149
+ * These live in `forte.a11y`, which is ordered AFTER `forte.components`,
150
+ * so they beat component CSS by layer order alone — no specificity games, and
151
+ * no `!important`. See layers.css for why that ordering is load-bearing.
152
+ */
153
+ @layer forte.a11y {
154
+ /* ------------------------------------------------------------------------
155
+ * Forced colors (Windows High Contrast)
156
+ *
157
+ * The UA assigns system colours from NATIVE element semantics, not ARIA — a
158
+ * <div role="button"> gets no ButtonText. Base UI builds most parts from
159
+ * div/span, so the library has to assign the keywords itself.
160
+ * --------------------------------------------------------------------- */
161
+ @media (forced-colors: active) {
162
+ .forte-hc-surface {
163
+ border-color: CanvasText;
164
+ background-color: Canvas;
165
+ color: CanvasText;
166
+ }
167
+
168
+ /* The :not() is load-bearing. Without it, an element that is BOTH selected
169
+ * and disabled — a disabled Select item that happens to be the current
170
+ * value, a disabled active Tab — matches this rule at (0,1,0) and beats the
171
+ * zero-specificity disabled remedy below, so it paints as fully selected
172
+ * and never turns GrayText. Excluding disabled here makes the two rules
173
+ * cover disjoint sets instead of competing. */
174
+ :is(
175
+ .forte-hc-selected,
176
+ [data-selected],
177
+ [data-checked],
178
+ [data-highlighted],
179
+ [aria-selected="true"],
180
+ [aria-checked="true"]
181
+ ):not([data-disabled], [aria-disabled="true"], :disabled) {
182
+ background-color: Highlight;
183
+ color: HighlightText;
184
+ }
185
+
186
+ :is(.forte-hc-selected, [data-checked], [data-highlighted], [aria-selected="true"]):not(
187
+ [data-disabled], [aria-disabled="true"], :disabled
188
+ ) :where(svg, .forte-icon) {
189
+ fill: HighlightText;
190
+ stroke: HighlightText;
191
+ }
192
+
193
+ /* `opacity` is NOT overridden by forced-colors, so a 55%-opacity disabled
194
+ * control keeps full system-colour contrast and still reads as enabled.
195
+ * GrayText at full opacity is the only reliable disabled signal. */
196
+ :where([data-disabled], [aria-disabled="true"], :disabled) {
197
+ color: GrayText;
198
+ border-color: GrayText;
199
+ opacity: 1;
200
+ }
201
+
202
+ :where([data-disabled], [aria-disabled="true"], :disabled) :where(svg, .forte-icon) {
203
+ fill: GrayText;
204
+ stroke: GrayText;
205
+ }
206
+
207
+ .forte-focus-ring:focus-visible,
208
+ .forte-focus-ring-within:has(:focus-visible) {
209
+ outline: 3px solid Highlight;
210
+ outline-offset: 2px;
211
+ box-shadow: none;
212
+ }
213
+
214
+ /* Purely decorative and gradient-dependent — hide rather than show a
215
+ * meaningless system-coloured block. */
216
+ .forte-hc-decorative {
217
+ display: none;
218
+ }
219
+
220
+ .forte-scrim {
221
+ background-color: Canvas;
222
+ backdrop-filter: none;
223
+ opacity: 1;
224
+ }
225
+
226
+ .forte-link {
227
+ color: LinkText;
228
+ text-decoration: underline;
229
+ }
230
+
231
+ /* The invisible hit-target expander would otherwise paint. */
232
+ .forte-target::after {
233
+ display: none;
234
+ }
235
+ }
236
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Registered custom properties
3
+ * ---------------------------------------------------------------------------
4
+ * `@property` must live at the top level of the stylesheet — it is NOT affected
5
+ * by (and cannot be nested inside) `@layer`.
6
+ *
7
+ * Registering `--forte-accent-seed` is the single highest-value declaration in
8
+ * this file. An *unregistered* custom property holding a malformed colour makes
9
+ * every token derived from it "invalid at computed-value time": the whole ramp
10
+ * silently falls back to inheriting `color`, with no console error and no
11
+ * visual clue beyond a page that has quietly lost its palette. Registering the
12
+ * seed with a typed syntax and an initial value contains that failure to the
13
+ * one bad declaration — the other eleven steps keep working.
14
+ *
15
+ * Registration also makes these properties animatable, which is what lets the
16
+ * theme picker cross-fade between palettes instead of snapping.
17
+ */
18
+
19
+ @property --forte-accent-seed {
20
+ syntax: "<color>";
21
+ inherits: true;
22
+ initial-value: oklch(0.55 0.14 247);
23
+ }
24
+
25
+ @property --forte-secondary-seed {
26
+ syntax: "<color>";
27
+ inherits: true;
28
+ initial-value: oklch(0.58 0.15 305);
29
+ }
30
+
31
+ /* 0 = pure grey, 1 = a hue-matched sliver of the brand in every neutral. */
32
+ @property --forte-neutral-tint {
33
+ syntax: "<number>";
34
+ inherits: true;
35
+ initial-value: 1;
36
+ }
37
+
38
+ /* 1 = geometry (travel, scale, spin) allowed. 0 = suppressed. */
39
+ @property --forte-motion-ok {
40
+ syntax: "<number>";
41
+ inherits: true;
42
+ initial-value: 1;
43
+ }
44
+
45
+ /* Always (1 - motion-ok). Lets a rule fade *in* a non-motion cue. */
46
+ @property --forte-motion-off {
47
+ syntax: "<number>";
48
+ inherits: true;
49
+ initial-value: 0;
50
+ }
51
+
52
+ /* The sign of the inline axis: 1 in LTR, -1 in RTL. It exists because
53
+ * `translate` and `transform` have no logical form — a component that has to
54
+ * move something along the inline axis multiplies its (always positive)
55
+ * distance by this. Set in tokens.css from the `dir` attribute; registering it
56
+ * here gives every component a working default even when a rule for the
57
+ * current direction never matched. */
58
+ @property --forte-direction {
59
+ syntax: "<number>";
60
+ inherits: true;
61
+ initial-value: 1;
62
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Optional minimal reset for forte-ui primitives.
3
+ * Scoped into the `forte-ui` cascade layer so it never overrides consumer
4
+ * styles. Import is optional:
5
+ * import "@forte-ui/react/styles/reset.css";
6
+ */
7
+ @layer forte {
8
+ :where(.forte-reset *, .forte-reset) {
9
+ box-sizing: border-box;
10
+ }
11
+ }
@@ -0,0 +1,281 @@
1
+ /**
2
+ * forte-ui × Tailwind v4 — the token bridge.
3
+ * ---------------------------------------------------------------------------
4
+ * Import it in the stylesheet that imports Tailwind, BEFORE Tailwind itself:
5
+ *
6
+ * @import "@forte-ui/react/tailwind.css";
7
+ * @import "tailwindcss";
8
+ *
9
+ * (`theme.css` is still required, once, anywhere in the app — this file only
10
+ * teaches Tailwind the token names; it does not define the tokens.)
11
+ *
12
+ * It re-points Tailwind's theme at the forte-ui tokens, so utilities and
13
+ * components stay one system: `bg-primary` is `--forte-color-primary`, `gap-5`
14
+ * is `--forte-space-5`, `rounded-control` follows the `data-forte-radius` preset,
15
+ * and everything responds to a seed change, dark mode, and theme scopes.
16
+ *
17
+ * ---------------------------------------------------------------------------
18
+ * Why the import order is load-bearing
19
+ * ---------------------------------------------------------------------------
20
+ * The `@layer` statement below fixes the cascade-layer order at its first
21
+ * appearance, and both halves of it matter:
22
+ *
23
+ * - `forte-ui` sits AFTER `base`, or Tailwind's Preflight — which lives in
24
+ * `base` and sets `button { background: transparent }` and friends — would
25
+ * beat every component's own styles by layer order alone.
26
+ * - `forte-ui` sits BEFORE `utilities`, or `p-4` on a Button would lose to
27
+ * the button's own padding, and the library's "your CSS always wins"
28
+ * contract would silently break for utility classes specifically.
29
+ *
30
+ * Import Tailwind first and its own `theme, base, components, utilities`
31
+ * statement wins the race instead — `forte-ui` then lands after `utilities`,
32
+ * which is the second failure above. Keeping this import first costs nothing
33
+ * and settles the order for every stylesheet loaded later, including the
34
+ * per-component CSS the library's JS injects.
35
+ *
36
+ * ---------------------------------------------------------------------------
37
+ * Why `@theme inline` and not plain `@theme`
38
+ * ---------------------------------------------------------------------------
39
+ * A plain `@theme` emits `--color-primary: var(--forte-color-primary)` on
40
+ * `:root` and points utilities at *that*. But a `var()` inside an unregistered
41
+ * custom property is substituted where the property is DECLARED, so the value
42
+ * would freeze to whatever `:root` resolved — and every `.forte-theme` scope,
43
+ * `data-theme` island and `data-forte-density` / `data-forte-radius` preset would
44
+ * stop reaching the utility. `inline` substitutes the token reference into
45
+ * the utility itself (`background-color: var(--forte-color-panel)`), which
46
+ * resolves at the element. Do not drop the keyword.
47
+ *
48
+ * ---------------------------------------------------------------------------
49
+ * Why Tailwind's own scales are deleted, not extended
50
+ * ---------------------------------------------------------------------------
51
+ * Two reasons, one per failure mode:
52
+ *
53
+ * - Philosophy with teeth: with the default palette present, `bg-slate-800`
54
+ * compiles, survives review, and then ignores the seed, dark mode and
55
+ * every theme scope. Deleting the namespace turns that into a build-time
56
+ * "unknown utility" instead of a shipped bug.
57
+ * - Arithmetic: Tailwind's spacing is a multiplier (`p-13` is as valid as
58
+ * `p-4`), while forte-ui's scale is eight designed steps that go
59
+ * non-linear past 4 (5 = 1.5rem … 8 = 3rem). Mapping the eight steps while
60
+ * keeping the multiplier would leave `p-8` (3rem) LARGER than `p-9`
61
+ * (2.25rem) — replacing the scale wholesale is what keeps it monotonic.
62
+ *
63
+ * To opt back into a stock scale anyway, re-declare it in your own `@theme`
64
+ * after this import; later definitions win. The `--container-*` scale is left
65
+ * untouched on purpose — `max-w-lg` is how you say `min(32rem, 100%)`.
66
+ */
67
+
68
+ @layer theme, base, forte, components, utilities;
69
+
70
+ @theme {
71
+ --color-*: initial;
72
+ --spacing-*: initial;
73
+ --text-*: initial;
74
+ --font-*: initial;
75
+ --font-weight-*: initial;
76
+ --leading-*: initial;
77
+ --tracking-*: initial;
78
+ --radius-*: initial;
79
+ --shadow-*: initial;
80
+ --ease-*: initial;
81
+ --animate-*: initial;
82
+ }
83
+
84
+ @theme inline {
85
+ /* ------------------------------------------------------------------------
86
+ * Colour — semantic slots first. These are the names the components
87
+ * themselves consume, so anything built out of them re-themes with the
88
+ * library rather than beside it.
89
+ * --------------------------------------------------------------------- */
90
+ --color-background: var(--forte-color-background);
91
+ --color-foreground: var(--forte-color-foreground);
92
+ --color-foreground-muted: var(--forte-color-foreground-muted);
93
+ --color-foreground-subtle: var(--forte-color-foreground-subtle);
94
+
95
+ --color-panel: var(--forte-color-panel);
96
+ --color-panel-hover: var(--forte-color-panel-hover);
97
+ --color-panel-active: var(--forte-color-panel-active);
98
+ --color-overlay: var(--forte-color-overlay);
99
+
100
+ --color-border: var(--forte-color-border);
101
+ --color-border-muted: var(--forte-color-border-muted);
102
+ --color-border-strong: var(--forte-color-border-strong);
103
+
104
+ --color-primary: var(--forte-color-primary);
105
+ --color-primary-hover: var(--forte-color-primary-hover);
106
+ --color-primary-active: var(--forte-color-primary-active);
107
+ --color-primary-soft: var(--forte-color-primary-soft);
108
+ --color-primary-soft-hover: var(--forte-color-primary-soft-hover);
109
+ --color-primary-soft-active: var(--forte-color-primary-soft-active);
110
+ --color-primary-border: var(--forte-color-primary-border);
111
+ --color-primary-text: var(--forte-color-primary-text);
112
+
113
+ --color-secondary: var(--forte-color-secondary);
114
+ --color-secondary-hover: var(--forte-color-secondary-hover);
115
+ --color-secondary-active: var(--forte-color-secondary-active);
116
+ --color-secondary-soft: var(--forte-color-secondary-soft);
117
+ --color-secondary-soft-hover: var(--forte-color-secondary-soft-hover);
118
+ --color-secondary-soft-active: var(--forte-color-secondary-soft-active);
119
+ --color-secondary-border: var(--forte-color-secondary-border);
120
+ --color-secondary-text: var(--forte-color-secondary-text);
121
+
122
+ --color-danger: var(--forte-color-danger);
123
+ --color-danger-hover: var(--forte-color-danger-hover);
124
+ --color-danger-soft: var(--forte-color-danger-soft);
125
+ --color-danger-border: var(--forte-color-danger-border);
126
+ --color-danger-text: var(--forte-color-danger-text);
127
+
128
+ --color-success: var(--forte-color-success);
129
+ --color-success-text: var(--forte-color-success-text);
130
+ --color-warning: var(--forte-color-warning);
131
+ --color-warning-text: var(--forte-color-warning-text);
132
+
133
+ /* Auto-contrast text for a solid fill. `text-white` is deliberately gone;
134
+ * this is the token that stays readable when the seed moves. */
135
+ --color-on-primary: var(--forte-color-on-primary);
136
+ --color-on-secondary: var(--forte-color-on-secondary);
137
+ --color-on-danger: var(--forte-color-on-danger);
138
+
139
+ /* The raw ramps. Prefer a semantic slot above unless the step number IS the
140
+ * subject — a palette display, a bespoke chart scale. */
141
+ --color-accent-1: var(--forte-accent-1);
142
+ --color-accent-2: var(--forte-accent-2);
143
+ --color-accent-3: var(--forte-accent-3);
144
+ --color-accent-4: var(--forte-accent-4);
145
+ --color-accent-5: var(--forte-accent-5);
146
+ --color-accent-6: var(--forte-accent-6);
147
+ --color-accent-7: var(--forte-accent-7);
148
+ --color-accent-8: var(--forte-accent-8);
149
+ --color-accent-9: var(--forte-accent-9);
150
+ --color-accent-10: var(--forte-accent-10);
151
+ --color-accent-11: var(--forte-accent-11);
152
+ --color-accent-12: var(--forte-accent-12);
153
+
154
+ --color-secondary-1: var(--forte-secondary-1);
155
+ --color-secondary-2: var(--forte-secondary-2);
156
+ --color-secondary-3: var(--forte-secondary-3);
157
+ --color-secondary-4: var(--forte-secondary-4);
158
+ --color-secondary-5: var(--forte-secondary-5);
159
+ --color-secondary-6: var(--forte-secondary-6);
160
+ --color-secondary-7: var(--forte-secondary-7);
161
+ --color-secondary-8: var(--forte-secondary-8);
162
+ --color-secondary-9: var(--forte-secondary-9);
163
+ --color-secondary-10: var(--forte-secondary-10);
164
+ --color-secondary-11: var(--forte-secondary-11);
165
+ --color-secondary-12: var(--forte-secondary-12);
166
+
167
+ --color-gray-1: var(--forte-gray-1);
168
+ --color-gray-2: var(--forte-gray-2);
169
+ --color-gray-3: var(--forte-gray-3);
170
+ --color-gray-4: var(--forte-gray-4);
171
+ --color-gray-5: var(--forte-gray-5);
172
+ --color-gray-6: var(--forte-gray-6);
173
+ --color-gray-7: var(--forte-gray-7);
174
+ --color-gray-8: var(--forte-gray-8);
175
+ --color-gray-9: var(--forte-gray-9);
176
+ --color-gray-10: var(--forte-gray-10);
177
+ --color-gray-11: var(--forte-gray-11);
178
+ --color-gray-12: var(--forte-gray-12);
179
+
180
+ /* ------------------------------------------------------------------------
181
+ * Spacing — the eight steps, 1:1. `gap-5` IS `--forte-space-5` (1.5rem, not
182
+ * Tailwind's stock 1.25rem). Sizing beyond 3rem is what the untouched
183
+ * `--container-*` scale is for: `w-full max-w-lg`.
184
+ * --------------------------------------------------------------------- */
185
+ /* Zero is not a token, but `p-0` / `inset-0` / `m-0` all route through the
186
+ * spacing scale — without this key they compile to
187
+ * `calc(var(--spacing) * 0)`, which is invalid once the multiplier is gone
188
+ * and so drops the declaration entirely. It fails silently, which is the
189
+ * worst way for it to fail. */
190
+ --spacing-0: 0;
191
+
192
+ --spacing-1: var(--forte-space-1);
193
+ --spacing-2: var(--forte-space-2);
194
+ --spacing-3: var(--forte-space-3);
195
+ --spacing-4: var(--forte-space-4);
196
+ --spacing-5: var(--forte-space-5);
197
+ --spacing-6: var(--forte-space-6);
198
+ --spacing-7: var(--forte-space-7);
199
+ --spacing-8: var(--forte-space-8);
200
+
201
+ /* Surface padding is density-aware — a `data-forte-density` preset rewrites
202
+ * it — which is exactly the case `inline` exists for. The rest of the
203
+ * density family (`--forte-control-h-*`, `--forte-target-*`) has no natural
204
+ * utility name; reach for it as `h-(--forte-control-h-md)`, which resolves at
205
+ * the element for the same reason. */
206
+ --spacing-surface: var(--forte-surface-p);
207
+
208
+ /* ------------------------------------------------------------------------
209
+ * Typography.
210
+ * --------------------------------------------------------------------- */
211
+ --font-sans: var(--forte-font-sans);
212
+ --font-mono: var(--forte-font-mono);
213
+
214
+ --text-1: var(--forte-font-size-1);
215
+ --text-2: var(--forte-font-size-2);
216
+ --text-3: var(--forte-font-size-3);
217
+ --text-4: var(--forte-font-size-4);
218
+ --text-5: var(--forte-font-size-5);
219
+ --text-6: var(--forte-font-size-6);
220
+
221
+ --font-weight-normal: var(--forte-font-weight-normal);
222
+ --font-weight-medium: var(--forte-font-weight-medium);
223
+ --font-weight-semibold: var(--forte-font-weight-semibold);
224
+ --font-weight-bold: var(--forte-font-weight-bold);
225
+
226
+ --leading-tight: var(--forte-line-height-tight);
227
+ --leading-normal: var(--forte-line-height-normal);
228
+
229
+ --tracking-tight: var(--forte-letter-spacing-tight);
230
+ --tracking-normal: var(--forte-letter-spacing-normal);
231
+
232
+ /* ------------------------------------------------------------------------
233
+ * Geometry and elevation. `rounded-control` / `rounded-surface` are the
234
+ * semantic pair the `data-forte-radius` presets retarget; the numbered steps
235
+ * are the raw scale behind them.
236
+ * --------------------------------------------------------------------- */
237
+ --radius-1: var(--forte-radius-1);
238
+ --radius-2: var(--forte-radius-2);
239
+ --radius-3: var(--forte-radius-3);
240
+ --radius-4: var(--forte-radius-4);
241
+ --radius-5: var(--forte-radius-5);
242
+ --radius-6: var(--forte-radius-6);
243
+ --radius-control: var(--forte-radius-control);
244
+ --radius-surface: var(--forte-radius-surface);
245
+ --radius-pill: var(--forte-radius-pill);
246
+
247
+ --shadow-1: var(--forte-shadow-1);
248
+ --shadow-2: var(--forte-shadow-2);
249
+ --shadow-3: var(--forte-shadow-3);
250
+ --shadow-4: var(--forte-shadow-4);
251
+
252
+ /* ------------------------------------------------------------------------
253
+ * Motion. Durations and easings only — travel, scale and `--forte-motion-ok`
254
+ * stay out on purpose. Those are the tokens that collapse under reduced
255
+ * motion, and a `translate-y-*` utility built from one would need the
256
+ * `calc(... * var(--forte-motion-ok))` gate that a utility cannot carry.
257
+ * Anything that has to move writes CSS, the way a component does.
258
+ *
259
+ * Pair a spring easing with its matching duration — a shorter duration
260
+ * truncates the spring mid-bounce.
261
+ * --------------------------------------------------------------------- */
262
+ /* The namespace behind `duration-*` is `--transition-duration-*`, not
263
+ * `--duration-*` — a name that silently generates no utility at all. */
264
+ --transition-duration-instant: var(--forte-duration-instant);
265
+ --transition-duration-fast: var(--forte-duration-fast);
266
+ --transition-duration-normal: var(--forte-duration-normal);
267
+ --transition-duration-slow: var(--forte-duration-slow);
268
+ --transition-duration-move: var(--forte-duration-move);
269
+ --transition-duration-spring-gentle: var(--forte-duration-spring-gentle);
270
+ --transition-duration-spring-snappy: var(--forte-duration-spring-snappy);
271
+ --transition-duration-spring-precise: var(--forte-duration-spring-precise);
272
+ --transition-duration-spring-bouncy: var(--forte-duration-spring-bouncy);
273
+
274
+ --ease-standard: var(--forte-ease-standard);
275
+ --ease-emphasized: var(--forte-ease-emphasized);
276
+ --ease-exit: var(--forte-ease-exit);
277
+ --ease-spring-gentle: var(--forte-ease-spring-gentle);
278
+ --ease-spring-snappy: var(--forte-ease-spring-snappy);
279
+ --ease-spring-precise: var(--forte-ease-spring-precise);
280
+ --ease-spring-bouncy: var(--forte-ease-spring-bouncy);
281
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * forte-ui — the one stylesheet a consumer needs.
3
+ *
4
+ * import "@forte-ui/react/theme.css";
5
+ *
6
+ * Import it ONCE, at the root of your app, before any component. It brings in
7
+ * the cascade-layer declaration, the registered custom properties, the colour
8
+ * ramps, the semantic tokens, the motion system, the accessibility responses,
9
+ * and the shared pattern classes.
10
+ *
11
+ * ---------------------------------------------------------------------------
12
+ * Theming
13
+ * ---------------------------------------------------------------------------
14
+ * One variable re-skins everything:
15
+ *
16
+ * :root { --forte-accent-seed: #7c3aed; }
17
+ *
18
+ * All twelve accent steps, the brand-tinted neutrals, and a readable text
19
+ * colour for solid fills are derived from it, in both light and dark mode,
20
+ * with no JavaScript. Also available:
21
+ *
22
+ * --forte-secondary-seed second brand colour, same treatment
23
+ * --forte-neutral-tint 0 = pure grey ... 1 = brand-tinted greys
24
+ * data-forte-radius "none" | "soft" | "pill"
25
+ * data-forte-density "compact" | "spacious"
26
+ * data-forte-motion "reduce" | "off" | "full"
27
+ * data-theme "light" | "dark" (otherwise follows the OS)
28
+ *
29
+ * Supported seed envelope: lightness 0.45-0.90, chroma 0.02-0.30, and inside
30
+ * the sRGB gamut. Outside it the ramp still renders but the derived contrast
31
+ * guarantees no longer hold — scripts/check-contrast.mjs enforces the envelope.
32
+ *
33
+ * Scoping: apply `.forte-theme` or `data-forte-theme` to any element to re-theme
34
+ * just that subtree. The ramps are re-declared on those selectors precisely so
35
+ * this works; overriding the seed on an arbitrary element does not. The
36
+ * `data-forte-*` switches need no such hook — put one on any element and it
37
+ * applies to that element and everything under it, including nested
38
+ * `.forte-theme` scopes, until a descendant sets its own.
39
+ *
40
+ * ---------------------------------------------------------------------------
41
+ * Overriding
42
+ * ---------------------------------------------------------------------------
43
+ * Everything ships inside `@layer forte.*`, which loses to unlayered CSS.
44
+ * Your own rules and utility classes win without `!important`. The flip side
45
+ * is a documented opt-out: an unlayered `transition` or `--forte-motion-ok: 1`
46
+ * in your app will also defeat the library's reduced-motion handling.
47
+ */
48
+
49
+ /* Order matters: layers.css establishes the layer order, and properties.css
50
+ * registers custom properties that later files depend on for typed fallback. */
51
+ @import "./layers.css";
52
+ @import "./properties.css";
53
+ @import "./tokens.color.css";
54
+ @import "./tokens.css";
55
+ @import "./motion.css";
56
+ @import "./a11y.css";
57
+ @import "./patterns.css";