tailwind-oklch 0.2.0 → 0.4.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.
Files changed (4) hide show
  1. package/README.md +102 -17
  2. package/index.css +71 -0
  3. package/package.json +5 -5
  4. package/plugin.js +34 -5
package/README.md CHANGED
@@ -74,20 +74,41 @@ Set one axis at a time. The other two axes inherit from the parent or the root d
74
74
 
75
75
  The same pattern applies to `border-b-*` (border-bottom), `accent-*`, `from-*` (gradient from), `to-*` (gradient to), and `shadow-*`.
76
76
 
77
- ### Shorthand Utilities (all axes at once)
77
+ ### Global Hue and Chroma
78
78
 
79
- The plugin generates shorthands that set all three axes in a single class:
79
+ Most of the time, every color property on an element shares the same hue — the differences are in lightness and chroma. The `hue-*` utility sets the hue for **all** color properties at once:
80
80
 
81
+ ```html
82
+ <!-- Set hue once, vary L and C per property -->
83
+ <div class="hue-danger bg-1-mid text-10-lo border-3-mhi">
84
+ <button class="bg-5-mhi text-0-lo">Acknowledge</button>
85
+ <button class="bg-5-mhi text-10-lo">Cancel</button>
86
+ </div>
81
87
  ```
82
- {property}-{L}-{C}-{H}
88
+
89
+ `chroma-*` does the same for chroma:
90
+
91
+ ```html
92
+ <!-- Everything low-chroma -->
93
+ <div class="hue-primary chroma-lo bg-lc-1 text-lc-fore border-lc-3">
83
94
  ```
84
95
 
85
- Examples:
96
+ Per-property utilities (`bg-h-*`, `text-c-*`, etc.) still work as overrides when you need one property to differ.
97
+
98
+ ### Shorthand Utilities
99
+
100
+ The plugin generates shorthands for common combinations:
101
+
102
+ **Two-axis: `{property}-{L}-{C}`** — sets luminance and chroma, inherits hue from the cascade (set by `hue-*` or `:root` default):
86
103
 
87
104
  ```html
88
- <div class="bg-3-mhi-accent"> <!-- L=3, C=medium-high, H=accent -->
89
- <p class="text-fore-lo-neutral"> <!-- L=foreground, C=low, H=neutral -->
90
- <div class="border-5-mid-primary"> <!-- L=5, C=medium, H=primary -->
105
+ <div class="hue-accent bg-3-mhi text-10-lo border-2-mid">
106
+ ```
107
+
108
+ **Three-axis: `{property}-{L}-{C}-{H}`** — sets all three axes explicitly in a single class:
109
+
110
+ ```html
111
+ <div class="bg-3-mhi-accent text-fore-lo-neutral border-5-mid-primary">
91
112
  ```
92
113
 
93
114
  Available properties: `bg`, `text`, `border`, `border-b`, `accent`, `from`, `to`.
@@ -129,6 +150,40 @@ All utilities work with standard Tailwind modifiers:
129
150
  </input>
