@cube-dev/ui-kit 0.0.0-canary-d03ae24 → 0.0.0-canary-1e93c5c

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 (451) hide show
  1. package/dist/_internal/hooks/use-chained-callback.js +1 -1
  2. package/dist/_internal/hooks/use-debounced-value.js +1 -1
  3. package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
  4. package/dist/_internal/hooks/use-event.js +1 -1
  5. package/dist/_internal/hooks/use-is-first-render.js +1 -1
  6. package/dist/_internal/hooks/use-sync-ref.js +1 -1
  7. package/dist/_internal/hooks/use-timer/timer.js +1 -1
  8. package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
  9. package/dist/_internal/hooks/use-warn.js +1 -1
  10. package/dist/components/Block.js +1 -1
  11. package/dist/components/CollectionItem.js +1 -1
  12. package/dist/components/GlobalStyles.js +1 -1
  13. package/dist/components/GridProvider.js +1 -1
  14. package/dist/components/HiddenInput.js +1 -1
  15. package/dist/components/Root.js +1 -1
  16. package/dist/components/actions/Action/Action.js +1 -1
  17. package/dist/components/actions/Banner/Banner.js +1 -1
  18. package/dist/components/actions/Button/Button.js +1 -1
  19. package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
  20. package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
  21. package/dist/components/actions/ButtonSplit/context.js +1 -1
  22. package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
  23. package/dist/components/actions/CommandMenu/styled.js +1 -1
  24. package/dist/components/actions/ItemAction/ItemAction.js +1 -1
  25. package/dist/components/actions/ItemActionContext.js +1 -1
  26. package/dist/components/actions/ItemButton/ItemButton.js +1 -1
  27. package/dist/components/actions/Link/Link.js +1 -1
  28. package/dist/components/actions/Menu/Menu.js +1 -1
  29. package/dist/components/actions/Menu/MenuItem.js +1 -1
  30. package/dist/components/actions/Menu/MenuSection.js +1 -1
  31. package/dist/components/actions/Menu/MenuTrigger.js +1 -1
  32. package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
  33. package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
  34. package/dist/components/actions/Menu/context.js +1 -1
  35. package/dist/components/actions/Menu/styled.js +1 -1
  36. package/dist/components/actions/index.js +1 -1
  37. package/dist/components/actions/use-action.js +1 -1
  38. package/dist/components/actions/use-anchored-menu.js +1 -1
  39. package/dist/components/actions/use-context-menu.js +1 -1
  40. package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
  41. package/dist/components/content/Alert/Alert.js +1 -1
  42. package/dist/components/content/Alert/use-alert.js +1 -1
  43. package/dist/components/content/Avatar/Avatar.js +1 -1
  44. package/dist/components/content/Badge/Badge.js +1 -1
  45. package/dist/components/content/Card/Card.js +1 -1
  46. package/dist/components/content/Content.js +1 -1
  47. package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
  48. package/dist/components/content/CopySnippet/CopySnippet.js +1 -1
  49. package/dist/components/content/Disclosure/Disclosure.js +1 -1
  50. package/dist/components/content/Divider.js +1 -1
  51. package/dist/components/content/Footer.js +1 -1
  52. package/dist/components/content/Header.js +1 -1
  53. package/dist/components/content/HotKeys/HotKeys.js +1 -1
  54. package/dist/components/content/InlineInput/InlineInput.js +1 -1
  55. package/dist/components/content/Item/Item.js +1 -1
  56. package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
  57. package/dist/components/content/ItemCard/ItemCard.js +1 -1
  58. package/dist/components/content/Layout/GridLayout.js +1 -1
  59. package/dist/components/content/Layout/Layout.js +1 -1
  60. package/dist/components/content/Layout/LayoutBlock.js +1 -1
  61. package/dist/components/content/Layout/LayoutCenter.js +1 -1
  62. package/dist/components/content/Layout/LayoutContainer.js +1 -1
  63. package/dist/components/content/Layout/LayoutContent.js +1 -1
  64. package/dist/components/content/Layout/LayoutContext.js +1 -1
  65. package/dist/components/content/Layout/LayoutFlex.js +1 -1
  66. package/dist/components/content/Layout/LayoutFooter.js +1 -1
  67. package/dist/components/content/Layout/LayoutGrid.js +1 -1
  68. package/dist/components/content/Layout/LayoutHeader.js +1 -1
  69. package/dist/components/content/Layout/LayoutPane.js +1 -1
  70. package/dist/components/content/Layout/LayoutPanel.js +1 -1
  71. package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
  72. package/dist/components/content/Layout/LayoutToolbar.js +1 -1
  73. package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
  74. package/dist/components/content/Layout/index.js +1 -1
  75. package/dist/components/content/Layout/utils.js +1 -1
  76. package/dist/components/content/Paragraph.js +1 -1
  77. package/dist/components/content/Placeholder/Placeholder.js +1 -1
  78. package/dist/components/content/PrismCode/PrismCode.js +1 -1
  79. package/dist/components/content/PrismCode/prismSetup.js +1 -1
  80. package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
  81. package/dist/components/content/Result/Result.js +1 -1
  82. package/dist/components/content/Skeleton/Skeleton.js +1 -1
  83. package/dist/components/content/Tag/Tag.js +1 -1
  84. package/dist/components/content/Text.d.ts +7 -7
  85. package/dist/components/content/Text.js +1 -1
  86. package/dist/components/content/TextItem/TextItem.js +1 -1
  87. package/dist/components/content/Title.js +1 -1
  88. package/dist/components/content/Tree/Tree.js +1 -1
  89. package/dist/components/content/Tree/TreeNode.js +1 -1
  90. package/dist/components/content/Tree/styled.js +1 -1
  91. package/dist/components/content/Tree/tree-index.js +1 -1
  92. package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
  93. package/dist/components/content/Tree/use-load-data.js +1 -1
  94. package/dist/components/content/highlightText.js +1 -1
  95. package/dist/components/content/use-auto-tooltip.js +1 -1
  96. package/dist/components/fields/Checkbox/Checkbox.js +1 -1
  97. package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
  98. package/dist/components/fields/Checkbox/context.js +1 -1
  99. package/dist/components/fields/ComboBox/ComboBox.js +1 -1
  100. package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
  101. package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
  102. package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
  103. package/dist/components/fields/DatePicker/DateInput.js +1 -1
  104. package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
  105. package/dist/components/fields/DatePicker/DatePicker.js +1 -1
  106. package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
  107. package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
  108. package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
  109. package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
  110. package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
  111. package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
  112. package/dist/components/fields/DatePicker/TimeInput.js +1 -1
  113. package/dist/components/fields/DatePicker/intl.js +1 -1
  114. package/dist/components/fields/DatePicker/parseDate.js +1 -1
  115. package/dist/components/fields/DatePicker/props.js +1 -1
  116. package/dist/components/fields/DatePicker/utils.js +1 -1
  117. package/dist/components/fields/FileInput/FileInput.js +1 -1
  118. package/dist/components/fields/FilterListBox/FilterListBox.js +1 -1
  119. package/dist/components/fields/FilterPicker/FilterPicker.js +1 -1
  120. package/dist/components/fields/Input/Input.js +1 -1
  121. package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
  122. package/dist/components/fields/ListBox/ListBox.js +1 -1
  123. package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -1
  124. package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
  125. package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
  126. package/dist/components/fields/NumberInput/NumberInput.js +1 -1
  127. package/dist/components/fields/NumberInput/StepButton.js +1 -1
  128. package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
  129. package/dist/components/fields/Picker/Picker.js +1 -1
  130. package/dist/components/fields/RadioGroup/Radio.js +1 -1
  131. package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
  132. package/dist/components/fields/RadioGroup/context.js +1 -1
  133. package/dist/components/fields/SearchInput/SearchInput.js +1 -1
  134. package/dist/components/fields/Select/Select.js +1 -1
  135. package/dist/components/fields/Slider/Gradation.js +1 -1
  136. package/dist/components/fields/Slider/HueSlider.js +1 -1
  137. package/dist/components/fields/Slider/RangeSlider.js +1 -1
  138. package/dist/components/fields/Slider/Slider.js +1 -1
  139. package/dist/components/fields/Slider/SliderBase.js +1 -1
  140. package/dist/components/fields/Slider/SliderThumb.js +1 -1
  141. package/dist/components/fields/Slider/SliderTrack.js +1 -1
  142. package/dist/components/fields/Slider/elements.js +1 -1
  143. package/dist/components/fields/Slider/index.js +1 -1
  144. package/dist/components/fields/Switch/Switch.js +1 -1
  145. package/dist/components/fields/TextArea/TextArea.js +1 -1
  146. package/dist/components/fields/TextInput/TextInput.js +1 -1
  147. package/dist/components/fields/TextInput/TextInputBase.js +1 -1
  148. package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
  149. package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
  150. package/dist/components/form/FieldWrapper/extract-field-wrapper-props.js +1 -1
  151. package/dist/components/form/Form/Field.js +1 -1
  152. package/dist/components/form/Form/Form.js +1 -1
  153. package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
  154. package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
  155. package/dist/components/form/Form/SubmitError.js +1 -1
  156. package/dist/components/form/Form/index.js +1 -1
  157. package/dist/components/form/Form/use-field/use-field-props.js +1 -1
  158. package/dist/components/form/Form/use-field/use-field.js +1 -1
  159. package/dist/components/form/Form/use-form.js +1 -1
  160. package/dist/components/form/Form/validation.js +1 -1
  161. package/dist/components/form/Label.js +1 -1
  162. package/dist/components/form/wrapper.js +1 -1
  163. package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
  164. package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
  165. package/dist/components/layout/Board/Board.js +18 -1
  166. package/dist/components/layout/Board/Board.js.map +1 -1
  167. package/dist/components/layout/Board/BoardProvider.js +1 -1
  168. package/dist/components/layout/Board/BoardResponsive.js +1 -1
  169. package/dist/components/layout/Board/Widget.js +1 -1
  170. package/dist/components/layout/Board/WidgetHost.js +6 -4
  171. package/dist/components/layout/Board/WidgetHost.js.map +1 -1
  172. package/dist/components/layout/Board/board-context.js +1 -1
  173. package/dist/components/layout/Board/board-store.js +1 -1
  174. package/dist/components/layout/Board/grid-core/calculate.js +1 -1
  175. package/dist/components/layout/Board/grid-core/collision.js +1 -1
  176. package/dist/components/layout/Board/grid-core/compactors.js +1 -1
  177. package/dist/components/layout/Board/grid-core/constraints.js +1 -1
  178. package/dist/components/layout/Board/grid-core/layout.js +1 -1
  179. package/dist/components/layout/Board/grid-core/sort.js +1 -1
  180. package/dist/components/layout/Board/index.js +1 -1
  181. package/dist/components/layout/Board/responsive-utils.js +1 -1
  182. package/dist/components/layout/Board/use-board-layout.js +1 -1
  183. package/dist/components/layout/Board/use-board-registry.js +17 -12
  184. package/dist/components/layout/Board/use-board-registry.js.map +1 -1
  185. package/dist/components/layout/Flex.js +1 -1
  186. package/dist/components/layout/Flow.js +1 -1
  187. package/dist/components/layout/Grid.js +1 -1
  188. package/dist/components/layout/Panel.js +1 -1
  189. package/dist/components/layout/Prefix.js +1 -1
  190. package/dist/components/layout/ResizablePanel.js +1 -1
  191. package/dist/components/layout/Space.js +1 -1
  192. package/dist/components/layout/Suffix.js +1 -1
  193. package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
  194. package/dist/components/navigation/Tabs/TabButton.js +1 -1
  195. package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
  196. package/dist/components/navigation/Tabs/TabPanel.js +1 -1
  197. package/dist/components/navigation/Tabs/TabPicker.js +1 -1
  198. package/dist/components/navigation/Tabs/Tabs.js +1 -1
  199. package/dist/components/navigation/Tabs/TabsAction.js +1 -1
  200. package/dist/components/navigation/Tabs/TabsContext.js +1 -1
  201. package/dist/components/navigation/Tabs/popover-placement.js +1 -1
  202. package/dist/components/navigation/Tabs/styled.js +1 -1
  203. package/dist/components/navigation/Tabs/types.js +1 -1
  204. package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
  205. package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
  206. package/dist/components/organisms/FileTabs/FileTabs.js +1 -1
  207. package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
  208. package/dist/components/other/Calendar/Calendar.js +1 -1
  209. package/dist/components/other/Calendar/CalendarCell.js +1 -1
  210. package/dist/components/other/Calendar/CalendarGrid.js +1 -1
  211. package/dist/components/other/Calendar/RangeCalendar.js +1 -1
  212. package/dist/components/other/CloudLogo/CloudLogo.js +1 -1
  213. package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
  214. package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
  215. package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
  216. package/dist/components/overlays/Dialog/Dialog.js +1 -1
  217. package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
  218. package/dist/components/overlays/Dialog/DialogForm.js +1 -1
  219. package/dist/components/overlays/Dialog/DialogTrigger.js +1 -1
  220. package/dist/components/overlays/Dialog/context.js +1 -1
  221. package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
  222. package/dist/components/overlays/Modal/Modal.js +1 -1
  223. package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
  224. package/dist/components/overlays/Modal/Overlay.js +1 -1
  225. package/dist/components/overlays/Modal/Popover.js +1 -1
  226. package/dist/components/overlays/Modal/Tray.js +1 -1
  227. package/dist/components/overlays/Modal/Underlay.js +1 -1
  228. package/dist/components/overlays/Notifications/Notification.js +1 -1
  229. package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
  230. package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
  231. package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
  232. package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
  233. package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
  234. package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
  235. package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
  236. package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
  237. package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
  238. package/dist/components/overlays/Notifications/index.js +1 -1
  239. package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
  240. package/dist/components/overlays/Notifications/use-notifications.js +1 -1
  241. package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
  242. package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
  243. package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
  244. package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
  245. package/dist/components/overlays/Toast/ToastItem.js +1 -1
  246. package/dist/components/overlays/Toast/index.js +1 -1
  247. package/dist/components/overlays/Toast/useProgressToast.js +1 -1
  248. package/dist/components/overlays/Toast/useToast.js +1 -1
  249. package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
  250. package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
  251. package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
  252. package/dist/components/overlays/Tooltip/context.js +1 -1
  253. package/dist/components/portal/Portal.js +1 -1
  254. package/dist/components/portal/PortalProvider.js +1 -1
  255. package/dist/components/portal/usePortal.js +1 -1
  256. package/dist/components/shared/DraggableCollection.js +1 -1
  257. package/dist/components/shared/InvalidIcon.js +1 -1
  258. package/dist/components/shared/ValidIcon.js +1 -1
  259. package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
  260. package/dist/components/status/Spin/Cube.js +1 -1
  261. package/dist/components/status/Spin/InternalSpinner.js +1 -1
  262. package/dist/components/status/Spin/Spin.js +1 -1
  263. package/dist/components/status/Spin/SpinsContainer.js +1 -1
  264. package/dist/data/item-themes.js +1 -1
  265. package/dist/data/themes.js +1 -1
  266. package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
  267. package/dist/icons/AdjustmentsIcon.js +1 -1
  268. package/dist/icons/AiIcon.js +1 -1
  269. package/dist/icons/AreaChartIcon.js +1 -1
  270. package/dist/icons/BackwardIcon.js +1 -1
  271. package/dist/icons/BarChartIcon.js +1 -1
  272. package/dist/icons/BellFilledIcon.js +1 -1
  273. package/dist/icons/BellIcon.js +1 -1
  274. package/dist/icons/BooleanIcon.js +1 -1
  275. package/dist/icons/CalendarEditIcon.js +1 -1
  276. package/dist/icons/CalendarIcon.js +1 -1
  277. package/dist/icons/CaretDownIcon.js +1 -1
  278. package/dist/icons/CaretUpIcon.js +1 -1
  279. package/dist/icons/ChartAreaStackedIcon.js +1 -1
  280. package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
  281. package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
  282. package/dist/icons/ChartBarGroupedIcon.js +1 -1
  283. package/dist/icons/ChartBarHorizontalIcon.js +1 -1
  284. package/dist/icons/ChartBarLineIcon.js +1 -1
  285. package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
  286. package/dist/icons/ChartBarStackedIcon.js +1 -1
  287. package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
  288. package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
  289. package/dist/icons/ChartBoxPlot2Icon.js +1 -1
  290. package/dist/icons/ChartBoxPlotIcon.js +1 -1
  291. package/dist/icons/ChartBubbleIcon.js +1 -1
  292. package/dist/icons/ChartDonut2Icon.js +1 -1
  293. package/dist/icons/ChartFunnelIcon.js +1 -1
  294. package/dist/icons/ChartHeatmapIcon.js +1 -1
  295. package/dist/icons/ChartKPIIcon.js +1 -1
  296. package/dist/icons/ChartPie2Icon.js +1 -1
  297. package/dist/icons/ChartScatterIcon.js +1 -1
  298. package/dist/icons/CheckCircleFilledIcon.js +1 -1
  299. package/dist/icons/CheckCircleIcon.js +1 -1
  300. package/dist/icons/CheckIcon.js +1 -1
  301. package/dist/icons/CircleFilledIcon.js +1 -1
  302. package/dist/icons/ClearIcon.js +1 -1
  303. package/dist/icons/CloseCircleFilledIcon.js +1 -1
  304. package/dist/icons/CloseCircleIcon.js +1 -1
  305. package/dist/icons/CloseIcon.js +1 -1
  306. package/dist/icons/CodeIcon.js +1 -1
  307. package/dist/icons/ColumnTotalIcon.js +1 -1
  308. package/dist/icons/CopyIcon.js +1 -1
  309. package/dist/icons/CountIcon.js +1 -1
  310. package/dist/icons/CubeIcon.js +1 -1
  311. package/dist/icons/CubePauseIcon.js +1 -1
  312. package/dist/icons/CubePlayIcon.js +1 -1
  313. package/dist/icons/CurrencyDollarIcon.js +1 -1
  314. package/dist/icons/DangerIcon.js +1 -1
  315. package/dist/icons/DashboardIcon.js +1 -1
  316. package/dist/icons/DatabaseIcon.js +1 -1
  317. package/dist/icons/DecimalDecreaseIcon.js +1 -1
  318. package/dist/icons/DecimalIncreaseIcon.js +1 -1
  319. package/dist/icons/DirectionIcon.js +1 -1
  320. package/dist/icons/DonutIcon.js +1 -1
  321. package/dist/icons/DownIcon.js +1 -1
  322. package/dist/icons/EditIcon.js +1 -1
  323. package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
  324. package/dist/icons/ExclamationCircleIcon.js +1 -1
  325. package/dist/icons/ExclamationIcon.js +1 -1
  326. package/dist/icons/EyeIcon.js +1 -1
  327. package/dist/icons/EyeInvisibleIcon.js +1 -1
  328. package/dist/icons/FilterIcon.js +1 -1
  329. package/dist/icons/FolderFilledIcon.js +1 -1
  330. package/dist/icons/FolderIcon.js +1 -1
  331. package/dist/icons/FolderOpenFilledIcon.js +1 -1
  332. package/dist/icons/FolderOpenIcon.js +1 -1
  333. package/dist/icons/ForwardIcon.js +1 -1
  334. package/dist/icons/GripVerticalIcon.js +1 -1
  335. package/dist/icons/HierarchyIcon.js +1 -1
  336. package/dist/icons/HierarchyOpenIcon.js +1 -1
  337. package/dist/icons/Icon.js +1 -1
  338. package/dist/icons/InfoCircleIcon.js +1 -1
  339. package/dist/icons/InfoIcon.js +1 -1
  340. package/dist/icons/KeyIcon.js +1 -1
  341. package/dist/icons/LeftIcon.js +1 -1
  342. package/dist/icons/LineChartIcon.js +1 -1
  343. package/dist/icons/LoadingIcon.js +1 -1
  344. package/dist/icons/LockFilledIcon.js +1 -1
  345. package/dist/icons/LockIcon.js +1 -1
  346. package/dist/icons/MoreIcon.js +1 -1
  347. package/dist/icons/NotAllowedIcon.js +1 -1
  348. package/dist/icons/Number123Icon.js +1 -1
  349. package/dist/icons/NumberIcon.js +1 -1
  350. package/dist/icons/PauseCircleFilledIcon.js +1 -1
  351. package/dist/icons/PauseCircleIcon.js +1 -1
  352. package/dist/icons/PauseIcon.js +1 -1
  353. package/dist/icons/PercentageIcon.js +1 -1
  354. package/dist/icons/PieChartIcon.js +1 -1
  355. package/dist/icons/PlayCircleIcon.js +1 -1
  356. package/dist/icons/PlayIcon.js +1 -1
  357. package/dist/icons/PlusIcon.js +1 -1
  358. package/dist/icons/ProgressBarIcon.js +1 -1
  359. package/dist/icons/ReloadIcon.js +1 -1
  360. package/dist/icons/ReportIcon.js +1 -1
  361. package/dist/icons/ReturnIcon.js +1 -1
  362. package/dist/icons/RightIcon.js +1 -1
  363. package/dist/icons/RowTotalsIcon.js +1 -1
  364. package/dist/icons/SchemeIcon.js +1 -1
  365. package/dist/icons/SearchIcon.js +1 -1
  366. package/dist/icons/SemanticQueryIcon.js +1 -1
  367. package/dist/icons/SettingsIcon.js +1 -1
  368. package/dist/icons/ShieldFilledIcon.js +1 -1
  369. package/dist/icons/ShieldIcon.js +1 -1
  370. package/dist/icons/SlashIcon.js +1 -1
  371. package/dist/icons/SparklesIcon.js +1 -1
  372. package/dist/icons/SqlIcon.js +1 -1
  373. package/dist/icons/StatsIcon.js +1 -1
  374. package/dist/icons/StopIcon.js +1 -1
  375. package/dist/icons/StringIcon.js +1 -1
  376. package/dist/icons/SubtotalsIcon.js +1 -1
  377. package/dist/icons/SwitchIcon.js +1 -1
  378. package/dist/icons/TableIcon.js +1 -1
  379. package/dist/icons/ThumbsDownIcon.js +1 -1
  380. package/dist/icons/ThumbsUpIcon.js +1 -1
  381. package/dist/icons/ThunderboltCrossedIcon.js +1 -1
  382. package/dist/icons/ThunderboltFilledIcon.js +1 -1
  383. package/dist/icons/ThunderboltIcon.js +1 -1
  384. package/dist/icons/TimeIcon.js +1 -1
  385. package/dist/icons/TrashIcon.js +1 -1
  386. package/dist/icons/UnlockIcon.js +1 -1
  387. package/dist/icons/UpIcon.js +1 -1
  388. package/dist/icons/UserGroupIcon.js +1 -1
  389. package/dist/icons/UserIcon.js +1 -1
  390. package/dist/icons/UserLockIcon.js +1 -1
  391. package/dist/icons/ViewIcon.js +1 -1
  392. package/dist/icons/WarningFilledIcon.js +1 -1
  393. package/dist/icons/WarningIcon.js +1 -1
  394. package/dist/icons/wrap-icon.js +1 -1
  395. package/dist/index.js +1 -1
  396. package/dist/provider.js +1 -1
  397. package/dist/providers/TrackingProvider.js +1 -1
  398. package/dist/providers/navigationAdapter.default.js +1 -1
  399. package/dist/tokens/base.js +1 -1
  400. package/dist/tokens/colors.js +2 -1
  401. package/dist/tokens/colors.js.map +1 -1
  402. package/dist/tokens/index.js +1 -1
  403. package/dist/tokens/layout.js +1 -1
  404. package/dist/tokens/palette.js +105 -105
  405. package/dist/tokens/palette.js.map +1 -1
  406. package/dist/tokens/shadows.js +1 -1
  407. package/dist/tokens/sizes.js +1 -1
  408. package/dist/tokens/spacing.js +1 -1
  409. package/dist/tokens/typography.js +1 -1
  410. package/dist/utils/ResizeSensor.js +1 -1
  411. package/dist/utils/is-dev-env.js +1 -1
  412. package/dist/utils/modules.js +1 -1
  413. package/dist/utils/promise.js +1 -1
  414. package/dist/utils/raf.js +1 -1
  415. package/dist/utils/random.js +1 -1
  416. package/dist/utils/range.js +1 -1
  417. package/dist/utils/react/RenderCache.js +1 -1
  418. package/dist/utils/react/Slots.js +1 -1
  419. package/dist/utils/react/chain.js +1 -1
  420. package/dist/utils/react/forwardRefWithGenerics.js +1 -1
  421. package/dist/utils/react/index.js +1 -1
  422. package/dist/utils/react/interactions.js +1 -1
  423. package/dist/utils/react/isTextOnly.js +1 -1
  424. package/dist/utils/react/mapProps.js +1 -1
  425. package/dist/utils/react/mergeProps.js +1 -1
  426. package/dist/utils/react/nullableValue.js +1 -1
  427. package/dist/utils/react/resolveIcon.js +1 -1
  428. package/dist/utils/react/sharedStore.js +1 -1
  429. package/dist/utils/react/useCombinedRefs.js +1 -1
  430. package/dist/utils/react/useControlledFocusVisible.js +1 -1
  431. package/dist/utils/react/useEventBus.js +1 -1
  432. package/dist/utils/react/useId.js +1 -1
  433. package/dist/utils/react/useIsDarwin.js +1 -1
  434. package/dist/utils/react/useKeySymbols.js +1 -1
  435. package/dist/utils/react/useLayoutEffect.js +1 -1
  436. package/dist/utils/react/useLocalStorage.js +1 -1
  437. package/dist/utils/react/useMergeStyles.js +1 -1
  438. package/dist/utils/react/usePopoverSync.js +1 -1
  439. package/dist/utils/react/useQaProps.js +1 -1
  440. package/dist/utils/react/useViewportSize.js +1 -1
  441. package/dist/utils/react/wrapNodeIfPlain.js +1 -1
  442. package/dist/utils/selection.js +1 -1
  443. package/dist/utils/styles.js +1 -1
  444. package/dist/utils/tree.js +1 -1
  445. package/dist/utils/warnings.js +1 -1
  446. package/dist/version.js +3 -3
  447. package/docs/glaze/api.md +150 -510
  448. package/docs/glaze/methodology.md +213 -438
  449. package/docs/glaze/migration.md +14 -152
  450. package/package.json +3 -3
  451. package/docs/glaze/okhst.md +0 -308
