ui-style-kit-css 2.7.0 → 2.7.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.
Files changed (57) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +11 -11
  3. package/dist/ui-style-kit.css +788 -1305
  4. package/dist/ui-style-kit.min.css +2 -2
  5. package/dist/ui-style-kit.visual.css +788 -1305
  6. package/dist/ui-style-kit.visual.min.css +2 -2
  7. package/dist/ui-style-kit.with-bridge.css +788 -1305
  8. package/dist/ui-style-kit.with-bridge.min.css +2 -2
  9. package/dist/visual/art-deco.css +191 -744
  10. package/dist/visual/bauhaus.css +2 -2
  11. package/dist/visual/bento.css +2 -2
  12. package/dist/visual/brutalism.css +150 -708
  13. package/dist/visual/clay.css +2 -2
  14. package/dist/visual/cyberpunk.css +160 -718
  15. package/dist/visual/data-terminal.css +164 -722
  16. package/dist/visual/editorial-luxe.css +167 -725
  17. package/dist/visual/industrial-utility.css +171 -729
  18. package/dist/visual/maximalist.css +171 -729
  19. package/dist/visual/minimal-saas.css +161 -715
  20. package/dist/visual/neo-noir.css +2 -2
  21. package/dist/visual/neumorphism.css +161 -719
  22. package/dist/visual/organic-modern.css +2 -2
  23. package/dist/visual/paper-editorial.css +186 -744
  24. package/dist/visual/retro-glass.css +167 -720
  25. package/dist/visual/retrofuturism.css +160 -718
  26. package/dist/visual/tactile.css +163 -721
  27. package/dist/visual/technical-blueprint.css +175 -729
  28. package/dist/visual/y2k.css +183 -721
  29. package/docs/DEMO-SHOWCASE.md +16 -0
  30. package/docs/ECOSYSTEM.md +2 -2
  31. package/docs/PUBLISHING.md +11 -7
  32. package/docs/RELEASE-2.7.1.md +21 -0
  33. package/docs/RELEASE-2.7.2.md +55 -0
  34. package/docs/api/publish-select-patch.md +80 -0
  35. package/manifest.json +1 -1
  36. package/package.json +1 -1
  37. package/styles/art-deco.css +12 -3
  38. package/styles/bauhaus.css +5 -3
  39. package/styles/bento.css +11 -7
  40. package/styles/brutalism.css +5 -3
  41. package/styles/clay.css +12 -7
  42. package/styles/cyberpunk.css +10 -6
  43. package/styles/data-terminal.css +4 -2
  44. package/styles/editorial-luxe.css +3 -2
  45. package/styles/industrial-utility.css +8 -6
  46. package/styles/maximalist.css +3 -1
  47. package/styles/minimal-saas.css +7 -3
  48. package/styles/native-elements.css +19 -0
  49. package/styles/neo-noir.css +13 -5
  50. package/styles/neumorphism.css +10 -5
  51. package/styles/organic-modern.css +1 -1
  52. package/styles/paper-editorial.css +7 -5
  53. package/styles/retro-glass.css +10 -5
  54. package/styles/retrofuturism.css +4 -3
  55. package/styles/tactile.css +7 -4
  56. package/styles/technical-blueprint.css +8 -4
  57. package/styles/y2k.css +30 -11
@@ -4,6 +4,22 @@ The default `index.html` and `demo/index.html` present one shared library showca
4
4
  semantic components, overview, color tokens, prefixed components, native HTML,
5
5
  the Interactive Surface bridge, and usage examples.
6
6
 
7
+ ## Interaction contrast
8
+
9
+ Hover, press, and keyboard focus must preserve readable labels. A filled action
10
+ keeps its paired foreground and background; an inline-link rule must not recolor
11
+ a button or navigation component. Gloss and grain remain decorative rather than
12
+ replacing the label's underlying paint.
13
+
14
+ The release regressions check 20 presets, 25 named palettes plus native palettes,
15
+ three modes, and five interaction states, including hover on pressed buttons.
16
+ They cover prefixed, semantic, and mixed React class models, anchor buttons,
17
+ native controls, disclosures, navigation, and table labels. The
18
+ contrast probe samples the central label lane and accounts for translucent paint
19
+ and full-face pseudo-elements; positioned dropdown arrows are outside that lane.
20
+
21
+ Recheck the rendered demo after changing palette values in the workbench.
22
+
7
23
  ## Preview state and palette editing
8
24
 
9
25
  Use `?ui=tactile&theme=None&mode=dark` to preview a native palette. The `personality`
package/docs/ECOSYSTEM.md CHANGED
@@ -14,11 +14,11 @@ Before a UI branch or pull request is expected to validate, verify the reviewed
14
14
 
15
15
  | Library | Current aligned version | Owns |
16
16
  |---|---:|---|
17
- | `ui-style-kit-css@2.7.0` | current release candidate | visual identity, color themes, UI paint, native HTML styling, content wrapping, and bridge tokens |
17
+ | `ui-style-kit-css@2.7.2` | current UI version | visual identity, color themes, UI paint, native HTML styling, content wrapping, and bridge tokens |
18
18
  | `interactive-surface-css@1.7.3` | compatible state release | interaction-state primitives, surface behavior, state layers, and input affordances |
19
19
  | `layout-style-css@3.2.3` | compatible structural release | structural wrappers, grids, sections, app shells, and layout recipes |
20
20
 
21
- The current combination is `ui-style-kit-css@2.7.0`, `interactive-surface-css@1.7.3`, and `layout-style-css@3.2.3`. UI Style Kit `2.7.0` is the current release candidate; `2.6.1` remains published on npm. The companion versions are reviewed releases. Layout Style `3.2.3` is the compatible structural release. The validated minimum remains `ui-style-kit-css@2.1.0`, `interactive-surface-css@1.5.0`, and `layout-style-css@3.0.0`.
21
+ The current combination is `ui-style-kit-css@2.7.2`, `interactive-surface-css@1.7.3`, and `layout-style-css@3.2.3`. UI Style Kit `2.7.2` is the current UI version. The companion versions are reviewed releases. Layout Style `3.2.3` is the compatible structural release. The validated minimum remains `ui-style-kit-css@2.1.0`, `interactive-surface-css@1.5.0`, and `layout-style-css@3.0.0`.
22
22
 
23
23
  ## Layout-to-visual pairing matrix
24
24
 
@@ -1,10 +1,14 @@
1
1
  # Publishing Guide
2
2
 
3
- ## 2.7.0 release workflow
3
+ ## 2.7.2 focused patch route
4
4
 
