@cube-dev/ui-kit 0.0.0-canary-7c5dc45 → 0.0.0-canary-7d44972
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.
- package/dist/CHANGELOG.md +8 -0
- package/dist/_internal/hooks/use-chained-callback.js +1 -1
- package/dist/_internal/hooks/use-debounced-value.js +1 -1
- package/dist/_internal/hooks/use-deprecation-warning.js +1 -1
- package/dist/_internal/hooks/use-event.js +1 -1
- package/dist/_internal/hooks/use-is-first-render.js +1 -1
- package/dist/_internal/hooks/use-sync-ref.js +1 -1
- package/dist/_internal/hooks/use-timer/timer.js +1 -1
- package/dist/_internal/hooks/use-timer/use-timer.js +1 -1
- package/dist/_internal/hooks/use-warn.js +1 -1
- package/dist/components/Block.js +1 -1
- package/dist/components/CollectionItem.js +1 -1
- package/dist/components/GlobalStyles.js +7 -7
- package/dist/components/GlobalStyles.js.map +1 -1
- package/dist/components/GridProvider.js +1 -1
- package/dist/components/HiddenInput.js +1 -1
- package/dist/components/Root.js +1 -1
- package/dist/components/actions/Action/Action.js +1 -1
- package/dist/components/actions/Banner/Banner.js +1 -1
- package/dist/components/actions/Button/Button.js +1 -1
- package/dist/components/actions/ButtonGroup/ButtonGroup.js +1 -1
- package/dist/components/actions/ButtonSplit/ButtonSplit.js +1 -1
- package/dist/components/actions/ButtonSplit/context.js +1 -1
- package/dist/components/actions/CommandMenu/CommandMenu.js +1 -1
- package/dist/components/actions/CommandMenu/styled.js +1 -1
- package/dist/components/actions/ItemAction/ItemAction.js +1 -1
- package/dist/components/actions/ItemActionContext.js +1 -1
- package/dist/components/actions/ItemButton/ItemButton.js +1 -1
- package/dist/components/actions/Link/Link.js +1 -1
- package/dist/components/actions/Menu/Menu.js +1 -1
- package/dist/components/actions/Menu/MenuItem.js +1 -1
- package/dist/components/actions/Menu/MenuSection.js +1 -1
- package/dist/components/actions/Menu/MenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubMenuTrigger.js +1 -1
- package/dist/components/actions/Menu/SubmenuTriggerContext.js +1 -1
- package/dist/components/actions/Menu/context.js +1 -1
- package/dist/components/actions/Menu/styled.js +1 -1
- package/dist/components/actions/index.js +1 -1
- package/dist/components/actions/use-action.js +1 -1
- package/dist/components/actions/use-action.js.map +1 -1
- package/dist/components/actions/use-anchored-menu.js +1 -1
- package/dist/components/actions/use-context-menu.js +1 -1
- package/dist/components/content/ActiveZone/ActiveZone.js +1 -1
- package/dist/components/content/Alert/Alert.js +1 -1
- package/dist/components/content/Alert/use-alert.js +1 -1
- package/dist/components/content/Avatar/Avatar.js +1 -1
- package/dist/components/content/Badge/Badge.js +1 -1
- package/dist/components/content/Card/Card.js +1 -1
- package/dist/components/content/Content.js +1 -1
- package/dist/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
- package/dist/components/content/CopySnippet/CopySnippet.js +4 -4
- package/dist/components/content/CopySnippet/CopySnippet.js.map +1 -1
- package/dist/components/content/Disclosure/Disclosure.js +1 -1
- package/dist/components/content/Divider.js +1 -1
- package/dist/components/content/Footer.js +1 -1
- package/dist/components/content/Header.js +1 -1
- package/dist/components/content/HotKeys/HotKeys.js +1 -1
- package/dist/components/content/InfoBadge/InfoBadge.js +1 -1
- package/dist/components/content/InlineInput/InlineInput.js +1 -1
- package/dist/components/content/Item/Item.js +1 -1
- package/dist/components/content/ItemBadge/ItemBadge.js +1 -1
- package/dist/components/content/ItemCard/ItemCard.js +1 -1
- package/dist/components/content/Layout/GridLayout.js +1 -1
- package/dist/components/content/Layout/Layout.js +1 -1
- package/dist/components/content/Layout/LayoutBlock.js +1 -1
- package/dist/components/content/Layout/LayoutCenter.js +1 -1
- package/dist/components/content/Layout/LayoutContainer.js +1 -1
- package/dist/components/content/Layout/LayoutContent.js +1 -1
- package/dist/components/content/Layout/LayoutContext.js +1 -1
- package/dist/components/content/Layout/LayoutFlex.js +1 -1
- package/dist/components/content/Layout/LayoutFooter.js +1 -1
- package/dist/components/content/Layout/LayoutGrid.js +1 -1
- package/dist/components/content/Layout/LayoutHeader.js +1 -1
- package/dist/components/content/Layout/LayoutPane.js +1 -1
- package/dist/components/content/Layout/LayoutPanel.js +1 -1
- package/dist/components/content/Layout/LayoutPanelHeader.js +1 -1
- package/dist/components/content/Layout/LayoutToolbar.js +1 -1
- package/dist/components/content/Layout/hooks/useTinyScrollbar.js +1 -1
- package/dist/components/content/Layout/index.js +1 -1
- package/dist/components/content/Layout/utils.js +1 -1
- package/dist/components/content/Paragraph.js +1 -1
- package/dist/components/content/Placeholder/Placeholder.js +1 -1
- package/dist/components/content/PrismCode/PrismCode.js +2 -6
- package/dist/components/content/PrismCode/PrismCode.js.map +1 -1
- package/dist/components/content/PrismCode/prismSetup.js +1 -1
- package/dist/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
- package/dist/components/content/Result/Result.js +1 -1
- package/dist/components/content/Skeleton/Skeleton.js +1 -1
- package/dist/components/content/Tag/Tag.js +1 -1
- package/dist/components/content/Text.js +1 -1
- package/dist/components/content/TextItem/TextItem.js +1 -1
- package/dist/components/content/Title.js +1 -1
- package/dist/components/content/Tree/Tree.js +1 -1
- package/dist/components/content/Tree/TreeNode.js +1 -1
- package/dist/components/content/Tree/styled.js +1 -1
- package/dist/components/content/Tree/tree-index.js +1 -1
- package/dist/components/content/Tree/use-checkbox-tree.js +1 -1
- package/dist/components/content/Tree/use-load-data.js +1 -1
- package/dist/components/content/highlightText.js +1 -1
- package/dist/components/content/use-auto-tooltip.js +1 -1
- package/dist/components/fields/Checkbox/Checkbox.js +1 -1
- package/dist/components/fields/Checkbox/CheckboxGroup.js +1 -1
- package/dist/components/fields/Checkbox/context.js +1 -1
- package/dist/components/fields/ComboBox/ComboBox.js +1 -1
- package/dist/components/fields/CommandTextArea/CommandTextArea.js +1 -1
- package/dist/components/fields/CommandTextArea/caretPosition.js +1 -1
- package/dist/components/fields/CommandTextArea/useCaretAnchor.js +1 -1
- package/dist/components/fields/DatePicker/DateInput.js +1 -1
- package/dist/components/fields/DatePicker/DateInputBase.js +1 -1
- package/dist/components/fields/DatePicker/DatePicker.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerButton.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerElement.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerInput.js +1 -1
- package/dist/components/fields/DatePicker/DatePickerSegment.js +1 -1
- package/dist/components/fields/DatePicker/DateRangePicker.js +1 -1
- package/dist/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
- package/dist/components/fields/DatePicker/TimeInput.js +1 -1
- package/dist/components/fields/DatePicker/parseDate.js +1 -1
- package/dist/components/fields/DatePicker/props.js +1 -1
- package/dist/components/fields/DatePicker/utils.js +1 -1
- package/dist/components/fields/FileInput/FileInput.js +1 -1
- package/dist/components/fields/FilterListBox/FilterListBox.js +1 -1
- package/dist/components/fields/FilterPicker/FilterPicker.js +2 -1
- package/dist/components/fields/FilterPicker/FilterPicker.js.map +1 -1
- package/dist/components/fields/Input/Input.js +1 -1
- package/dist/components/fields/ListBox/DraggableListBox.js +1 -1
- package/dist/components/fields/ListBox/ListBox.js +1 -1
- package/dist/components/fields/ListBoxPopover/ListBoxPopover.js +1 -1
- package/dist/components/fields/ListBoxPopover/listNavigation.js +1 -1
- package/dist/components/fields/ListBoxPopover/useCompositeFocus.js +1 -1
- package/dist/components/fields/NumberInput/NumberInput.js +1 -1
- package/dist/components/fields/NumberInput/StepButton.js +1 -1
- package/dist/components/fields/PasswordInput/PasswordInput.js +1 -1
- package/dist/components/fields/Picker/Picker.js +1 -1
- package/dist/components/fields/RadioGroup/Radio.js +1 -1
- package/dist/components/fields/RadioGroup/RadioGroup.js +1 -1
- package/dist/components/fields/RadioGroup/context.js +1 -1
- package/dist/components/fields/SearchComboBox/SearchComboBox.js +1 -1
- package/dist/components/fields/SearchInput/SearchInput.js +1 -1
- package/dist/components/fields/Select/Select.js +1 -1
- package/dist/components/fields/Slider/Gradation.js +1 -1
- package/dist/components/fields/Slider/HueSlider.js +1 -1
- package/dist/components/fields/Slider/RangeSlider.js +1 -1
- package/dist/components/fields/Slider/Slider.js +1 -1
- package/dist/components/fields/Slider/SliderBase.js +1 -1
- package/dist/components/fields/Slider/SliderThumb.js +1 -1
- package/dist/components/fields/Slider/SliderTrack.js +1 -1
- package/dist/components/fields/Slider/elements.js +1 -1
- package/dist/components/fields/Slider/index.js +1 -1
- package/dist/components/fields/Switch/Switch.js +1 -1
- package/dist/components/fields/TextArea/TextArea.js +1 -1
- package/dist/components/fields/TextInput/TextInput.js +1 -1
- package/dist/components/fields/TextInput/TextInputBase.js +1 -1
- package/dist/components/fields/TextInputMapper/TextInputMapper.js +1 -1
- package/dist/components/form/FieldWrapper/FieldWrapper.js +1 -1
- package/dist/components/form/Form/Field.js +1 -1
- package/dist/components/form/Form/Form.js +1 -1
- package/dist/components/form/Form/ResetButton/ResetButton.js +1 -1
- package/dist/components/form/Form/SubmitButton/SubmitButton.js +1 -1
- package/dist/components/form/Form/SubmitError.js +1 -1
- package/dist/components/form/Form/index.js +1 -1
- package/dist/components/form/Form/use-field/use-field-props.js +1 -1
- package/dist/components/form/Form/use-field/use-field.js +1 -1
- package/dist/components/form/Form/use-form.js +1 -1
- package/dist/components/form/Form/validation.js +1 -1
- package/dist/components/form/Label.js +1 -1
- package/dist/components/form/validation/ValidationIndicator.js +1 -1
- package/dist/components/form/validation/resolve-validation-props.js +1 -1
- package/dist/components/form/validation/use-validation-props.js +1 -1
- package/dist/components/form/wrapper.js +1 -1
- package/dist/components/helpers/DisplayTransition/DisplayTransition.js +1 -1
- package/dist/components/helpers/IconSwitch/IconSwitch.js +1 -1
- package/dist/components/layout/Board/Board.js +1 -1
- package/dist/components/layout/Board/BoardProvider.js +1 -1
- package/dist/components/layout/Board/BoardResponsive.js +1 -1
- package/dist/components/layout/Board/Widget.js +1 -1
- package/dist/components/layout/Board/WidgetHost.js +1 -1
- package/dist/components/layout/Board/board-context.js +1 -1
- package/dist/components/layout/Board/board-store.js +1 -1
- package/dist/components/layout/Board/grid-core/calculate.js +1 -1
- package/dist/components/layout/Board/grid-core/collision.js +1 -1
- package/dist/components/layout/Board/grid-core/compactors.js +1 -1
- package/dist/components/layout/Board/grid-core/constraints.js +1 -1
- package/dist/components/layout/Board/grid-core/layout.js +1 -1
- package/dist/components/layout/Board/grid-core/sort.js +1 -1
- package/dist/components/layout/Board/index.js +1 -1
- package/dist/components/layout/Board/responsive-utils.js +1 -1
- package/dist/components/layout/Board/use-board-layout.js +1 -1
- package/dist/components/layout/Board/use-board-registry.js +1 -1
- package/dist/components/layout/Flex.js +1 -1
- package/dist/components/layout/Flow.js +1 -1
- package/dist/components/layout/Grid.js +1 -1
- package/dist/components/layout/Panel.js +1 -1
- package/dist/components/layout/Prefix.js +1 -1
- package/dist/components/layout/ResizablePanel.js +1 -1
- package/dist/components/layout/Space.js +1 -1
- package/dist/components/layout/Suffix.js +1 -1
- package/dist/components/navigation/Tabs/DraggableTabList.js +1 -1
- package/dist/components/navigation/Tabs/TabButton.js +1 -1
- package/dist/components/navigation/Tabs/TabDropIndicator.js +1 -1
- package/dist/components/navigation/Tabs/TabPanel.js +1 -1
- package/dist/components/navigation/Tabs/TabPicker.js +1 -1
- package/dist/components/navigation/Tabs/Tabs.js +1 -1
- package/dist/components/navigation/Tabs/TabsAction.js +1 -1
- package/dist/components/navigation/Tabs/TabsContext.js +1 -1
- package/dist/components/navigation/Tabs/popover-placement.js +1 -1
- package/dist/components/navigation/Tabs/styled.js +1 -1
- package/dist/components/navigation/Tabs/types.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-editing.js +1 -1
- package/dist/components/navigation/Tabs/use-tab-indicator.js +1 -1
- package/dist/components/organisms/FileTabs/FileTabs.js +1 -1
- package/dist/components/organisms/StatsCard/StatsCard.js +1 -1
- package/dist/components/other/Calendar/Calendar.js +1 -1
- package/dist/components/other/Calendar/CalendarCell.js +1 -1
- package/dist/components/other/Calendar/CalendarGrid.js +1 -1
- package/dist/components/other/Calendar/RangeCalendar.js +1 -1
- package/dist/components/other/CloudLogo/CloudLogo.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialog.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
- package/dist/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
- package/dist/components/overlays/Dialog/Dialog.js +1 -1
- package/dist/components/overlays/Dialog/DialogContainer.js +1 -1
- package/dist/components/overlays/Dialog/DialogForm.js +1 -1
- package/dist/components/overlays/Dialog/DialogTrigger.js +2 -2
- package/dist/components/overlays/Dialog/DialogTrigger.js.map +1 -1
- package/dist/components/overlays/Dialog/context.js +1 -1
- package/dist/components/overlays/Dialog/use-dialog-container.js +1 -1
- package/dist/components/overlays/Modal/Modal.js +1 -1
- package/dist/components/overlays/Modal/OpenTransitionContext.js +1 -1
- package/dist/components/overlays/Modal/Overlay.js +1 -1
- package/dist/components/overlays/Modal/Popover.js +1 -1
- package/dist/components/overlays/Modal/Tray.js +1 -1
- package/dist/components/overlays/Modal/Underlay.js +1 -1
- package/dist/components/overlays/Notifications/Notification.js +1 -1
- package/dist/components/overlays/Notifications/NotificationAction.js +1 -1
- package/dist/components/overlays/Notifications/NotificationCard.js +1 -1
- package/dist/components/overlays/Notifications/NotificationContext.js +1 -1
- package/dist/components/overlays/Notifications/NotificationItem.js +1 -1
- package/dist/components/overlays/Notifications/OverlayContainer.js +1 -1
- package/dist/components/overlays/Notifications/OverlayProvider.js +1 -1
- package/dist/components/overlays/Notifications/PersistentNotificationsList.js +1 -1
- package/dist/components/overlays/Notifications/dismissed-storage.js +1 -1
- package/dist/components/overlays/Notifications/format-relative-time.js +1 -1
- package/dist/components/overlays/Notifications/index.js +1 -1
- package/dist/components/overlays/Notifications/use-notification-state.js +1 -1
- package/dist/components/overlays/Notifications/use-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-overlay-timers.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-notifications.js +1 -1
- package/dist/components/overlays/Notifications/use-persistent-state.js +1 -1
- package/dist/components/overlays/Notifications/use-toast-state.js +1 -1
- package/dist/components/overlays/Toast/ToastItem.js +1 -1
- package/dist/components/overlays/Toast/index.js +1 -1
- package/dist/components/overlays/Toast/useProgressToast.js +1 -1
- package/dist/components/overlays/Toast/useToast.js +1 -1
- package/dist/components/overlays/Tooltip/Tooltip.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipProvider.js +1 -1
- package/dist/components/overlays/Tooltip/TooltipTrigger.js +1 -1
- package/dist/components/overlays/Tooltip/context.js +1 -1
- package/dist/components/portal/Portal.js +1 -1
- package/dist/components/portal/PortalProvider.js +1 -1
- package/dist/components/portal/usePortal.js +1 -1
- package/dist/components/shared/DraggableCollection.js +1 -1
- package/dist/components/shared/InvalidIcon.js +1 -1
- package/dist/components/shared/ValidIcon.js +1 -1
- package/dist/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
- package/dist/components/status/Spin/Cube.js +1 -1
- package/dist/components/status/Spin/InternalSpinner.js +1 -1
- package/dist/components/status/Spin/Spin.js +1 -1
- package/dist/components/status/Spin/SpinsContainer.js +1 -1
- package/dist/data/item-themes.js +3 -5
- package/dist/data/item-themes.js.map +1 -1
- package/dist/data/themes.js +1 -1
- package/dist/i18n/I18nProvider.js +1 -1
- package/dist/i18n/createFormatter.js +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/instance.js +1 -1
- package/dist/i18n/locales/de-DE/uikit.js +1 -1
- package/dist/i18n/locales/en-US/uikit.js +1 -1
- package/dist/i18n/locales/es-ES/uikit.js +1 -1
- package/dist/i18n/locales/es-MX/uikit.js +1 -1
- package/dist/i18n/locales/fr-FR/uikit.js +1 -1
- package/dist/i18n/locales/it-IT/uikit.js +1 -1
- package/dist/i18n/locales/ja-JP/uikit.js +1 -1
- package/dist/i18n/locales/nb-NO/uikit.js +1 -1
- package/dist/i18n/locales/pt-BR/uikit.js +1 -1
- package/dist/i18n/locales/pt-PT/uikit.js +1 -1
- package/dist/i18n/locales/sv-SE/uikit.js +1 -1
- package/dist/i18n/locales/vi-VN/uikit.js +1 -1
- package/dist/i18n/locales.js +1 -1
- package/dist/i18n/useFormatter.js +1 -1
- package/dist/i18n/useI18n.js +1 -1
- package/dist/icons/AdjustmentsHorizontalIcon.js +1 -1
- package/dist/icons/AdjustmentsIcon.js +1 -1
- package/dist/icons/AiIcon.js +1 -1
- package/dist/icons/AreaChartIcon.js +1 -1
- package/dist/icons/BackwardIcon.js +1 -1
- package/dist/icons/BarChartIcon.js +1 -1
- package/dist/icons/BellFilledIcon.js +1 -1
- package/dist/icons/BellIcon.js +1 -1
- package/dist/icons/BooleanIcon.js +1 -1
- package/dist/icons/CalendarEditIcon.js +1 -1
- package/dist/icons/CalendarIcon.js +1 -1
- package/dist/icons/CaretDownIcon.js +1 -1
- package/dist/icons/CaretUpIcon.js +1 -1
- package/dist/icons/ChartAreaStackedIcon.js +1 -1
- package/dist/icons/ChartAreaStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBarGroupedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarGroupedIcon.js +1 -1
- package/dist/icons/ChartBarHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarLineIcon.js +1 -1
- package/dist/icons/ChartBarStackedHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
- package/dist/icons/ChartBarStackedPercentageIcon.js +1 -1
- package/dist/icons/ChartBoxPlot2Icon.js +1 -1
- package/dist/icons/ChartBoxPlotIcon.js +1 -1
- package/dist/icons/ChartBubbleIcon.js +1 -1
- package/dist/icons/ChartDonut2Icon.js +1 -1
- package/dist/icons/ChartFunnelIcon.js +1 -1
- package/dist/icons/ChartHeatmapIcon.js +1 -1
- package/dist/icons/ChartKPIIcon.js +1 -1
- package/dist/icons/ChartPie2Icon.js +1 -1
- package/dist/icons/ChartScatterIcon.js +1 -1
- package/dist/icons/CheckCircleFilledIcon.js +1 -1
- package/dist/icons/CheckCircleIcon.js +1 -1
- package/dist/icons/CheckIcon.js +1 -1
- package/dist/icons/CircleFilledIcon.js +1 -1
- package/dist/icons/ClearIcon.js +1 -1
- package/dist/icons/CloseCircleFilledIcon.js +1 -1
- package/dist/icons/CloseCircleIcon.js +1 -1
- package/dist/icons/CloseIcon.js +1 -1
- package/dist/icons/CodeIcon.js +1 -1
- package/dist/icons/ColumnTotalIcon.js +1 -1
- package/dist/icons/CopyIcon.js +1 -1
- package/dist/icons/CountIcon.js +1 -1
- package/dist/icons/CubeIcon.js +1 -1
- package/dist/icons/CubePauseIcon.js +1 -1
- package/dist/icons/CubePlayIcon.js +1 -1
- package/dist/icons/CurrencyDollarIcon.js +1 -1
- package/dist/icons/DangerIcon.js +1 -1
- package/dist/icons/DashboardIcon.js +1 -1
- package/dist/icons/DatabaseIcon.js +1 -1
- package/dist/icons/DecimalDecreaseIcon.js +1 -1
- package/dist/icons/DecimalIncreaseIcon.js +1 -1
- package/dist/icons/DirectionIcon.js +1 -1
- package/dist/icons/DonutIcon.js +1 -1
- package/dist/icons/DownIcon.js +1 -1
- package/dist/icons/EditIcon.js +1 -1
- package/dist/icons/ExclamationCircleFilledIcon.js +1 -1
- package/dist/icons/ExclamationCircleIcon.js +1 -1
- package/dist/icons/ExclamationIcon.js +1 -1
- package/dist/icons/EyeIcon.js +1 -1
- package/dist/icons/EyeInvisibleIcon.js +1 -1
- package/dist/icons/FilterIcon.js +1 -1
- package/dist/icons/FolderFilledIcon.js +1 -1
- package/dist/icons/FolderIcon.js +1 -1
- package/dist/icons/FolderOpenFilledIcon.js +1 -1
- package/dist/icons/FolderOpenIcon.js +1 -1
- package/dist/icons/ForwardIcon.js +1 -1
- package/dist/icons/GripVerticalIcon.js +1 -1
- package/dist/icons/HierarchyIcon.js +1 -1
- package/dist/icons/HierarchyOpenIcon.js +1 -1
- package/dist/icons/Icon.js +1 -1
- package/dist/icons/InfoCircleIcon.js +1 -1
- package/dist/icons/InfoIcon.js +1 -1
- package/dist/icons/KeyIcon.js +1 -1
- package/dist/icons/LeftIcon.js +1 -1
- package/dist/icons/LineChartIcon.js +1 -1
- package/dist/icons/LoadingIcon.js +1 -1
- package/dist/icons/LockFilledIcon.js +1 -1
- package/dist/icons/LockIcon.js +1 -1
- package/dist/icons/MoreIcon.js +1 -1
- package/dist/icons/NotAllowedIcon.js +1 -1
- package/dist/icons/Number123Icon.js +1 -1
- package/dist/icons/NumberIcon.js +1 -1
- package/dist/icons/PauseCircleFilledIcon.js +1 -1
- package/dist/icons/PauseCircleIcon.js +1 -1
- package/dist/icons/PauseIcon.js +1 -1
- package/dist/icons/PercentageIcon.js +1 -1
- package/dist/icons/PieChartIcon.js +1 -1
- package/dist/icons/PlayCircleIcon.js +1 -1
- package/dist/icons/PlayIcon.js +1 -1
- package/dist/icons/PlusIcon.js +1 -1
- package/dist/icons/ProgressBarIcon.js +1 -1
- package/dist/icons/ReloadIcon.js +1 -1
- package/dist/icons/ReportIcon.js +1 -1
- package/dist/icons/ReturnIcon.js +1 -1
- package/dist/icons/RightIcon.js +1 -1
- package/dist/icons/RowTotalsIcon.js +1 -1
- package/dist/icons/SchemeIcon.js +1 -1
- package/dist/icons/SearchIcon.js +1 -1
- package/dist/icons/SemanticQueryIcon.js +1 -1
- package/dist/icons/SettingsIcon.js +1 -1
- package/dist/icons/ShieldFilledIcon.js +1 -1
- package/dist/icons/ShieldIcon.js +1 -1
- package/dist/icons/SlashIcon.js +1 -1
- package/dist/icons/SparklesIcon.js +1 -1
- package/dist/icons/SqlIcon.js +1 -1
- package/dist/icons/StatsIcon.js +1 -1
- package/dist/icons/StopIcon.js +1 -1
- package/dist/icons/StringIcon.js +1 -1
- package/dist/icons/SubtotalsIcon.js +1 -1
- package/dist/icons/SwitchIcon.js +1 -1
- package/dist/icons/TableIcon.js +1 -1
- package/dist/icons/ThumbsDownIcon.js +1 -1
- package/dist/icons/ThumbsUpIcon.js +1 -1
- package/dist/icons/ThunderboltCrossedIcon.js +1 -1
- package/dist/icons/ThunderboltFilledIcon.js +1 -1
- package/dist/icons/ThunderboltIcon.js +1 -1
- package/dist/icons/TimeIcon.js +1 -1
- package/dist/icons/TrashIcon.js +1 -1
- package/dist/icons/UnlockIcon.js +1 -1
- package/dist/icons/UpIcon.js +1 -1
- package/dist/icons/UserGroupIcon.js +1 -1
- package/dist/icons/UserIcon.js +1 -1
- package/dist/icons/UserLockIcon.js +1 -1
- package/dist/icons/ViewIcon.js +1 -1
- package/dist/icons/WarningFilledIcon.js +1 -1
- package/dist/icons/WarningIcon.js +1 -1
- package/dist/icons/wrap-icon.js +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.js +4 -5
- package/dist/index.js.map +1 -1
- package/dist/provider.js +1 -1
- package/dist/providers/TrackingProvider.js +1 -1
- package/dist/providers/navigationAdapter.default.js +1 -1
- package/dist/tokens/base.js +1 -1
- package/dist/tokens/colors.d.ts +7 -2
- package/dist/tokens/colors.js +8 -16
- package/dist/tokens/colors.js.map +1 -1
- package/dist/tokens/index.d.ts +17 -5
- package/dist/tokens/index.js +13 -23
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/layout.js +1 -1
- package/dist/tokens/palette.js +126 -169
- package/dist/tokens/palette.js.map +1 -1
- package/dist/tokens/shadows.js +1 -1
- package/dist/tokens/sizes.js +1 -1
- package/dist/tokens/spacing.js +1 -1
- package/dist/tokens/typography.d.ts +0 -1
- package/dist/tokens/typography.js +1 -29
- package/dist/tokens/typography.js.map +1 -1
- package/dist/utils/ResizeSensor.js +1 -1
- package/dist/utils/is-dev-env.js +1 -1
- package/dist/utils/modules.js +1 -1
- package/dist/utils/promise.js +1 -1
- package/dist/utils/raf.js +1 -1
- package/dist/utils/random.js +1 -1
- package/dist/utils/range.js +1 -1
- package/dist/utils/react/RenderCache.js +1 -1
- package/dist/utils/react/Slots.js +1 -1
- package/dist/utils/react/chain.js +1 -1
- package/dist/utils/react/forwardRefWithGenerics.js +1 -1
- package/dist/utils/react/index.js +1 -1
- package/dist/utils/react/interactions.js +1 -1
- package/dist/utils/react/isTextOnly.js +1 -1
- package/dist/utils/react/mapProps.js +1 -1
- package/dist/utils/react/mergeProps.js +1 -1
- package/dist/utils/react/nullableValue.js +1 -1
- package/dist/utils/react/resolveIcon.js +1 -1
- package/dist/utils/react/sharedStore.js +1 -1
- package/dist/utils/react/useCombinedRefs.js +1 -1
- package/dist/utils/react/useControlledFocusVisible.js +1 -1
- package/dist/utils/react/useEventBus.js +1 -1
- package/dist/utils/react/useId.js +1 -1
- package/dist/utils/react/useIsDarwin.js +1 -1
- package/dist/utils/react/useKeySymbols.js +1 -1
- package/dist/utils/react/useLayoutEffect.js +1 -1
- package/dist/utils/react/useLocalStorage.js +1 -1
- package/dist/utils/react/useMergeStyles.js +1 -1
- package/dist/utils/react/usePopoverSync.js +1 -1
- package/dist/utils/react/useQaProps.js +1 -1
- package/dist/utils/react/useViewportSize.js +1 -1
- package/dist/utils/react/wrapNodeIfPlain.js +1 -1
- package/dist/utils/selection.js +1 -1
- package/dist/utils/styles.js +1 -1
- package/dist/utils/tree.js +1 -1
- package/dist/utils/warnings.js +1 -1
- package/dist/version.js +2 -2
- package/docs/Typography.md +1 -1
- package/docs/Usage.md +0 -10
- package/docs/components/content/CopySnippet.md +1 -1
- package/docs/components/content/PrismCode.md +0 -1
- package/docs/glaze/api.md +414 -1033
- package/docs/glaze/methodology.md +208 -536
- package/docs/glaze/migration.md +49 -127
- package/package.json +3 -3
- package/dist/tokens/lazy-styles.js +0 -33
- package/dist/tokens/lazy-styles.js.map +0 -1
- package/dist/tokens/palette.d.ts +0 -15
- package/docs/Colors.md +0 -77
- package/docs/glaze/okhst.md +0 -190
package/docs/glaze/api.md
CHANGED
|
@@ -6,18 +6,12 @@ Full reference for every public method, option, and type exported by `@tenphi/gl
|
|
|
6
6
|
|
|
7
7
|
- [Theme creation](#theme-creation)
|
|
8
8
|
- [Theme methods](#theme-methods)
|
|
9
|
-
- [DTCG](#themedtcgoptions)
|
|
10
|
-
- [DTCG Resolver-Module](#themedtcgresolveroptions)
|
|
11
|
-
- [Tailwind CSS](#themetailwindoptions)
|
|
12
|
-
- [High-contrast pairs](#high-contrast-pairs)
|
|
13
9
|
- [Color definitions](#color-definitions)
|
|
14
|
-
- [Dark seed](#dark-seed-darkhue--darksaturation)
|
|
15
10
|
- [Standalone color tokens](#standalone-color-tokens)
|
|
16
11
|
- [Shadows](#shadows)
|
|
17
12
|
- [Mix colors](#mix-colors)
|
|
18
13
|
- [Palette](#palette)
|
|
19
14
|
- [Output formats](#output-formats)
|
|
20
|
-
- [Hue channel splitting](#hue-channel-splitting-splithue)
|
|
21
15
|
- [Adaptation modes](#adaptation-modes)
|
|
22
16
|
- [Light / dark scheme mapping](#light--dark-scheme-mapping)
|
|
23
17
|
- [Configuration](#configuration)
|
|
@@ -29,42 +23,25 @@ Full reference for every public method, option, and type exported by `@tenphi/gl
|
|
|
29
23
|
|
|
30
24
|
## Theme creation
|
|
31
25
|
|
|
32
|
-
| Method
|
|
33
|
-
|
|
34
|
-
| `glaze(hue, saturation?, config?)`
|
|
35
|
-
| `glaze({ hue, saturation
|
|
36
|
-
| `glaze.
|
|
37
|
-
| `glaze.
|
|
38
|
-
| `glaze.
|
|
39
|
-
| `glaze.fromRgb(r, g, b)` | Create a theme from RGB values (0–255). Extracts hue and saturation. |
|
|
40
|
-
| `glaze.paletteFrom(data)` | Create a palette from a `palette.export()` snapshot (`kind: 'palette'`). |
|
|
41
|
-
| `glaze.colorFrom(data)` | Create a color token from a `token.export()` snapshot (`kind: 'color'`). |
|
|
42
|
-
| `glaze.isThemeExport(data)` | Type guard for theme authoring snapshots. |
|
|
43
|
-
| `glaze.isColorTokenExport(data)` | Type guard for color-token authoring snapshots. |
|
|
44
|
-
| `glaze.isPaletteExport(data)` | Type guard for palette authoring snapshots. |
|
|
26
|
+
| Method | Description |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `glaze(hue, saturation?, config?)` | Create a theme from hue (0–360) and saturation (0–100). Optional `config` overrides the global config for this theme. |
|
|
29
|
+
| `glaze({ hue, saturation }, config?)` | Create a theme from an options object, with optional per-theme config override. |
|
|
30
|
+
| `glaze.from(data)` | Create a theme from an exported configuration (`theme.export()` snapshot). |
|
|
31
|
+
| `glaze.fromHex(hex)` | Create a theme from a hex color (`#rgb` or `#rrggbb`). Extracts hue and saturation. |
|
|
32
|
+
| `glaze.fromRgb(r, g, b)` | Create a theme from RGB values (0–255). Extracts hue and saturation. |
|
|
45
33
|
|
|
46
34
|
```ts
|
|
47
35
|
const a = glaze(280, 80);
|
|
48
36
|
const b = glaze({ hue: 280, saturation: 80 });
|
|
49
|
-
const bDark = glaze({ hue: 280, saturation: 80, darkHue: 268, darkSaturation: 65 });
|
|
50
37
|
const c = glaze.fromHex('#7a4dbf');
|
|
51
38
|
const d = glaze.fromRgb(122, 77, 191);
|
|
52
|
-
const e = glaze.
|
|
39
|
+
const e = glaze.from(a.export());
|
|
53
40
|
|
|
54
41
|
// Per-theme config override:
|
|
55
|
-
const rawTheme = glaze(280, 80, {
|
|
42
|
+
const rawTheme = glaze(280, 80, { lightLightness: false, darkLightness: false });
|
|
56
43
|
```
|
|
57
44
|
|
|
58
|
-
Authoring restore triad (parallel to `.export()` on each instance):
|
|
59
|
-
|
|
60
|
-
| Export | Restore |
|
|
61
|
-
| ------ | ------- |
|
|
62
|
-
| `theme.export()` | `glaze.themeFrom()` |
|
|
63
|
-
| `token.export()` | `glaze.colorFrom()` |
|
|
64
|
-
| `palette.export()` | `glaze.paletteFrom()` |
|
|
65
|
-
|
|
66
|
-
Every snapshot includes `kind` + `version` (`GLAZE_EXPORT_VERSION`, currently `1`). Legacy snapshots without those fields still restore. Wrong `kind`, or a `version` outside `1..=GLAZE_EXPORT_VERSION`, throws.
|
|
67
|
-
|
|
68
45
|
The optional `config` parameter is a `GlazeConfigOverride` — see [Per-instance config override](#per-instance-config-override).
|
|
69
46
|
|
|
70
47
|
---
|
|
@@ -73,43 +50,38 @@ The optional `config` parameter is a `GlazeConfigOverride` — see [Per-instance
|
|
|
73
50
|
|
|
74
51
|
A `GlazeTheme` exposes:
|
|
75
52
|
|
|
76
|
-
| Method
|
|
77
|
-
|
|
78
|
-
| `theme.hue` (readonly)
|
|
79
|
-
| `theme.saturation` (readonly)
|
|
80
|
-
| `theme.
|
|
81
|
-
| `theme.
|
|
82
|
-
| `theme.
|
|
83
|
-
| `theme.
|
|
84
|
-
| `theme.
|
|
85
|
-
| `theme.
|
|
86
|
-
| `theme.
|
|
87
|
-
| `theme.
|
|
88
|
-
| `theme.
|
|
89
|
-
| `theme.
|
|
90
|
-
| `theme.
|
|
91
|
-
| `theme.
|
|
92
|
-
| `theme.
|
|
93
|
-
| `theme.
|
|
94
|
-
| `theme.json(options?)` | Export as plain JSON. |
|
|
95
|
-
| `theme.css(options?)` | Export as CSS custom property declarations. |
|
|
96
|
-
| `theme.dtcg(options?)` | Export one W3C DTCG token tree per scheme. |
|
|
97
|
-
| `theme.dtcgResolver(options?)` | Export one DTCG Resolver-Module document containing every scheme. |
|
|
98
|
-
| `theme.tailwind(options?)` | Export a Tailwind CSS v4 theme and scheme overrides. |
|
|
53
|
+
| Method | Description |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `theme.hue` (readonly) | The hue seed (0–360). |
|
|
56
|
+
| `theme.saturation` (readonly) | The saturation seed (0–100). |
|
|
57
|
+
| `theme.colors(defs)` | Add/replace colors (additive merge — adds new, overwrites existing by name, doesn't remove others). |
|
|
58
|
+
| `theme.color(name)` | Get a color definition by name. |
|
|
59
|
+
| `theme.color(name, def)` | Set a single color definition. |
|
|
60
|
+
| `theme.remove(name \| names[])` | Remove one or more color definitions. |
|
|
61
|
+
| `theme.has(name)` | Check if a color is defined. |
|
|
62
|
+
| `theme.list()` | List all defined color names. |
|
|
63
|
+
| `theme.reset()` | Clear all color definitions. |
|
|
64
|
+
| `theme.export()` | Export the theme configuration as a JSON-safe object. |
|
|
65
|
+
| `theme.extend(options)` | Create a child theme inheriting all color definitions (see [`extend`](#themeextendoptions) below). |
|
|
66
|
+
| `theme.resolve()` | Resolve all colors and return a `Map<string, ResolvedColor>`. |
|
|
67
|
+
| `theme.tokens(options?)` | Export as a flat token map grouped by scheme variant. |
|
|
68
|
+
| `theme.tasty(options?)` | Export as Tasty style-to-state bindings. |
|
|
69
|
+
| `theme.json(options?)` | Export as plain JSON. |
|
|
70
|
+
| `theme.css(options?)` | Export as CSS custom property declarations. |
|
|
99
71
|
|
|
100
72
|
### `theme.colors(defs)`
|
|
101
73
|
|
|
102
74
|
```ts
|
|
103
|
-
theme.colors({ surface: {
|
|
104
|
-
theme.colors({ text: {
|
|
75
|
+
theme.colors({ surface: { lightness: 97 } });
|
|
76
|
+
theme.colors({ text: { lightness: 30 } });
|
|
105
77
|
// Both 'surface' and 'text' are now defined.
|
|
106
78
|
```
|
|
107
79
|
|
|
108
80
|
### `theme.color(name) / theme.color(name, def)`
|
|
109
81
|
|
|
110
82
|
```ts
|
|
111
|
-
theme.color('surface', {
|
|
112
|
-
const def = theme.color('surface');
|
|
83
|
+
theme.color('surface', { lightness: 97, saturation: 0.75 }); // set
|
|
84
|
+
const def = theme.color('surface'); // get
|
|
113
85
|
```
|
|
114
86
|
|
|
115
87
|
### `theme.extend(options)`
|
|
@@ -119,89 +91,73 @@ Creates a new theme inheriting all color definitions, optionally replacing the h
|
|
|
119
91
|
```ts
|
|
120
92
|
const danger = primary.extend({
|
|
121
93
|
hue: 23,
|
|
122
|
-
colors: { 'accent-fill': {
|
|
94
|
+
colors: { 'accent-fill': { lightness: 48, mode: 'fixed' } },
|
|
123
95
|
});
|
|
124
96
|
|
|
125
|
-
// Inherit parent's config override and
|
|
126
|
-
const highSat = base.extend({ config: {
|
|
97
|
+
// Inherit parent's config override and tighten the dark window further:
|
|
98
|
+
const highSat = base.extend({ config: { darkLightness: [10, 100] } });
|
|
127
99
|
```
|
|
128
100
|
|
|
129
101
|
`GlazeExtendOptions`:
|
|
130
102
|
|
|
131
|
-
| Field
|
|
132
|
-
|
|
133
|
-
| `hue`
|
|
134
|
-
| `saturation` | `number`
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `colors` | `ColorMap` | Per-theme overrides (additive merge over the inherited map). |
|
|
138
|
-
| `config` | `GlazeConfigOverride` | Config override for the child. Shallow-merged with the parent's override — child fields win. |
|
|
103
|
+
| Field | Type | Description |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `hue` | `number` | Replace the hue seed. Defaults to the parent's hue. |
|
|
106
|
+
| `saturation` | `number` | Replace the saturation seed. Defaults to the parent's saturation. |
|
|
107
|
+
| `colors` | `ColorMap` | Per-theme overrides (additive merge over the inherited map). |
|
|
108
|
+
| `config` | `GlazeConfigOverride` | Config override for the child. Shallow-merged with the parent's override — child fields win. |
|
|
139
109
|
|
|
140
110
|
Colors marked with `inherit: false` on the parent are **not** copied into the child.
|
|
141
111
|
|
|
142
|
-
### `theme.resolve()`
|
|
143
|
-
|
|
144
|
-
Resolves the dependency graph and returns a
|
|
145
|
-
`Map<string, ResolvedColor>`. Export methods call it automatically; use it
|
|
146
|
-
directly for tests, diagnostics, or a custom output pipeline.
|
|
147
|
-
|
|
148
|
-
```ts
|
|
149
|
-
const resolved = theme.resolve();
|
|
150
|
-
const surface = resolved.get('surface');
|
|
151
|
-
// surface?.light.t is canonical tone on 0–1.
|
|
152
|
-
```
|
|
153
|
-
|
|
154
112
|
### `theme.tokens(options?)`
|
|
155
113
|
|
|
156
114
|
Flat token map grouped by scheme variant.
|
|
157
115
|
|
|
158
116
|
```ts
|
|
159
|
-
theme.tokens()
|
|
160
|
-
// → { light: { surface: '
|
|
117
|
+
theme.tokens()
|
|
118
|
+
// → { light: { surface: 'okhsl(...)' }, dark: { surface: 'okhsl(...)' } }
|
|
161
119
|
```
|
|
162
120
|
|
|
163
121
|
`GlazeJsonOptions`:
|
|
164
122
|
|
|
165
|
-
| Option
|
|
166
|
-
|
|
167
|
-
| `format` | `'
|
|
168
|
-
| `modes`
|
|
123
|
+
| Option | Default | Description |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| `format` | `'okhsl'` | Output color format. One of `'okhsl' \| 'rgb' \| 'hsl' \| 'oklch'`. |
|
|
126
|
+
| `modes` | `{ dark: true, highContrast: false }` (or global config) | Which scheme variants to include. |
|
|
169
127
|
|
|
170
128
|
### `theme.tasty(options?)`
|
|
171
129
|
|
|
172
|
-
|
|
130
|
+
Tasty style-to-state bindings for the [Tasty style system](https://tasty.style/docs). Uses `#name` color token keys and state aliases (`''`, `@dark`, etc.).
|
|
173
131
|
|
|
174
132
|
```ts
|
|
175
|
-
theme.tasty()
|
|
133
|
+
theme.tasty()
|
|
176
134
|
// → {
|
|
177
|
-
// '#surface': { '': '
|
|
135
|
+
// '#surface': { '': 'okhsl(...)', '@dark': 'okhsl(...)' },
|
|
178
136
|
// ...
|
|
179
137
|
// }
|
|
180
138
|
```
|
|
181
139
|
|
|
182
140
|
`GlazeTokenOptions`:
|
|
183
141
|
|
|
184
|
-
| Option
|
|
185
|
-
|
|
186
|
-
| `format`
|
|
187
|
-
| `modes`
|
|
188
|
-
| `states.dark`
|
|
189
|
-
| `states.highContrast` | `'@
|
|
190
|
-
| `
|
|
191
|
-
| `name` | `'theme'` | Base name for the theme-level hue var (`$theme-hue` / `--theme-hue`). Palette export auto-derives this from the theme name. |
|
|
192
|
-
| `prefix` | (palette only) | See [Palette](#palette). |
|
|
142
|
+
| Option | Default | Description |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `format` | `'okhsl'` | Output color format. |
|
|
145
|
+
| `modes` | global config | Which scheme variants to include. |
|
|
146
|
+
| `states.dark` | `'@dark'` (or global config) | State alias for dark mode tokens. |
|
|
147
|
+
| `states.highContrast` | `'@high-contrast'` (or global config) | State alias for high-contrast tokens. |
|
|
148
|
+
| `prefix` | (palette only) | See [Palette](#palette). |
|
|
193
149
|
|
|
194
|
-
When both `dark` and `highContrast` modes are enabled, dark high-contrast variants are emitted under the combined key `<dark> & <highContrast>` (e.g. `'@
|
|
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'`).
|
|
195
151
|
|
|
196
152
|
### `theme.json(options?)`
|
|
197
153
|
|
|
198
154
|
Per-color JSON map.
|
|
199
155
|
|
|
200
156
|
```ts
|
|
201
|
-
theme.json()
|
|
157
|
+
theme.json()
|
|
202
158
|
// → {
|
|
203
|
-
// surface: { light: '
|
|
204
|
-
// text: { light: '
|
|
159
|
+
// surface: { light: 'okhsl(...)', dark: 'okhsl(...)' },
|
|
160
|
+
// text: { light: 'okhsl(...)', dark: 'okhsl(...)' },
|
|
205
161
|
// }
|
|
206
162
|
```
|
|
207
163
|
|
|
@@ -214,8 +170,8 @@ CSS custom property declaration strings, grouped by scheme variant.
|
|
|
214
170
|
```ts
|
|
215
171
|
theme.css();
|
|
216
172
|
// → {
|
|
217
|
-
// light: '--surface-color:
|
|
218
|
-
// dark: '--surface-color:
|
|
173
|
+
// light: '--surface-color: rgb(...);\n--text-color: rgb(...);',
|
|
174
|
+
// dark: '--surface-color: rgb(...);\n--text-color: rgb(...);',
|
|
219
175
|
// lightContrast: '...',
|
|
220
176
|
// darkContrast: '...',
|
|
221
177
|
// }
|
|
@@ -223,188 +179,23 @@ theme.css();
|
|
|
223
179
|
|
|
224
180
|
`GlazeCssOptions`:
|
|
225
181
|
|
|
226
|
-
| Option
|
|
227
|
-
|
|
228
|
-
| `format`
|
|
229
|
-
| `suffix`
|
|
230
|
-
| `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). |
|
|
231
|
-
| `name` | `'theme'` | Base name for the theme-level hue var (`--theme-hue`). Palette export auto-derives this from the theme name. |
|
|
182
|
+
| Option | Default | Description |
|
|
183
|
+
|---|---|---|
|
|
184
|
+
| `format` | `'rgb'` | Output color format. |
|
|
185
|
+
| `suffix` | `'-color'` | Suffix appended to each CSS property name. Pass `''` for bare property names. |
|
|
232
186
|
|
|
233
187
|
`GlazeCssResult` always contains all four keys (`light`, `dark`, `lightContrast`, `darkContrast`); empty if no colors are defined for that variant.
|
|
234
188
|
|
|
235
|
-
### `theme.
|
|
236
|
-
|
|
237
|
-
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.
|
|
238
|
-
|
|
239
|
-
```ts
|
|
240
|
-
theme.dtcg();
|
|
241
|
-
// → {
|
|
242
|
-
// light: {
|
|
243
|
-
// surface: {
|
|
244
|
-
// $type: 'color',
|
|
245
|
-
// $value: { colorSpace: 'srgb', components: [0.96, 0.94, 0.98], hex: '#f5f0fa' },
|
|
246
|
-
// },
|
|
247
|
-
// },
|
|
248
|
-
// dark: {
|
|
249
|
-
// surface: {
|
|
250
|
-
// $type: 'color',
|
|
251
|
-
// $value: { colorSpace: 'srgb', components: [0.16, 0.14, 0.2], hex: '#292333' },
|
|
252
|
-
// },
|
|
253
|
-
// },
|
|
254
|
-
// }
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
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).
|
|
258
|
-
|
|
259
|
-
`GlazeDtcgOptions`:
|
|
260
|
-
|
|
261
|
-
| Option | Default | Description |
|
|
262
|
-
| ------------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
263
|
-
| `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. |
|
|
264
|
-
| `modes` | global config | Which scheme variants to include. `light` is always present. |
|
|
265
|
-
|
|
266
|
-
`alpha` is included on `$value` only when the color's opacity is below 1. `$type` is always `'color'`.
|
|
267
|
-
|
|
268
|
-
### `theme.dtcgResolver(options?)`
|
|
269
|
-
|
|
270
|
-
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.
|
|
271
|
-
|
|
272
|
-
```ts
|
|
273
|
-
theme.dtcgResolver({ modes: { highContrast: true } });
|
|
274
|
-
// → {
|
|
275
|
-
// version: '2025.10',
|
|
276
|
-
// sets: {
|
|
277
|
-
// base: {
|
|
278
|
-
// sources: [
|
|
279
|
-
// {
|
|
280
|
-
// surface: {
|
|
281
|
-
// $type: 'color',
|
|
282
|
-
// $value: { colorSpace: 'srgb', components: [0.96, 0.94, 0.98], hex: '#f5f0fa' },
|
|
283
|
-
// },
|
|
284
|
-
// },
|
|
285
|
-
// ],
|
|
286
|
-
// },
|
|
287
|
-
// },
|
|
288
|
-
// modifiers: {
|
|
289
|
-
// scheme: {
|
|
290
|
-
// default: 'light',
|
|
291
|
-
// contexts: {
|
|
292
|
-
// light: [],
|
|
293
|
-
// dark: [
|
|
294
|
-
// {
|
|
295
|
-
// surface: {
|
|
296
|
-
// $type: 'color',
|
|
297
|
-
// $value: { colorSpace: 'srgb', components: [0.16, 0.14, 0.2], hex: '#292333' },
|
|
298
|
-
// },
|
|
299
|
-
// },
|
|
300
|
-
// ],
|
|
301
|
-
// lightContrast: [ /* … */ ],
|
|
302
|
-
// darkContrast: [ /* … */ ],
|
|
303
|
-
// },
|
|
304
|
-
// },
|
|
305
|
-
// },
|
|
306
|
-
// resolutionOrder: [
|
|
307
|
-
// { $ref: '#/sets/base' },
|
|
308
|
-
// { $ref: '#/modifiers/scheme' },
|
|
309
|
-
// ],
|
|
310
|
-
// }
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
**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.
|
|
314
|
-
|
|
315
|
-
`GlazeDtcgResolverOptions` (extends `GlazeDtcgOptions`, so `modes` and `colorSpace` pass through):
|
|
316
|
-
|
|
317
|
-
| Option | Default | Description |
|
|
318
|
-
| -------------- | ------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
319
|
-
| `colorSpace` | `'srgb'` | Same as `dtcg()` — flows through to every source and context. |
|
|
320
|
-
| `modes` | global config | Which scheme variants to emit as contexts. `light` is always present (the default); absent variants are omitted. |
|
|
321
|
-
| `setName` | `'base'` | Name of the single set holding the default (light) token tree. |
|
|
322
|
-
| `modifierName` | `'scheme'` | Name of the modifier describing the scheme axis. |
|
|
323
|
-
| `contextNames` | identity | Override the four context names (`light` / `dark` / `lightContrast` / `darkContrast`) — e.g. `{ dark: 'night' }`. |
|
|
324
|
-
| `version` | `'2025.10'` | Resolver document version. |
|
|
325
|
-
|
|
326
|
-
### `theme.tailwind(options?)`
|
|
327
|
-
|
|
328
|
-
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.
|
|
329
|
-
|
|
330
|
-
```css
|
|
331
|
-
@theme {
|
|
332
|
-
--color-surface: oklch(0.96 0.01 280);
|
|
333
|
-
--color-text: oklch(0.3 0.05 280);
|
|
334
|
-
}
|
|
335
|
-
.dark {
|
|
336
|
-
--color-surface: oklch(0.16 0.01 280);
|
|
337
|
-
--color-text: oklch(0.85 0.05 280);
|
|
338
|
-
}
|
|
339
|
-
.high-contrast {
|
|
340
|
-
--color-surface: oklch(0.98 0.01 280);
|
|
341
|
-
--color-text: oklch(0.1 0.05 280);
|
|
342
|
-
}
|
|
343
|
-
.dark.high-contrast {
|
|
344
|
-
--color-surface: oklch(0.05 0.01 280);
|
|
345
|
-
--color-text: oklch(0.95 0.05 280);
|
|
346
|
-
}
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
`GlazeTailwindOptions`:
|
|
350
|
-
|
|
351
|
-
| Option | Default | Description |
|
|
352
|
-
| ---------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
353
|
-
| `format` | `'oklch'` | Output color format for the values. |
|
|
354
|
-
| `namespace` | `'color-'` | CSS custom property namespace, forming `--<namespace><name>` (e.g. `--color-surface`). Named `namespace` to avoid clashing with the palette theme-prefix option. |
|
|
355
|
-
| `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). |
|
|
356
|
-
| `highContrastSelector` | `'.high-contrast'` | Selector wrapping the light high-contrast overrides. The combined dark + high-contrast block uses `${darkSelector}${highContrastSelector}` (e.g. `.dark.high-contrast`). |
|
|
357
|
-
| `modes` | global config | Which scheme variants to include. The `@theme` block (light) is always emitted when colors exist. |
|
|
358
|
-
|
|
359
|
-
### `theme.export(override?)`
|
|
189
|
+
### `theme.export()`
|
|
360
190
|
|
|
361
191
|
```ts
|
|
362
192
|
const snapshot = theme.export();
|
|
363
|
-
// → {
|
|
364
|
-
// kind: 'theme',
|
|
365
|
-
// version: 1,
|
|
366
|
-
// hue: 280,
|
|
367
|
-
// saturation: 80,
|
|
368
|
-
// colors: { surface: { ... }, ... },
|
|
369
|
-
// config: { lightTone: {...}, darkTone: {...}, pastel: false, ... },
|
|
370
|
-
// }
|
|
371
|
-
|
|
372
|
-
const restored = glaze.themeFrom(snapshot);
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
Returns a deep-cloned, JSON-safe authoring snapshot (definitions + frozen
|
|
376
|
-
effective config — not resolved color strings). Freezes
|
|
377
|
-
`getConfig() ∪ instance local ∪ override` at call time. Restored themes pin
|
|
378
|
-
that freeze as their local override. Distinct from `theme.json()`, which
|
|
379
|
-
emits resolved color strings.
|
|
380
|
-
|
|
381
|
-
---
|
|
382
|
-
|
|
383
|
-
## High-contrast pairs
|
|
384
|
-
|
|
385
|
-
`HCPair<T>` means either one value used in both ordinary and high-contrast
|
|
386
|
-
schemes, or an explicit `[normal, highContrast]` pair:
|
|
193
|
+
// → { hue: 280, saturation: 80, colors: { surface: { ... }, ... } }
|
|
387
194
|
|
|
388
|
-
|
|
389
|
-
type HCPair<T> = T | [T, T];
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
It is used by `tone`, `contrast`, shadow `intensity`, and mix `value`:
|
|
393
|
-
|
|
394
|
-
```ts
|
|
395
|
-
tone: '-8'; // -8 in normal and HC
|
|
396
|
-
tone: ['-8', '-16']; // -8 normal, -16 HC
|
|
397
|
-
contrast: {
|
|
398
|
-
apca: 'content';
|
|
399
|
-
} // preset with automatic HC enhancement
|
|
400
|
-
contrast: {
|
|
401
|
-
apca: ['content', 'body'];
|
|
402
|
-
} // explicit normal/HC targets
|
|
195
|
+
const restored = glaze.from(snapshot);
|
|
403
196
|
```
|
|
404
197
|
|
|
405
|
-
|
|
406
|
-
metric. An explicit HC value disables automatic APCA enhancement or WCAG preset
|
|
407
|
-
promotion for that color.
|
|
198
|
+
The export contains only the configuration — not resolved color values. Resolved values are recomputed on demand.
|
|
408
199
|
|
|
409
200
|
---
|
|
410
201
|
|
|
@@ -418,288 +209,88 @@ type ColorDef = RegularColorDef | ShadowColorDef | MixColorDef;
|
|
|
418
209
|
|
|
419
210
|
### `RegularColorDef`
|
|
420
211
|
|
|
421
|
-
| Field
|
|
422
|
-
|
|
423
|
-
| `
|
|
424
|
-
| `saturation` | `number`
|
|
425
|
-
| `hue`
|
|
426
|
-
| `
|
|
427
|
-
| `
|
|
428
|
-
| `
|
|
429
|
-
| `
|
|
430
|
-
| `
|
|
431
|
-
| `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). |
|
|
432
|
-
| `opacity` | `number` | Fixed alpha 0–1. Output includes alpha in the CSS value. Combining with `contrast` is not recommended (a `console.warn` is emitted). |
|
|
433
|
-
| `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 per-theme / per-token `pastel` override when omitted. Default: unset. See [Per-color `pastel`](#per-color-pastel). |
|
|
434
|
-
| `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). |
|
|
435
|
-
| `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. |
|
|
436
|
-
|
|
437
|
-
#### Tone values
|
|
438
|
-
|
|
439
|
-
`tone` (0–100) replaces authored OKHSL lightness with a contrast-shaped axis.
|
|
440
|
-
Equal tone differences give equal WCAG contrast for neutrals; chromatic results
|
|
441
|
-
can drift in measured luminance. See [OKHST in Glaze](okhst.md). To port old
|
|
442
|
-
`lightness` values, see [migration.md](migration.md).
|
|
443
|
-
|
|
444
|
-
| Form | Example | Meaning |
|
|
445
|
-
| ------------------- | ----------------------- | --------------------------------------------------------------------------------------------- |
|
|
446
|
-
| Number (absolute) | `tone: 45` | Absolute tone 0–100. |
|
|
447
|
-
| String (tone delta) | `tone: '-52'` | Signed difference from the base color's resolved tone (requires `base`). |
|
|
448
|
-
| Extreme | `tone: 'max'` / `'min'` | Force to the scheme's highest (`'max'` = 100) or lowest (`'min'` = 0) tone. With a `base`, the light-scheme shift is replayed in dark. No `base` needed. |
|
|
449
|
-
| HC pair | `tone: ['-7', '-20']` | `[normal, high-contrast]`. A single value applies to both. |
|
|
450
|
-
|
|
451
|
-
**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.
|
|
452
|
-
|
|
453
|
-
**A tone delta** applies a signed difference to the base color's resolved tone.
|
|
454
|
-
It gives an exact contrast step for neutrals and a stable visual progression for
|
|
455
|
-
chromatic colors. In dark mode with `mode: 'auto'`, it is anchored to the
|
|
456
|
-
base's per-scheme tone. If `base + delta` falls outside `[0, 100]`, the result
|
|
457
|
-
is clamped to the boundary, or — with `autoFlip` (default on) — mirrored to the
|
|
458
|
-
other side of the base. If the mirrored target is also out of range, the original
|
|
459
|
-
delta is kept and clamped on the authored side.
|
|
460
|
-
|
|
461
|
-
**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. Without a `base`, 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.
|
|
462
|
-
|
|
463
|
-
**Extreme tone with a `base`** keeps the pair's contrast across schemes. The tone windows are asymmetric by default (`lightTone: [10, 100]`, `darkTone: [15, 95]`), so re-mapping the extreme through the dark window would squeeze the base-to-extreme span and cost contrast. Instead Glaze measures the tone shift the light scheme applied between the base and the extreme, then replays it against the base's resolved dark tone — mirrored under `mode: 'auto'` (both ends invert), same-signed under `'fixed'`. The result is clamped to `[0, 100]` only, so it may cross the `darkTone` window edge; that is intentional, since the author asked for the extreme. When the shift does not fit above or below the dark base, the color pins at tone 100 / 0. `mode: 'static'` is unaffected, and high-contrast variants already use the full range.
|
|
212
|
+
| Field | Type | Description |
|
|
213
|
+
|---|---|---|
|
|
214
|
+
| `lightness` | `HCPair<number \| RelativeValue>` | Number = absolute (0–100). String (`'+N'`/`'-N'`) = relative to base's lightness (requires `base`). Optional HC pair `[normal, hc]`. |
|
|
215
|
+
| `saturation` | `number` | Saturation factor applied to the seed saturation (0–1). Default: `1`. |
|
|
216
|
+
| `hue` | `number \| RelativeValue` | Number = absolute (0–360). String (`'+N'`/`'-N'`) = relative to the **theme seed hue** (never to a base color). |
|
|
217
|
+
| `base` | `string` | Name of another color in the same theme — makes this a *dependent* color. |
|
|
218
|
+
| `contrast` | `HCPair<MinContrast>` | WCAG contrast floor against `base`. Requires `base`. |
|
|
219
|
+
| `mode` | `'auto' \| 'fixed' \| 'static'` | Adaptation mode. Default: `'auto'`. See [Adaptation modes](#adaptation-modes). |
|
|
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). |
|
|
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. |
|
|
464
222
|
|
|
465
|
-
|
|
466
|
-
theme.colors({
|
|
467
|
-
bg: { tone: 60 },
|
|
468
|
-
fg: { base: 'bg', tone: 'max' },
|
|
469
|
-
});
|
|
470
|
-
// light: bg 62.0, fg 100.0 — shift +38.0, contrast 3.18:1
|
|
471
|
-
// dark: bg 43.9, fg 5.9 — shift -38.0, contrast 3.18:1
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
A dependent color with `base` but no `tone` inherits the base's tone (equivalent to a delta of 0).
|
|
223
|
+
#### Lightness values
|
|
475
224
|
|
|
476
|
-
|
|
225
|
+
| Form | Example | Meaning |
|
|
226
|
+
|---|---|---|
|
|
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. |
|
|
477
230
|
|
|
478
|
-
`
|
|
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.
|
|
479
232
|
|
|
480
|
-
|
|
481
|
-
- **`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`).
|
|
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.
|
|
482
234
|
|
|
483
|
-
|
|
235
|
+
A dependent color with `base` but no `lightness` inherits the base's lightness (equivalent to a delta of 0).
|
|
484
236
|
|
|
485
|
-
#### `contrast` (floor)
|
|
237
|
+
#### `contrast` (WCAG floor)
|
|
486
238
|
|
|
487
239
|
```ts
|
|
488
|
-
type
|
|
489
|
-
type ContrastSpec =
|
|
490
|
-
| number // bare WCAG ratio
|
|
491
|
-
| ContrastPreset // named WCAG preset
|
|
492
|
-
| { wcag: HCPair<number | ContrastPreset> }
|
|
493
|
-
| { apca: HCPair<number> }; // APCA Lc target
|
|
240
|
+
type MinContrast = number | 'AA' | 'AAA' | 'AA-large' | 'AAA-large';
|
|
494
241
|
```
|
|
495
242
|
|
|
496
|
-
| Preset
|
|
497
|
-
|
|
498
|
-
| `'AA-large'`
|
|
499
|
-
| `'AA'`
|
|
500
|
-
| `'AAA-large'` | 4.5
|
|
501
|
-
| `'AAA'`
|
|
502
|
-
|
|
503
|
-
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] }`).
|
|
504
|
-
|
|
505
|
-
```ts
|
|
506
|
-
contrast: 4.5; // WCAG 4.5
|
|
507
|
-
contrast: 'AAA'; // WCAG 7
|
|
508
|
-
contrast: {
|
|
509
|
-
wcag: 6;
|
|
510
|
-
} // WCAG 6
|
|
511
|
-
contrast: {
|
|
512
|
-
wcag: [4.5, 7];
|
|
513
|
-
} // WCAG 4.5 normal / 7 high-contrast (explicit)
|
|
514
|
-
contrast: {
|
|
515
|
-
apca: 60;
|
|
516
|
-
} // APCA Lc 60 normal / 75 high-contrast (auto)
|
|
517
|
-
contrast: {
|
|
518
|
-
apca: [45, 60];
|
|
519
|
-
} // APCA Lc 45 normal / 60 high-contrast (explicit)
|
|
520
|
-
contrast: {
|
|
521
|
-
apca: 'content';
|
|
522
|
-
} // APCA preset -> Lc 60 normal / 75 high-contrast (auto)
|
|
523
|
-
contrast: {
|
|
524
|
-
apca: ['content', 'body'];
|
|
525
|
-
} // Lc 60 normal / 75 high-contrast (explicit)
|
|
526
|
-
```
|
|
527
|
-
|
|
528
|
-
**WCAG HC auto-promotion:** a bare WCAG preset (no `[normal, hc]` pair at either
|
|
529
|
-
the outer `contrast` or inner `wcag` level) is automatically promoted to its
|
|
530
|
-
spec-defined "Enhanced" successor in high-contrast mode — `AA` → `AAA` (4.5 → 7)
|
|
531
|
-
and `AA-large` → `AAA-large` (3 → 4.5), per WCAG SC 1.4.3 → 1.4.6. `AAA` and
|
|
532
|
-
`AAA-large` are already the top WCAG tier and are left unchanged; bare numeric
|
|
533
|
-
targets have no successor tier and are also left unchanged. An explicit HC value
|
|
534
|
-
via either pair overrides and skips the promotion.
|
|
535
|
-
|
|
536
|
-
**APCA Enhanced Level (HC auto-boost):** a bare APCA scalar (no `[normal, hc]`
|
|
537
|
-
pair at either the outer `contrast` or inner `apca` level) is automatically
|
|
538
|
-
boosted by **+15 Lc** in high-contrast mode, the APCA analog of WCAG's
|
|
539
|
-
AAA-over-AA step. On by default; an explicit HC value via either pair
|
|
540
|
-
overrides it and skips the boost. The enhanced target is clamped to 106 Lc.
|
|
541
|
-
For large/bold text (where APCA caps contrast at Lc 90 to avoid glare), pass
|
|
542
|
-
an explicit HC pair to hold that ceiling.
|
|
243
|
+
| Preset | Ratio |
|
|
244
|
+
|---|---|
|
|
245
|
+
| `'AA-large'` | 3 |
|
|
246
|
+
| `'AA'` | 4.5 |
|
|
247
|
+
| `'AAA-large'` | 4.5 |
|
|
248
|
+
| `'AAA'` | 7 |
|
|
543
249
|
|
|
544
|
-
|
|
545
|
-
`'preferred'` (Lc 90), `'body'` (75), `'content'` (60, ~AA), `'large'` (45, ~3:1),
|
|
546
|
-
`'non-text'` (30), `'min'` (15, point of invisibility).
|
|
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.
|
|
547
251
|
|
|
548
|
-
|
|
549
|
-
satisfies it, the tone is kept; otherwise the solver uses the tone-shaped scale
|
|
550
|
-
for a closed-form WCAG seed and fast search 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.
|
|
551
253
|
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
**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.
|
|
555
|
-
|
|
556
|
-
**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 [Contrast verification](okhst.md#contrast-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.
|
|
557
255
|
|
|
558
256
|
#### Per-color hue override
|
|
559
257
|
|
|
560
258
|
```ts
|
|
561
259
|
const theme = glaze(280, 80);
|
|
562
260
|
theme.colors({
|
|
563
|
-
surface:
|
|
564
|
-
gradientEnd: {
|
|
565
|
-
warning:
|
|
261
|
+
surface: { lightness: 97 },
|
|
262
|
+
gradientEnd: { lightness: 90, hue: '+20' }, // 280 + 20 = 300
|
|
263
|
+
warning: { lightness: 60, hue: 40 }, // absolute
|
|
566
264
|
});
|
|
567
265
|
```
|
|
568
266
|
|
|
569
267
|
Relative hue is always relative to the **theme seed hue**, not to a base color.
|
|
570
268
|
|
|
571
|
-
#### Dark seed (`darkHue` / `darkSaturation`)
|
|
572
|
-
|
|
573
|
-
Tone inverts automatically between light and dark, but hue and saturation do
|
|
574
|
-
not — by default every scheme reuses the one seed, with dark getting a flat
|
|
575
|
-
`darkDesaturation` haircut. When a palette needs a genuinely different chroma in
|
|
576
|
-
dark (a cooler accent, a calmer surface tint), author a second seed:
|
|
577
|
-
|
|
578
|
-
```ts
|
|
579
|
-
const theme = glaze({
|
|
580
|
-
hue: 280,
|
|
581
|
-
saturation: 80,
|
|
582
|
-
darkHue: 268, // dark schemes seed from 268 instead of 280
|
|
583
|
-
darkSaturation: 65, // and from 65 instead of 80
|
|
584
|
-
});
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
Individual colors can override either channel for dark on their own:
|
|
588
|
-
|
|
589
|
-
```ts
|
|
590
|
-
theme.colors({
|
|
591
|
-
surface: { tone: 97 },
|
|
592
|
-
accent: { tone: 55, hue: '+20', darkHue: '+35' },
|
|
593
|
-
warning: { tone: 60, saturation: 0.9, darkSaturation: 0.6 },
|
|
594
|
-
});
|
|
595
|
-
```
|
|
596
|
-
|
|
597
|
-
Both apply to the `dark` **and** `darkContrast` variants. The rules:
|
|
598
|
-
|
|
599
|
-
| Rule | Behavior |
|
|
600
|
-
| ---- | -------- |
|
|
601
|
-
| Units | Seed-level `darkSaturation` is `0–100` (like `saturation` on the theme). Def-level `darkSaturation` is a `0–1` factor (like `saturation` on a color def). |
|
|
602
|
-
| Fallback | `darkHue` falls back to `hue`, `darkSaturation` to `saturation`, and the def falls back to the seed. Omitting everything reproduces the previous behavior exactly. |
|
|
603
|
-
| Relative hue | `darkHue: '+N'` anchors to the theme's **dark** seed hue. A plain `hue: '+N'` with no `darkHue` also re-anchors to the dark seed, so a whole palette rotates together. |
|
|
604
|
-
| Absolute hue | An absolute `hue` (no `darkHue`) is used verbatim in dark — absolute means absolute in every scheme. |
|
|
605
|
-
| `darkDesaturation` | Bypassed as soon as any explicit dark saturation is authored, at either level. The value you write is the value you get. |
|
|
606
|
-
| `mode: 'static'` | Ignores both. A static color is pinned to one hue and saturation across every scheme. |
|
|
607
|
-
| Shadows and mixes | Have no channels of their own — they derive hue and saturation from their `bg` / `fg` / `target`, so they inherit dark overrides automatically. |
|
|
608
|
-
|
|
609
|
-
With [`splitHue`](#hue-channel-splitting-splithue), a dark seed makes the hue
|
|
610
|
-
custom properties scheme-dependent; Glaze re-declares them in the dark block
|
|
611
|
-
automatically.
|
|
612
|
-
|
|
613
|
-
#### Per-color `pastel`
|
|
614
|
-
|
|
615
|
-
`pastel: true` on a single color def overrides the per-theme / per-token `pastel` override 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.
|
|
616
|
-
|
|
617
|
-
```ts
|
|
618
|
-
const theme = glaze(280, 80);
|
|
619
|
-
theme.colors({
|
|
620
|
-
plain: { tone: 50, saturation: 1 },
|
|
621
|
-
soft: { tone: 50, saturation: 1, pastel: true },
|
|
622
|
-
});
|
|
623
|
-
// theme.resolve().get('soft')!.light.pastel === true
|
|
624
|
-
// theme.css().light contains different rgb() triples for `--plain` and `--soft`
|
|
625
|
-
```
|
|
626
|
-
|
|
627
|
-
Omit the field to inherit the theme/token `pastel` override (default `false`) — useful for keeping the default behavior while opting a single accent into the pastel gamut.
|
|
628
|
-
|
|
629
|
-
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:
|
|
630
|
-
|
|
631
|
-
```ts
|
|
632
|
-
const parent = glaze(280, 80);
|
|
633
|
-
parent.colors({ soft: { tone: 50, saturation: 1, pastel: true } });
|
|
634
|
-
|
|
635
|
-
const child = parent.extend({
|
|
636
|
-
colors: { soft: { tone: 50, saturation: 1, pastel: false } },
|
|
637
|
-
});
|
|
638
|
-
// child.resolve().get('soft')!.light.pastel === false
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
> **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.
|
|
642
|
-
>
|
|
643
|
-
> 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.
|
|
644
|
-
|
|
645
|
-
#### Roles
|
|
646
|
-
|
|
647
|
-
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.
|
|
648
|
-
|
|
649
|
-
| Role | Polarity | Use | Aliases (name inference) |
|
|
650
|
-
| ----------- | -------- | ---------------------------------------------------- | ----------------------------------------------------------------- |
|
|
651
|
-
| `'text'` | fg | Text / icons / foreground content | `text`, `fg`, `foreground`, `content`, `ink`, `label`, `stroke` |
|
|
652
|
-
| `'border'` | fg | Non-text spot elements (borders, dividers, outlines) | `border`, `divider`, `outline`, `separator`, `hairline`, `rule` |
|
|
653
|
-
| `'surface'` | bg | Backgrounds / fills | `surface`, `bg`, `background`, `fill`, `canvas`, `paper`, `layer` |
|
|
654
|
-
|
|
655
|
-
Resolution chain (per color):
|
|
656
|
-
|
|
657
|
-
1. Explicit `role` (normalized from an alias) wins.
|
|
658
|
-
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`).
|
|
659
|
-
3. Else, the opposite of the base's role (a `surface` base ⇒ this is `text`).
|
|
660
|
-
4. Else, `'text'` (foreground) — i.e. the base is treated as the background.
|
|
661
|
-
|
|
662
|
-
```ts
|
|
663
|
-
const theme = glaze(280, 60);
|
|
664
|
-
theme.colors({
|
|
665
|
-
surface: { tone: 90 },
|
|
666
|
-
text: { base: 'surface', contrast: { apca: 'content' } }, // inferred text
|
|
667
|
-
border: { base: 'surface', tone: '-10' }, // inferred border
|
|
668
|
-
});
|
|
669
|
-
// role fixes APCA polarity; set `pastel: true` explicitly if a border
|
|
670
|
-
// needs the hue-independent safe chroma limit.
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
Disable name inference with `glaze.configure({ inferRole: false })` (the base-opposite and foreground-default fallbacks still apply).
|
|
674
|
-
|
|
675
269
|
### `ShadowColorDef`
|
|
676
270
|
|
|
677
|
-
| Field
|
|
678
|
-
|
|
679
|
-
| `type`
|
|
680
|
-
| `bg`
|
|
681
|
-
| `fg`
|
|
682
|
-
| `intensity` | `HCPair<number>` | Shadow intensity, 0–100. Supports HC pairs.
|
|
683
|
-
| `tuning`
|
|
684
|
-
| `
|
|
685
|
-
| `inherit` | `boolean` | Inheritance flag, default `true`. |
|
|
271
|
+
| Field | Type | Description |
|
|
272
|
+
|---|---|---|
|
|
273
|
+
| `type` | `'shadow'` | Discriminator. |
|
|
274
|
+
| `bg` | `string` | Background color name — must reference a non-shadow color in the same theme. |
|
|
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. |
|
|
276
|
+
| `intensity` | `HCPair<number>` | Shadow intensity, 0–100. Supports HC pairs. |
|
|
277
|
+
| `tuning` | `ShadowTuning` | Per-color tuning overrides. Merged field-by-field with the global `shadowTuning`. |
|
|
278
|
+
| `inherit` | `boolean` | Inheritance flag, default `true`. |
|
|
686
279
|
|
|
687
280
|
See [Shadows](#shadows) below for the algorithm and tuning details.
|
|
688
281
|
|
|
689
282
|
### `MixColorDef`
|
|
690
283
|
|
|
691
|
-
| Field
|
|
692
|
-
|
|
693
|
-
| `type`
|
|
694
|
-
| `base`
|
|
695
|
-
| `target`
|
|
696
|
-
| `value`
|
|
697
|
-
| `blend`
|
|
698
|
-
| `space`
|
|
699
|
-
| `contrast` | `HCPair<
|
|
700
|
-
| `
|
|
701
|
-
| `role` | `RoleInput` | Semantic role of the mixed result against `base`. Same semantics as `RegularColorDef.role` (see [Roles](#roles)). |
|
|
702
|
-
| `inherit` | `boolean` | Inheritance flag, default `true`. |
|
|
284
|
+
| Field | Type | Description |
|
|
285
|
+
|---|---|---|
|
|
286
|
+
| `type` | `'mix'` | Discriminator. |
|
|
287
|
+
| `base` | `string` | "From" color name. |
|
|
288
|
+
| `target` | `string` | "To" color name. |
|
|
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. |
|
|
290
|
+
| `blend` | `'opaque' \| 'transparent'` | Default `'opaque'`. |
|
|
291
|
+
| `space` | `'okhsl' \| 'srgb'` | Interpolation space for opaque blending. Default `'okhsl'`. Ignored for `'transparent'` (always composites in linear sRGB). |
|
|
292
|
+
| `contrast` | `HCPair<MinContrast>` | Optional WCAG floor against `base`. The solver adjusts the mix ratio (opaque) or opacity (transparent). |
|
|
293
|
+
| `inherit` | `boolean` | Inheritance flag, default `true`. |
|
|
703
294
|
|
|
704
295
|
See [Mix colors](#mix-colors) below.
|
|
705
296
|
|
|
@@ -719,155 +310,130 @@ glaze.color(color: GlazeFromInput | GlazeColorInput | GlazeColorValue, config?:
|
|
|
719
310
|
|
|
720
311
|
`glaze.color()` accepts **four input shapes**, discriminated by structure:
|
|
721
312
|
|
|
722
|
-
| Shape
|
|
723
|
-
|
|
724
|
-
| **Bare string**
|
|
725
|
-
| **Value object**
|
|
726
|
-
| **`{ from, ...overrides }`** | `{ from: '#1a1a2e', base: bg, contrast: 'AA' }` | Value + color overrides in one object.
|
|
727
|
-
| **Structured**
|
|
313
|
+
| Shape | Example | Notes |
|
|
314
|
+
|---|---|---|
|
|
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). |
|
|
317
|
+
| **`{ from, ...overrides }`** | `{ from: '#1a1a2e', base: bg, contrast: 'AA' }` | Value + color overrides in one object. |
|
|
318
|
+
| **Structured** | `{ hue: 152, saturation: 95, lightness: 74 }` | Full theme-style token (hue/saturation/lightness all in 0–100). |
|
|
728
319
|
|
|
729
320
|
`GlazeColorValue` (bare string or value-object forms) accepts:
|
|
730
321
|
|
|
731
|
-
| Form
|
|
732
|
-
|
|
733
|
-
| Hex
|
|
734
|
-
| `rgb()`
|
|
735
|
-
| `hsl()`
|
|
736
|
-
| `okhsl()`
|
|
737
|
-
| `
|
|
738
|
-
| `
|
|
739
|
-
| `
|
|
740
|
-
| `
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
|
747
|
-
|
|
|
748
|
-
| `
|
|
749
|
-
| `
|
|
750
|
-
| `
|
|
751
|
-
| `
|
|
752
|
-
| `
|
|
753
|
-
| `
|
|
754
|
-
| `
|
|
755
|
-
| `mode` | `AdaptationMode` | Default: `'auto'`. |
|
|
756
|
-
| `autoFlip` | `boolean` | Flip out-of-bounds results instead of clamping. Default: global `autoFlip`. |
|
|
757
|
-
| `opacity` | `number` | Fixed alpha 0–1. |
|
|
758
|
-
| `base` | `GlazeColorToken \| GlazeColorValue` | Optional dependency. See [Pairing colors](#pairing-colors). |
|
|
759
|
-
| `contrast` | `HCPair<ContrastSpec>` | Contrast floor against `base` (WCAG or APCA). Without `base`, anchored to the literal seed. |
|
|
760
|
-
| `pastel` | `boolean` | Per-color `pastel` override. Falls through to the per-theme / per-token `pastel` override when omitted. See [Per-color `pastel`](#per-color-pastel). |
|
|
761
|
-
| `role` | `RoleInput` | Semantic role against `base` / the seed (see [Roles](#roles)). Fixes APCA polarity. |
|
|
762
|
-
| `name` | `string` | Debug label for warnings; doesn't change output keys. Reserved names (`'value'`, `'seed'`, `'externalBase'`) are rejected. |
|
|
322
|
+
| Form | Example | Notes |
|
|
323
|
+
|---|---|---|
|
|
324
|
+
| Hex | `'#26fcb2'`, `'#26fcb2ff'`, `'#abc'` | 3, 6, or 8 digits. Alpha is dropped with a `console.warn` — use `opacity` instead. |
|
|
325
|
+
| `rgb()` | `'rgb(38 252 178)'`, `'rgb(38 252 178 / 0.8)'` | Modern space syntax. Alpha dropped with warning. |
|
|
326
|
+
| `hsl()` | `'hsl(152 97% 57%)'` | Modern space syntax. Alpha dropped with warning. |
|
|
327
|
+
| `okhsl()` | `'okhsl(152 95% 74%)'` | Glaze's own emit format. Alpha dropped with warning. |
|
|
328
|
+
| `oklch()` | `'oklch(0.85 0.18 152)'` | Glaze's own emit format. Alpha dropped with warning. |
|
|
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. |
|
|
330
|
+
| `RgbColor` object | `{ r: 38, g: 252, b: 178 }` | sRGB 0–255. RGB tuple `[r, g, b]` is not supported — use this object form. |
|
|
331
|
+
| `OklchColor` object | `{ l: 0.85, c: 0.18, h: 152 }` | OKLCh (L/C: 0–1, H: degrees), same semantics as `oklch()` strings. |
|
|
332
|
+
|
|
333
|
+
`GlazeColorInput` (structured form) is `{ hue, saturation, lightness, ... }`:
|
|
334
|
+
|
|
335
|
+
| Field | Type | Description |
|
|
336
|
+
|---|---|---|
|
|
337
|
+
| `hue` | `number` | 0–360. |
|
|
338
|
+
| `saturation` | `number` | 0–100. |
|
|
339
|
+
| `lightness` | `HCPair<number>` | 0–100, optional HC pair. |
|
|
340
|
+
| `saturationFactor` | `number` | Multiplier on the seed (0–1). Default: `1`. |
|
|
341
|
+
| `mode` | `AdaptationMode` | Default: `'auto'`. |
|
|
342
|
+
| `opacity` | `number` | Fixed alpha 0–1. |
|
|
343
|
+
| `base` | `GlazeColorToken \| GlazeColorValue` | Optional dependency. See [Pairing colors](#pairing-colors). |
|
|
344
|
+
| `contrast` | `HCPair<MinContrast>` | WCAG floor against `base`. Without `base`, anchored to the literal seed. |
|
|
345
|
+
| `name` | `string` | Debug label for warnings; doesn't change output keys. Reserved names (`'value'`, `'seed'`, `'externalBase'`) are rejected. |
|
|
763
346
|
|
|
764
347
|
`GlazeFromInput` (from form) is `{ from: GlazeColorValue, ...colorOverrides }`:
|
|
765
348
|
|
|
766
|
-
| Field
|
|
767
|
-
|
|
768
|
-
| `from`
|
|
769
|
-
| `hue`
|
|
770
|
-
| `saturation`
|
|
771
|
-
| `
|
|
772
|
-
| `saturationFactor` | Multiplier on the seed (0–1).
|
|
773
|
-
| `
|
|
774
|
-
| `
|
|
775
|
-
| `
|
|
776
|
-
| `
|
|
777
|
-
| `
|
|
778
|
-
| `contrast` | Contrast floor (WCAG or APCA). Without `base`, anchored to the literal seed; with `base`, solved per scheme. |
|
|
779
|
-
| `base` | `GlazeColorToken` or raw `GlazeColorValue`. See [Pairing colors](#pairing-colors). |
|
|
780
|
-
| `opacity` | Fixed alpha 0–1. Combining with `contrast` is not recommended — `console.warn` is emitted. |
|
|
781
|
-
| `pastel` | Per-color `pastel` override. Falls through to the per-theme / per-token `pastel` override when omitted. See [Per-color `pastel`](#per-color-pastel). |
|
|
782
|
-
| `role` | Semantic role against `base` / the seed (see [Roles](#roles)). Fixes APCA polarity. |
|
|
783
|
-
| `name` | Debug label only — surfaces in warnings/errors. Does not change output keys. |
|
|
349
|
+
| Field | Notes |
|
|
350
|
+
|---|---|
|
|
351
|
+
| `from` | **Required.** The source color value — same forms as `GlazeColorValue`. |
|
|
352
|
+
| `hue` | Number (absolute 0–360) or `'+N'`/`'-N'` (relative to seed, never to `base`). |
|
|
353
|
+
| `saturation` | Override seed saturation (0–100). |
|
|
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. |
|
|
355
|
+
| `saturationFactor` | Multiplier on the seed (0–1). |
|
|
356
|
+
| `mode` | `'auto'` (default) / `'fixed'` / `'static'`. |
|
|
357
|
+
| `contrast` | WCAG floor. Without `base`, anchored to the literal seed; with `base`, solved per scheme. |
|
|
358
|
+
| `base` | `GlazeColorToken` or raw `GlazeColorValue`. See [Pairing colors](#pairing-colors). |
|
|
359
|
+
| `opacity` | Fixed alpha 0–1. Combining with `contrast` is not recommended — `console.warn` is emitted. |
|
|
360
|
+
| `name` | Debug label only — surfaces in warnings/errors. Does not change output keys. |
|
|
784
361
|
|
|
785
362
|
Named CSS colors (`'red'`, `'blueviolet'`) are not supported.
|
|
786
363
|
|
|
787
364
|
### Defaults
|
|
788
365
|
|
|
789
|
-
Every input form defaults to `mode: 'auto'` so the resolved token adapts between light and dark like an ordinary theme color.
|
|
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:
|
|
790
367
|
|
|
791
368
|
- **Value-shorthand** (bare strings, value objects, and `{ from, ...overrides }`):
|
|
792
|
-
- Light variant preserves the input
|
|
793
|
-
-
|
|
794
|
-
- **Structured input** (`{ hue, saturation,
|
|
795
|
-
-
|
|
796
|
-
-
|
|
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).
|
|
373
|
+
- All fields are **snapshotted at color-creation time** — later `glaze.configure()` calls don't retroactively change existing tokens.
|
|
797
374
|
|
|
798
375
|
```ts
|
|
799
376
|
// Bare string — adapts automatically
|
|
800
|
-
glaze.color('#26fcb2')
|
|
377
|
+
glaze.color('#26fcb2')
|
|
801
378
|
|
|
802
379
|
// Value-object — same behavior
|
|
803
|
-
glaze.color({ h: 152, s: 0.95, l: 0.74 })
|
|
804
|
-
|
|
805
|
-
// OKHST value-object — tone axis
|
|
806
|
-
glaze.color({ h: 152, s: 0.95, t: 0.7 });
|
|
380
|
+
glaze.color({ h: 152, s: 0.95, l: 0.74 })
|
|
807
381
|
|
|
808
382
|
// From form — value + color overrides
|
|
809
|
-
glaze.color({ from: '#1a1a2e', hue: '+20', contrast: 'AA' })
|
|
383
|
+
glaze.color({ from: '#1a1a2e', hue: '+20', contrast: 'AA' })
|
|
810
384
|
|
|
811
|
-
// Structured form — explicit hue/saturation/
|
|
812
|
-
glaze.color({ hue: 152, saturation: 95,
|
|
385
|
+
// Structured form — explicit hue/saturation/lightness (0–100)
|
|
386
|
+
glaze.color({ hue: 152, saturation: 95, lightness: 74 })
|
|
813
387
|
```
|
|
814
388
|
|
|
815
389
|
### Token methods
|
|
816
390
|
|
|
817
391
|
A `GlazeColorToken` exposes:
|
|
818
392
|
|
|
819
|
-
| Method
|
|
820
|
-
|
|
821
|
-
| `token.resolve()`
|
|
822
|
-
| `token.token(options?)`
|
|
823
|
-
| `token.tasty(options?)`
|
|
824
|
-
| `token.json(options?)`
|
|
393
|
+
| Method | Description |
|
|
394
|
+
|---|---|
|
|
395
|
+
| `token.resolve()` | Resolve as a `ResolvedColor` (light/dark/lightContrast/darkContrast variants). |
|
|
396
|
+
| `token.token(options?)` | Flat token map (no color-name key). Options: `format`, `modes`, `states`. |
|
|
397
|
+
| `token.tasty(options?)` | Tasty state map (no color-name key). Same options as `token.token`. |
|
|
398
|
+
| `token.json(options?)` | JSON map (no color-name key). Options: `format`, `modes`. |
|
|
825
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`). |
|
|
826
|
-
| `token.
|
|
827
|
-
| `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`. |
|
|
828
|
-
| `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`. |
|
|
829
|
-
| `token.export(override?)` | JSON-safe snapshot — freezes effective config at call time; pass to `glaze.colorFrom(...)` to rehydrate. Optional `override` merges over the instance local (and nested `base` exports). |
|
|
400
|
+
| `token.export()` | JSON-safe snapshot — pass to `glaze.colorFrom(...)` to rehydrate. |
|
|
830
401
|
|
|
831
402
|
### Per-instance config override
|
|
832
403
|
|
|
833
|
-
The optional `config` argument (`GlazeConfigOverride`) overrides
|
|
834
|
-
resolve-relevant fields for a token or theme. A tone window can be
|
|
835
|
-
`[lo, hi]`, `{ lo, hi, eps }`, or `false` (full range). Both themes and
|
|
836
|
-
standalone tokens keep a sparse local override — omitted fields (except
|
|
837
|
-
instance-only `pastel`) fall through to the live global at resolve time.
|
|
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]`.
|
|
838
405
|
|
|
839
406
|
`GlazeConfigOverride`:
|
|
840
407
|
|
|
841
|
-
| Field
|
|
842
|
-
|
|
843
|
-
| `
|
|
844
|
-
| `
|
|
845
|
-
| `darkDesaturation` | `0.1`
|
|
846
|
-
| `
|
|
847
|
-
| `
|
|
848
|
-
| `
|
|
849
|
-
| `shadowTuning` | `undefined` | Default shadow tuning (meaningful for themes; harmless on color tokens). |
|
|
408
|
+
| Field | Default (from global) | Description |
|
|
409
|
+
|---|---|---|
|
|
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). |
|
|
412
|
+
| `darkDesaturation` | `0.1` | Saturation reduction in dark scheme (0–1). |
|
|
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. |
|
|
415
|
+
| `shadowTuning` | `undefined` | Default shadow tuning (meaningful for themes; harmless on color tokens). |
|
|
850
416
|
|
|
851
417
|
Config overrides apply to both `glaze.color()` tokens and `glaze()` themes:
|
|
852
418
|
|
|
853
419
|
```ts
|
|
854
|
-
// Standalone color — preserve raw
|
|
855
|
-
glaze.color('#26fcb2', {
|
|
420
|
+
// Standalone color — preserve raw lightness in both schemes
|
|
421
|
+
glaze.color('#26fcb2', { darkLightness: false })
|
|
856
422
|
|
|
857
423
|
// Restore the #000 → white dark flip (full dark range)
|
|
858
424
|
glaze.color('#000000', {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
})
|
|
425
|
+
lightLightness: false,
|
|
426
|
+
darkLightness: [15, 100],
|
|
427
|
+
})
|
|
862
428
|
|
|
863
429
|
// Structured form with config override
|
|
864
|
-
glaze.color({ hue: 152, saturation: 95,
|
|
430
|
+
glaze.color({ hue: 152, saturation: 95, lightness: 74 }, { darkLightness: false })
|
|
865
431
|
|
|
866
432
|
// Theme with config override
|
|
867
|
-
const rawTheme = glaze(280, 80, {
|
|
433
|
+
const rawTheme = glaze(280, 80, { lightLightness: false })
|
|
868
434
|
```
|
|
869
435
|
|
|
870
|
-
|
|
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)).
|
|
871
437
|
|
|
872
438
|
### Theme config override
|
|
873
439
|
|
|
@@ -877,31 +443,24 @@ When a theme is created with a `GlazeConfigOverride`, the override is **merged o
|
|
|
877
443
|
- Fields you didn't override still react to later `glaze.configure()` calls.
|
|
878
444
|
|
|
879
445
|
```ts
|
|
880
|
-
const t = glaze(280, 80, {
|
|
881
|
-
t.colors({ text: {
|
|
882
|
-
// text.light
|
|
883
|
-
// 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.
|
|
884
449
|
// text.dark.s reacts to glaze.configure({ darkDesaturation }) since it's not overridden.
|
|
885
450
|
```
|
|
886
451
|
|
|
887
452
|
`extend` inherits the parent's override and shallow-merges the child's:
|
|
888
453
|
|
|
889
454
|
```ts
|
|
890
|
-
const child = t.extend({ config: {
|
|
891
|
-
// child:
|
|
455
|
+
const child = t.extend({ config: { darkLightness: false } });
|
|
456
|
+
// child: lightLightness: [0, 50] (inherited) + darkLightness: false (added)
|
|
892
457
|
```
|
|
893
458
|
|
|
894
|
-
`theme.export(
|
|
895
|
-
call time. Restoring via `glaze.themeFrom(data)` (or the compat alias
|
|
896
|
-
`glaze.from`) pins that freeze as the restored theme's local override — matching
|
|
897
|
-
standalone color-token behavior.
|
|
459
|
+
`theme.export()` includes `config`; `glaze.from(data)` restores it.
|
|
898
460
|
|
|
899
461
|
### `glaze.colorFrom(data)`
|
|
900
462
|
|
|
901
|
-
Inverse of `token.export()`. The exported snapshot includes the original input,
|
|
902
|
-
all overrides (with any `base` token recursively serialized), and the effective
|
|
903
|
-
config freeze from export time — so later `glaze.configure()` calls don't change
|
|
904
|
-
rehydrated tokens.
|
|
463
|
+
Inverse of `token.export()`. The exported snapshot includes the original input, all overrides (with any `base` token recursively serialized), and the full effective config — so later `glaze.configure()` calls don't change rehydrated tokens.
|
|
905
464
|
|
|
906
465
|
```ts
|
|
907
466
|
const text = glaze.color({ from: '#1a1a1a', contrast: 'AA' });
|
|
@@ -914,7 +473,7 @@ Both value-form and structured-form tokens round-trip.
|
|
|
914
473
|
|
|
915
474
|
### Pairing colors
|
|
916
475
|
|
|
917
|
-
Set `base` to anchor a standalone color to another standalone color or raw value. The contrast solver and relative `
|
|
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.
|
|
918
477
|
|
|
919
478
|
```ts
|
|
920
479
|
const bg = glaze.color('#1a1a2e');
|
|
@@ -922,11 +481,10 @@ const bg = glaze.color('#1a1a2e');
|
|
|
922
481
|
// Text guaranteed AA against `bg` in every scheme.
|
|
923
482
|
const text = glaze.color({ from: '#ffffff', base: bg, contrast: 'AA' });
|
|
924
483
|
|
|
925
|
-
// Border 8
|
|
926
|
-
const border = glaze.color({
|
|
927
|
-
from: '#000000',
|
|
484
|
+
// Border 8 lightness units lighter than `bg` in each scheme.
|
|
485
|
+
const border = glaze.color({ from: '#000000',
|
|
928
486
|
base: bg,
|
|
929
|
-
|
|
487
|
+
lightness: '+8',
|
|
930
488
|
mode: 'fixed',
|
|
931
489
|
});
|
|
932
490
|
|
|
@@ -937,11 +495,11 @@ const text2 = glaze.color({ from: '#ffffff', base: '#1a1a2e', contrast: 'AA' });
|
|
|
937
495
|
Behavior with `base`:
|
|
938
496
|
|
|
939
497
|
- `contrast` is solved per scheme against `base`'s resolved variant (light / dark / lightContrast / darkContrast).
|
|
940
|
-
- Relative `
|
|
498
|
+
- Relative `lightness: '+N'` / `'-N'` is anchored to `base`'s lightness per scheme (matches theme behavior).
|
|
941
499
|
- Relative `hue: '+N'` / `'-N'` still anchors to the **seed** (the value passed to `glaze.color()`), not the base.
|
|
942
500
|
- `mode` works as a per-pair knob.
|
|
943
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.
|
|
944
|
-
- **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/
|
|
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.
|
|
945
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.
|
|
946
504
|
|
|
947
505
|
Chains compose:
|
|
@@ -964,8 +522,8 @@ The `name` override appears in `console.warn` / Error messages but **does not**
|
|
|
964
522
|
|
|
965
523
|
```ts
|
|
966
524
|
theme.colors({
|
|
967
|
-
surface: {
|
|
968
|
-
text:
|
|
525
|
+
surface: { lightness: 95 },
|
|
526
|
+
text: { base: 'surface', lightness: '-52', contrast: 'AAA' },
|
|
969
527
|
|
|
970
528
|
'shadow-sm': { type: 'shadow', bg: 'surface', fg: 'text', intensity: 5 },
|
|
971
529
|
'shadow-md': { type: 'shadow', bg: 'surface', fg: 'text', intensity: 10 },
|
|
@@ -1004,22 +562,20 @@ theme.colors({
|
|
|
1004
562
|
|
|
1005
563
|
Fine-tune behavior per-color or globally via `glaze.configure({ shadowTuning })`. Per-color `tuning` is merged field-by-field with the global one.
|
|
1006
564
|
|
|
1007
|
-
| Parameter
|
|
1008
|
-
|
|
1009
|
-
| `saturationFactor` | `0.18`
|
|
1010
|
-
| `maxSaturation`
|
|
1011
|
-
| `lightnessFactor`
|
|
1012
|
-
| `lightnessBounds`
|
|
1013
|
-
| `minGapTarget`
|
|
1014
|
-
| `alphaMax`
|
|
1015
|
-
| `bgHueBlend`
|
|
565
|
+
| Parameter | Default | Description |
|
|
566
|
+
|---|---|---|
|
|
567
|
+
| `saturationFactor` | `0.18` | Fraction of fg saturation kept in pigment. |
|
|
568
|
+
| `maxSaturation` | `0.25` | Upper clamp on pigment saturation. |
|
|
569
|
+
| `lightnessFactor` | `0.25` | Multiplier for bg lightness → pigment lightness. |
|
|
570
|
+
| `lightnessBounds` | `[0.05, 0.20]` | Clamp range for pigment lightness. |
|
|
571
|
+
| `minGapTarget` | `0.05` | Target minimum gap between pigment and bg lightness. |
|
|
572
|
+
| `alphaMax` | `1.0` | Asymptotic maximum alpha. |
|
|
573
|
+
| `bgHueBlend` | `0.2` | Blend weight pulling pigment hue toward bg hue. `0` = pure fg hue, `1` = pure bg hue. |
|
|
1016
574
|
|
|
1017
575
|
```ts
|
|
1018
576
|
theme.colors({
|
|
1019
577
|
'shadow-soft': {
|
|
1020
|
-
type: 'shadow',
|
|
1021
|
-
bg: 'surface',
|
|
1022
|
-
intensity: 10,
|
|
578
|
+
type: 'shadow', bg: 'surface', intensity: 10,
|
|
1023
579
|
tuning: { alphaMax: 0.3, saturationFactor: 0.1 },
|
|
1024
580
|
},
|
|
1025
581
|
});
|
|
@@ -1047,12 +603,12 @@ const css = glaze.format(v, 'oklch');
|
|
|
1047
603
|
|
|
1048
604
|
`GlazeShadowInput`:
|
|
1049
605
|
|
|
1050
|
-
| Field
|
|
1051
|
-
|
|
1052
|
-
| `bg`
|
|
1053
|
-
| `fg`
|
|
1054
|
-
| `intensity` | `number`
|
|
1055
|
-
| `tuning`
|
|
606
|
+
| Field | Type | Description |
|
|
607
|
+
|---|---|---|
|
|
608
|
+
| `bg` | `GlazeColorValue` | Background. Any `GlazeColorValue` form. Alpha components dropped with warning. |
|
|
609
|
+
| `fg` | `GlazeColorValue` | Optional foreground. Same forms as `bg`. |
|
|
610
|
+
| `intensity` | `number` | 0–100. |
|
|
611
|
+
| `tuning` | `ShadowTuning` | Optional. |
|
|
1056
612
|
|
|
1057
613
|
### Fixed opacity (regular colors)
|
|
1058
614
|
|
|
@@ -1060,7 +616,7 @@ For a simple fixed-alpha color (no shadow algorithm), use `opacity` on a regular
|
|
|
1060
616
|
|
|
1061
617
|
```ts
|
|
1062
618
|
theme.colors({
|
|
1063
|
-
overlay: {
|
|
619
|
+
overlay: { lightness: 0, opacity: 0.5 },
|
|
1064
620
|
});
|
|
1065
621
|
// → 'oklch(0 0 0 / 0.5)'
|
|
1066
622
|
```
|
|
@@ -1075,9 +631,9 @@ Produces a solid color by interpolating between `base` and `target`:
|
|
|
1075
631
|
|
|
1076
632
|
```ts
|
|
1077
633
|
theme.colors({
|
|
1078
|
-
surface: {
|
|
1079
|
-
accent:
|
|
1080
|
-
tint:
|
|
634
|
+
surface: { lightness: 95 },
|
|
635
|
+
accent: { lightness: 30 },
|
|
636
|
+
tint: { type: 'mix', base: 'surface', target: 'accent', value: 30 },
|
|
1081
637
|
});
|
|
1082
638
|
```
|
|
1083
639
|
|
|
@@ -1091,14 +647,11 @@ Produces the target color with controlled opacity — useful for hover overlays:
|
|
|
1091
647
|
|
|
1092
648
|
```ts
|
|
1093
649
|
theme.colors({
|
|
1094
|
-
surface: {
|
|
1095
|
-
black:
|
|
650
|
+
surface: { lightness: 95 },
|
|
651
|
+
black: { lightness: 0, saturation: 0 },
|
|
1096
652
|
hover: {
|
|
1097
|
-
type: 'mix',
|
|
1098
|
-
|
|
1099
|
-
target: 'black',
|
|
1100
|
-
value: 8,
|
|
1101
|
-
blend: 'transparent',
|
|
653
|
+
type: 'mix', base: 'surface', target: 'black',
|
|
654
|
+
value: 8, blend: 'transparent',
|
|
1102
655
|
},
|
|
1103
656
|
});
|
|
1104
657
|
// hover → black with alpha = 0.08
|
|
@@ -1108,10 +661,10 @@ The output color has `h`, `s`, `l` from the target and `alpha = value / 100`.
|
|
|
1108
661
|
|
|
1109
662
|
### Blend space (opaque only)
|
|
1110
663
|
|
|
1111
|
-
| `space`
|
|
1112
|
-
|
|
1113
|
-
| `'okhsl'` (default) | Perceptually uniform OKHSL interpolation. | Design token derivation.
|
|
1114
|
-
| `'srgb'`
|
|
664
|
+
| `space` | Behavior | Best for |
|
|
665
|
+
|---|---|---|
|
|
666
|
+
| `'okhsl'` (default) | Perceptually uniform OKHSL interpolation. | Design token derivation. |
|
|
667
|
+
| `'srgb'` | Linear sRGB channel interpolation. | Matching browser compositing of CSS color-mix / overlay. |
|
|
1115
668
|
|
|
1116
669
|
Transparent blending always composites in linear sRGB (matches browser alpha compositing).
|
|
1117
670
|
|
|
@@ -1142,22 +695,10 @@ Mix colors can reference other mix colors:
|
|
|
1142
695
|
|
|
1143
696
|
```ts
|
|
1144
697
|
theme.colors({
|
|
1145
|
-
white: {
|
|
1146
|
-
black: {
|
|
1147
|
-
gray:
|
|
1148
|
-
|
|
1149
|
-
base: 'white',
|
|
1150
|
-
target: 'black',
|
|
1151
|
-
value: 50,
|
|
1152
|
-
space: 'srgb',
|
|
1153
|
-
},
|
|
1154
|
-
lightGray: {
|
|
1155
|
-
type: 'mix',
|
|
1156
|
-
base: 'white',
|
|
1157
|
-
target: 'gray',
|
|
1158
|
-
value: 50,
|
|
1159
|
-
space: 'srgb',
|
|
1160
|
-
},
|
|
698
|
+
white: { lightness: 100, saturation: 0 },
|
|
699
|
+
black: { lightness: 0, saturation: 0 },
|
|
700
|
+
gray: { type: 'mix', base: 'white', target: 'black', value: 50, space: 'srgb' },
|
|
701
|
+
lightGray: { type: 'mix', base: 'white', target: 'gray', value: 50, space: 'srgb' },
|
|
1161
702
|
});
|
|
1162
703
|
```
|
|
1163
704
|
|
|
@@ -1179,67 +720,35 @@ const palette = glaze.palette(
|
|
|
1179
720
|
|
|
1180
721
|
`GlazePaletteOptions`:
|
|
1181
722
|
|
|
1182
|
-
| Option
|
|
1183
|
-
|
|
723
|
+
| Option | Description |
|
|
724
|
+
|---|---|
|
|
1184
725
|
| `primary` | Name of the primary theme. The primary's tokens are duplicated **without** prefix in all exports, providing convenient short aliases alongside the prefixed versions. Throws if the name doesn't match any theme. |
|
|
1185
726
|
|
|
1186
727
|
A `GlazePalette` exposes:
|
|
1187
728
|
|
|
1188
|
-
| Method
|
|
1189
|
-
|
|
1190
|
-
| `palette.
|
|
1191
|
-
| `palette.
|
|
1192
|
-
| `palette.
|
|
1193
|
-
| `palette.
|
|
1194
|
-
| `palette.export(override?)` | Authoring snapshot — restorable via `glaze.paletteFrom()`. Optional override forwarded to themes. |
|
|
1195
|
-
| `palette.tokens(options?)` | Flat token map grouped by scheme variant. |
|
|
1196
|
-
| `palette.tasty(options?)` | [Tasty](https://tasty.style) style-to-state bindings. |
|
|
1197
|
-
| `palette.json(options?)` | Per-theme **resolved** color JSON (not restorable as authoring config). |
|
|
1198
|
-
| `palette.css(options?)` | CSS custom property declaration strings. |
|
|
1199
|
-
| `palette.dtcg(options?)` | Per-scheme W3C DTCG token trees. |
|
|
1200
|
-
| `palette.dtcgResolver(options?)` | One DTCG Resolver-Module document for every scheme. |
|
|
1201
|
-
| `palette.tailwind(options?)` | One Tailwind CSS v4 theme with scheme overrides. |
|
|
1202
|
-
|
|
1203
|
-
### `palette.export(override?)` / `glaze.paletteFrom()`
|
|
1204
|
-
|
|
1205
|
-
```ts
|
|
1206
|
-
const snapshot = palette.export();
|
|
1207
|
-
// → {
|
|
1208
|
-
// kind: 'palette',
|
|
1209
|
-
// version: 1,
|
|
1210
|
-
// primary: 'brand',
|
|
1211
|
-
// themes: { brand: { kind: 'theme', ... }, danger: { ... } },
|
|
1212
|
-
// }
|
|
1213
|
-
|
|
1214
|
-
const restored = glaze.paletteFrom(JSON.parse(JSON.stringify(snapshot)));
|
|
1215
|
-
const brand = restored.theme('brand')!;
|
|
1216
|
-
```
|
|
1217
|
-
|
|
1218
|
-
Optional `override` is forwarded to each nested `theme.export(override)`.
|
|
1219
|
-
Config snapshot vs resolved output: use `export()` / `paletteFrom()` to
|
|
1220
|
-
persist and restore the authoring graph (themes, color defs, relations). Use
|
|
1221
|
-
`json()` / `tokens()` / `css()` / … to emit resolved color strings for apps
|
|
1222
|
-
and design tools.
|
|
729
|
+
| Method | Description |
|
|
730
|
+
|---|---|
|
|
731
|
+
| `palette.tokens(options?)` | Flat token map grouped by scheme variant. |
|
|
732
|
+
| `palette.tasty(options?)` | Tasty style-to-state bindings. |
|
|
733
|
+
| `palette.json(options?)` | Per-theme JSON map (no prefix needed — keyed by theme name). |
|
|
734
|
+
| `palette.css(options?)` | CSS custom property declaration strings. |
|
|
1223
735
|
|
|
1224
736
|
### `GlazePaletteExportOptions`
|
|
1225
737
|
|
|
1226
738
|
Shared by `tokens`, `tasty`, and `css`:
|
|
1227
739
|
|
|
1228
|
-
| Option
|
|
1229
|
-
|
|
1230
|
-
| `prefix`
|
|
1231
|
-
| `primary` | inherits from palette creation | `string` to override, `false` to disable for this call.
|
|
740
|
+
| Option | Default | Description |
|
|
741
|
+
|---|---|---|
|
|
742
|
+
| `prefix` | `true` (= `"<themeName>-"`) | `false` disables prefixing. Or pass a custom map: `{ primary: 'brand-', danger: 'error-' }`. |
|
|
743
|
+
| `primary` | inherits from palette creation | `string` to override, `false` to disable for this call. |
|
|
1232
744
|
|
|
1233
745
|
Each export method also accepts its own format/options shape:
|
|
1234
746
|
|
|
1235
|
-
| Method
|
|
1236
|
-
|
|
1237
|
-
| `palette.tokens(options?)`
|
|
1238
|
-
| `palette.tasty(options?)`
|
|
1239
|
-
| `palette.css(options?)`
|
|
1240
|
-
| `palette.dtcg(options?)` | `colorSpace`, `modes` |
|
|
1241
|
-
| `palette.dtcgResolver(options?)` | `colorSpace`, `modes`, resolver names |
|
|
1242
|
-
| `palette.tailwind(options?)` | `format`, `modes`, selectors, `namespace` |
|
|
747
|
+
| Method | Additional options |
|
|
748
|
+
|---|---|
|
|
749
|
+
| `palette.tokens(options?)` | `format`, `modes` |
|
|
750
|
+
| `palette.tasty(options?)` | `format`, `modes`, `states` |
|
|
751
|
+
| `palette.css(options?)` | `format`, `suffix` |
|
|
1243
752
|
|
|
1244
753
|
`palette.css()` does not accept `modes`; it always returns all four CSS strings (`light`, `dark`, `lightContrast`, `darkContrast`).
|
|
1245
754
|
|
|
@@ -1250,8 +759,8 @@ By default all palette tokens are prefixed:
|
|
|
1250
759
|
```ts
|
|
1251
760
|
palette.tokens();
|
|
1252
761
|
// → {
|
|
1253
|
-
// light: { 'primary-surface': '
|
|
1254
|
-
// dark: { 'primary-surface': '
|
|
762
|
+
// light: { 'primary-surface': 'okhsl(...)', 'danger-surface': 'okhsl(...)' },
|
|
763
|
+
// dark: { 'primary-surface': 'okhsl(...)', 'danger-surface': 'okhsl(...)' },
|
|
1255
764
|
// }
|
|
1256
765
|
```
|
|
1257
766
|
|
|
@@ -1287,10 +796,10 @@ const palette = glaze.palette(
|
|
|
1287
796
|
palette.tokens();
|
|
1288
797
|
// → {
|
|
1289
798
|
// light: {
|
|
1290
|
-
// 'primary-surface': '
|
|
1291
|
-
// 'danger-surface': '
|
|
1292
|
-
// 'success-surface': '
|
|
1293
|
-
// 'surface': '
|
|
799
|
+
// 'primary-surface': 'okhsl(...)',
|
|
800
|
+
// 'danger-surface': 'okhsl(...)',
|
|
801
|
+
// 'success-surface': 'okhsl(...)',
|
|
802
|
+
// 'surface': 'okhsl(...)', // unprefixed alias
|
|
1294
803
|
// },
|
|
1295
804
|
// }
|
|
1296
805
|
```
|
|
@@ -1316,8 +825,8 @@ JSON export groups by theme name (no prefix needed):
|
|
|
1316
825
|
```ts
|
|
1317
826
|
palette.json();
|
|
1318
827
|
// → {
|
|
1319
|
-
// primary: { surface: { light: '
|
|
1320
|
-
// danger: { surface: { light: '
|
|
828
|
+
// primary: { surface: { light: 'okhsl(...)', dark: 'okhsl(...)' } },
|
|
829
|
+
// danger: { surface: { light: 'okhsl(...)', dark: 'okhsl(...)' } },
|
|
1321
830
|
// }
|
|
1322
831
|
```
|
|
1323
832
|
|
|
@@ -1336,113 +845,29 @@ const stylesheet = `
|
|
|
1336
845
|
`palette.css()` accepts the same `GlazeCssOptions` as `theme.css()` plus `GlazePaletteExportOptions`.
|
|
1337
846
|
It does not accept `modes`; all four result fields are always returned.
|
|
1338
847
|
|
|
1339
|
-
### `palette.dtcg()`
|
|
1340
|
-
|
|
1341
|
-
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).
|
|
1342
|
-
|
|
1343
|
-
```ts
|
|
1344
|
-
palette.dtcg();
|
|
1345
|
-
// → {
|
|
1346
|
-
// light: {
|
|
1347
|
-
// 'primary-surface': { $type: 'color', $value: { ... } },
|
|
1348
|
-
// 'surface': { $type: 'color', $value: { ... } }, // unprefixed alias
|
|
1349
|
-
// 'danger-surface': { $type: 'color', $value: { ... } },
|
|
1350
|
-
// },
|
|
1351
|
-
// dark: { ... },
|
|
1352
|
-
// }
|
|
1353
|
-
```
|
|
1354
|
-
|
|
1355
|
-
Accepts `GlazeDtcgOptions` plus `GlazePaletteExportOptions`.
|
|
1356
|
-
|
|
1357
|
-
### `palette.dtcgResolver()`
|
|
1358
|
-
|
|
1359
|
-
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.
|
|
1360
|
-
|
|
1361
|
-
```ts
|
|
1362
|
-
palette.dtcgResolver();
|
|
1363
|
-
// → {
|
|
1364
|
-
// version: '2025.10',
|
|
1365
|
-
// sets: { base: { sources: [ { 'primary-surface': {…}, 'surface': {…}, 'danger-surface': {…} } ] } },
|
|
1366
|
-
// modifiers: { scheme: { default: 'light', contexts: { light: [], dark: [ {…} ] } } },
|
|
1367
|
-
// resolutionOrder: [ { $ref: '#/sets/base' }, { $ref: '#/modifiers/scheme' } ],
|
|
1368
|
-
// }
|
|
1369
|
-
```
|
|
1370
|
-
|
|
1371
|
-
Accepts `GlazeDtcgResolverOptions` plus `GlazePaletteExportOptions`.
|
|
1372
|
-
|
|
1373
|
-
### `palette.tailwind()`
|
|
1374
|
-
|
|
1375
|
-
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`.
|
|
1376
|
-
|
|
1377
|
-
```ts
|
|
1378
|
-
const css = palette.tailwind();
|
|
1379
|
-
// @theme {
|
|
1380
|
-
// --color-primary-surface: oklch(...);
|
|
1381
|
-
// --color-surface: oklch(...); /* unprefixed alias */
|
|
1382
|
-
// --color-danger-surface: oklch(...);
|
|
1383
|
-
// }
|
|
1384
|
-
// .dark { ... }
|
|
1385
|
-
```
|
|
1386
|
-
|
|
1387
|
-
Accepts `GlazeTailwindOptions` plus `GlazePaletteExportOptions`. The palette `prefix` option (theme prefixing) is separate from `GlazeTailwindOptions.namespace` (the `--color-*` CSS namespace).
|
|
1388
|
-
|
|
1389
848
|
---
|
|
1390
849
|
|
|
1391
850
|
## Output formats
|
|
1392
851
|
|
|
1393
852
|
Control the color format with the `format` option on any export method:
|
|
1394
853
|
|
|
1395
|
-
| Format
|
|
1396
|
-
|
|
1397
|
-
| `'
|
|
1398
|
-
| `'rgb'`
|
|
1399
|
-
| `'hsl'`
|
|
1400
|
-
| `'
|
|
1401
|
-
| `'okhst'` | `okhst(H S% T%)` | `okhst(H S% T% / A)` | OKHST tone axis. **[Tasty](https://tasty.style)-only** — same restriction as `okhsl`. |
|
|
854
|
+
| Format | Output (alpha = 1) | Output (alpha < 1) | Notes |
|
|
855
|
+
|---|---|---|---|
|
|
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. |
|
|
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. |
|
|
1402
860
|
|
|
1403
861
|
```ts
|
|
1404
|
-
theme.tokens();
|
|
1405
|
-
theme.tokens({ format: 'rgb' });
|
|
1406
|
-
theme.
|
|
1407
|
-
theme.
|
|
862
|
+
theme.tokens(); // 'okhsl(280 60% 97%)'
|
|
863
|
+
theme.tokens({ format: 'rgb' }); // 'rgb(244 240 250)'
|
|
864
|
+
theme.tokens({ format: 'hsl' }); // 'hsl(270.5 45.2% 95.8%)'
|
|
865
|
+
theme.tokens({ format: 'oklch' }); // 'oklch(0.965 0.0123 280)'
|
|
1408
866
|
```
|
|
1409
867
|
|
|
1410
868
|
All numeric output strips trailing zeros for cleaner CSS (e.g. `95` not `95.0`).
|
|
1411
869
|
|
|
1412
|
-
The `format` option works on
|
|
1413
|
-
|
|
1414
|
-
### Hue channel splitting (`splitHue`)
|
|
1415
|
-
|
|
1416
|
-
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:
|
|
1417
|
-
|
|
1418
|
-
```css
|
|
1419
|
-
/* theme.css({ format: 'oklch', splitHue: true, name: 'brand' }) */
|
|
1420
|
-
--brand-hue: 240;
|
|
1421
|
-
--accent-hue: calc(var(--brand-hue) + 20);
|
|
1422
|
-
--surface-color: oklch(0.52 0.06 var(--brand-hue));
|
|
1423
|
-
--accent-color: oklch(0.62 0.03 var(--accent-hue));
|
|
1424
|
-
```
|
|
1425
|
-
|
|
1426
|
-
**Requirements:** every exported color must be pastel (`pastel: true` on the theme/token override 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.
|
|
1427
|
-
|
|
1428
|
-
**Dark hues:** hue vars are scheme-independent unless the theme or a color authors a [dark hue](#dark-seed-darkhue--darksaturation). When one does, the whole hue set is re-declared in the dark block (and in the Tasty dark state, gated by `modes.dark`):
|
|
1429
|
-
|
|
1430
|
-
```css
|
|
1431
|
-
/* glaze({ hue: 240, saturation: 18, darkHue: 200 }) */
|
|
1432
|
-
:root {
|
|
1433
|
-
--brand-hue: 240;
|
|
1434
|
-
--accent-hue: calc(var(--brand-hue) + 20);
|
|
1435
|
-
}
|
|
1436
|
-
/* dark */
|
|
1437
|
-
--brand-hue: 200;
|
|
1438
|
-
--accent-hue: calc(var(--brand-hue) + 20);
|
|
1439
|
-
```
|
|
1440
|
-
|
|
1441
|
-
`--accent-hue` repeats verbatim on purpose: a custom property substitutes `var()` at computed-value time on the element that declares it, so it has to be re-declared to pick up the new `--brand-hue`. Colors with `mode: 'static'` are pinned to an absolute hue instead, so they don't drift with the dark seed.
|
|
1442
|
-
|
|
1443
|
-
**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).
|
|
1444
|
-
|
|
1445
|
-
`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()`.
|
|
1446
871
|
|
|
1447
872
|
---
|
|
1448
873
|
|
|
@@ -1450,84 +875,87 @@ On `theme.css()`, `theme.tasty()`, `palette.css()`, `palette.tasty()`, and stand
|
|
|
1450
875
|
|
|
1451
876
|
`mode` controls how a color adapts across schemes:
|
|
1452
877
|
|
|
1453
|
-
| Mode
|
|
1454
|
-
|
|
1455
|
-
| `'auto'` (default) | Full adaptation.
|
|
1456
|
-
| `'fixed'`
|
|
1457
|
-
| `'static'`
|
|
878
|
+
| Mode | Behavior |
|
|
879
|
+
|---|---|
|
|
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. |
|
|
1458
883
|
|
|
1459
|
-
### How relative
|
|
884
|
+
### How relative lightness adapts
|
|
1460
885
|
|
|
1461
|
-
**`auto`** —
|
|
886
|
+
**`auto`** — relative lightness sign flips in dark scheme:
|
|
1462
887
|
|
|
1463
888
|
```
|
|
1464
|
-
Light: surface
|
|
1465
|
-
Dark: surface inverts to
|
|
1466
|
-
|
|
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)
|
|
1467
892
|
```
|
|
1468
893
|
|
|
1469
|
-
**`fixed`** —
|
|
894
|
+
**`fixed`** — lightness is mapped (not inverted), relative sign preserved:
|
|
1470
895
|
|
|
1471
896
|
```
|
|
1472
|
-
Light: accent-fill
|
|
1473
|
-
Dark: accent-fill maps
|
|
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
|
|
1474
899
|
```
|
|
1475
900
|
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
**`static`** — no adaptation, same tone in every scheme.
|
|
901
|
+
**`static`** — no adaptation, same value in every scheme.
|
|
1479
902
|
|
|
1480
903
|
---
|
|
1481
904
|
|
|
1482
905
|
## Light / dark scheme mapping
|
|
1483
906
|
|
|
1484
|
-
|
|
1485
|
-
[Scheme adaptation](okhst.md#scheme-adaptation) for the product-level model and
|
|
1486
|
-
the [canonical OKHST specification](https://github.com/tenphi/okhst) for the
|
|
1487
|
-
transfer math.
|
|
1488
|
-
|
|
1489
|
-
### Light scheme
|
|
907
|
+
### Light scheme — lightness
|
|
1490
908
|
|
|
1491
|
-
|
|
1492
|
-
The window's `lo`/`hi` are OKHSL-lightness boundaries (0–100); authored tone is
|
|
1493
|
-
positioned within the corresponding tone interval and converted to final OKHSL
|
|
1494
|
-
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:
|
|
1495
910
|
|
|
1496
|
-
```
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
finalL = fromTone(finalTone) // OKHSL lightness
|
|
911
|
+
```ts
|
|
912
|
+
const [lo, hi] = lightLightness; // default: [10, 100]
|
|
913
|
+
const mappedL = (lightness * (hi - lo)) / 100 + lo;
|
|
1500
914
|
```
|
|
1501
915
|
|
|
1502
|
-
|
|
916
|
+
Both `auto` and `fixed` modes use the same linear formula. `static` mode and HC variants bypass the mapping (identity: `mappedL = l`).
|
|
1503
917
|
|
|
1504
|
-
|
|
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 |
|
|
1505
923
|
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
inverted
|
|
1509
|
-
|
|
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
|
|
1510
933
|
```
|
|
1511
934
|
|
|
1512
|
-
The inversion
|
|
1513
|
-
exactly contrast-even for neutrals and approximate for chromatic colors. The
|
|
1514
|
-
ordinary light/dark asymmetry lives in the two windows' `(lo, hi, eps)` values
|
|
1515
|
-
(`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]`).
|
|
1516
936
|
|
|
1517
|
-
|
|
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.
|
|
1518
938
|
|
|
939
|
+
**`fixed`** — mapped without inversion (not affected by `darkCurve`):
|
|
940
|
+
|
|
941
|
+
```ts
|
|
942
|
+
const mappedL = (lightness * (hi - lo)) / 100 + lo;
|
|
1519
943
|
```
|
|
1520
|
-
finalTone = remap(authorTone, darkTone)
|
|
1521
|
-
```
|
|
1522
944
|
|
|
1523
|
-
|
|
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.
|
|
1524
952
|
|
|
1525
953
|
### Dark scheme — saturation
|
|
1526
954
|
|
|
1527
955
|
`darkDesaturation` reduces saturation for all colors in dark scheme:
|
|
1528
956
|
|
|
1529
957
|
```ts
|
|
1530
|
-
S_dark = S_light * (1 - darkDesaturation)
|
|
958
|
+
S_dark = S_light * (1 - darkDesaturation) // default: 0.1
|
|
1531
959
|
```
|
|
1532
960
|
|
|
1533
961
|
`static` mode skips desaturation.
|
|
@@ -1538,12 +966,13 @@ S_dark = S_light * (1 - darkDesaturation); // default: 0.1
|
|
|
1538
966
|
|
|
1539
967
|
```ts
|
|
1540
968
|
glaze.configure({
|
|
1541
|
-
|
|
1542
|
-
|
|
969
|
+
lightLightness: [10, 100], // or false to disable clamping
|
|
970
|
+
darkLightness: [15, 95], // or false to disable clamping
|
|
1543
971
|
darkDesaturation: 0.1,
|
|
972
|
+
darkCurve: 0.5, // or [normal, hc] pair
|
|
1544
973
|
states: {
|
|
1545
|
-
dark: '@
|
|
1546
|
-
highContrast: '@
|
|
974
|
+
dark: '@dark',
|
|
975
|
+
highContrast: '@high-contrast',
|
|
1547
976
|
},
|
|
1548
977
|
modes: {
|
|
1549
978
|
dark: true,
|
|
@@ -1556,33 +985,28 @@ glaze.configure({
|
|
|
1556
985
|
});
|
|
1557
986
|
```
|
|
1558
987
|
|
|
1559
|
-
A `ToneWindow` is `[lo, hi]` (OKHSL-lightness boundaries, reference eps — the
|
|
1560
|
-
common form), `{ lo, hi, eps }` (advanced: explicit per-scheme render eps), or
|
|
1561
|
-
`false` for the full range `[0, 100]` at the reference eps. `false` removes the
|
|
1562
|
-
boundaries, not the tone transfer.
|
|
1563
|
-
|
|
1564
988
|
`GlazeConfig`:
|
|
1565
989
|
|
|
1566
|
-
| Field
|
|
1567
|
-
|
|
1568
|
-
| `
|
|
1569
|
-
| `
|
|
1570
|
-
| `darkDesaturation`
|
|
1571
|
-
| `
|
|
1572
|
-
| `states.
|
|
1573
|
-
| `
|
|
1574
|
-
| `modes.
|
|
1575
|
-
| `
|
|
1576
|
-
| `
|
|
1577
|
-
| `
|
|
1578
|
-
|
|
1579
|
-
| Method
|
|
1580
|
-
|
|
990
|
+
| Field | Default | Description |
|
|
991
|
+
|---|---|---|
|
|
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. |
|
|
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. |
|
|
996
|
+
| `states.dark` | `'@dark'` | State alias for dark mode tokens (Tasty export). |
|
|
997
|
+
| `states.highContrast` | `'@high-contrast'` | State alias for HC tokens. |
|
|
998
|
+
| `modes.dark` | `true` | Include dark variants in exports. |
|
|
999
|
+
| `modes.highContrast` | `false` | Include HC variants. |
|
|
1000
|
+
| `shadowTuning` | `undefined` | Default tuning for all shadow colors. Per-color tuning merges field-by-field. |
|
|
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). |
|
|
1002
|
+
|
|
1003
|
+
| Method | Description |
|
|
1004
|
+
|---|---|
|
|
1581
1005
|
| `glaze.configure(config)` | Merge into the global config. Bumps a config version that invalidates theme caches. |
|
|
1582
|
-
| `glaze.getConfig()`
|
|
1583
|
-
| `glaze.resetConfig()`
|
|
1006
|
+
| `glaze.getConfig()` | Snapshot the current resolved config (shallow copy). |
|
|
1007
|
+
| `glaze.resetConfig()` | Reset to defaults (also bumps the version counter). |
|
|
1584
1008
|
|
|
1585
|
-
|
|
1009
|
+
Standalone `glaze.color()` tokens snapshot the resolve-relevant fields at create time, so later `configure()` calls don't change already-created tokens. Themes merge the live global at resolve time for fields not overridden via `GlazeConfigOverride`.
|
|
1586
1010
|
|
|
1587
1011
|
---
|
|
1588
1012
|
|
|
@@ -1612,38 +1036,30 @@ Resolution priority (highest first):
|
|
|
1612
1036
|
|
|
1613
1037
|
## Validation
|
|
1614
1038
|
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
|
1622
|
-
|
|
|
1623
|
-
|
|
|
1624
|
-
|
|
|
1625
|
-
| `
|
|
1626
|
-
|
|
|
1627
|
-
|
|
|
1628
|
-
| `
|
|
1629
|
-
|
|
|
1630
|
-
| `
|
|
1631
|
-
|
|
|
1632
|
-
| `base` references non-existent
|
|
1633
|
-
|
|
|
1634
|
-
|
|
|
1635
|
-
|
|
|
1636
|
-
|
|
|
1637
|
-
|
|
|
1638
|
-
|
|
|
1639
|
-
| `contrast` + `opacity` combined | `console.warn` |
|
|
1640
|
-
| Mix `base` references non-existent color | Validation error |
|
|
1641
|
-
| Mix `target` references non-existent color | Validation error |
|
|
1642
|
-
| Mix `base` references a shadow color | Validation error |
|
|
1643
|
-
| Mix `target` references a shadow color | Validation error |
|
|
1644
|
-
| Mix `value` outside 0–100 | Clamp silently |
|
|
1645
|
-
| Circular references involving mix colors | Validation error |
|
|
1646
|
-
| Contrast target physically unreachable | `console.warn` (deduped per `(name, scheme, target)`); closest passing variant returned |
|
|
1039
|
+
| Condition | Behavior |
|
|
1040
|
+
|---|---|
|
|
1041
|
+
| `contrast` without `base` in a **theme** color | Validation error |
|
|
1042
|
+
| Relative `lightness` without `base` in a **theme** color | Validation error |
|
|
1043
|
+
| `contrast` without `base` in `glaze.color()` | Anchors against the literal seed (no error) |
|
|
1044
|
+
| Relative `lightness` without `base` in `glaze.color()` | Anchors against the literal seed (no error) |
|
|
1045
|
+
| `lightness` resolves outside 0–100 | Clamp silently |
|
|
1046
|
+
| `saturation` outside 0–1 | Clamp silently |
|
|
1047
|
+
| Circular `base` references | Validation error |
|
|
1048
|
+
| `base` references non-existent name | Validation error |
|
|
1049
|
+
| Shadow `bg` references non-existent color | Validation error |
|
|
1050
|
+
| Shadow `fg` references non-existent color | Validation error |
|
|
1051
|
+
| Shadow `bg` references another shadow color | Validation error |
|
|
1052
|
+
| Shadow `fg` references another shadow color | Validation error |
|
|
1053
|
+
| Regular color `base` references a shadow color | Validation error |
|
|
1054
|
+
| Shadow `intensity` outside 0–100 | Clamp silently |
|
|
1055
|
+
| `contrast` + `opacity` combined | `console.warn` |
|
|
1056
|
+
| Mix `base` references non-existent color | Validation error |
|
|
1057
|
+
| Mix `target` references non-existent color | Validation error |
|
|
1058
|
+
| Mix `base` references a shadow color | Validation error |
|
|
1059
|
+
| Mix `target` references a shadow color | Validation error |
|
|
1060
|
+
| Mix `value` outside 0–100 | Clamp silently |
|
|
1061
|
+
| Circular references involving mix colors | Validation error |
|
|
1062
|
+
| Contrast target physically unreachable | `console.warn` (deduped per `(name, scheme, target)`); closest passing variant returned |
|
|
1647
1063
|
|
|
1648
1064
|
---
|
|
1649
1065
|
|
|
@@ -1669,19 +1085,19 @@ import {
|
|
|
1669
1085
|
} from '@tenphi/glaze';
|
|
1670
1086
|
```
|
|
1671
1087
|
|
|
1672
|
-
| Function
|
|
1673
|
-
|
|
1674
|
-
| `okhslToLinearSrgb(h, s, l)`
|
|
1675
|
-
| `okhslToSrgb(h, s, l)`
|
|
1676
|
-
| `okhslToOklab([h, s, l])`
|
|
1677
|
-
| `oklabToOkhsl([L, a, b])`
|
|
1678
|
-
| `srgbToOkhsl([r, g, b])`
|
|
1679
|
-
| `hslToSrgb(h, s, l)`
|
|
1680
|
-
| `parseHex(hex)`
|
|
1681
|
-
| `parseHexAlpha(hex)`
|
|
1682
|
-
| `relativeLuminanceFromLinearRgb(rgb)` | WCAG relative luminance from linear sRGB.
|
|
1683
|
-
| `contrastRatioFromLuminance(yA, yB)`
|
|
1684
|
-
| `gamutClampedLuminance(linearRgb)`
|
|
1088
|
+
| Function | Description |
|
|
1089
|
+
|---|---|
|
|
1090
|
+
| `okhslToLinearSrgb(h, s, l)` | OKHSL (h: 0–360, s/l: 0–1) → linear sRGB tuple. |
|
|
1091
|
+
| `okhslToSrgb(h, s, l)` | OKHSL → gamma-encoded sRGB tuple (0–1 per channel). |
|
|
1092
|
+
| `okhslToOklab([h, s, l])` | OKHSL → OKLab `[L, a, b]`. |
|
|
1093
|
+
| `oklabToOkhsl([L, a, b])` | OKLab → OKHSL. |
|
|
1094
|
+
| `srgbToOkhsl([r, g, b])` | Gamma sRGB (0–1) → OKHSL. |
|
|
1095
|
+
| `hslToSrgb(h, s, l)` | CSS HSL → sRGB tuple. |
|
|
1096
|
+
| `parseHex(hex)` | Parse `#rgb` / `#rrggbb` to sRGB tuple. Returns `null` on invalid input. |
|
|
1097
|
+
| `parseHexAlpha(hex)` | Parse `#rgb` / `#rrggbb` / `#rrggbbaa`; returns `[r, g, b, a?]`. |
|
|
1098
|
+
| `relativeLuminanceFromLinearRgb(rgb)` | WCAG relative luminance from linear sRGB. |
|
|
1099
|
+
| `contrastRatioFromLuminance(yA, yB)` | WCAG contrast ratio from two luminances. |
|
|
1100
|
+
| `gamutClampedLuminance(linearRgb)` | Relative luminance with channel clamping for out-of-gamut colors. |
|
|
1685
1101
|
|
|
1686
1102
|
### Format writers
|
|
1687
1103
|
|
|
@@ -1689,77 +1105,42 @@ import {
|
|
|
1689
1105
|
import { formatOkhsl, formatRgb, formatHsl, formatOklch } from '@tenphi/glaze';
|
|
1690
1106
|
|
|
1691
1107
|
formatOkhsl(280, 60, 95); // 'okhsl(280 60% 95%)'
|
|
1692
|
-
formatRgb(280, 60, 95);
|
|
1693
|
-
formatHsl(280, 60, 95);
|
|
1108
|
+
formatRgb(280, 60, 95); // 'rgb(244 240 250)'
|
|
1109
|
+
formatHsl(280, 60, 95); // 'hsl(280 60% 95%)'
|
|
1694
1110
|
formatOklch(280, 60, 95); // 'oklch(0.95 ... 280)'
|
|
1695
1111
|
```
|
|
1696
1112
|
|
|
1697
1113
|
To attach an alpha component, use `glaze.format(variant, format)` on a `ResolvedColorVariant` (which carries the `alpha` channel) instead of these raw writers.
|
|
1698
1114
|
|
|
1699
|
-
### OKHST tone utilities
|
|
1700
|
-
|
|
1701
|
-
```ts
|
|
1702
|
-
import {
|
|
1703
|
-
toTone,
|
|
1704
|
-
fromTone,
|
|
1705
|
-
toneFromY,
|
|
1706
|
-
yFromTone,
|
|
1707
|
-
okhstToOkhsl,
|
|
1708
|
-
okhslToOkhst,
|
|
1709
|
-
variantToOkhsl,
|
|
1710
|
-
REF_EPS,
|
|
1711
|
-
} from '@tenphi/glaze';
|
|
1712
|
-
```
|
|
1713
|
-
|
|
1714
|
-
| Function | Description |
|
|
1715
|
-
| ------------------------------------------- | ------------------------------------------------------------------------- |
|
|
1716
|
-
| `toTone(l, eps?)` | OKHSL lightness (0–1) → tone (0–100). Defaults to `REF_EPS`. |
|
|
1717
|
-
| `fromTone(t, eps?)` | Tone (0–100) → OKHSL lightness (0–1). Inverse of `toTone`. |
|
|
1718
|
-
| `toneFromY(y, eps?)` / `yFromTone(t, eps?)` | Same transfer in luminance space (0–1). |
|
|
1719
|
-
| `okhstToOkhsl({ h, s, t })` | OKHST → OKHSL (`{ h, s, l }`). |
|
|
1720
|
-
| `okhslToOkhst({ h, s, l })` | OKHSL → OKHST (`{ h, s, t }`). |
|
|
1721
|
-
| `variantToOkhsl(variant)` | `ResolvedColorVariant` (stores `t`) → `{ h, s, l, alpha }` for rendering. |
|
|
1722
|
-
| `REF_EPS` | Reference epsilon (`0.05`) for the canonical tone axis. |
|
|
1723
|
-
|
|
1724
|
-
`ResolvedColorVariant` stores `{ h, s, t, alpha }` (tone, not lightness). Use
|
|
1725
|
-
`variantToOkhsl(variant).l` to recover OKHSL lightness. See
|
|
1726
|
-
[OKHST in Glaze](okhst.md) for the model.
|
|
1727
|
-
|
|
1728
1115
|
### Contrast solver
|
|
1729
1116
|
|
|
1730
1117
|
```ts
|
|
1731
1118
|
import {
|
|
1732
|
-
|
|
1119
|
+
findLightnessForContrast,
|
|
1733
1120
|
findValueForMixContrast,
|
|
1734
|
-
resolveContrastForMode,
|
|
1735
1121
|
resolveMinContrast,
|
|
1736
|
-
apcaContrast,
|
|
1737
1122
|
} from '@tenphi/glaze';
|
|
1738
1123
|
```
|
|
1739
1124
|
|
|
1740
|
-
| Function
|
|
1741
|
-
|
|
1742
|
-
| `
|
|
1743
|
-
| `findValueForMixContrast(opts)`
|
|
1744
|
-
| `
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
`
|
|
1751
|
-
|
|
1752
|
-
|
|
|
1753
|
-
|
|
|
1754
|
-
| `
|
|
1755
|
-
| `
|
|
1756
|
-
| `
|
|
1757
|
-
| `
|
|
1758
|
-
| `
|
|
1759
|
-
| `
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
| `initialDirection` | higher-contrast side | Direction to search first (`'lighter'` or `'darker'`). |
|
|
1763
|
-
| `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. |
|
|
1764
|
-
|
|
1765
|
-
Result: `{ tone, contrast, met, branch: 'lighter' | 'darker' | 'preferred', flipped? }`. `flipped: true` indicates the initial direction failed and the opposite direction satisfied the target.
|
|
1125
|
+
| Function | Description |
|
|
1126
|
+
|---|---|
|
|
1127
|
+
| `findLightnessForContrast(opts)` | Binary-search for the OKHSL lightness that meets a WCAG contrast floor against a base color. Returns `{ lightness, contrast, met, branch }`. |
|
|
1128
|
+
| `findValueForMixContrast(opts)` | Same, but searches for a mix `value` (0–1) that meets a contrast floor between a base and a target. |
|
|
1129
|
+
| `resolveMinContrast(value)` | Resolves a `MinContrast` (preset or number) to a numeric ratio. |
|
|
1130
|
+
|
|
1131
|
+
`findLightnessForContrast` options:
|
|
1132
|
+
|
|
1133
|
+
| Option | Default | Description |
|
|
1134
|
+
|---|---|---|
|
|
1135
|
+
| `hue` | — | Candidate hue (0–360). |
|
|
1136
|
+
| `saturation` | — | Candidate saturation (0–1). |
|
|
1137
|
+
| `preferredLightness` | — | Preferred candidate lightness (0–1). Kept if it already meets the target. |
|
|
1138
|
+
| `baseLinearRgb` | — | Base color as linear sRGB tuple. |
|
|
1139
|
+
| `contrast` | — | WCAG floor (`MinContrast`). |
|
|
1140
|
+
| `lightnessRange` | `[0, 1]` | Search bounds. |
|
|
1141
|
+
| `epsilon` | `1e-4` | Convergence threshold. |
|
|
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. |
|
|
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. |
|
|
1145
|
+
|
|
1146
|
+
Result: `{ lightness, contrast, met, branch: 'lighter' | 'darker' | 'preferred', flipped? }`. `flipped: true` indicates the initial direction failed and the opposite direction satisfied the target.
|