opui-css 4.1.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/CHANGELOG.md +282 -247
  2. package/LICENSE +21 -21
  3. package/MIGRATING.md +127 -105
  4. package/README.md +87 -87
  5. package/astro/index.ts +46 -46
  6. package/components/AGENTS.md +248 -247
  7. package/components/Accordion/Accordion.astro +42 -42
  8. package/components/Anchor/Anchor.astro +51 -51
  9. package/components/Avatar/Avatar.astro +38 -44
  10. package/components/Badge/Badge.astro +59 -54
  11. package/components/Button/Button.astro +45 -45
  12. package/components/ButtonGroup/ButtonGroup.astro +29 -29
  13. package/components/Callout/Callout.astro +75 -75
  14. package/components/Card/Card.astro +36 -36
  15. package/components/Checkbox/Checkbox.astro +76 -76
  16. package/components/Checkbox/CheckboxInput.astro +32 -32
  17. package/components/Chip/Chip.astro +37 -37
  18. package/components/ClassicSelect/ClassicSelect.astro +83 -83
  19. package/components/DescriptionList/Description.astro +12 -12
  20. package/components/DescriptionList/DescriptionList.astro +22 -22
  21. package/components/DescriptionList/Item.astro +12 -12
  22. package/components/DescriptionList/Term.astro +12 -12
  23. package/components/DescriptionList/index.ts +12 -12
  24. package/components/Dialog/Dialog.astro +41 -41
  25. package/components/Divider/Divider.astro +17 -14
  26. package/components/Drawer/Drawer.astro +49 -49
  27. package/components/Drawer/DrawerFooter.astro +14 -14
  28. package/components/Drawer/DrawerHeader.astro +31 -31
  29. package/components/FieldDescription/FieldDescription.astro +13 -13
  30. package/components/FieldGroup/FieldGroup.astro +31 -31
  31. package/components/FieldLegend/FieldLegend.astro +15 -15
  32. package/components/FieldSet/FieldSet.astro +15 -15
  33. package/components/Form/Form.astro +15 -15
  34. package/components/IconButton/IconButton.astro +26 -26
  35. package/components/List/List.astro +36 -36
  36. package/components/ListItem/ListItem.astro +118 -118
  37. package/components/Progress/Progress.astro +41 -40
  38. package/components/Radio/Radio.astro +70 -70
  39. package/components/Radio/RadioInput.astro +24 -24
  40. package/components/Range/Range.astro +136 -136
  41. package/components/Select/Select.astro +106 -106
  42. package/components/Switch/Switch.astro +101 -101
  43. package/components/Switch/SwitchInput.astro +25 -25
  44. package/components/Table/Body.astro +13 -13
  45. package/components/Table/Cell.astro +13 -13
  46. package/components/Table/Column.astro +15 -15
  47. package/components/Table/ColumnGroup.astro +13 -13
  48. package/components/Table/Head.astro +13 -13
  49. package/components/Table/HeaderCell.astro +13 -13
  50. package/components/Table/Row.astro +13 -13
  51. package/components/Table/Table.astro +18 -15
  52. package/components/Table/index.ts +20 -20
  53. package/components/Tabs/Tabs.astro +28 -28
  54. package/components/Tabs/TabsItem.astro +47 -47
  55. package/components/Tabs/TabsPanel.astro +21 -21
  56. package/components/Tabs/TabsTab.astro +19 -19
  57. package/components/Tabs/index.ts +14 -14
  58. package/components/TextField/TextField.astro +128 -128
  59. package/components/Textarea/Textarea.astro +106 -106
  60. package/components/Toast/Toast.astro +42 -42
  61. package/components/ToggleButton/ToggleButton.astro +53 -53
  62. package/components/ToggleGroup/ToggleGroup.astro +49 -49
  63. package/components/Tooltip/Tooltip.astro +30 -30
  64. package/core/normalize.css +194 -194
  65. package/core/palette.css +59 -59
  66. package/core/utils.css +71 -71
  67. package/css/components/accordion.css +174 -174
  68. package/css/components/anchor.css +27 -27
  69. package/css/components/avatar.css +65 -65
  70. package/css/components/badge.css +107 -107
  71. package/css/components/button-group.css +179 -179
  72. package/css/components/button.css +215 -215
  73. package/css/components/callout.css +109 -109
  74. package/css/components/card.css +117 -117
  75. package/css/components/checkbox.css +205 -205
  76. package/css/components/chip.css +87 -87
  77. package/css/components/description-list.css +80 -77
  78. package/css/components/dialog.css +68 -68
  79. package/css/components/divider.css +20 -20
  80. package/css/components/drawer.css +171 -171
  81. package/css/components/form.css +146 -146
  82. package/css/components/icon-button.css +139 -139
  83. package/css/components/link.css +21 -21
  84. package/css/components/list.css +345 -345
  85. package/css/components/progress.css +102 -97
  86. package/css/components/radio.css +172 -172
  87. package/css/components/range.css +337 -337
  88. package/css/components/select.css +169 -169
  89. package/css/components/spinner.css +37 -37
  90. package/css/components/switch.css +268 -268
  91. package/css/components/table.css +179 -179
  92. package/css/components/tabs.css +83 -77
  93. package/css/components/text-field.css +450 -450
  94. package/css/components/text-input.css +64 -64
  95. package/css/components/textarea.css +24 -24
  96. package/css/components/toast.css +161 -161
  97. package/css/components/toggle-button.css +87 -87
  98. package/css/components/toggle-group.css +56 -56
  99. package/css/components/tooltip.css +67 -67
  100. package/css/components/typography.css +585 -585
  101. package/css/components.css +41 -41
  102. package/css/imports.css +16 -16
  103. package/css/js/checkbox.js +21 -21
  104. package/css/js/toast.js +94 -94
  105. package/css/theme.css +132 -132
  106. package/dist/op.css +65 -65
  107. package/dist/op.css.map +1 -1
  108. package/dist/opui.components.css +5159 -5145
  109. package/dist/opui.components.css.map +1 -1
  110. package/dist/opui.css +5668 -5654
  111. package/dist/opui.css.map +1 -1
  112. package/env.d.ts +14 -14
  113. package/open-props.css +9 -9
  114. package/package.json +81 -81