5
- The current checkout is a release candidate. [Release preparation notes](RELEASE-2.7.0.md)
5
+ The owner authorized selected affected checks and prohibited CI/full suites for this repair. Follow [the 2.7.2 publication boundary](RELEASE-2.7.2.md) and the reviewed manual publish-select-patch.yml workflow. It requires signed exact source, the merged exact-head STE-Adam review, generated-asset reproduction, package admission and anonymous byte readback. It uses the existing npm publisher credential; no new secret or application deployment is included. Do not dispatch either legacy publisher for this patch. The 2.7.1 procedure below is historical and does not describe current 2.7.2 evidence.
6
+
7
+ ## 2.7.1 release workflow
8
+
9
+ This guide prepares version `2.7.1`. [Release preparation notes](RELEASE-2.7.1.md)
6
10
  record the current local scope and gates; existing visual-QA documents are historical
7
- evidence, not proof that subsequent edits passed browser validation. The 2.7.0
11
+ evidence, not proof that subsequent edits passed browser validation. The 2.7.1
8
12
  changelog entry must carry the approved publication date before tagging.
9
13
 
10
14
  Update the tracked `wiki/` sources with the README and docs. Publishing those pages
@@ -13,9 +17,9 @@ documentation generator is configured in this package; reusable JavaScript helpe
13
17
  use JSDoc-compatible comments, and the checked-in build owns generated CSS, manifests,
14
18
  icons, README size measurements, and demo asset hashes.
15
19
 
16
- Prepare `ui-style-kit-css@2.7.0` on its release branch, open a pull request against `main`, and merge only after the fast automated gate is green and any requested manual demo review is complete. The aligned companion releases are `layout-style-css@3.2.3` and `interactive-surface-css@1.7.3`.
20
+ Prepare `ui-style-kit-css@2.7.1` on its release branch, open a pull request against `main`, and merge only after the fast automated gate is green and any requested manual demo review is complete. The aligned companion releases are `layout-style-css@3.2.3` and `interactive-surface-css@1.7.3`.
17
21
 
18
- Do not push `v2.7.0` before the reviewed release commit is on `main`. A pushed version tag runs Release Version Alignment, which validates the tag/package/changelog contract and creates the GitHub Release; publishing that release triggers the protected npm workflow.
22
+ Do not push `v2.7.1` before the reviewed release commit is on `main`. A pushed version tag runs Release Version Alignment, which validates the tag/package/changelog contract and creates the GitHub Release; publishing that release triggers the protected npm workflow.
19
23
 
20
24
  Release Version Alignment owns the fast automated release gate: lint, build, unit checks, the tagged Chromium release-smoke Playwright suite, and packed ecosystem preflight with `--skip-clean-install`. The visual-baseline suite, full UI matrix, and clean-install ecosystem matrix are manual escalation tools, not default push or publish blockers. The protected npm workflow intentionally does not rerun browser gates; it revalidates the immutable tag, package contracts, browser-free compatibility checks, companion commit reachability, the explicit release preflight with `--skip-clean-install`, npm token presence, npm owner authorization, and registry state before publishing.
21
25
 
@@ -76,7 +80,7 @@ npm run check:ecosystem:packs -- --layout-repo ../Layout-Style-CSS --interactive
76
80
  npm publish
77
81
  ```
78
82
 
79
- `prepublishOnly` runs `npm run release:verify`, so a direct `npm publish` still has the default fast release gate. For GitHub releases, push or dispatch the matching package tag, such as `v2.7.0`, only after the release PR is merged. The release workflows verify that `package.json`, `package-lock.json`, `CHANGELOG.md`, generated dist banners, and ecosystem pins are aligned before publishing. Dispatch the protected npm workflow from the current `main` workflow file when recovering publication for a release that has already passed Release Version Alignment.
83
+ `prepublishOnly` runs `npm run release:verify`, so a direct `npm publish` still has the default fast release gate. For GitHub releases, push or dispatch the matching package tag, such as `v2.7.1`, only after the release PR is merged. The release workflows verify that `package.json`, `package-lock.json`, `CHANGELOG.md`, generated dist banners, and ecosystem pins are aligned before publishing. Dispatch the protected npm workflow from the current `main` workflow file when recovering publication for a release that has already passed Release Version Alignment.
80
84
 
81
85
  The repository `NPM_TOKEN` secret must authenticate to npm as a user that appears in `npm owner ls ui-style-kit-css`. If the token belongs to another npm account or lacks package publish rights, npm may report a misleading registry `E404` at publish time.
82
86
 
@@ -88,4 +92,4 @@ npm run release:minor
88
92
  npm run release:major
89
93
  ```
90
94
 
