ui-style-kit-css 2.1.0 → 2.3.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 (64) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +169 -54
  3. package/STYLE-MAP.md +55 -0
  4. package/dist/ui-style-kit.css +23744 -7015
  5. package/dist/ui-style-kit.min.css +2 -2
  6. package/dist/ui-style-kit.visual.css +22948 -6669
  7. package/dist/ui-style-kit.visual.min.css +2 -2
  8. package/dist/ui-style-kit.with-bridge.css +23941 -7205
  9. package/dist/ui-style-kit.with-bridge.min.css +2 -2
  10. package/dist/visual/art-deco.css +4776 -0
  11. package/dist/visual/bauhaus.css +1894 -147
  12. package/dist/visual/bento.css +1910 -166
  13. package/dist/visual/brutalism.css +1853 -98
  14. package/dist/visual/clay.css +4789 -0
  15. package/dist/visual/cyberpunk.css +1840 -94
  16. package/dist/visual/data-terminal.css +4804 -0
  17. package/dist/visual/editorial-luxe.css +4804 -0
  18. package/dist/visual/industrial-utility.css +4797 -0
  19. package/dist/visual/maximalist.css +1862 -112
  20. package/dist/visual/minimal-saas.css +1886 -147
  21. package/dist/visual/neo-noir.css +4790 -0
  22. package/dist/visual/neumorphism.css +1896 -151
  23. package/dist/visual/organic-modern.css +4767 -0
  24. package/dist/visual/paper-editorial.css +4799 -0
  25. package/dist/visual/retro-glass.css +1859 -93
  26. package/dist/visual/retrofuturism.css +1852 -113
  27. package/dist/visual/tactile.css +1851 -111
  28. package/dist/visual/technical-blueprint.css +4791 -0
  29. package/dist/visual/y2k.css +1840 -92
  30. package/docs/BRIDGE-MIGRATION.md +20 -0
  31. package/docs/ECOSYSTEM.md +39 -4
  32. package/docs/PUBLISHING.md +38 -13
  33. package/docs/STYLE-GUIDE.md +53 -13
  34. package/docs/TOKENS.md +50 -1
  35. package/docs/superpowers/plans/2026-08-29-preset-identity-system-refinement.md +649 -0
  36. package/docs/superpowers/specs/2026-08-29-preset-identity-system-refinement-design.md +212 -0
  37. package/manifest.json +482 -2
  38. package/package.json +77 -7
  39. package/styles/art-deco.css +683 -0
  40. package/styles/bauhaus.css +237 -3
  41. package/styles/bento.css +266 -7
  42. package/styles/brutalism.css +235 -3
  43. package/styles/clay.css +692 -0
  44. package/styles/components.css +608 -14
  45. package/styles/content-overflow.css +423 -4
  46. package/styles/cyberpunk.css +234 -3
  47. package/styles/data-terminal.css +691 -0
  48. package/styles/editorial-luxe.css +687 -0
  49. package/styles/industrial-utility.css +690 -0
  50. package/styles/interactive-surface-bridge.css +17 -10
  51. package/styles/interactive-surface-theme.css +17 -8
  52. package/styles/maximalist.css +238 -4
  53. package/styles/minimal-saas.css +234 -3
  54. package/styles/native-elements.css +80 -12
  55. package/styles/neo-noir.css +690 -0
  56. package/styles/neumorphism.css +234 -3
  57. package/styles/organic-modern.css +683 -0
  58. package/styles/paper-editorial.css +688 -0
  59. package/styles/retro-glass.css +242 -3
  60. package/styles/retrofuturism.css +233 -3
  61. package/styles/tactile.css +235 -3
  62. package/styles/technical-blueprint.css +686 -0
  63. package/styles/theme-colors.css +796 -5
  64. package/styles/y2k.css +237 -3