@@ -1,49 +1,49 @@
1
- ---
2
- type Props = {
3
- [key: string]: any
4
- class?: string
5
- name?: string
6
- orientation?: "vertical"
7
- selection?: "single" | "multiple"
8
- size?: "default" | "small" | "x-small"
9
- }
10
-
11
- export const title = "Toggle Group"
12
-
13
- const {
14
- class: className,
15
- name,
16
- orientation,
17
- selection = "multiple",
18
- size = "default",
19
- ...rest
20
- } = Astro.props
21
-
22
- const { $id } = Astro.locals
23
- const groupName = name || $id("toggle-group")
24
- const inputType = selection === "single" ? "radio" : "checkbox"
25
-
26
- const originalName = Astro.locals.currentToggleGroupName
27
- const originalType = Astro.locals.currentToggleGroupType
28
-
29
- Astro.locals.currentToggleGroupName = groupName
30
- Astro.locals.currentToggleGroupType = inputType
31
-
32
- const html = await Astro.slots.render("default")
33
-
34
- Astro.locals.currentToggleGroupName = originalName
35
- Astro.locals.currentToggleGroupType = originalType
36
- ---
37
-
38
- <div
39
- class:list={[
40
- "toggle-group",
41
- size !== "default" && size,
42
- orientation,
43
- className,
44
- ]}
45
- role={selection === "single" ? "radiogroup" : "group"}
46
- {...rest}
47
- >
48
- <Fragment set:html={html} />
49
- </div>
1
+ ---
2
+ type Props = {
3
+ [key: string]: any
4
+ class?: string
5
+ name?: string
6
+ orientation?: "vertical"
7
+ selection?: "single" | "multiple"
8
+ size?: "default" | "small" | "x-small"
9
+ }
10
+
11
+ export const title = "Toggle Group"
12
+
13
+ const {
14
+ class: className,
15
+ name,
16
+ orientation,
17
+ selection = "multiple",
18
+ size = "default",
19
+ ...rest
20
+ } = Astro.props
21
+
22
+ const { $id } = Astro.locals
23
+ const groupName = name || $id("toggle-group")
24
+ const inputType = selection === "single" ? "radio" : "checkbox"
25
+
26
+ const originalName = Astro.locals.currentToggleGroupName
27
+ const originalType = Astro.locals.currentToggleGroupType
28
+
29
+ Astro.locals.currentToggleGroupName = groupName
30
+ Astro.locals.currentToggleGroupType = inputType
31
+
32
+ const html = await Astro.slots.render("default")
33
+
34
+ Astro.locals.currentToggleGroupName = originalName
35
+ Astro.locals.currentToggleGroupType = originalType
36
+ ---
37
+
38
+ <div
39
+ class:list={[
40
+ "ui-toggle-group",
41
+ size !== "default" && size && `ui-${size}`,
42
+ orientation && `ui-${orientation}`,
43
+ className,
44
+ ]}
45
+ role={selection === "single" ? "radiogroup" : "group"}
46
+ {...rest}
47
+ >
48
+ <Fragment set:html={html} />
49
+ </div>
@@ -1,30 +1,30 @@
1
- ---
2
- import Anchor from "../Anchor/Anchor.astro"
3
-
4
- type Props = {
5
- [key: string]: any
6
- alignment?: string
7
- arrow?: boolean
8
- class?: string
9
- id?: string
10
- label?: string
11
- }
12
-
13
- export const title = "Tooltip"
14
-
15
- const { alignment, arrow, class: className, id, label, ...rest } = Astro.props
16
- ---
17
-
18
- <Anchor
19
- alignment={alignment}
20
- class:list={["tooltip", { "with-arrow": arrow }, className]}
21
- id={id}
22
- trigger="hover"
23
- {...rest}
24
- >
25
- <slot />
26
- <Fragment slot="anchored">
27
- {label}
28
- <slot name="content" />
29
- </Fragment>
30
- </Anchor>
1
+ ---
2
+ import Anchor from "../Anchor/Anchor.astro"
3
+
4
+ type Props = {
5
+ [key: string]: any
6
+ alignment?: string
7
+ arrow?: boolean
8
+ class?: string
9
+ id?: string
10
+ label?: string
11
+ }
12
+
13
+ export const title = "Tooltip"
14
+
15
+ const { alignment, arrow, class: className, id, label, ...rest } = Astro.props
16
+ ---
17
+
18
+ <Anchor
19
+ alignment={alignment}
20
+ class:list={["ui-tooltip", { "ui-with-arrow": arrow }, className]}
21
+ id={id}
22
+ trigger="hover"
23
+ {...rest}
24
+ >
25
+ <slot />
26
+ <Fragment slot="anchored">
27
+ {label}
28
+ <slot name="content" />
29
+ </Fragment>
30
+ </Anchor>
@@ -1,194 +1,194 @@
1
- @layer normalize {
2
-
3
- *,
4
- ::before,
5
- ::after {
6
- /* Set box sizing instead of inheriting */
7
- /* https://www.oddbird.net/2025/09/04/box-model/ */
8
- box-sizing: border-box;
9
- }
10
-
11
- * {
12
- scrollbar-width: thin;
13
- }
14
-
15
- :where(html) {
16
- --_page-bg-color: var(--surface-default);
17
-
18
- accent-color: var(--primary);
19
- background-color: var(--_page-bg-color);
20
- block-size: 100%;
21
- caret-color: var(--primary);
22
- color: var(--text-muted, var(--text-color-2));
23
- /* text-color-2 is for backwards compatibility */
24
- font-family: var(--font-sans);
25
- interpolate-size: allow-keywords;
26
- line-height: var(--font-lineheight-4);
27
-
28
- /* https://kilianvalkhof.com/2022/css-html/your-css-reset-needs-text-size-adjust-probably/ */
29
- -moz-text-size-adjust: none;
30
- -webkit-text-size-adjust: none;
31
- text-size-adjust: none;
32
-
33
- @media (prefers-reduced-motion: no-preference) {
34
- scroll-behavior: smooth;
35
- }
36
- }
37
-
38
- :where(body) {
39
- -moz-osx-font-smoothing: grayscale;
40
- -webkit-font-smoothing: antialiased;
41
- container-type: inline-size;
42
- font-size: 16px;
43
- font-synthesis: style;
44
- font-weight: 400;
45
- inline-size: 100%;
46
- margin: 0;
47
- min-block-size: 100%;
48
- min-inline-size: 320px;
49
- position: relative;
50
- text-rendering: optimizeLegibility;
51
- }
52
-
53
- :where(:not(dialog, popover)) {
54
- margin: 0;
55
- }
56
-
57
- :where(dialog:not([open])) {
58
- outline: none !important;
59
- }
60
-
61
-
62
- :where(:not(fieldset, progress, meter)) {
63
- background-origin: border-box;
64
- background-repeat: no-repeat;
65
- border-style: solid;
66
- border-width: 0;
67
- }
68
-
69
- :where(fieldset) {
70
- border: var(--field-border-width) solid var(--field-border-color);
71
- border-radius: var(--field-border-radius);
72
- padding: var(--size-3);
73
- display: grid;
74
- gap: var(--size-3);
75
- }
76
-
77
- :where(input, button, textarea),
78
- :where(input[type="file"])::-webkit-file-upload-button {
79
- color: inherit;
80
- font: inherit;
81
- letter-spacing: inherit;
82
- }
83
-
84
- :where(input):-webkit-autofill,
85
- :where(input):-webkit-autofill:hover,
86
- :where(input):-webkit-autofill:focus,
87
- :where(textarea):-webkit-autofill,
88
- :where(textarea):-webkit-autofill:hover,
89
- :where(textarea):-webkit-autofill:focus,
90
- :where(select):-webkit-autofill,
91
- :where(select):-webkit-autofill:hover,
92
- :where(select):-webkit-autofill:focus,
93
- :where(input):autofill,
94
- :where(input):autofill:hover,
95
- :where(input):autofill:focus,
96
- :where(textarea):autofill,
97
- :where(textarea):autofill:hover,
98
- :where(textarea):autofill:focus,
99
- :where(select):autofill,
100
- :where(select):autofill:hover,
101
- :where(select):autofill:focus {
102
- -webkit-text-fill-color: var(--text-muted, var(--text-color-2));
103
- -webkit-box-shadow: 0 0 0px 1e5px var(--well-1) inset;
104
- transition: background-color 5000s ease-in-out 0s;
105
- }
106
-
107
- ::placeholder {
108
- color: var(--text-muted, var(--text-color-2));
109
- }
110
-
111
- ::-moz-placeholder {
112
- opacity: 1;
113
- }
114
-
115
- :focus-visible {
116
- /* Inverts the --_page-bg-color */
117
- --_focus-visible-color: rgb(from var(--_page-bg-color) calc(255 - r) calc(255 - g) calc(255 - b));
118
-
119
- border-radius: var(--border-radius, 0px);
120
- outline: 2px solid var(--_focus-visible-color);
121
- outline-offset: 2px;
122
- }
123
-
124
- @media (prefers-reduced-motion: no-preference) {
125
- :where(:focus-visible) {
126
- transition: outline-offset .15 var(--ease-2);
127
- }
128
-
129
- :where(:not(:active):focus-visible) {
130
- transition-duration: 0.15s;
131
- }
132
- }
133
-
134
- :where(:not(:active):focus-visible) {
135
- outline-offset: var(--outline-offset, 0px);
136
- }
137
-
138
- :where(a[href],
139
- area,
140
- button,
141
- input:not([type="text"],
142
- [type="email"],
143
- [type="number"],
144
- [type="password"],
145
- [type=""],
146
- [type="tel"],
147
- [type="url"]),
148
- label[for],
149
- select,
150
- summary) {
151
- cursor: pointer;
152
- }
153
-
154
- :where(a[href],
155
- area,
156
- button,
157
- [role="button"],
158
- input,
159
- label[for],
160
- select,
161
- summary,
162
- textarea,
163
- [tabindex]:not([tabindex*="-"])) {
164
- -webkit-tap-highlight-color: transparent;
165
- touch-action: manipulation;
166
- }
167
-
168
- :where(img, svg, video, canvas, audio, iframe, embed, object) {
169
- display: block;
170
- }
171
-
172
- :where(img, svg, video) {
173
- block-size: auto;
174
- max-inline-size: 100%;
175
- }
176
-
177
- :where(svg:not([width])) {
178
- inline-size: var(--size-7);
179
- }
180
-
181
- :where(dt:not(:first-of-type)) {
182
- margin-block-start: var(--size-5);
183
- }
184
-
185
- :where(figure) {
186
- display: grid;
187
- gap: var(--size-2);
188
- place-items: center;
189
- }
190
-
191
- :target {
192
- scroll-margin-block-start: 2rem;
193
- }
194
- }
1
+ @layer normalize {
2
+
3
+ *,
4
+ ::before,
5
+ ::after {
6
+ /* Set box sizing instead of inheriting */
7
+ /* https://www.oddbird.net/2025/09/04/box-model/ */
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ * {
12
+ scrollbar-width: thin;
13
+ }
14
+
15
+ :where(html) {
16
+ --_page-bg-color: var(--surface-default);
17
+
18
+ accent-color: var(--primary);
19
+ background-color: var(--_page-bg-color);
20
+ block-size: 100%;
21
+ caret-color: var(--primary);
22
+ color: var(--text-muted, var(--text-color-2));
23
+ /* text-color-2 is for backwards compatibility */
24
+ font-family: var(--font-sans);
25
+ interpolate-size: allow-keywords;
26
+ line-height: var(--font-lineheight-4);
27
+
28
+ /* https://kilianvalkhof.com/2022/css-html/your-css-reset-needs-text-size-adjust-probably/ */
29
+ -moz-text-size-adjust: none;
30
+ -webkit-text-size-adjust: none;
31
+ text-size-adjust: none;
32
+
33
+ @media (prefers-reduced-motion: no-preference) {
34
+ scroll-behavior: smooth;
35
+ }
36
+ }
37
+
38
+ :where(body) {
39
+ -moz-osx-font-smoothing: grayscale;
40
+ -webkit-font-smoothing: antialiased;
41
+ container-type: inline-size;
42
+ font-size: 16px;
43
+ font-synthesis: style;
44
+ font-weight: 400;
45
+ inline-size: 100%;
46
+ margin: 0;
47
+ min-block-size: 100%;
48
+ min-inline-size: 320px;
49
+ position: relative;
50
+ text-rendering: optimizeLegibility;
51
+ }
52
+
53
+ :where(:not(dialog, popover)) {
54
+ margin: 0;
55
+ }
56
+
57
+ :where(dialog:not([open])) {
58
+ outline: none !important;
59
+ }
60
+
61
+
62
+ :where(:not(fieldset, progress, meter)) {
63
+ background-origin: border-box;
64
+ background-repeat: no-repeat;
65
+ border-style: solid;
66
+ border-width: 0;
67
+ }
68
+
69
+ :where(fieldset) {
70
+ border: var(--field-border-width) solid var(--field-border-color);
71
+ border-radius: var(--field-border-radius);
72
+ padding: var(--size-3);
73
+ display: grid;
74
+ gap: var(--size-3);
75
+ }
76
+
77
+ :where(input, button, textarea),
78
+ :where(input[type="file"])::-webkit-file-upload-button {
79
+ color: inherit;
80
+ font: inherit;
81
+ letter-spacing: inherit;
82
+ }
83
+
84
+ :where(input):-webkit-autofill,
85
+ :where(input):-webkit-autofill:hover,
86
+ :where(input):-webkit-autofill:focus,
87
+ :where(textarea):-webkit-autofill,
88
+ :where(textarea):-webkit-autofill:hover,
89
+ :where(textarea):-webkit-autofill:focus,
90
+ :where(select):-webkit-autofill,
91
+ :where(select):-webkit-autofill:hover,
92
+ :where(select):-webkit-autofill:focus,
93
+ :where(input):autofill,
94
+ :where(input):autofill:hover,
95
+ :where(input):autofill:focus,
96
+ :where(textarea):autofill,
97
+ :where(textarea):autofill:hover,
98
+ :where(textarea):autofill:focus,
99
+ :where(select):autofill,
100
+ :where(select):autofill:hover,
101
+ :where(select):autofill:focus {
102
+ -webkit-text-fill-color: var(--text-muted, var(--text-color-2));
103
+ -webkit-box-shadow: 0 0 0px 1e5px var(--well-1) inset;
104
+ transition: background-color 5000s ease-in-out 0s;
105
+ }
106
+
107
+ ::placeholder {
108
+ color: var(--text-muted, var(--text-color-2));
109
+ }
110
+
111
+ ::-moz-placeholder {
112
+ opacity: 1;
113
+ }
114
+
115
+ :focus-visible {
116
+ /* Inverts the --_page-bg-color */
117
+ --_focus-visible-color: rgb(from var(--_page-bg-color) calc(255 - r) calc(255 - g) calc(255 - b));
118
+
119
+ border-radius: var(--border-radius, 0px);
120
+ outline: 2px solid var(--_focus-visible-color);
121
+ outline-offset: 2px;
122
+ }
123
+
124
+ @media (prefers-reduced-motion: no-preference) {
125
+ :where(:focus-visible) {
126
+ transition: outline-offset .15 var(--ease-2);
127
+ }
128
+
129
+ :where(:not(:active):focus-visible) {
130
+ transition-duration: 0.15s;
131
+ }
132
+ }
133
+
134
+ :where(:not(:active):focus-visible) {
135
+ outline-offset: var(--outline-offset, 0px);
136
+ }
137
+
138
+ :where(a[href],
139
+ area,
140
+ button,
141
+ input:not([type="text"],
142
+ [type="email"],
143
+ [type="number"],
144
+ [type="password"],
145
+ [type=""],
146
+ [type="tel"],
147
+ [type="url"]),
148
+ label[for],
149
+ select,
150
+ summary) {
151
+ cursor: pointer;
152
+ }
153
+
154
+ :where(a[href],
155
+ area,
156
+ button,
157
+ [role="button"],
158
+ input,
159
+ label[for],
160
+ select,
161
+ summary,
162
+ textarea,
163
+ [tabindex]:not([tabindex*="-"])) {
164
+ -webkit-tap-highlight-color: transparent;
165
+ touch-action: manipulation;
166
+ }
167
+
168
+ :where(img, svg, video, canvas, audio, iframe, embed, object) {
169
+ display: block;
170
+ }
171
+
172
+ :where(img, svg, video) {
173
+ block-size: auto;
174
+ max-inline-size: 100%;
175
+ }
176
+
177
+ :where(svg:not([width])) {
178
+ inline-size: var(--size-7);
179
+ }
180
+
181
+ :where(dt:not(:first-of-type)) {
182
+ margin-block-start: var(--size-5);
183
+ }
184
+
185
+ :where(figure) {
186
+ display: grid;
187
+ gap: var(--size-2);
188
+ place-items: center;
189
+ }
190
+
191
+ :target {
192
+ scroll-margin-block-start: 2rem;
193
+ }
194
+ }
package/core/palette.css CHANGED
@@ -1,59 +1,59 @@
1
- :where(:root) {
2
- --palette-hue: 250;
3
- /* <angle */
4
- --palette-hue-rotate-by: 0;
5
- /* +- deg : warm or cool the palette */
6
- --palette-chroma: 0.15;
7
- /* 0-1 : lower to mute and pastel, over 2 at own risk */
8
-
9
- /* New API: a single OKLCH source that drives the entire ramp.
10
- The default below derives from the legacy --palette-hue / --palette-chroma
11
- vars so themes that haven't migrated keep working unchanged. Themes opting
12
- into the new API just set --palette-source directly. */
13
- --palette-source: oklch(58% calc(0.21 * var(--palette-chroma, 1)) var(--palette-hue, 250));
14
- }
15
-
16
- * {
17
- --color-1: oklch(from var(--palette-source) 98% calc(0.03 * (c / 0.21)) calc(h + (0 * var(--palette-hue-rotate-by))));
18
- --color-2: oklch(from var(--palette-source) 97% calc(0.06 * (c / 0.21)) calc(h + (1 * var(--palette-hue-rotate-by))));
19
- --color-3: oklch(from var(--palette-source) 93% calc(0.1 * (c / 0.21)) calc(h + (2 * var(--palette-hue-rotate-by))));
20
- --color-4: oklch(from var(--palette-source) 84% calc(0.12 * (c / 0.21)) calc(h + (3 * var(--palette-hue-rotate-by))));
21
- --color-5: oklch(from var(--palette-source) 80% calc(0.16 * (c / 0.21)) calc(h + (4 * var(--palette-hue-rotate-by))));
22
- --color-6: oklch(from var(--palette-source) 71% calc(0.19 * (c / 0.21)) calc(h + (5 * var(--palette-hue-rotate-by))));
23
- --color-7: oklch(from var(--palette-source) 66% calc(0.2 * (c / 0.21)) calc(h + (6 * var(--palette-hue-rotate-by))));
24
- --color-8: oklch(from var(--palette-source) 58% calc(0.21 * (c / 0.21)) calc(h + (7 * var(--palette-hue-rotate-by))));
25
- --color-9: oklch(from var(--palette-source) 53% calc(0.2 * (c / 0.21)) calc(h + (8 * var(--palette-hue-rotate-by))));
26
- --color-10: oklch(from var(--palette-source) 49% calc(0.19 * (c / 0.21)) calc(h + (9 * var(--palette-hue-rotate-by))));
27
- --color-11: oklch(from var(--palette-source) 42% calc(0.17 * (c / 0.21)) calc(h + (10 * var(--palette-hue-rotate-by))));
28
- --color-12: oklch(from var(--palette-source) 35% calc(0.15 * (c / 0.21)) calc(h + (11 * var(--palette-hue-rotate-by))));
29
- --color-13: oklch(from var(--palette-source) 27% calc(0.12 * (c / 0.21)) calc(h + (12 * var(--palette-hue-rotate-by))));
30
- --color-14: oklch(from var(--palette-source) 20% calc(0.09 * (c / 0.21)) calc(h + (13 * var(--palette-hue-rotate-by))));
31
- --color-15: oklch(from var(--palette-source) 16% calc(0.07 * (c / 0.21)) calc(h + (14 * var(--palette-hue-rotate-by))));
32
- --color-16: oklch(from var(--palette-source) 10% calc(0.05 * (c / 0.21)) calc(h + (15 * var(--palette-hue-rotate-by))));
33
- }
34
-
35
- /* Gray ramp — derived from each --color-N step so it shares the palette's
36
- per-step lightness curve. --gray-chroma / --gray-hue follow the Open Props
37
- convention (hue is the third oklch arg, NOT lightness). Override either
38
- in a theme to warm/cool the grays without redefining each --gray-N. */
39
- * {
40
- --gray-chroma: 0.01;
41
- --gray-hue: 255;
42
-
43
- --gray-1: oklch(from var(--color-1) l var(--gray-chroma) var(--gray-hue));
44
- --gray-2: oklch(from var(--color-2) l var(--gray-chroma) var(--gray-hue));
45
- --gray-3: oklch(from var(--color-3) l var(--gray-chroma) var(--gray-hue));
46
- --gray-4: oklch(from var(--color-4) l var(--gray-chroma) var(--gray-hue));
47
- --gray-5: oklch(from var(--color-5) l var(--gray-chroma) var(--gray-hue));
48
- --gray-6: oklch(from var(--color-6) l var(--gray-chroma) var(--gray-hue));
49
- --gray-7: oklch(from var(--color-7) l var(--gray-chroma) var(--gray-hue));
50
- --gray-8: oklch(from var(--color-8) l var(--gray-chroma) var(--gray-hue));
51
- --gray-9: oklch(from var(--color-9) l var(--gray-chroma) var(--gray-hue));
52
- --gray-10: oklch(from var(--color-10) l var(--gray-chroma) var(--gray-hue));
53
- --gray-11: oklch(from var(--color-11) l var(--gray-chroma) var(--gray-hue));
54
- --gray-12: oklch(from var(--color-12) l var(--gray-chroma) var(--gray-hue));
55
- --gray-13: oklch(from var(--color-13) l var(--gray-chroma) var(--gray-hue));
56
- --gray-14: oklch(from var(--color-14) l var(--gray-chroma) var(--gray-hue));
57
- --gray-15: oklch(from var(--color-15) l var(--gray-chroma) var(--gray-hue));
58
- --gray-16: oklch(from var(--color-16) l var(--gray-chroma) var(--gray-hue));
59
- }
1
+ :where(:root) {
2
+ --palette-hue: 250;
3
+ /* <angle */
4
+ --palette-hue-rotate-by: 0;
5
+ /* +- deg : warm or cool the palette */
6
+ --palette-chroma: 0.15;
7
+ /* 0-1 : lower to mute and pastel, over 2 at own risk */
8
+
9
+ /* New API: a single OKLCH source that drives the entire ramp.
10
+ The default below derives from the legacy --palette-hue / --palette-chroma
11
+ vars so themes that haven't migrated keep working unchanged. Themes opting
12
+ into the new API just set --palette-source directly. */
13
+ --palette-source: oklch(58% calc(0.21 * var(--palette-chroma, 1)) var(--palette-hue, 250));
14
+ }
15
+
16
+ * {
17
+ --color-1: oklch(from var(--palette-source) 98% calc(0.03 * (c / 0.21)) calc(h + (0 * var(--palette-hue-rotate-by))));
18
+ --color-2: oklch(from var(--palette-source) 97% calc(0.06 * (c / 0.21)) calc(h + (1 * var(--palette-hue-rotate-by))));
19
+ --color-3: oklch(from var(--palette-source) 93% calc(0.1 * (c / 0.21)) calc(h + (2 * var(--palette-hue-rotate-by))));
20
+ --color-4: oklch(from var(--palette-source) 84% calc(0.12 * (c / 0.21)) calc(h + (3 * var(--palette-hue-rotate-by))));
21
+ --color-5: oklch(from var(--palette-source) 80% calc(0.16 * (c / 0.21)) calc(h + (4 * var(--palette-hue-rotate-by))));
22
+ --color-6: oklch(from var(--palette-source) 71% calc(0.19 * (c / 0.21)) calc(h + (5 * var(--palette-hue-rotate-by))));
23
+ --color-7: oklch(from var(--palette-source) 66% calc(0.2 * (c / 0.21)) calc(h + (6 * var(--palette-hue-rotate-by))));
24
+ --color-8: oklch(from var(--palette-source) 58% calc(0.21 * (c / 0.21)) calc(h + (7 * var(--palette-hue-rotate-by))));
25
+ --color-9: oklch(from var(--palette-source) 53% calc(0.2 * (c / 0.21)) calc(h + (8 * var(--palette-hue-rotate-by))));
26
+ --color-10: oklch(from var(--palette-source) 49% calc(0.19 * (c / 0.21)) calc(h + (9 * var(--palette-hue-rotate-by))));
27
+ --color-11: oklch(from var(--palette-source) 42% calc(0.17 * (c / 0.21)) calc(h + (10 * var(--palette-hue-rotate-by))));
28
+ --color-12: oklch(from var(--palette-source) 35% calc(0.15 * (c / 0.21)) calc(h + (11 * var(--palette-hue-rotate-by))));
29
+ --color-13: oklch(from var(--palette-source) 27% calc(0.12 * (c / 0.21)) calc(h + (12 * var(--palette-hue-rotate-by))));
30
+ --color-14: oklch(from var(--palette-source) 20% calc(0.09 * (c / 0.21)) calc(h + (13 * var(--palette-hue-rotate-by))));
31
+ --color-15: oklch(from var(--palette-source) 16% calc(0.07 * (c / 0.21)) calc(h + (14 * var(--palette-hue-rotate-by))));
32
+ --color-16: oklch(from var(--palette-source) 10% calc(0.05 * (c / 0.21)) calc(h + (15 * var(--palette-hue-rotate-by))));
33
+ }
34
+
35
+ /* Gray ramp — derived from each --color-N step so it shares the palette's
36
+ per-step lightness curve. --gray-chroma / --gray-hue follow the Open Props
37
+ convention (hue is the third oklch arg, NOT lightness). Override either
38
+ in a theme to warm/cool the grays without redefining each --gray-N. */
39
+ * {
40
+ --gray-chroma: 0.01;
41
+ --gray-hue: 255;
42
+
43
+ --gray-1: oklch(from var(--color-1) l var(--gray-chroma) var(--gray-hue));
44
+ --gray-2: oklch(from var(--color-2) l var(--gray-chroma) var(--gray-hue));
45
+ --gray-3: oklch(from var(--color-3) l var(--gray-chroma) var(--gray-hue));
46
+ --gray-4: oklch(from var(--color-4) l var(--gray-chroma) var(--gray-hue));
47
+ --gray-5: oklch(from var(--color-5) l var(--gray-chroma) var(--gray-hue));
48
+ --gray-6: oklch(from var(--color-6) l var(--gray-chroma) var(--gray-hue));
49
+ --gray-7: oklch(from var(--color-7) l var(--gray-chroma) var(--gray-hue));
50
+ --gray-8: oklch(from var(--color-8) l var(--gray-chroma) var(--gray-hue));
51
+ --gray-9: oklch(from var(--color-9) l var(--gray-chroma) var(--gray-hue));
52
+ --gray-10: oklch(from var(--color-10) l var(--gray-chroma) var(--gray-hue));
53
+ --gray-11: oklch(from var(--color-11) l var(--gray-chroma) var(--gray-hue));
54
+ --gray-12: oklch(from var(--color-12) l var(--gray-chroma) var(--gray-hue));
55
+ --gray-13: oklch(from var(--color-13) l var(--gray-chroma) var(--gray-hue));
56
+ --gray-14: oklch(from var(--color-14) l var(--gray-chroma) var(--gray-hue));
57
+ --gray-15: oklch(from var(--color-15) l var(--gray-chroma) var(--gray-hue));
58
+ --gray-16: oklch(from var(--color-16) l var(--gray-chroma) var(--gray-hue));
59
+ }