91
- Use patch for compatible fixes, minor for new themes, presets, component capabilities, or browser-support contracts, and major for incompatible public API changes. Version `2.7.0` is a minor candidate because it adds shared component presentation and spacing controls while retaining the existing preset and semantic component APIs. Future feature versioning continues to follow this policy.
95
+ Use patch for compatible fixes, minor for new themes, presets, component capabilities, or browser-support contracts, and major for incompatible public API changes. Version `2.7.1` is a patch release because it repairs interaction paint and contrast while retaining the preset and semantic component APIs. Future feature versioning continues to follow this policy.
@@ -0,0 +1,21 @@
1
+ # v2.7.1 interaction contrast patch
2
+
3
+ This compatible patch preserves the 20 presets, 25 named color themes, native palettes, three modes, and existing public entrypoints.
4
+
5
+ ## Corrections
6
+
7
+ - Neutral hover rules no longer replace filled action backgrounds while retaining their foregrounds.
8
+ - Outlined CTAs retain readable surface ink at rest and their paired primary fill on hover. Neutral defaults exclude these paint-owning modifiers; Clay icon buttons use the control surface beneath their labels.
9
+ - Inline-link presentation excludes prefixed and semantic action classes. The build generates semantic aliases only for selectors that positively select a promoted component; exclusions alone cannot introduce a competing component rule. Variant exclusions also cover mixed prefixed/semantic markup used by React consumers.
10
+ - Primary, danger, warning, and current-navigation labels retain a matched foreground and background. Decorative reflections stay outside the central label lane.
11
+ - Neumorphism table values use readable surface ink, and Bento success and warning badge labels remain readable on translucent tints.
12
+ - Neo Noir warning paint belongs to its skewed face, preserving the component geometry.
13
+ - Y2K cut modifiers preserve primary action paint, and the compact trust seal contains its full number and caption.
14
+
15
+ ## Verification boundary
16
+
17
+ Focused Chromium regressions cover all presets, native plus named palettes, all modes, and rest, hover, active, keyboard-focus, and pressed-hover states. Fixtures include prefixed buttons, both semantic namespaces, mixed React class models, anchor actions, marketing CTAs, icon actions, native fields, disclosures, navigation, and tables. The React paint check asserts the real theme IDs visited, preventing a repeated native palette from masquerading as named-theme coverage.
18
+
19
+ Manual demo interaction uses the connected local Opera browser because Gnomie Browser Commander's runtime is unavailable in this session. Local evidence, protected GitHub release checks, npm publication, and live demo verification remain separate gates. No jsdoc2md generator is configured in this CSS package; JSDoc-compatible comments and the repository build maintain the generated artifacts.
20
+
21
+ Publication follows [PUBLISHING.md](PUBLISHING.md). The aligned companions remain Interactive Surface CSS 1.7.3 and Layout Style CSS 3.2.3.
@@ -0,0 +1,55 @@
1
+ # v2.7.2 native select affordance patch
2
+
3
+ This compatible patch restores dropdown cues while retaining the 20 presets,
4
+ 25 themes, public entrypoints, native popups and semantic namespaces.
5
+
6
+ ## Corrections
7
+
8
+ Preset-layer semantic field background shorthands reset the native indicator's
9
+ image, size, position and repetition. The shared fallback restores the existing
10
+ public tokens above generic component paint. The reserved text gutter survives
11
+ compact preset padding. Retro Glass keeps its indicator above its recessed
12
+ material; Neo Noir keeps its browser-owned arrow without duplicate custom paint.
13
+ Tactile hardware arrows and Clay texture layers remain preset-owned.
14
+
15
+ ## Focused evidence
16
+
17
+ Two individually selected Chromium cases passed. The first visits all 20 presets
18
+ in light, dark and contrast modes with native, canonical `.usk-select`, compatibility
19
+ `.ui-select` and prefixed controls. The second checks keyboard selection, disabled
20
+ and multiple-select semantics, and settled LTR/RTL positioning under reduced
21
+ motion. The selected original single/multiple source contract and new publication
22
+ authority case also passed. The three changed stylesheets pass focused lint.
23
+ Named-theme, Firefox, WebKit and whole-suite results are not claimed here.
24
+
25
+ The first shared fix exposed Y2K gutter reset and Retro Glass material precedence.
26
+ Generated alias tracing identified Neo Noir's reduced root specificity. Test-only
27
+ corrections distinguish repeating Clay texture from indicators, preserve Tactile's
28
+ hardware end cap, and await computed CSS settlement in a standards-mode fixture.
29
+
30
+ Gnomie visually inspected the candidate CSS on the retained actual installed SYS
31
+ catalog DOM at desktop and phone widths. Both catalog page-size and language
32
+ controls had bounded arrows without overflow. This diagnostic preview is separate
33
+ from published-package consumer qualification and hosted acceptance.
34
+
35
+ ## Publication boundary
36
+
37
+ The owner authorized selected affected checks and prohibited CI/full suites for
38
+ this repair. The manual `publish-select-patch.yml` route is restricted to 2.7.2.
39
+ It requires a verified exact source commit, merged PR and STE-Adam's latest
40
+ approval of that head independently of the author. A trusted main controller is
41
+ retained before candidate checkout. It reproduces tracked generated assets, checks
42
+ package contents, packs without lifecycle hooks, uses the existing npm package-owner
43
+ credential and compares anonymous public npm bytes to its SHA-256/SHA-512 receipt.
44
+ The matching GitHub release includes that tarball and receipt. The built-in
45
+ repository token creates its tag/release without starting legacy CI publishers.
46
+ No tests, CI script, new secret, paid resource or application deployment is included.
47
+
48
+ Default historical publishers and package hooks remain unchanged. This route does
49
+ not assert their suites ran. This CSS repository has no configured jsdoc2md
50
+ generator. The new publisher has a [granular jsdoc2md reference](api/publish-select-patch.md), generated using the existing SYS workspace tool. Professional JSDoc-compatible comments, maintained documentation and
51
+ the normal build preserve the source/generated boundary. Tracked wiki changes do
52
+ not publish the hosted Wiki. SYS must qualify the actual published stable package
53
+ and its integrity before production.
54
+
55
+ Interactive Surface CSS 1.7.3 and Layout Style CSS 3.2.3 remain aligned companions.
@@ -0,0 +1,80 @@
1
+ <!-- Generated with jsdoc2md from scripts/publish-select-patch.mjs; do not edit by hand. -->
2
+
3
+ ## Functions
4
+
5
+ <dl>
6
+ <dt><a href="#admitFocusedPatch">admitFocusedPatch(evidence)</a> ⇒ <code>string</code></dt>
7
+ <dd><p>Admit only this patch&#39;s verified source and the latest exact-source STE-Adam review.</p>
8
+ </dd>
9
+ <dt><a href="#run">run(program, args)</a> ⇒ <code>string</code></dt>
10
+ <dd><p>Execute a fixed program with argument-array boundaries and no credential output on failure.</p>
11
+ </dd>
12
+ <dt><a href="#api">api(endpoint)</a> ⇒ <code>object</code></dt>
13
+ <dd><p>Read one bounded JSON result from the authenticated repository API.</p>
14
+ </dd>
15
+ <dt><a href="#receipt">receipt()</a> ⇒ <code>object</code></dt>
16
+ <dd><p>Read the immutable checksum receipt produced before publication.</p>
17
+ </dd>
18
+ <dt><a href="#main">main(mode)</a> ⇒ <code>Promise.&lt;void&gt;</code></dt>
19
+ <dd><p>Publish-support commands perform admission, artifact hashing and public byte readback only.
20
+ The workflow owns the explicit npm publication; no tests or lifecycle hooks are dispatched here.</p>
21
+ </dd>
22
+ </dl>
23
+
24
+ <a name="admitFocusedPatch"></a>
25
+
26
+ ## admitFocusedPatch(evidence) ⇒ <code>string</code>
27
+ Admit only this patch's verified source and the latest exact-source STE-Adam review.
28
+
29
+ **Kind**: global function
30
+ **Returns**: <code>string</code> - Exact admitted source commit.
31
+
32
+ | Param | Type | Description |
33
+ | --- | --- | --- |
34
+ | evidence | <code>object</code> | Authoritative GitHub and checked-out package evidence. |
35
+
36
+ <a name="run"></a>
37
+
38
+ ## run(program, args) ⇒ <code>string</code>
39
+ Execute a fixed program with argument-array boundaries and no credential output on failure.
40
+
41
+ **Kind**: global function
42
+ **Returns**: <code>string</code> - Successful standard output.
43
+
44
+ | Param | Type | Description |
45
+ | --- | --- | --- |
46
+ | program | <code>string</code> | Fixed executable. |
47
+ | args | <code>Array.&lt;string&gt;</code> | Literal arguments. |
48
+
49
+ <a name="api"></a>
50
+
51
+ ## api(endpoint) ⇒ <code>object</code>
52
+ Read one bounded JSON result from the authenticated repository API.
53
+
54
+ **Kind**: global function
55
+ **Returns**: <code>object</code> - Parsed API result.
56
+
57
+ | Param | Type | Description |
58
+ | --- | --- | --- |
59
+ | endpoint | <code>string</code> | Fixed repository endpoint with validated scope. |
60
+
61
+ <a name="receipt"></a>
62
+
63
+ ## receipt() ⇒ <code>object</code>
64
+ Read the immutable checksum receipt produced before publication.
65
+
66
+ **Kind**: global function
67
+ **Returns**: <code>object</code> - Exact artifact identity.
68
+ <a name="main"></a>
69
+
70
+ ## main(mode) ⇒ <code>Promise.&lt;void&gt;</code>
71
+ Publish-support commands perform admission, artifact hashing and public byte readback only.
72
+ The workflow owns the explicit npm publication; no tests or lifecycle hooks are dispatched here.
73
+
74
+ **Kind**: global function
75
+ **Returns**: <code>Promise.&lt;void&gt;</code> - Completion after the selected phase verifies its boundary.
76
+
77
+ | Param | Type | Description |
78
+ | --- | --- | --- |
79
+ | mode | <code>string</code> | Fixed workflow phase. |
80
+
package/manifest.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "breakingChange": "increment-schemaVersion-before-removing-or-renaming-fields"
6
6
  },