130
151
  ```
131
152
 
153
+ ### Relative Luminance Offsets
154
+
155
+ Sometimes you don't want to set an absolute luminance — you want to nudge it relative to the inherited value. The `lc-up` and `lc-down` utilities shift luminance **toward more contrast** or **toward less contrast** without replacing the underlying `--bg-l` or `--tx-l` variable. This means children still inherit the original value.
156
+
157
+ - **`lc-up-{N}`** — increase contrast (move away from the page color)
158
+ - **`lc-down-{N}`** — decrease contrast (move toward the page color)
159
+
160
+ Where `{N}` is 1–5, with each step equal to ~0.08 OKLCH lightness (roughly one position on the 0–10 scale).
161
+
162
+ Available for `bg` and `text`:
163
+
164
+ | Pattern | Effect |
165
+ |---|---|
166
+ | `bg-lc-up-{N}` | Background becomes more contrasting |
167
+ | `bg-lc-down-{N}` | Background becomes less contrasting |
168
+ | `text-lc-up-{N}` | Text becomes more contrasting |
169
+ | `text-lc-down-{N}` | Text becomes less contrasting |
170
+
171
+ The direction automatically adapts to light/dark mode — "up" always means more contrast with the page, "down" always means less, regardless of whether luminance values are increasing or decreasing.
172
+
173
+ ```html
174
+ <!-- A card with a hover state one step brighter/darker than the parent -->
175
+ <div class="bg-3-mlo-primary">
176
+ <button class="hover:bg-lc-up-1">Slightly more contrast on hover</button>
177
+ <span class="bg-lc-down-2">Subtler background, closer to page</span>
178
+ </div>
179
+
180
+ <!-- Muted secondary text that's two steps less contrasting than default -->
181
+ <p class="text-fore-lo-neutral">
182
+ Primary text
183
+ <span class="text-lc-down-2">Secondary text</span>
184
+ </p>
185
+ ```
186
+
132
187
  ### Gradients
133
188
 
134
189
  ```html
@@ -217,18 +272,48 @@ document.documentElement.style.setProperty('--hue-primary', '180');
217
272
 
218
273
  A numeric chroma scale (`c-10` through `c-95`) is also available for finer control in the decomposed utilities.
219
274
 
275
+ ### LC Adjustment Steps
276
+
277
+ Used by the relative luminance offset utilities (`bg-lc-up-*`, `bg-lc-down-*`, etc.):
278
+
279
+ | Step | OKLCH L offset | Approximate scale positions |
280
+ |---|---|---|
281
+ | `1` | 0.08 | ~1 step |
282
+ | `2` | 0.16 | ~2 steps |
283
+ | `3` | 0.24 | ~3 steps |
284
+ | `4` | 0.32 | ~4 steps |
285
+ | `5` | 0.40 | ~5 steps |
286
+
287
+ Override in a `@theme` block:
288
+
289
+ ```css
290
+ @theme {
291
+ --lc-adj-1: 0.06; /* smaller steps */
292
+ --lc-adj-2: 0.12;
293
+ }
294
+ ```
295
+
220
296
  ### Supported Properties
221
297
 
222
- | Prefix | CSS Property | Decomposed | Shorthand |
223
- |---|---|---|---|
224
- | `bg` | `background-color` | `bg-lc-*`, `bg-c-*`, `bg-h-*` | `bg-{L}-{C}-{H}` |
225
- | `text` | `color` | `text-lc-*`, `text-c-*`, `text-h-*` | `text-{L}-{C}-{H}` |
226
- | `border` | `border-color` | `border-lc-*`, `border-c-*`, `border-h-*` | `border-{L}-{C}-{H}` |
227
- | `border-b` | `border-bottom-color` | `border-b-lc-*`, `border-b-c-*`, `border-b-h-*` | `border-b-{L}-{C}-{H}` |
228
- | `accent` | `accent-color` | `accent-lc-*`, `accent-c-*`, `accent-h-*` | `accent-{L}-{C}-{H}` |
229
- | `from` | gradient from | `from-lc-*`, `from-c-*`, `from-h-*` | `from-{L}-{C}-{H}` |
230
- | `to` | gradient to | `to-lc-*`, `to-c-*`, `to-h-*` | `to-{L}-{C}-{H}` |
231
- | `shadow` | shadow color | `shadow-lc-*`, `shadow-c-*`, `shadow-h-*` | |
298
+ **Global context setters** (set all properties at once):
299
+
300
+ | Utility | Sets |
301
+ |---|---|
302
+ | `hue-{H}` | Hue for all properties (`--bg-h`, `--tx-h`, `--bd-h`, etc.) |
303
+ | `chroma-{C}` | Chroma for all properties (`--bg-c`, `--tx-c`, `--bd-c`, etc.) |
304
+
305
+ **Per-property utilities:**
306
+
307
+ | Prefix | CSS Property | Decomposed | 2-axis Shorthand | 3-axis Shorthand |
308
+ |---|---|---|---|---|
309
+ | `bg` | `background-color` | `bg-lc-*`, `bg-c-*`, `bg-h-*` | `bg-{L}-{C}` | `bg-{L}-{C}-{H}` |
310
+ | `text` | `color` | `text-lc-*`, `text-c-*`, `text-h-*` | `text-{L}-{C}` | `text-{L}-{C}-{H}` |
311
+ | `border` | `border-color` | `border-lc-*`, `border-c-*`, `border-h-*` | `border-{L}-{C}` | `border-{L}-{C}-{H}` |
312
+ | `border-b` | `border-bottom-color` | `border-b-lc-*`, `border-b-c-*`, `border-b-h-*` | `border-b-{L}-{C}` | `border-b-{L}-{C}-{H}` |
313
+ | `accent` | `accent-color` | `accent-lc-*`, `accent-c-*`, `accent-h-*` | `accent-{L}-{C}` | `accent-{L}-{C}-{H}` |
314
+ | `from` | gradient from | `from-lc-*`, `from-c-*`, `from-h-*` | `from-{L}-{C}` | `from-{L}-{C}-{H}` |
315
+ | `to` | gradient to | `to-lc-*`, `to-c-*`, `to-h-*` | `to-{L}-{C}` | `to-{L}-{C}-{H}` |
316
+ | `shadow` | shadow color | `shadow-lc-*`, `shadow-c-*`, `shadow-h-*` | — | — |
232
317
 