@@ -0,0 +1,649 @@
1
+ # Preset Identity System Refinement Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Make all 20 UI presets visibly distinct and internally coherent across CTAs, marketing surfaces, metrics, dialogs, and native controls while preserving the 2.3.0 public API.
6
+
7
+ **Architecture:** Add a manifest-complete internal identity registry that describes each preset's visual vocabulary and acts as a build-time contract. Keep the actual component treatments explicit in the authored preset CSS, separate the filled and outlined CTA roles in the demo, and extend focused tests so uniqueness is proven across a composite component signature instead of one `clip-path`.
8
+
9
+ **Tech Stack:** CSS cascade layers, CSS custom properties, CSS Grid, container queries, Node.js ES modules, `node:test`, `css-tree`, Lightning CSS, Stylelint, Playwright.
10
+
11
+ **Spec:** `docs/superpowers/specs/2026-08-29-preset-identity-system-refinement-design.md`
12
+
13
+ ## Global Constraints
14
+
15
+ - Keep `ui-style-kit-css@2.3.0`, `layout-style-css@3.1.0`, and `interactive-surface-css@1.6.0` unchanged.
16
+ - Preserve all existing public classes, class suffixes, color schemes, modes, focused exports, deprecated structural helpers, and bridge exports.
17
+ - Add no public class names and remove none.
18
+ - Consume only the active theme tokens for color; do not introduce fixed component colors.
19
+ - Keep UI visual CSS before UI interaction theme, Interactive Surface state core, Layout CSS, and application overrides.
20
+ - Do not stage, commit, push, tag, publish, create a GitHub release, or deploy.
21
+ - Preserve `desktop.ini`, ignored browser artifacts, and unrelated user changes.
22
+ - Use professional JSDoc-compatible comments for every changed JavaScript helper.
23
+ - Run focused checks at task checkpoints. Run the complete release gate only once in Task 7.
24
+ - Execute inline in the current workspace because repository instructions prohibit subagents and worktrees unless explicitly requested.
25
+
26
+ ---
27
+
28
+ ## File Map
29
+
30
+ - Create `scripts/preset-identities.mjs`: internal registry, JSDoc types, and manifest validation.
31
+ - Create `tests/preset-identities.test.js`: registry completeness, malformed-registry, and composite-signature contracts.
32
+ - Modify `scripts/build.mjs`: validate the registry before generating distributions.
33
+ - Modify `demo/demo.js`: separate filled and outlined CTA roles and add stable demo test hooks.
34
+ - Modify `demo/demo.css`: contain style-specific specimens without imposing visual identity.
35
+ - Modify all `styles/<preset>.css` files listed by `manifest.json`: explicit CTA, surface, metric/tile, and native fallback identity rules.
36
+ - Modify `tests/marketing-components.test.js`: CTA role, sizing, relationship, and surface vocabulary contracts.
37
+ - Modify `tests/native-elements-contract.test.js`: preset-scoped native button and dialog identity coverage.
38
+ - Modify `tests/e2e/demo.spec.js` and `tests/matrix/ui-matrix.spec.js`: rendered geometry and state assertions for all 20 presets.
39
+ - Modify `README.md`, `CHANGELOG.md`, `docs/STYLE-GUIDE.md`, and `wiki/UI-Systems.md`: document coherent preset identities and CTA composition.
40
+ - Regenerate `styles/components.css`, `styles/content-overflow.css`, `demo/demo-manifest.js`, `dist/*.css`, and `dist/visual/*.css` through `npm.cmd run build`.
41
+
42
+ ---
43
+
44
+ ### Task 1: Add the Manifest-complete Identity Registry
45
+
46
+ **Files:**
47
+ - Create: `scripts/preset-identities.mjs`
48
+ - Create: `tests/preset-identities.test.js`
49
+ - Modify: `scripts/build.mjs`
50
+
51
+ **Interfaces:**
52
+ - Produces: `PRESET_IDENTITIES: readonly PresetIdentity[]`
53
+ - Produces: `validatePresetIdentities(manifest, identities = PRESET_IDENTITIES): void`
54
+ - Consumes: `manifest.presets` entries with `{id: string, prefix: string}`.
55
+ - Later tasks consume each entry's `composition`, `specimenSuffix`, `filledInlineSize`, `filledAlignment`, `description`, and `signatureSelectors`.
56
+
57
+ - [ ] **Step 1: Write the registry completeness and error-path tests**
58
+
59
+ Create `tests/preset-identities.test.js` with direct tests for exact manifest coverage and malformed input:
60
+
61
+ ```js
62
+ import test from 'node:test';
63
+ import assert from 'node:assert/strict';
64
+ import fs from 'node:fs';
65
+ import path from 'node:path';
66
+ import { fileURLToPath } from 'node:url';
67
+ import { PRESET_IDENTITIES, validatePresetIdentities } from '../scripts/preset-identities.mjs';
68
+
69
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
70
+ const manifest = JSON.parse(fs.readFileSync(path.join(root, 'manifest.json'), 'utf8'));
71
+
72
+ test('identity registry exactly matches the public preset manifest', () => {
73
+ assert.doesNotThrow(() => validatePresetIdentities(manifest));
74
+ assert.deepEqual(
75
+ PRESET_IDENTITIES.map(({ id, prefix }) => [id, prefix]),
76
+ manifest.presets.map(({ id, prefix }) => [id, prefix])
77
+ );
78
+ });
79
+
80
+ test('identity validation rejects omissions and duplicate identities', () => {
81
+ assert.throws(
82
+ () => validatePresetIdentities(manifest, PRESET_IDENTITIES.slice(1)),
83
+ /missing identity for minimal-saas/
84
+ );
85
+ assert.throws(
86
+ () => validatePresetIdentities(manifest, [...PRESET_IDENTITIES, PRESET_IDENTITIES[0]]),
87
+ /duplicate identity for minimal-saas/
88
+ );
89
+ });
90
+ ```
91
+
92
+ - [ ] **Step 2: Run the focused test and confirm the missing-module failure**
93
+
94
+ Run: `node --test tests/preset-identities.test.js`
95
+
96
+ Expected: FAIL because `scripts/preset-identities.mjs` does not exist.
97
+
98
+ - [ ] **Step 3: Implement the typed identity registry**
99
+
100
+ Create `scripts/preset-identities.mjs` with this JSDoc contract and the exact manifest-ordered entries:
101
+
102
+ ```js
103
+ /**
104
+ * @typedef {'compact'|'block'|'soft'|'elongated'|'expressive'} CompositionFamily
105
+ */
106
+
107
+ /**
108
+ * @typedef {Object} PresetIdentity
109
+ * @property {string} id Public manifest preset identifier.
110
+ * @property {string} prefix Public class and token prefix.
111
+ * @property {CompositionFamily} composition Intentional CTA width and alignment family.
112
+ * @property {string} specimenSuffix Existing preset-owned metric or specimen suffix.
113
+ * @property {string} filledInlineSize Required computed inline-size declaration for the filled CTA.
114
+ * @property {'start'|'center'|'end'} filledAlignment Required grid alignment for the filled CTA.
115
+ * @property {string} description Human-readable component identity.
116
+ * @property {readonly string[]} signatureSelectors Prefix-relative selectors used by contracts.
117
+ */
118
+
119
+ const signatureSelectors = Object.freeze([
120
+ 'button-cut',
121
+ 'button-outline-heavy',
122
+ 'card-service',
123
+ 'media-scrim',
124
+ 'callout-bar'
125
+ ]);
126
+
127
+ const identityRows = [
128
+ ['minimal-saas', 'saas', 'compact', 'metric', 'fit-content', 'start', 'single-corner fold, fine outline, low elevation'],
129
+ ['bento', 'bento', 'block', 'grid-feature', 'min(100%,14rem)', 'center', 'stepped tile edges and compact block composition'],
130
+ ['maximalist', 'max', 'expressive', 'well', 'fit-content', 'end', 'skewed poster silhouette and pronounced layered shadow'],
131
+ ['bauhaus', 'bau', 'block', 'well', 'min(100%,12rem)', 'start', 'asymmetric hard geometry and structural blocks'],
132
+ ['tactile', 'tactile', 'expressive', 'well', 'fit-content', 'center', 'chamfered keycap with bevel and pressed depth'],
133
+ ['neumorphism', 'neo', 'soft', 'well', 'fit-content', 'center', 'soft clipping with raised and inset shadows'],
134
+ ['retrofuturism', 'retro', 'elongated', 'well', 'min(100%,18rem)', 'center', 'elongated console geometry with metallic rim'],
135
+ ['brutalism', 'brutal', 'block', 'well', 'min(100%,14rem)', 'start', 'blunt cut, thick border, and hard offset shadow'],
136
+ ['cyberpunk', 'cyber', 'elongated', 'well', 'min(100%,18rem)', 'end', 'multi-notch technical polygon with neon edge'],
137
+ ['y2k', 'y2k', 'soft', 'well', 'min(100%,14rem)', 'center', 'glossy hexagonal capsule with reflective depth'],
138
+ ['retro-glass', 'rg', 'elongated', 'well', 'min(100%,16rem)', 'center', 'frosted angular tab with inner highlight'],
139
+ ['editorial-luxe', 'luxe', 'compact', 'metric', 'fit-content', 'start', 'slim bookplate with hairline framing'],
140
+ ['organic-modern', 'organic', 'soft', 'metric', 'fit-content', 'center', 'asymmetric pebble contour with soft depth'],
141
+ ['industrial-utility', 'utility', 'compact', 'metric', 'fit-content', 'start', 'octagonal equipment control with operational density'],
142
+ ['technical-blueprint', 'blueprint', 'compact', 'metric', 'fit-content', 'start', 'drafting-corner outline and technical rules'],
143
+ ['art-deco', 'deco', 'soft', 'metric', 'min(100%,15rem)', 'center', 'symmetric chevrons with double-rule framing'],
144
+ ['clay', 'clay', 'soft', 'metric', 'fit-content', 'center', 'inflated pill with chunky soft shadow'],
145
+ ['data-terminal', 'terminal', 'compact', 'metric', 'fit-content', 'start', 'terminal brackets with luminous outline'],
146
+ ['paper-editorial', 'paper', 'compact', 'metric', 'fit-content', 'start', 'ticket notches with inked offset edge'],
147
+ ['neo-noir', 'noir', 'elongated', 'metric', 'min(100%,16rem)', 'end', 'cinematic slant with edge lighting']
148
+ ];
149
+
150
+ /** @type {readonly PresetIdentity[]} */
151
+ export const PRESET_IDENTITIES = Object.freeze(identityRows.map(
152
+ ([id, prefix, composition, specimenSuffix, filledInlineSize, filledAlignment, description]) => Object.freeze({
153
+ id,
154
+ prefix,
155
+ composition,
156
+ specimenSuffix,
157
+ filledInlineSize,
158
+ filledAlignment,
159
+ description,
160
+ signatureSelectors
161
+ })
162
+ ));
163
+ ```
164
+
165
+ Implement `validatePresetIdentities` by checking arrays, duplicate IDs, missing IDs, unknown IDs, prefix equality, supported composition families, and a non-empty `signatureSelectors` list. Throw `TypeError` for malformed arguments and `Error` for contract mismatches.
166
+
167
+ - [ ] **Step 4: Wire validation into the build before any generated writes**
168
+
169
+ Modify `scripts/build.mjs`:
170
+
171
+ ```js
172
+ import { validatePresetIdentities } from './preset-identities.mjs';
173
+
174
+ // Place immediately after package/manifest version equality validation.
175
+ validatePresetIdentities(publicManifest);
176
+ ```
177
+
178
+ - [ ] **Step 5: Prove the registry and build guard**
179
+
180
+ Run: `node --test tests/preset-identities.test.js`
181
+
182
+ Expected: 2 tests pass.
183
+
184
+ Run: `node scripts/build.mjs`
185
+
186
+ Expected: exit 0 with all current bundles regenerated.
187
+
188
+ Inspect: `git diff -- scripts/preset-identities.mjs tests/preset-identities.test.js scripts/build.mjs`
189
+
190
+ ---
191
+
192
+ ### Task 2: Separate CTA Roles and Establish Intentional Composition
193
+
194
+ **Files:**
195
+ - Modify: `demo/demo.js`
196
+ - Modify: `tests/marketing-components.test.js`
197
+ - Modify: all 20 `styles/<preset>.css` files from `manifest.json`
198
+
199
+ **Interfaces:**
200
+ - Consumes: `PRESET_IDENTITIES` from Task 1.
201
+ - Produces: demo hooks `marketing-primary-cta` and `marketing-secondary-cta`.
202
+ - Preserves: independent public `button-cut` and `button-outline-heavy` modifiers.
203
+
204
+ - [ ] **Step 1: Add failing CTA composition contracts**
205
+
206
+ Extend `tests/marketing-components.test.js` to import `PRESET_IDENTITIES`, parse effective declarations with `css-tree`, and assert:
207
+
208
+ ```js
209
+ test('commercial CTAs use separate filled and outlined roles', () => {
210
+ const demo = read('demo/demo.js');
211
+ assert.match(demo, /data-testid="marketing-primary-cta"[^>]*button-cut/);
212
+ assert.match(demo, /data-testid="marketing-secondary-cta"[^>]*button-outline-heavy/);
213
+ assert.doesNotMatch(demo, /data-testid="marketing-secondary-cta"[^>]*button-cut/);
214
+ });
215
+
216
+ test('every preset declares intentional CTA sizing and independent outline geometry', () => {
217
+ for (const { id, prefix, filledInlineSize, filledAlignment } of PRESET_IDENTITIES) {
218
+ const css = read(`styles/${id}.css`);
219
+ const filled = effectiveDeclarations(css, (selector) => selector.includes(`.${prefix}-button-cut`));
220
+ const outline = effectiveDeclarations(css, (selector) => selector.includes(`.${prefix}-button-outline-heavy`));
221
+
222
+ assert.equal(filled.get('inline-size'), filledInlineSize, `${id} filled CTA width`);
223
+ assert.equal(filled.get('justify-self'), filledAlignment, `${id} filled CTA alignment`);
224
+ assert.ok(outline.has('clip-path') || outline.has('border-radius'), `${id} outline CTA needs owned geometry`);
225
+ }
226
+ });
227
+ ```
228
+
229
+ - [ ] **Step 2: Confirm the focused test fails on stacked modifiers and missing composition**
230
+
231
+ Run: `node --test tests/marketing-components.test.js`
232
+
233
+ Expected: FAIL because `View Usage` stacks `button-cut` and the 20 CTAs do not yet match the registry sizing/alignment contracts.
234
+
235
+ - [ ] **Step 3: Separate the demo roles**
236
+
237
+ Modify the two anchors in `demo/demo.js`:
238
+
239
+ ```html
240
+ <a data-testid="marketing-primary-cta" class="${p}-button ${p}-button-primary ${p}-button-cut" href="#components">Explore</a>
241
+ <a data-testid="marketing-secondary-cta" class="${p}-button ${p}-button-outline-heavy" href="#usage">View Usage</a>
242
+ ```
243
+
244
+ - [ ] **Step 4: Author the exact CTA composition matrix**
245
+
246
+ In each preset stylesheet, consolidate the final effective CTA rules so later declarations implement this matrix:
247
+
248
+ | Preset | Filled action width/alignment | Filled silhouette | Outline relationship |
249
+ | --- | --- | --- | --- |
250
+ | Minimal SaaS | `fit-content` / start | one trailing fold | same fold, fine primary outline, low shadow |
251
+ | Bento | `min(100%, 14rem)` / center | stepped trailing tile | stepped frame, compact block border |
252
+ | Maximalist | `fit-content` / end | long poster skew | opposing skew, offset shadow |
253
+ | Bauhaus | `min(100%, 12rem)` / start | opposing hard cuts | two-pixel asymmetric frame |
254
+ | Tactile | `fit-content` / center | eight-point chamfer | chamfered bevel with inset highlight |
255
+ | Neumorphism | `fit-content` / center | softly clipped rounded inset | raised outline with paired light/dark shadows |
256
+ | Retrofuturism | `min(100%, 18rem)` / center | elongated console hexagon | double metallic rim |
257
+ | Brutalism | `min(100%, 14rem)` / start | blunt opposing cuts | three-pixel border and hard offset shadow |
258
+ | Cyberpunk | `min(100%, 18rem)` / end | asymmetric multi-notch | notched neon edge and glow |
259
+ | Y2K | `min(100%, 14rem)` / center | hexagonal capsule | glossy capsule frame and highlight |
260
+ | Retro Glass | `min(100%, 16rem)` / center | angular tab | translucent frame with inner highlight |
261
+ | Editorial Luxe | `fit-content` / start | slim bookplate | hairline/double bookplate frame |
262
+ | Organic Modern | `fit-content` / center | asymmetric pebble | related leaf contour and soft shadow |
263
+ | Industrial Utility | `fit-content` / start | octagonal control | equipment outline with inset rule |
264
+ | Technical Blueprint | `fit-content` / start | drafting-corner polygon | technical outline with inset drafting rule |
265
+ | Art Deco | `min(100%, 15rem)` / center | symmetric chevrons | double-rule chevron frame |
266
+ | Clay | `fit-content` / center | inflated clipped pill | inflated outline with chunky soft shadow |
267
+ | Data Terminal | `fit-content` / start | command bracket | bracket outline with restrained glow |
268
+ | Paper Editorial | `fit-content` / start | paired ticket notches | ticket outline and ink-offset shadow |
269
+ | Neo Noir | `min(100%, 16rem)` / end | cinematic slant | opposing slant with edge light |
270
+
271
+ Every final `button-cut` rule must set `inline-size`, `max-inline-size: 100%`, and `justify-self`. Every final `button-outline-heavy` rule must set its own silhouette, border treatment, and material/depth treatment. Preserve the existing `outline-offset: -3px` focus rule for clipped controls.
272
+
273
+ - [ ] **Step 5: Prove CTA roles and inspect the cross-preset slice**
274
+
275
+ Run: `node --test tests/marketing-components.test.js tests/preset-identities.test.js`
276
+
277
+ Expected: all focused tests pass.
278
+
279
+ Run: `npx stylelint "styles/*.css"`
280
+
281
+ Expected: exit 0.
282
+
283
+ Inspect: `git diff -- demo/demo.js styles tests/marketing-components.test.js`
284
+
285
+ ---
286
+
287
+ ### Task 3: Connect Surfaces, Metrics, and Native Fallbacks to Each Identity
288
+
289
+ **Files:**
290
+ - Modify: all 20 `styles/<preset>.css` files
291
+ - Modify: `tests/preset-identities.test.js`
292
+ - Modify: `tests/native-elements-contract.test.js`
293
+
294
+ **Interfaces:**
295
+ - Consumes: `signatureSelectors` and `specimenSuffix` from Task 1.
296
+ - Produces: unique composite identity signatures for all 20 presets.
297
+ - Preserves: shared native semantics and bridge detachment behavior.
298
+
299
+ - [ ] **Step 1: Add failing composite and native identity tests**
300
+
301
+ In `tests/preset-identities.test.js`, add `effectiveDeclarations` and `normalizedSignature` helpers using `css-tree`. The signature must include effective values for `background`, `border`, `border-radius`, `box-shadow`, `clip-path`, `inline-size`, `justify-self`, and `font-family`, with the active prefix replaced by `preset`.
302
+
303
+ ```js
304
+ test('all presets expose distinct composite component identities', () => {
305
+ const signatures = new Map();
306
+
307
+ for (const identity of PRESET_IDENTITIES) {
308
+ const css = fs.readFileSync(path.join(root, 'styles', `${identity.id}.css`), 'utf8');
309
+ const selectors = [
310
+ ...identity.signatureSelectors,
311
+ identity.specimenSuffix
312
+ ];
313
+ const signature = selectors.map((suffix) =>
314
+ normalizedSignature(css, `.${identity.prefix}-${suffix}`, identity.prefix)
315
+ ).join('|');
316
+
317
+ assert.equal(signatures.has(signature), false, `${identity.id} duplicates ${signatures.get(signature)}`);
318
+ signatures.set(signature, identity.id);
319
+ }
320
+ });
321
+ ```
322
+
323
+ In `tests/native-elements-contract.test.js`, assert every stylesheet contains preset-scoped rules for unclassed action inputs/buttons and dialogs, and that the action and dialog blocks each declare at least two of `border`, `border-radius`, `box-shadow`, or `background`.
324
+
325
+ - [ ] **Step 2: Confirm the focused contracts fail for generic metrics and native treatments**
326
+
327
+ Run: `node --test tests/preset-identities.test.js tests/native-elements-contract.test.js`
328
+
329
+ Expected: FAIL because most native identity blocks are absent and several composite signatures remain generic.
330
+
331
+ - [ ] **Step 3: Apply the surface/material matrix**
332
+
333
+ For each preset, add one consolidated identity block covering `card-service`, `media-scrim`, `feature-strip`, `callout-bar`, and the registry metric or style-specimen suffix:
334
+
335
+ | Preset | Surface/material treatment |
336
+ | --- | --- |
337
+ | Minimal SaaS | fine border, small leading accent rule, low neutral elevation |
338
+ | Bento | stepped/tiled corners, nested borders, compact gaps, no generic pill |
339
+ | Maximalist | two-pixel border, layered theme-token fill, pronounced offset shadow |
340
+ | Bauhaus | zero radius, two-pixel hard border, asymmetric primary edge |
341
+ | Tactile | bevel gradient, inset top highlight, physical drop depth |
342
+ | Neumorphism | soft radius, raised outer shadows, inset metric shadow, quiet border |
343
+ | Retrofuturism | elongated panel proportion, double rim, metallic inset highlight |
344
+ | Brutalism | three-pixel border, zero radius, hard text-token offset shadow |
345
+ | Cyberpunk | notched or hard surface corners, primary edge, token-driven neon glow |
346
+ | Y2K | large capsule radius, glossy token gradient, reflective inset highlight |
347
+ | Retro Glass | translucent token surface, angular corners, backdrop blur, inner highlight |
348
+ | Editorial Luxe | compact bookplate proportions, hairline/double rules, no heavy shadow |
349
+ | Organic Modern | asymmetric radii, soft layered theme-token shadow, relaxed spacing |
350
+ | Industrial Utility | small radius, two-pixel equipment border, inset status rail |
351
+ | Technical Blueprint | zero radius, drafting border, token-driven grid/technical rule |
352
+ | Art Deco | symmetric geometry, double border, restrained centered ornament |
353
+ | Clay | extra-large radius, inflated token fill, chunky soft shadow |
354
+ | Data Terminal | zero radius, one-pixel luminous primary edge, monospace compact density |
355
+ | Paper Editorial | zero radius, heavy top rule, ink-like offset edge |
356
+ | Neo Noir | restrained radius, high-contrast primary edge, cinematic shadow/glow |
357
+
358
+ Do not clip dialog surfaces or content-bearing cards in a way that can cut focus rings or text. Use border, radius, edge, and shadow language for those surfaces when clipping would be unsafe.
359
+
360
+ - [ ] **Step 4: Add safe preset-scoped native identity blocks**
361
+
362
+ In each preset stylesheet, add scoped rules after the shared native layer:
363
+
364
+ ```css
365
+ [data-ui="PRESET_ID"][data-theme][data-mode] :where(
366
+ button:not([class]),
367
+ input[type="button"]:not([class]),
368
+ input[type="submit"]:not([class]),
369
+ input[type="reset"]:not([class])
370
+ ) {
371
+ /* Preset-specific border, radius, shadow, typography, and safe silhouette. */
372
+ }
373
+
374
+ [data-ui="PRESET_ID"][data-theme][data-mode] :where(dialog) {
375
+ /* Matching surface border, radius, background, and depth without clipping content. */
376
+ }
377
+ ```
378
+
379
+ Use the same matrix language as the preset's CTA and surface. Keep `min-block-size`, padding, foreground/background contrast roles, focus rules, busy pseudo-elements, disabled styling, and bridge state ownership unchanged.
380
+
381
+ - [ ] **Step 5: Prove composite uniqueness and native coverage**
382
+
383
+ Run: `node --test tests/preset-identities.test.js tests/native-elements-contract.test.js tests/marketing-components.test.js`
384
+
385
+ Expected: all focused tests pass and all 20 composite signatures are unique.
386
+
387
+ Run: `npm.cmd run check:contrast`
388
+
389
+ Expected: all 1,200 semantic theme/mode/preset states pass.
390
+
391
+ Inspect: `git diff -- styles tests/preset-identities.test.js tests/native-elements-contract.test.js`
392
+
393
+ ---
394
+
395
+ ### Task 4: Repair Bento Metrics and Dense Demo Specimens
396
+
397
+ **Files:**
398
+ - Modify: `styles/bento.css`
399
+ - Modify: `demo/demo.css`
400
+ - Modify: `tests/marketing-components.test.js`
401
+ - Modify: `tests/e2e/demo.spec.js`
402
+
403
+ **Interfaces:**
404
+ - Preserves: `.bento-grid-feature`, `.bento-tile`, `.bento-tile-lg`, and `.bento-tile-sm` public classes.
405
+ - Produces: intrinsic one/two-column behavior with container-aware tile spans.
406
+
407
+ - [ ] **Step 1: Add failing Bento containment contracts**
408
+
409
+ Add static assertions:
410
+
411
+ ```js
412
+ test('Bento feature metrics use intrinsic columns and container-aware spans', () => {
413
+ const css = read('styles/bento.css');
414
+ assert.match(css, /\.bento-grid-feature\s*\{[^}]*container-type:\s*inline-size/s);
415
+ assert.match(css, /grid-template-columns:\s*repeat\(auto-fit,\s*minmax\(min\(100%,\s*14rem\),\s*1fr\)\)/);
416
+ assert.match(css, /@container\s*\(min-width:\s*34rem\)[\s\S]*\.bento-tile-lg\s*\{[^}]*grid-column:\s*span 2/);
417
+ assert.match(css, /\.bento-stat-label[^}]*overflow-wrap:\s*normal/);
418
+ });
419
+ ```
420
+
421
+ Extend the existing Playwright geometry block to collect both Bento tile widths, label line boxes, and container width. Assert every tile is at least 12rem when the container is that wide and no label has more than two line boxes.
422
+
423
+ - [ ] **Step 2: Confirm the static test fails on the six-column layout**
424
+
425
+ Run: `node --test tests/marketing-components.test.js`
426
+
427
+ Expected: FAIL because `.bento-grid-feature` still uses `repeat(6, 1fr)`.
428
+
429
+ - [ ] **Step 3: Implement intrinsic grid sizing and child container queries**
430
+
431
+ Replace the current Bento helper with:
432
+
433
+ ```css
434
+ .bento-grid-feature {
435
+ container-type: inline-size;
436
+ display: grid;
437
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
438
+ grid-auto-rows: minmax(9rem, auto);
439
+ gap: var(--bento-space-5);
440
+ }
441
+
442
+ .bento-tile,
443
+ .bento-tile-lg,
444
+ .bento-tile-md,
445
+ .bento-tile-sm {
446
+ min-inline-size: 0;
447
+ grid-column: auto;
448
+ grid-row: auto;
449
+ }
450
+
451
+ .bento-stat-label {
452
+ overflow-wrap: normal;
453
+ word-break: normal;
454
+ }
455
+
456
+ @container (min-width: 34rem) {
457
+ .bento-tile-lg {
458
+ grid-column: span 2;
459
+ grid-row: span 2;
460
+ }
461
+ }
462
+ ```
463
+
464
+ Keep the existing tile fill, border, radius, and shadow declarations in the consolidated Bento identity block from Task 3.
465
+
466
+ - [ ] **Step 4: Keep the demo host neutral and containable**
467
+
468
+ In `demo/demo.css`, ensure `.demo-token-sample` and its direct style-specific child have `min-inline-size: 0` and `max-inline-size: 100%`. Do not add preset-specific colors, radii, or shadows to demo CSS.
469
+
470
+ - [ ] **Step 5: Prove the focused containment slice**
471
+
472
+ Run: `node --test tests/marketing-components.test.js`
473
+
474
+ Expected: all tests pass.
475
+
476
+ Run: `npx stylelint "styles/bento.css" "demo/demo.css"`
477
+
478
+ Expected: exit 0.
479
+
480
+ The Playwright assertion is authored but not run if the active browser policy remains blocked.
481
+
482
+ ---
483
+
484
+ ### Task 5: Expand Rendered Contracts and Release Documentation
485
+
486
+ **Files:**
487
+ - Modify: `tests/e2e/demo.spec.js`
488
+ - Modify: `tests/matrix/ui-matrix.spec.js`
489
+ - Modify: `README.md`
490
+ - Modify: `CHANGELOG.md`
491
+ - Modify: `docs/STYLE-GUIDE.md`
492
+ - Modify: `wiki/UI-Systems.md`
493
+
494
+ **Interfaces:**
495
+ - Consumes: demo hooks from Task 2 and registry entries from Task 1.
496
+ - Produces: 20-preset geometry/state coverage at 1440px, 1024px, and 390px.
497
+
498
+ - [ ] **Step 1: Add rendered CTA relationship and containment assertions**
499
+
500
+ For each preset and viewport, collect computed style and geometry for both commercial CTA hooks, service card, callout bar, metric/tile specimen, native action buttons, and inline dialog. Assert:
501
+
502
+ ```js
503
+ expect(primary.width).toBeGreaterThanOrEqual(96);
504
+ expect(primary.right).toBeLessThanOrEqual(service.right + 1);
505
+ expect(secondary.width).toBeGreaterThanOrEqual(96);
506
+ expect(secondary.right).toBeLessThanOrEqual(callout.right + 1);
507
+ expect(primary.signature).not.toBe(secondary.signature);
508
+ expect(nativeButtons.every(({ contrast }) => contrast >= 4.5)).toBe(true);
509
+ expect(dialog.left).toBeGreaterThanOrEqual(nativePanel.left - 1);
510
+ expect(dialog.right).toBeLessThanOrEqual(nativePanel.right + 1);
511
+ expect(documentOverflow).toBeLessThanOrEqual(1);
512
+ ```
513
+
514
+ Build each signature from computed `clipPath`, `borderRadius`, `borderWidth`, `boxShadow`, `inlineSize`, and `justifySelf`.
515
+
516
+ - [ ] **Step 2: Add matrix assertions for light, dark, contrast, focus, busy, and reduced motion**
517
+
518
+ Extend `tests/matrix/ui-matrix.spec.js` so each preset validates:
519
+
520
+ - visible focus outline for filled, outlined, native, and dialog actions;
521
+ - spinner containment in busy controls;
522
+ - readable media-scrim caption;
523
+ - no CTA label overflow or vertical character stacking;
524
+ - disabled/native foreground uses the shared readable muted role;
525
+ - reduced motion makes CTA and loader animation duration effectively zero or one millisecond.
526
+
527
+ - [ ] **Step 3: Update release-facing documentation**
528
+
529
+ Add a 2.3.0 refinement bullet to `CHANGELOG.md` describing coherent preset-specific CTA, surface, metric, and native treatments. In `README.md`, `docs/STYLE-GUIDE.md`, and `wiki/UI-Systems.md`, document:
530
+
531
+ - filled service action: `button-primary button-cut`;
532
+ - framed callout action: `button-outline-heavy`;
533
+ - modifiers remain independently composable;
534
+ - UI presets control geometry/material while color schemes control semantic color;
535
+ - no `button-cta` class exists or is required.
536
+
537
+ - [ ] **Step 4: Run documentation and static contracts only**
538
+
539
+ Run: `node --test tests/class-api.test.js tests/public-api.test.js tests/preset-identities.test.js tests/marketing-components.test.js`
540
+
541
+ Expected: all focused tests pass.
542
+
543
+ Run: `git diff --check -- README.md CHANGELOG.md docs/STYLE-GUIDE.md wiki/UI-Systems.md tests/e2e/demo.spec.js tests/matrix/ui-matrix.spec.js`
544
+
545
+ Expected: exit 0.
546
+
547
+ ---
548
+
549
+ ### Task 6: Regenerate Distributions and Run Focused Release Checks
550
+
551
+ **Files:**
552
+ - Generated: `styles/components.css`
553
+ - Generated: `styles/content-overflow.css`
554
+ - Generated: `demo/demo-manifest.js`
555
+ - Generated: `dist/ui-style-kit*.css`
556
+ - Generated: `dist/visual/*.css`
557
+ - Generated if sizes change: `README.md`
558
+
559
+ **Interfaces:**
560
+ - Consumes: all authored changes from Tasks 1-5.
561
+ - Produces: synchronized full, minified, visual, focused, and bridge bundles.
562
+
563
+ - [ ] **Step 1: Regenerate through the canonical build**
564
+
565
+ Run: `npm.cmd run build`
566
+
567
+ Expected: generated foundations, demo manifest, distributions, and README sizes synchronize without Lightning CSS warnings.
568
+
569
+ - [ ] **Step 2: Run focused unit contracts**
570
+
571
+ Run: `node --test tests/preset-identities.test.js tests/marketing-components.test.js tests/native-elements-contract.test.js tests/control-refinements.test.js tests/readme-size-sync.test.js tests/package-integrity.test.js`
572
+
573
+ Expected: all focused tests pass.
574
+
575
+ - [ ] **Step 3: Run style and contrast checks**
576
+
577
+ Run: `npm.cmd run lint`
578
+
579
+ Expected: exit 0.
580
+
581
+ Run: `npm.cmd run check:contrast`
582
+
583
+ Expected: all 1,200 semantic states and media-scrim contracts pass.
584
+
585
+ - [ ] **Step 4: Run package integrity and dry-run inspection**
586
+
587
+ Run: `npm.cmd run check:package`
588
+
589
+ Expected: exit 0.
590
+
591
+ Run: `npm.cmd run pack:dry-run`
592
+
593
+ Expected: package contains only intended styles, distributions, documentation, manifests, and metadata; no browser artifacts or `desktop.ini`.
594
+
595
+ - [ ] **Step 5: Review authored and generated scope**
596
+
597
+ Run: `git status --short`
598
+
599
+ Run: `git diff --stat`
600
+
601
+ Run: `git diff --check`
602
+
603
+ Expected: no whitespace errors, no staged changes, and no unrelated files modified by this task.
604
+
605
+ ---
606
+
607
+ ### Task 7: Run the Complete Local 2.3.0 Release Gate Once
608
+
609
+ **Files:**
610
+ - Verify only; fix failures in the smallest responsible authored subsystem, regenerate, and rerun only the failed focused command before restarting this final gate.
611
+
612
+ **Interfaces:**
613
+ - Consumes: complete integrated working tree.
614
+ - Produces: final local release-candidate evidence without external publication.
615
+
616
+ - [ ] **Step 1: Run the CI-equivalent release command**
617
+
618
+ Run: `npm.cmd run release:verify`
619
+
620
+ Expected: build, Stylelint, unit contracts, contrast, package validation, E2E, Axe, visual, matrix, ecosystem pack proof, audit, and dry-run packaging all pass.
621
+
622
+ If browser execution is blocked by the active browser policy, stop the browser portion without substituting another browser surface. Record the exact blocked commands and preserve the passing non-browser evidence.
623
+
624
+ - [ ] **Step 2: Recheck whitespace and version surfaces**
625
+
626
+ Run: `git diff --check`
627
+
628
+ Run: `rg -n '2\.1\.0|layout-style-css@2\.|interactive-surface-css@(?!1\.6\.0)' README.md CHANGELOG.md package.json manifest.json docs wiki scripts tests -g '*.md' -g '*.json' -g '*.mjs' -g '*.js'`
629
+
630
+ Expected: no stale release or companion-version statements except explicitly labeled historical changelog entries.
631
+
632
+ - [ ] **Step 3: Inspect the tarball and working tree**
633
+
634
+ Run: `npm.cmd run pack:dry-run`
635
+
636
+ Run: `git status --short --branch`
637
+
638
+ Expected: branch `2.3.0`, no staged files, no temporary package/browser artifacts, and only the intended dirty release-candidate files plus preserved user files.
639
+
640
+ - [ ] **Step 4: Prepare the final handoff**
641
+
642
+ Report:
643
+
644
+ - implemented component identity behavior;
645
+ - changed authored and generated file groups;
646
+ - focused and final verification commands with results;
647
+ - browser checks that passed or remained policy-blocked;
648
+ - package contents and version consistency;
649
+ - explicit confirmation that no commit, push, tag, release, or publication occurred.