7
7
  "name": "ui-style-kit-css",
8
- "version": "2.7.0",
8
+ "version": "2.7.2",
9
9
  "cascadeLayers": [
10
10
  "ui-style-kit.theme_colors",
11
11
  "ui-style-kit.native_elements",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui-style-kit-css",
3
- "version": "2.7.0",
3
+ "version": "2.7.2",
4
4
  "description": "CSS theme and UI style preset library for accessible websites, dashboards, admin interfaces, and client-facing pages.",
5
5
  "style": "dist/ui-style-kit.css",
6
6
  "main": "dist/ui-style-kit.css",
@@ -438,7 +438,8 @@
438
438
  .deco-card, .deco-panel { background: var(--deco-card-bg); }
439
439
  .deco-toolbar, .deco-table-wrap { background: var(--deco-control-bg); }
440
440
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
441
- .deco-button:where(:not([data-ui-variant])):not(.deco-button-primary):not(.deco-button-secondary):not(.deco-button-danger):not(.deco-button-warning):not(.deco-button-ghost), .deco-icon-button { background: var(--deco-control-bg); }
441
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
442
+ .deco-button:where(:not([data-ui-variant])):not(.deco-button-primary):not(.deco-button-secondary):not(.deco-button-danger):not(.deco-button-warning):not(.deco-button-ghost):not(.deco-button-outline-heavy), .deco-icon-button { background: var(--deco-control-bg); }
442
443
  .deco-button, .deco-icon-button, .deco-badge, .deco-nav-link { font-family: var(--deco-font-control); }
443
444
 
444
445
 
@@ -630,7 +631,7 @@
630
631
  .deco-button.deco-button-outline-heavy,
631
632
  .deco-button-outline-heavy {
632
633
  background: transparent;
633
- color: var(--usk-primary-ink, var(--deco-primary));
634
+ color: var(--usk-primary-ink, var(--deco-text));
634
635
  border-style: solid;
635
636
  border-width: 2px;
636
637
  border-color: var(--deco-primary);
@@ -1058,6 +1059,12 @@
1058
1059
  }
1059
1060
  }
1060
1061
 
1062
+ /** Named palettes preserve their tested primary paint pair instead of tempering only the fill. */
1063
+ [data-ui="art-deco"][data-theme][data-mode] :is(.deco-button-primary, .deco-nav-link[aria-current="page"], .deco-nav-link.is-active) {
1064
+ background-color: var(--deco-primary);
1065
+ color: var(--deco-on-primary);
1066
+ }
1067
+
1061
1068
  /**
1062
1069
  * Lets explicit runtime token edits render exact user-supplied action colors
1063
1070
  * while untouched shared themes keep the tempered Art Deco jewel paint.
@@ -1524,7 +1531,9 @@
1524
1531
  text-indent: 0;
1525
1532
  }
1526
1533
 
1527
- .deco-button:where(:not([data-ui-variant])):not(.deco-button-primary):not(.deco-button-secondary):not(.deco-button-danger):not(.deco-button-warning):not(.deco-button-ghost),
1534
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
1535
+
1536
+ .deco-button:where(:not([data-ui-variant])):not(.deco-button-primary):not(.deco-button-secondary):not(.deco-button-danger):not(.deco-button-warning):not(.deco-button-ghost):not(.deco-button-outline-heavy),
1528
1537
  .deco-icon-button {
1529
1538
  background-color: var(--deco-surface-strong);
1530
1539
  background-image: none;
@@ -464,7 +464,8 @@
464
464
  .bau-card, .bau-panel { background: var(--bau-card-bg); }
465
465
  .bau-toolbar, .bau-table-wrap { background: var(--bau-control-bg); }
466
466
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
467
- .bau-button:where(:not([data-ui-variant])):not(.bau-button-primary):not(.bau-button-secondary):not(.bau-button-danger):not(.bau-button-warning):not(.bau-button-ghost):not(.is-primary):not(.is-secondary):not(.is-danger):not(.is-ghost):not(.is-busy):not(.is-hover), .bau-icon-button { background: var(--bau-control-bg); }
467
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
468
+ .bau-button:where(:not([data-ui-variant])):not(.bau-button-primary):not(.bau-button-secondary):not(.bau-button-danger):not(.bau-button-warning):not(.bau-button-ghost):not(.bau-button-outline-heavy):not(.is-primary):not(.is-secondary):not(.is-danger):not(.is-ghost):not(.is-busy):not(.is-hover), .bau-icon-button { background: var(--bau-control-bg); }
468
469
  .bau-button, .bau-icon-button, .bau-badge, .bau-nav-link { font-family: var(--bau-font-control); }
469
470
 
470
471
 
@@ -662,7 +663,7 @@
662
663
  .bau-button.bau-button-outline-heavy,
663
664
  .bau-button-outline-heavy {
664
665
  background: transparent;
665
- color: var(--usk-primary-ink, var(--bau-primary));
666
+ color: var(--usk-primary-ink, var(--bau-text));
666
667
  border-style: solid;
667
668
  border-width: 2px;
668
669
  border-color: var(--bau-primary);
@@ -950,7 +951,8 @@
950
951
  .bau-button-primary { background: var(--bau-primary); color: var(--bau-on-primary); border-color: var(--bau-primary); }
951
952
  .bau-button-secondary { background: var(--bau-secondary); color: var(--bau-on-secondary); border-color: var(--bau-secondary); }
952
953
  .bau-button-danger { background: var(--bau-danger); color: var(--bau-on-danger); border-color: var(--bau-danger); }
953
- .bau-button-ghost { background: transparent; color: var(--usk-primary-ink, var(--bau-primary)); border-color: transparent; }
954
+ /** Native palettes need surface ink when the primary fill is too dark for an unfilled action. */
955
+ .bau-button-ghost { background: transparent; color: var(--usk-primary-ink, var(--bau-text)); border-color: transparent; }
954
956
  }