package/docs/glaze/api.md CHANGED
@@ -39,7 +39,7 @@ const d = glaze.fromRgb(122, 77, 191);
39
39
  const e = glaze.from(a.export());
40
40
 
41
41
  // Per-theme config override:
42
- const rawTheme = glaze(280, 80, { lightTone: false, darkTone: false });
42
+ const rawTheme = glaze(280, 80, { lightLightness: false, darkLightness: false });
43
43
  ```
44
44
 
45
45
  The optional `config` parameter is a `GlazeConfigOverride` — see [Per-instance config override](#per-instance-config-override).
@@ -72,15 +72,15 @@ A `GlazeTheme` exposes:
72
72
  ### `theme.colors(defs)`
73
73
 
74
74
  ```ts
75
- theme.colors({ surface: { tone: 97 } });
76
- theme.colors({ text: { tone: 30 } });
75
+ theme.colors({ surface: { lightness: 97 } });
76
+ theme.colors({ text: { lightness: 30 } });
77
77
  // Both 'surface' and 'text' are now defined.
78
78
  ```
79
79
 
80
80
  ### `theme.color(name) / theme.color(name, def)`
81
81
 
82
82
  ```ts
83
- theme.color('surface', { tone: 97, saturation: 0.75 }); // set
83
+ theme.color('surface', { lightness: 97, saturation: 0.75 }); // set
84
84
  const def = theme.color('surface'); // get