233
318
  ### Light / Dark Mode
234
319
 
package/index.css CHANGED
@@ -82,6 +82,14 @@
82
82
  --c-80: 0.24;
83
83
  --c-90: 0.27;
84
84
  --c-95: 0.30;
85
+
86
+ /* ── LC Adjustment Steps ───────────────────────────────────────────
87
+ Each step ≈ one position on the 0–10 scale (~0.08 OKLCH L). */
88
+ --lc-adj-1: 0.08;
89
+ --lc-adj-2: 0.16;
90
+ --lc-adj-3: 0.24;
91
+ --lc-adj-4: 0.32;
92
+ --lc-adj-5: 0.40;
85
93
  }
86
94
 
87
95
  /* ── Light-mode luminance contrast range ──────────────────────────────
@@ -89,6 +97,7 @@
89
97
  the page), 10/fore is near black (high contrast, like text). */
90
98
 
91
99
  :root:not(.dark) {
100
+ --lc-dir: -1;
92
101
  --lc-range-start: 0.95;
93
102
  --lc-range-end: 0.15;
94
103
 
@@ -117,6 +126,8 @@
117
126
  naturally flows to children that only set bg-lc-* or bg-c-*. */
118
127
 
119
128
  :root {
129
+ --lc-dir: 1;
130
+
120
131
  --bg-l: var(--l-5);
121
132
  --bg-c: var(--c-lo);
122
133
  --bg-h: var(--hue-primary);
@@ -150,6 +161,38 @@
150
161
  --bdb-h: var(--hue-primary);
151
162
  }
152
163
 
164
+ /* ── Global Hue ─────────────────────────────────────────────────────────
165
+ Set the hue for ALL color properties at once. Per-property hue
166
+ utilities (bg-h-*, text-h-*, etc.) still work as overrides.
167
+ Usage: hue-primary, hue-accent, hue-danger, etc. */
168
+
169
+ @utility hue-* {
170
+ --bg-h: --value(--hue-*);
171
+ --tx-h: --value(--hue-*);
172
+ --bd-h: --value(--hue-*);
173
+ --bdb-h: --value(--hue-*);
174
+ --ac-h: --value(--hue-*);
175
+ --gf-h: --value(--hue-*);
176
+ --gt-h: --value(--hue-*);
177
+ --sh-h: --value(--hue-*);
178
+ }
179
+
180
+ /* ── Global Chroma ──────────────────────────────────────────────────────
181
+ Set the chroma for ALL color properties at once. Per-property chroma
182
+ utilities (bg-c-*, text-c-*, etc.) still work as overrides.
183
+ Usage: chroma-lo, chroma-mid, chroma-hi, etc. */
184
+
185
+ @utility chroma-* {
186
+ --bg-c: --value(--c-*);
187
+ --tx-c: --value(--c-*);
188
+ --bd-c: --value(--c-*);
189
+ --bdb-c: --value(--c-*);
190
+ --ac-c: --value(--c-*);
191
+ --gf-c: --value(--c-*);
192
+ --gt-c: --value(--c-*);
193
+ --sh-c: --value(--c-*);
194
+ }
195
+
153
196
  /* ── Background ──────────────────────────────────────────────────────── */
154
197
 
155
198
  @utility bg-lc-* {
@@ -167,6 +210,20 @@
167
210
  background-color: oklch(var(--bg-l) var(--bg-c) var(--bg-h));
168
211
  }
169
212
 
213
+ /* ── Background LC Adjustments ───────────────────────────────────────
214
+ Nudge background luminance up (more contrast) or down (less contrast)
215
+ relative to the current --bg-l, without changing --bg-l itself. */
216
+
217
+ @utility bg-lc-up-* {
218
+ --bg-l-adj: --value(--lc-adj-*);
219
+ background-color: oklch(clamp(0, calc(var(--bg-l) + var(--lc-dir) * var(--bg-l-adj)), 1) var(--bg-c) var(--bg-h));
220
+ }
221
+
222
+ @utility bg-lc-down-* {
223
+ --bg-l-adj: --value(--lc-adj-*);
224
+ background-color: oklch(clamp(0, calc(var(--bg-l) - var(--lc-dir) * var(--bg-l-adj)), 1) var(--bg-c) var(--bg-h));
225
+ }
226
+
170
227
  /* ── Text ────────────────────────────────────────────────────────────── */
171
228
 
172
229
  @utility text-lc-* {
@@ -184,6 +241,20 @@
184
241
  color: oklch(var(--tx-l) var(--tx-c) var(--tx-h));
185
242
  }
186
243
 
244
+ /* ── Text LC Adjustments ─────────────────────────────────────────────
245
+ Nudge text luminance up (more contrast) or down (less contrast)
246
+ relative to the current --tx-l, without changing --tx-l itself. */
247
+
248
+ @utility text-lc-up-* {
249
+ --tx-l-adj: --value(--lc-adj-*);
250
+ color: oklch(clamp(0, calc(var(--tx-l) + var(--lc-dir) * var(--tx-l-adj)), 1) var(--tx-c) var(--tx-h));
251
+ }
252
+
253
+ @utility text-lc-down-* {
254
+ --tx-l-adj: --value(--lc-adj-*);
255
+ color: oklch(clamp(0, calc(var(--tx-l) - var(--lc-dir) * var(--tx-l-adj)), 1) var(--tx-c) var(--tx-h));
256
+ }
257
+
187
258
  /* ── Border ──────────────────────────────────────────────────────────── */
188
259
 
189
260
  @utility border-lc-* {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailwind-oklch",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "OKLCH color composition system for Tailwind CSS v4",
5
5
  "style": "index.css",
6
6
  "main": "index.css",
@@ -12,9 +12,6 @@
12
12
  "index.css",
13
13
  "plugin.js"
14
14
  ],
15
- "scripts": {
16
- "format": "oxfmt --write \"demo/src/**/*.{ts,tsx,js,mjs}\" \"demo/astro.config.mjs\""
17
- },
18
15
  "peerDependencies": {
19
16
  "tailwindcss": ">=4.0.0"
20
17
  },
@@ -27,5 +24,8 @@
27
24
  "license": "MIT",
28
25
  "devDependencies": {
29
26
  "oxfmt": "^0.32.0"
27
+ },
28
+ "scripts": {
29
+ "format": "oxfmt --write \"demo/src/**/*.{ts,tsx,js,mjs}\" \"demo/astro.config.mjs\""
30
30
  }
31
- }
31
+ }
package/plugin.js CHANGED
@@ -1,12 +1,18 @@
1
1
  /**
2
2
  * tailwind-oklch shorthand generator
3
3
  *
4
- * Generates .{prop}-{L}-{C}-{H} utilities for all combinations of
5
- * the 0–10 luminance contrast scale × chroma × hue stops across bg/text/border.
4
+ * Generates two kinds of shorthand utilities:
6
5
  *
7
- * Each shorthand sets the three axis variables AND applies the
8
- * resolved color, so children can inherit and override single axes
9
- * via decomposed utilities (e.g. hover:bg-lc-8).
6
+ * Three-axis: .{prop}-{L}-{C}-{H} — sets all three axes explicitly
7
+ * e.g. bg-3-mhi-accent
8
+ *
9
+ * Two-axis: .{prop}-{L}-{C} — sets L and C, inherits H from
10
+ * the cascade (set by hue-* or :root default)
11
+ * e.g. bg-3-mhi (pair with hue-accent on a parent)
12
+ *
13
+ * Each shorthand sets the axis variables AND applies the resolved
14
+ * color, so children can inherit and override single axes via
15
+ * decomposed utilities (e.g. hover:bg-lc-8).
10
16
  *
11
17
  * Load via: @plugin "tailwind-oklch/plugin";
12
18
  */