955
957
 
956
958
  @layer ui-style-kit.bauhaus {
package/styles/bento.css CHANGED
@@ -454,7 +454,8 @@
454
454
  /* Theme-responsive component defaults */
455
455
  .bento-card, .bento-panel { background: var(--bento-card-bg); }
456
456
  .bento-toolbar, .bento-table-wrap { background: var(--bento-control-bg); }
457
- .bento-button:where(:not(.bento-button-primary):not(.bento-button-secondary):not(.bento-button-danger):not(.bento-button-warning):not(.bento-button-ghost):not(.is-primary):not(.is-secondary):not(.is-danger):not(.is-ghost):not(.is-hover):not(.is-busy)), .bento-icon-button { background: var(--bento-control-bg); }
457
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
458
+ .bento-button:where(:not(.bento-button-primary):not(.bento-button-secondary):not(.bento-button-danger):not(.bento-button-warning):not(.bento-button-ghost):not(.bento-button-outline-heavy):not(.is-primary):not(.is-secondary):not(.is-danger):not(.is-ghost):not(.is-hover):not(.is-busy)), .bento-icon-button { background: var(--bento-control-bg); }
458
459
  .bento-button, .bento-icon-button, .bento-badge, .bento-nav-link { font-family: var(--bento-font-control); }
459
460
 
460
461
 
@@ -500,8 +501,9 @@
500
501
  .bento-badge { display: inline-flex; align-items: center; gap: var(--bento-space-1); min-height: 1.75rem; padding: .38rem .72rem; background: var(--bento-tile-secondary-bg); color: var(--bento-text); border: 1px solid var(--bento-tile-edge); border-radius: var(--bento-radius-sm); box-shadow: inset 0 1px 0 rgb(var(--bento-surface-strong-rgb) / .62); font-size: .8125rem; font-weight: 800; line-height: 1; }
501
502
  .bento-badge-primary { background: var(--bento-primary); color: var(--bento-on-primary); border-color: var(--bento-primary); }
502
503
  .bento-badge-secondary { background: rgb(var(--bento-primary-rgb) / .10); color: var(--usk-primary-ink, var(--bento-primary)); border-color: transparent; }
503
- .bento-badge-success { background: rgb(var(--bento-success-rgb) / .14); color: var(--bento-success); border-color: transparent; }
504
- .bento-badge-warning { background: rgb(var(--bento-warning-rgb) / .14); color: var(--bento-warning); border-color: transparent; }
504
+ /** Warning and success tints use surface text rather than their solid signal fill as ink. */
505
+ .bento-badge-success { background: rgb(var(--bento-success-rgb) / .14); color: var(--bento-text); border-color: transparent; }
506
+ .bento-badge-warning { background: rgb(var(--bento-warning-rgb) / .14); color: var(--bento-text); border-color: transparent; }
505
507
  .bento-badge-danger { background: rgb(var(--bento-danger-rgb) / .14); color: var(--bento-danger); border-color: transparent; }
506
508
 
507
509
  .bento-nav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--bento-space-2); padding: var(--bento-space-2); background: var(--bento-card-bg); border: 1px solid var(--bento-tile-edge); border-radius: var(--bento-tile-radius); box-shadow: var(--bento-tile-shadow); }
@@ -674,7 +676,7 @@
674
676
  .bento-button.bento-button-outline-heavy,
675
677
  .bento-button-outline-heavy {
676
678
  background: transparent;
677
- color: var(--usk-primary-ink, var(--bento-primary));
679
+ color: var(--usk-primary-ink, var(--bento-text));
678
680
  border-style: solid;
679
681
  border-width: 2px;
680
682
  border-color: var(--bento-primary);
@@ -817,7 +819,7 @@
817
819
  }