85
85
  ```
86
86
 
@@ -91,11 +91,11 @@ Creates a new theme inheriting all color definitions, optionally replacing the h
91
91
  ```ts
92
92
  const danger = primary.extend({
93
93
  hue: 23,
94
- colors: { 'accent-fill': { tone: 48, mode: 'fixed' } },
94
+ colors: { 'accent-fill': { lightness: 48, mode: 'fixed' } },
95
95
  });
96
96
 
97
- // Inherit parent's config override and widen the dark window further:
98
- const highSat = base.extend({ config: { darkTone: [10, 100] } });
97
+ // Inherit parent's config override and tighten the dark window further:
98
+ const highSat = base.extend({ config: { darkLightness: [10, 100] } });
99
99
  ```
100
100
 
101
101
  `GlazeExtendOptions`:
@@ -115,14 +115,14 @@ Flat token map grouped by scheme variant.
115
115
 
116
116
  ```ts
117
117
  theme.tokens()
118
- // → { light: { surface: 'oklch(...)' }, dark: { surface: 'oklch(...)' } }
118
+ // → { light: { surface: 'okhsl(...)' }, dark: { surface: 'okhsl(...)' } }
119
119
  ```
120
120
 
121
121
  `GlazeJsonOptions`:
122
122
 
123
123
  | Option | Default | Description |
124
124
  |---|---|---|
125
- | `format` | `'oklch'` | Output color format. One of `'rgb' \| 'hsl' \| 'oklch'`. `'okhsl'` and `'okhst'` throw — use `tasty()` for those. |
125
+ | `format` | `'okhsl'` | Output color format. One of `'okhsl' \| 'rgb' \| 'hsl' \| 'oklch'`. |
126
126
  | `modes` | `{ dark: true, highContrast: false }` (or global config) | Which scheme variants to include. |
127
127
 
128
128
  ### `theme.tasty(options?)`
@@ -141,12 +141,10 @@ theme.tasty()
141
141
 
142
142
  | Option | Default | Description |
143
143
  |---|---|---|
144
- | `format` | `'okhsl'` | Output color format. `'okhsl'` and `'okhst'` are supported here (Tasty-only spaces). |
144
+ | `format` | `'okhsl'` | Output color format. |
145
145
  | `modes` | global config | Which scheme variants to include. |
146
146
  | `states.dark` | `'@dark'` (or global config) | State alias for dark mode tokens. |
147
147
  | `states.highContrast` | `'@high-contrast'` (or global config) | State alias for high-contrast tokens. |
148
- | `splitHue` | `false` | Emit hue as a separate custom property (`$name-hue` token + `var()` in `oklch` values). Requires `format: 'oklch'` and every color to be pastel. |
149
- | `name` | `'theme'` | Base name for the theme-level hue var (`$theme-hue` / `--theme-hue`). Palette export auto-derives this from the theme name. |
150
148
  | `prefix` | (palette only) | See [Palette](#palette). |
151
149
 
152
150
  When both `dark` and `highContrast` modes are enabled, dark high-contrast variants are emitted under the combined key `<dark> & <highContrast>` (e.g. `'@dark & @high-contrast'`).
@@ -158,8 +156,8 @@ Per-color JSON map.
158
156
  ```ts
159
157
  theme.json()
160
158
  // → {
161
- // surface: { light: 'oklch(...)', dark: 'oklch(...)' },
162
- // text: { light: 'oklch(...)', dark: 'oklch(...)' },
159
+ // surface: { light: 'okhsl(...)', dark: 'okhsl(...)' },
160
+ // text: { light: 'okhsl(...)', dark: 'okhsl(...)' },
163
161
  // }
164
162
  ```
165
163
 
@@ -183,137 +181,11 @@ theme.css();
183
181
 
184
182
  | Option | Default | Description |
185
183
  |---|---|---|
186
- | `format` | `'rgb'` | Output color format. `'okhsl'` and `'okhst'` throw — use `tasty()` for those. |
184
+ | `format` | `'rgb'` | Output color format. |
187
185
  | `suffix` | `'-color'` | Suffix appended to each CSS property name. Pass `''` for bare property names. |
188
- | `splitHue` | `false` | Emit hue as a separate `--*-hue` custom property referenced via `var()` in `oklch` color values. Requires `format: 'oklch'` and every color to be pastel. Shadow/mix colors stay inline (blended hue; they do not follow `--hue` rotation). |
189
- | `name` | `'theme'` | Base name for the theme-level hue var (`--theme-hue`). Palette export auto-derives this from the theme name. |
190
186
 
191
187
  `GlazeCssResult` always contains all four keys (`light`, `dark`, `lightContrast`, `darkContrast`); empty if no colors are defined for that variant.
192
188
 
193
- ### `theme.dtcg(options?)`
194
-
195
- W3C [Design Tokens Format Module (2025.10)](https://www.designtokens.org/) documents — the vendor-neutral JSON format consumed by Figma, Tokens Studio, Style Dictionary v4+, Terrazzo, Penpot, and every DTCG-compatible tool. Returns one spec-conformant token tree per scheme variant.
196
-
197
- ```ts
198
- theme.dtcg()
199
- // → {
200
- // light: {
201
- // surface: {
202
- // $type: 'color',
203
- // $value: { colorSpace: 'srgb', components: [0.96, 0.94, 0.98], hex: '#f5f0fa' },
204
- // },
205
- // },
206
- // dark: {
207
- // surface: {
208
- // $type: 'color',
209
- // $value: { colorSpace: 'srgb', components: [0.16, 0.14, 0.2], hex: '#292333' },
210
- // },
211
- // },
212
- // }
213
- ```
214
-
215
- Write each document to its own `.tokens.json` file — one file per scheme is the most tool-compatible convention (one per Style Dictionary theme / Tokens Studio set / Figma variable mode).
216
-
217
- `GlazeDtcgOptions`:
218
-
219
- | Option | Default | Description |
220
- |---|---|---|
221
- | `colorSpace` | `'srgb'` | Color space for `$value`. `'srgb'` emits gamma sRGB `components` (0–1) plus a `hex` hint — universally understood. `'oklch'` emits `[L, C, H]` components with no hex — Glaze-native, wide-gamut. |
222
- | `modes` | global config | Which scheme variants to include. `light` is always present. |
223
-
224
- `alpha` is included on `$value` only when the color's opacity is below 1. `$type` is always `'color'`.
225
-
226
- ### `theme.dtcgResolver(options?)`
227
-
228
- A single W3C [DTCG Resolver-Module](https://www.designtokens.org/) document describing **every scheme variant in one file** — an alternative to `dtcg()`'s per-scheme files for tools that resolve sets + modifiers (e.g. Dispersa). The light document becomes `sets.base.sources[0]` (the default context); each other variant becomes a context override on a single `scheme` modifier.
229
-
230
- ```ts
231
- theme.dtcgResolver({ modes: { highContrast: true } })
232
- // → {
233
- // version: '2025.10',
234
- // sets: {
235
- // base: {
236
- // sources: [
237
- // {
238
- // surface: {
239
- // $type: 'color',
240
- // $value: { colorSpace: 'srgb', components: [0.96, 0.94, 0.98], hex: '#f5f0fa' },
241
- // },
242
- // },
243
- // ],
244
- // },
245
- // },
246
- // modifiers: {
247
- // scheme: {
248
- // default: 'light',
249
- // contexts: {
250
- // light: [],
251
- // dark: [
252
- // {
253
- // surface: {
254
- // $type: 'color',
255
- // $value: { colorSpace: 'srgb', components: [0.16, 0.14, 0.2], hex: '#292333' },
256
- // },
257
- // },
258
- // ],
259
- // lightContrast: [ /* … */ ],
260
- // darkContrast: [ /* … */ ],
261
- // },
262
- // },
263
- // },
264
- // resolutionOrder: [
265
- // { $ref: '#/sets/base' },
266
- // { $ref: '#/modifiers/scheme' },
267
- // ],
268
- // }
269
- ```
270
-
271
- **Why one modifier with four contexts.** Glaze resolves `darkContrast` independently — it is not `dark` + `lightContrast` layered. The resolver model composes modifiers additively (last in `resolutionOrder` wins on conflict), so two independent modifiers (`scheme` × `contrast`) would produce wrong values for the dark + high-contrast permutation. One `scheme` modifier with a context per variant keeps every resolved value exact. Choose `dtcgResolver()` when you want single-file theming and feed it to a resolver tool; choose `dtcg()` for maximum per-file tool compatibility.
272
-
273
- `GlazeDtcgResolverOptions` (extends `GlazeDtcgOptions`, so `modes` and `colorSpace` pass through):
274
-
275
- | Option | Default | Description |
276
- |---|---|---|
277
- | `colorSpace` | `'srgb'` | Same as `dtcg()` — flows through to every source and context. |
278
- | `modes` | global config | Which scheme variants to emit as contexts. `light` is always present (the default); absent variants are omitted. |
279
- | `setName` | `'base'` | Name of the single set holding the default (light) token tree. |
280
- | `modifierName` | `'scheme'` | Name of the modifier describing the scheme axis. |
281
- | `contextNames` | identity | Override the four context names (`light` / `dark` / `lightContrast` / `darkContrast`) — e.g. `{ dark: 'night' }`. |
282
- | `version` | `'2025.10'` | Resolver document version. |
283
-
284
- ### `theme.tailwind(options?)`
285
-
286
- A Tailwind CSS v4 `@theme` block (light baseline) plus dark / high-contrast overrides under configurable selectors. Returns a single ready-to-paste CSS string. The `--color-*` namespace auto-generates `bg-*` / `text-*` / `border-*` utilities.
287
-
288
- ```css
289
- @theme {
290
- --color-surface: oklch(0.96 0.01 280);
291
- --color-text: oklch(0.3 0.05 280);
292
- }
293
- .dark {
294
- --color-surface: oklch(0.16 0.01 280);
295
- --color-text: oklch(0.85 0.05 280);
296
- }
297
- .high-contrast {
298
- --color-surface: oklch(0.98 0.01 280);
299
- --color-text: oklch(0.1 0.05 280);
300
- }
301
- .dark.high-contrast {
302
- --color-surface: oklch(0.05 0.01 280);
303
- --color-text: oklch(0.95 0.05 280);
304
- }
305
- ```
306
-
307
- `GlazeTailwindOptions`:
308
-
309
- | Option | Default | Description |
310
- |---|---|---|
311
- | `format` | `'oklch'` | Output color format for the values. |
312
- | `namespace` | `'color-'` | CSS custom property namespace, forming `--<namespace><name>` (e.g. `--color-surface`). Named `namespace` to avoid clashing with the palette theme-prefix option. |
313
- | `darkSelector` | `'.dark'` | Selector wrapping the dark overrides. Pass an at-rule like `'@media (prefers-color-scheme: dark)'` to drive dark mode from the OS preference (it nests `:root` automatically). |
314
- | `highContrastSelector` | `'.high-contrast'` | Selector wrapping the light high-contrast overrides. The combined dark + high-contrast block uses `${darkSelector}${highContrastSelector}` (e.g. `.dark.high-contrast`). |
315
- | `modes` | global config | Which scheme variants to include. The `@theme` block (light) is always emitted when colors exist. |
316
-
317
189
  ### `theme.export()`
318
190
 
319
191
  ```ts
@@ -339,182 +211,61 @@ type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;
339
211
 
340
212
  | Field | Type | Description |
341
213
  |---|---|---|
342
- | `tone` | `HCPair<ToneValue>` | Number = absolute (0–100, contrast-uniform). `'+N'`/`'-N'` = relative to base's tone (requires `base`). `'max'`/`'min'` = forced to the scheme's tone extreme (no `base`). Optional HC pair `[normal, hc]`. |
214
+ | `lightness` | `HCPair<number \| RelativeValue>` | Number = absolute (0–100). String (`'+N'`/`'-N'`) = relative to base's lightness (requires `base`). Optional HC pair `[normal, hc]`. |
343
215
  | `saturation` | `number` | Saturation factor applied to the seed saturation (0–1). Default: `1`. |