@@ -28,8 +34,16 @@ module.exports = function ({ addUtilities }) {
28
34
  const utilities = {};
29
35
 
30
36
  for (const prop of properties) {
37
+ // Two-axis shorthands: .{prop}-{L}-{C} — inherits H from cascade
31
38
  for (const l of luminances) {
32
39
  for (const c of chromas) {
40
+ utilities[`.${prop.prefix}-${l}-${c}`] = {
41
+ [prop.vars[0]]: `var(--l-${l})`,
42
+ [prop.vars[1]]: `var(--c-${c})`,
43
+ [prop.css]: `oklch(var(${prop.vars[0]}) var(${prop.vars[1]}) var(${prop.vars[2]}))`,
44
+ };
45
+
46
+ // Three-axis shorthands: .{prop}-{L}-{C}-{H}
33
47
  for (const h of hues) {
34
48
  utilities[`.${prop.prefix}-${l}-${c}-${h}`] = {
35
49
  [prop.vars[0]]: `var(--l-${l})`,
@@ -48,6 +62,21 @@ module.exports = function ({ addUtilities }) {
48
62
 
49
63
  for (const l of luminances) {
50
64
  for (const c of chromas) {
65
+ // Two-axis gradient shorthands — inherit H from cascade
66
+ utilities[`.from-${l}-${c}`] = {
67
+ '--gf-l': `var(--l-${l})`,
68
+ '--gf-c': `var(--c-${c})`,
69
+ '--tw-gradient-from': `oklch(var(--gf-l) var(--gf-c) var(--gf-h))`,
70
+ '--tw-gradient-stops': stopsExpr,
71
+ };
72
+ utilities[`.to-${l}-${c}`] = {
73
+ '--gt-l': `var(--l-${l})`,
74
+ '--gt-c': `var(--c-${c})`,
75
+ '--tw-gradient-to': `oklch(var(--gt-l) var(--gt-c) var(--gt-h))`,
76
+ '--tw-gradient-stops': stopsExpr,
77
+ };
78
+
79
+ // Three-axis gradient shorthands
51
80
  for (const h of hues) {
52
81
  utilities[`.from-${l}-${c}-${h}`] = {
53
82
  '--gf-l': `var(--l-${l})`,