818
820
  .bento-button.bento-button-outline-heavy, .bento-button-outline-heavy {
819
821
  background: rgb(var(--bento-surface-strong-rgb) / var(--bento-panel-alpha));
820
- color: var(--usk-primary-ink, var(--bento-primary));
822
+ color: var(--usk-primary-ink, var(--bento-text));
821
823
  border-width: 1px;
822
824
  border-color: rgb(var(--bento-primary-rgb) / .32);
823
825
  border-radius: var(--bento-control-radius);
@@ -1210,7 +1212,6 @@
1210
1212
 
1211
1213
  [data-ui=bento][data-mode] :is(.bento-button, .bento-icon-button) {
1212
1214
  align-items: center;
1213
- background: var(--bento-mosaic-panel-soft);
1214
1215
  border: 1px solid var(--bento-mosaic-line);
1215
1216
  border-radius: 8px;
1216
1217
  display: inline-flex;
@@ -1221,6 +1222,8 @@
1221
1222
  padding: 0 16px;
1222
1223
  transition: background-color 150ms ease, border-color 150ms ease, box-shadow 150ms ease, transform 150ms ease;
1223
1224
  }
1225
+ /** Mosaic neutral paint yields to the outlined CTA's paired hover fill. */
1226
+ [data-ui=bento][data-mode] :is(.bento-button, .bento-icon-button):where(:not(.bento-button-outline-heavy)) { background: var(--bento-mosaic-panel-soft); }
1224
1227
  [data-ui=bento][data-mode] .bento-button:hover:not(:disabled) { transform: translateY(-1px); }
1225
1228
  [data-ui=bento][data-mode] .bento-button:active:not(:disabled) { transform: translateY(1px); }
1226
1229
  [data-ui=bento][data-mode] .bento-button.is-primary,
@@ -1595,7 +1598,8 @@
1595
1598
  [data-ui=bento][data-mode] .bento-card, [data-ui=bento][data-mode] .bento-panel { padding: 16px; }
1596
1599
  [data-ui=bento][data-mode] .bento-button, [data-ui=bento][data-mode] .bento-icon-button { border-radius: 8px; box-shadow: none; font-weight: 750; text-shadow: none; }
1597
1600
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
1598
- [data-ui=bento][data-mode] .bento-button:where(:not([data-ui-variant])):not(.bento-button-primary):not(.bento-button-secondary):not(.bento-button-danger):not(.bento-button-warning):not(.bento-button-ghost):not(.is-primary):not(.is-secondary):not(.is-danger):not(.is-ghost):not(.is-busy):not(.is-hover) { background: var(--bento-surface-soft); }
1601
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
1602
+ [data-ui=bento][data-mode] .bento-button:where(:not([data-ui-variant])):not(.bento-button-primary):not(.bento-button-secondary):not(.bento-button-danger):not(.bento-button-warning):not(.bento-button-ghost):not(.bento-button-outline-heavy):not(.is-primary):not(.is-secondary):not(.is-danger):not(.is-ghost):not(.is-busy):not(.is-hover) { background: var(--bento-surface-soft); }
1599
1603
  [data-ui=bento][data-mode] .bento-button.bento-button-primary, [data-ui=bento][data-mode] .bento-button.is-primary, [data-ui=bento][data-mode] .bento-button.is-busy { background: var(--bento-primary); color: var(--bento-on-primary); border-color: var(--bento-primary); }
1600
1604
  [data-ui=bento][data-mode] .bento-button.bento-button-secondary, [data-ui=bento][data-mode] .bento-button.is-secondary { background: transparent; color: var(--bento-link); border-color: var(--bento-primary); }
1601
1605
  [data-ui=bento][data-mode] .bento-button.bento-button-danger, [data-ui=bento][data-mode] .bento-button.is-danger { background: var(--bento-mosaic-danger-soft); color: var(--bento-text); border-color: var(--bento-danger); }
@@ -432,7 +432,8 @@
432
432
 
433
433
  [data-ui="brutalism"][data-mode] { background: var(--brutal-theme-bg); background-size: var(--brutal-theme-bg-size); }
434
434
 
435
- [data-ui="brutalism"] a { color: var(--brutal-link); text-decoration-thickness: 0.14em; text-underline-offset: 0.16em; font-weight: 800; }
435
+ /** Inline-link ink must not override the foreground paired with an action surface. */
436
+ [data-ui="brutalism"] a:where(:not(.brutal-button):not(.brutal-icon-button)) { color: var(--brutal-link); text-decoration-thickness: 0.14em; text-underline-offset: 0.16em; font-weight: 800; }
436
437
  [data-ui="brutalism"] ::selection { background: var(--brutal-primary); color: var(--brutal-on-primary); }
437
438
 
438
439
  /* Spinner geometry follows the brutalism preset's blunt mechanical edges. */
@@ -525,7 +526,8 @@
525
526
  .brutal-card, .brutal-panel { background: var(--brutal-card-bg); }
526
527
  .brutal-toolbar, .brutal-table-wrap { background: var(--brutal-control-bg); }
527
528
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
528
- .brutal-button:where(:not([data-ui-variant])):not(.brutal-button-primary):not(.brutal-button-secondary):not(.brutal-button-danger):not(.brutal-button-warning):not(.brutal-button-ghost), .brutal-icon-button { background: var(--brutal-control-bg); }
529
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
530
+ .brutal-button:where(:not([data-ui-variant])):not(.brutal-button-primary):not(.brutal-button-secondary):not(.brutal-button-danger):not(.brutal-button-warning):not(.brutal-button-ghost):not(.brutal-button-outline-heavy), .brutal-icon-button { background: var(--brutal-control-bg); }
529
531
  .brutal-button, .brutal-icon-button, .brutal-badge, .brutal-nav-link { font-family: var(--brutal-font-control); }
530
532
 
531
533
 
@@ -639,7 +641,7 @@
639
641
  .brutal-button.brutal-button-outline-heavy,
640
642
  .brutal-button-outline-heavy {
641
643
  background: transparent;
642
- color: var(--usk-primary-ink, var(--brutal-primary));
644
+ color: var(--usk-primary-ink, var(--brutal-text));
643
645
  border-style: solid;
644
646
  border-width: 2px;
645
647
  border-color: var(--brutal-primary);
package/styles/clay.css CHANGED
@@ -446,7 +446,8 @@
446
446
  .clay-card, .clay-panel { background: var(--clay-card-bg); }
447
447
  .clay-toolbar, .clay-table-wrap { background: var(--clay-control-bg); }
448
448
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
449
- .clay-button:where(:not([data-ui-variant])):not(.clay-button-primary):not(.clay-button-secondary):not(.clay-button-danger):not(.clay-button-warning):not(.clay-button-ghost), .clay-icon-button { background: var(--clay-control-bg); }
449
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
450
+ .clay-button:where(:not([data-ui-variant])):not(.clay-button-primary):not(.clay-button-secondary):not(.clay-button-danger):not(.clay-button-warning):not(.clay-button-ghost):not(.clay-button-outline-heavy), .clay-icon-button { background: var(--clay-control-bg); }
450
451
  .clay-button, .clay-icon-button, .clay-badge, .clay-nav-link { font-family: var(--clay-font-control); }
451
452
 
452
453
 
@@ -638,7 +639,7 @@
638
639
  .clay-button.clay-button-outline-heavy,
639
640
  .clay-button-outline-heavy {
640
641
  background: transparent;
641
- color: var(--usk-primary-ink, var(--clay-primary));
642
+ color: var(--usk-primary-ink, var(--clay-text));
642
643
  border-style: solid;
643
644
  border-width: 2px;
644
645
  border-color: var(--clay-primary);
@@ -895,7 +896,8 @@
895
896
  --clay-molded-track: var(--clay-grain-image), linear-gradient(180deg, var(--clay-material-contact), transparent 46%), var(--clay-material-inset);
896
897
  --clay-molded-raised: var(--clay-grain-image), linear-gradient(176deg, var(--clay-material-highlight), transparent 42%), var(--clay-material-raised);
897
898
  --clay-molded-thumb: var(--clay-grain-image), radial-gradient(circle at 34% 24%, var(--clay-material-highlight), transparent 46%), linear-gradient(176deg, var(--clay-material-highlight), transparent 44%), var(--clay-thumb-material);
898
- --clay-molded-primary: var(--clay-grain-image), linear-gradient(176deg, var(--clay-material-highlight), transparent 42%), var(--clay-pigment-primary);
899
+ /** Raised highlights stay above the label, preserving the pigment's paired ink. */
900
+ --clay-molded-primary: var(--clay-grain-image), linear-gradient(176deg, var(--clay-material-highlight), transparent 20%), var(--clay-pigment-primary);
899
901
  --clay-molded-success: var(--clay-grain-image), linear-gradient(176deg, var(--clay-material-highlight), transparent 42%), var(--clay-pigment-success);
900
902
  --clay-molded-warning: var(--clay-grain-image), linear-gradient(176deg, var(--clay-material-highlight), transparent 42%), var(--clay-pigment-warning);
901
903
  --clay-molded-danger: var(--clay-grain-image), linear-gradient(176deg, var(--clay-material-highlight), transparent 42%), var(--clay-pigment-danger);
@@ -1073,11 +1075,12 @@
1073
1075
  }
1074
1076
 
1075
1077
  /** Gives every button the shallow relief and debossed lettering shown in the reference. */
1078
+ /** Action and icon labels use the control surface; thumb pigment belongs to movable parts. */
1076
1079
  .clay-button, .clay-icon-button,
1077
1080
  [data-ui="clay"][data-mode] :where(button:not([class]), input[type="button"]:not([class]), input[type="submit"]:not([class]), input[type="reset"]:not([class])) {
1078
1081
  min-height: 2rem;
1079
1082
  padding: .34rem .64rem;
1080
- background-color: var(--clay-thumb-material);
1083
+ background-color: var(--clay-control-bg);
1081
1084
  background-image: var(--clay-grain-image), linear-gradient(174deg, var(--clay-material-highlight), transparent 34%);
1082
1085
  background-size: var(--clay-grain-size), auto;
1083
1086
  border: 1px solid var(--clay-material-seam);
@@ -1102,7 +1105,8 @@
1102
1105
  text-shadow: var(--clay-label-relief);
1103
1106
  }
1104
1107
  .clay-button-primary { background: var(--clay-molded-primary); color: var(--clay-pigment-ink); border-color: var(--clay-pigment-primary); }
1105
- .clay-button-primary:hover { background-color: var(--clay-pigment-primary-hover); border-color: var(--clay-pigment-primary-hover); }
1108
+ /** Hover changes the relief and edge without lightening the pigment beneath its label. */
1109
+ .clay-button-primary:hover { background: var(--clay-molded-primary); border-color: var(--clay-pigment-primary-hover); }
1106
1110
  .clay-button-secondary { background: var(--clay-grain-image), linear-gradient(176deg, var(--clay-material-highlight), transparent 42%), var(--clay-pigment-secondary); color: var(--clay-on-secondary); border-color: var(--clay-pigment-secondary); }
1107
1111
  .clay-button-secondary:hover { background-color: var(--clay-pigment-secondary); border-color: var(--clay-pigment-secondary); }
1108
1112
  .clay-button-danger { background: var(--clay-molded-danger); color: rgb(var(--clay-danger-text-rgb)); border-color: var(--clay-pigment-danger); }
@@ -1127,7 +1131,7 @@
1127
1131
  }
1128
1132
  .clay-button.clay-button-outline-heavy, .clay-button-outline-heavy {
1129
1133
  background-color: var(--clay-material-raised);
1130
- color: var(--usk-primary-ink, var(--clay-primary));
1134
+ color: var(--usk-primary-ink, var(--clay-text));
1131
1135
  border: 2px solid var(--clay-primary);
1132
1136
  clip-path: var(--clay-chip-clip);
1133
1137
  }
@@ -1229,7 +1233,8 @@
1229
1233
  .clay-badge-danger { background: var(--clay-grain-image), linear-gradient(176deg, var(--clay-material-highlight), transparent 42%), color-mix(in srgb, var(--clay-pigment-danger) 28%, var(--clay-material-raised)); color: var(--clay-material-ink); border-color: color-mix(in srgb, var(--clay-pigment-danger), var(--clay-material-seam) 52%); }
1230
1234
  }
