@handamade/psi-tokens 0.22.0 → 0.23.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 CHANGED
@@ -29,7 +29,7 @@ Then set the theme on your root element:
29
29
 
30
30
  All tokens are CSS custom properties: `--psi-bg-primary`, `--psi-fg-secondary`, `--psi-space-12`, etc.
31
31
 
32
- **utilities.css is required**: it carries `.psi-container`, `.psi-text-*`, `.psi-display-*` utility classes and the `prefers-reduced-motion` zeroing for all duration tokens (D30) — required for NavBar rendering and accessibility compliance.
32
+ **utilities.css is required**: it carries `.psi-container`, `.psi-text-*`, `.psi-display-*`, `.psi-fg-*` (D94) utility classes and the `prefers-reduced-motion` zeroing for all duration tokens (D30) — required for NavBar rendering and accessibility compliance.
33
33
 
34
34
  ## Creating a custom theme
35
35
 
@@ -190,7 +190,7 @@
190
190
  "radius": "Control radius is size-invariant (D56) — it does NOT ride the size ramp, because border-radius sits on each component's base rule and all four sizes resolve to radius-8. One dial, --psi-control-radius, is the layer to override, aliased per component: --psi-button-radius (Button, and IconButton via the same token), --psi-input-radius, --psi-select-radius, --psi-checkbox-box-radius, and --psi-tooltip-radius. Checkbox and Tooltip cap themselves with min(var(--psi-control-radius), var(--psi-radius-4)) and min(…, var(--psi-radius-6)) respectively so neither over-rounds a small object — but the published radius scale's floor is radius-4, so Checkbox's cap is a no-op for every on-scale value a theme can set; it only bites at an off-scale value like 0px. Tooltip's higher ceiling does track a sharper theme, down to radius-4. Tag and Switch stay --psi-radius-full: pill-ness is component identity, not theme expression. A theme retunes every control's shape by setting --psi-control-radius once. Psi now has two radius dials, not one: --psi-control-radius (here, for interactive controls) and --psi-surface-radius (for elevated surfaces — Dialog, Panel, Menu). --psi-card-radius sits on neither dial, so a theme that retunes controls or surfaces leaves Card at its own default of radius-8."
191
191
  },
