@xtyle/core 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +212 -0
- package/algorithms.d.ts +25 -0
- package/concepts/algorithms.md +28 -0
- package/concepts/consuming.md +45 -0
- package/concepts/open-register.md +28 -0
- package/concepts/overview.md +43 -0
- package/dist/algorithms/factory.d.ts +102 -0
- package/dist/algorithms/factory.d.ts.map +1 -0
- package/dist/algorithms/factory.js +2187 -0
- package/dist/algorithms/factory.js.map +1 -0
- package/dist/audit.d.ts +52 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +71 -0
- package/dist/audit.js.map +1 -0
- package/dist/authoring.d.ts +52 -0
- package/dist/authoring.d.ts.map +1 -0
- package/dist/authoring.js +89 -0
- package/dist/authoring.js.map +1 -0
- package/dist/baked.d.ts +3 -0
- package/dist/baked.d.ts.map +1 -0
- package/dist/baked.js +9 -0
- package/dist/baked.js.map +1 -0
- package/dist/batteries.js +339 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +202 -0
- package/dist/cli.js.map +1 -0
- package/dist/color.d.ts +45 -0
- package/dist/color.d.ts.map +1 -0
- package/dist/color.js +130 -0
- package/dist/color.js.map +1 -0
- package/dist/concepts.d.ts +8 -0
- package/dist/concepts.d.ts.map +1 -0
- package/dist/concepts.js +31 -0
- package/dist/concepts.js.map +1 -0
- package/dist/constraints.d.ts +3 -0
- package/dist/constraints.d.ts.map +1 -0
- package/dist/constraints.js +11 -0
- package/dist/constraints.js.map +1 -0
- package/dist/convert.d.ts +59 -0
- package/dist/convert.d.ts.map +1 -0
- package/dist/convert.js +317 -0
- package/dist/convert.js.map +1 -0
- package/dist/coverage.d.ts +20 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +37 -0
- package/dist/coverage.js.map +1 -0
- package/dist/css/components/accordion.d.ts +2 -0
- package/dist/css/components/accordion.d.ts.map +1 -0
- package/dist/css/components/accordion.js +98 -0
- package/dist/css/components/accordion.js.map +1 -0
- package/dist/css/components/alert.d.ts +2 -0
- package/dist/css/components/alert.d.ts.map +1 -0
- package/dist/css/components/alert.js +98 -0
- package/dist/css/components/alert.js.map +1 -0
- package/dist/css/components/app-shell.d.ts +2 -0
- package/dist/css/components/app-shell.d.ts.map +1 -0
- package/dist/css/components/app-shell.js +145 -0
- package/dist/css/components/app-shell.js.map +1 -0
- package/dist/css/components/avatar-group.d.ts +2 -0
- package/dist/css/components/avatar-group.d.ts.map +1 -0
- package/dist/css/components/avatar-group.js +65 -0
- package/dist/css/components/avatar-group.js.map +1 -0
- package/dist/css/components/avatar.d.ts +2 -0
- package/dist/css/components/avatar.d.ts.map +1 -0
- package/dist/css/components/avatar.js +108 -0
- package/dist/css/components/avatar.js.map +1 -0
- package/dist/css/components/badge.d.ts +2 -0
- package/dist/css/components/badge.d.ts.map +1 -0
- package/dist/css/components/badge.js +161 -0
- package/dist/css/components/badge.js.map +1 -0
- package/dist/css/components/bar.d.ts +2 -0
- package/dist/css/components/bar.d.ts.map +1 -0
- package/dist/css/components/bar.js +102 -0
- package/dist/css/components/bar.js.map +1 -0
- package/dist/css/components/base.d.ts +15 -0
- package/dist/css/components/base.d.ts.map +1 -0
- package/dist/css/components/base.js +62 -0
- package/dist/css/components/base.js.map +1 -0
- package/dist/css/components/breadcrumb.d.ts +2 -0
- package/dist/css/components/breadcrumb.d.ts.map +1 -0
- package/dist/css/components/breadcrumb.js +89 -0
- package/dist/css/components/breadcrumb.js.map +1 -0
- package/dist/css/components/button.d.ts +2 -0
- package/dist/css/components/button.d.ts.map +1 -0
- package/dist/css/components/button.js +165 -0
- package/dist/css/components/button.js.map +1 -0
- package/dist/css/components/card-link.d.ts +2 -0
- package/dist/css/components/card-link.d.ts.map +1 -0
- package/dist/css/components/card-link.js +11 -0
- package/dist/css/components/card-link.js.map +1 -0
- package/dist/css/components/card.d.ts +2 -0
- package/dist/css/components/card.d.ts.map +1 -0
- package/dist/css/components/card.js +85 -0
- package/dist/css/components/card.js.map +1 -0
- package/dist/css/components/carousel.d.ts +2 -0
- package/dist/css/components/carousel.d.ts.map +1 -0
- package/dist/css/components/carousel.js +75 -0
- package/dist/css/components/carousel.js.map +1 -0
- package/dist/css/components/checkbox.d.ts +2 -0
- package/dist/css/components/checkbox.d.ts.map +1 -0
- package/dist/css/components/checkbox.js +122 -0
- package/dist/css/components/checkbox.js.map +1 -0
- package/dist/css/components/cluster.d.ts +2 -0
- package/dist/css/components/cluster.d.ts.map +1 -0
- package/dist/css/components/cluster.js +41 -0
- package/dist/css/components/cluster.js.map +1 -0
- package/dist/css/components/code.d.ts +2 -0
- package/dist/css/components/code.d.ts.map +1 -0
- package/dist/css/components/code.js +135 -0
- package/dist/css/components/code.js.map +1 -0
- package/dist/css/components/color-picker.d.ts +2 -0
- package/dist/css/components/color-picker.d.ts.map +1 -0
- package/dist/css/components/color-picker.js +458 -0
- package/dist/css/components/color-picker.js.map +1 -0
- package/dist/css/components/dialog.d.ts +2 -0
- package/dist/css/components/dialog.d.ts.map +1 -0
- package/dist/css/components/dialog.js +103 -0
- package/dist/css/components/dialog.js.map +1 -0
- package/dist/css/components/dock-zone.d.ts +2 -0
- package/dist/css/components/dock-zone.d.ts.map +1 -0
- package/dist/css/components/dock-zone.js +285 -0
- package/dist/css/components/dock-zone.js.map +1 -0
- package/dist/css/components/dock.d.ts +2 -0
- package/dist/css/components/dock.d.ts.map +1 -0
- package/dist/css/components/dock.js +66 -0
- package/dist/css/components/dock.js.map +1 -0
- package/dist/css/components/eyebrow.d.ts +2 -0
- package/dist/css/components/eyebrow.d.ts.map +1 -0
- package/dist/css/components/eyebrow.js +22 -0
- package/dist/css/components/eyebrow.js.map +1 -0
- package/dist/css/components/field.d.ts +2 -0
- package/dist/css/components/field.d.ts.map +1 -0
- package/dist/css/components/field.js +135 -0
- package/dist/css/components/field.js.map +1 -0
- package/dist/css/components/form-group.d.ts +2 -0
- package/dist/css/components/form-group.d.ts.map +1 -0
- package/dist/css/components/form-group.js +66 -0
- package/dist/css/components/form-group.js.map +1 -0
- package/dist/css/components/grid.d.ts +2 -0
- package/dist/css/components/grid.d.ts.map +1 -0
- package/dist/css/components/grid.js +42 -0
- package/dist/css/components/grid.js.map +1 -0
- package/dist/css/components/heading.d.ts +2 -0
- package/dist/css/components/heading.d.ts.map +1 -0
- package/dist/css/components/heading.js +37 -0
- package/dist/css/components/heading.js.map +1 -0
- package/dist/css/components/heatmap.d.ts +2 -0
- package/dist/css/components/heatmap.d.ts.map +1 -0
- package/dist/css/components/heatmap.js +111 -0
- package/dist/css/components/heatmap.js.map +1 -0
- package/dist/css/components/hero.d.ts +2 -0
- package/dist/css/components/hero.d.ts.map +1 -0
- package/dist/css/components/hero.js +30 -0
- package/dist/css/components/hero.js.map +1 -0
- package/dist/css/components/icon.d.ts +2 -0
- package/dist/css/components/icon.d.ts.map +1 -0
- package/dist/css/components/icon.js +24 -0
- package/dist/css/components/icon.js.map +1 -0
- package/dist/css/components/image.d.ts +2 -0
- package/dist/css/components/image.d.ts.map +1 -0
- package/dist/css/components/image.js +118 -0
- package/dist/css/components/image.js.map +1 -0
- package/dist/css/components/kbd.d.ts +2 -0
- package/dist/css/components/kbd.d.ts.map +1 -0
- package/dist/css/components/kbd.js +30 -0
- package/dist/css/components/kbd.js.map +1 -0
- package/dist/css/components/link.d.ts +2 -0
- package/dist/css/components/link.d.ts.map +1 -0
- package/dist/css/components/link.js +61 -0
- package/dist/css/components/link.js.map +1 -0
- package/dist/css/components/menu.d.ts +2 -0
- package/dist/css/components/menu.d.ts.map +1 -0
- package/dist/css/components/menu.js +114 -0
- package/dist/css/components/menu.js.map +1 -0
- package/dist/css/components/number-input.d.ts +2 -0
- package/dist/css/components/number-input.d.ts.map +1 -0
- package/dist/css/components/number-input.js +92 -0
- package/dist/css/components/number-input.js.map +1 -0
- package/dist/css/components/pagination.d.ts +2 -0
- package/dist/css/components/pagination.d.ts.map +1 -0
- package/dist/css/components/pagination.js +105 -0
- package/dist/css/components/pagination.js.map +1 -0
- package/dist/css/components/panel.d.ts +2 -0
- package/dist/css/components/panel.d.ts.map +1 -0
- package/dist/css/components/panel.js +116 -0
- package/dist/css/components/panel.js.map +1 -0
- package/dist/css/components/parallax.d.ts +2 -0
- package/dist/css/components/parallax.d.ts.map +1 -0
- package/dist/css/components/parallax.js +34 -0
- package/dist/css/components/parallax.js.map +1 -0
- package/dist/css/components/pie.d.ts +2 -0
- package/dist/css/components/pie.d.ts.map +1 -0
- package/dist/css/components/pie.js +100 -0
- package/dist/css/components/pie.js.map +1 -0
- package/dist/css/components/progress.d.ts +2 -0
- package/dist/css/components/progress.d.ts.map +1 -0
- package/dist/css/components/progress.js +161 -0
- package/dist/css/components/progress.js.map +1 -0
- package/dist/css/components/radio.d.ts +2 -0
- package/dist/css/components/radio.d.ts.map +1 -0
- package/dist/css/components/radio.js +134 -0
- package/dist/css/components/radio.js.map +1 -0
- package/dist/css/components/section.d.ts +2 -0
- package/dist/css/components/section.d.ts.map +1 -0
- package/dist/css/components/section.js +45 -0
- package/dist/css/components/section.js.map +1 -0
- package/dist/css/components/segmented.d.ts +2 -0
- package/dist/css/components/segmented.d.ts.map +1 -0
- package/dist/css/components/segmented.js +129 -0
- package/dist/css/components/segmented.js.map +1 -0
- package/dist/css/components/select.d.ts +2 -0
- package/dist/css/components/select.d.ts.map +1 -0
- package/dist/css/components/select.js +75 -0
- package/dist/css/components/select.js.map +1 -0
- package/dist/css/components/separator.d.ts +2 -0
- package/dist/css/components/separator.d.ts.map +1 -0
- package/dist/css/components/separator.js +60 -0
- package/dist/css/components/separator.js.map +1 -0
- package/dist/css/components/skeleton.d.ts +2 -0
- package/dist/css/components/skeleton.d.ts.map +1 -0
- package/dist/css/components/skeleton.js +56 -0
- package/dist/css/components/skeleton.js.map +1 -0
- package/dist/css/components/slider.d.ts +2 -0
- package/dist/css/components/slider.d.ts.map +1 -0
- package/dist/css/components/slider.js +131 -0
- package/dist/css/components/slider.js.map +1 -0
- package/dist/css/components/sparkline.d.ts +2 -0
- package/dist/css/components/sparkline.d.ts.map +1 -0
- package/dist/css/components/sparkline.js +78 -0
- package/dist/css/components/sparkline.js.map +1 -0
- package/dist/css/components/spinner.d.ts +2 -0
- package/dist/css/components/spinner.d.ts.map +1 -0
- package/dist/css/components/spinner.js +33 -0
- package/dist/css/components/spinner.js.map +1 -0
- package/dist/css/components/splitter.d.ts +2 -0
- package/dist/css/components/splitter.d.ts.map +1 -0
- package/dist/css/components/splitter.js +90 -0
- package/dist/css/components/splitter.js.map +1 -0
- package/dist/css/components/stack.d.ts +2 -0
- package/dist/css/components/stack.d.ts.map +1 -0
- package/dist/css/components/stack.js +36 -0
- package/dist/css/components/stack.js.map +1 -0
- package/dist/css/components/stat.d.ts +2 -0
- package/dist/css/components/stat.d.ts.map +1 -0
- package/dist/css/components/stat.js +78 -0
- package/dist/css/components/stat.js.map +1 -0
- package/dist/css/components/statusbar.d.ts +2 -0
- package/dist/css/components/statusbar.d.ts.map +1 -0
- package/dist/css/components/statusbar.js +120 -0
- package/dist/css/components/statusbar.js.map +1 -0
- package/dist/css/components/swatch.d.ts +2 -0
- package/dist/css/components/swatch.d.ts.map +1 -0
- package/dist/css/components/swatch.js +102 -0
- package/dist/css/components/swatch.js.map +1 -0
- package/dist/css/components/switch.d.ts +2 -0
- package/dist/css/components/switch.d.ts.map +1 -0
- package/dist/css/components/switch.js +144 -0
- package/dist/css/components/switch.js.map +1 -0
- package/dist/css/components/table.d.ts +2 -0
- package/dist/css/components/table.d.ts.map +1 -0
- package/dist/css/components/table.js +142 -0
- package/dist/css/components/table.js.map +1 -0
- package/dist/css/components/tabs.d.ts +2 -0
- package/dist/css/components/tabs.d.ts.map +1 -0
- package/dist/css/components/tabs.js +158 -0
- package/dist/css/components/tabs.js.map +1 -0
- package/dist/css/components/text.d.ts +2 -0
- package/dist/css/components/text.d.ts.map +1 -0
- package/dist/css/components/text.js +35 -0
- package/dist/css/components/text.js.map +1 -0
- package/dist/css/components/textarea.d.ts +2 -0
- package/dist/css/components/textarea.d.ts.map +1 -0
- package/dist/css/components/textarea.js +57 -0
- package/dist/css/components/textarea.js.map +1 -0
- package/dist/css/components/toast.d.ts +2 -0
- package/dist/css/components/toast.d.ts.map +1 -0
- package/dist/css/components/toast.js +161 -0
- package/dist/css/components/toast.js.map +1 -0
- package/dist/css/components/toc.d.ts +2 -0
- package/dist/css/components/toc.d.ts.map +1 -0
- package/dist/css/components/toc.js +80 -0
- package/dist/css/components/toc.js.map +1 -0
- package/dist/css/components/toolbar.d.ts +2 -0
- package/dist/css/components/toolbar.d.ts.map +1 -0
- package/dist/css/components/toolbar.js +69 -0
- package/dist/css/components/toolbar.js.map +1 -0
- package/dist/css/components/tooltip.d.ts +2 -0
- package/dist/css/components/tooltip.d.ts.map +1 -0
- package/dist/css/components/tooltip.js +151 -0
- package/dist/css/components/tooltip.js.map +1 -0
- package/dist/css/components/tree.d.ts +2 -0
- package/dist/css/components/tree.d.ts.map +1 -0
- package/dist/css/components/tree.js +135 -0
- package/dist/css/components/tree.js.map +1 -0
- package/dist/css/components.d.ts +15 -0
- package/dist/css/components.d.ts.map +1 -0
- package/dist/css/components.js +210 -0
- package/dist/css/components.js.map +1 -0
- package/dist/css/index.d.ts +77 -0
- package/dist/css/index.d.ts.map +1 -0
- package/dist/css/index.js +87 -0
- package/dist/css/index.js.map +1 -0
- package/dist/css/utilities.d.ts +16 -0
- package/dist/css/utilities.d.ts.map +1 -0
- package/dist/css/utilities.js +108 -0
- package/dist/css/utilities.js.map +1 -0
- package/dist/cuti.d.ts +42 -0
- package/dist/cuti.d.ts.map +1 -0
- package/dist/cuti.js +66 -0
- package/dist/cuti.js.map +1 -0
- package/dist/dom.d.ts +11 -0
- package/dist/dom.d.ts.map +1 -0
- package/dist/dom.js +37 -0
- package/dist/dom.js.map +1 -0
- package/dist/elements/accordion.d.ts +34 -0
- package/dist/elements/accordion.d.ts.map +1 -0
- package/dist/elements/accordion.js +158 -0
- package/dist/elements/accordion.js.map +1 -0
- package/dist/elements/alert.d.ts +25 -0
- package/dist/elements/alert.d.ts.map +1 -0
- package/dist/elements/alert.js +82 -0
- package/dist/elements/alert.js.map +1 -0
- package/dist/elements/app-shell.d.ts +35 -0
- package/dist/elements/app-shell.d.ts.map +1 -0
- package/dist/elements/app-shell.js +207 -0
- package/dist/elements/app-shell.js.map +1 -0
- package/dist/elements/avatar-group.d.ts +19 -0
- package/dist/elements/avatar-group.d.ts.map +1 -0
- package/dist/elements/avatar-group.js +58 -0
- package/dist/elements/avatar-group.js.map +1 -0
- package/dist/elements/avatar.d.ts +35 -0
- package/dist/elements/avatar.d.ts.map +1 -0
- package/dist/elements/avatar.js +105 -0
- package/dist/elements/avatar.js.map +1 -0
- package/dist/elements/badge.d.ts +41 -0
- package/dist/elements/badge.d.ts.map +1 -0
- package/dist/elements/badge.js +129 -0
- package/dist/elements/badge.js.map +1 -0
- package/dist/elements/bar.d.ts +35 -0
- package/dist/elements/bar.d.ts.map +1 -0
- package/dist/elements/bar.js +204 -0
- package/dist/elements/bar.js.map +1 -0
- package/dist/elements/base.d.ts +86 -0
- package/dist/elements/base.d.ts.map +1 -0
- package/dist/elements/base.js +157 -0
- package/dist/elements/base.js.map +1 -0
- package/dist/elements/breadcrumb.d.ts +24 -0
- package/dist/elements/breadcrumb.d.ts.map +1 -0
- package/dist/elements/breadcrumb.js +89 -0
- package/dist/elements/breadcrumb.js.map +1 -0
- package/dist/elements/button.d.ts +42 -0
- package/dist/elements/button.d.ts.map +1 -0
- package/dist/elements/button.js +158 -0
- package/dist/elements/button.js.map +1 -0
- package/dist/elements/card-link.d.ts +23 -0
- package/dist/elements/card-link.d.ts.map +1 -0
- package/dist/elements/card-link.js +70 -0
- package/dist/elements/card-link.js.map +1 -0
- package/dist/elements/card.d.ts +34 -0
- package/dist/elements/card.d.ts.map +1 -0
- package/dist/elements/card.js +119 -0
- package/dist/elements/card.js.map +1 -0
- package/dist/elements/carousel.d.ts +50 -0
- package/dist/elements/carousel.d.ts.map +1 -0
- package/dist/elements/carousel.js +265 -0
- package/dist/elements/carousel.js.map +1 -0
- package/dist/elements/checkbox.d.ts +81 -0
- package/dist/elements/checkbox.d.ts.map +1 -0
- package/dist/elements/checkbox.js +293 -0
- package/dist/elements/checkbox.js.map +1 -0
- package/dist/elements/cluster.d.ts +24 -0
- package/dist/elements/cluster.d.ts.map +1 -0
- package/dist/elements/cluster.js +80 -0
- package/dist/elements/cluster.js.map +1 -0
- package/dist/elements/code-highlight.d.ts +56 -0
- package/dist/elements/code-highlight.d.ts.map +1 -0
- package/dist/elements/code-highlight.js +134 -0
- package/dist/elements/code-highlight.js.map +1 -0
- package/dist/elements/code-langs-custom.d.ts +17 -0
- package/dist/elements/code-langs-custom.d.ts.map +1 -0
- package/dist/elements/code-langs-custom.js +26 -0
- package/dist/elements/code-langs-custom.js.map +1 -0
- package/dist/elements/code-langs.generated.d.ts +8 -0
- package/dist/elements/code-langs.generated.d.ts.map +1 -0
- package/dist/elements/code-langs.generated.js +514 -0
- package/dist/elements/code-langs.generated.js.map +1 -0
- package/dist/elements/code.d.ts +75 -0
- package/dist/elements/code.d.ts.map +1 -0
- package/dist/elements/code.js +212 -0
- package/dist/elements/code.js.map +1 -0
- package/dist/elements/color-picker.d.ts +90 -0
- package/dist/elements/color-picker.d.ts.map +1 -0
- package/dist/elements/color-picker.js +738 -0
- package/dist/elements/color-picker.js.map +1 -0
- package/dist/elements/dialog.d.ts +34 -0
- package/dist/elements/dialog.d.ts.map +1 -0
- package/dist/elements/dialog.js +134 -0
- package/dist/elements/dialog.js.map +1 -0
- package/dist/elements/dock-layout.d.ts +63 -0
- package/dist/elements/dock-layout.d.ts.map +1 -0
- package/dist/elements/dock-layout.js +79 -0
- package/dist/elements/dock-layout.js.map +1 -0
- package/dist/elements/dock-model.d.ts +143 -0
- package/dist/elements/dock-model.d.ts.map +1 -0
- package/dist/elements/dock-model.js +259 -0
- package/dist/elements/dock-model.js.map +1 -0
- package/dist/elements/dock-zone.d.ts +146 -0
- package/dist/elements/dock-zone.d.ts.map +1 -0
- package/dist/elements/dock-zone.js +777 -0
- package/dist/elements/dock-zone.js.map +1 -0
- package/dist/elements/dock.d.ts +35 -0
- package/dist/elements/dock.d.ts.map +1 -0
- package/dist/elements/dock.js +106 -0
- package/dist/elements/dock.js.map +1 -0
- package/dist/elements/eyebrow.d.ts +26 -0
- package/dist/elements/eyebrow.d.ts.map +1 -0
- package/dist/elements/eyebrow.js +57 -0
- package/dist/elements/eyebrow.js.map +1 -0
- package/dist/elements/field-options.d.ts +9 -0
- package/dist/elements/field-options.d.ts.map +1 -0
- package/dist/elements/field-options.js +31 -0
- package/dist/elements/field-options.js.map +1 -0
- package/dist/elements/field.d.ts +74 -0
- package/dist/elements/field.d.ts.map +1 -0
- package/dist/elements/field.js +298 -0
- package/dist/elements/field.js.map +1 -0
- package/dist/elements/form-group.d.ts +49 -0
- package/dist/elements/form-group.d.ts.map +1 -0
- package/dist/elements/form-group.js +195 -0
- package/dist/elements/form-group.js.map +1 -0
- package/dist/elements/fragment-host.d.ts +166 -0
- package/dist/elements/fragment-host.d.ts.map +1 -0
- package/dist/elements/fragment-host.js +363 -0
- package/dist/elements/fragment-host.js.map +1 -0
- package/dist/elements/fragment-ssr.d.ts +39 -0
- package/dist/elements/fragment-ssr.d.ts.map +1 -0
- package/dist/elements/fragment-ssr.js +234 -0
- package/dist/elements/fragment-ssr.js.map +1 -0
- package/dist/elements/fragments/accordion/source.generated.d.ts +27 -0
- package/dist/elements/fragments/accordion/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/accordion/source.generated.js +4 -0
- package/dist/elements/fragments/accordion/source.generated.js.map +1 -0
- package/dist/elements/fragments/alert/source.generated.d.ts +30 -0
- package/dist/elements/fragments/alert/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/alert/source.generated.js +4 -0
- package/dist/elements/fragments/alert/source.generated.js.map +1 -0
- package/dist/elements/fragments/app-shell/source.generated.d.ts +25 -0
- package/dist/elements/fragments/app-shell/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/app-shell/source.generated.js +4 -0
- package/dist/elements/fragments/app-shell/source.generated.js.map +1 -0
- package/dist/elements/fragments/avatar/source.generated.d.ts +22 -0
- package/dist/elements/fragments/avatar/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/avatar/source.generated.js +4 -0
- package/dist/elements/fragments/avatar/source.generated.js.map +1 -0
- package/dist/elements/fragments/avatar-group/source.generated.d.ts +25 -0
- package/dist/elements/fragments/avatar-group/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/avatar-group/source.generated.js +4 -0
- package/dist/elements/fragments/avatar-group/source.generated.js.map +1 -0
- package/dist/elements/fragments/badge/source.generated.d.ts +25 -0
- package/dist/elements/fragments/badge/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/badge/source.generated.js +4 -0
- package/dist/elements/fragments/badge/source.generated.js.map +1 -0
- package/dist/elements/fragments/bar/source.generated.d.ts +25 -0
- package/dist/elements/fragments/bar/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/bar/source.generated.js +4 -0
- package/dist/elements/fragments/bar/source.generated.js.map +1 -0
- package/dist/elements/fragments/breadcrumb/source.generated.d.ts +30 -0
- package/dist/elements/fragments/breadcrumb/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/breadcrumb/source.generated.js +4 -0
- package/dist/elements/fragments/breadcrumb/source.generated.js.map +1 -0
- package/dist/elements/fragments/button/source.generated.d.ts +22 -0
- package/dist/elements/fragments/button/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/button/source.generated.js +4 -0
- package/dist/elements/fragments/button/source.generated.js.map +1 -0
- package/dist/elements/fragments/card/source.generated.d.ts +22 -0
- package/dist/elements/fragments/card/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/card/source.generated.js +4 -0
- package/dist/elements/fragments/card/source.generated.js.map +1 -0
- package/dist/elements/fragments/card-link/source.generated.d.ts +22 -0
- package/dist/elements/fragments/card-link/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/card-link/source.generated.js +4 -0
- package/dist/elements/fragments/card-link/source.generated.js.map +1 -0
- package/dist/elements/fragments/checkbox/source.generated.d.ts +27 -0
- package/dist/elements/fragments/checkbox/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/checkbox/source.generated.js +4 -0
- package/dist/elements/fragments/checkbox/source.generated.js.map +1 -0
- package/dist/elements/fragments/cluster/source.generated.d.ts +25 -0
- package/dist/elements/fragments/cluster/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/cluster/source.generated.js +4 -0
- package/dist/elements/fragments/cluster/source.generated.js.map +1 -0
- package/dist/elements/fragments/code/source.generated.d.ts +30 -0
- package/dist/elements/fragments/code/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/code/source.generated.js +4 -0
- package/dist/elements/fragments/code/source.generated.js.map +1 -0
- package/dist/elements/fragments/color-picker/source.generated.d.ts +25 -0
- package/dist/elements/fragments/color-picker/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/color-picker/source.generated.js +4 -0
- package/dist/elements/fragments/color-picker/source.generated.js.map +1 -0
- package/dist/elements/fragments/component-host.json +801 -0
- package/dist/elements/fragments/dialog/source.generated.d.ts +30 -0
- package/dist/elements/fragments/dialog/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/dialog/source.generated.js +4 -0
- package/dist/elements/fragments/dialog/source.generated.js.map +1 -0
- package/dist/elements/fragments/dock/source.generated.d.ts +25 -0
- package/dist/elements/fragments/dock/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/dock/source.generated.js +4 -0
- package/dist/elements/fragments/dock/source.generated.js.map +1 -0
- package/dist/elements/fragments/eyebrow/source.generated.d.ts +22 -0
- package/dist/elements/fragments/eyebrow/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/eyebrow/source.generated.js +4 -0
- package/dist/elements/fragments/eyebrow/source.generated.js.map +1 -0
- package/dist/elements/fragments/field/source.generated.d.ts +27 -0
- package/dist/elements/fragments/field/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/field/source.generated.js +4 -0
- package/dist/elements/fragments/field/source.generated.js.map +1 -0
- package/dist/elements/fragments/form-group/source.generated.d.ts +22 -0
- package/dist/elements/fragments/form-group/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/form-group/source.generated.js +4 -0
- package/dist/elements/fragments/form-group/source.generated.js.map +1 -0
- package/dist/elements/fragments/grid/source.generated.d.ts +25 -0
- package/dist/elements/fragments/grid/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/grid/source.generated.js +4 -0
- package/dist/elements/fragments/grid/source.generated.js.map +1 -0
- package/dist/elements/fragments/heading/source.generated.d.ts +22 -0
- package/dist/elements/fragments/heading/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/heading/source.generated.js +4 -0
- package/dist/elements/fragments/heading/source.generated.js.map +1 -0
- package/dist/elements/fragments/heatmap/source.generated.d.ts +25 -0
- package/dist/elements/fragments/heatmap/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/heatmap/source.generated.js +4 -0
- package/dist/elements/fragments/heatmap/source.generated.js.map +1 -0
- package/dist/elements/fragments/icon/source.generated.d.ts +25 -0
- package/dist/elements/fragments/icon/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/icon/source.generated.js +4 -0
- package/dist/elements/fragments/icon/source.generated.js.map +1 -0
- package/dist/elements/fragments/image/source.generated.d.ts +25 -0
- package/dist/elements/fragments/image/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/image/source.generated.js +4 -0
- package/dist/elements/fragments/image/source.generated.js.map +1 -0
- package/dist/elements/fragments/kbd/source.generated.d.ts +25 -0
- package/dist/elements/fragments/kbd/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/kbd/source.generated.js +4 -0
- package/dist/elements/fragments/kbd/source.generated.js.map +1 -0
- package/dist/elements/fragments/link/source.generated.d.ts +22 -0
- package/dist/elements/fragments/link/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/link/source.generated.js +4 -0
- package/dist/elements/fragments/link/source.generated.js.map +1 -0
- package/dist/elements/fragments/menu/source.generated.d.ts +30 -0
- package/dist/elements/fragments/menu/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/menu/source.generated.js +4 -0
- package/dist/elements/fragments/menu/source.generated.js.map +1 -0
- package/dist/elements/fragments/number-input/source.generated.d.ts +30 -0
- package/dist/elements/fragments/number-input/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/number-input/source.generated.js +4 -0
- package/dist/elements/fragments/number-input/source.generated.js.map +1 -0
- package/dist/elements/fragments/pagination/source.generated.d.ts +25 -0
- package/dist/elements/fragments/pagination/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/pagination/source.generated.js +4 -0
- package/dist/elements/fragments/pagination/source.generated.js.map +1 -0
- package/dist/elements/fragments/panel/source.generated.d.ts +30 -0
- package/dist/elements/fragments/panel/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/panel/source.generated.js +4 -0
- package/dist/elements/fragments/panel/source.generated.js.map +1 -0
- package/dist/elements/fragments/pie/source.generated.d.ts +25 -0
- package/dist/elements/fragments/pie/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/pie/source.generated.js +4 -0
- package/dist/elements/fragments/pie/source.generated.js.map +1 -0
- package/dist/elements/fragments/progress/source.generated.d.ts +25 -0
- package/dist/elements/fragments/progress/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/progress/source.generated.js +4 -0
- package/dist/elements/fragments/progress/source.generated.js.map +1 -0
- package/dist/elements/fragments/radio/source.generated.d.ts +30 -0
- package/dist/elements/fragments/radio/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/radio/source.generated.js +4 -0
- package/dist/elements/fragments/radio/source.generated.js.map +1 -0
- package/dist/elements/fragments/section/source.generated.d.ts +22 -0
- package/dist/elements/fragments/section/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/section/source.generated.js +4 -0
- package/dist/elements/fragments/section/source.generated.js.map +1 -0
- package/dist/elements/fragments/segmented/source.generated.d.ts +30 -0
- package/dist/elements/fragments/segmented/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/segmented/source.generated.js +4 -0
- package/dist/elements/fragments/segmented/source.generated.js.map +1 -0
- package/dist/elements/fragments/select/source.generated.d.ts +22 -0
- package/dist/elements/fragments/select/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/select/source.generated.js +4 -0
- package/dist/elements/fragments/select/source.generated.js.map +1 -0
- package/dist/elements/fragments/selector-escape.d.ts +8 -0
- package/dist/elements/fragments/selector-escape.d.ts.map +1 -0
- package/dist/elements/fragments/selector-escape.js +14 -0
- package/dist/elements/fragments/selector-escape.js.map +1 -0
- package/dist/elements/fragments/separator/source.generated.d.ts +22 -0
- package/dist/elements/fragments/separator/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/separator/source.generated.js +4 -0
- package/dist/elements/fragments/separator/source.generated.js.map +1 -0
- package/dist/elements/fragments/skeleton/source.generated.d.ts +25 -0
- package/dist/elements/fragments/skeleton/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/skeleton/source.generated.js +4 -0
- package/dist/elements/fragments/skeleton/source.generated.js.map +1 -0
- package/dist/elements/fragments/slider/source.generated.d.ts +30 -0
- package/dist/elements/fragments/slider/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/slider/source.generated.js +4 -0
- package/dist/elements/fragments/slider/source.generated.js.map +1 -0
- package/dist/elements/fragments/sparkline/source.generated.d.ts +25 -0
- package/dist/elements/fragments/sparkline/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/sparkline/source.generated.js +4 -0
- package/dist/elements/fragments/sparkline/source.generated.js.map +1 -0
- package/dist/elements/fragments/spinner/source.generated.d.ts +25 -0
- package/dist/elements/fragments/spinner/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/spinner/source.generated.js +4 -0
- package/dist/elements/fragments/spinner/source.generated.js.map +1 -0
- package/dist/elements/fragments/splitter/source.generated.d.ts +30 -0
- package/dist/elements/fragments/splitter/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/splitter/source.generated.js +4 -0
- package/dist/elements/fragments/splitter/source.generated.js.map +1 -0
- package/dist/elements/fragments/stack/source.generated.d.ts +25 -0
- package/dist/elements/fragments/stack/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/stack/source.generated.js +4 -0
- package/dist/elements/fragments/stack/source.generated.js.map +1 -0
- package/dist/elements/fragments/stat/source.generated.d.ts +25 -0
- package/dist/elements/fragments/stat/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/stat/source.generated.js +4 -0
- package/dist/elements/fragments/stat/source.generated.js.map +1 -0
- package/dist/elements/fragments/statusbar/source.generated.d.ts +25 -0
- package/dist/elements/fragments/statusbar/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/statusbar/source.generated.js +4 -0
- package/dist/elements/fragments/statusbar/source.generated.js.map +1 -0
- package/dist/elements/fragments/swatch/source.generated.d.ts +30 -0
- package/dist/elements/fragments/swatch/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/swatch/source.generated.js +4 -0
- package/dist/elements/fragments/swatch/source.generated.js.map +1 -0
- package/dist/elements/fragments/switch/source.generated.d.ts +27 -0
- package/dist/elements/fragments/switch/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/switch/source.generated.js +4 -0
- package/dist/elements/fragments/switch/source.generated.js.map +1 -0
- package/dist/elements/fragments/tabs/source.generated.d.ts +27 -0
- package/dist/elements/fragments/tabs/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/tabs/source.generated.js +4 -0
- package/dist/elements/fragments/tabs/source.generated.js.map +1 -0
- package/dist/elements/fragments/text/source.generated.d.ts +25 -0
- package/dist/elements/fragments/text/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/text/source.generated.js +4 -0
- package/dist/elements/fragments/text/source.generated.js.map +1 -0
- package/dist/elements/fragments/textarea/source.generated.d.ts +30 -0
- package/dist/elements/fragments/textarea/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/textarea/source.generated.js +4 -0
- package/dist/elements/fragments/textarea/source.generated.js.map +1 -0
- package/dist/elements/fragments/toast/source.generated.d.ts +30 -0
- package/dist/elements/fragments/toast/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/toast/source.generated.js +4 -0
- package/dist/elements/fragments/toast/source.generated.js.map +1 -0
- package/dist/elements/fragments/toc/source.generated.d.ts +25 -0
- package/dist/elements/fragments/toc/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/toc/source.generated.js +4 -0
- package/dist/elements/fragments/toc/source.generated.js.map +1 -0
- package/dist/elements/fragments/toolbar/source.generated.d.ts +25 -0
- package/dist/elements/fragments/toolbar/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/toolbar/source.generated.js +4 -0
- package/dist/elements/fragments/toolbar/source.generated.js.map +1 -0
- package/dist/elements/fragments/tooltip/source.generated.d.ts +25 -0
- package/dist/elements/fragments/tooltip/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/tooltip/source.generated.js +4 -0
- package/dist/elements/fragments/tooltip/source.generated.js.map +1 -0
- package/dist/elements/fragments/tree/source.generated.d.ts +30 -0
- package/dist/elements/fragments/tree/source.generated.d.ts.map +1 -0
- package/dist/elements/fragments/tree/source.generated.js +4 -0
- package/dist/elements/fragments/tree/source.generated.js.map +1 -0
- package/dist/elements/grid.d.ts +24 -0
- package/dist/elements/grid.d.ts.map +1 -0
- package/dist/elements/grid.js +94 -0
- package/dist/elements/grid.js.map +1 -0
- package/dist/elements/heading.d.ts +21 -0
- package/dist/elements/heading.d.ts.map +1 -0
- package/dist/elements/heading.js +62 -0
- package/dist/elements/heading.js.map +1 -0
- package/dist/elements/heatmap.d.ts +54 -0
- package/dist/elements/heatmap.d.ts.map +1 -0
- package/dist/elements/heatmap.js +292 -0
- package/dist/elements/heatmap.js.map +1 -0
- package/dist/elements/hero.d.ts +16 -0
- package/dist/elements/hero.d.ts.map +1 -0
- package/dist/elements/hero.js +24 -0
- package/dist/elements/hero.js.map +1 -0
- package/dist/elements/host-controls.d.ts +32 -0
- package/dist/elements/host-controls.d.ts.map +1 -0
- package/dist/elements/host-controls.js +53 -0
- package/dist/elements/host-controls.js.map +1 -0
- package/dist/elements/icon.d.ts +33 -0
- package/dist/elements/icon.d.ts.map +1 -0
- package/dist/elements/icon.js +110 -0
- package/dist/elements/icon.js.map +1 -0
- package/dist/elements/image.d.ts +37 -0
- package/dist/elements/image.d.ts.map +1 -0
- package/dist/elements/image.js +190 -0
- package/dist/elements/image.js.map +1 -0
- package/dist/elements/index.d.ts +134 -0
- package/dist/elements/index.d.ts.map +1 -0
- package/dist/elements/index.js +127 -0
- package/dist/elements/index.js.map +1 -0
- package/dist/elements/kbd.d.ts +16 -0
- package/dist/elements/kbd.d.ts.map +1 -0
- package/dist/elements/kbd.js +47 -0
- package/dist/elements/kbd.js.map +1 -0
- package/dist/elements/link.d.ts +27 -0
- package/dist/elements/link.d.ts.map +1 -0
- package/dist/elements/link.js +81 -0
- package/dist/elements/link.js.map +1 -0
- package/dist/elements/live-register.d.ts +11 -0
- package/dist/elements/live-register.d.ts.map +1 -0
- package/dist/elements/live-register.js +25 -0
- package/dist/elements/live-register.js.map +1 -0
- package/dist/elements/menu.d.ts +38 -0
- package/dist/elements/menu.d.ts.map +1 -0
- package/dist/elements/menu.js +210 -0
- package/dist/elements/menu.js.map +1 -0
- package/dist/elements/native-input-attrs.d.ts +8 -0
- package/dist/elements/native-input-attrs.d.ts.map +1 -0
- package/dist/elements/native-input-attrs.js +23 -0
- package/dist/elements/native-input-attrs.js.map +1 -0
- package/dist/elements/number-input.d.ts +49 -0
- package/dist/elements/number-input.d.ts.map +1 -0
- package/dist/elements/number-input.js +224 -0
- package/dist/elements/number-input.js.map +1 -0
- package/dist/elements/overlay-position.d.ts +87 -0
- package/dist/elements/overlay-position.d.ts.map +1 -0
- package/dist/elements/overlay-position.js +124 -0
- package/dist/elements/overlay-position.js.map +1 -0
- package/dist/elements/pagination.d.ts +38 -0
- package/dist/elements/pagination.d.ts.map +1 -0
- package/dist/elements/pagination.js +124 -0
- package/dist/elements/pagination.js.map +1 -0
- package/dist/elements/panel.d.ts +36 -0
- package/dist/elements/panel.d.ts.map +1 -0
- package/dist/elements/panel.js +109 -0
- package/dist/elements/panel.js.map +1 -0
- package/dist/elements/parallax.d.ts +32 -0
- package/dist/elements/parallax.d.ts.map +1 -0
- package/dist/elements/parallax.js +167 -0
- package/dist/elements/parallax.js.map +1 -0
- package/dist/elements/pie.d.ts +26 -0
- package/dist/elements/pie.d.ts.map +1 -0
- package/dist/elements/pie.js +146 -0
- package/dist/elements/pie.js.map +1 -0
- package/dist/elements/progress.d.ts +62 -0
- package/dist/elements/progress.d.ts.map +1 -0
- package/dist/elements/progress.js +187 -0
- package/dist/elements/progress.js.map +1 -0
- package/dist/elements/radio.d.ts +67 -0
- package/dist/elements/radio.d.ts.map +1 -0
- package/dist/elements/radio.js +268 -0
- package/dist/elements/radio.js.map +1 -0
- package/dist/elements/section.d.ts +33 -0
- package/dist/elements/section.d.ts.map +1 -0
- package/dist/elements/section.js +83 -0
- package/dist/elements/section.js.map +1 -0
- package/dist/elements/segmented.d.ts +61 -0
- package/dist/elements/segmented.d.ts.map +1 -0
- package/dist/elements/segmented.js +182 -0
- package/dist/elements/segmented.js.map +1 -0
- package/dist/elements/select.d.ts +35 -0
- package/dist/elements/select.d.ts.map +1 -0
- package/dist/elements/select.js +144 -0
- package/dist/elements/select.js.map +1 -0
- package/dist/elements/separator.d.ts +25 -0
- package/dist/elements/separator.d.ts.map +1 -0
- package/dist/elements/separator.js +62 -0
- package/dist/elements/separator.js.map +1 -0
- package/dist/elements/skeleton.d.ts +18 -0
- package/dist/elements/skeleton.d.ts.map +1 -0
- package/dist/elements/skeleton.js +44 -0
- package/dist/elements/skeleton.js.map +1 -0
- package/dist/elements/slider.d.ts +65 -0
- package/dist/elements/slider.d.ts.map +1 -0
- package/dist/elements/slider.js +295 -0
- package/dist/elements/slider.js.map +1 -0
- package/dist/elements/sparkline.d.ts +29 -0
- package/dist/elements/sparkline.d.ts.map +1 -0
- package/dist/elements/sparkline.js +178 -0
- package/dist/elements/sparkline.js.map +1 -0
- package/dist/elements/spinner.d.ts +17 -0
- package/dist/elements/spinner.d.ts.map +1 -0
- package/dist/elements/spinner.js +51 -0
- package/dist/elements/spinner.js.map +1 -0
- package/dist/elements/splitter.d.ts +50 -0
- package/dist/elements/splitter.d.ts.map +1 -0
- package/dist/elements/splitter.js +240 -0
- package/dist/elements/splitter.js.map +1 -0
- package/dist/elements/stack.d.ts +22 -0
- package/dist/elements/stack.d.ts.map +1 -0
- package/dist/elements/stack.js +73 -0
- package/dist/elements/stack.js.map +1 -0
- package/dist/elements/stat.d.ts +39 -0
- package/dist/elements/stat.d.ts.map +1 -0
- package/dist/elements/stat.js +99 -0
- package/dist/elements/stat.js.map +1 -0
- package/dist/elements/statusbar.d.ts +61 -0
- package/dist/elements/statusbar.d.ts.map +1 -0
- package/dist/elements/statusbar.js +309 -0
- package/dist/elements/statusbar.js.map +1 -0
- package/dist/elements/swatch.d.ts +40 -0
- package/dist/elements/swatch.d.ts.map +1 -0
- package/dist/elements/swatch.js +144 -0
- package/dist/elements/swatch.js.map +1 -0
- package/dist/elements/switch.d.ts +40 -0
- package/dist/elements/switch.d.ts.map +1 -0
- package/dist/elements/switch.js +141 -0
- package/dist/elements/switch.js.map +1 -0
- package/dist/elements/table.d.ts +35 -0
- package/dist/elements/table.d.ts.map +1 -0
- package/dist/elements/table.js +176 -0
- package/dist/elements/table.js.map +1 -0
- package/dist/elements/tabs.d.ts +50 -0
- package/dist/elements/tabs.d.ts.map +1 -0
- package/dist/elements/tabs.js +194 -0
- package/dist/elements/tabs.js.map +1 -0
- package/dist/elements/text.d.ts +32 -0
- package/dist/elements/text.d.ts.map +1 -0
- package/dist/elements/text.js +81 -0
- package/dist/elements/text.js.map +1 -0
- package/dist/elements/textarea.d.ts +46 -0
- package/dist/elements/textarea.d.ts.map +1 -0
- package/dist/elements/textarea.js +194 -0
- package/dist/elements/textarea.js.map +1 -0
- package/dist/elements/toast.d.ts +78 -0
- package/dist/elements/toast.d.ts.map +1 -0
- package/dist/elements/toast.js +207 -0
- package/dist/elements/toast.js.map +1 -0
- package/dist/elements/toc.d.ts +32 -0
- package/dist/elements/toc.d.ts.map +1 -0
- package/dist/elements/toc.js +122 -0
- package/dist/elements/toc.js.map +1 -0
- package/dist/elements/toolbar.d.ts +27 -0
- package/dist/elements/toolbar.d.ts.map +1 -0
- package/dist/elements/toolbar.js +79 -0
- package/dist/elements/toolbar.js.map +1 -0
- package/dist/elements/tooltip.d.ts +63 -0
- package/dist/elements/tooltip.d.ts.map +1 -0
- package/dist/elements/tooltip.js +227 -0
- package/dist/elements/tooltip.js.map +1 -0
- package/dist/elements/tree.d.ts +33 -0
- package/dist/elements/tree.d.ts.map +1 -0
- package/dist/elements/tree.js +180 -0
- package/dist/elements/tree.js.map +1 -0
- package/dist/emit/css.d.ts +3 -0
- package/dist/emit/css.d.ts.map +1 -0
- package/dist/emit/css.js +13 -0
- package/dist/emit/css.js.map +1 -0
- package/dist/emit/index.d.ts +10 -0
- package/dist/emit/index.d.ts.map +1 -0
- package/dist/emit/index.js +25 -0
- package/dist/emit/index.js.map +1 -0
- package/dist/emit/json.d.ts +3 -0
- package/dist/emit/json.d.ts.map +1 -0
- package/dist/emit/json.js +8 -0
- package/dist/emit/json.js.map +1 -0
- package/dist/emit/monaco.d.ts +9 -0
- package/dist/emit/monaco.d.ts.map +1 -0
- package/dist/emit/monaco.js +80 -0
- package/dist/emit/monaco.js.map +1 -0
- package/dist/emit/prism.d.ts +9 -0
- package/dist/emit/prism.d.ts.map +1 -0
- package/dist/emit/prism.js +37 -0
- package/dist/emit/prism.js.map +1 -0
- package/dist/gauntlet.d.ts +27 -0
- package/dist/gauntlet.d.ts.map +1 -0
- package/dist/gauntlet.js +199 -0
- package/dist/gauntlet.js.map +1 -0
- package/dist/graph.d.ts +21 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +66 -0
- package/dist/graph.js.map +1 -0
- package/dist/host/algorithms-bundle.generated.d.ts +5 -0
- package/dist/host/algorithms-bundle.generated.d.ts.map +1 -0
- package/dist/host/algorithms-bundle.generated.js +3 -0
- package/dist/host/algorithms-bundle.generated.js.map +1 -0
- package/dist/host/authoring-prelude-entry.d.ts +2 -0
- package/dist/host/authoring-prelude-entry.d.ts.map +1 -0
- package/dist/host/authoring-prelude-entry.js +17 -0
- package/dist/host/authoring-prelude-entry.js.map +1 -0
- package/dist/host/authoring-prelude.generated.d.ts +2 -0
- package/dist/host/authoring-prelude.generated.d.ts.map +1 -0
- package/dist/host/authoring-prelude.generated.js +3 -0
- package/dist/host/authoring-prelude.generated.js.map +1 -0
- package/dist/host/bundle.d.ts +26 -0
- package/dist/host/bundle.d.ts.map +1 -0
- package/dist/host/bundle.js +38 -0
- package/dist/host/bundle.js.map +1 -0
- package/dist/host/index.d.ts +29 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +148 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/registry.d.ts +24 -0
- package/dist/host/registry.d.ts.map +1 -0
- package/dist/host/registry.js +83 -0
- package/dist/host/registry.js.map +1 -0
- package/dist/icon-builder.d.ts +155 -0
- package/dist/icon-builder.d.ts.map +1 -0
- package/dist/icon-builder.js +486 -0
- package/dist/icon-builder.js.map +1 -0
- package/dist/icons.d.ts +45 -0
- package/dist/icons.d.ts.map +1 -0
- package/dist/icons.js +100 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest/accordion.manifest.d.ts +3 -0
- package/dist/manifest/accordion.manifest.d.ts.map +1 -0
- package/dist/manifest/accordion.manifest.js +190 -0
- package/dist/manifest/accordion.manifest.js.map +1 -0
- package/dist/manifest/alert.manifest.d.ts +3 -0
- package/dist/manifest/alert.manifest.d.ts.map +1 -0
- package/dist/manifest/alert.manifest.js +251 -0
- package/dist/manifest/alert.manifest.js.map +1 -0
- package/dist/manifest/app-shell.manifest.d.ts +3 -0
- package/dist/manifest/app-shell.manifest.d.ts.map +1 -0
- package/dist/manifest/app-shell.manifest.js +287 -0
- package/dist/manifest/app-shell.manifest.js.map +1 -0
- package/dist/manifest/avatar-group.manifest.d.ts +3 -0
- package/dist/manifest/avatar-group.manifest.d.ts.map +1 -0
- package/dist/manifest/avatar-group.manifest.js +180 -0
- package/dist/manifest/avatar-group.manifest.js.map +1 -0
- package/dist/manifest/avatar.manifest.d.ts +3 -0
- package/dist/manifest/avatar.manifest.d.ts.map +1 -0
- package/dist/manifest/avatar.manifest.js +249 -0
- package/dist/manifest/avatar.manifest.js.map +1 -0
- package/dist/manifest/badge.manifest.d.ts +3 -0
- package/dist/manifest/badge.manifest.d.ts.map +1 -0
- package/dist/manifest/badge.manifest.js +284 -0
- package/dist/manifest/badge.manifest.js.map +1 -0
- package/dist/manifest/bar.manifest.d.ts +3 -0
- package/dist/manifest/bar.manifest.d.ts.map +1 -0
- package/dist/manifest/bar.manifest.js +342 -0
- package/dist/manifest/bar.manifest.js.map +1 -0
- package/dist/manifest/breadcrumb.manifest.d.ts +3 -0
- package/dist/manifest/breadcrumb.manifest.d.ts.map +1 -0
- package/dist/manifest/breadcrumb.manifest.js +280 -0
- package/dist/manifest/breadcrumb.manifest.js.map +1 -0
- package/dist/manifest/button.manifest.d.ts +3 -0
- package/dist/manifest/button.manifest.d.ts.map +1 -0
- package/dist/manifest/button.manifest.js +377 -0
- package/dist/manifest/button.manifest.js.map +1 -0
- package/dist/manifest/card-link.manifest.d.ts +3 -0
- package/dist/manifest/card-link.manifest.d.ts.map +1 -0
- package/dist/manifest/card-link.manifest.js +133 -0
- package/dist/manifest/card-link.manifest.js.map +1 -0
- package/dist/manifest/card.manifest.d.ts +3 -0
- package/dist/manifest/card.manifest.d.ts.map +1 -0
- package/dist/manifest/card.manifest.js +280 -0
- package/dist/manifest/card.manifest.js.map +1 -0
- package/dist/manifest/carousel.manifest.d.ts +3 -0
- package/dist/manifest/carousel.manifest.d.ts.map +1 -0
- package/dist/manifest/carousel.manifest.js +170 -0
- package/dist/manifest/carousel.manifest.js.map +1 -0
- package/dist/manifest/checkbox.manifest.d.ts +3 -0
- package/dist/manifest/checkbox.manifest.d.ts.map +1 -0
- package/dist/manifest/checkbox.manifest.js +249 -0
- package/dist/manifest/checkbox.manifest.js.map +1 -0
- package/dist/manifest/cluster.manifest.d.ts +3 -0
- package/dist/manifest/cluster.manifest.d.ts.map +1 -0
- package/dist/manifest/cluster.manifest.js +132 -0
- package/dist/manifest/cluster.manifest.js.map +1 -0
- package/dist/manifest/code.manifest.d.ts +3 -0
- package/dist/manifest/code.manifest.d.ts.map +1 -0
- package/dist/manifest/code.manifest.js +269 -0
- package/dist/manifest/code.manifest.js.map +1 -0
- package/dist/manifest/color-picker.manifest.d.ts +3 -0
- package/dist/manifest/color-picker.manifest.d.ts.map +1 -0
- package/dist/manifest/color-picker.manifest.js +379 -0
- package/dist/manifest/color-picker.manifest.js.map +1 -0
- package/dist/manifest/dialog.manifest.d.ts +3 -0
- package/dist/manifest/dialog.manifest.d.ts.map +1 -0
- package/dist/manifest/dialog.manifest.js +267 -0
- package/dist/manifest/dialog.manifest.js.map +1 -0
- package/dist/manifest/dock-zone.manifest.d.ts +3 -0
- package/dist/manifest/dock-zone.manifest.d.ts.map +1 -0
- package/dist/manifest/dock-zone.manifest.js +277 -0
- package/dist/manifest/dock-zone.manifest.js.map +1 -0
- package/dist/manifest/dock.manifest.d.ts +3 -0
- package/dist/manifest/dock.manifest.d.ts.map +1 -0
- package/dist/manifest/dock.manifest.js +239 -0
- package/dist/manifest/dock.manifest.js.map +1 -0
- package/dist/manifest/eyebrow.manifest.d.ts +3 -0
- package/dist/manifest/eyebrow.manifest.d.ts.map +1 -0
- package/dist/manifest/eyebrow.manifest.js +105 -0
- package/dist/manifest/eyebrow.manifest.js.map +1 -0
- package/dist/manifest/field.manifest.d.ts +3 -0
- package/dist/manifest/field.manifest.d.ts.map +1 -0
- package/dist/manifest/field.manifest.js +380 -0
- package/dist/manifest/field.manifest.js.map +1 -0
- package/dist/manifest/form-group.manifest.d.ts +3 -0
- package/dist/manifest/form-group.manifest.d.ts.map +1 -0
- package/dist/manifest/form-group.manifest.js +218 -0
- package/dist/manifest/form-group.manifest.js.map +1 -0
- package/dist/manifest/grid.manifest.d.ts +3 -0
- package/dist/manifest/grid.manifest.d.ts.map +1 -0
- package/dist/manifest/grid.manifest.js +141 -0
- package/dist/manifest/grid.manifest.js.map +1 -0
- package/dist/manifest/heading.manifest.d.ts +3 -0
- package/dist/manifest/heading.manifest.d.ts.map +1 -0
- package/dist/manifest/heading.manifest.js +166 -0
- package/dist/manifest/heading.manifest.js.map +1 -0
- package/dist/manifest/heatmap.manifest.d.ts +3 -0
- package/dist/manifest/heatmap.manifest.d.ts.map +1 -0
- package/dist/manifest/heatmap.manifest.js +423 -0
- package/dist/manifest/heatmap.manifest.js.map +1 -0
- package/dist/manifest/hero.manifest.d.ts +3 -0
- package/dist/manifest/hero.manifest.d.ts.map +1 -0
- package/dist/manifest/hero.manifest.js +142 -0
- package/dist/manifest/hero.manifest.js.map +1 -0
- package/dist/manifest/icon.manifest.d.ts +3 -0
- package/dist/manifest/icon.manifest.d.ts.map +1 -0
- package/dist/manifest/icon.manifest.js +177 -0
- package/dist/manifest/icon.manifest.js.map +1 -0
- package/dist/manifest/image.manifest.d.ts +3 -0
- package/dist/manifest/image.manifest.d.ts.map +1 -0
- package/dist/manifest/image.manifest.js +186 -0
- package/dist/manifest/image.manifest.js.map +1 -0
- package/dist/manifest/index.d.ts +4 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +4 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/manifest/kbd.manifest.d.ts +3 -0
- package/dist/manifest/kbd.manifest.d.ts.map +1 -0
- package/dist/manifest/kbd.manifest.js +119 -0
- package/dist/manifest/kbd.manifest.js.map +1 -0
- package/dist/manifest/link.manifest.d.ts +3 -0
- package/dist/manifest/link.manifest.d.ts.map +1 -0
- package/dist/manifest/link.manifest.js +183 -0
- package/dist/manifest/link.manifest.js.map +1 -0
- package/dist/manifest/lint.d.ts +40 -0
- package/dist/manifest/lint.d.ts.map +1 -0
- package/dist/manifest/lint.js +90 -0
- package/dist/manifest/lint.js.map +1 -0
- package/dist/manifest/menu.manifest.d.ts +3 -0
- package/dist/manifest/menu.manifest.d.ts.map +1 -0
- package/dist/manifest/menu.manifest.js +245 -0
- package/dist/manifest/menu.manifest.js.map +1 -0
- package/dist/manifest/number-input.manifest.d.ts +3 -0
- package/dist/manifest/number-input.manifest.d.ts.map +1 -0
- package/dist/manifest/number-input.manifest.js +193 -0
- package/dist/manifest/number-input.manifest.js.map +1 -0
- package/dist/manifest/pagination.manifest.d.ts +3 -0
- package/dist/manifest/pagination.manifest.d.ts.map +1 -0
- package/dist/manifest/pagination.manifest.js +213 -0
- package/dist/manifest/pagination.manifest.js.map +1 -0
- package/dist/manifest/panel.manifest.d.ts +3 -0
- package/dist/manifest/panel.manifest.d.ts.map +1 -0
- package/dist/manifest/panel.manifest.js +246 -0
- package/dist/manifest/panel.manifest.js.map +1 -0
- package/dist/manifest/parallax.manifest.d.ts +3 -0
- package/dist/manifest/parallax.manifest.d.ts.map +1 -0
- package/dist/manifest/parallax.manifest.js +124 -0
- package/dist/manifest/parallax.manifest.js.map +1 -0
- package/dist/manifest/pie.manifest.d.ts +3 -0
- package/dist/manifest/pie.manifest.d.ts.map +1 -0
- package/dist/manifest/pie.manifest.js +284 -0
- package/dist/manifest/pie.manifest.js.map +1 -0
- package/dist/manifest/progress.manifest.d.ts +3 -0
- package/dist/manifest/progress.manifest.d.ts.map +1 -0
- package/dist/manifest/progress.manifest.js +288 -0
- package/dist/manifest/progress.manifest.js.map +1 -0
- package/dist/manifest/radio.manifest.d.ts +3 -0
- package/dist/manifest/radio.manifest.d.ts.map +1 -0
- package/dist/manifest/radio.manifest.js +296 -0
- package/dist/manifest/radio.manifest.js.map +1 -0
- package/dist/manifest/registry.d.ts +20 -0
- package/dist/manifest/registry.d.ts.map +1 -0
- package/dist/manifest/registry.js +146 -0
- package/dist/manifest/registry.js.map +1 -0
- package/dist/manifest/section.manifest.d.ts +3 -0
- package/dist/manifest/section.manifest.d.ts.map +1 -0
- package/dist/manifest/section.manifest.js +173 -0
- package/dist/manifest/section.manifest.js.map +1 -0
- package/dist/manifest/segmented.manifest.d.ts +3 -0
- package/dist/manifest/segmented.manifest.d.ts.map +1 -0
- package/dist/manifest/segmented.manifest.js +261 -0
- package/dist/manifest/segmented.manifest.js.map +1 -0
- package/dist/manifest/select.manifest.d.ts +3 -0
- package/dist/manifest/select.manifest.d.ts.map +1 -0
- package/dist/manifest/select.manifest.js +262 -0
- package/dist/manifest/select.manifest.js.map +1 -0
- package/dist/manifest/separator.manifest.d.ts +3 -0
- package/dist/manifest/separator.manifest.d.ts.map +1 -0
- package/dist/manifest/separator.manifest.js +164 -0
- package/dist/manifest/separator.manifest.js.map +1 -0
- package/dist/manifest/skeleton.manifest.d.ts +3 -0
- package/dist/manifest/skeleton.manifest.d.ts.map +1 -0
- package/dist/manifest/skeleton.manifest.js +141 -0
- package/dist/manifest/skeleton.manifest.js.map +1 -0
- package/dist/manifest/slider.manifest.d.ts +3 -0
- package/dist/manifest/slider.manifest.d.ts.map +1 -0
- package/dist/manifest/slider.manifest.js +294 -0
- package/dist/manifest/slider.manifest.js.map +1 -0
- package/dist/manifest/sparkline.manifest.d.ts +3 -0
- package/dist/manifest/sparkline.manifest.d.ts.map +1 -0
- package/dist/manifest/sparkline.manifest.js +227 -0
- package/dist/manifest/sparkline.manifest.js.map +1 -0
- package/dist/manifest/spinner.manifest.d.ts +3 -0
- package/dist/manifest/spinner.manifest.d.ts.map +1 -0
- package/dist/manifest/spinner.manifest.js +137 -0
- package/dist/manifest/spinner.manifest.js.map +1 -0
- package/dist/manifest/splitter.manifest.d.ts +3 -0
- package/dist/manifest/splitter.manifest.d.ts.map +1 -0
- package/dist/manifest/splitter.manifest.js +192 -0
- package/dist/manifest/splitter.manifest.js.map +1 -0
- package/dist/manifest/stack.manifest.d.ts +3 -0
- package/dist/manifest/stack.manifest.d.ts.map +1 -0
- package/dist/manifest/stack.manifest.js +125 -0
- package/dist/manifest/stack.manifest.js.map +1 -0
- package/dist/manifest/stat.manifest.d.ts +3 -0
- package/dist/manifest/stat.manifest.d.ts.map +1 -0
- package/dist/manifest/stat.manifest.js +197 -0
- package/dist/manifest/stat.manifest.js.map +1 -0
- package/dist/manifest/statusbar.manifest.d.ts +3 -0
- package/dist/manifest/statusbar.manifest.d.ts.map +1 -0
- package/dist/manifest/statusbar.manifest.js +232 -0
- package/dist/manifest/statusbar.manifest.js.map +1 -0
- package/dist/manifest/swatch.manifest.d.ts +3 -0
- package/dist/manifest/swatch.manifest.d.ts.map +1 -0
- package/dist/manifest/swatch.manifest.js +215 -0
- package/dist/manifest/swatch.manifest.js.map +1 -0
- package/dist/manifest/switch.manifest.d.ts +3 -0
- package/dist/manifest/switch.manifest.d.ts.map +1 -0
- package/dist/manifest/switch.manifest.js +323 -0
- package/dist/manifest/switch.manifest.js.map +1 -0
- package/dist/manifest/table.manifest.d.ts +3 -0
- package/dist/manifest/table.manifest.d.ts.map +1 -0
- package/dist/manifest/table.manifest.js +303 -0
- package/dist/manifest/table.manifest.js.map +1 -0
- package/dist/manifest/tabs.manifest.d.ts +3 -0
- package/dist/manifest/tabs.manifest.d.ts.map +1 -0
- package/dist/manifest/tabs.manifest.js +343 -0
- package/dist/manifest/tabs.manifest.js.map +1 -0
- package/dist/manifest/text.manifest.d.ts +3 -0
- package/dist/manifest/text.manifest.d.ts.map +1 -0
- package/dist/manifest/text.manifest.js +189 -0
- package/dist/manifest/text.manifest.js.map +1 -0
- package/dist/manifest/textarea.manifest.d.ts +3 -0
- package/dist/manifest/textarea.manifest.d.ts.map +1 -0
- package/dist/manifest/textarea.manifest.js +233 -0
- package/dist/manifest/textarea.manifest.js.map +1 -0
- package/dist/manifest/toast.manifest.d.ts +3 -0
- package/dist/manifest/toast.manifest.d.ts.map +1 -0
- package/dist/manifest/toast.manifest.js +299 -0
- package/dist/manifest/toast.manifest.js.map +1 -0
- package/dist/manifest/toc.manifest.d.ts +3 -0
- package/dist/manifest/toc.manifest.d.ts.map +1 -0
- package/dist/manifest/toc.manifest.js +139 -0
- package/dist/manifest/toc.manifest.js.map +1 -0
- package/dist/manifest/toolbar.manifest.d.ts +3 -0
- package/dist/manifest/toolbar.manifest.d.ts.map +1 -0
- package/dist/manifest/toolbar.manifest.js +243 -0
- package/dist/manifest/toolbar.manifest.js.map +1 -0
- package/dist/manifest/tooltip.manifest.d.ts +3 -0
- package/dist/manifest/tooltip.manifest.d.ts.map +1 -0
- package/dist/manifest/tooltip.manifest.js +248 -0
- package/dist/manifest/tooltip.manifest.js.map +1 -0
- package/dist/manifest/tree.manifest.d.ts +3 -0
- package/dist/manifest/tree.manifest.d.ts.map +1 -0
- package/dist/manifest/tree.manifest.js +231 -0
- package/dist/manifest/tree.manifest.js.map +1 -0
- package/dist/manifest/types.d.ts +68 -0
- package/dist/manifest/types.d.ts.map +1 -0
- package/dist/manifest/types.js +2 -0
- package/dist/manifest/types.js.map +1 -0
- package/dist/markup/accordion.d.ts +20 -0
- package/dist/markup/accordion.d.ts.map +1 -0
- package/dist/markup/accordion.js +3 -0
- package/dist/markup/accordion.js.map +1 -0
- package/dist/markup/alert.d.ts +9 -0
- package/dist/markup/alert.d.ts.map +1 -0
- package/dist/markup/alert.js +3 -0
- package/dist/markup/alert.js.map +1 -0
- package/dist/markup/app-shell.d.ts +3 -0
- package/dist/markup/app-shell.d.ts.map +1 -0
- package/dist/markup/app-shell.js +3 -0
- package/dist/markup/app-shell.js.map +1 -0
- package/dist/markup/avatar-group.d.ts +5 -0
- package/dist/markup/avatar-group.d.ts.map +1 -0
- package/dist/markup/avatar-group.js +3 -0
- package/dist/markup/avatar-group.js.map +1 -0
- package/dist/markup/avatar.d.ts +28 -0
- package/dist/markup/avatar.d.ts.map +1 -0
- package/dist/markup/avatar.js +46 -0
- package/dist/markup/avatar.js.map +1 -0
- package/dist/markup/badge.d.ts +3 -0
- package/dist/markup/badge.d.ts.map +1 -0
- package/dist/markup/badge.js +3 -0
- package/dist/markup/badge.js.map +1 -0
- package/dist/markup/bar.d.ts +13 -0
- package/dist/markup/bar.d.ts.map +1 -0
- package/dist/markup/bar.js +3 -0
- package/dist/markup/bar.js.map +1 -0
- package/dist/markup/breadcrumb.d.ts +33 -0
- package/dist/markup/breadcrumb.d.ts.map +1 -0
- package/dist/markup/breadcrumb.js +53 -0
- package/dist/markup/breadcrumb.js.map +1 -0
- package/dist/markup/button.d.ts +5 -0
- package/dist/markup/button.d.ts.map +1 -0
- package/dist/markup/button.js +3 -0
- package/dist/markup/button.js.map +1 -0
- package/dist/markup/card-link.d.ts +11 -0
- package/dist/markup/card-link.d.ts.map +1 -0
- package/dist/markup/card-link.js +3 -0
- package/dist/markup/card-link.js.map +1 -0
- package/dist/markup/card.d.ts +3 -0
- package/dist/markup/card.d.ts.map +1 -0
- package/dist/markup/card.js +3 -0
- package/dist/markup/card.js.map +1 -0
- package/dist/markup/checkbox.d.ts +24 -0
- package/dist/markup/checkbox.d.ts.map +1 -0
- package/dist/markup/checkbox.js +48 -0
- package/dist/markup/checkbox.js.map +1 -0
- package/dist/markup/cluster.d.ts +3 -0
- package/dist/markup/cluster.d.ts.map +1 -0
- package/dist/markup/cluster.js +3 -0
- package/dist/markup/cluster.js.map +1 -0
- package/dist/markup/code.d.ts +50 -0
- package/dist/markup/code.d.ts.map +1 -0
- package/dist/markup/code.js +112 -0
- package/dist/markup/code.js.map +1 -0
- package/dist/markup/color-picker.d.ts +64 -0
- package/dist/markup/color-picker.d.ts.map +1 -0
- package/dist/markup/color-picker.js +112 -0
- package/dist/markup/color-picker.js.map +1 -0
- package/dist/markup/dialog.d.ts +3 -0
- package/dist/markup/dialog.d.ts.map +1 -0
- package/dist/markup/dialog.js +3 -0
- package/dist/markup/dialog.js.map +1 -0
- package/dist/markup/dock.d.ts +4 -0
- package/dist/markup/dock.d.ts.map +1 -0
- package/dist/markup/dock.js +3 -0
- package/dist/markup/dock.js.map +1 -0
- package/dist/markup/escape.d.ts +11 -0
- package/dist/markup/escape.d.ts.map +1 -0
- package/dist/markup/escape.js +15 -0
- package/dist/markup/escape.js.map +1 -0
- package/dist/markup/eyebrow.d.ts +21 -0
- package/dist/markup/eyebrow.d.ts.map +1 -0
- package/dist/markup/eyebrow.js +26 -0
- package/dist/markup/eyebrow.js.map +1 -0
- package/dist/markup/field.d.ts +36 -0
- package/dist/markup/field.d.ts.map +1 -0
- package/dist/markup/field.js +93 -0
- package/dist/markup/field.js.map +1 -0
- package/dist/markup/form-group.d.ts +3 -0
- package/dist/markup/form-group.d.ts.map +1 -0
- package/dist/markup/form-group.js +3 -0
- package/dist/markup/form-group.js.map +1 -0
- package/dist/markup/grid.d.ts +4 -0
- package/dist/markup/grid.d.ts.map +1 -0
- package/dist/markup/grid.js +3 -0
- package/dist/markup/grid.js.map +1 -0
- package/dist/markup/heading.d.ts +3 -0
- package/dist/markup/heading.d.ts.map +1 -0
- package/dist/markup/heading.js +3 -0
- package/dist/markup/heading.js.map +1 -0
- package/dist/markup/heatmap.d.ts +5 -0
- package/dist/markup/heatmap.d.ts.map +1 -0
- package/dist/markup/heatmap.js +3 -0
- package/dist/markup/heatmap.js.map +1 -0
- package/dist/markup/icon.d.ts +4 -0
- package/dist/markup/icon.d.ts.map +1 -0
- package/dist/markup/icon.js +3 -0
- package/dist/markup/icon.js.map +1 -0
- package/dist/markup/image.d.ts +6 -0
- package/dist/markup/image.d.ts.map +1 -0
- package/dist/markup/image.js +3 -0
- package/dist/markup/image.js.map +1 -0
- package/dist/markup/index.d.ts +98 -0
- package/dist/markup/index.d.ts.map +1 -0
- package/dist/markup/index.js +58 -0
- package/dist/markup/index.js.map +1 -0
- package/dist/markup/kbd.d.ts +6 -0
- package/dist/markup/kbd.d.ts.map +1 -0
- package/dist/markup/kbd.js +3 -0
- package/dist/markup/kbd.js.map +1 -0
- package/dist/markup/link.d.ts +20 -0
- package/dist/markup/link.d.ts.map +1 -0
- package/dist/markup/link.js +32 -0
- package/dist/markup/link.js.map +1 -0
- package/dist/markup/menu.d.ts +22 -0
- package/dist/markup/menu.d.ts.map +1 -0
- package/dist/markup/menu.js +3 -0
- package/dist/markup/menu.js.map +1 -0
- package/dist/markup/number-input.d.ts +16 -0
- package/dist/markup/number-input.d.ts.map +1 -0
- package/dist/markup/number-input.js +22 -0
- package/dist/markup/number-input.js.map +1 -0
- package/dist/markup/pagination.d.ts +36 -0
- package/dist/markup/pagination.d.ts.map +1 -0
- package/dist/markup/pagination.js +102 -0
- package/dist/markup/pagination.js.map +1 -0
- package/dist/markup/panel.d.ts +23 -0
- package/dist/markup/panel.d.ts.map +1 -0
- package/dist/markup/panel.js +54 -0
- package/dist/markup/panel.js.map +1 -0
- package/dist/markup/pie.d.ts +14 -0
- package/dist/markup/pie.d.ts.map +1 -0
- package/dist/markup/pie.js +3 -0
- package/dist/markup/pie.js.map +1 -0
- package/dist/markup/progress.d.ts +3 -0
- package/dist/markup/progress.d.ts.map +1 -0
- package/dist/markup/progress.js +3 -0
- package/dist/markup/progress.js.map +1 -0
- package/dist/markup/radio.d.ts +19 -0
- package/dist/markup/radio.d.ts.map +1 -0
- package/dist/markup/radio.js +31 -0
- package/dist/markup/radio.js.map +1 -0
- package/dist/markup/section.d.ts +16 -0
- package/dist/markup/section.d.ts.map +1 -0
- package/dist/markup/section.js +3 -0
- package/dist/markup/section.js.map +1 -0
- package/dist/markup/segmented.d.ts +24 -0
- package/dist/markup/segmented.d.ts.map +1 -0
- package/dist/markup/segmented.js +59 -0
- package/dist/markup/segmented.js.map +1 -0
- package/dist/markup/select.d.ts +29 -0
- package/dist/markup/select.d.ts.map +1 -0
- package/dist/markup/select.js +61 -0
- package/dist/markup/select.js.map +1 -0
- package/dist/markup/separator.d.ts +6 -0
- package/dist/markup/separator.d.ts.map +1 -0
- package/dist/markup/separator.js +3 -0
- package/dist/markup/separator.js.map +1 -0
- package/dist/markup/skeleton.d.ts +4 -0
- package/dist/markup/skeleton.d.ts.map +1 -0
- package/dist/markup/skeleton.js +3 -0
- package/dist/markup/skeleton.js.map +1 -0
- package/dist/markup/slider.d.ts +3 -0
- package/dist/markup/slider.d.ts.map +1 -0
- package/dist/markup/slider.js +3 -0
- package/dist/markup/slider.js.map +1 -0
- package/dist/markup/sparkline.d.ts +6 -0
- package/dist/markup/sparkline.d.ts.map +1 -0
- package/dist/markup/sparkline.js +3 -0
- package/dist/markup/sparkline.js.map +1 -0
- package/dist/markup/spinner.d.ts +10 -0
- package/dist/markup/spinner.d.ts.map +1 -0
- package/dist/markup/spinner.js +10 -0
- package/dist/markup/spinner.js.map +1 -0
- package/dist/markup/splitter.d.ts +3 -0
- package/dist/markup/splitter.d.ts.map +1 -0
- package/dist/markup/splitter.js +3 -0
- package/dist/markup/splitter.js.map +1 -0
- package/dist/markup/stack.d.ts +3 -0
- package/dist/markup/stack.d.ts.map +1 -0
- package/dist/markup/stack.js +3 -0
- package/dist/markup/stack.js.map +1 -0
- package/dist/markup/stat.d.ts +7 -0
- package/dist/markup/stat.d.ts.map +1 -0
- package/dist/markup/stat.js +3 -0
- package/dist/markup/stat.js.map +1 -0
- package/dist/markup/statusbar.d.ts +3 -0
- package/dist/markup/statusbar.d.ts.map +1 -0
- package/dist/markup/statusbar.js +3 -0
- package/dist/markup/statusbar.js.map +1 -0
- package/dist/markup/swatch.d.ts +4 -0
- package/dist/markup/swatch.d.ts.map +1 -0
- package/dist/markup/swatch.js +3 -0
- package/dist/markup/swatch.js.map +1 -0
- package/dist/markup/switch.d.ts +3 -0
- package/dist/markup/switch.d.ts.map +1 -0
- package/dist/markup/switch.js +3 -0
- package/dist/markup/switch.js.map +1 -0
- package/dist/markup/tabs.d.ts +25 -0
- package/dist/markup/tabs.d.ts.map +1 -0
- package/dist/markup/tabs.js +3 -0
- package/dist/markup/tabs.js.map +1 -0
- package/dist/markup/text.d.ts +17 -0
- package/dist/markup/text.d.ts.map +1 -0
- package/dist/markup/text.js +3 -0
- package/dist/markup/text.js.map +1 -0
- package/dist/markup/textarea.d.ts +4 -0
- package/dist/markup/textarea.d.ts.map +1 -0
- package/dist/markup/textarea.js +3 -0
- package/dist/markup/textarea.js.map +1 -0
- package/dist/markup/toast.d.ts +44 -0
- package/dist/markup/toast.d.ts.map +1 -0
- package/dist/markup/toast.js +76 -0
- package/dist/markup/toast.js.map +1 -0
- package/dist/markup/toc.d.ts +7 -0
- package/dist/markup/toc.d.ts.map +1 -0
- package/dist/markup/toc.js +3 -0
- package/dist/markup/toc.js.map +1 -0
- package/dist/markup/toolbar.d.ts +21 -0
- package/dist/markup/toolbar.d.ts.map +1 -0
- package/dist/markup/toolbar.js +36 -0
- package/dist/markup/toolbar.js.map +1 -0
- package/dist/markup/tooltip.d.ts +4 -0
- package/dist/markup/tooltip.d.ts.map +1 -0
- package/dist/markup/tooltip.js +3 -0
- package/dist/markup/tooltip.js.map +1 -0
- package/dist/markup/tree.d.ts +46 -0
- package/dist/markup/tree.d.ts.map +1 -0
- package/dist/markup/tree.js +81 -0
- package/dist/markup/tree.js.map +1 -0
- package/dist/mcp/resources.d.ts +3 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +13 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +21 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +4 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +162 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/series.d.ts +86 -0
- package/dist/series.d.ts.map +1 -0
- package/dist/series.js +207 -0
- package/dist/series.js.map +1 -0
- package/dist/theme-file.d.ts +53 -0
- package/dist/theme-file.d.ts.map +1 -0
- package/dist/theme-file.js +51 -0
- package/dist/theme-file.js.map +1 -0
- package/dist/timeseries.d.ts +26 -0
- package/dist/timeseries.d.ts.map +1 -0
- package/dist/timeseries.js +23 -0
- package/dist/timeseries.js.map +1 -0
- package/dist/token-meta.d.ts +19 -0
- package/dist/token-meta.d.ts.map +1 -0
- package/dist/token-meta.js +74 -0
- package/dist/token-meta.js.map +1 -0
- package/dist/types.d.ts +152 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vocab.d.ts +45 -0
- package/dist/vocab.d.ts.map +1 -0
- package/dist/vocab.js +41 -0
- package/dist/vocab.js.map +1 -0
- package/manifest.json +96 -0
- package/package.json +60 -0
|
@@ -0,0 +1,2187 @@
|
|
|
1
|
+
import { clampToGamut, contrast, formatCss, hueDelta, oklch, pickReadable, schemeOf, toOklchColor, withAlpha, withLightness, } from "../color.js";
|
|
2
|
+
import { resolveGraph } from "../graph.js";
|
|
3
|
+
import { FULL_TONES } from "../vocab.js";
|
|
4
|
+
const AA = 4.5;
|
|
5
|
+
const AAA = 7;
|
|
6
|
+
const ENFORCE = AA + 0.2;
|
|
7
|
+
export const SURFACE_SEPARATION = 1.5;
|
|
8
|
+
export const BORDER_SEPARATION = 1.5;
|
|
9
|
+
export const DIVIDER_SEPARATION = 1.8;
|
|
10
|
+
const DEFAULT_SHIFT_STEP = 90;
|
|
11
|
+
const DEFAULT_ACCENT_SPLIT = 45;
|
|
12
|
+
// Chroma of the faint accent-hue wash on a surface synthesized from an accent (the "keep the tone"
|
|
13
|
+
// derivation); kept low enough that any hue stays a neutral-reading surface rather than a muddy fill.
|
|
14
|
+
const DERIVED_SURFACE_TINT_C = 0.02;
|
|
15
|
+
// How accent-2/3/4 fan off the primary accent. "split-complement": 2 and 3 flank the
|
|
16
|
+
// accent at ∓the accentSplit knob, 4 is its 180° complement; if a theme pins either wing, the
|
|
17
|
+
// other mirrors its hue across the accent instead of the fixed knob, so the pair stays symmetric
|
|
18
|
+
// around the author's choice. "wheel": an even fan, each accent one accentShiftStep past the last.
|
|
19
|
+
const ACCENT_FAN = "split-complement";
|
|
20
|
+
const ACHROMATIC_CHROMA = 0.02;
|
|
21
|
+
const DERIVED_ACCENT_HUE_ROTATION = 150;
|
|
22
|
+
const DERIVED_ACCENT_FALLBACK_HUE = 250;
|
|
23
|
+
const DERIVED_ACCENT_L = 0.62;
|
|
24
|
+
const DERIVED_ACCENT_C = 0.16;
|
|
25
|
+
const ACCENT_RAMP_L_MIN = 0.1;
|
|
26
|
+
const ACCENT_RAMP_L_MAX = 0.95;
|
|
27
|
+
const HUE_STABLE_CHROMA = 0.1;
|
|
28
|
+
// The fan (accent-2/3/4) varies hue at the accent's L/C, which collapses to identical grays when the
|
|
29
|
+
// accent has near-zero chroma. Floor the fan's *base* chroma (not the primary accent) so a near-gray
|
|
30
|
+
// accent still fans into distinct faint tints instead of four identical grays. Above the floor the
|
|
31
|
+
// base is the accent unchanged, so every chromatic theme derives byte-identically. Must stay below
|
|
32
|
+
// HUE_STABLE_CHROMA: the constant-L/C fan invariant exempts accents under that line, and the floored
|
|
33
|
+
// fan has to land inside that exempted band or it would trip the very invariant it derives under.
|
|
34
|
+
const FAN_MIN_CHROMA = 0.045;
|
|
35
|
+
const HUE_TOLERANCE = 8;
|
|
36
|
+
const LIGHTNESS_TOLERANCE = 0.05;
|
|
37
|
+
const DEFAULT_TYPE_SCALE = 1.2;
|
|
38
|
+
const DEFAULT_RADIUS_SCALE = 1;
|
|
39
|
+
const BASE_TEXT_REM = 1;
|
|
40
|
+
const DEFAULT_FONTS = {
|
|
41
|
+
sans: 'system-ui, -apple-system, "Segoe UI", Roboto, sans-serif',
|
|
42
|
+
mono: 'ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace',
|
|
43
|
+
display: '"Avenir Next", "Futura", "Century Gothic", "Trebuchet MS", system-ui, -apple-system, "Segoe UI", sans-serif',
|
|
44
|
+
};
|
|
45
|
+
const TEXT_LIGHT = { l: 0.98, c: 0, h: 0, alpha: 1 };
|
|
46
|
+
const TEXT_DARK = { l: 0.15, c: 0, h: 0, alpha: 1 };
|
|
47
|
+
const TRUE_WHITE = { l: 1, c: 0, h: 0, alpha: 1 };
|
|
48
|
+
const TRUE_BLACK = { l: 0, c: 0, h: 0, alpha: 1 };
|
|
49
|
+
const TEXT_POLES = [TRUE_WHITE, TRUE_BLACK];
|
|
50
|
+
function bestTruePole(bg) {
|
|
51
|
+
return contrast(TRUE_BLACK, bg) >= contrast(TRUE_WHITE, bg) ? TRUE_BLACK : TRUE_WHITE;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Each status role borrows its hue from a named palette color rather than a free-standing
|
|
55
|
+
* constant, so the statuses are never detached from the catalog: re-hueing (or pinning) the
|
|
56
|
+
* named color moves its status with it. A direct pin on the status token itself still wins.
|
|
57
|
+
*/
|
|
58
|
+
const STATUS_TO_HUE = {
|
|
59
|
+
success: "green",
|
|
60
|
+
warn: "yellow",
|
|
61
|
+
danger: "red",
|
|
62
|
+
info: "blue",
|
|
63
|
+
};
|
|
64
|
+
/** The accent chroma at which the named hues derive at their catalog saturation (factor ~1);
|
|
65
|
+
* a more saturated accent pushes them up, a muted one down. */
|
|
66
|
+
const NEUTRAL_ACCENT_CHROMA = 0.13;
|
|
67
|
+
const PALETTE_HUES = {
|
|
68
|
+
red: { h: 25, c: 0.2 },
|
|
69
|
+
orange: { h: 55, c: 0.18 },
|
|
70
|
+
yellow: { h: 95, c: 0.17 },
|
|
71
|
+
green: { h: 145, c: 0.18 },
|
|
72
|
+
blue: { h: 250, c: 0.18 },
|
|
73
|
+
purple: { h: 300, c: 0.18 },
|
|
74
|
+
brown: { h: 50, c: 0.08 },
|
|
75
|
+
pink: { h: 350, c: 0.16 },
|
|
76
|
+
cyan: { h: 200, c: 0.14 },
|
|
77
|
+
gray: "gray",
|
|
78
|
+
white: "white",
|
|
79
|
+
black: "black",
|
|
80
|
+
};
|
|
81
|
+
const PALETTE_STOPS = ["subtle", "muted", "base", "strong", "contrast"];
|
|
82
|
+
// Syntax-highlighting scope colors. The vivid roles each take an evenly-spread hue
|
|
83
|
+
// offset from the accent, so any accent yields a mutually-distinguishable code
|
|
84
|
+
// palette that re-themes with the chrome. The structural roles (comment / operator
|
|
85
|
+
// / punctuation / variable) stay quiet by design — they read by muted chroma and
|
|
86
|
+
// lightness, not by a signature hue.
|
|
87
|
+
// Vivid roles in lightness-rank order (index 0 = nearest the editor bg, 7 = nearest
|
|
88
|
+
// the readable pole). Hue is decorrelated from rank by a bit-reversal permutation:
|
|
89
|
+
// adjacent lightness ranks land far apart on the hue wheel and far-apart ranks share
|
|
90
|
+
// a hue — so whichever axis a tight bg compresses, the other keeps neighbours apart.
|
|
91
|
+
const CODE_VIVID_ROLES = [
|
|
92
|
+
"keyword",
|
|
93
|
+
"number",
|
|
94
|
+
"function",
|
|
95
|
+
"type",
|
|
96
|
+
"string",
|
|
97
|
+
"tag",
|
|
98
|
+
"attr",
|
|
99
|
+
"regexp",
|
|
100
|
+
];
|
|
101
|
+
const CODE_HUE_RANK = [0, 4, 2, 6, 1, 5, 3, 7];
|
|
102
|
+
const CODE_STRUCTURAL_ROLES = ["comment", "operator", "punctuation", "variable"];
|
|
103
|
+
const CODE_SCOPES = [...CODE_VIVID_ROLES, ...CODE_STRUCTURAL_ROLES];
|
|
104
|
+
const CODE_SURFACES = ["--code-bg", "--code-fg", "--code-line-highlight", "--code-selection"];
|
|
105
|
+
const SURFACES = ["--body-bg", "--bg-0", "--bg-1", "--bg-2", "--bg-3"];
|
|
106
|
+
const PANEL_REF_INDEX = SURFACES.indexOf("--bg-2");
|
|
107
|
+
const PANEL_SURFACES = ["--bg-1", "--bg-2"];
|
|
108
|
+
const TEXT_STEPS = ["xs", "sm", "body", "lg", "xl", "2xl", "3xl", "4xl", "5xl"];
|
|
109
|
+
const LEADING_STEPS = ["tight", "normal", "loose"];
|
|
110
|
+
const WEIGHT_STEPS = ["normal", "medium", "semibold", "bold"];
|
|
111
|
+
const RADIUS_STEPS = ["none", "sm", "md", "lg", "full"];
|
|
112
|
+
const BORDER_STEPS = ["thin", "normal", "thick"];
|
|
113
|
+
const DURATION_STEPS = ["fast", "base", "slow"];
|
|
114
|
+
const EASE_STEPS = ["standard", "emphasized"];
|
|
115
|
+
const SPACE_STEPS = [0, 1, 2, 3, 4, 5, 6, 7, 8];
|
|
116
|
+
const ELEVATION_STEPS = [0, 1, 2, 3, 4, 5];
|
|
117
|
+
const WEIGHT_VALUES = {
|
|
118
|
+
normal: 400,
|
|
119
|
+
medium: 500,
|
|
120
|
+
semibold: 600,
|
|
121
|
+
bold: 700,
|
|
122
|
+
};
|
|
123
|
+
const LEADING_VALUES = {
|
|
124
|
+
tight: 1.2,
|
|
125
|
+
normal: 1.5,
|
|
126
|
+
loose: 1.8,
|
|
127
|
+
};
|
|
128
|
+
const DENSITY_MULTIPLIER = {
|
|
129
|
+
compact: 0.8,
|
|
130
|
+
normal: 1,
|
|
131
|
+
comfortable: 1.25,
|
|
132
|
+
};
|
|
133
|
+
const SPACE_BASE_REM = 0.25;
|
|
134
|
+
function buildProduces() {
|
|
135
|
+
const produces = [];
|
|
136
|
+
const categories = {};
|
|
137
|
+
const add = (name, category) => {
|
|
138
|
+
produces.push(name);
|
|
139
|
+
categories[name] = category;
|
|
140
|
+
};
|
|
141
|
+
add("--bg-sunken", "color");
|
|
142
|
+
for (const s of SURFACES)
|
|
143
|
+
add(s, "color");
|
|
144
|
+
add("--scrim", "color");
|
|
145
|
+
add("--surface-overlay", "color");
|
|
146
|
+
add("--surface-overlay-border", "color");
|
|
147
|
+
for (let i = 0; i <= 3; i++)
|
|
148
|
+
add(`--fg-${i}`, "color");
|
|
149
|
+
add("--fg-disabled", "color");
|
|
150
|
+
add("--placeholder", "color");
|
|
151
|
+
add("--line", "color");
|
|
152
|
+
add("--line-2", "color");
|
|
153
|
+
add("--ring", "color");
|
|
154
|
+
add("--ring-bg", "color");
|
|
155
|
+
add("--accent", "color");
|
|
156
|
+
add("--accent-hover", "color");
|
|
157
|
+
add("--accent-active", "color");
|
|
158
|
+
add("--accent-bg", "color");
|
|
159
|
+
add("--accent-fg", "color");
|
|
160
|
+
add("--accent-text", "color");
|
|
161
|
+
add("--accent-vivid", "color");
|
|
162
|
+
for (const n of ["2", "3", "4"]) {
|
|
163
|
+
add(`--accent-${n}`, "color");
|
|
164
|
+
add(`--accent-${n}-bg`, "color");
|
|
165
|
+
add(`--accent-${n}-fg`, "color");
|
|
166
|
+
add(`--accent-${n}-text`, "color");
|
|
167
|
+
add(`--accent-${n}-vivid`, "color");
|
|
168
|
+
}
|
|
169
|
+
add("--accent-shift-step", "number");
|
|
170
|
+
add("--neutral", "color");
|
|
171
|
+
add("--neutral-bg", "color");
|
|
172
|
+
add("--neutral-fg", "color");
|
|
173
|
+
add("--neutral-text", "color");
|
|
174
|
+
add("--neutral-vivid", "color");
|
|
175
|
+
add("--field-bg", "color");
|
|
176
|
+
add("--field-border", "color");
|
|
177
|
+
for (const role of Object.keys(STATUS_TO_HUE)) {
|
|
178
|
+
add(`--${role}`, "color");
|
|
179
|
+
add(`--${role}-bg`, "color");
|
|
180
|
+
add(`--${role}-fg`, "color");
|
|
181
|
+
add(`--${role}-text`, "color");
|
|
182
|
+
add(`--${role}-vivid`, "color");
|
|
183
|
+
}
|
|
184
|
+
for (const s of ["hover", "press", "selected", "disabled", "drag"]) {
|
|
185
|
+
add(`--state-${s}`, "color");
|
|
186
|
+
}
|
|
187
|
+
add("--link", "color");
|
|
188
|
+
add("--link-hover", "color");
|
|
189
|
+
add("--selection", "color");
|
|
190
|
+
add("--highlight", "color");
|
|
191
|
+
add("--selection-cue", "keyword");
|
|
192
|
+
add("--shadow", "shadow");
|
|
193
|
+
for (const hue of Object.keys(PALETTE_HUES)) {
|
|
194
|
+
add(`--color-${hue}`, "color");
|
|
195
|
+
for (const stop of PALETTE_STOPS)
|
|
196
|
+
add(`--color-${hue}-${stop}`, "color");
|
|
197
|
+
add(`--${hue}`, "color");
|
|
198
|
+
add(`--${hue}-bg`, "color");
|
|
199
|
+
add(`--${hue}-fg`, "color");
|
|
200
|
+
add(`--${hue}-text`, "color");
|
|
201
|
+
add(`--${hue}-vivid`, "color");
|
|
202
|
+
}
|
|
203
|
+
for (const t of CODE_SURFACES)
|
|
204
|
+
add(t, "color");
|
|
205
|
+
for (const role of CODE_SCOPES)
|
|
206
|
+
add(`--code-${role}`, "color");
|
|
207
|
+
add("--font-sans", "font");
|
|
208
|
+
add("--font-mono", "font");
|
|
209
|
+
add("--font-display", "font");
|
|
210
|
+
for (const step of TEXT_STEPS)
|
|
211
|
+
add(`--text-${step}`, "length");
|
|
212
|
+
for (const step of LEADING_STEPS)
|
|
213
|
+
add(`--leading-${step}`, "number");
|
|
214
|
+
for (const step of WEIGHT_STEPS)
|
|
215
|
+
add(`--weight-${step}`, "number");
|
|
216
|
+
for (const step of RADIUS_STEPS)
|
|
217
|
+
add(`--radius-${step}`, "length");
|
|
218
|
+
for (const step of BORDER_STEPS)
|
|
219
|
+
add(`--border-${step}`, "length");
|
|
220
|
+
for (const step of DURATION_STEPS)
|
|
221
|
+
add(`--duration-${step}`, "duration");
|
|
222
|
+
for (const step of EASE_STEPS)
|
|
223
|
+
add(`--ease-${step}`, "easing");
|
|
224
|
+
for (const step of ELEVATION_STEPS)
|
|
225
|
+
add(`--elevation-${step}`, "shadow");
|
|
226
|
+
for (const step of SPACE_STEPS)
|
|
227
|
+
add(`--space-${step}`, "length");
|
|
228
|
+
return { produces, categories };
|
|
229
|
+
}
|
|
230
|
+
const { produces: PRODUCES, categories: CATEGORIES } = buildProduces();
|
|
231
|
+
/**
|
|
232
|
+
* Legal value sets for `keyword` (intent) tokens. A keyword token names a
|
|
233
|
+
* rendering *intent* a component branches on, so its values are a closed
|
|
234
|
+
* vocabulary, not free text; the format invariant rejects any algorithm that
|
|
235
|
+
* emits a value outside its token's domain.
|
|
236
|
+
*/
|
|
237
|
+
export const KEYWORD_DOMAINS = {
|
|
238
|
+
"--selection-cue": ["tint", "marker"],
|
|
239
|
+
};
|
|
240
|
+
function stepLightness(base, scheme, step, index) {
|
|
241
|
+
const direction = scheme === "dark" ? 1 : -1;
|
|
242
|
+
return base + direction * step * index;
|
|
243
|
+
}
|
|
244
|
+
function contrastBandFloor(knobs) {
|
|
245
|
+
const band = knobs.contrastBand;
|
|
246
|
+
if (typeof band === "number")
|
|
247
|
+
return band;
|
|
248
|
+
if (band === "aaa")
|
|
249
|
+
return AAA;
|
|
250
|
+
if (band === "aa")
|
|
251
|
+
return AA;
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
function vibrancyOf(knobs, preset) {
|
|
255
|
+
const v = typeof knobs.vibrancy === "number" ? knobs.vibrancy : preset.defaultVibrancy;
|
|
256
|
+
return Math.min(1, Math.max(0, v));
|
|
257
|
+
}
|
|
258
|
+
function typeScaleOf(knobs) {
|
|
259
|
+
const v = typeof knobs.typeScale === "number" ? knobs.typeScale : DEFAULT_TYPE_SCALE;
|
|
260
|
+
return Math.min(2, Math.max(1.05, v));
|
|
261
|
+
}
|
|
262
|
+
function radiusScaleOf(knobs) {
|
|
263
|
+
const v = typeof knobs.radiusScale === "number" ? knobs.radiusScale : DEFAULT_RADIUS_SCALE;
|
|
264
|
+
return Math.max(0, v);
|
|
265
|
+
}
|
|
266
|
+
function densityOf(knobs) {
|
|
267
|
+
const d = knobs.density;
|
|
268
|
+
if (typeof d === "number")
|
|
269
|
+
return Math.max(0.4, d);
|
|
270
|
+
if (d === "compact" || d === "comfortable")
|
|
271
|
+
return DENSITY_MULTIPLIER[d];
|
|
272
|
+
return DENSITY_MULTIPLIER.normal;
|
|
273
|
+
}
|
|
274
|
+
function fontsOf(knobs) {
|
|
275
|
+
return {
|
|
276
|
+
sans: knobs.fonts?.sans ?? DEFAULT_FONTS.sans,
|
|
277
|
+
mono: knobs.fonts?.mono ?? DEFAULT_FONTS.mono,
|
|
278
|
+
display: knobs.fonts?.display ?? DEFAULT_FONTS.display,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function emittedContrast(fg, bgCss) {
|
|
282
|
+
return contrast(formatCss(fg), bgCss);
|
|
283
|
+
}
|
|
284
|
+
export function enforceContrastFloor(fg, bg, scheme, floor = ENFORCE) {
|
|
285
|
+
const bgCss = formatCss(bg);
|
|
286
|
+
if (emittedContrast(fg, bgCss) >= floor)
|
|
287
|
+
return fg;
|
|
288
|
+
const preferred = scheme === "dark" ? TRUE_WHITE.l : TRUE_BLACK.l;
|
|
289
|
+
const other = scheme === "dark" ? TRUE_BLACK.l : TRUE_WHITE.l;
|
|
290
|
+
const swept = sweepToward(fg, bgCss, preferred, floor) ?? sweepToward(fg, bgCss, other, floor);
|
|
291
|
+
const pole = bestTruePole(bgCss);
|
|
292
|
+
if (!swept)
|
|
293
|
+
return pole;
|
|
294
|
+
return emittedContrast(pole, bgCss) > emittedContrast(swept, bgCss) ? pole : swept;
|
|
295
|
+
}
|
|
296
|
+
function sweepToward(fg, bgCss, targetL, floor) {
|
|
297
|
+
for (let i = 0; i <= 100; i++) {
|
|
298
|
+
const t = i / 100;
|
|
299
|
+
const candidate = {
|
|
300
|
+
l: fg.l + (targetL - fg.l) * t,
|
|
301
|
+
c: fg.c * (1 - t),
|
|
302
|
+
h: fg.h,
|
|
303
|
+
alpha: fg.alpha,
|
|
304
|
+
};
|
|
305
|
+
if (emittedContrast(candidate, bgCss) >= floor)
|
|
306
|
+
return candidate;
|
|
307
|
+
}
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
function bestPoleContrast(bg) {
|
|
311
|
+
return Math.max(contrast(TEXT_LIGHT, bg), contrast(TEXT_DARK, bg));
|
|
312
|
+
}
|
|
313
|
+
function ensureTextHeadroom(bg, scheme, floor = ENFORCE) {
|
|
314
|
+
if (bestPoleContrast(bg) >= floor)
|
|
315
|
+
return bg;
|
|
316
|
+
const target = scheme === "dark" ? 0 : 1;
|
|
317
|
+
let candidate = bg;
|
|
318
|
+
for (let i = 1; i <= 100; i++) {
|
|
319
|
+
const t = i / 100;
|
|
320
|
+
candidate = withLightness(bg, bg.l + (target - bg.l) * t);
|
|
321
|
+
if (bestPoleContrast(candidate) >= floor)
|
|
322
|
+
return candidate;
|
|
323
|
+
}
|
|
324
|
+
return withLightness(bg, target);
|
|
325
|
+
}
|
|
326
|
+
function fillWithTextHeadroom(l, c, h, floor = ENFORCE) {
|
|
327
|
+
const seed = oklch(l, c, h);
|
|
328
|
+
if (bestPoleContrast(seed) >= floor)
|
|
329
|
+
return seed;
|
|
330
|
+
let fallback = seed;
|
|
331
|
+
for (let i = 1; i <= 100; i++) {
|
|
332
|
+
const down = oklch(l - (l * i) / 100, c, h);
|
|
333
|
+
if (bestPoleContrast(down) >= floor)
|
|
334
|
+
return down;
|
|
335
|
+
const up = oklch(l + ((1 - l) * i) / 100, c, h);
|
|
336
|
+
if (bestPoleContrast(up) >= floor)
|
|
337
|
+
return up;
|
|
338
|
+
fallback = bestPoleContrast(down) >= bestPoleContrast(up) ? down : up;
|
|
339
|
+
}
|
|
340
|
+
return fallback;
|
|
341
|
+
}
|
|
342
|
+
function lightnessForContrast(pole, bg, bgCss, target) {
|
|
343
|
+
let bestL = pole.l;
|
|
344
|
+
for (let i = 0; i <= 200; i++) {
|
|
345
|
+
const t = i / 200;
|
|
346
|
+
const candidateL = pole.l + (bg.l - pole.l) * t;
|
|
347
|
+
if (emittedContrast(withLightness(pole, candidateL), bgCss) >= target)
|
|
348
|
+
bestL = candidateL;
|
|
349
|
+
else
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
return bestL;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Push a palette ramp's `strong` stop along lightness — toward whichever pole it already
|
|
356
|
+
* leans, so the ramp stays monotonic — until it clears `target` contrast against the
|
|
357
|
+
* `subtle` tint it is read on (the soft badge / avatar fallback pairing). Hue and chroma
|
|
358
|
+
* are preserved (gamut-clamped); only lightness moves, so `strong` stays usable as the
|
|
359
|
+
* outline ink too.
|
|
360
|
+
*/
|
|
361
|
+
function liftStopForContrast(fg, bgCss, target, towardLight) {
|
|
362
|
+
if (contrast(formatCss(fg), bgCss) >= target)
|
|
363
|
+
return fg;
|
|
364
|
+
const poleL = towardLight ? 1 : 0;
|
|
365
|
+
let best = fg;
|
|
366
|
+
for (let i = 1; i <= 100; i++) {
|
|
367
|
+
const candidate = clampToGamut(oklch(fg.l + (poleL - fg.l) * (i / 100), fg.c, fg.h));
|
|
368
|
+
best = candidate;
|
|
369
|
+
if (contrast(formatCss(candidate), bgCss) >= target)
|
|
370
|
+
return candidate;
|
|
371
|
+
}
|
|
372
|
+
return best;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Keep a solid fill that paints directly on the page (a primary control's surface) from
|
|
376
|
+
* collapsing onto `--bg-0`. When the fill's lightness coincides with the page's — a near-gray
|
|
377
|
+
* accent, or any accent whose lightness lands on the background's — luminance contrast drops
|
|
378
|
+
* toward 1:1 and the control vanishes even though its own text still reads. Push lightness away
|
|
379
|
+
* from the surface (toward the far pole) until it clears `separation` against the surface, while
|
|
380
|
+
* never dropping below the text-headroom (best-pole contrast) the fill arrived with — so a
|
|
381
|
+
* mid-lightness page can't park the fill in the dead zone where neither text pole reaches its
|
|
382
|
+
* on-fill floor. Hue and chroma are held.
|
|
383
|
+
*/
|
|
384
|
+
function separateFillFromSurface(fill, surface, separation, textFloor) {
|
|
385
|
+
const surfaceCss = formatCss(surface);
|
|
386
|
+
if (contrast(formatCss(fill), surfaceCss) >= separation)
|
|
387
|
+
return fill;
|
|
388
|
+
const headroom = Math.min(textFloor, bestPoleContrast(fill));
|
|
389
|
+
const poleL = surface.l < 0.5 ? 1 : 0;
|
|
390
|
+
let best = fill;
|
|
391
|
+
for (let i = 1; i <= 100; i++) {
|
|
392
|
+
const candidate = clampToGamut(oklch(fill.l + (poleL - fill.l) * (i / 100), fill.c, fill.h));
|
|
393
|
+
best = candidate;
|
|
394
|
+
if (contrast(formatCss(candidate), surfaceCss) >= separation &&
|
|
395
|
+
bestPoleContrast(candidate) >= headroom - 0.01) {
|
|
396
|
+
return candidate;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return best;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Floor a divider/border against the surface it delineates. A fixed lightness shift off the
|
|
403
|
+
* surface reads as a hairline in a mid-range theme, but collapses below perceptibility when the bg
|
|
404
|
+
* anchor nears a pole — a border on near-black goes invisible, so a bordered card on a near-black
|
|
405
|
+
* page loses its only separation channel. Push the border toward the readable pole until it clears
|
|
406
|
+
* `minContrast`.
|
|
407
|
+
*/
|
|
408
|
+
export function borderForContrast(seed, surface, minContrast) {
|
|
409
|
+
const surfaceCss = formatCss(surface);
|
|
410
|
+
if (emittedContrast(seed, surfaceCss) >= minContrast)
|
|
411
|
+
return seed;
|
|
412
|
+
const targetL = surface.l < 0.5 ? 1 : 0;
|
|
413
|
+
let candidate = seed;
|
|
414
|
+
for (let i = 1; i <= 100; i++) {
|
|
415
|
+
candidate = withLightness(seed, seed.l + (targetL - seed.l) * (i / 100));
|
|
416
|
+
if (emittedContrast(candidate, surfaceCss) >= minContrast)
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
return candidate;
|
|
420
|
+
}
|
|
421
|
+
function readableOnTint(tint, hue, floor, inkChroma) {
|
|
422
|
+
const tintCss = formatCss(tint);
|
|
423
|
+
const towardDark = contrast("#000000", tintCss) >= contrast("#ffffff", tintCss);
|
|
424
|
+
const targetL = towardDark ? 0 : 1;
|
|
425
|
+
const seedChroma = inkChroma ?? (towardDark ? 0.06 : 0.04);
|
|
426
|
+
const seed = oklch(tint.l + (towardDark ? -0.4 : 0.4), seedChroma, hue);
|
|
427
|
+
for (let i = 0; i <= 100; i++) {
|
|
428
|
+
const t = i / 100;
|
|
429
|
+
const css = formatCss({
|
|
430
|
+
l: seed.l + (targetL - seed.l) * t,
|
|
431
|
+
c: seed.c * (1 - t),
|
|
432
|
+
h: hue,
|
|
433
|
+
alpha: 1,
|
|
434
|
+
});
|
|
435
|
+
if (contrast(css, tintCss) >= floor)
|
|
436
|
+
return css;
|
|
437
|
+
}
|
|
438
|
+
return towardDark ? "#000000" : "#ffffff";
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* A hued ink for a status `-text` token. Its non-negotiable job is to clear
|
|
442
|
+
* `tintFloor` against its own `-bg` tint; on top of that it tries to also clear
|
|
443
|
+
* `panelFloor` against the neutral panels it may sit on. When no tint-readable
|
|
444
|
+
* color can also serve the panels (a chromatic background pushing tint and panel
|
|
445
|
+
* to incompatible lightnesses), tint-readability wins and the panel is sacrificed.
|
|
446
|
+
*/
|
|
447
|
+
function readableHuedOnTintAndPanel(tint, hue, tintFloor, panels, panelFloor, seedChroma) {
|
|
448
|
+
const tintCss = formatCss(tint);
|
|
449
|
+
const panelCss = panels.map((p) => formatCss(p));
|
|
450
|
+
const sweep = (towardDark) => {
|
|
451
|
+
const targetL = towardDark ? 0 : 1;
|
|
452
|
+
const seed = towardDark
|
|
453
|
+
? oklch(tint.l - 0.4, seedChroma, hue)
|
|
454
|
+
: oklch(tint.l + 0.4, seedChroma * 0.667, hue);
|
|
455
|
+
const out = [];
|
|
456
|
+
for (let i = 0; i <= 100; i++) {
|
|
457
|
+
const t = i / 100;
|
|
458
|
+
out.push(formatCss({
|
|
459
|
+
l: seed.l + (targetL - seed.l) * t,
|
|
460
|
+
c: seed.c * (1 - t),
|
|
461
|
+
h: hue,
|
|
462
|
+
alpha: 1,
|
|
463
|
+
}));
|
|
464
|
+
}
|
|
465
|
+
return out;
|
|
466
|
+
};
|
|
467
|
+
const minPanel = (css) => panelCss.length === 0 ? Infinity : Math.min(...panelCss.map((p) => contrast(css, p)));
|
|
468
|
+
let best = null;
|
|
469
|
+
let bestMin = -1;
|
|
470
|
+
for (const towardDark of [true, false]) {
|
|
471
|
+
for (const css of sweep(towardDark)) {
|
|
472
|
+
if (contrast(css, tintCss) < tintFloor)
|
|
473
|
+
continue;
|
|
474
|
+
const m = minPanel(css);
|
|
475
|
+
if (m >= panelFloor)
|
|
476
|
+
return css;
|
|
477
|
+
if (m > bestMin) {
|
|
478
|
+
bestMin = m;
|
|
479
|
+
best = css;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return best ?? readableOnTint(tint, hue, tintFloor);
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* A vivid on-surface tone color: the ink at `hue` carrying `targetChroma` (the tone's own
|
|
487
|
+
* theme-scaled chroma, so it reads as punchy as the solid rather than gamut-max neon, and
|
|
488
|
+
* stays perceptually even across hues) at the lightness that best clears `floor` against
|
|
489
|
+
* every surface in `panels`. Distinct from `-text`, which is muted because it must also read
|
|
490
|
+
* on the soft tint and so overshoots panel contrast at the cost of chroma. Sweeps lightness
|
|
491
|
+
* toward the panels' contrasting pole and keeps the candidate holding the most of the target
|
|
492
|
+
* chroma while clearing the floor — so light mode (dark ink on light panels) stays as punchy
|
|
493
|
+
* as the gamut allows there, not collapsed.
|
|
494
|
+
*/
|
|
495
|
+
function vividOnPanel(hue, panels, floor, targetChroma) {
|
|
496
|
+
const panelCss = panels.map((p) => formatCss(p));
|
|
497
|
+
const minPanel = (css) => panelCss.length === 0 ? Infinity : Math.min(...panelCss.map((p) => contrast(css, p)));
|
|
498
|
+
const avgL = panels.reduce((sum, p) => sum + p.l, 0) / Math.max(1, panels.length);
|
|
499
|
+
const towardLight = avgL < 0.5;
|
|
500
|
+
let best = null;
|
|
501
|
+
let bestChroma = -1;
|
|
502
|
+
for (let i = 0; i <= 80; i++) {
|
|
503
|
+
const t = i / 80;
|
|
504
|
+
const l = towardLight ? 0.5 + t * 0.45 : 0.5 - t * 0.42;
|
|
505
|
+
// In-gamut chroma at this lightness, capped at the target so it never blows out to neon.
|
|
506
|
+
const chroma = clampToGamut(oklch(l, targetChroma, hue)).c;
|
|
507
|
+
const css = formatCss(oklch(l, chroma, hue));
|
|
508
|
+
if (minPanel(css) >= floor && chroma > bestChroma) {
|
|
509
|
+
bestChroma = chroma;
|
|
510
|
+
best = css;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
// No AA-clearing ink at this chroma exists (a mid-gray surface where even the poles
|
|
514
|
+
// barely read); fall back to the most-contrasting achromatic pole.
|
|
515
|
+
return best ?? (towardLight ? "#ffffff" : "#000000");
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* The accent anchor used when no accent is specified (no `--accent` pin and no
|
|
519
|
+
* `anchors.accent`). Deterministic and gamut-safe: rotate the background hue by a
|
|
520
|
+
* fixed angle toward a vivid accent, falling back to a fixed blue when the
|
|
521
|
+
* background (or, secondarily, the foreground) is too achromatic to carry a hue.
|
|
522
|
+
* Lightness and chroma are fixed at vivid-accent values, then gamut-clamped.
|
|
523
|
+
*/
|
|
524
|
+
function deriveAccentAnchor(bg, fg) {
|
|
525
|
+
const sourceHue = bg.c >= ACHROMATIC_CHROMA
|
|
526
|
+
? bg.h
|
|
527
|
+
: fg.c >= ACHROMATIC_CHROMA
|
|
528
|
+
? fg.h
|
|
529
|
+
: undefined;
|
|
530
|
+
const hue = sourceHue === undefined
|
|
531
|
+
? DERIVED_ACCENT_FALLBACK_HUE
|
|
532
|
+
: (((sourceHue + DERIVED_ACCENT_HUE_ROTATION) % 360) + 360) % 360;
|
|
533
|
+
return clampToGamut(oklch(DERIVED_ACCENT_L, DERIVED_ACCENT_C, hue));
|
|
534
|
+
}
|
|
535
|
+
function shadowString(scheme, level, vibrancy, preset) {
|
|
536
|
+
if (level <= 0)
|
|
537
|
+
return "none";
|
|
538
|
+
const baseAlpha = (scheme === "dark" ? 0.5 : 0.16) + vibrancy * 0.1 + preset.elevationAlphaBoost;
|
|
539
|
+
const y = Math.max(1, Math.round(level * 2 * preset.elevationStrengthMul));
|
|
540
|
+
const blur = Math.max(1, Math.round(level * 4 * preset.elevationStrengthMul));
|
|
541
|
+
const spread = Math.max(0, level - 3);
|
|
542
|
+
const alpha = Math.min(0.92, baseAlpha + level * 0.04);
|
|
543
|
+
const ambientY = Math.max(1, Math.round(level / 2));
|
|
544
|
+
const ambientBlur = Math.max(1, Math.round(level * 2 * preset.elevationStrengthMul));
|
|
545
|
+
const ambientAlpha = Math.min(0.7, alpha * 0.6);
|
|
546
|
+
return [
|
|
547
|
+
`0 ${y}px ${blur}px ${spread}px rgba(0, 0, 0, ${alpha.toFixed(2)})`,
|
|
548
|
+
`0 ${ambientY}px ${ambientBlur}px 0 rgba(0, 0, 0, ${ambientAlpha.toFixed(2)})`,
|
|
549
|
+
].join(", ");
|
|
550
|
+
}
|
|
551
|
+
function paletteRamp(register, hue, spec, scheme, vibrancy, floor, preset, accent, panels, pinnedBase) {
|
|
552
|
+
const set = (suffix, color) => {
|
|
553
|
+
register[suffix ? `--color-${hue}-${suffix}` : `--color-${hue}`] = formatCss(color);
|
|
554
|
+
};
|
|
555
|
+
// The component-facing five-token tone family — solid / soft-tint / on-solid ink / on-tint
|
|
556
|
+
// ink / vivid panel ink — re-expressed from the ramp so `tone="pink"` resolves the same shape
|
|
557
|
+
// as `tone="accent"`.
|
|
558
|
+
const family = (solid, bg, fg, text, vivid) => {
|
|
559
|
+
register[`--${hue}`] = solid;
|
|
560
|
+
register[`--${hue}-bg`] = bg;
|
|
561
|
+
register[`--${hue}-fg`] = fg;
|
|
562
|
+
register[`--${hue}-text`] = text;
|
|
563
|
+
register[`--${hue}-vivid`] = vivid;
|
|
564
|
+
};
|
|
565
|
+
const grayscale = (lights, chroma) => {
|
|
566
|
+
const stops = lights.map((l) => oklch(l, chroma, 0));
|
|
567
|
+
const baseStop = stops[2];
|
|
568
|
+
const subtleStop = stops[0];
|
|
569
|
+
const strongStop = liftStopForContrast(stops[3], formatCss(subtleStop), AA + 0.2, stops[3].l >= subtleStop.l);
|
|
570
|
+
// Achromatic inks must stay neutral — a hued ink would read as tinted gray (e.g. blue text on a gray chip).
|
|
571
|
+
const contrast = readableOnTint(baseStop, 0, AA + 0.3, 0);
|
|
572
|
+
set("", baseStop);
|
|
573
|
+
set("subtle", subtleStop);
|
|
574
|
+
set("muted", stops[1]);
|
|
575
|
+
set("base", baseStop);
|
|
576
|
+
set("strong", strongStop);
|
|
577
|
+
register[`--color-${hue}-contrast`] = contrast;
|
|
578
|
+
// Achromatic poles can't read `strong` on `subtle` (same end of the scale), so the soft ink
|
|
579
|
+
// is computed toward the opposite pole instead. Vivid is the readable achromatic ink that
|
|
580
|
+
// clears every panel — chroma 0, so it lands on the contrasting pole.
|
|
581
|
+
family(formatCss(baseStop), formatCss(subtleStop), contrast, readableOnTint(subtleStop, 0, AA + 0.2, 0), vividOnPanel(0, panels, floor, 0));
|
|
582
|
+
};
|
|
583
|
+
if (spec === "white") {
|
|
584
|
+
grayscale([0.82, 0.9, 0.97, 1], 0);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
if (spec === "black") {
|
|
588
|
+
grayscale([0.05, 0.12, 0.2, 0.32], 0);
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
if (spec === "gray") {
|
|
592
|
+
grayscale([0.4, 0.55, 0.68, 0.82], 0.005);
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
// The named hues track the accent's posture: chroma scales with the accent's own chroma
|
|
596
|
+
// about a neutral reference (factor ~1), floored so a near-gray accent still leaves a color
|
|
597
|
+
// recognizable, and the lightness ladder biases gently toward the accent's lightness.
|
|
598
|
+
const accentChromaFactor = Math.max(0.5, Math.min(1.6, accent.c / NEUTRAL_ACCENT_CHROMA));
|
|
599
|
+
const chroma = spec.c * accentChromaFactor * (0.6 + vibrancy * 0.7) * preset.paletteChromaMul;
|
|
600
|
+
const baseL = scheme === "dark" ? 0.7 : 0.55;
|
|
601
|
+
const lBias = Math.max(-0.06, Math.min(0.06, (accent.l - baseL) * 0.25));
|
|
602
|
+
const ladderL = (scheme === "dark" ? [0.45, 0.58, baseL, 0.82] : [0.78, 0.66, baseL, 0.42]).map((l) => Math.max(0.05, Math.min(0.97, l + lBias)));
|
|
603
|
+
const ladderC = [chroma * 0.7, chroma * 0.9, chroma, chroma * 0.85];
|
|
604
|
+
const stops = ladderL.map((l, i) => clampToGamut(oklch(l, ladderC[i], spec.h)));
|
|
605
|
+
const base = stops[2];
|
|
606
|
+
// When the tone solid is pinned, the four-token family is built around the pinned color
|
|
607
|
+
// (its exact value as the solid, its readable ink as the on-solid fg) while the `--color-*`
|
|
608
|
+
// swatch ramp keeps its derived lightness ladder — so a pinned `--green` carries venom into
|
|
609
|
+
// `--green-bg/--green-fg/--green-text`, and the swatch scale stays monotonic.
|
|
610
|
+
const solidBase = pinnedBase ?? base;
|
|
611
|
+
const subtleStop = stops[0];
|
|
612
|
+
const strongStop = liftStopForContrast(stops[3], formatCss(subtleStop), AA + 0.2, stops[3].l >= subtleStop.l);
|
|
613
|
+
const contrast = readableOnTint(solidBase, spec.h, Math.max(floor, AA + 0.3));
|
|
614
|
+
set("", base);
|
|
615
|
+
set("subtle", subtleStop);
|
|
616
|
+
set("muted", stops[1]);
|
|
617
|
+
set("base", base);
|
|
618
|
+
set("strong", strongStop);
|
|
619
|
+
register[`--color-${hue}-contrast`] = contrast;
|
|
620
|
+
// The tone `-bg` is a soft wash near the surface — lightness just off `--bg-0`, a fraction of the
|
|
621
|
+
// tone's chroma — like `--accent-bg`/`--{role}-bg`, not the swatch ramp's `subtle` chip (a
|
|
622
|
+
// recognizable color that reads garish as a full background). `-text` is then derived to clear AA
|
|
623
|
+
// on that wash. The `--color-*` swatch ramp keeps its own `subtle`/`strong` stops for swatches.
|
|
624
|
+
const bg0p = panels[0];
|
|
625
|
+
const washL = scheme === "dark" ? Math.max(0.2, bg0p.l + 0.08) : Math.min(0.92, bg0p.l - 0.04);
|
|
626
|
+
const bgTint = ensureTextHeadroom(oklch(washL, chroma * 0.35, spec.h), scheme, AA + 0.3);
|
|
627
|
+
const bgText = readableHuedOnTintAndPanel(bgTint, spec.h, AA + 0.3, panels.slice(1), AA + 0.05, chroma);
|
|
628
|
+
// vivid carries the tone's own theme-scaled chroma to the panels' contrasting pole.
|
|
629
|
+
family(formatCss(solidBase), formatCss(bgTint), contrast, bgText, vividOnPanel(spec.h, panels, floor, chroma));
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* The honest derivation lineage for a single `derive` invocation: every produced
|
|
633
|
+
* token expressed as a {@link TokenNode} whose `refs` name the tokens it derives
|
|
634
|
+
* from and whose `resolve` recomputes its value. `resolveGraph(buildGraph(preset,
|
|
635
|
+
* opts))` reconstructs the register, so the graph — not a side-channel — is the
|
|
636
|
+
* source of the output. Pinned constraints enter as `value` nodes that downstream
|
|
637
|
+
* tokens reference, preserving the pin re-entry semantics: a dependent re-solves
|
|
638
|
+
* around the pin yet still declares it as a ref.
|
|
639
|
+
*
|
|
640
|
+
* Color tokens whose values depend on contrast-coupled OKLCH math compute through
|
|
641
|
+
* shared intermediates captured in this builder's scope; their `refs` remain
|
|
642
|
+
* honest (they name the anchor / knob / token inputs the math consumed) even
|
|
643
|
+
* though the `resolve` closure returns a precomputed string rather than reparsing
|
|
644
|
+
* its refs. Structural and scale tokens (space / text / radius / fonts / …) are
|
|
645
|
+
* pure functions of their knob inputs.
|
|
646
|
+
*/
|
|
647
|
+
/** A foreground's own lightness implies the room it wants: light ink wants a dark room, dark ink a light one. */
|
|
648
|
+
function schemeFromFg(fg) {
|
|
649
|
+
return fg.l >= 0.5 ? "dark" : "light";
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* A surface synthesized for `scheme` when no background is given: placed at the algorithm's own
|
|
653
|
+
* signature surface depth (so a derived theme keeps the algorithm's contrast character) and washed
|
|
654
|
+
* faintly toward `hue`, with text headroom guaranteed so an ink can always clear it.
|
|
655
|
+
*/
|
|
656
|
+
function deriveSurface(scheme, hue, chroma, depth, floor) {
|
|
657
|
+
const l = scheme === "dark" ? depth : 1 - depth;
|
|
658
|
+
return ensureTextHeadroom(oklch(l, chroma, hue), scheme, floor);
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* The algorithm's base response to *whatever the caller specified* — including nothing. The only
|
|
662
|
+
* explicit inputs are the token values the caller provides; every token left unspecified is derived
|
|
663
|
+
* from the ones that are, never backfilled from a fixed constant. So an accent alone grows a whole
|
|
664
|
+
* room around it (a surface washed toward its hue, an ink for contrast), a foreground alone picks
|
|
665
|
+
* its own scheme and a surface at the opposite pole, and the bare call falls to the algorithm's
|
|
666
|
+
* signature default. A `scheme` knob overrides the inferred pole, flipping a given background's
|
|
667
|
+
* lightness across 0.5 to honor it while keeping its hue and chroma.
|
|
668
|
+
*/
|
|
669
|
+
function completeAnchors(preset, opts) {
|
|
670
|
+
const pin = opts.constraints ?? {};
|
|
671
|
+
// Every seed enters through the one token channel. A provided value of any token seeds the whole
|
|
672
|
+
// derivation — scheme included — with nothing privileged: `--bg-0`/`--fg-0`/`--accent` are simply
|
|
673
|
+
// the three you reach for most, not a separate tier.
|
|
674
|
+
const givenBg = parsePin(pin["--bg-0"]);
|
|
675
|
+
const givenFg = parsePin(pin["--fg-0"]);
|
|
676
|
+
const givenAccent = parsePin(pin["--accent"]);
|
|
677
|
+
const defBg = toOklchColor(preset.defaultAnchors.bg);
|
|
678
|
+
const defFg = toOklchColor(preset.defaultAnchors.fg);
|
|
679
|
+
const defScheme = schemeOf(defBg);
|
|
680
|
+
const surfaceDepth = defScheme === "dark" ? defBg.l : 1 - defBg.l;
|
|
681
|
+
const floor = Math.max(ENFORCE, preset.contrastFloor);
|
|
682
|
+
const inferredScheme = givenBg
|
|
683
|
+
? schemeOf(givenBg)
|
|
684
|
+
: givenFg
|
|
685
|
+
? schemeFromFg(givenFg)
|
|
686
|
+
: defScheme;
|
|
687
|
+
const scheme = opts.knobs?.scheme ?? inferredScheme;
|
|
688
|
+
let bg;
|
|
689
|
+
if (givenBg) {
|
|
690
|
+
bg = scheme === schemeOf(givenBg) ? givenBg : withLightness(givenBg, 1 - givenBg.l);
|
|
691
|
+
}
|
|
692
|
+
else if (givenAccent || givenFg) {
|
|
693
|
+
const hue = givenAccent?.h ?? givenFg.h;
|
|
694
|
+
const tint = givenAccent ? DERIVED_SURFACE_TINT_C : 0.005;
|
|
695
|
+
bg = deriveSurface(scheme, hue, tint, surfaceDepth, floor);
|
|
696
|
+
}
|
|
697
|
+
else {
|
|
698
|
+
bg = scheme === defScheme ? defBg : withLightness(defBg, 1 - defBg.l);
|
|
699
|
+
}
|
|
700
|
+
const fg = givenFg ?? defFg;
|
|
701
|
+
const accentExplicit = givenAccent !== null || preset.defaultAnchors.accent !== undefined;
|
|
702
|
+
const accent = givenAccent ??
|
|
703
|
+
(preset.defaultAnchors.accent
|
|
704
|
+
? toOklchColor(preset.defaultAnchors.accent)
|
|
705
|
+
: deriveAccentAnchor(bg, fg));
|
|
706
|
+
return { bg, fg, accent, scheme, accentExplicit };
|
|
707
|
+
}
|
|
708
|
+
/** A pinned color value parsed to OKLCH, or null if absent / unparseable. */
|
|
709
|
+
function parsePin(value) {
|
|
710
|
+
if (!value)
|
|
711
|
+
return null;
|
|
712
|
+
try {
|
|
713
|
+
const o = toOklchColor(value);
|
|
714
|
+
if (Number.isNaN(o.l) || Number.isNaN(o.c))
|
|
715
|
+
return null;
|
|
716
|
+
return o;
|
|
717
|
+
}
|
|
718
|
+
catch {
|
|
719
|
+
return null;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
/** As {@link parsePin}, but only when the pin carries a usable hue — the gate for re-hueing a derived family around it. */
|
|
723
|
+
function parseChromaticPin(value) {
|
|
724
|
+
const o = parsePin(value);
|
|
725
|
+
if (!o || Number.isNaN(o.h) || o.c < ACHROMATIC_CHROMA)
|
|
726
|
+
return null;
|
|
727
|
+
return o;
|
|
728
|
+
}
|
|
729
|
+
/** The catalog hue angle for a named palette color (achromatic entries report 0). */
|
|
730
|
+
function paletteHueAngle(name) {
|
|
731
|
+
const spec = PALETTE_HUES[name];
|
|
732
|
+
return typeof spec === "object" ? spec.h : 0;
|
|
733
|
+
}
|
|
734
|
+
/** The hue a status role inherits from its named palette color, following a pin on that color. */
|
|
735
|
+
function resolveStatusHue(role, pinned) {
|
|
736
|
+
const name = STATUS_TO_HUE[role] ?? "red";
|
|
737
|
+
const pin = parseChromaticPin(pinned[`--${name}`] ?? pinned[`--color-${name}-base`] ?? pinned[`--color-${name}`]);
|
|
738
|
+
return pin ? pin.h : paletteHueAngle(name);
|
|
739
|
+
}
|
|
740
|
+
export function buildGraph(preset, opts) {
|
|
741
|
+
const completed = completeAnchors(preset, opts);
|
|
742
|
+
const bg = completed.bg;
|
|
743
|
+
const fgAnchor = completed.fg;
|
|
744
|
+
const pinned = opts.constraints ?? {};
|
|
745
|
+
const accent = pinned["--accent"] ? toOklchColor(pinned["--accent"]) : completed.accent;
|
|
746
|
+
const scheme = completed.scheme;
|
|
747
|
+
const knobs = opts.knobs ?? {};
|
|
748
|
+
const shiftStep = typeof knobs.accentShiftStep === "number" ? knobs.accentShiftStep : DEFAULT_SHIFT_STEP;
|
|
749
|
+
const accentSplit = typeof knobs.accentSplit === "number" ? knobs.accentSplit : DEFAULT_ACCENT_SPLIT;
|
|
750
|
+
const band = contrastBandFloor(knobs);
|
|
751
|
+
const floor = Math.max(ENFORCE, preset.contrastFloor, (band ?? 0) + 0.2);
|
|
752
|
+
const extreme = preset.extreme === true;
|
|
753
|
+
let vibrancy = vibrancyOf(knobs, preset);
|
|
754
|
+
if (extreme)
|
|
755
|
+
vibrancy = 1;
|
|
756
|
+
const typeScale = typeScaleOf(knobs);
|
|
757
|
+
const radiusScale = radiusScaleOf(knobs);
|
|
758
|
+
const density = densityOf(knobs);
|
|
759
|
+
const fonts = fontsOf(knobs);
|
|
760
|
+
const surfaceStep = 0.045;
|
|
761
|
+
const nodes = [];
|
|
762
|
+
const lit = (name, value, refs) => {
|
|
763
|
+
nodes.push(refs && refs.length ? { name, value, refs } : { name, value });
|
|
764
|
+
};
|
|
765
|
+
const pinKeys = new Set(Object.keys(pinned));
|
|
766
|
+
const refIfPinned = (...names) => names.filter((n) => pinKeys.has(n));
|
|
767
|
+
lit("--scheme", scheme);
|
|
768
|
+
const bg0 = pinned["--bg-0"]
|
|
769
|
+
? toOklchColor(pinned["--bg-0"])
|
|
770
|
+
: extreme
|
|
771
|
+
? oklch(scheme === "dark" ? 0 : 1, 0, 0)
|
|
772
|
+
: ensureTextHeadroom(withLightness(bg, stepLightness(bg.l, scheme, surfaceStep, 1)), scheme, floor);
|
|
773
|
+
const pageFloor = (fill) => separateFillFromSurface(fill, bg0, SURFACE_SEPARATION, floor);
|
|
774
|
+
const direction = scheme === "dark" ? 1 : -1;
|
|
775
|
+
const surfaceColors = SURFACES.map((_, index) => withLightness(bg0, bg0.l + direction * surfaceStep * (index - 1)));
|
|
776
|
+
SURFACES.forEach((name, index) => {
|
|
777
|
+
lit(name, formatCss(surfaceColors[index]), refIfPinned("--bg-0"));
|
|
778
|
+
});
|
|
779
|
+
lit("--bg-sunken", formatCss(withLightness(bg0, bg0.l - direction * surfaceStep * 2)), refIfPinned("--bg-0"));
|
|
780
|
+
lit("--scrim", formatCss(oklch(scheme === "dark" ? 0 : 0.1, 0, 0, 0.6)));
|
|
781
|
+
const overlayBase = withLightness(bg0, scheme === "dark" ? bg0.l + 0.07 : bg0.l + 0.03);
|
|
782
|
+
lit("--surface-overlay", formatCss(overlayBase), refIfPinned("--bg-0"));
|
|
783
|
+
lit("--surface-overlay-border", formatCss(withAlpha(withLightness(bg0, scheme === "dark" ? bg0.l + 0.25 : bg0.l - 0.2), 0.6)), refIfPinned("--bg-0"));
|
|
784
|
+
const fg0 = pinned["--fg-0"]
|
|
785
|
+
? toOklchColor(pinned["--fg-0"])
|
|
786
|
+
: extreme
|
|
787
|
+
? bestTruePole(formatCss(bg0))
|
|
788
|
+
: enforceContrastFloor(withLightness(fgAnchor, scheme === "dark" ? Math.max(fgAnchor.l, 0.9) : Math.min(fgAnchor.l, 0.2)), bg0, scheme, floor);
|
|
789
|
+
lit("--fg-0", formatCss(fg0), refIfPinned("--bg-0", "--fg-0"));
|
|
790
|
+
const fgBg0Css = formatCss(bg0);
|
|
791
|
+
const fg0Contrast = emittedContrast(fg0, fgBg0Css);
|
|
792
|
+
const panelRef = surfaceColors[PANEL_REF_INDEX];
|
|
793
|
+
const panelRefCss = formatCss(panelRef);
|
|
794
|
+
const panelSurfaces = PANEL_SURFACES.map((s) => surfaceColors[SURFACES.indexOf(s)]);
|
|
795
|
+
const rampFloor = extreme
|
|
796
|
+
? Math.min(fg0Contrast, Math.max(floor, fg0Contrast * 0.66))
|
|
797
|
+
: Math.min(floor, fg0Contrast);
|
|
798
|
+
const conservativeFloorL = (target) => {
|
|
799
|
+
const againstBg0 = lightnessForContrast(fg0, bg0, fgBg0Css, target);
|
|
800
|
+
const againstPanel = lightnessForContrast(fg0, panelRef, panelRefCss, target);
|
|
801
|
+
return Math.abs(againstBg0 - fg0.l) <= Math.abs(againstPanel - fg0.l)
|
|
802
|
+
? againstBg0
|
|
803
|
+
: againstPanel;
|
|
804
|
+
};
|
|
805
|
+
const textLight = scheme === "dark";
|
|
806
|
+
const enforceOnPanels = (color) => {
|
|
807
|
+
const onBg0 = enforceContrastFloor(color, bg0, scheme, floor);
|
|
808
|
+
const sameSidePanels = panelSurfaces.filter((p) => p.l < 0.5 === textLight);
|
|
809
|
+
if (sameSidePanels.length === 0)
|
|
810
|
+
return onBg0;
|
|
811
|
+
const panelCss = sameSidePanels.map((p) => formatCss(p));
|
|
812
|
+
const minPanel = (c) => Math.min(...panelCss.map((p) => emittedContrast(c, p)));
|
|
813
|
+
if (minPanel(onBg0) >= floor - 0.01)
|
|
814
|
+
return onBg0;
|
|
815
|
+
const targetL = textLight ? 1 : 0;
|
|
816
|
+
let best = onBg0;
|
|
817
|
+
let bestMin = minPanel(onBg0);
|
|
818
|
+
for (let i = 1; i <= 100; i++) {
|
|
819
|
+
const t = i / 100;
|
|
820
|
+
const candidate = withLightness(onBg0, onBg0.l + (targetL - onBg0.l) * t);
|
|
821
|
+
if (emittedContrast(candidate, fgBg0Css) < floor - 0.01)
|
|
822
|
+
break;
|
|
823
|
+
const m = minPanel(candidate);
|
|
824
|
+
if (m > bestMin) {
|
|
825
|
+
bestMin = m;
|
|
826
|
+
best = candidate;
|
|
827
|
+
}
|
|
828
|
+
if (m >= floor)
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
return best;
|
|
832
|
+
};
|
|
833
|
+
// Hue-preserving contrast enforcement for brand-toned text tokens (link, accent-text):
|
|
834
|
+
// step lightness toward the readable pole keeping chroma + hue until it clears the floor
|
|
835
|
+
// against bg-0 and the same-side panels. Unlike `enforceOnPanels` — which leans on
|
|
836
|
+
// `sweepToward`'s desaturate-to-gray / true-pole fallback (right for neutral text) — this
|
|
837
|
+
// keeps a vivid accent vivid instead of collapsing it to black on light themes; it only
|
|
838
|
+
// falls back to that floor-guaranteeing path when hue can't survive the required contrast.
|
|
839
|
+
const enforceChromaticOnPanels = (color) => {
|
|
840
|
+
const bg0Css = formatCss(bg0);
|
|
841
|
+
const sameSidePanels = panelSurfaces.filter((p) => p.l < 0.5 === textLight);
|
|
842
|
+
const refsCss = [bg0Css, ...sameSidePanels.map((p) => formatCss(p))];
|
|
843
|
+
const minRef = (c) => Math.min(...refsCss.map((r) => emittedContrast(c, r)));
|
|
844
|
+
if (minRef(color) >= floor - 0.01)
|
|
845
|
+
return color;
|
|
846
|
+
const targetL = textLight ? 1 : 0;
|
|
847
|
+
for (let i = 1; i <= 100; i++) {
|
|
848
|
+
const candidate = withLightness(color, color.l + (targetL - color.l) * (i / 100));
|
|
849
|
+
if (minRef(candidate) >= floor)
|
|
850
|
+
return candidate;
|
|
851
|
+
}
|
|
852
|
+
return enforceOnPanels(color);
|
|
853
|
+
};
|
|
854
|
+
const floorL = conservativeFloorL(rampFloor);
|
|
855
|
+
for (let i = 1; i <= 3; i++) {
|
|
856
|
+
const reduced = withLightness(fg0, fg0.l + (floorL - fg0.l) * (i / 3));
|
|
857
|
+
lit(`--fg-${i}`, formatCss(reduced), ["--fg-0", ...refIfPinned("--bg-0")]);
|
|
858
|
+
}
|
|
859
|
+
lit("--fg-disabled", formatCss(withLightness(fg0, conservativeFloorL(3))), ["--fg-0", ...refIfPinned("--bg-0")]);
|
|
860
|
+
const placeholderFloor = extreme ? rampFloor : Math.min(floor, fg0Contrast);
|
|
861
|
+
const placeholderL = conservativeFloorL(placeholderFloor);
|
|
862
|
+
lit("--placeholder", formatCss(withLightness(fg0, placeholderL)), ["--fg-0", ...refIfPinned("--bg-0")]);
|
|
863
|
+
// A chosen accent (provided or baked) is honored verbatim — the algorithm's taste lands in the
|
|
864
|
+
// expansion around it, not in overriding the color. Only a synthesized accent is shaped: scaled
|
|
865
|
+
// to the algorithm's chroma and floored for separation, since it is a guess that should read well.
|
|
866
|
+
const accentFill = pinned["--accent"] || completed.accentExplicit
|
|
867
|
+
? accent
|
|
868
|
+
: pageFloor(fillWithTextHeadroom(accent.l, accent.c * (0.6 + vibrancy * 0.8) * preset.accentChromaMul, accent.h, floor));
|
|
869
|
+
const accentValue = pinned["--accent"] ?? formatCss(accentFill);
|
|
870
|
+
lit("--accent", accentValue, refIfPinned("--accent"));
|
|
871
|
+
lit("--accent-fg", pickReadable(accentFill, TEXT_POLES, floor), ["--accent"]);
|
|
872
|
+
const accentTextColor = enforceChromaticOnPanels(accentFill);
|
|
873
|
+
const accentTextCss = formatCss(accentTextColor);
|
|
874
|
+
// The soft tint must read against the very ink the soft variant paints on it, so derive the
|
|
875
|
+
// tint to clear AA against `--accent-text` (nudging its lightness away from the ink), rather
|
|
876
|
+
// than leaving the pairing to chance.
|
|
877
|
+
const accentTint = liftStopForContrast(oklch(scheme === "dark" ? Math.max(0.2, bg0.l + 0.08) : Math.min(0.92, bg0.l - 0.04), accentFill.c * preset.accentTintChromaMul, accentFill.h), accentTextCss, AA + 0.2, accentTextColor.l < 0.5);
|
|
878
|
+
lit("--accent-bg", formatCss(accentTint), ["--accent", ...refIfPinned("--bg-0")]);
|
|
879
|
+
lit("--accent-text", accentTextCss, ["--accent", ...refIfPinned("--bg-0")]);
|
|
880
|
+
lit("--accent-vivid", vividOnPanel(accentFill.h, [bg0, ...panelSurfaces], floor, accentFill.c), ["--accent", ...refIfPinned("--bg-0")]);
|
|
881
|
+
const pinnedNeutral = parsePin(pinned["--neutral"]);
|
|
882
|
+
const neutralFill = pinnedNeutral ??
|
|
883
|
+
pageFloor(fillWithTextHeadroom(scheme === "dark" ? 0.6 : 0.5, preset.neutralChroma, accentFill.h, floor));
|
|
884
|
+
const neutralTintHue = Number.isFinite(neutralFill.h) ? neutralFill.h : accentFill.h;
|
|
885
|
+
lit("--neutral", formatCss(neutralFill), ["--accent", ...refIfPinned("--neutral")]);
|
|
886
|
+
const neutralTextColor = enforceOnPanels(neutralFill);
|
|
887
|
+
const neutralTextCss = formatCss(neutralTextColor);
|
|
888
|
+
const neutralTint = liftStopForContrast(oklch(scheme === "dark" ? Math.max(0.2, bg0.l + 0.06) : Math.min(0.92, bg0.l - 0.04), 0.005, neutralTintHue), neutralTextCss, AA + 0.2, neutralTextColor.l < 0.5);
|
|
889
|
+
lit("--neutral-bg", formatCss(neutralTint), ["--accent", ...refIfPinned("--bg-0")]);
|
|
890
|
+
lit("--neutral-fg", pickReadable(neutralFill, TEXT_POLES, floor), ["--neutral"]);
|
|
891
|
+
lit("--neutral-text", neutralTextCss, ["--neutral", ...refIfPinned("--bg-0")]);
|
|
892
|
+
lit("--neutral-vivid", neutralTextCss, ["--neutral-text", ...refIfPinned("--bg-0")]);
|
|
893
|
+
const lineSeed = extreme
|
|
894
|
+
? oklch(scheme === "dark" ? 0.7 : 0.3, 0, 0)
|
|
895
|
+
: withLightness(bg0, scheme === "dark" ? bg0.l + 0.12 : bg0.l - 0.12);
|
|
896
|
+
lit("--line", formatCss(borderForContrast(lineSeed, bg0, BORDER_SEPARATION)), refIfPinned("--bg-0"));
|
|
897
|
+
const line2Seed = extreme
|
|
898
|
+
? oklch(scheme === "dark" ? 0.85 : 0.15, 0, 0)
|
|
899
|
+
: withLightness(bg0, scheme === "dark" ? bg0.l + 0.2 : bg0.l - 0.2);
|
|
900
|
+
lit("--line-2", formatCss(borderForContrast(line2Seed, bg0, DIVIDER_SEPARATION)), refIfPinned("--bg-0"));
|
|
901
|
+
lit("--ring", formatCss(withAlpha(accentFill, 0.7)), ["--accent"]);
|
|
902
|
+
lit("--ring-bg", formatCss(withAlpha(accentFill, 0.18)), ["--accent"]);
|
|
903
|
+
const fieldBg = withLightness(bg0, scheme === "dark" ? bg0.l - 0.03 : bg0.l + 0.02);
|
|
904
|
+
lit("--field-bg", formatCss(fieldBg), refIfPinned("--bg-0"));
|
|
905
|
+
const fieldBorderSeed = extreme
|
|
906
|
+
? oklch(scheme === "dark" ? 0.8 : 0.2, 0, 0)
|
|
907
|
+
: withLightness(bg0, scheme === "dark" ? bg0.l + 0.16 : bg0.l - 0.16);
|
|
908
|
+
lit("--field-border", formatCss(borderForContrast(fieldBorderSeed, fieldBg, BORDER_SEPARATION)), refIfPinned("--bg-0"));
|
|
909
|
+
lit("--accent-hover", formatCss(withLightness(accentFill, accentFill.l + (scheme === "dark" ? 0.06 : -0.06))), ["--accent"]);
|
|
910
|
+
lit("--accent-active", formatCss(withLightness(accentFill, accentFill.l + (scheme === "dark" ? -0.06 : 0.06))), ["--accent"]);
|
|
911
|
+
const accentDisplay = toOklchColor(accentValue);
|
|
912
|
+
const accentDelta = (from, to) => ({
|
|
913
|
+
dL: to.l - from.l,
|
|
914
|
+
dC: to.c - from.c,
|
|
915
|
+
dH: hueDelta(from.h, to.h),
|
|
916
|
+
});
|
|
917
|
+
const applyAccentDelta = (from, delta) => {
|
|
918
|
+
const rawL = from.l + delta.dL;
|
|
919
|
+
const l = delta.dL === 0
|
|
920
|
+
? Math.min(1, Math.max(0, rawL))
|
|
921
|
+
: Math.min(ACCENT_RAMP_L_MAX, Math.max(ACCENT_RAMP_L_MIN, rawL));
|
|
922
|
+
return {
|
|
923
|
+
l,
|
|
924
|
+
c: Math.max(0, from.c + delta.dC),
|
|
925
|
+
h: (((from.h + delta.dH) % 360) + 360) % 360,
|
|
926
|
+
alpha: 1,
|
|
927
|
+
};
|
|
928
|
+
};
|
|
929
|
+
const emitAccent = (color) => {
|
|
930
|
+
const maxC = clampToGamut({ l: color.l, c: color.c, h: color.h, alpha: 1 }).c;
|
|
931
|
+
return formatCss({ ...color, c: Math.min(color.c, maxC) });
|
|
932
|
+
};
|
|
933
|
+
const a1 = accentDisplay;
|
|
934
|
+
const fanBase = { ...a1, c: Math.max(a1.c, FAN_MIN_CHROMA) };
|
|
935
|
+
const rotate = (deg) => ({ dL: 0, dC: 0, dH: deg });
|
|
936
|
+
const fanned = (n, derived) => pinned[`--accent-${n}`] ? toOklchColor(pinned[`--accent-${n}`]) : derived;
|
|
937
|
+
let a2;
|
|
938
|
+
let a3;
|
|
939
|
+
let a4;
|
|
940
|
+
// The lineage edges differ per fan: a split-complement's 2/3 flank the accent and 4 is its
|
|
941
|
+
// complement (all off `--accent`, so a pinned flank pulls its mirror in), while a wheel chains
|
|
942
|
+
// 3 off 2 and 4 off 3. Declared per-branch so `lineage()` names what each token actually reads.
|
|
943
|
+
let a2Refs;
|
|
944
|
+
let a3Refs;
|
|
945
|
+
let a4Refs;
|
|
946
|
+
if (ACCENT_FAN === "split-complement") {
|
|
947
|
+
// The two flanks are symmetric either way: pin either wing and the other mirrors its hue
|
|
948
|
+
// across the accent, so the fan stays balanced around the author's choice. With neither
|
|
949
|
+
// pinned it's the default ∓split; with both pinned each holds its own value. Lightness and
|
|
950
|
+
// chroma stay the fan base's throughout, per the constant-L/C fan.
|
|
951
|
+
const mirrorOf = (c) => applyAccentDelta(fanBase, rotate(-hueDelta(a1.h, c.h)));
|
|
952
|
+
const a2Pin = pinned["--accent-2"];
|
|
953
|
+
const a3Pin = pinned["--accent-3"];
|
|
954
|
+
let a2Derived = applyAccentDelta(fanBase, rotate(-accentSplit));
|
|
955
|
+
let a3Derived = applyAccentDelta(fanBase, rotate(accentSplit));
|
|
956
|
+
if (a2Pin && !a3Pin)
|
|
957
|
+
a3Derived = mirrorOf(toOklchColor(a2Pin));
|
|
958
|
+
else if (a3Pin && !a2Pin)
|
|
959
|
+
a2Derived = mirrorOf(toOklchColor(a3Pin));
|
|
960
|
+
a2 = fanned("2", a2Derived);
|
|
961
|
+
a3 = fanned("3", a3Derived);
|
|
962
|
+
a4 = fanned("4", applyAccentDelta(fanBase, rotate(180)));
|
|
963
|
+
a2Refs = a3Pin && !a2Pin ? ["--accent", "--accent-3"] : ["--accent"];
|
|
964
|
+
a3Refs = a2Pin && !a3Pin ? ["--accent", "--accent-2"] : ["--accent"];
|
|
965
|
+
a4Refs = ["--accent"];
|
|
966
|
+
}
|
|
967
|
+
else {
|
|
968
|
+
// Each accent is one hue-step past the last. Chaining off `fanBase` (not `a1`) keeps the whole
|
|
969
|
+
// wheel at the floored chroma for a near-gray accent instead of escalating it down the chain; a
|
|
970
|
+
// chromatic accent has `fanBase === a1`, so the step stays byte-identical.
|
|
971
|
+
a2 = fanned("2", applyAccentDelta(fanBase, rotate(shiftStep)));
|
|
972
|
+
a3 = fanned("3", applyAccentDelta(a2, accentDelta(fanBase, a2)));
|
|
973
|
+
a4 = fanned("4", applyAccentDelta(a3, accentDelta(a2, a3)));
|
|
974
|
+
a2Refs = ["--accent", "--accent-shift-step"];
|
|
975
|
+
a3Refs = ["--accent-2", "--accent"];
|
|
976
|
+
a4Refs = ["--accent-3", "--accent-2"];
|
|
977
|
+
}
|
|
978
|
+
lit("--accent-2", emitAccent(a2), a2Refs);
|
|
979
|
+
lit("--accent-3", emitAccent(a3), a3Refs);
|
|
980
|
+
lit("--accent-4", emitAccent(a4), a4Refs);
|
|
981
|
+
lit("--accent-shift-step", String(shiftStep));
|
|
982
|
+
// Give each accent-ramp variant the same four-token family the primary accent has, so an
|
|
983
|
+
// `accent-3` button / rail reads the same way an `accent` one does — derived, not hand-tuned.
|
|
984
|
+
const emitAccentFamily = (n, raw) => {
|
|
985
|
+
const color = toOklchColor(emitAccent(raw));
|
|
986
|
+
lit(`--accent-${n}-fg`, pickReadable(color, TEXT_POLES, floor), [`--accent-${n}`]);
|
|
987
|
+
const tint = oklch(scheme === "dark" ? Math.max(0.2, bg0.l + 0.08) : Math.min(0.92, bg0.l - 0.04), color.c * preset.accentTintChromaMul, color.h);
|
|
988
|
+
lit(`--accent-${n}-bg`, formatCss(tint), [`--accent-${n}`, ...refIfPinned("--bg-0")]);
|
|
989
|
+
lit(`--accent-${n}-text`, readableHuedOnTintAndPanel(tint, color.h, AA + 0.3, panelSurfaces, AA + 0.05, color.c), [`--accent-${n}-bg`, ...refIfPinned("--bg-0")]);
|
|
990
|
+
lit(`--accent-${n}-vivid`, vividOnPanel(color.h, [bg0, ...panelSurfaces], floor, color.c), [`--accent-${n}`, ...refIfPinned("--bg-0")]);
|
|
991
|
+
};
|
|
992
|
+
emitAccentFamily("2", a2);
|
|
993
|
+
emitAccentFamily("3", a3);
|
|
994
|
+
emitAccentFamily("4", a4);
|
|
995
|
+
lit("--selection-cue", extreme || knobs.cues === "redundant" ? "marker" : "tint");
|
|
996
|
+
const statusChroma = Math.max(0.12, accent.c) * (0.6 + vibrancy * 0.7) * preset.statusChromaMul;
|
|
997
|
+
for (const role of Object.keys(STATUS_TO_HUE)) {
|
|
998
|
+
// The role's hue comes from its named palette color (danger←red, success←green,
|
|
999
|
+
// warn←orange, info←blue), following a pin on that color — so a re-hued red moves danger.
|
|
1000
|
+
// A direct pin on the status fill still wins: it drives its own tint and inks at the
|
|
1001
|
+
// pin's hue, so a pinned `--danger` carries through `--danger-bg/--danger-fg/--danger-text`.
|
|
1002
|
+
const namedHue = resolveStatusHue(role, pinned);
|
|
1003
|
+
const pinnedFill = parseChromaticPin(pinned[`--${role}`]);
|
|
1004
|
+
const roleHue = pinnedFill ? pinnedFill.h : namedHue;
|
|
1005
|
+
const fillL = scheme === "dark" ? 0.62 : 0.52;
|
|
1006
|
+
const fill = pinnedFill ?? pageFloor(fillWithTextHeadroom(fillL, statusChroma, roleHue, floor));
|
|
1007
|
+
const tintL = scheme === "dark" ? Math.min(0.3, bg0.l + 0.08) : Math.min(0.92, bg0.l - 0.04);
|
|
1008
|
+
const tint = ensureTextHeadroom(oklch(tintL, statusChroma * 0.35, roleHue), scheme, AA + 0.3);
|
|
1009
|
+
const fillRefs = refIfPinned("--accent", `--${role}`);
|
|
1010
|
+
lit(`--${role}`, formatCss(fill), fillRefs);
|
|
1011
|
+
lit(`--${role}-bg`, formatCss(tint), [`--${role}`, ...refIfPinned("--bg-0")]);
|
|
1012
|
+
lit(`--${role}-fg`, pickReadable(fill, TEXT_POLES, floor), [`--${role}`]);
|
|
1013
|
+
lit(`--${role}-text`, readableHuedOnTintAndPanel(tint, roleHue, AA + 0.3, panelSurfaces, AA + 0.05, statusChroma), [`--${role}-bg`, ...refIfPinned("--bg-0")]);
|
|
1014
|
+
lit(`--${role}-vivid`, vividOnPanel(roleHue, [bg0, ...panelSurfaces], floor, statusChroma), [`--${role}`, ...refIfPinned("--bg-0")]);
|
|
1015
|
+
}
|
|
1016
|
+
const overlayL = scheme === "dark" ? 1 : 0;
|
|
1017
|
+
// A flat-alpha tint reads weakest where the surface sits closest to the overlay's
|
|
1018
|
+
// opposite pole — 6% white over near-black (or black over near-white) barely registers
|
|
1019
|
+
// (measured ~1.10:1 vs ~1.19:1 on a mid-range dark bg). Boost the alpha as the bg anchor
|
|
1020
|
+
// approaches that extreme so hover/press/selected keep a perceptible step; mid-range
|
|
1021
|
+
// themes are untouched (boost = 1).
|
|
1022
|
+
const extremeDist = scheme === "dark" ? bg0.l : 1 - bg0.l;
|
|
1023
|
+
const overlayBoost = 1 + Math.max(0, (0.15 - extremeDist) / 0.15) * 0.8;
|
|
1024
|
+
const overlay = (a) => formatCss(oklch(overlayL, 0, 0, Math.min(0.4, a * overlayBoost)));
|
|
1025
|
+
lit("--state-hover", overlay(0.06));
|
|
1026
|
+
lit("--state-press", overlay(0.12));
|
|
1027
|
+
lit("--state-selected", overlay(0.16));
|
|
1028
|
+
lit("--state-disabled", overlay(0.08));
|
|
1029
|
+
lit("--state-drag", overlay(0.1));
|
|
1030
|
+
lit("--selection", formatCss(withAlpha(accentFill, 0.3)), ["--accent"]);
|
|
1031
|
+
lit("--highlight", formatCss(withAlpha(oklch(scheme === "dark" ? 0.85 : 0.9, 0.16, paletteHueAngle("yellow")), 0.35)));
|
|
1032
|
+
const linkColor = enforceChromaticOnPanels(accent);
|
|
1033
|
+
const linkCss = formatCss(linkColor);
|
|
1034
|
+
let linkHoverColor = enforceChromaticOnPanels(withLightness(accent, accent.l + (scheme === "dark" ? 0.08 : -0.08)));
|
|
1035
|
+
if (formatCss(linkHoverColor) === linkCss) {
|
|
1036
|
+
// The base hover step collapsed onto the link. Two causes: a low-chroma accent has no hue to
|
|
1037
|
+
// keep them apart once enforcement pulls both to the same readable lightness; a high-chroma
|
|
1038
|
+
// accent pinned near a lightness pole has its step erased by gamut clamping (both lightnesses
|
|
1039
|
+
// clamp to one displayable hex). Force a distinct emitted value, re-enforcing each candidate so
|
|
1040
|
+
// it always lands readable: grow the step toward the readable pole (the natural hover feel);
|
|
1041
|
+
// if the pole clamps every step to one hex, nudge the other way (there is headroom off an
|
|
1042
|
+
// extreme); if lightness is pinned at a pole for this hue, drop chroma so the value shifts.
|
|
1043
|
+
const pole = textLight ? 1 : 0;
|
|
1044
|
+
const toward = linkColor.l < pole ? 1 : -1;
|
|
1045
|
+
const distinctHover = (candidate) => {
|
|
1046
|
+
const enforced = enforceChromaticOnPanels(candidate);
|
|
1047
|
+
return formatCss(enforced) === linkCss ? undefined : enforced;
|
|
1048
|
+
};
|
|
1049
|
+
let hover;
|
|
1050
|
+
for (let step = 0.1; step <= 0.6 && !hover; step += 0.05) {
|
|
1051
|
+
hover = distinctHover(withLightness(linkColor, linkColor.l + toward * step));
|
|
1052
|
+
}
|
|
1053
|
+
for (let step = 0.1; step <= 0.6 && !hover; step += 0.05) {
|
|
1054
|
+
hover = distinctHover(withLightness(linkColor, linkColor.l - toward * step));
|
|
1055
|
+
}
|
|
1056
|
+
for (let cut = 0.7; cut >= 0.05 && !hover; cut -= 0.15) {
|
|
1057
|
+
hover = distinctHover(oklch(linkColor.l, linkColor.c * cut, linkColor.h));
|
|
1058
|
+
}
|
|
1059
|
+
linkHoverColor = hover ?? linkHoverColor;
|
|
1060
|
+
}
|
|
1061
|
+
lit("--link", formatCss(linkColor), ["--accent", ...refIfPinned("--bg-0")]);
|
|
1062
|
+
lit("--link-hover", formatCss(linkHoverColor), ["--link", ...refIfPinned("--bg-0")]);
|
|
1063
|
+
for (const [hue, spec] of Object.entries(PALETTE_HUES)) {
|
|
1064
|
+
// Pinning the tone solid (or its swatch base) re-hues the whole derived family around it,
|
|
1065
|
+
// so the soft tint and inks track the pin instead of the generic catalog hue.
|
|
1066
|
+
const pinnedBase = typeof spec === "object"
|
|
1067
|
+
? parseChromaticPin(pinned[`--${hue}`] ?? pinned[`--color-${hue}-base`] ?? pinned[`--color-${hue}`])
|
|
1068
|
+
: null;
|
|
1069
|
+
const effectiveSpec = pinnedBase && typeof spec === "object" ? { h: pinnedBase.h, c: pinnedBase.c } : spec;
|
|
1070
|
+
const ramp = {};
|
|
1071
|
+
paletteRamp(ramp, hue, effectiveSpec, scheme, vibrancy, floor, preset, accent, [bg0, ...panelSurfaces], pinnedBase ?? undefined);
|
|
1072
|
+
lit(`--color-${hue}`, ramp[`--color-${hue}`]);
|
|
1073
|
+
for (const stop of PALETTE_STOPS) {
|
|
1074
|
+
lit(`--color-${hue}-${stop}`, ramp[`--color-${hue}-${stop}`], [
|
|
1075
|
+
`--color-${hue}`,
|
|
1076
|
+
]);
|
|
1077
|
+
}
|
|
1078
|
+
lit(`--${hue}`, ramp[`--${hue}`], [`--color-${hue}-base`]);
|
|
1079
|
+
lit(`--${hue}-bg`, ramp[`--${hue}-bg`], [`--color-${hue}-subtle`]);
|
|
1080
|
+
lit(`--${hue}-fg`, ramp[`--${hue}-fg`], [`--color-${hue}-base`]);
|
|
1081
|
+
lit(`--${hue}-text`, ramp[`--${hue}-text`], [`--color-${hue}-subtle`]);
|
|
1082
|
+
lit(`--${hue}-vivid`, ramp[`--${hue}-vivid`], [
|
|
1083
|
+
`--color-${hue}-base`,
|
|
1084
|
+
...refIfPinned("--bg-0"),
|
|
1085
|
+
]);
|
|
1086
|
+
}
|
|
1087
|
+
const codeBg = ensureTextHeadroom(withLightness(bg0, scheme === "dark" ? bg0.l - 0.02 : bg0.l + 0.012), scheme, floor);
|
|
1088
|
+
const codeBgCss = formatCss(codeBg);
|
|
1089
|
+
lit("--code-bg", codeBgCss, refIfPinned("--bg-0"));
|
|
1090
|
+
const codeFg = enforceContrastFloor(fg0, codeBg, scheme, floor);
|
|
1091
|
+
const codeFgCss = formatCss(codeFg);
|
|
1092
|
+
lit("--code-fg", codeFgCss, ["--fg-0", ...refIfPinned("--bg-0")]);
|
|
1093
|
+
lit("--code-line-highlight", formatCss(withAlpha(accentFill, 0.1)), ["--accent"]);
|
|
1094
|
+
lit("--code-selection", formatCss(withAlpha(accentFill, 0.3)), ["--accent"]);
|
|
1095
|
+
// The readable ink direction follows the editor surface itself, not the page
|
|
1096
|
+
// scheme — a vivid mid-lightness `--code-bg` (e.g. a saturated brand panel) can
|
|
1097
|
+
// invert which pole reads, and sweeping the wrong way collapses the palette.
|
|
1098
|
+
const codeTowardLight = contrast("#ffffff", codeBgCss) >= contrast("#000000", codeBgCss);
|
|
1099
|
+
const codePole = codeTowardLight ? 1 : 0;
|
|
1100
|
+
const codeFloor = AA;
|
|
1101
|
+
const readableHuedOnCode = (l, c, h, fl) => {
|
|
1102
|
+
const seed = oklch(l, c, h);
|
|
1103
|
+
let best = seed;
|
|
1104
|
+
let bestContrast = emittedContrast(seed, codeBgCss);
|
|
1105
|
+
if (bestContrast >= fl)
|
|
1106
|
+
return seed;
|
|
1107
|
+
for (let i = 1; i <= 100; i++) {
|
|
1108
|
+
const cand = withLightness(seed, seed.l + (codePole - seed.l) * (i / 100));
|
|
1109
|
+
const ct = emittedContrast(cand, codeBgCss);
|
|
1110
|
+
if (ct >= fl)
|
|
1111
|
+
return cand;
|
|
1112
|
+
if (ct > bestContrast) {
|
|
1113
|
+
bestContrast = ct;
|
|
1114
|
+
best = cand;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
return best;
|
|
1118
|
+
};
|
|
1119
|
+
const codeChroma = Math.max(0.08, Math.max(0.1, accent.c) * (0.7 + vibrancy * 0.7) * preset.paletteChromaMul);
|
|
1120
|
+
// A near-gray accent has no hue to anchor the spread to, so seed the code wheel
|
|
1121
|
+
// from the fallback hue rather than letting `NaN` collapse every scope to one ink.
|
|
1122
|
+
const codeBaseHue = Number.isFinite(accent.h) ? accent.h : DERIVED_ACCENT_FALLBACK_HUE;
|
|
1123
|
+
const codeBaseL = codeTowardLight ? 0.76 : 0.46;
|
|
1124
|
+
// Place the vivid scopes inside the lightness band where `--code-bg` already
|
|
1125
|
+
// clears AA toward its readable pole, rather than letting each scope sweep there
|
|
1126
|
+
// independently — independent sweeps converge in lightness and collapse the
|
|
1127
|
+
// palette on a tight bg. Spreading distinct lightnesses across the achievable
|
|
1128
|
+
// band keeps neighbours separable by construction, by as much as the bg affords.
|
|
1129
|
+
const codePoleL = codeTowardLight ? 1 : 0;
|
|
1130
|
+
const aaEdgeL = lightnessForContrast(oklch(codePoleL, 0, 0), codeBg, codeBgCss, codeFloor);
|
|
1131
|
+
// Keep the band clear of the pole: near the pole gamut-clamping kills chroma, so
|
|
1132
|
+
// the brightest scopes would desaturate into the neutral plain-text ink.
|
|
1133
|
+
const bandLo = aaEdgeL + (codePoleL - aaEdgeL) * 0.06;
|
|
1134
|
+
const bandHi = codePoleL - (codePoleL - aaEdgeL) * 0.32;
|
|
1135
|
+
CODE_VIVID_ROLES.forEach((role, rank) => {
|
|
1136
|
+
const hue = (((codeBaseHue + CODE_HUE_RANK[rank] * 45) % 360) + 360) % 360;
|
|
1137
|
+
const bandL = bandLo + (bandHi - bandLo) * (rank / 7);
|
|
1138
|
+
const fill = readableHuedOnCode(bandL, codeChroma, hue, codeFloor);
|
|
1139
|
+
lit(`--code-${role}`, formatCss(fill), ["--accent", "--code-bg"]);
|
|
1140
|
+
});
|
|
1141
|
+
// Large-text floor (3:1) so comments recede without vanishing.
|
|
1142
|
+
const commentFloor = Math.max(3, codeFloor * 0.62);
|
|
1143
|
+
const commentL = codeTowardLight ? 0.6 : 0.56;
|
|
1144
|
+
lit("--code-comment", formatCss(readableHuedOnCode(commentL, Math.min(0.03, codeChroma * 0.3), codeBaseHue, commentFloor)), ["--accent", "--code-bg"]);
|
|
1145
|
+
lit("--code-operator", formatCss(readableHuedOnCode(codeBaseL, codeChroma * 0.5, codeBaseHue, codeFloor)), ["--accent", "--code-bg"]);
|
|
1146
|
+
lit("--code-punctuation", formatCss(enforceContrastFloor(withLightness(codeFg, codeFg.l + (codePole - codeFg.l) * 0.18), codeBg, scheme, codeFloor)), ["--code-fg", "--code-bg"]);
|
|
1147
|
+
lit("--code-variable", codeFgCss, ["--code-fg"]);
|
|
1148
|
+
lit("--font-sans", fonts.sans);
|
|
1149
|
+
lit("--font-mono", fonts.mono);
|
|
1150
|
+
lit("--font-display", fonts.display);
|
|
1151
|
+
const bodyIndex = TEXT_STEPS.indexOf("body");
|
|
1152
|
+
TEXT_STEPS.forEach((step, index) => {
|
|
1153
|
+
const rem = BASE_TEXT_REM * typeScale ** (index - bodyIndex);
|
|
1154
|
+
lit(`--text-${step}`, `${rem.toFixed(4).replace(/\.?0+$/, "")}rem`);
|
|
1155
|
+
});
|
|
1156
|
+
for (const step of LEADING_STEPS) {
|
|
1157
|
+
lit(`--leading-${step}`, String(LEADING_VALUES[step]));
|
|
1158
|
+
}
|
|
1159
|
+
for (const step of WEIGHT_STEPS) {
|
|
1160
|
+
lit(`--weight-${step}`, String(WEIGHT_VALUES[step]));
|
|
1161
|
+
}
|
|
1162
|
+
const radiusPx = {
|
|
1163
|
+
none: 0,
|
|
1164
|
+
sm: 2 * radiusScale,
|
|
1165
|
+
md: 4 * radiusScale,
|
|
1166
|
+
lg: 8 * radiusScale,
|
|
1167
|
+
full: 9999,
|
|
1168
|
+
};
|
|
1169
|
+
for (const step of RADIUS_STEPS) {
|
|
1170
|
+
lit(`--radius-${step}`, `${radiusPx[step]}px`);
|
|
1171
|
+
}
|
|
1172
|
+
const borderPx = { thin: 1, normal: 1.5, thick: 2 };
|
|
1173
|
+
for (const step of BORDER_STEPS) {
|
|
1174
|
+
lit(`--border-${step}`, `${borderPx[step]}px`);
|
|
1175
|
+
}
|
|
1176
|
+
const durationMs = { fast: 120, base: 200, slow: 320 };
|
|
1177
|
+
for (const step of DURATION_STEPS) {
|
|
1178
|
+
lit(`--duration-${step}`, `${durationMs[step]}ms`);
|
|
1179
|
+
}
|
|
1180
|
+
lit("--ease-standard", "cubic-bezier(0.2, 0, 0, 1)");
|
|
1181
|
+
lit("--ease-emphasized", "cubic-bezier(0.3, 0, 0, 1)");
|
|
1182
|
+
const elevationStrings = {};
|
|
1183
|
+
for (const level of ELEVATION_STEPS) {
|
|
1184
|
+
const value = shadowString(scheme, level, vibrancy, preset);
|
|
1185
|
+
elevationStrings[level] = value;
|
|
1186
|
+
lit(`--elevation-${level}`, value);
|
|
1187
|
+
}
|
|
1188
|
+
lit("--shadow", elevationStrings[3], ["--elevation-3"]);
|
|
1189
|
+
for (const step of SPACE_STEPS) {
|
|
1190
|
+
const rem = SPACE_BASE_REM * step * density;
|
|
1191
|
+
lit(`--space-${step}`, `${rem.toFixed(4).replace(/\.?0+$/, "")}rem`);
|
|
1192
|
+
}
|
|
1193
|
+
const producedNames = new Set(nodes.map((n) => n.name));
|
|
1194
|
+
for (const [name, value] of Object.entries(pinned)) {
|
|
1195
|
+
if (producedNames.has(name)) {
|
|
1196
|
+
for (const node of nodes) {
|
|
1197
|
+
if (node.name === name) {
|
|
1198
|
+
node.value = value;
|
|
1199
|
+
node.resolve = undefined;
|
|
1200
|
+
node.refs = undefined;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
else {
|
|
1205
|
+
nodes.push({ name, value });
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
return nodes;
|
|
1209
|
+
}
|
|
1210
|
+
/**
|
|
1211
|
+
* The resolved base inputs a derivation reads, factored so both `buildGraph` and the
|
|
1212
|
+
* pipeline's per-pass {@link PassContext} agree on anchors / scheme / pins for an
|
|
1213
|
+
* identical request. Mirrors the head of {@link buildGraph}.
|
|
1214
|
+
*/
|
|
1215
|
+
export function resolveBaseInputs(preset, opts) {
|
|
1216
|
+
const completed = completeAnchors(preset, opts);
|
|
1217
|
+
return {
|
|
1218
|
+
knobs: opts.knobs ?? {},
|
|
1219
|
+
scheme: completed.scheme,
|
|
1220
|
+
pinned: opts.constraints ?? {},
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
export function buildPassContext(preset, opts, passIndex) {
|
|
1224
|
+
const base = resolveBaseInputs(preset, opts);
|
|
1225
|
+
return { ...base, passIndex };
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* The shared pipeline runner every construction path uses, so baked and hosted forms
|
|
1229
|
+
* run the identical pass code. The first pass receives an empty register and produces
|
|
1230
|
+
* the base; each later pass transforms the register it is handed. Returns the final
|
|
1231
|
+
* register and a snapshot after every pass (snapshot count === pass count).
|
|
1232
|
+
*/
|
|
1233
|
+
export function runPipeline(passes, makeCtx) {
|
|
1234
|
+
let register = {};
|
|
1235
|
+
const trace = [];
|
|
1236
|
+
passes.forEach((pass, index) => {
|
|
1237
|
+
register = pass.run(register, makeCtx(index));
|
|
1238
|
+
trace.push({ name: pass.name, register });
|
|
1239
|
+
});
|
|
1240
|
+
return { register, trace };
|
|
1241
|
+
}
|
|
1242
|
+
/**
|
|
1243
|
+
* The base pass for the xtyle family: the whole current graph derivation expressed as
|
|
1244
|
+
* pass one. It ignores the incoming register and rebuilds from `opts` so the pin
|
|
1245
|
+
* re-entry and tail constraint sweep in {@link buildGraph} stay intact — making the
|
|
1246
|
+
* four shipped algorithms strictly single-pass and byte-identical to today.
|
|
1247
|
+
*/
|
|
1248
|
+
export function settlePass(preset, opts) {
|
|
1249
|
+
return {
|
|
1250
|
+
name: "settle",
|
|
1251
|
+
run: () => resolveGraph(buildGraph(preset, opts)),
|
|
1252
|
+
};
|
|
1253
|
+
}
|
|
1254
|
+
/**
|
|
1255
|
+
* Re-emits a resolved register as value-only {@link TokenNode}s in key order. For a
|
|
1256
|
+
* multi-pass algorithm this is the honest graph-as-data: each token carries its final
|
|
1257
|
+
* composed value (refs collapse to literals, the truthful statement that the value is
|
|
1258
|
+
* the pipeline's result). `resolveGraph(registerToNodes(r))` reproduces `r`.
|
|
1259
|
+
*/
|
|
1260
|
+
export function registerToNodes(register) {
|
|
1261
|
+
return Object.entries(register).map(([name, value]) => ({ name, value }));
|
|
1262
|
+
}
|
|
1263
|
+
function alpha(value) {
|
|
1264
|
+
if (!value)
|
|
1265
|
+
return 1;
|
|
1266
|
+
const rgba = /rgba?\([^)]*?,\s*([0-9.]+)\s*\)/.exec(value);
|
|
1267
|
+
if (rgba && rgba[1] !== undefined)
|
|
1268
|
+
return Number.parseFloat(rgba[1]);
|
|
1269
|
+
if (value.startsWith("#") && value.length === 9) {
|
|
1270
|
+
return Number.parseInt(value.slice(7, 9), 16) / 255;
|
|
1271
|
+
}
|
|
1272
|
+
if (value.startsWith("#") && value.length === 5) {
|
|
1273
|
+
return Number.parseInt(value.slice(4, 5).repeat(2), 16) / 255;
|
|
1274
|
+
}
|
|
1275
|
+
return 1;
|
|
1276
|
+
}
|
|
1277
|
+
function parseRem(value) {
|
|
1278
|
+
if (!value)
|
|
1279
|
+
return Number.NaN;
|
|
1280
|
+
const m = /^(-?[0-9.]+)(rem|px)$/.exec(value.trim());
|
|
1281
|
+
return m ? Number.parseFloat(m[1]) : Number.NaN;
|
|
1282
|
+
}
|
|
1283
|
+
function parseMs(value) {
|
|
1284
|
+
if (!value)
|
|
1285
|
+
return Number.NaN;
|
|
1286
|
+
const m = /^(-?[0-9.]+)ms$/.exec(value.trim());
|
|
1287
|
+
return m ? Number.parseFloat(m[1]) : Number.NaN;
|
|
1288
|
+
}
|
|
1289
|
+
function shadowStrength(value) {
|
|
1290
|
+
if (!value || value === "none")
|
|
1291
|
+
return 0;
|
|
1292
|
+
let total = 0;
|
|
1293
|
+
const offsets = value.match(/([0-9.]+)px/g) ?? [];
|
|
1294
|
+
for (const off of offsets)
|
|
1295
|
+
total += Number.parseFloat(off);
|
|
1296
|
+
const alphas = value.match(/rgba?\([^)]*,\s*([0-9.]+)\)/g) ?? [];
|
|
1297
|
+
for (const a of alphas) {
|
|
1298
|
+
const m = /,\s*([0-9.]+)\)/.exec(a);
|
|
1299
|
+
if (m)
|
|
1300
|
+
total += Number.parseFloat(m[1]) * 20;
|
|
1301
|
+
}
|
|
1302
|
+
return total;
|
|
1303
|
+
}
|
|
1304
|
+
const STATE_TOKENS = [
|
|
1305
|
+
"--state-hover",
|
|
1306
|
+
"--state-press",
|
|
1307
|
+
"--state-selected",
|
|
1308
|
+
"--state-disabled",
|
|
1309
|
+
"--state-drag",
|
|
1310
|
+
];
|
|
1311
|
+
const CEILING_EPSILON = 0.05;
|
|
1312
|
+
function achievableFloor(declaredFloor, bgCss) {
|
|
1313
|
+
if (!bgCss)
|
|
1314
|
+
return declaredFloor;
|
|
1315
|
+
const ceiling = Math.max(contrast("#000000", bgCss), contrast("#ffffff", bgCss));
|
|
1316
|
+
return Math.min(declaredFloor, ceiling - CEILING_EPSILON);
|
|
1317
|
+
}
|
|
1318
|
+
/** Perceptual OKLab distance between two colors — sees hue separation that luminance contrast can't. */
|
|
1319
|
+
function oklabDist(a, b) {
|
|
1320
|
+
const x = toOklchColor(a);
|
|
1321
|
+
const y = toOklchColor(b);
|
|
1322
|
+
const rad = Math.PI / 180;
|
|
1323
|
+
const ax = x.c * Math.cos(x.h * rad);
|
|
1324
|
+
const ay = x.c * Math.sin(x.h * rad);
|
|
1325
|
+
const bx = y.c * Math.cos(y.h * rad);
|
|
1326
|
+
const by = y.c * Math.sin(y.h * rad);
|
|
1327
|
+
return Math.hypot(x.l - y.l, ax - bx, ay - by);
|
|
1328
|
+
}
|
|
1329
|
+
export function makeInvariants(preset) {
|
|
1330
|
+
const onFillFloor = preset.declaredTextOnFillFloor;
|
|
1331
|
+
return [
|
|
1332
|
+
(ctx) => {
|
|
1333
|
+
for (const name of PRODUCES) {
|
|
1334
|
+
const value = ctx.register[name];
|
|
1335
|
+
const category = ctx.categories[name];
|
|
1336
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
1337
|
+
return {
|
|
1338
|
+
name: "every token non-empty and format-valid for its category",
|
|
1339
|
+
ok: false,
|
|
1340
|
+
detail: `${name} is ${value === undefined ? "missing" : "empty"}`,
|
|
1341
|
+
};
|
|
1342
|
+
}
|
|
1343
|
+
if (/nan/i.test(value)) {
|
|
1344
|
+
return {
|
|
1345
|
+
name: "every token non-empty and format-valid for its category",
|
|
1346
|
+
ok: false,
|
|
1347
|
+
detail: `${name} contains NaN: ${value}`,
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
switch (category) {
|
|
1351
|
+
case "color": {
|
|
1352
|
+
try {
|
|
1353
|
+
const o = toOklchColor(value);
|
|
1354
|
+
if (Number.isNaN(o.l) ||
|
|
1355
|
+
Number.isNaN(o.c) ||
|
|
1356
|
+
Number.isNaN(o.h) ||
|
|
1357
|
+
Number.isNaN(alpha(value))) {
|
|
1358
|
+
return {
|
|
1359
|
+
name: "every token non-empty and format-valid for its category",
|
|
1360
|
+
ok: false,
|
|
1361
|
+
detail: `${name} parses to NaN: ${value}`,
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
catch (error) {
|
|
1366
|
+
return {
|
|
1367
|
+
name: "every token non-empty and format-valid for its category",
|
|
1368
|
+
ok: false,
|
|
1369
|
+
detail: `${name} unparseable color: ${value} (${String(error)})`,
|
|
1370
|
+
};
|
|
1371
|
+
}
|
|
1372
|
+
break;
|
|
1373
|
+
}
|
|
1374
|
+
case "length": {
|
|
1375
|
+
if (Number.isNaN(parseRem(value))) {
|
|
1376
|
+
return {
|
|
1377
|
+
name: "every token non-empty and format-valid for its category",
|
|
1378
|
+
ok: false,
|
|
1379
|
+
detail: `${name} not a css length: ${value}`,
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
break;
|
|
1383
|
+
}
|
|
1384
|
+
case "duration": {
|
|
1385
|
+
if (Number.isNaN(parseMs(value))) {
|
|
1386
|
+
return {
|
|
1387
|
+
name: "every token non-empty and format-valid for its category",
|
|
1388
|
+
ok: false,
|
|
1389
|
+
detail: `${name} not a duration: ${value}`,
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
break;
|
|
1393
|
+
}
|
|
1394
|
+
case "number": {
|
|
1395
|
+
if (Number.isNaN(Number.parseFloat(value))) {
|
|
1396
|
+
return {
|
|
1397
|
+
name: "every token non-empty and format-valid for its category",
|
|
1398
|
+
ok: false,
|
|
1399
|
+
detail: `${name} not a number: ${value}`,
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1402
|
+
break;
|
|
1403
|
+
}
|
|
1404
|
+
case "easing": {
|
|
1405
|
+
if (!value.startsWith("cubic-bezier(")) {
|
|
1406
|
+
return {
|
|
1407
|
+
name: "every token non-empty and format-valid for its category",
|
|
1408
|
+
ok: false,
|
|
1409
|
+
detail: `${name} not an easing: ${value}`,
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
break;
|
|
1413
|
+
}
|
|
1414
|
+
case "shadow": {
|
|
1415
|
+
if (value !== "none" && !value.includes("rgba")) {
|
|
1416
|
+
return {
|
|
1417
|
+
name: "every token non-empty and format-valid for its category",
|
|
1418
|
+
ok: false,
|
|
1419
|
+
detail: `${name} not a shadow: ${value}`,
|
|
1420
|
+
};
|
|
1421
|
+
}
|
|
1422
|
+
break;
|
|
1423
|
+
}
|
|
1424
|
+
case "font":
|
|
1425
|
+
break;
|
|
1426
|
+
case "keyword": {
|
|
1427
|
+
const domain = KEYWORD_DOMAINS[name];
|
|
1428
|
+
if (domain && !domain.includes(value)) {
|
|
1429
|
+
return {
|
|
1430
|
+
name: "every token non-empty and format-valid for its category",
|
|
1431
|
+
ok: false,
|
|
1432
|
+
detail: `${name} not in {${domain.join(" | ")}}: ${value}`,
|
|
1433
|
+
};
|
|
1434
|
+
}
|
|
1435
|
+
break;
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
return { name: "every token non-empty and format-valid for its category", ok: true };
|
|
1440
|
+
},
|
|
1441
|
+
(ctx) => {
|
|
1442
|
+
const name = `fg-0 on bg-0 clears ${onFillFloor >= AAA - 0.01 ? "AAA" : "AA"}`;
|
|
1443
|
+
if (ctx.constraints["--fg-0"]) {
|
|
1444
|
+
return { name, ok: true, detail: "skipped (pinned text)" };
|
|
1445
|
+
}
|
|
1446
|
+
const fg0 = ctx.register["--fg-0"];
|
|
1447
|
+
const bg0 = ctx.register["--bg-0"];
|
|
1448
|
+
const ratio = fg0 && bg0 ? contrast(fg0, bg0) : 0;
|
|
1449
|
+
const required = achievableFloor(onFillFloor, ctx.constraints["--bg-0"] ? bg0 : undefined);
|
|
1450
|
+
return {
|
|
1451
|
+
name,
|
|
1452
|
+
ok: ratio >= required - 0.01,
|
|
1453
|
+
detail: `contrast ${ratio.toFixed(2)} (floor ${required.toFixed(2)}${ctx.constraints["--bg-0"] ? ` best-achievable, declared ${onFillFloor}` : ""})`,
|
|
1454
|
+
};
|
|
1455
|
+
},
|
|
1456
|
+
(ctx) => {
|
|
1457
|
+
const name = `fg ramp clears ${preset.contrastFloor >= AAA - 0.01 ? "AAA" : "AA"}`;
|
|
1458
|
+
if (ctx.constraints["--fg-0"]) {
|
|
1459
|
+
return { name, ok: true, detail: "skipped (pinned text)" };
|
|
1460
|
+
}
|
|
1461
|
+
const bg0 = ctx.register["--bg-0"];
|
|
1462
|
+
if (!bg0)
|
|
1463
|
+
return { name, ok: false, detail: "missing --bg-0" };
|
|
1464
|
+
const required = achievableFloor(preset.contrastFloor, ctx.constraints["--bg-0"] ? bg0 : undefined);
|
|
1465
|
+
for (let i = 1; i <= 3; i++) {
|
|
1466
|
+
const key = `--fg-${i}`;
|
|
1467
|
+
if (ctx.constraints[key])
|
|
1468
|
+
continue;
|
|
1469
|
+
const fg = ctx.register[key];
|
|
1470
|
+
const ratio = fg ? contrast(fg, bg0) : 0;
|
|
1471
|
+
if (ratio < required - 0.01) {
|
|
1472
|
+
return {
|
|
1473
|
+
name,
|
|
1474
|
+
ok: false,
|
|
1475
|
+
detail: `${key} contrast ${ratio.toFixed(2)} (floor ${required.toFixed(2)}${ctx.constraints["--bg-0"] ? ` best-achievable, declared ${preset.contrastFloor}` : ""})`,
|
|
1476
|
+
};
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
return { name, ok: true };
|
|
1480
|
+
},
|
|
1481
|
+
(ctx) => {
|
|
1482
|
+
const pairs = [
|
|
1483
|
+
["--accent-fg", "--accent"],
|
|
1484
|
+
["--neutral-fg", "--neutral"],
|
|
1485
|
+
["--success-fg", "--success"],
|
|
1486
|
+
["--warn-fg", "--warn"],
|
|
1487
|
+
["--danger-fg", "--danger"],
|
|
1488
|
+
["--info-fg", "--info"],
|
|
1489
|
+
["--accent-text", "--bg-0"],
|
|
1490
|
+
["--neutral-text", "--bg-0"],
|
|
1491
|
+
];
|
|
1492
|
+
const surfaceFill = new Set(SURFACES);
|
|
1493
|
+
for (const [fgName, fillName] of pairs) {
|
|
1494
|
+
const fill = ctx.register[fillName];
|
|
1495
|
+
const pinned = Boolean(ctx.constraints[fillName]);
|
|
1496
|
+
if (pinned && !surfaceFill.has(fillName))
|
|
1497
|
+
continue;
|
|
1498
|
+
const fg = ctx.register[fgName];
|
|
1499
|
+
if (!fg || !fill)
|
|
1500
|
+
continue;
|
|
1501
|
+
const required = pinned ? achievableFloor(onFillFloor, fill) : onFillFloor;
|
|
1502
|
+
if (contrast(fg, fill) < required - 0.01) {
|
|
1503
|
+
return {
|
|
1504
|
+
name: `on-fill text clears ${onFillFloor >= AAA - 0.01 ? "AAA" : "AA"}`,
|
|
1505
|
+
ok: false,
|
|
1506
|
+
detail: `${fgName} on ${fillName} = ${contrast(fg, fill).toFixed(2)} (floor ${required.toFixed(2)}${pinned ? " best-achievable" : ""})`,
|
|
1507
|
+
};
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
return {
|
|
1511
|
+
name: `on-fill text clears ${onFillFloor >= AAA - 0.01 ? "AAA" : "AA"}`,
|
|
1512
|
+
ok: true,
|
|
1513
|
+
};
|
|
1514
|
+
},
|
|
1515
|
+
(ctx) => {
|
|
1516
|
+
const pairs = [
|
|
1517
|
+
["--success-text", "--success-bg"],
|
|
1518
|
+
["--warn-text", "--warn-bg"],
|
|
1519
|
+
["--danger-text", "--danger-bg"],
|
|
1520
|
+
["--info-text", "--info-bg"],
|
|
1521
|
+
];
|
|
1522
|
+
for (const [fgName, fillName] of pairs) {
|
|
1523
|
+
const fg = ctx.register[fgName];
|
|
1524
|
+
const fill = ctx.register[fillName];
|
|
1525
|
+
if (!fg || !fill)
|
|
1526
|
+
continue;
|
|
1527
|
+
if (contrast(fg, fill) < AA - 0.01) {
|
|
1528
|
+
return {
|
|
1529
|
+
name: "text-on-tint clears AA",
|
|
1530
|
+
ok: false,
|
|
1531
|
+
detail: `${fgName} on ${fillName} = ${contrast(fg, fill).toFixed(2)}`,
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
return { name: "text-on-tint clears AA", ok: true };
|
|
1536
|
+
},
|
|
1537
|
+
(ctx) => {
|
|
1538
|
+
const name = "achromatic tone inks stay neutral";
|
|
1539
|
+
const achromatic = ["gray", "white", "black"];
|
|
1540
|
+
for (const hue of achromatic) {
|
|
1541
|
+
for (const token of [`--${hue}-fg`, `--${hue}-text`, `--color-${hue}-contrast`]) {
|
|
1542
|
+
const value = ctx.register[token];
|
|
1543
|
+
if (!value)
|
|
1544
|
+
continue;
|
|
1545
|
+
const c = toOklchColor(value).c;
|
|
1546
|
+
if (c >= ACHROMATIC_CHROMA) {
|
|
1547
|
+
return { name, ok: false, detail: `${token} = ${value} (chroma ${c.toFixed(3)} ≥ ${ACHROMATIC_CHROMA})` };
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
return { name, ok: true };
|
|
1552
|
+
},
|
|
1553
|
+
(ctx) => {
|
|
1554
|
+
const name = "panel text clears AA on --bg-1 and --bg-2";
|
|
1555
|
+
const neutralText = [
|
|
1556
|
+
"--fg-1",
|
|
1557
|
+
"--fg-2",
|
|
1558
|
+
"--fg-3",
|
|
1559
|
+
"--placeholder",
|
|
1560
|
+
"--link",
|
|
1561
|
+
"--accent-text",
|
|
1562
|
+
"--neutral-text",
|
|
1563
|
+
"--neutral-vivid",
|
|
1564
|
+
];
|
|
1565
|
+
if (ctx.constraints["--bg-0"])
|
|
1566
|
+
return { name, ok: true, detail: "skipped (pinned bg-0)" };
|
|
1567
|
+
const bg0 = ctx.register["--bg-0"];
|
|
1568
|
+
if (!bg0)
|
|
1569
|
+
return { name, ok: true };
|
|
1570
|
+
const textLight = ctx.scheme === "dark";
|
|
1571
|
+
const themePole = textLight ? "#ffffff" : "#000000";
|
|
1572
|
+
const band = contrastBandFloor(ctx.knobs);
|
|
1573
|
+
const inkFloor = Math.max(ENFORCE, preset.contrastFloor, (band ?? 0) + 0.2);
|
|
1574
|
+
const statusRoles = Object.keys(STATUS_TO_HUE);
|
|
1575
|
+
for (const panel of PANEL_SURFACES) {
|
|
1576
|
+
const bg = ctx.register[panel];
|
|
1577
|
+
if (!bg)
|
|
1578
|
+
continue;
|
|
1579
|
+
const bgL = toOklchColor(bg).l;
|
|
1580
|
+
if (bgL < 0.5 !== textLight)
|
|
1581
|
+
continue;
|
|
1582
|
+
const poleCeiling = contrast(themePole, bg);
|
|
1583
|
+
const required = Math.min(AA, poleCeiling - CEILING_EPSILON);
|
|
1584
|
+
const fg0Reach = (() => {
|
|
1585
|
+
const v = ctx.register["--fg-0"];
|
|
1586
|
+
return v ? contrast(v, bg) : Infinity;
|
|
1587
|
+
})();
|
|
1588
|
+
const inkReach = (source) => {
|
|
1589
|
+
const v = ctx.register[source];
|
|
1590
|
+
if (!v)
|
|
1591
|
+
return Infinity;
|
|
1592
|
+
const ink = toOklchColor(v);
|
|
1593
|
+
const targetL = textLight ? 1 : 0;
|
|
1594
|
+
let reach = contrast(v, bg);
|
|
1595
|
+
for (let i = 1; i <= 100; i++) {
|
|
1596
|
+
const t = i / 100;
|
|
1597
|
+
const candidate = withLightness(ink, ink.l + (targetL - ink.l) * t);
|
|
1598
|
+
if (contrast(formatCss(candidate), bg0) < inkFloor - 0.01)
|
|
1599
|
+
break;
|
|
1600
|
+
reach = Math.max(reach, contrast(formatCss(candidate), bg));
|
|
1601
|
+
}
|
|
1602
|
+
return reach;
|
|
1603
|
+
};
|
|
1604
|
+
const accentInkReach = inkReach("--accent");
|
|
1605
|
+
const neutralInkReach = inkReach("--neutral");
|
|
1606
|
+
const check = (token, ceilingReach = Infinity) => {
|
|
1607
|
+
const fg = ctx.register[token];
|
|
1608
|
+
if (!fg)
|
|
1609
|
+
return null;
|
|
1610
|
+
const floorFor = Math.min(required, ceilingReach);
|
|
1611
|
+
const ratio = contrast(fg, bg);
|
|
1612
|
+
if (ratio < floorFor - 0.05) {
|
|
1613
|
+
return {
|
|
1614
|
+
name,
|
|
1615
|
+
ok: false,
|
|
1616
|
+
detail: `${token} on ${panel} = ${ratio.toFixed(2)} (floor ${floorFor.toFixed(2)})`,
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
return null;
|
|
1620
|
+
};
|
|
1621
|
+
const fg0Bounded = new Set(["--fg-1", "--fg-2", "--fg-3", "--placeholder"]);
|
|
1622
|
+
const accentBounded = new Set(["--link", "--accent-text"]);
|
|
1623
|
+
const reachFor = (token) => {
|
|
1624
|
+
if (fg0Bounded.has(token))
|
|
1625
|
+
return fg0Reach;
|
|
1626
|
+
if (accentBounded.has(token))
|
|
1627
|
+
return accentInkReach;
|
|
1628
|
+
if (token === "--neutral-text" || token === "--neutral-vivid")
|
|
1629
|
+
return neutralInkReach;
|
|
1630
|
+
return Infinity;
|
|
1631
|
+
};
|
|
1632
|
+
for (const token of neutralText) {
|
|
1633
|
+
const fail = check(token, reachFor(token));
|
|
1634
|
+
if (fail)
|
|
1635
|
+
return fail;
|
|
1636
|
+
}
|
|
1637
|
+
for (const role of statusRoles) {
|
|
1638
|
+
const tintBg = ctx.register[`--${role}-bg`];
|
|
1639
|
+
if (tintBg) {
|
|
1640
|
+
const whiteJoint = contrast("#ffffff", tintBg) >= AA && contrast("#ffffff", bg) >= AA;
|
|
1641
|
+
const blackJoint = contrast("#000000", tintBg) >= AA && contrast("#000000", bg) >= AA;
|
|
1642
|
+
if (!whiteJoint && !blackJoint)
|
|
1643
|
+
continue;
|
|
1644
|
+
}
|
|
1645
|
+
const fail = check(`--${role}-text`);
|
|
1646
|
+
if (fail)
|
|
1647
|
+
return fail;
|
|
1648
|
+
const failVivid = check(`--${role}-vivid`);
|
|
1649
|
+
if (failVivid)
|
|
1650
|
+
return failVivid;
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
return { name, ok: true };
|
|
1654
|
+
},
|
|
1655
|
+
(ctx) => {
|
|
1656
|
+
const name = "solid fills separate from --bg-0";
|
|
1657
|
+
const bg0 = ctx.register["--bg-0"];
|
|
1658
|
+
if (!bg0)
|
|
1659
|
+
return { name, ok: true };
|
|
1660
|
+
const fills = ["--accent", "--neutral", ...Object.keys(STATUS_TO_HUE).map((r) => `--${r}`)];
|
|
1661
|
+
for (const token of fills) {
|
|
1662
|
+
if (ctx.constraints[token])
|
|
1663
|
+
continue;
|
|
1664
|
+
const fill = ctx.register[token];
|
|
1665
|
+
if (!fill)
|
|
1666
|
+
continue;
|
|
1667
|
+
const ratio = contrast(fill, bg0);
|
|
1668
|
+
if (ratio < SURFACE_SEPARATION - 0.05) {
|
|
1669
|
+
return { name, ok: false, detail: `${token} = ${ratio.toFixed(2)} on --bg-0 (floor ${SURFACE_SEPARATION})` };
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
return { name, ok: true };
|
|
1673
|
+
},
|
|
1674
|
+
(ctx) => {
|
|
1675
|
+
const name = "borders separate from their surface";
|
|
1676
|
+
const borders = [
|
|
1677
|
+
["--line", "--bg-0", BORDER_SEPARATION],
|
|
1678
|
+
["--line-2", "--bg-0", DIVIDER_SEPARATION],
|
|
1679
|
+
["--field-border", "--field-bg", BORDER_SEPARATION],
|
|
1680
|
+
];
|
|
1681
|
+
for (const [token, surface, separation] of borders) {
|
|
1682
|
+
if (ctx.constraints[token])
|
|
1683
|
+
continue;
|
|
1684
|
+
const border = ctx.register[token];
|
|
1685
|
+
const bg = ctx.register[surface];
|
|
1686
|
+
if (!border || !bg)
|
|
1687
|
+
continue;
|
|
1688
|
+
const ratio = contrast(border, bg);
|
|
1689
|
+
if (ratio < separation - 0.05) {
|
|
1690
|
+
return { name, ok: false, detail: `${token} = ${ratio.toFixed(2)} on ${surface} (floor ${separation})` };
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
return { name, ok: true };
|
|
1694
|
+
},
|
|
1695
|
+
(ctx) => {
|
|
1696
|
+
const ladder = ["--bg-sunken", ...SURFACES];
|
|
1697
|
+
const ls = ladder.map((name) => {
|
|
1698
|
+
const value = ctx.register[name];
|
|
1699
|
+
return value ? toOklchColor(value).l : 0;
|
|
1700
|
+
});
|
|
1701
|
+
const ascending = ctx.scheme === "dark";
|
|
1702
|
+
for (let i = 1; i < ls.length; i++) {
|
|
1703
|
+
const prev = ls[i - 1];
|
|
1704
|
+
const cur = ls[i];
|
|
1705
|
+
const ok = ascending ? cur >= prev - 1e-6 : cur <= prev + 1e-6;
|
|
1706
|
+
if (!ok) {
|
|
1707
|
+
return {
|
|
1708
|
+
name: "surface lightness monotonic",
|
|
1709
|
+
ok: false,
|
|
1710
|
+
detail: `${ladder[i - 1]}=${prev.toFixed(3)} ${ladder[i]}=${cur.toFixed(3)} (${ctx.scheme})`,
|
|
1711
|
+
};
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
return { name: "surface lightness monotonic", ok: true };
|
|
1715
|
+
},
|
|
1716
|
+
(ctx) => {
|
|
1717
|
+
for (const name of STATE_TOKENS) {
|
|
1718
|
+
const value = ctx.register[name];
|
|
1719
|
+
if (!value)
|
|
1720
|
+
continue;
|
|
1721
|
+
const a = alpha(value);
|
|
1722
|
+
if (a >= 1) {
|
|
1723
|
+
return {
|
|
1724
|
+
name: "state overlays translucent",
|
|
1725
|
+
ok: false,
|
|
1726
|
+
detail: `${name} alpha ${a}`,
|
|
1727
|
+
};
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
return { name: "state overlays translucent", ok: true };
|
|
1731
|
+
},
|
|
1732
|
+
(ctx) => {
|
|
1733
|
+
const linkName = `links clear ${onFillFloor >= AAA - 0.01 ? "AAA" : "AA"} on bg-0`;
|
|
1734
|
+
const bg0 = ctx.register["--bg-0"];
|
|
1735
|
+
const required = achievableFloor(onFillFloor, ctx.constraints["--bg-0"] ? bg0 : undefined);
|
|
1736
|
+
for (const name of ["--link", "--link-hover"]) {
|
|
1737
|
+
const link = ctx.register[name];
|
|
1738
|
+
if (!link || !bg0)
|
|
1739
|
+
continue;
|
|
1740
|
+
const ratio = contrast(link, bg0);
|
|
1741
|
+
if (ratio < required - 0.01) {
|
|
1742
|
+
return {
|
|
1743
|
+
name: linkName,
|
|
1744
|
+
ok: false,
|
|
1745
|
+
detail: `${name} on --bg-0 = ${ratio.toFixed(2)} (floor ${required.toFixed(2)}${ctx.constraints["--bg-0"] ? " best-achievable" : ""})`,
|
|
1746
|
+
};
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
return { name: linkName, ok: true };
|
|
1750
|
+
},
|
|
1751
|
+
(ctx) => {
|
|
1752
|
+
const name = "link hover distinct from link";
|
|
1753
|
+
const link = ctx.register["--link"];
|
|
1754
|
+
const hover = ctx.register["--link-hover"];
|
|
1755
|
+
if (!link || !hover)
|
|
1756
|
+
return { name, ok: true };
|
|
1757
|
+
// A user pinning either token owns the collapse; the guard only governs derived values.
|
|
1758
|
+
if (ctx.constraints["--link"] || ctx.constraints["--link-hover"])
|
|
1759
|
+
return { name, ok: true };
|
|
1760
|
+
if (link === hover) {
|
|
1761
|
+
// A `--link` forced to a pure pole to clear contrast against an un-clearable same-side
|
|
1762
|
+
// panel (a mid-gray page whose panels sit too close to it) has no distinct *readable*
|
|
1763
|
+
// neighbor: any different hover would drop below the floor. That genuine-pole collapse is
|
|
1764
|
+
// acceptable — readability wins over a hover delta — but every other collapse is a bug.
|
|
1765
|
+
if (link === "#000000" || link === "#ffffff")
|
|
1766
|
+
return { name, ok: true };
|
|
1767
|
+
return { name, ok: false, detail: `--link and --link-hover both ${link}` };
|
|
1768
|
+
}
|
|
1769
|
+
return { name, ok: true };
|
|
1770
|
+
},
|
|
1771
|
+
(ctx) => {
|
|
1772
|
+
const name = "unpinned accent ramp holds its fan at constant L/C";
|
|
1773
|
+
const accentValue = ctx.register["--accent"];
|
|
1774
|
+
if (!accentValue) {
|
|
1775
|
+
return { name, ok: true };
|
|
1776
|
+
}
|
|
1777
|
+
const accent = toOklchColor(accentValue);
|
|
1778
|
+
if (accent.c < HUE_STABLE_CHROMA) {
|
|
1779
|
+
return { name, ok: true };
|
|
1780
|
+
}
|
|
1781
|
+
const step = typeof ctx.knobs.accentShiftStep === "number"
|
|
1782
|
+
? ctx.knobs.accentShiftStep
|
|
1783
|
+
: DEFAULT_SHIFT_STEP;
|
|
1784
|
+
const split = typeof ctx.knobs.accentSplit === "number"
|
|
1785
|
+
? ctx.knobs.accentSplit
|
|
1786
|
+
: DEFAULT_ACCENT_SPLIT;
|
|
1787
|
+
const accent2Value = ctx.register["--accent-2"];
|
|
1788
|
+
const accent3Value = ctx.register["--accent-3"];
|
|
1789
|
+
const pinnedAccent2 = ctx.constraints["--accent-2"] && accent2Value ? toOklchColor(accent2Value) : null;
|
|
1790
|
+
const pinnedAccent3 = ctx.constraints["--accent-3"] && accent3Value ? toOklchColor(accent3Value) : null;
|
|
1791
|
+
const fanOffset = (n) => ACCENT_FAN === "split-complement"
|
|
1792
|
+
? n === 2
|
|
1793
|
+
? pinnedAccent3
|
|
1794
|
+
? -hueDelta(accent.h, pinnedAccent3.h)
|
|
1795
|
+
: -split
|
|
1796
|
+
: n === 3
|
|
1797
|
+
? pinnedAccent2
|
|
1798
|
+
? -hueDelta(accent.h, pinnedAccent2.h)
|
|
1799
|
+
: split
|
|
1800
|
+
: 180
|
|
1801
|
+
: step * (n - 1);
|
|
1802
|
+
for (let n = 2; n <= 4; n++) {
|
|
1803
|
+
if (ctx.constraints[`--accent-${n}`])
|
|
1804
|
+
continue;
|
|
1805
|
+
const value = ctx.register[`--accent-${n}`];
|
|
1806
|
+
if (!value)
|
|
1807
|
+
continue;
|
|
1808
|
+
const rotated = toOklchColor(value);
|
|
1809
|
+
const wantH = (((accent.h + fanOffset(n)) % 360) + 360) % 360;
|
|
1810
|
+
if (rotated.c >= HUE_STABLE_CHROMA) {
|
|
1811
|
+
let dh = Math.abs(rotated.h - wantH) % 360;
|
|
1812
|
+
if (dh > 180)
|
|
1813
|
+
dh = 360 - dh;
|
|
1814
|
+
if (dh > HUE_TOLERANCE) {
|
|
1815
|
+
return {
|
|
1816
|
+
name,
|
|
1817
|
+
ok: false,
|
|
1818
|
+
detail: `--accent-${n} h=${rotated.h.toFixed(1)} want ${wantH.toFixed(1)}`,
|
|
1819
|
+
};
|
|
1820
|
+
}
|
|
1821
|
+
}
|
|
1822
|
+
if (Math.abs(rotated.l - accent.l) > LIGHTNESS_TOLERANCE) {
|
|
1823
|
+
return {
|
|
1824
|
+
name,
|
|
1825
|
+
ok: false,
|
|
1826
|
+
detail: `--accent-${n} l=${rotated.l.toFixed(3)} want ${accent.l.toFixed(3)}`,
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1829
|
+
const maxChroma = clampToGamut({ l: accent.l, c: accent.c, h: wantH, alpha: 1 }).c;
|
|
1830
|
+
const expectedChroma = Math.min(accent.c, maxChroma);
|
|
1831
|
+
if (Math.abs(rotated.c - expectedChroma) > 0.02) {
|
|
1832
|
+
return {
|
|
1833
|
+
name,
|
|
1834
|
+
ok: false,
|
|
1835
|
+
detail: `--accent-${n} chroma ${rotated.c.toFixed(3)} want max-at-hue ${expectedChroma.toFixed(3)}`,
|
|
1836
|
+
};
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
return { name, ok: true };
|
|
1840
|
+
},
|
|
1841
|
+
(ctx) => {
|
|
1842
|
+
for (const name of ["--ring", "--ring-bg", "--scrim", "--selection", "--highlight"]) {
|
|
1843
|
+
const value = ctx.register[name];
|
|
1844
|
+
if (!value)
|
|
1845
|
+
continue;
|
|
1846
|
+
if (alpha(value) >= 1) {
|
|
1847
|
+
return {
|
|
1848
|
+
name: "ring/scrim/selection/highlight carry alpha < 1",
|
|
1849
|
+
ok: false,
|
|
1850
|
+
detail: `${name} alpha ${alpha(value)}`,
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
return { name: "ring/scrim/selection/highlight carry alpha < 1", ok: true };
|
|
1855
|
+
},
|
|
1856
|
+
(ctx) => {
|
|
1857
|
+
let prev = -Infinity;
|
|
1858
|
+
for (const step of TEXT_STEPS) {
|
|
1859
|
+
const rem = parseRem(ctx.register[`--text-${step}`]);
|
|
1860
|
+
if (Number.isNaN(rem)) {
|
|
1861
|
+
return {
|
|
1862
|
+
name: "type scale strictly increasing",
|
|
1863
|
+
ok: false,
|
|
1864
|
+
detail: `--text-${step} not a length`,
|
|
1865
|
+
};
|
|
1866
|
+
}
|
|
1867
|
+
if (rem <= prev) {
|
|
1868
|
+
return {
|
|
1869
|
+
name: "type scale strictly increasing",
|
|
1870
|
+
ok: false,
|
|
1871
|
+
detail: `--text-${step}=${rem} not > ${prev}`,
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
prev = rem;
|
|
1875
|
+
}
|
|
1876
|
+
return { name: "type scale strictly increasing", ok: true };
|
|
1877
|
+
},
|
|
1878
|
+
(ctx) => {
|
|
1879
|
+
let prev = -Infinity;
|
|
1880
|
+
for (const step of WEIGHT_STEPS) {
|
|
1881
|
+
const w = Number.parseFloat(ctx.register[`--weight-${step}`] ?? "");
|
|
1882
|
+
if (Number.isNaN(w) || w <= prev) {
|
|
1883
|
+
return {
|
|
1884
|
+
name: "weights strictly increasing",
|
|
1885
|
+
ok: false,
|
|
1886
|
+
detail: `--weight-${step}=${w} not > ${prev}`,
|
|
1887
|
+
};
|
|
1888
|
+
}
|
|
1889
|
+
prev = w;
|
|
1890
|
+
}
|
|
1891
|
+
return { name: "weights strictly increasing", ok: true };
|
|
1892
|
+
},
|
|
1893
|
+
(ctx) => {
|
|
1894
|
+
let prev = -Infinity;
|
|
1895
|
+
for (const step of LEADING_STEPS) {
|
|
1896
|
+
const v = Number.parseFloat(ctx.register[`--leading-${step}`] ?? "");
|
|
1897
|
+
if (Number.isNaN(v) || v <= prev) {
|
|
1898
|
+
return {
|
|
1899
|
+
name: "leading strictly increasing",
|
|
1900
|
+
ok: false,
|
|
1901
|
+
detail: `--leading-${step}=${v} not > ${prev}`,
|
|
1902
|
+
};
|
|
1903
|
+
}
|
|
1904
|
+
prev = v;
|
|
1905
|
+
}
|
|
1906
|
+
return { name: "leading strictly increasing", ok: true };
|
|
1907
|
+
},
|
|
1908
|
+
(ctx) => {
|
|
1909
|
+
let prev = -Infinity;
|
|
1910
|
+
for (const step of RADIUS_STEPS) {
|
|
1911
|
+
const v = parseRem(ctx.register[`--radius-${step}`]);
|
|
1912
|
+
if (Number.isNaN(v) || v < prev - 1e-9) {
|
|
1913
|
+
return {
|
|
1914
|
+
name: "radius ladder non-decreasing",
|
|
1915
|
+
ok: false,
|
|
1916
|
+
detail: `--radius-${step}=${v} < ${prev}`,
|
|
1917
|
+
};
|
|
1918
|
+
}
|
|
1919
|
+
prev = v;
|
|
1920
|
+
}
|
|
1921
|
+
return { name: "radius ladder non-decreasing", ok: true };
|
|
1922
|
+
},
|
|
1923
|
+
(ctx) => {
|
|
1924
|
+
let prev = -Infinity;
|
|
1925
|
+
for (const step of BORDER_STEPS) {
|
|
1926
|
+
const v = parseRem(ctx.register[`--border-${step}`]);
|
|
1927
|
+
if (Number.isNaN(v) || v <= prev) {
|
|
1928
|
+
return {
|
|
1929
|
+
name: "borders strictly increasing",
|
|
1930
|
+
ok: false,
|
|
1931
|
+
detail: `--border-${step}=${v} not > ${prev}`,
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
prev = v;
|
|
1935
|
+
}
|
|
1936
|
+
return { name: "borders strictly increasing", ok: true };
|
|
1937
|
+
},
|
|
1938
|
+
(ctx) => {
|
|
1939
|
+
let prev = -Infinity;
|
|
1940
|
+
for (const step of DURATION_STEPS) {
|
|
1941
|
+
const v = parseMs(ctx.register[`--duration-${step}`]);
|
|
1942
|
+
if (Number.isNaN(v) || v <= prev) {
|
|
1943
|
+
return {
|
|
1944
|
+
name: "durations strictly increasing",
|
|
1945
|
+
ok: false,
|
|
1946
|
+
detail: `--duration-${step}=${v} not > ${prev}`,
|
|
1947
|
+
};
|
|
1948
|
+
}
|
|
1949
|
+
prev = v;
|
|
1950
|
+
}
|
|
1951
|
+
return { name: "durations strictly increasing", ok: true };
|
|
1952
|
+
},
|
|
1953
|
+
(ctx) => {
|
|
1954
|
+
let prev = -Infinity;
|
|
1955
|
+
for (const level of ELEVATION_STEPS) {
|
|
1956
|
+
const v = shadowStrength(ctx.register[`--elevation-${level}`]);
|
|
1957
|
+
if (v < prev - 1e-9) {
|
|
1958
|
+
return {
|
|
1959
|
+
name: "elevation strength non-decreasing",
|
|
1960
|
+
ok: false,
|
|
1961
|
+
detail: `--elevation-${level}=${v} < ${prev}`,
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1964
|
+
prev = v;
|
|
1965
|
+
}
|
|
1966
|
+
return { name: "elevation strength non-decreasing", ok: true };
|
|
1967
|
+
},
|
|
1968
|
+
(ctx) => {
|
|
1969
|
+
let prev = -Infinity;
|
|
1970
|
+
for (const step of SPACE_STEPS) {
|
|
1971
|
+
const v = parseRem(ctx.register[`--space-${step}`]);
|
|
1972
|
+
if (Number.isNaN(v) || v < prev - 1e-9) {
|
|
1973
|
+
return {
|
|
1974
|
+
name: "space ramp non-decreasing",
|
|
1975
|
+
ok: false,
|
|
1976
|
+
detail: `--space-${step}=${v} < ${prev}`,
|
|
1977
|
+
};
|
|
1978
|
+
}
|
|
1979
|
+
prev = v;
|
|
1980
|
+
}
|
|
1981
|
+
return { name: "space ramp non-decreasing", ok: true };
|
|
1982
|
+
},
|
|
1983
|
+
(ctx) => {
|
|
1984
|
+
for (const [hue, spec] of Object.entries(PALETTE_HUES)) {
|
|
1985
|
+
const stops = PALETTE_STOPS.filter((s) => s !== "contrast").map((stop) => ctx.register[`--color-${hue}-${stop}`]);
|
|
1986
|
+
const ls = stops.map((v) => (v ? toOklchColor(v).l : Number.NaN));
|
|
1987
|
+
if (ls.some((l) => Number.isNaN(l))) {
|
|
1988
|
+
return {
|
|
1989
|
+
name: "palette ramps monotonic in OKLCH lightness",
|
|
1990
|
+
ok: false,
|
|
1991
|
+
detail: `--color-${hue} ramp has a non-color stop`,
|
|
1992
|
+
};
|
|
1993
|
+
}
|
|
1994
|
+
const ascending = ls[ls.length - 1] >= ls[0];
|
|
1995
|
+
for (let i = 1; i < ls.length; i++) {
|
|
1996
|
+
const prev = ls[i - 1];
|
|
1997
|
+
const cur = ls[i];
|
|
1998
|
+
const ok = ascending ? cur > prev + 1e-9 : cur < prev - 1e-9;
|
|
1999
|
+
if (!ok) {
|
|
2000
|
+
return {
|
|
2001
|
+
name: "palette ramps monotonic in OKLCH lightness",
|
|
2002
|
+
ok: false,
|
|
2003
|
+
detail: `--color-${hue} ramp l[${i}]=${cur} not strictly ${ascending ? ">" : "<"} ${prev}`,
|
|
2004
|
+
};
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
const base = ctx.register[`--color-${hue}-base`];
|
|
2008
|
+
const contrastStop = ctx.register[`--color-${hue}-contrast`];
|
|
2009
|
+
if (base && contrastStop && contrast(base, contrastStop) < AA - 0.01) {
|
|
2010
|
+
return {
|
|
2011
|
+
name: "palette ramps monotonic in OKLCH lightness",
|
|
2012
|
+
ok: false,
|
|
2013
|
+
detail: `--color-${hue}-contrast on -base = ${contrast(base, contrastStop).toFixed(2)}`,
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
2016
|
+
// The pure achromatic poles (white/black) keep `subtle` and `strong` at the same
|
|
2017
|
+
// end of the lightness scale by design — they are never paired as a soft
|
|
2018
|
+
// badge/avatar tint+ink, so they are exempt from the readable-on-subtle rule.
|
|
2019
|
+
if (spec !== "white" && spec !== "black") {
|
|
2020
|
+
const subtle = ctx.register[`--color-${hue}-subtle`];
|
|
2021
|
+
const strong = ctx.register[`--color-${hue}-strong`];
|
|
2022
|
+
if (subtle && strong && contrast(subtle, strong) < AA - 0.01) {
|
|
2023
|
+
return {
|
|
2024
|
+
name: "palette ramps monotonic in OKLCH lightness",
|
|
2025
|
+
ok: false,
|
|
2026
|
+
detail: `--color-${hue}-strong on -subtle = ${contrast(subtle, strong).toFixed(2)}`,
|
|
2027
|
+
};
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
2030
|
+
if (typeof spec === "object" && base) {
|
|
2031
|
+
const o = toOklchColor(base);
|
|
2032
|
+
if (o.c >= HUE_STABLE_CHROMA) {
|
|
2033
|
+
let dh = Math.abs(o.h - spec.h) % 360;
|
|
2034
|
+
if (dh > 180)
|
|
2035
|
+
dh = 360 - dh;
|
|
2036
|
+
if (dh > 20) {
|
|
2037
|
+
return {
|
|
2038
|
+
name: "palette ramps monotonic in OKLCH lightness",
|
|
2039
|
+
ok: false,
|
|
2040
|
+
detail: `--color-${hue}-base h=${o.h.toFixed(1)} strayed from ${spec.h}`,
|
|
2041
|
+
};
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
return { name: "palette ramps monotonic in OKLCH lightness", ok: true };
|
|
2047
|
+
},
|
|
2048
|
+
(ctx) => {
|
|
2049
|
+
// Every tone's four-token family must be self-consistent: the on-solid ink reads on the
|
|
2050
|
+
// solid fill, and the soft ink reads on the soft tint. This is the "any tone, anywhere"
|
|
2051
|
+
// guarantee — a pink or accent-3 button can't ship unreadable, same as the semantic six.
|
|
2052
|
+
const name = "every tone family clears AA (fg on solid, text on bg)";
|
|
2053
|
+
for (const tone of FULL_TONES) {
|
|
2054
|
+
const solid = ctx.register[`--${tone}`];
|
|
2055
|
+
const fg = ctx.register[`--${tone}-fg`];
|
|
2056
|
+
const bg = ctx.register[`--${tone}-bg`];
|
|
2057
|
+
const text = ctx.register[`--${tone}-text`];
|
|
2058
|
+
if (!solid || !fg || !bg || !text) {
|
|
2059
|
+
return { name, ok: false, detail: `--${tone} family is incomplete` };
|
|
2060
|
+
}
|
|
2061
|
+
if (contrast(solid, fg) < AA - 0.01) {
|
|
2062
|
+
return { name, ok: false, detail: `--${tone}-fg on --${tone} = ${contrast(solid, fg).toFixed(2)}` };
|
|
2063
|
+
}
|
|
2064
|
+
if (contrast(bg, text) < AA - 0.01) {
|
|
2065
|
+
return { name, ok: false, detail: `--${tone}-text on --${tone}-bg = ${contrast(bg, text).toFixed(2)}` };
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
return { name, ok: true };
|
|
2069
|
+
},
|
|
2070
|
+
(ctx) => {
|
|
2071
|
+
const name = "code palette readable on --code-bg";
|
|
2072
|
+
const codeBg = ctx.register["--code-bg"];
|
|
2073
|
+
if (!codeBg)
|
|
2074
|
+
return { name, ok: false, detail: "--code-bg missing" };
|
|
2075
|
+
const readFloor = achievableFloor(AA, codeBg);
|
|
2076
|
+
const commentFloor = achievableFloor(3, codeBg);
|
|
2077
|
+
for (const role of [...CODE_VIVID_ROLES, "operator"]) {
|
|
2078
|
+
const v = ctx.register[`--code-${role}`];
|
|
2079
|
+
const ratio = v ? contrast(v, codeBg) : 0;
|
|
2080
|
+
if (ratio < readFloor - 0.05) {
|
|
2081
|
+
return { name, ok: false, detail: `--code-${role} on --code-bg = ${ratio.toFixed(2)} (floor ${readFloor.toFixed(2)})` };
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
const commentRatio = contrast(ctx.register["--code-comment"] ?? "#000", codeBg);
|
|
2085
|
+
if (commentRatio < commentFloor - 0.05) {
|
|
2086
|
+
return { name, ok: false, detail: `--code-comment on --code-bg = ${commentRatio.toFixed(2)} (floor ${commentFloor.toFixed(2)})` };
|
|
2087
|
+
}
|
|
2088
|
+
return { name, ok: true };
|
|
2089
|
+
},
|
|
2090
|
+
(ctx) => {
|
|
2091
|
+
// OKLab distance, not WCAG contrast — luminance-only contrast is blind to two equally-light hues.
|
|
2092
|
+
// `variable` is excluded: it's the plain-text baseline (`--code-fg`), not a colored scope.
|
|
2093
|
+
const name = "code scopes mutually distinguishable";
|
|
2094
|
+
const MIN_DE = 0.006;
|
|
2095
|
+
const distinct = [...CODE_VIVID_ROLES, "comment"].map((r) => `--code-${r}`);
|
|
2096
|
+
for (let i = 0; i < distinct.length; i++) {
|
|
2097
|
+
for (let j = i + 1; j < distinct.length; j++) {
|
|
2098
|
+
const ni = distinct[i];
|
|
2099
|
+
const nj = distinct[j];
|
|
2100
|
+
const a = ctx.register[ni];
|
|
2101
|
+
const b = ctx.register[nj];
|
|
2102
|
+
if (!a || !b)
|
|
2103
|
+
continue;
|
|
2104
|
+
const d = oklabDist(a, b);
|
|
2105
|
+
if (d < MIN_DE) {
|
|
2106
|
+
return { name, ok: false, detail: `${ni} vs ${nj} ΔE=${d.toFixed(4)} (min ${MIN_DE})` };
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
return { name, ok: true };
|
|
2111
|
+
},
|
|
2112
|
+
(ctx) => {
|
|
2113
|
+
// Mistaking success for danger is a usability failure WCAG contrast can't see — two
|
|
2114
|
+
// equally-light status hues read as one. Floored well under the muted reality
|
|
2115
|
+
// (xtyle-quiet's closest pair sits ~0.044), so it guards a real collapse, not taste.
|
|
2116
|
+
const name = "status roles mutually distinguishable";
|
|
2117
|
+
const MIN_DE = 0.02;
|
|
2118
|
+
const roles = Object.keys(STATUS_TO_HUE).map((r) => `--${r}`);
|
|
2119
|
+
for (let i = 0; i < roles.length; i++) {
|
|
2120
|
+
for (let j = i + 1; j < roles.length; j++) {
|
|
2121
|
+
const ni = roles[i];
|
|
2122
|
+
const nj = roles[j];
|
|
2123
|
+
const a = ctx.register[ni];
|
|
2124
|
+
const b = ctx.register[nj];
|
|
2125
|
+
if (!a || !b)
|
|
2126
|
+
continue;
|
|
2127
|
+
const d = oklabDist(a, b);
|
|
2128
|
+
if (d < MIN_DE) {
|
|
2129
|
+
return { name, ok: false, detail: `${ni} vs ${nj} ΔE=${d.toFixed(4)} (min ${MIN_DE})` };
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
return { name, ok: true };
|
|
2134
|
+
},
|
|
2135
|
+
];
|
|
2136
|
+
}
|
|
2137
|
+
export const PRODUCED_TOKENS = PRODUCES;
|
|
2138
|
+
export const TOKEN_CATEGORIES = CATEGORIES;
|
|
2139
|
+
/**
|
|
2140
|
+
* Builds an `Algorithm` from a preset and a pipeline factory. `buildPasses(preset, opts)`
|
|
2141
|
+
* returns the ordered passes for one derivation; `derive` runs them and returns the final
|
|
2142
|
+
* register, `deriveTraced` keeps every snapshot, and `passes` exposes a stable single-derive
|
|
2143
|
+
* pass list for introspection. For a single-pass family algorithm `lineage` is the honest
|
|
2144
|
+
* graph from {@link buildGraph}; for a multi-pass one it re-emits the final register as
|
|
2145
|
+
* value-only nodes so `resolveGraph(lineage(opts)) === derive(opts)` holds either way.
|
|
2146
|
+
*/
|
|
2147
|
+
export function makeXtylePipelineAlgorithm(preset, buildPasses) {
|
|
2148
|
+
const run = (opts) => {
|
|
2149
|
+
const passes = buildPasses(preset, opts);
|
|
2150
|
+
return runPipeline(passes, (passIndex) => buildPassContext(preset, opts, passIndex));
|
|
2151
|
+
};
|
|
2152
|
+
const singlePass = buildPasses(preset, {}).length === 1;
|
|
2153
|
+
return {
|
|
2154
|
+
id: preset.id,
|
|
2155
|
+
produces: PRODUCES,
|
|
2156
|
+
knobs: preset.knobs,
|
|
2157
|
+
categories: CATEGORIES,
|
|
2158
|
+
derive: (opts = {}) => run(opts).register,
|
|
2159
|
+
lineage: (opts = {}) => singlePass
|
|
2160
|
+
? buildGraph(preset, opts).map(({ name, value, refs }) => refs && refs.length ? { name, value, refs } : { name, value })
|
|
2161
|
+
: registerToNodes(run(opts).register),
|
|
2162
|
+
invariants: makeInvariants(preset),
|
|
2163
|
+
passes: buildPasses(preset, {}).map((pass) => ({ name: pass.name, run: pass.run })),
|
|
2164
|
+
deriveTraced: (opts = {}) => run(opts),
|
|
2165
|
+
};
|
|
2166
|
+
}
|
|
2167
|
+
export function makeXtyleAlgorithm(preset) {
|
|
2168
|
+
return makeXtylePipelineAlgorithm(preset, (p, opts) => [settlePass(p, opts)]);
|
|
2169
|
+
}
|
|
2170
|
+
export const SHARED_KNOBS = [
|
|
2171
|
+
"scheme",
|
|
2172
|
+
"accentShiftStep",
|
|
2173
|
+
"accentSplit",
|
|
2174
|
+
"contrastBand",
|
|
2175
|
+
"vibrancy",
|
|
2176
|
+
"typeScale",
|
|
2177
|
+
"radiusScale",
|
|
2178
|
+
"density",
|
|
2179
|
+
"cues",
|
|
2180
|
+
"fonts",
|
|
2181
|
+
"anchors",
|
|
2182
|
+
];
|
|
2183
|
+
export const DEFAULT_ANCHORS = {
|
|
2184
|
+
bg: "#0f1115",
|
|
2185
|
+
fg: "#e8eaed",
|
|
2186
|
+
};
|
|
2187
|
+
//# sourceMappingURL=factory.js.map
|