1231
1235
  .clay-nav { gap: 0; padding: .18rem; background: var(--clay-material-inset); border-color: var(--clay-material-seam); border-radius: .48rem .6rem .52rem .56rem; box-shadow: var(--clay-carved-shadow); clip-path: var(--clay-control-clip); filter: var(--clay-edge-filter); }
1232
- .clay-nav-link { min-height: 2.1rem; padding: .42rem .62rem; border-radius: .3rem .38rem .32rem .36rem; clip-path: var(--clay-control-clip); font-weight: 500; text-shadow: var(--clay-label-relief); }
1236
+ /** Navigation labels retain full surface ink over the textured clay slab. */
1237
+ .clay-nav-link { min-height: 2.1rem; padding: .42rem .62rem; border-radius: .3rem .38rem .32rem .36rem; clip-path: var(--clay-control-clip); font-weight: 500; color: var(--clay-text); text-shadow: var(--clay-label-relief); }
1233
1238
  .clay-nav-link[aria-current="page"], .clay-nav-link.is-active { background: var(--clay-molded-primary); color: var(--clay-pigment-ink); box-shadow: var(--clay-filled-shadow); clip-path: var(--clay-control-clip); filter: var(--clay-edge-filter); }
1234
1239
 
1235
1240
  .clay-alert { padding: .7rem .82rem; background-color: var(--clay-material-raised); background-image: var(--clay-grain-image), linear-gradient(170deg, var(--clay-material-highlight), transparent 42%); background-size: var(--clay-grain-size), auto; border: 1px solid var(--clay-material-seam); border-inline-start-width: .28rem; border-radius: .42rem .55rem .46rem .52rem; box-shadow: var(--clay-relief-shadow); clip-path: var(--clay-control-clip); filter: var(--clay-edge-filter); }
@@ -427,7 +427,8 @@
427
427
  }
428
428
  [data-ui="cyberpunk"] *, [data-ui="cyberpunk"] *::before, [data-ui="cyberpunk"] *::after { box-sizing: border-box; }
429
429
  [data-ui="cyberpunk"][data-mode] { background: var(--cyber-theme-bg); background-size: var(--cyber-theme-bg-size); }
430
- [data-ui="cyberpunk"] a { color: var(--cyber-link); text-decoration-color: rgb(var(--cyber-primary-rgb) / 0.6); text-underline-offset: 0.18em; }
430
+ /** Inline-link ink must not override the foreground paired with an action surface. */
431
+ [data-ui="cyberpunk"] a:where(:not(.cyber-button):not(.cyber-icon-button)) { color: var(--cyber-link); text-decoration-color: rgb(var(--cyber-primary-rgb) / 0.6); text-underline-offset: 0.18em; }
431
432
  [data-ui="cyberpunk"] ::selection { background: var(--cyber-primary); color: var(--cyber-on-primary); }