344
216
  | `hue` | `number \| RelativeValue` | Number = absolute (0–360). String (`'+N'`/`'-N'`) = relative to the **theme seed hue** (never to a base color). |
345
217
  | `base` | `string` | Name of another color in the same theme — makes this a *dependent* color. |
346
- | `contrast` | `HCPair<ContrastSpec>` | Contrast floor against `base`. Requires `base`. See [`contrast`](#contrast-floor). |
218
+ | `contrast` | `HCPair<MinContrast>` | WCAG contrast floor against `base`. Requires `base`. |
347
219
  | `mode` | `'auto' \| 'fixed' \| 'static'` | Adaptation mode. Default: `'auto'`. See [Adaptation modes](#adaptation-modes). |
348
- | `autoFlip` | `boolean` | Flip out-of-bounds results (relative `tone` overshoot / unmet `contrast`) to the opposite side instead of clamping. Default: the global `autoFlip` (`true`). See [`autoFlip`](#autoflip). |
349
220
  | `opacity` | `number` | Fixed alpha 0–1. Output includes alpha in the CSS value. Combining with `contrast` is not recommended (a `console.warn` is emitted). |
350
- | `pastel` | `boolean` | Per-color override for the hue-independent "safe" chroma limit used in OKHSL↔sRGB conversions (luminance, contrast solving, output formatting). Falls through to the global / per-theme `pastel` config when omitted. Default: unset. See [Per-color `pastel`](#per-color-pastel). |
351
- | `role` | `RoleInput` | Semantic role against `base` (`'text'` / `'surface'` / `'border'` or an alias). Fixes APCA contrast polarity. Resolved via: explicit `role` → name inference → opposite of the base's role → `'text'`. See [Roles](#roles). |
352
221
  | `inherit` | `boolean` | Whether this color is inherited by child themes via `extend()`. Default: `true`. Set to `false` to make the color local to the current theme. |
353
222
 
354
- #### Tone values
355
-
356
- `tone` (0–100) replaces OKHSL lightness with a contrast-uniform axis — equal tone steps give equal WCAG contrast. See [`docs/okhst.md`](okhst.md) for the math. (To port old `lightness` values, see [migration.md](migration.md).)
223
+ #### Lightness values
357
224
 
358
225
  | Form | Example | Meaning |
359
226
  |---|---|---|
360
- | Number (absolute) | `tone: 45` | Absolute tone 0–100. |
361
- | String (relative) | `tone: '-52'` | Relative to base color's tone (requires `base`). |
362
- | Extreme | `tone: 'max'` / `'min'` | Force to the scheme's highest (`'max'` = 100) or lowest (`'min'` = 0) tone. No `base` needed. |
363
- | HC pair | `tone: ['-7', '-20']` | `[normal, high-contrast]`. A single value applies to both. |
364
-
365
- **Absolute tone** on a dependent color (`base` set) positions the color independently. In dark mode it is tone-mapped (inverted + windowed) on its own. The `contrast` solver acts as a safety net.
366
-
367
- **Relative tone** applies a signed delta to the base color's resolved tone. Because tone is contrast-uniform, a fixed delta yields a fixed contrast step. In dark mode with `mode: 'auto'`, the offset is anchored to the base's per-scheme tone. If `base + delta` falls outside `[0, 100]`, the result is clamped to the boundary, or — with `autoFlip` (default on) — mirrored to the other side of the base.
227
+ | Number (absolute) | `lightness: 45` | Absolute lightness 0–100. |
228
+ | String (relative) | `lightness: '-52'` | Relative to base color's lightness (requires `base`). |
229
+ | HC pair | `lightness: ['-7', '-20']` | `[normal, high-contrast]`. A single value applies to both. |
368
230
 
369
- **Extreme tone** (`'max'` / `'min'`) forces the color to the scheme's tone extreme without a contrast hack or a magic number. `'max'` resolves to author tone 100 and `'min'` to 0; both flow through scheme mapping like an absolute tone, so under `mode: 'auto'` they invert in dark (`'max'` is lightest in light, darkest in dark). Use `mode: 'static'` to pin the same extreme across schemes, or `mode: 'fixed'` to keep the same end without inverting. No `base` required.
231
+ **Absolute lightness** on a dependent color (`base` set) positions the color independently. In dark mode it is dark-mapped on its own. The `contrast` solver acts as a safety net.
370
232
 
371
- A dependent color with `base` but no `tone` inherits the base's tone (equivalent to a delta of 0).
233
+ **Relative lightness** applies a signed delta to the base color's resolved lightness. In dark mode with `mode: 'auto'`, the sign flips automatically so a `'-52'` light-mode offset becomes a `+52` dark-mode offset.
372
234
 
373
- #### `autoFlip`
235
+ A dependent color with `base` but no `lightness` inherits the base's lightness (equivalent to a delta of 0).
374
236
 
375
- `autoFlip` governs what happens when a result would fall outside its valid range:
376
-
377
- - **Relative `tone` overshoot:** when `base ± delta` exceeds `[0, 100]`, `autoFlip` mirrors the delta to the other side of the base (e.g. `'+30'` becomes `'-30'`) instead of clamping to the boundary.
378
- - **`contrast` direction:** when the requested tone direction can't meet the floor, `autoFlip` lets the solver try the opposite side (the same behavior as the global `autoFlip`).
379
-
380
- `autoFlip` defaults to the global `autoFlip` (`true`). Set `autoFlip: false` on a color to clamp instead of mirror — useful when you want a relative offset to stay on the authored side of the base, or to keep an unmet contrast pinned to one direction's extreme.
381
-
382
- #### `contrast` (floor)
237
+ #### `contrast` (WCAG floor)
383
238
 
384
239
  ```ts
385
- type ContrastPreset = 'AA' | 'AAA' | 'AA-large' | 'AAA-large';
386
- type ContrastSpec =
387
- | number // bare WCAG ratio
388
- | ContrastPreset // named WCAG preset
389
- | { wcag: HCPair<number | ContrastPreset> }
390
- | { apca: HCPair<number> }; // APCA Lc target
240
+ type MinContrast = number | 'AA' | 'AAA' | 'AA-large' | 'AAA-large';
391
241
  ```
392
242
 
393
- | Preset | WCAG ratio |
243
+ | Preset | Ratio |
394
244
  |---|---|
395
245
  | `'AA-large'` | 3 |
396
246
  | `'AA'` | 4.5 |
397
247
  | `'AAA-large'` | 4.5 |
398
248
  | `'AAA'` | 7 |
399
249
 
400
- A bare number or preset means **WCAG**. Use `{ wcag }` / `{ apca }` to pick the metric explicitly. The `[normal, highContrast]` pair may live at the outer level (`[4.5, 7]`, `[{ wcag: 4.5 }, { wcag: 7 }]`) or inside the metric (`{ wcag: [4.5, 7] }`, `{ apca: [45, 60] }`).
401
-
402
- ```ts
403
- contrast: 4.5 // WCAG 4.5
404
- contrast: 'AAA' // WCAG 7
405
- contrast: { wcag: 6 } // WCAG 6
406
- contrast: { wcag: [4.5, 7] } // WCAG 4.5 normal / 7 high-contrast (explicit)
407
- contrast: { apca: 60 } // APCA Lc 60 normal / 75 high-contrast (auto)
408
- contrast: { apca: [45, 60] } // APCA Lc 45 normal / 60 high-contrast (explicit)
409
- contrast: { apca: 'content' } // APCA preset -> Lc 60 normal / 75 high-contrast (auto)
410
- contrast: { apca: ['content', 'body'] } // Lc 60 normal / 75 high-contrast (explicit)
411
- ```
412
-
413
- **WCAG HC auto-promotion:** a bare WCAG preset (no `[normal, hc]` pair at either
414
- the outer `contrast` or inner `wcag` level) is automatically promoted to its
415
- spec-defined "Enhanced" successor in high-contrast mode — `AA` → `AAA` (4.5 → 7)
416
- and `AA-large` → `AAA-large` (3 → 4.5), per WCAG SC 1.4.3 → 1.4.6. `AAA` and
417
- `AAA-large` are already the top WCAG tier and are left unchanged; bare numeric
418
- targets have no successor tier and are also left unchanged. An explicit HC value
419
- via either pair overrides and skips the promotion.
420
-
421
- **APCA Enhanced Level (HC auto-boost):** a bare APCA scalar (no `[normal, hc]`
422
- pair at either the outer `contrast` or inner `apca` level) is automatically
423
- boosted by **+15 Lc** in high-contrast mode, the APCA analog of WCAG's
424
- AAA-over-AA step. On by default; an explicit HC value via either pair
425
- overrides it and skips the boost. The enhanced target is clamped to 106 Lc.
426
- For large/bold text (where APCA caps contrast at Lc 90 to avoid glare), pass
427
- an explicit HC pair to hold that ceiling — see
428
- [`docs/okhst.md`](okhst.md) §Enhanced Level.
429
-
430
- APCA preset keywords (Bronze Simple Mode conformance levels, role-independent):
431
- `'preferred'` (Lc 90), `'body'` (75), `'content'` (60, ~AA), `'large'` (45, ~3:1),
432
- `'non-text'` (30), `'min'` (15, point of invisibility). See
433
- [`docs/okhst.md`](okhst.md) §APCA.
250
+ You can also pass any numeric ratio directly (e.g., `contrast: 4.5`, `contrast: 11`). The constraint is applied independently for each scheme — if the `lightness` already satisfies the floor it's kept, otherwise the solver adjusts lightness until the target is met.
434
251
 
435
- The floor is applied independently per scheme — if the `tone` already satisfies it the tone is kept, otherwise the solver searches in tone (contrast-uniform → a closed-form WCAG seed and fast convergence) until the target is met.
252
+ By default, `autoFlip` lets the solver cross to the opposite side of the base color when the requested lightness direction cannot satisfy contrast. Set `glaze.configure({ autoFlip: false })` to keep strict directionality: unmet colors pin to that direction's 0 or 100 lightness extreme instead of falling back to the original requested value.
436
253
 
437
- By default, the solver crosses to the opposite side of the base color when the requested tone direction cannot satisfy the floor. This is controlled per-color by [`autoFlip`](#autoflip) (which defaults to the global `autoFlip`). Set `glaze.configure({ autoFlip: false })` — or `autoFlip: false` on a single color — to keep strict directionality: unmet colors pin to that direction's 0 or 100 tone extreme instead of falling back to the original requested value.
438
-
439
- **Full tone spectrum in HC mode:** in high-contrast variants the `lightTone` and `darkTone` window constraints are bypassed entirely (the window is forced to `[0, 100]`). Colors can reach the full range, maximizing perceivable contrast.
440
-
441
- **Chromatic drift (verification):** tone is contrast-uniform for grays. A chromatic swatch at a given tone shares its OKHSL lightness with the equivalent gray but drifts in real luminance, so a contrast-floored color may land slightly under its gray-tone expectation. Glaze measures the resolved result against the base and emits a deduped advisory `console.warn` when it drifts below the target. See [`docs/okhst.md`](okhst.md) §Verification.
254
+ **Full lightness spectrum in HC mode:** in high-contrast variants the `lightLightness` and `darkLightness` window constraints are bypassed entirely. Colors can reach the full 0–100 range, maximizing perceivable contrast.
442
255
 
443
256
  #### Per-color hue override
444
257
 
445
258
  ```ts
446
259
  const theme = glaze(280, 80);
447
260
  theme.colors({
448
- surface: { tone: 97 },
449
- gradientEnd: { tone: 90, hue: '+20' }, // 280 + 20 = 300
450
- warning: { tone: 60, hue: 40 }, // absolute
261
+ surface: { lightness: 97 },
262
+ gradientEnd: { lightness: 90, hue: '+20' }, // 280 + 20 = 300
263
+ warning: { lightness: 60, hue: 40 }, // absolute
451
264
  });
452
265
  ```
453
266
 
454
267
  Relative hue is always relative to the **theme seed hue**, not to a base color.
455
268
 
456
- #### Per-color `pastel`
457
-
458
- `pastel: true` on a single color def overrides the global / per-theme `pastel` config for that color only. It toggles the hue-independent "safe" chroma limit used in every OKHSL↔sRGB conversion that touches this color: luminance calculations during contrast solving, gamut clamping during sRGB blend / mix edges, and output formatting. The effective flag is carried on the resolved variant (`ResolvedColorVariant.pastel`) so formatting matches the gamut mapping applied during resolution.
459
-
460
- ```ts
461
- const theme = glaze(280, 80);
462
- theme.colors({
463
- plain: { tone: 50, saturation: 1 },
464
- soft: { tone: 50, saturation: 1, pastel: true },
465
- });
466
- // theme.resolve().get('soft')!.light.pastel === true
467
- // theme.css().light contains different rgb() triples for `--plain` and `--soft`
468
- ```
469
-
470
- Omit the field to inherit the global / per-theme `pastel` config — useful for keeping the default behavior while opting a single accent into the pastel gamut.
471
-
472
- The flag is part of the def object, so `extend()` copies it through to child themes alongside the rest of the def. Override it again on the child to flip a single color back:
473
-
474
- ```ts
475
- const parent = glaze(280, 80);
476
- parent.colors({ soft: { tone: 50, saturation: 1, pastel: true } });
477
-
478
- const child = parent.extend({
479
- colors: { soft: { tone: 50, saturation: 1, pastel: false } },
480
- });
481
- // child.resolve().get('soft')!.light.pastel === false
482
- ```
483
-
484
- > **Note:** Per-color `pastel` is also supported on `ShadowColorDef` and `MixColorDef` (see the tables above). For shadows the math itself happens in OKHSL space, so the flag mainly controls the gamut-mapped output formatting and any luminance verification for that variant.
485
- >
486
- > Standalone `glaze.color()` tokens accept the same `pastel` field on both the structured (`GlazeColorInput`) and value-shorthand (`GlazeColorOverrides`) forms, and it survives the `export()` / `glaze.colorFrom()` round-trip.
487
-
488
- #### Roles
489
-
490
- A color's `role` describes how it is used against its `base` and fixes **APCA contrast polarity** — which side is the foreground vs the background. APCA is asymmetric (`|apca(a,b)| ≠ |apca(b,a)|`), so the role picks the correct argument order; WCAG is symmetric and unaffected.
491
-
492
- | Role | Polarity | Use | Aliases (name inference) |
493
- |---|---|---|---|
494
- | `'text'` | fg | Text / icons / foreground content | `text`, `fg`, `foreground`, `content`, `ink`, `label`, `stroke` |
495
- | `'border'` | fg | Non-text spot elements (borders, dividers, outlines) | `border`, `divider`, `outline`, `separator`, `hairline`, `rule` |
496
- | `'surface'` | bg | Backgrounds / fills | `surface`, `bg`, `background`, `fill`, `canvas`, `paper`, `layer` |
497
-
498
- Resolution chain (per color):
499
-
500
- 1. Explicit `role` (normalized from an alias) wins.
501
- 2. Else, when `inferRole` is enabled (default), infer from the color name — the **last** recognized token wins (`button-text` → `text`, `input-bg` → `surface`, `card-outline` → `border`).
502
- 3. Else, the opposite of the base's role (a `surface` base ⇒ this is `text`).
503
- 4. Else, `'text'` (foreground) — i.e. the base is treated as the background.
504
-
505
- ```ts
506
- const theme = glaze(280, 60);
507
- theme.colors({
508
- surface: { tone: 90 },
509
- text: { base: 'surface', contrast: { apca: 'content' } }, // inferred text
510
- border: { base: 'surface', tone: '-10' }, // inferred border
511
- });
512
- // role fixes APCA polarity; set `pastel: true` explicitly if a border
513
- // needs the hue-independent safe chroma limit.
514
- ```
515
-
516
- Disable name inference with `glaze.configure({ inferRole: false })` (the base-opposite and foreground-default fallbacks still apply).
517
-
518
269
  ### `ShadowColorDef`
519
270
 
520
271
  | Field | Type | Description |
@@ -524,7 +275,6 @@ Disable name inference with `glaze.configure({ inferRole: false })` (the base-op
524
275
  | `fg` | `string` | Optional foreground color name for tinting and intensity modulation. Must reference a non-shadow color. Omit for an achromatic shadow at full user-specified intensity. |
525
276
  | `intensity` | `HCPair<number>` | Shadow intensity, 0–100. Supports HC pairs. |
526
277
  | `tuning` | `ShadowTuning` | Per-color tuning overrides. Merged field-by-field with the global `shadowTuning`. |
527
- | `pastel` | `boolean` | Per-color `pastel` override. See [Per-color `pastel`](#per-color-pastel). |
528
278
  | `inherit` | `boolean` | Inheritance flag, default `true`. |
529
279
 
530
280
  See [Shadows](#shadows) below for the algorithm and tuning details.
@@ -539,9 +289,7 @@ See [Shadows](#shadows) below for the algorithm and tuning details.
539
289
  | `value` | `HCPair<number>` | Mix ratio 0–100 (0 = pure base, 100 = pure target). In `'transparent'` blend, this becomes the target's opacity. Supports HC pairs. |
540
290
  | `blend` | `'opaque' \| 'transparent'` | Default `'opaque'`. |
541
291
  | `space` | `'okhsl' \| 'srgb'` | Interpolation space for opaque blending. Default `'okhsl'`. Ignored for `'transparent'` (always composites in linear sRGB). |
542
- | `contrast` | `HCPair<ContrastSpec>` | Optional contrast floor against `base` (WCAG or APCA — see [`contrast`](#contrast-floor)). The solver adjusts the mix ratio (opaque) or opacity (transparent). |
543
- | `pastel` | `boolean` | Per-color `pastel` override. See [Per-color `pastel`](#per-color-pastel). |
544
- | `role` | `RoleInput` | Semantic role of the mixed result against `base`. Same semantics as `RegularColorDef.role` (see [Roles](#roles)). |
292
+ | `contrast` | `HCPair<MinContrast>` | Optional WCAG floor against `base`. The solver adjusts the mix ratio (opaque) or opacity (transparent). |
545
293
  | `inherit` | `boolean` | Inheritance flag, default `true`. |
546
294
 
547
295
  See [Mix colors](#mix-colors) below.
@@ -564,10 +312,10 @@ glaze.color(color: GlazeFromInput | GlazeColorInput | GlazeColorValue, config?:
564
312
 
565
313
  | Shape | Example | Notes |
566
314
  |---|---|---|
567
- | **Bare string** | `'#26fcb2'` | Hex or CSS color function (`rgb()`, `hsl()`, `okhsl()`, `okhst()`, `oklch()`). |
568
- | **Value object** | `{ h: 152, s: 0.95, l: 0.74 }` | OKHSL, OKHST (`{ h, s, t }`), `{ r, g, b }` (sRGB 0–255), or `{ l, c, h }` (OKLCh). |
315
+ | **Bare string** | `'#26fcb2'` | Hex or CSS color function (`rgb()`, `hsl()`, `okhsl()`, `oklch()`). |
316
+ | **Value object** | `{ h: 152, s: 0.95, l: 0.74 }` | OKHSL, `{ r, g, b }` (sRGB 0–255), or `{ l, c, h }` (OKLCh). |
569
317
  | **`{ from, ...overrides }`** | `{ from: '#1a1a2e', base: bg, contrast: 'AA' }` | Value + color overrides in one object. |
570
- | **Structured** | `{ hue: 152, saturation: 95, tone: 74 }` | Full theme-style token (hue/saturation in 0–100, tone in 0–100). |
318
+ | **Structured** | `{ hue: 152, saturation: 95, lightness: 74 }` | Full theme-style token (hue/saturation/lightness all in 0–100). |
571
319
 
572
320
  `GlazeColorValue` (bare string or value-object forms) accepts:
573
321
 
@@ -577,28 +325,23 @@ glaze.color(color: GlazeFromInput | GlazeColorInput | GlazeColorValue, config?:
577
325
  | `rgb()` | `'rgb(38 252 178)'`, `'rgb(38 252 178 / 0.8)'` | Modern space syntax. Alpha dropped with warning. |
578
326
  | `hsl()` | `'hsl(152 97% 57%)'` | Modern space syntax. Alpha dropped with warning. |
579
327
  | `okhsl()` | `'okhsl(152 95% 74%)'` | Glaze's own emit format. Alpha dropped with warning. |
580
- | `okhst()` | `'okhst(152 95% 70%)'` | OKHST tone input (third value is tone 0–100). **Input only** — never emitted. Alpha dropped with warning. |
581
328
  | `oklch()` | `'oklch(0.85 0.18 152)'` | Glaze's own emit format. Alpha dropped with warning. |
582
- | `OkhslColor` object | `{ h: 152, s: 0.95, l: 0.74 }` | OKHSL shape (h: 0–360, s/l: 0–1). Passing 0–100 for `s`/`l` throws with a hint to use the structured form. |
583
- | `OkhstColor` object | `{ h: 152, s: 0.95, t: 0.70 }` | OKHST shape (h: 0–360, s/t: 0–1). The `t` key disambiguates it from `{ h, s, l }`. **Input only.** |
329
+ | `OkhslColor` object | `{ h: 152, s: 0.95, l: 0.74 }` | Glaze's native shape (h: 0–360, s/l: 0–1). Passing 0–100 for `s`/`l` throws with a hint to use the structured form. |
584
330
  | `RgbColor` object | `{ r: 38, g: 252, b: 178 }` | sRGB 0–255. RGB tuple `[r, g, b]` is not supported — use this object form. |
585
331
  | `OklchColor` object | `{ l: 0.85, c: 0.18, h: 152 }` | OKLCh (L/C: 0–1, H: degrees), same semantics as `oklch()` strings. |
586
332
 
587
- `GlazeColorInput` (structured form) is `{ hue, saturation, tone, ... }`:
333
+ `GlazeColorInput` (structured form) is `{ hue, saturation, lightness, ... }`:
588
334
 
589
335
  | Field | Type | Description |
590
336
  |---|---|---|
591
337
  | `hue` | `number` | 0–360. |
592
338
  | `saturation` | `number` | 0–100. |
593
- | `tone` | `HCPair<number \| ExtremeValue>` | 0–100 (contrast-uniform) or `'max'`/`'min'`, optional HC pair. |
339
+ | `lightness` | `HCPair<number>` | 0–100, optional HC pair. |
594
340
  | `saturationFactor` | `number` | Multiplier on the seed (0–1). Default: `1`. |
595
341
  | `mode` | `AdaptationMode` | Default: `'auto'`. |
596
- | `autoFlip` | `boolean` | Flip out-of-bounds results instead of clamping. Default: global `autoFlip`. |
597
342
  | `opacity` | `number` | Fixed alpha 0–1. |
598
343
  | `base` | `GlazeColorToken \| GlazeColorValue` | Optional dependency. See [Pairing colors](#pairing-colors). |
599
- | `contrast` | `HCPair<ContrastSpec>` | Contrast floor against `base` (WCAG or APCA). Without `base`, anchored to the literal seed. |
600
- | `pastel` | `boolean` | Per-color `pastel` override. Falls through to the global / per-theme `pastel` config when omitted. See [Per-color `pastel`](#per-color-pastel). |
601
- | `role` | `RoleInput` | Semantic role against `base` / the seed (see [Roles](#roles)). Fixes APCA polarity. |
344
+ | `contrast` | `HCPair<MinContrast>` | WCAG floor against `base`. Without `base`, anchored to the literal seed. |
602
345
  | `name` | `string` | Debug label for warnings; doesn't change output keys. Reserved names (`'value'`, `'seed'`, `'externalBase'`) are rejected. |
603
346
 
604
347
  `GlazeFromInput` (from form) is `{ from: GlazeColorValue, ...colorOverrides }`:
@@ -608,15 +351,12 @@ glaze.color(color: GlazeFromInput | GlazeColorInput | GlazeColorValue, config?:
608
351
  | `from` | **Required.** The source color value — same forms as `GlazeColorValue`. |
609
352
  | `hue` | Number (absolute 0–360) or `'+N'`/`'-N'` (relative to seed, never to `base`). |
610
353
  | `saturation` | Override seed saturation (0–100). |
611
- | `tone` | Number (absolute 0–100), `'+N'`/`'-N'`, or `'max'`/`'min'`. Without `base`, relative anchors to the seed; with `base`, anchors to `base`'s tone per scheme. |
354
+ | `lightness` | Number (absolute 0–100) or `'+N'`/`'-N'`. Without `base`, relative anchors to the seed; with `base`, anchors to `base`'s lightness per scheme. |
612
355
  | `saturationFactor` | Multiplier on the seed (0–1). |
613
356
  | `mode` | `'auto'` (default) / `'fixed'` / `'static'`. |
614
- | `autoFlip` | Flip out-of-bounds results instead of clamping. Default: global `autoFlip`. |
615
- | `contrast` | Contrast floor (WCAG or APCA). Without `base`, anchored to the literal seed; with `base`, solved per scheme. |
357
+ | `contrast` | WCAG floor. Without `base`, anchored to the literal seed; with `base`, solved per scheme. |
616
358
  | `base` | `GlazeColorToken` or raw `GlazeColorValue`. See [Pairing colors](#pairing-colors). |
617
359
  | `opacity` | Fixed alpha 0–1. Combining with `contrast` is not recommended — `console.warn` is emitted. |
618
- | `pastel` | Per-color `pastel` override. Falls through to the global / per-theme `pastel` config when omitted. See [Per-color `pastel`](#per-color-pastel). |
619
- | `role` | Semantic role against `base` / the seed (see [Roles](#roles)). Fixes APCA polarity. |
620
360
  | `name` | Debug label only — surfaces in warnings/errors. Does not change output keys. |
621
361
 
622
362
  Named CSS colors (`'red'`, `'blueviolet'`) are not supported.
@@ -626,10 +366,10 @@ Named CSS colors (`'red'`, `'blueviolet'`) are not supported.
626
366
  Every input form defaults to `mode: 'auto'` so the resolved token adapts between light and dark like an ordinary theme color. The config snapshot taken at create time differs by input form:
627
367
 
628
368
  - **Value-shorthand** (bare strings, value objects, and `{ from, ...overrides }`):
629
- - Light variant preserves the input tone exactly (`lightTone: false`).
630
- - All other config fields (`darkTone`, `darkDesaturation`, `autoFlip`) snapshot from `globalConfig` at create time.
631
- - **Structured input** (`{ hue, saturation, tone, ... }`):
632
- - Both tone windows snapshot from `globalConfig` at create time (same as a theme color).
369
+ - Light variant preserves the input lightness exactly (`lightLightness: false`).
370
+ - All other config fields (`darkLightness`, `darkDesaturation`, `darkCurve`, `autoFlip`) snapshot from `globalConfig` at create time.
371
+ - **Structured input** (`{ hue, saturation, lightness, ... }`):
372
+ - Both lightness windows snapshot from `globalConfig` at create time (same as a theme color).
633
373
  - All fields are **snapshotted at color-creation time** — later `glaze.configure()` calls don't retroactively change existing tokens.
634
374
 
635
375
  ```ts
@@ -639,14 +379,11 @@ glaze.color('#26fcb2')
639
379
  // Value-object — same behavior
640
380
  glaze.color({ h: 152, s: 0.95, l: 0.74 })
641
381
 
642
- // OKHST value-object — tone axis
643
- glaze.color({ h: 152, s: 0.95, t: 0.70 })
644
-
645
382
  // From form — value + color overrides
646
383
  glaze.color({ from: '#1a1a2e', hue: '+20', contrast: 'AA' })
647
384
 
648
- // Structured form — explicit hue/saturation/tone (0–100)
649
- glaze.color({ hue: 152, saturation: 95, tone: 74 })
385
+ // Structured form — explicit hue/saturation/lightness (0–100)
386
+ glaze.color({ hue: 152, saturation: 95, lightness: 74 })
650
387
  ```
651
388
 
652
389
  ### Token methods
@@ -657,45 +394,43 @@ A `GlazeColorToken` exposes:
657
394
  |---|---|
658
395
  | `token.resolve()` | Resolve as a `ResolvedColor` (light/dark/lightContrast/darkContrast variants). |
659
396
  | `token.token(options?)` | Flat token map (no color-name key). Options: `format`, `modes`, `states`. |
660
- | `token.tasty(options?)` | [Tasty](https://tasty.style) state map (no color-name key). Same options as `token.token`. |
397
+ | `token.tasty(options?)` | Tasty state map (no color-name key). Same options as `token.token`. |
661
398
  | `token.json(options?)` | JSON map (no color-name key). Options: `format`, `modes`. |
662
399
  | `token.css({ name, format?, suffix? })` | CSS custom property declarations grouped by scheme variant. `name` is **required** and becomes the variable identifier (`'brand'` → `--brand-color`). Defaults: `format: 'rgb'`, `suffix: '-color'` (matches `theme.css`). |
663
- | `token.dtcg(options?)` | DTCG color tokens, one per scheme variant (no color-name key). Each entry is a full `{ $type: 'color', $value }` token. Options: `colorSpace` (`'srgb'` \| `'oklch'`), `modes`. |
664
- | `token.dtcgResolver({ name, ... })` | A single DTCG Resolver-Module document for this color, keyed by `name` across all scheme variants. `name` is **required**. Same options as `theme.dtcgResolver()` plus `name`. |
665
- | `token.tailwind({ name, ... })` | Tailwind v4 `@theme` block + dark / high-contrast overrides for this color. `name` is **required** (forms `--color-<name>`). Same options as `theme.tailwind()` plus `name`. |
666
400
  | `token.export()` | JSON-safe snapshot — pass to `glaze.colorFrom(...)` to rehydrate. |
667
401
 
668
402
  ### Per-instance config override
669
403
 
670
- The optional `config` second argument (`GlazeConfigOverride`) overrides the resolve-relevant global config fields for a single token or theme. Fields that are omitted fall through to the live global config at create time (and are snapshotted). A tone window can be `[lo, hi]`, `{ lo, hi, eps }`, or `false` (disable clamping).
404
+ The optional `config` second argument (`GlazeConfigOverride`) overrides the resolve-relevant global config fields for a single token or theme. Fields that are omitted fall through to the live global config at create time (and are snapshotted). Pass `false` for a lightness window to disable clamping entirely — equivalent to `[0, 100]`.
671
405
 
672
406
  `GlazeConfigOverride`:
673
407
 
674
408
  | Field | Default (from global) | Description |
675
409
  |---|---|---|
676
- | `lightTone` | `[10, 100]` | Light tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` (disable clamping). |
677
- | `darkTone` | `[15, 95]` | Dark tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` (disable clamping). |
410
+ | `lightLightness` | `[10, 100]` | Light window `[lo, hi]` or `false` (disable clamping = `[0, 100]`). |
411
+ | `darkLightness` | `[15, 95]` | Dark window `[lo, hi]` or `false` (disable clamping). |
678
412
  | `darkDesaturation` | `0.1` | Saturation reduction in dark scheme (0–1). |
679
- | `autoFlip` | `true` | Default for each color's `autoFlip`: when solving `contrast` (or applying a relative `tone` that overshoots), allow crossing to the opposite side instead of clamping. |
413
+ | `darkCurve` | `0.5` | Möbius beta for dark `auto`-inversion (0–1). Accepts `[normal, hc]` pair. |
414
+ | `autoFlip` | `true` | When solving `contrast`, allow the solver to switch lightness direction if the requested side can't meet the target. |
680
415
  | `shadowTuning` | `undefined` | Default shadow tuning (meaningful for themes; harmless on color tokens). |
681
416
 
682
417
  Config overrides apply to both `glaze.color()` tokens and `glaze()` themes:
683
418
 
684
419
  ```ts
685
- // Standalone color — preserve raw tone in both schemes
686
- glaze.color('#26fcb2', { darkTone: false })
420
+ // Standalone color — preserve raw lightness in both schemes
421
+ glaze.color('#26fcb2', { darkLightness: false })
687
422
 
688
423
  // Restore the #000 → white dark flip (full dark range)
689
424
  glaze.color('#000000', {
690
- lightTone: false,
691
- darkTone: [15, 100],
425
+ lightLightness: false,
426
+ darkLightness: [15, 100],
692
427
  })
693
428
 
694
429
  // Structured form with config override
695
- glaze.color({ hue: 152, saturation: 95, tone: 74 }, { darkTone: false })
430
+ glaze.color({ hue: 152, saturation: 95, lightness: 74 }, { darkLightness: false })
696
431
 
697
432
  // Theme with config override
698
- const rawTheme = glaze(280, 80, { lightTone: false })
433
+ const rawTheme = glaze(280, 80, { lightLightness: false })
699
434
  ```
700
435
 
701
436
  The override is **snapshotted at create time** so later `glaze.configure()` calls don't change already-created tokens or themes (for non-overridden fields, the snapshot captured the global value at creation time; for themes, non-overridden fields are re-read from the live global at resolve time — see [Theme config override](#theme-config-override)).
@@ -708,18 +443,17 @@ When a theme is created with a `GlazeConfigOverride`, the override is **merged o
708
443
  - Fields you didn't override still react to later `glaze.configure()` calls.
709
444
 
710
445
  ```ts
711
- const t = glaze(280, 80, { lightTone: [0, 50] });
712
- t.colors({ text: { tone: 50, saturation: 1 } });
713
- // text.light lands inside the [0, 50] window — always, regardless of
714
- // global lightTone changes.
446
+ const t = glaze(280, 80, { lightLightness: [0, 50] });
447
+ t.colors({ text: { lightness: 50, saturation: 1 } });
448
+ // text.light.l ≈ 0.25 — always, regardless of global lightLightness changes.
715
449
  // text.dark.s reacts to glaze.configure({ darkDesaturation }) since it's not overridden.
716
450
  ```
717
451
 
718
452
  `extend` inherits the parent's override and shallow-merges the child's:
719
453
 
720
454
  ```ts
721
- const child = t.extend({ config: { darkTone: false } });
722
- // child: lightTone { lo: 0, hi: 50 } (inherited) + darkTone: false (added)
455
+ const child = t.extend({ config: { darkLightness: false } });
456
+ // child: lightLightness: [0, 50] (inherited) + darkLightness: false (added)
723
457
  ```
724
458
 
725
459
  `theme.export()` includes `config`; `glaze.from(data)` restores it.
@@ -739,7 +473,7 @@ Both value-form and structured-form tokens round-trip.
739
473
 
740
474
  ### Pairing colors
741
475
 
742
- Set `base` to anchor a standalone color to another standalone color or raw value. The contrast solver and relative `tone` offsets switch their anchor from the literal seed to the base's resolved variant per scheme — so the same text color automatically lands at AA against its background in light, dark, and high-contrast modes.
476
+ Set `base` to anchor a standalone color to another standalone color or raw value. The WCAG contrast solver and relative `lightness` offsets switch their anchor from the literal seed to the base's resolved variant per scheme — so the same text color automatically lands at AA against its background in light, dark, and high-contrast modes.
743
477
 
744
478
  ```ts
745
479
  const bg = glaze.color('#1a1a2e');
@@ -747,10 +481,10 @@ const bg = glaze.color('#1a1a2e');
747
481
  // Text guaranteed AA against `bg` in every scheme.
748
482
  const text = glaze.color({ from: '#ffffff', base: bg, contrast: 'AA' });
749
483
 
750
- // Border 8 tone units lighter than `bg` in each scheme.
484
+ // Border 8 lightness units lighter than `bg` in each scheme.
751
485
  const border = glaze.color({ from: '#000000',
752
486
  base: bg,
753
- tone: '+8',
487
+ lightness: '+8',
754
488
  mode: 'fixed',
755
489
  });
756
490
 
@@ -761,11 +495,11 @@ const text2 = glaze.color({ from: '#ffffff', base: '#1a1a2e', contrast: 'AA' });
761
495
  Behavior with `base`:
762
496
 
763
497
  - `contrast` is solved per scheme against `base`'s resolved variant (light / dark / lightContrast / darkContrast).
764
- - Relative `tone: '+N'` / `'-N'` is anchored to `base`'s tone per scheme (matches theme behavior).
498
+ - Relative `lightness: '+N'` / `'-N'` is anchored to `base`'s lightness per scheme (matches theme behavior).
765
499
  - Relative `hue: '+N'` / `'-N'` still anchors to the **seed** (the value passed to `glaze.color()`), not the base.
766
500
  - `mode` works as a per-pair knob.
767
501
  - The base token's `.resolve()` is called lazily on the first resolve of the dependent and the result is captured by reference; later mutations to the base don't apply.
768
- - **Structured bases are resolved at full range for linking math**: when a value/`from` color links to a base created via the structured form, the contrast/tone anchor uses the raw input tone (not the windowed output). This ensures the anchor matches what you intended, not what the light window remapped it to. The base's own `.resolve()` output is unaffected.
502
+ - **Structured bases are resolved at full range for linking math**: when a value/`from` color links to a base created via the structured form, the contrast/lightness anchor uses the raw input lightness (not the windowed output). This ensures the anchor matches what you intended, not what the light window remapped it to. The base's own `.resolve()` output is unaffected.
769
503
  - When the contrast target is physically unreachable, `glaze` emits a single `console.warn` per `(name, scheme, target)` triple and returns the closest passing variant. Use the `name` override to make the warning identifiable.
770
504
 
771
505
  Chains compose:
@@ -788,8 +522,8 @@ The `name` override appears in `console.warn` / Error messages but **does not**
788
522
 
789
523
  ```ts
790
524
  theme.colors({
791
- surface: { tone: 95 },
792
- text: { base: 'surface', tone: '-52', contrast: 'AAA' },
525
+ surface: { lightness: 95 },
526
+ text: { base: 'surface', lightness: '-52', contrast: 'AAA' },
793
527
 
794
528
  'shadow-sm': { type: 'shadow', bg: 'surface', fg: 'text', intensity: 5 },
795
529
  'shadow-md': { type: 'shadow', bg: 'surface', fg: 'text', intensity: 10 },
@@ -882,7 +616,7 @@ For a simple fixed-alpha color (no shadow algorithm), use `opacity` on a regular
882
616
 
883
617
  ```ts
884
618
  theme.colors({
885
- overlay: { tone: 0, opacity: 0.5 },
619
+ overlay: { lightness: 0, opacity: 0.5 },
886
620
  });
887
621
  // → 'oklch(0 0 0 / 0.5)'
888
622
  ```
@@ -897,8 +631,8 @@ Produces a solid color by interpolating between `base` and `target`:
897
631
 
898
632
  ```ts
899
633
  theme.colors({
900
- surface: { tone: 95 },
901
- accent: { tone: 30 },
634
+ surface: { lightness: 95 },
635
+ accent: { lightness: 30 },
902
636
  tint: { type: 'mix', base: 'surface', target: 'accent', value: 30 },
903
637
  });
904
638
  ```
@@ -913,8 +647,8 @@ Produces the target color with controlled opacity — useful for hover overlays:
913
647
 
914
648
  ```ts
915
649
  theme.colors({
916
- surface: { tone: 95 },
917
- black: { tone: 0, saturation: 0 },
650
+ surface: { lightness: 95 },
651
+ black: { lightness: 0, saturation: 0 },
918
652
  hover: {
919
653
  type: 'mix', base: 'surface', target: 'black',
920
654
  value: 8, blend: 'transparent',
@@ -961,8 +695,8 @@ Mix colors can reference other mix colors:
961
695
 
962
696
  ```ts
963
697
  theme.colors({
964
- white: { tone: 100, saturation: 0 },
965
- black: { tone: 0, saturation: 0 },
698
+ white: { lightness: 100, saturation: 0 },
699
+ black: { lightness: 0, saturation: 0 },
966
700
  gray: { type: 'mix', base: 'white', target: 'black', value: 50, space: 'srgb' },
967
701
  lightGray: { type: 'mix', base: 'white', target: 'gray', value: 50, space: 'srgb' },
968
702
  });
@@ -1111,56 +845,6 @@ const stylesheet = `
1111
845
  `palette.css()` accepts the same `GlazeCssOptions` as `theme.css()` plus `GlazePaletteExportOptions`.
1112
846
  It does not accept `modes`; all four result fields are always returned.
1113
847
 
1114
- ### `palette.dtcg()`
1115
-
1116
- DTCG export for a palette. Prefix defaults to `true` and the palette-level `primary` is honored (the primary theme's tokens are duplicated without prefix as aliases).
1117
-
1118
- ```ts
1119
- palette.dtcg()
1120
- // → {
1121
- // light: {
1122
- // 'primary-surface': { $type: 'color', $value: { ... } },
1123
- // 'surface': { $type: 'color', $value: { ... } }, // unprefixed alias
1124
- // 'danger-surface': { $type: 'color', $value: { ... } },
1125
- // },
1126
- // dark: { ... },
1127
- // }
1128
- ```
1129
-
1130
- Accepts `GlazeDtcgOptions` plus `GlazePaletteExportOptions`.
1131
-
1132
- ### `palette.dtcgResolver()`
1133
-
1134
- Resolver-Module export for a palette. Same as `theme.dtcgResolver()` but merges every theme (with prefix / `primary` aliasing) into the single `sets.base` source and each `scheme` context. Prefix defaults to `true`; the palette-level `primary` is honored.
1135
-
1136
- ```ts
1137
- palette.dtcgResolver()
1138
- // → {
1139
- // version: '2025.10',
1140
- // sets: { base: { sources: [ { 'primary-surface': {…}, 'surface': {…}, 'danger-surface': {…} } ] } },
1141
- // modifiers: { scheme: { default: 'light', contexts: { light: [], dark: [ {…} ] } } },
1142
- // resolutionOrder: [ { $ref: '#/sets/base' }, { $ref: '#/modifiers/scheme' } ],
1143
- // }
1144
- ```
1145
-
1146
- Accepts `GlazeDtcgResolverOptions` plus `GlazePaletteExportOptions`.
1147
-
1148
- ### `palette.tailwind()`
1149
-
1150
- Tailwind export for a palette. All themes are merged into a single `@theme` block (plus dark / high-contrast overrides), so each color is reachable as a Tailwind utility. Prefix defaults to `true`.
1151
-
1152
- ```ts
1153
- const css = palette.tailwind();
1154
- // @theme {
1155
- // --color-primary-surface: oklch(...);
1156
- // --color-surface: oklch(...); /* unprefixed alias */
1157
- // --color-danger-surface: oklch(...);
1158
- // }
1159
- // .dark { ... }
1160
- ```
1161
-
1162
- Accepts `GlazeTailwindOptions` plus `GlazePaletteExportOptions`. The palette `prefix` option (theme prefixing) is separate from `GlazeTailwindOptions.namespace` (the `--color-*` CSS namespace).
1163
-
1164
848
  ---
1165
849
 
1166
850
  ## Output formats
@@ -1169,40 +853,21 @@ Control the color format with the `format` option on any export method:
1169
853
 
1170
854
  | Format | Output (alpha = 1) | Output (alpha < 1) | Notes |
1171
855
  |---|---|---|---|
1172
- | `'okhsl'` (default for `tasty()`) | `okhsl(H S% L%)` | `okhsl(H S% L% / A)` | Glaze's native format, not a CSS function. **Tasty-only** (`tasty()`, `token()`, `.tasty()`). |
1173
- | `'okhst'` | `okhst(H S% T%)` | `okhst(H S% T% / A)` | OKHST tone axis. **Tasty-only** — same restriction as `okhsl`. |
1174
- | `'oklch'` (default for `tokens()` / `json()`) | `oklch(L C H)` | `oklch(L C H / A)` | OKLab-based LCH. Native CSS. Required for `splitHue`. |
1175
- | `'rgb'` (default for `css()`) | `rgb(R G B)` | `rgb(R G B / A)` | Rounded integers, modern space syntax. |
856
+ | `'okhsl'` (default for tokens/tasty/json) | `okhsl(H S% L%)` | `okhsl(H S% L% / A)` | Glaze's native format, not a CSS function. |
857
+ | `'rgb'` (default for css) | `rgb(R G B)` | `rgb(R G B / A)` | Rounded integers, modern space syntax. |
1176
858
  | `'hsl'` | `hsl(H S% L%)` | `hsl(H S% L% / A)` | Modern space syntax. |
859
+ | `'oklch'` | `oklch(L C H)` | `oklch(L C H / A)` | OKLab-based LCH. |
1177
860
 
1178
861
  ```ts
1179
- theme.tokens(); // 'oklch(0.965 0.0123 280)' (default)
862
+ theme.tokens(); // 'okhsl(280 60% 97%)'
1180
863
  theme.tokens({ format: 'rgb' }); // 'rgb(244 240 250)'
1181
- theme.tasty(); // 'okhsl(280 60% 97%)' (default)
1182
- theme.tasty({ format: 'okhst' }); // 'okhst(280 60% 97%)'
864
+ theme.tokens({ format: 'hsl' }); // 'hsl(270.5 45.2% 95.8%)'
865
+ theme.tokens({ format: 'oklch' }); // 'oklch(0.965 0.0123 280)'
1183
866
  ```
1184
867
 
1185
868
  All numeric output strips trailing zeros for cleaner CSS (e.g. `95` not `95.0`).
1186
869
 
1187
- The `format` option works on CSS-string exports: `theme.tokens()`, `theme.tasty()`, `theme.json()`, `theme.css()`, `theme.tailwind()`, the same on `palette`, and on `token.token()` / `.tasty()` / `.json()` / `.css()` / `.tailwind()`. **`okhsl` and `okhst` throw on non-Tasty exports** (`tokens`, `json`, `css`, `tailwind`) — they are not native CSS color spaces.
1188
-
1189
- ### Hue channel splitting (`splitHue`)
1190
-
1191
- On `theme.css()`, `theme.tasty()`, `palette.css()`, `palette.tasty()`, and standalone `color.css()` with `format: 'oklch'`, set `splitHue: true` to emit hue as its own custom property so consumers can re-skin at runtime:
1192
-
1193
- ```css
1194
- /* theme.css({ format: 'oklch', splitHue: true, name: 'brand' }) */
1195
- --brand-hue: 240;
1196
- --accent-hue: calc(var(--brand-hue) + 20);
1197
- --surface-color: oklch(0.52 0.06 var(--brand-hue));
1198
- --accent-color: oklch(0.62 0.03 var(--accent-hue));
1199
- ```
1200
-
1201
- **Requirements:** every exported color must be pastel (`pastel: true` globally or per-color). Pastel mode bounds chroma by the hue-independent safe chroma at each lightness, so emitted `C` stays in sRGB for any rotated hue. Non-pastel palettes throw rather than emit values that would clip under rotation.
1202
-
1203
- **Limitations:** `oklch` only (native CSS `var()` in the hue slot). Shadow and mix colors stay inline (blended hue). Standalone `.token()` / `.tasty()` do not support `splitHue` (return shape cannot carry the `$name-hue` declaration).
1204
-
1205
- `theme.dtcg()` / `theme.dtcgResolver()` / `palette.dtcg()` / `palette.dtcgResolver()` ignore `format` — DTCG emits structured `$value` objects, not CSS strings. Use the `colorSpace` option (`'srgb'` or `'oklch'`) to pick the color representation instead.
870
+ The `format` option works on every export: `theme.tokens()`, `theme.tasty()`, `theme.json()`, `theme.css()`, the same on `palette`, and on `token.token()` / `.tasty()` / `.json()` / `.css()`.
1206
871
 
1207
872
  ---
1208
873
 
@@ -1212,66 +877,78 @@ On `theme.css()`, `theme.tasty()`, `palette.css()`, `palette.tasty()`, and stand
1212
877
 
1213
878
  | Mode | Behavior |
1214
879
  |---|---|
1215
- | `'auto'` (default) | Full adaptation. Dark is a single tone inversion (`100 − t`) remapped into the dark window. High-contrast uses the full range. |
1216
- | `'fixed'` | Color stays recognizable. Tone is *mapped* (not inverted) into the dark window. Use for brand buttons, CTAs, status banners. |
1217
- | `'static'` | No adaptation. Same tone in every scheme. |
880
+ | `'auto'` (default) | Full adaptation. Light ↔ dark inversion via the Möbius curve. High-contrast boost. |
881
+ | `'fixed'` | Color stays recognizable. Lightness is *mapped* (not inverted) into the dark window. Use for brand buttons, CTAs, status banners. |
882
+ | `'static'` | No adaptation. Same value in every scheme. |
1218
883
 
1219
- ### How relative tone adapts
884
+ ### How relative lightness adapts
1220
885
 
1221
- **`auto`** — the offset is anchored to the base's per-scheme tone:
886
+ **`auto`** — relative lightness sign flips in dark scheme:
1222
887
 
1223
888
  ```
1224
- Light: surface tone=97, text tone='-52' → tone 45 (dark text on light bg)
1225
- Dark: surface inverts to a low tone; the '-52' offset re-anchors to the
1226
- base's light tone and maps into the dark window (light text on dark bg)
889
+ Light: surface L=97, text lightness='-52' → L=45 (dark text on light bg)
890
+ Dark: surface inverts to L≈20 (Möbius), sign flips → L=20+52=72
891
+ contrast solver may push further (light text on dark bg)
1227
892
  ```
1228
893
 
1229
- **`fixed`** — tone is mapped (not inverted), relative sign preserved:
894
+ **`fixed`** — lightness is mapped (not inverted), relative sign preserved:
1230
895
 
1231
896
  ```
1232
- Light: accent-fill tone=52, accent-text tone='+20' → lighter than the fill
1233
- Dark: accent-fill maps into the dark window, sign preserved
897
+ Light: accent-fill L=52, accent-text lightness='+48' → L=100 (white on brand)
898
+ Dark: accent-fill maps to L≈51.6, sign preserved → L≈99.6
1234
899
  ```
1235
900
 
1236
- Offsets that would push past `[0, 100]` clamp to the boundary, or — with `autoFlip` (default on) — mirror to the other side of the base. Set `autoFlip: false` to keep the authored side and clamp instead.
1237
-
1238
- **`static`** — no adaptation, same tone in every scheme.
901
+ **`static`** — no adaptation, same value in every scheme.
1239
902
 
1240
903
  ---
1241
904
 
1242
905
  ## Light / dark scheme mapping
1243
906
 
1244
- The mapping is now a single tone pipeline; there is no Möbius curve. See [`docs/okhst.md`](okhst.md) for the full math and the calibrated default constants.
1245
-
1246
- ### Light scheme
907
+ ### Light scheme — lightness
1247
908
 
1248
- An authored tone (0–100) is remapped into the `lightTone` window. The window's `lo`/`hi` are OKHSL-lightness endpoints (0–100); the tone is positioned within the window's tone interval and converted to a final OKHSL lightness. `static` mode and HC variants use the full range.
909
+ Absolute lightness values (root colors and dependent colors with absolute lightness) are mapped linearly within the configured `lightLightness` window:
1249
910
 
1250
- ```
1251
- window = lightTone // default [10, 100]
1252
- finalTone = remap(authorTone, window)
1253
- finalL = fromTone(finalTone) // OKHSL lightness
911
+ ```ts
912
+ const [lo, hi] = lightLightness; // default: [10, 100]
913
+ const mappedL = (lightness * (hi - lo)) / 100 + lo;
1254
914
  ```
1255
915
 
1256
- ### Dark scheme
916
+ Both `auto` and `fixed` modes use the same linear formula. `static` mode and HC variants bypass the mapping (identity: `mappedL = l`).
1257
917
 
1258
- **`auto`** — invert the tone, then remap into the dark window:
918
+ | Color | Raw L | Mapped L (default `[10, 100]`) |
919
+ |---|---|---|
920
+ | surface (L=97) | 97 | 97.3 |
921
+ | accent-fill (L=52) | 52 | 56.8 |
922
+ | near-black (L=0) | 0 | 10 |
1259
923
 
1260
- ```
1261
- window = darkTone // default [15, 95]
1262
- inverted = 100 - authorTone
1263
- finalTone = remap(inverted, window)
924
+ ### Dark scheme — lightness
925
+
926
+ **`auto`** — inverted with a Möbius transformation within the configured window:
927
+
928
+ ```ts
929
+ const [lo, hi] = darkLightness; // default: [15, 95]
930
+ const t = (100 - lightness) / 100;
931
+ const invertedL = lo + (hi - lo) * t / (t + darkCurve * (1 - t));
932
+ // darkCurve default: 0.5
1264
933
  ```
1265
934
 
1266
- Because tone is contrast-uniform, the inversion preserves contrast steps without a fitted curve — the asymmetry between light and dark lives entirely in the two windows' `(lo, hi, eps)` scalars (`eps` defaults to the reference `0.05`).
935
+ The `darkCurve` parameter (default `0.5`, range 0–1) controls how much the dark-mode inversion expands lightness deltas. Lower values produce stronger expansion; `1` gives linear (legacy) behavior. Accepts `[normal, highContrast]` pairs (e.g. `darkCurve: [0.5, 0.3]`).
1267
936
 
1268
- **`fixed`** — remap into the dark window without inversion:
937
+ Unlike a power curve, the Möbius transformation provides **proportional expansion** — small and large deltas are scaled by similar ratios, preserving the visual hierarchy of the light theme.
1269
938
 
939
+ **`fixed`** — mapped without inversion (not affected by `darkCurve`):
940
+
941
+ ```ts
942
+ const mappedL = (lightness * (hi - lo)) / 100 + lo;
1270
943
  ```
1271
- finalTone = remap(authorTone, darkTone)
1272
- ```
1273
944
 
1274
- In high-contrast variants both windows are bypassed (forced to the full `[0, 100]` range): `auto` still inverts, `fixed`/`static` do not.
945
+ | Color | Light L | Auto (curve=0.5) | Auto (curve=1, linear) | Fixed (mapped) |
946
+ |---|---|---|---|---|
947
+ | surface (L=97) | 97 | 19.7 | 17.4 | 92.6 |
948
+ | accent-fill (L=52) | 52 | 66.9 | 53.4 | 56.6 |
949
+ | accent-text (L=100) | 100 | 15 | 15 | 95 |
950
+
951
+ In high-contrast variants the `darkLightness` window is bypassed — `auto` uses the Möbius curve over the full `[0, 100]` range, `fixed` uses identity.
1275
952
 
1276
953
  ### Dark scheme — saturation
1277
954
 
@@ -1289,9 +966,10 @@ S_dark = S_light * (1 - darkDesaturation) // default: 0.1
1289
966
 
1290
967
  ```ts
1291
968
  glaze.configure({
1292
- lightTone: [10, 100], // [lo, hi]; or { lo, hi, eps } / false to disable clamping
1293
- darkTone: [15, 95], // [lo, hi]; or { lo, hi, eps } / false to disable clamping
969
+ lightLightness: [10, 100], // or false to disable clamping
970
+ darkLightness: [15, 95], // or false to disable clamping
1294
971
  darkDesaturation: 0.1,
972
+ darkCurve: 0.5, // or [normal, hc] pair
1295
973
  states: {
1296
974
  dark: '@dark',
1297
975
  highContrast: '@high-contrast',
@@ -1307,23 +985,20 @@ glaze.configure({
1307
985
  });
1308
986
  ```
1309
987
 
1310
- A `ToneWindow` is `[lo, hi]` (OKHSL-lightness endpoints, reference eps — the common form), `{ lo, hi, eps }` (advanced: explicit per-mode render eps), or `false` to disable clamping (full range `[0, 100]` at the reference eps). `false` removes the *boundaries*, not the contrast-uniform tone curve.
1311
-
1312
988
  `GlazeConfig`:
1313
989
 
1314
990
  | Field | Default | Description |
1315
991
  |---|---|---|
1316
- | `lightTone` | `[10, 100]` | Light scheme tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` to disable clamping. Bypassed in HC. |
1317
- | `darkTone` | `[15, 95]` | Dark scheme tone window: `[lo, hi]`, `{ lo, hi, eps }`, or `false` to disable clamping. Bypassed in HC. |
992
+ | `lightLightness` | `[10, 100]` | Light scheme lightness window `[lo, hi]`, or `false` to disable clamping (equivalent to `[0, 100]`). Bypassed in HC. |
993
+ | `darkLightness` | `[15, 95]` | Dark scheme lightness window, or `false` to disable clamping. Bypassed in HC. |
1318
994
  | `darkDesaturation` | `0.1` | Saturation reduction in dark scheme (0–1). |
995
+ | `darkCurve` | `0.5` | Möbius beta for dark `auto`-inversion (0–1). Accepts `[normal, hc]` pair. |
1319
996
  | `states.dark` | `'@dark'` | State alias for dark mode tokens (Tasty export). |
1320
997
  | `states.highContrast` | `'@high-contrast'` | State alias for HC tokens. |
1321
998
  | `modes.dark` | `true` | Include dark variants in exports. |
1322
999
  | `modes.highContrast` | `false` | Include HC variants. |
1323
1000
  | `shadowTuning` | `undefined` | Default tuning for all shadow colors. Per-color tuning merges field-by-field. |
1324
- | `autoFlip` | `true` | Default for each color's `autoFlip`. When solving `contrast` (or applying a relative `tone` that overshoots `[0, 100]`), allow crossing to the opposite side instead of clamping. With `false`, only the requested direction is considered; unmet contrasts pin the tone to that direction's extreme (and emit a warning) and overshooting offsets clamp to the boundary. Override per color via [`autoFlip`](#autoflip). |
1325
- | `pastel` | `false` | Hue-independent "safe" chroma limit across all colors so scaling saturation never exceeds the sRGB boundary at any hue for the given lightness. Override per color via [`pastel`](#per-color-pastel). |
1326
- | `inferRole` | `true` | Infer each color's [`role`](#roles) from its name when no explicit `role` is set. Set to `false` to opt out of name-based inference (the base-opposite and foreground-default fallbacks still apply). |
1001
+ | `autoFlip` | `true` | When solving `contrast`, allow the solver to switch away from the requested lightness direction if that side can't meet the target. With `false`, only the requested direction is considered; unmet contrasts pin the lightness to that direction's extreme (and emit a warning). |
1327
1002
 
1328
1003
  | Method | Description |
1329
1004
  |---|---|
@@ -1364,12 +1039,10 @@ Resolution priority (highest first):
1364
1039
  | Condition | Behavior |
1365
1040
  |---|---|
1366
1041
  | `contrast` without `base` in a **theme** color | Validation error |
1367
- | Relative `tone` without `base` in a **theme** color | Validation error |
1042
+ | Relative `lightness` without `base` in a **theme** color | Validation error |
1368
1043
  | `contrast` without `base` in `glaze.color()` | Anchors against the literal seed (no error) |
1369
- | Relative `tone` without `base` in `glaze.color()` | Anchors against the literal seed (no error) |
1370
- | Relative `tone` overshoots `[0, 100]` | Mirror to the other side of the base (`autoFlip` on, default), or clamp to the boundary (`autoFlip` off) |
1371
- | `tone` resolves outside 0–100 | Clamp silently |
1372
- | `'max'` / `'min'` without `base` | Allowed — resolves to the scheme's tone extreme (root color) |
1044
+ | Relative `lightness` without `base` in `glaze.color()` | Anchors against the literal seed (no error) |
1045
+ | `lightness` resolves outside 0–100 | Clamp silently |
1373
1046
  | `saturation` outside 0–1 | Clamp silently |
1374
1047
  | Circular `base` references | Validation error |
1375
1048
  | `base` references non-existent name | Validation error |
@@ -1439,68 +1112,35 @@ formatOklch(280, 60, 95); // 'oklch(0.95 ... 280)'
1439
1112
 
1440
1113
  To attach an alpha component, use `glaze.format(variant, format)` on a `ResolvedColorVariant` (which carries the `alpha` channel) instead of these raw writers.
1441
1114
 
1442
- ### OKHST tone utilities
1443
-
1444
- ```ts
1445
- import {
1446
- toTone,
1447
- fromTone,
1448
- toneFromY,
1449
- yFromTone,
1450
- okhstToOkhsl,
1451
- okhslToOkhst,
1452
- variantToOkhsl,
1453
- REF_EPS,
1454
- } from '@tenphi/glaze';
1455
- ```
1456
-
1457
- | Function | Description |
1458
- |---|---|
1459
- | `toTone(l, eps?)` | OKHSL lightness (0–1) → tone (0–100). Defaults to `REF_EPS`. |
1460
- | `fromTone(t, eps?)` | Tone (0–100) → OKHSL lightness (0–1). Inverse of `toTone`. |
1461
- | `toneFromY(y, eps?)` / `yFromTone(t, eps?)` | Same transfer in luminance space (0–1). |
1462
- | `okhstToOkhsl({ h, s, t })` | OKHST → OKHSL (`{ h, s, l }`). |
1463
- | `okhslToOkhst({ h, s, l })` | OKHSL → OKHST (`{ h, s, t }`). |
1464
- | `variantToOkhsl(variant)` | `ResolvedColorVariant` (stores `t`) → `{ h, s, l, alpha }` for rendering. |
1465
- | `REF_EPS` | Reference epsilon (`0.05`) for the canonical tone axis. |
1466
-
1467
- `ResolvedColorVariant` now stores `{ h, s, t, alpha }` (tone, not lightness). Use `variantToOkhsl(variant).l` to recover OKHSL lightness. See [`docs/okhst.md`](okhst.md) for the full model.
1468
-
1469
1115
  ### Contrast solver
1470
1116
 
1471
1117
  ```ts
1472
1118
  import {
1473
- findToneForContrast,
1119
+ findLightnessForContrast,
1474
1120
  findValueForMixContrast,
1475
- resolveContrastForMode,
1476
1121
  resolveMinContrast,
1477
- apcaContrast,
1478
1122
  } from '@tenphi/glaze';
1479
1123
  ```
1480
1124
 
1481
1125
  | Function | Description |
1482
1126
  |---|---|
1483
- | `findToneForContrast(opts)` | Binary-search for the tone (0–1) that meets a contrast floor (WCAG or APCA) against a base color. Returns `{ tone, contrast, met, branch, flipped? }`. |
1127
+ | `findLightnessForContrast(opts)` | Binary-search for the OKHSL lightness that meets a WCAG contrast floor against a base color. Returns `{ lightness, contrast, met, branch }`. |
1484
1128
  | `findValueForMixContrast(opts)` | Same, but searches for a mix `value` (0–1) that meets a contrast floor between a base and a target. |
1485
- | `resolveContrastForMode(spec, isHC, polarity?, outerExplicitHC?)` | Resolves a `ContrastSpec` to `{ metric: 'wcag' \| 'apca', target }` for the requested mode (picks the normal or HC entry of any pair). In HC, applies the metric's auto-enhancement unless `outerExplicitHC` is set or the inner metric pair carries an explicit HC value: APCA +15 Lc (clamped to 106); WCAG AA → AAA / AA-large → AAA-large (AAA-family and bare numbers unchanged). |
1486
- | `resolveMinContrast(value)` | Resolves a `MinContrast` (WCAG preset or number) to a numeric ratio. |
1487
- | `apcaContrast(yText, yBg)` | APCA Lc magnitude (0–106) for two relative luminances. |
1488
-
1489
- Exported constants: `APCA_PRESETS`, `APCA_HC_ENHANCEMENT` (`15`, the Enhanced Level delta), `APCA_MAX_LC` (`106`).
1129
+ | `resolveMinContrast(value)` | Resolves a `MinContrast` (preset or number) to a numeric ratio. |
1490
1130
 
1491
- `findToneForContrast` options:
1131
+ `findLightnessForContrast` options:
1492
1132
 
1493
1133
  | Option | Default | Description |
1494
1134
  |---|---|---|
1495
1135
  | `hue` | — | Candidate hue (0–360). |
1496
1136
  | `saturation` | — | Candidate saturation (0–1). |
1497
- | `preferredTone` | — | Preferred candidate tone (0–1). Kept if it already meets the target. |
1137
+ | `preferredLightness` | — | Preferred candidate lightness (0–1). Kept if it already meets the target. |
1498
1138
  | `baseLinearRgb` | — | Base color as linear sRGB tuple. |
1499
- | `contrast` | — | `ResolvedContrast` (`{ metric, target }`). |
1500
- | `toneRange` | `[0, 1]` | Search bounds in tone. |
1139
+ | `contrast` | — | WCAG floor (`MinContrast`). |
1140
+ | `lightnessRange` | `[0, 1]` | Search bounds. |
1501
1141
  | `epsilon` | `1e-4` | Convergence threshold. |
1502
- | `maxIterations` | `18` | Max binary-search iterations per branch. |
1503
- | `initialDirection` | higher-contrast side | Direction to search first (`'lighter'` or `'darker'`). |
1142
+ | `maxIterations` | `14` | Max binary-search iterations per branch. |
1143
+ | `initialDirection` | higher-contrast side | Direction to search first (`'lighter'` or `'darker'`). Theme resolution sets this from the requested lightness relative to the base color. |
1504
1144
  | `flip` | `false` | When `true`, try the opposite direction if the initial one doesn't meet the target. When `false`, only the initial direction is searched — unmet contrasts pin the result to that direction's extreme. |
1505
1145
 
1506
- Result: `{ tone, contrast, met, branch: 'lighter' | 'darker' | 'preferred', flipped? }`. `flipped: true` indicates the initial direction failed and the opposite direction satisfied the target.
1146
+ Result: `{ lightness, contrast, met, branch: 'lighter' | 'darker' | 'preferred', flipped? }`. `flipped: true` indicates the initial direction failed and the opposite direction satisfied the target.