@tenphi/cookbook 0.31.0 → 0.31.2

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.
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/tenphi/glaze/v2.0.1/assets/glaze.svg" width="128" height="128" alt="Glaze logo">
2
+ <img src="https://raw.githubusercontent.com/tenphi/glaze/v2.0.2/assets/glaze.svg" width="128" height="128" alt="Glaze logo">
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Glaze</h1>
@@ -143,14 +143,15 @@ In Glaze, a **scheme variant** is one of `light`, `dark`, `lightContrast`, or
143
143
 
144
144
  ## Documentation
145
145
 
146
+ * Explore the tone axis in the [interactive playground](https://glaze.tenphi.me/playground/).
146
147
  * Start with [the methodology](docs/methodology.md) to design a palette.
147
148
  * Use [migration and integration](docs/migration.md) to wire it into an
148
149
  application or replace an existing color system.
149
150
  * Keep the [API reference](docs/api.md) nearby for every method and option.
150
151
  * Read [OKHST in Glaze](docs/okhst.md) for the product-level color model, or
151
152
  the [full OKHST specification](https://github.com/tenphi/okhst) for its math.
152
- * [`AGENTS.md`](https://github.com/tenphi/glaze/blob/v2.0.1/AGENTS.md) — source-tree orientation for contributors.
153
+ * [`AGENTS.md`](https://github.com/tenphi/glaze/blob/main/AGENTS.md) — source-tree orientation for contributors.
153
154
 
154
155
  ## License
155
156
 
156
- [MIT](LICENSE)
157
+ [MIT](https://github.com/tenphi/glaze/blob/main/LICENSE)
@@ -1,18 +1,18 @@
1
1
  [
2
2
  {
3
3
  "name": "@tenphi/tasty",
4
- "version": "3.14.0",
4
+ "version": "3.16.0",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/tenphi/tasty",
7
- "ref": "v3.14.0",
7
+ "ref": "v3.16.0",
8
8
  "directory": "upstream/tasty"
9
9
  },
10
10
  {
11
11
  "name": "@tenphi/glaze",
12
- "version": "2.0.1",
12
+ "version": "2.0.2",
13
13
  "license": "MIT",
14
14
  "repository": "https://github.com/tenphi/glaze",
15
- "ref": "v2.0.1",
15
+ "ref": "v2.0.2",
16
16
  "directory": "upstream/glaze"
17
17
  }
18
18
  ]
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="https://raw.githubusercontent.com/tenphi/tasty/v3.14.0/assets/tasty.svg" width="128" height="128" alt="Tasty logo" />
2
+ <img src="https://raw.githubusercontent.com/tenphi/tasty/v3.16.0/assets/tasty.svg" width="128" height="128" alt="Tasty logo" />
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Tasty</h1>
@@ -548,7 +548,7 @@ Covered in [Types and Linting](#eslint-and-oxlint): 40+ rules for ESLint 9+ and
548
548
  [Tasty for VS Code](https://github.com/tenphi/tasty-vscode-extension) highlights color tokens, units, state keys, presets, and style properties inside `tasty()`, `tastyStatic()`, `styles` objects, and style functions, and adds snippets for components, state maps, and `configure()`. Install the `.vsix` from the [latest release](https://github.com/tenphi/tasty-vscode-extension/releases/latest).
549
549
 
550
550
  <p align="center">
551
- <img src="https://raw.githubusercontent.com/tenphi/tasty/v3.14.0/assets/tasty-vscode-highlight.png" width="512" alt="Tasty VS Code syntax highlighting example" />
551
+ <img src="https://raw.githubusercontent.com/tenphi/tasty/v3.16.0/assets/tasty-vscode-highlight.png" width="512" alt="Tasty VS Code syntax highlighting example" />
552
552
  </p>
553
553
 
554
554
  ### Glaze
@@ -72,6 +72,7 @@ The last row goes the other way — longhands over the shorthand — because `fl
72
72
  | `#name.50` | token at 50% opacity — digits are a decimal fraction: `.5` = `.50` = 50%, `.05` = 5%, `.100` = 10% |
73
73
  | `#name.$opacity` | opacity from a custom property |
74
74
  | `#clear` / `#current` | `transparent` / `currentcolor` |
75
+ | `#a+#b.04` | `#b` at 4% opacity over `#a`, as one color; layers stack left to right (`#a+#b.1+#c.04`) |
75
76
  | `$name` | custom property → `var(--name)` |
76
77
  | `(#a, #b)` | fallback chain |
77
78
  | `$$name` / `##name` | the custom property _name_ (not its value) — inside `transition` |
@@ -134,7 +135,7 @@ Directional modifiers beat placeholder zeros:
134
135
  - ❌ `padding: '2x 4x top right'` — a directional group takes one value, so `4x` is dropped → ✅ `padding: '2x top, 4x right'`
135
136
  - ❌ `fade: '3x 1x top bottom'` → ✅ `fade: '3x top, 1x bottom'`
136
137
 
137
- Value-only properties reject both colors and modifiers: `gap`, `columnGap`, `rowGap`, `opacity`, `zIndex`, `order`, `flexGrow`, `flexShrink`, `flexBasis`, `aspectRatio`, `lineClamp`, and `tabSize`. Logical axis category styles accept one or two values in start/end order and the `start`, `end`, and `longhand` modifiers. `fill`, `color`, `caretColor`, and `accentColor` take a color only (use `#clear` for transparent).
138
+ Value-only properties reject both colors and modifiers: `gap`, `columnGap`, `rowGap`, `opacity`, `zIndex`, `order`, `flexGrow`, `flexShrink`, `flexBasis`, `aspectRatio`, `lineClamp`, and `tabSize`. Logical axis category styles accept one or two values in start/end order and the `start`, `end`, and `longhand` modifiers. `fill`, `color`, `caretColor`, and `accentColor` take a color only (use `#clear` for transparent). An overlay is a compound color, in any color slot: ❌ `fill: '#surface #dark.04'` (deprecated overlay layer) · ❌ `fill: '#dark.04, #surface'` (half-transparent mix) → ✅ `fill: '#surface+#dark.04'`. Write it as one word, with no spaces around `+`. Every layer after the first needs an opacity suffix, and its token must be opaque: a translucent layer token, or one that is `#clear` in some state, leaves the result see-through, so vary the suffix (`#surface+#dark.$hover`) or the whole compound per state instead. `fill` also mixes two colors with a comma, the weight as a percentage: `'#dark 4%, #surface'`.
138
139
 
139
140
  ### `transition`
140
141
 
@@ -168,6 +168,7 @@ color: '#purple.5', // 50% opacity
168
168
  color: '#purple.05', // 5% opacity
169
169
  color: '#purple.$fade', // Opacity from a custom property
170
170
  fill: '#current', // → currentcolor
171
+ fill: '#surface+#dark.04', // #dark at 4% opacity over #surface, as one color
171
172
  color: '(#primary, #secondary)', // Fallback syntax
172
173
  ```
173
174
 
@@ -255,6 +256,57 @@ clamped, and rectangular, so there is no hue to interpolate against
255
256
  `transparent`. Nothing configures it — see
256
257
  [Color space](configuration.md#color-space).
257
258
 
259
+ ### Compound colors
260
+
261
+ Join color tokens with `+` to paint each one, at its own opacity, over the
262
+ colors before it. The result is one color, so it works anywhere a token does:
263
+
264
+ ```jsx
265
+ fill: '#surface+#dark.04',
266
+ // → color-mix(in srgb, var(--dark-color) 4%, var(--surface-color))
267
+
268
+ border: '1bw #border+#dark.1',
269
+ color: 'light-dark(#primary+#black.2, #primary+#white.2)',
270
+ '#hover-surface': '#surface-2+#surface-text.03',
271
+ ```
272
+
273
+ Read it left to right, bottom layer first: `#surface+#accent.1+#dark.04` paints
274
+ `#accent` at 10% over `#surface`, then `#dark` at 4% over that. Every operand is
275
+ an ordinary token — `#current`, `#clear`, a hex color, a replace token — and
276
+ takes its opacity suffix as it does anywhere: `#surface+#dark.$hover` reads the
277
+ opacity from `$hover`, and a faded base such as `#surface.5+#dark.04` is layered
278
+ as it is.
279
+
280
+ The layers mix in sRGB, the space browsers composite in, so the color is exactly
281
+ what stacking them as layers would show — but it is one color, which contrast
282
+ checkers can read and transitions interpolate. A faded base is exact too:
283
+ `#surface.5+#dark.04` is as translucent as the two layers would be.
284
+
285
+ Every layer's token has to be opaque. The mix counts a layer's own alpha as well
286
+ as its opacity suffix, and lowers the alpha of the whole color, so a layer token
287
+ that holds a translucent color, or turns transparent in some state, leaves the
288
+ result see-through: with `'#overlay': { '': '#clear', hovered: '#dark' }`,
289
+ `'#surface+#overlay.04'` is 96% opaque at rest. Vary the opacity instead
290
+ (`'#surface+#dark.$hover'`), or give each state its own color
291
+ (`fill: { '': '#surface', hovered: '#surface+#dark.04' }`).
292
+
293
+ - Write it as one word: `#surface + #dark.04` is three separate values, and
294
+ Tasty warns in development.
295
+ - A layer without an opacity covers everything before it: `#surface+#dark` is
296
+ `#dark`, with a development warning.
297
+ - A layer Tasty can see is transparent — `#clear`, a fade to `.0`, a color with
298
+ a zero alpha — is left out: `#surface+#clear` is `#surface`.
299
+ - Over a transparent base, a layer is just its fade: `#clear+#dark.04` compiles
300
+ to `#dark.04`.
301
+ - A `+` joining anything but color tokens (`#surface+1x`) is not a compound: the
302
+ token is dropped, with a development warning, and the style renders as if
303
+ that color were not there.
304
+
305
+ A `+` joins tokens only. To fade a whole compound, give it a token
306
+ (`'#hover-surface': '#surface+#dark.04'`) and fade that (`#hover-surface.5`). For
307
+ a mix that is not a layer over another color, such as an even blend in OKLCH,
308
+ write `color-mix()` itself.
309
+
258
310
  ---
259
311
 
260
312
  ## CSS Color Functions
@@ -356,7 +356,7 @@ const Badge = tasty({
356
356
  variants: {
357
357
  primary: {
358
358
  border: { '': '#white.2', pressed: '#primary-text', disabled: '#clear' },
359
- fill: { '': '#white #primary', hovered: '#white #primary-text' },
359
+ fill: { '': '#primary', hovered: '#primary-text' },
360
360
  },
361
361
  secondary: {
362
362
  border: { '': '#primary.15', pressed: '#primary.3' },
@@ -303,17 +303,67 @@ Avoid setting physical and logical declarations that resolve to the same edge in
303
303
 
304
304
  Background color with design token support. Preferred over `backgroundColor` and `background`.
305
305
 
306
- **Syntax:** `[color]` or `[base-color] [overlay-color]`
306
+ **Syntax:** `[color]`, or two colors mixed with a comma: `[color] [weight%], [color]`
307
307
 
308
308
  | Value | Effect |
309
309
  |-------|--------|
310
310
  | `"#purple"` | Token-based background color |
311
311
  | `"#purple.10"` | Token color at 10% opacity |
312
- | `"#surface #primary.10"` | Background `#surface` with `#primary.10` overlay (two colors enable smooth transitions between both) |
312
+ | `"#surface+#dark.04"` | `#dark` at 4% opacity over `#surface`, as one color — see [Compound colors](dsl.md#compound-colors) |
313
+ | `"#dark 4%, #surface"` | `#dark` mixed into `#surface` at 4% — the same color, written as `color-mix()` arguments |
313
314
  | `"rgb(255 128 0)"` | CSS color value |
314
315
  | `"color-mix(in oklab, #primary 50%, #surface)"` | CSS color function — see [CSS Color Functions](dsl.md#css-color-functions) |
315
316
 
316
- When two colors are provided, the first sets the background color and the second is applied as an overlay gradient layer. This enables independent CSS transitions on each color. With `image` or `backgroundImage` on the same element, the image is layered over the overlay color in one `background-image`.
317
+ #### Overlays
318
+
319
+ An overlay over a base color is a [compound color](dsl.md#compound-colors):
320
+
321
+ ```jsx
322
+ fill: { '': '#surface', hovered: '#surface+#dark.04', pressed: '#surface+#dark.08' }
323
+ // hovered → background-color: color-mix(in srgb, var(--dark-color) 4%, var(--surface-color));
324
+ ```
325
+
326
+ The overlay token has to be opaque, with its opacity in the suffix: a translucent
327
+ token, or one that turns `#clear` in some state, leaves the background
328
+ see-through.
329
+
330
+ #### Mixing two colors
331
+
332
+ A comma between two colors mixes them into one:
333
+
334
+ ```jsx
335
+ fill: '#dark 4%, #surface'
336
+ // → background-color: color-mix(in srgb, var(--dark-color) 4%, var(--surface-color));
337
+ ```
338
+
339
+ The comma-separated parts are the arguments of `color-mix()`, as written, mixed in sRGB: the space browsers composite layers in. When the weighted color is opaque, the mix is exactly what drawing it at that opacity over the other color shows. And because it is one `background-color`:
340
+
341
+ - contrast checkers such as axe-core and Lighthouse can read it;
342
+ - it transitions and animates between states like any other color;
343
+ - an `image` on the same element stays the only `background-image` layer.
344
+
345
+ The weight can come from a token or an expression: `'#dark $hover-weight, #surface'`, `'#dark ($hover * 100%), #surface'`.
346
+
347
+ Give the weight as a percentage, not as an opacity. A color without a percentage takes half the weight, and its own alpha weighs it down again, so the mix comes out see-through: `'#dark.04, #surface'` is 52% opaque, not `#dark` at 4% over `#surface`. In development Tasty warns about a `#name.N` or `#clear` part without a percentage. It can't see into a token, though, so a token holding a translucent color mixes the same way with no warning: keep the token opaque and put its weight in the percentage.
348
+
349
+ A mix takes two colors. Any more are ignored, with a development warning.
350
+
351
+ #### Two colors separated by a space (deprecated)
352
+
353
+ `fill: '#surface #dark.04'` paints the first color as `background-color` and the second as a `linear-gradient()` layer over it, through the `--tasty-second-fill-color` custom property. It still works, with a development warning, and is going away in the next major version: contrast checkers can't see through a `background-image`, so axe-core reports every text node over the layer as *incomplete*.
354
+
355
+ Put a `+` where the space is:
356
+
357
+ | Before | After |
358
+ |--------|-------|
359
+ | `'#surface #dark.04'` | `'#surface+#dark.04'` |
360
+ | `'#surface #clear'` | `'#surface'` |
361
+ | `'#surface #accent'` (an opaque overlay) | `'#accent'` |
362
+ | `'#base #overlay'` (a token holding a translucent color) | `'#base+#overlay.$overlay-alpha'`, with `#overlay` opaque and `$overlay-alpha` its opacity as a number |
363
+
364
+ The rewrites are exact when the overlay token is opaque. A state map no longer needs the same two-color shape in every state to transition smoothly: every state is now a plain background color.
365
+
366
+ If an overlay has to stay a translucent token, draw the layer yourself with `fill: '#base', image: 'linear-gradient(#overlay, #overlay)'`. Contrast checkers can't read that either.
317
367
 
318
368
  There is no default fill color, so `fill: true` is ignored with a development warning. Use `false` for no fill.
319
369
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenphi/cookbook",
3
- "version": "0.31.0",
3
+ "version": "0.31.2",
4
4
  "description": "Repository-native static documentation for Astro",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -68,8 +68,8 @@
68
68
  "author": "Andrey Yamanov",
69
69
  "license": "MIT",
70
70
  "dependencies": {
71
- "@tenphi/docs": "0.31.0",
72
- "@tenphi/renderer": "0.31.0"
71
+ "@tenphi/docs": "0.31.2",
72
+ "@tenphi/renderer": "0.31.2"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "astro": "^7.3.2"