432
433
 
433
434
  .cyber-page { position: relative; min-height: 100vh; padding: clamp(1rem, 4vw, 3rem); }
@@ -478,7 +479,8 @@
478
479
  .cyber-card, .cyber-panel { background: var(--cyber-card-bg); }
479
480
  .cyber-toolbar, .cyber-table-wrap { background: var(--cyber-control-bg); }
480
481
  /** Semantic variant attributes take precedence over the legacy neutral-control fallback. */
481
- .cyber-button:where(:not([data-ui-variant])):not(.cyber-button-primary):not(.cyber-button-secondary):not(.cyber-button-danger):not(.cyber-button-warning):not(.cyber-button-ghost), .cyber-icon-button { background: var(--cyber-control-bg); }
482
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
483
+ .cyber-button:where(:not([data-ui-variant])):not(.cyber-button-primary):not(.cyber-button-secondary):not(.cyber-button-danger):not(.cyber-button-warning):not(.cyber-button-ghost):not(.cyber-button-outline-heavy), .cyber-icon-button { background: var(--cyber-control-bg); }
482
484
  .cyber-button, .cyber-icon-button, .cyber-badge, .cyber-nav-link { font-family: var(--cyber-font-control); }
483
485
 
484
486
  /* Spinner geometry follows the cyberpunk preset's clipped neon readouts. */
@@ -580,7 +582,7 @@
580
582
  .cyber-button.cyber-button-outline-heavy,
581
583
  .cyber-button-outline-heavy {
582
584
  background: transparent;
583
- color: var(--usk-primary-ink, var(--cyber-primary));
585
+ color: var(--usk-primary-ink, var(--cyber-text));
584
586
  border-style: solid;
585
587
  border-width: 2px;
586
588
  border-color: var(--cyber-primary);
@@ -1047,7 +1049,7 @@
1047
1049
  .cyber-button:hover,
1048
1050
  .cyber-icon-button:hover {
1049
1051
  border-color: var(--cyber-primary);
1050
- color: var(--usk-primary-ink, var(--cyber-primary));
1052
+ color: var(--usk-primary-ink, var(--cyber-text));
1051
1053
  box-shadow: 0 0 .75rem rgb(var(--cyber-primary-rgb) / .2);
1052
1054
  }
1053
1055
 
@@ -1618,7 +1620,8 @@
1618
1620
  border-color: transparent;
1619
1621
  background-color: transparent;
1620
1622
  background-image: none;
1621
- color: var(--usk-primary-ink, var(--cyber-primary));
1623
+ /** Unfilled native controls use readable surface ink rather than neon fill pigment. */
1624
+ color: var(--usk-primary-ink, var(--cyber-text));
1622
1625
  box-shadow: none;
1623
1626
  }
1624
1627
 
@@ -1627,7 +1630,8 @@
1627
1630
  border-color: var(--cyber-danger);
1628
1631
  background-color: rgb(var(--cyber-danger-rgb) / .12);
1629
1632
  background-image: linear-gradient(135deg, rgb(var(--cyber-danger-rgb) / .16), transparent 62%);
1630
- color: var(--cyber-danger);
1633
+ /** The signal tint is decorative; its label uses the contrasting surface foreground. */
1634
+ color: var(--cyber-text);
1631
1635
  box-shadow: var(--cyber-template-danger-glow);
1632
1636
  }
1633
1637
 
@@ -438,7 +438,9 @@
438
438
  .terminal-card, .terminal-panel { background: var(--terminal-card-bg); }
439
439
  .terminal-toolbar, .terminal-table-wrap { background: var(--terminal-control-bg); }
440
440
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
441
- .terminal-button:where(:not([data-ui-variant])):not(.terminal-button-primary):not(.terminal-button-secondary):not(.terminal-button-danger):not(.terminal-button-warning):not(.terminal-button-ghost):not(.is-active):not([aria-pressed="true"]),
441
+ /** Native press state bypasses the neutral fallback just like persistent pressed hooks. */
442
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
443
+ .terminal-button:where(:not([data-ui-variant])):not(.terminal-button-primary):not(.terminal-button-secondary):not(.terminal-button-danger):not(.terminal-button-warning):not(.terminal-button-ghost):not(.terminal-button-outline-heavy):not(.is-active):not([aria-pressed="true"]):not(:active),
442
444
  .terminal-icon-button:not(.is-active):not([aria-pressed="true"]) { background: var(--terminal-control-bg); }
443
445
  .terminal-button, .terminal-icon-button, .terminal-badge, .terminal-nav-link { font-family: var(--terminal-font-control); }
444
446
 
@@ -631,7 +633,7 @@
631
633
  .terminal-button.terminal-button-outline-heavy,
632
634
  .terminal-button-outline-heavy {
633
635
  background: transparent;
634
- color: var(--usk-primary-ink, var(--terminal-primary));
636
+ color: var(--usk-primary-ink, var(--terminal-text));
635
637
  border-style: solid;
636
638
  border-width: 2px;
637
639
  border-color: var(--terminal-primary);
@@ -438,7 +438,8 @@
438
438
  .luxe-card, .luxe-panel { background: var(--luxe-card-bg); }
439
439
  .luxe-toolbar, .luxe-table-wrap { background: var(--luxe-control-bg); }
440
440
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
441
- .luxe-button:where(:not([data-ui-variant])):not(.luxe-button-primary):not(.luxe-button-secondary):not(.luxe-button-danger):not(.luxe-button-warning):not(.luxe-button-ghost), .luxe-icon-button { background: var(--luxe-control-bg); }
441
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
442
+ .luxe-button:where(:not([data-ui-variant])):not(.luxe-button-primary):not(.luxe-button-secondary):not(.luxe-button-danger):not(.luxe-button-warning):not(.luxe-button-ghost):not(.luxe-button-outline-heavy), .luxe-icon-button { background: var(--luxe-control-bg); }
442
443
  .luxe-button, .luxe-icon-button, .luxe-badge, .luxe-nav-link { font-family: var(--luxe-font-control); }
443
444
 
444
445
 
@@ -630,7 +631,7 @@
630
631
  .luxe-button.luxe-button-outline-heavy,
631
632
  .luxe-button-outline-heavy {
632
633
  background: transparent;
633
- color: var(--usk-primary-ink, var(--luxe-primary));
634
+ color: var(--usk-primary-ink, var(--luxe-text));
634
635
  border-style: solid;
635
636
  border-width: 2px;
636
637
  border-color: var(--luxe-primary);