192
192
  "utilities": {
193
- "note": "Every utility class shipped in utilities.css, generated from the same source as the CSS (D79). Scaled utility families set one property each and create no layout context: .psi-gap-* sets gap only, so pair it with display:flex or grid yourself. The bare/fixed utilities (.psi-container, .psi-media-tint, .psi-sr-only) set several. Import @handamade/psi-tokens/utilities.css — it is required, not optional; .psi-container and the reduced-motion duration zeroing live there.",
193
+ "note": "Every utility class shipped in utilities.css, generated from the same source as the CSS (D79). Scaled utility families set one property each and create no layout context: .psi-gap-* sets gap only, so pair it with display:flex or grid yourself. The bare/fixed utilities (.psi-container, .psi-media-tint, .psi-sr-only) set several. Every utility sits in @layer psi.utilities, above @layer psi.components, so on a component root it beats the component's own value (D94). Import @handamade/psi-tokens/utilities.css — it is required, not optional; .psi-container and the reduced-motion duration zeroing live there.",
194
194
  "families": [
195
195
  {
196
196
  "prefix": "psi-gap-*",
@@ -486,6 +486,26 @@
486
486
  "psi-my-144"
487
487
  ]
488
488
  },
489
+ {
490
+ "prefix": "psi-fg-*",
491
+ "property": "color",
492
+ "scale": null,
493
+ "classes": [
494
+ "psi-fg-primary",
495
+ "psi-fg-secondary",
496
+ "psi-fg-tertiary",
497
+ "psi-fg-quaternary",
498
+ "psi-fg-primary-inverted",
499
+ "psi-fg-static-white",
500
+ "psi-fg-static-black",
501
+ "psi-fg-on-accent",
502
+ "psi-fg-accent",
503
+ "psi-fg-success",
504
+ "psi-fg-warning",
505
+ "psi-fg-danger",
506
+ "psi-fg-on-inverted"
507
+ ]
508
+ },
489
509
  {
490
510
  "prefix": "psi-text-*",
491
511
  "property": "font",
@@ -562,6 +582,19 @@
562
582
  "psi-display-32-32-extrabold",
563
583
  "psi-display-36-64-black",
564
584
  "psi-display-56-128-black",
585
+ "psi-fg-accent",
586
+ "psi-fg-danger",
587
+ "psi-fg-on-accent",
588
+ "psi-fg-on-inverted",
589
+ "psi-fg-primary",
590
+ "psi-fg-primary-inverted",
591
+ "psi-fg-quaternary",
592
+ "psi-fg-secondary",
593
+ "psi-fg-static-black",
594
+ "psi-fg-static-white",
595
+ "psi-fg-success",
596
+ "psi-fg-tertiary",
597
+ "psi-fg-warning",
565
598
  "psi-gap-0",
566
599
  "psi-gap-12",
567
600
  "psi-gap-120",
@@ -121,6 +121,20 @@
121
121
  .psi-mx-144 { margin-inline: var(--psi-space-144); }
122
122
  .psi-my-144 { margin-block: var(--psi-space-144); }
123
123
 
124
+ .psi-fg-primary { color: var(--psi-fg-primary); }
125
+ .psi-fg-secondary { color: var(--psi-fg-secondary); }
126
+ .psi-fg-tertiary { color: var(--psi-fg-tertiary); }
127
+ .psi-fg-quaternary { color: var(--psi-fg-quaternary); }
128
+ .psi-fg-primary-inverted { color: var(--psi-fg-primary-inverted); }
129
+ .psi-fg-static-white { color: var(--psi-fg-static-white); }
130
+ .psi-fg-static-black { color: var(--psi-fg-static-black); }
131
+ .psi-fg-on-accent { color: var(--psi-fg-on-accent); }
132
+ .psi-fg-accent { color: var(--psi-fg-accent); }
133
+ .psi-fg-success { color: var(--psi-fg-success); }
134
+ .psi-fg-warning { color: var(--psi-fg-warning); }
135
+ .psi-fg-danger { color: var(--psi-fg-danger); }
136
+ .psi-fg-on-inverted { color: var(--psi-fg-on-inverted); }
137
+
124
138
  .psi-text-12-16-regular { font: var(--psi-text-12-16-regular); }
125
139
  .psi-text-12-16-medium { font: var(--psi-text-12-16-medium); }
126
140
  .psi-text-14-20-regular { font: var(--psi-text-14-20-regular); }
package/llms.txt CHANGED
@@ -14,6 +14,7 @@ OKLCH formula-based design tokens. Code is the source of truth; all artifacts ge
14
14
  - Override --psi-{component}-* tokens for one-off component theming; never fork semantic tokens.
15
15
  - Scales are pixel-true: --psi-space-8 is 8px (0.5rem). Typography: --psi-text-{size}-{lh}-{weight}.
16
16
  - Themes: import base.css + {theme}.css + components.css + utilities.css; set data-psi-theme="{name}" ({light,dark,acme,ember}).
17
+ - Foreground utilities (D94): `.psi-fg-<role>` sets `color: var(--psi-fg-<role>)` for every fg token (`psi-fg-primary`, `psi-fg-secondary`, `psi-fg-tertiary`, `psi-fg-on-accent`, `psi-fg-danger`, …). Like every utility it sits in `@layer psi.utilities` and beats a component's own colour.
17
18
  - Scoped tokens bind only their declared property groups (D46): fg* → text properties, bg*/fill*/scrim* → surfaces, border* → borders, --psi-space-* → gaps/padding/margin. Cross-family bindings that are design decisions carry both scopes (fgDanger: text+border for error borders; fillAccent: surface+border for selected controls). The token build enforces component bindings; the repo's stylelint rule (psi/token-scopes) enforces first-party consumer CSS (component modules + apps/). External consumers aren't gated automatically — dist/scope-map.json carries the machine-readable scopes to lint against.
18
19
 
19
20
  ## Motion (--psi-duration-*, --psi-ease-*)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handamade/psi-tokens",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {