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
@@ -438,7 +438,8 @@
438
438
  .utility-card, .utility-panel { background: var(--utility-card-bg); }
439
439
  .utility-toolbar, .utility-table-wrap { background: var(--utility-control-bg); }
440
440
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
441
- .utility-button:where(:not([data-ui-variant])):not(.utility-button-primary):not(.utility-button-secondary):not(.utility-button-danger):not(.utility-button-warning):not(.utility-button-ghost):not(.utility-button-guarded), .utility-icon-button { background: var(--utility-control-bg); }
441
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
442
+ .utility-button:where(:not([data-ui-variant])):not(.utility-button-primary):not(.utility-button-secondary):not(.utility-button-danger):not(.utility-button-warning):not(.utility-button-ghost):not(.utility-button-outline-heavy):not(.utility-button-guarded), .utility-icon-button { background: var(--utility-control-bg); }
442
443
  .utility-button, .utility-icon-button, .utility-badge, .utility-nav-link { font-family: var(--utility-font-control); }
443
444
 
444
445
 
@@ -630,7 +631,7 @@
630
631
  .utility-button.utility-button-outline-heavy,
631
632
  .utility-button-outline-heavy {
632
633
  background: transparent;
633
- color: var(--usk-primary-ink, var(--utility-primary));
634
+ color: var(--usk-primary-ink, var(--utility-text));
634
635
  border-style: solid;
635
636
  border-width: 2px;
636
637
  border-color: var(--utility-primary);
@@ -944,7 +945,8 @@
944
945
  @media print {
945
946
  [data-ui="industrial-utility"] { background: #fff !important; color: #000 !important; }
946
947
  [data-ui="industrial-utility"] * { box-shadow: none !important; text-shadow: none !important; }
947
- [data-ui="industrial-utility"] a { color: #000 !important; text-decoration: underline; }
948
+ /** Inline-link ink must not override the foreground paired with an action surface. */
949
+ [data-ui="industrial-utility"] a { color: #000 !important; text-decoration: underline; }
948
950
  }
949
951
  }
950
952
 
@@ -1096,15 +1098,15 @@
1096
1098
  outline-offset: 2px;
1097
1099
  }
1098
1100
 
1099
- [data-ui="industrial-utility"] a {
1101
+ [data-ui="industrial-utility"] a:where(:not(.utility-button):not(.utility-icon-button):not(.utility-nav-link)) {
1100
1102
  color: var(--utility-material-lamp-blue);
1101
1103
  font-weight: 700;
1102
1104
  text-decoration-thickness: 1px;
1103
1105
  text-underline-offset: 3px;
1104
1106
  }
1105
1107
 
1106
- [data-ui="industrial-utility"] a:hover,
1107
- [data-ui="industrial-utility"] a.is-hover {
1108
+ [data-ui="industrial-utility"] a:where(:not(.utility-button):not(.utility-icon-button):not(.utility-nav-link)):hover,
1109
+ [data-ui="industrial-utility"] a:where(:not(.utility-button):not(.utility-icon-button):not(.utility-nav-link)).is-hover {
1108
1110
  color: var(--utility-material-warning);
1109
1111
  }
1110
1112
 
@@ -440,7 +440,8 @@
440
440
  .max-button:hover, .max-icon-button:hover { transform: translate(-2px, -2px); border-color: var(--max-ink); box-shadow: .4rem .4rem 0 rgb(var(--max-secondary-rgb) / .76); }
441
441
  .max-button:active, .max-icon-button:active, .max-button[aria-pressed="true"], .max-icon-button[aria-pressed="true"], .max-button.is-active, .max-icon-button.is-active { transform: translate(.12rem, .12rem); box-shadow: .12rem .12rem 0 var(--max-ink); }
442
442
  .max-button-primary { background: var(--max-poster-fill); color: var(--max-on-primary); border-color: var(--max-ink); }
443
- .max-button-primary:hover { background: linear-gradient(110deg, var(--max-primary-hover), var(--max-danger), var(--max-accent)); border-color: var(--max-ink); }
443
+ /** A single foreground can span only gradient stops from its paired color role. */
444
+ .max-button-primary:hover { background: linear-gradient(110deg, var(--max-primary-hover), var(--max-primary)); border-color: var(--max-ink); }
444
445
  .max-button-secondary { background: var(--max-secondary); color: var(--max-on-secondary); border-color: var(--max-secondary); }
445
446
  .max-button-secondary:hover { background: var(--max-secondary-hover); border-color: var(--max-secondary-hover); }
446
447
  .max-button-danger { background: var(--max-danger); color: var(--max-on-danger); border-color: var(--max-ink); }
@@ -452,6 +453,7 @@
452
453
  .max-card, .max-panel { background: var(--max-card-bg); }
453
454
  .max-toolbar, .max-table-wrap { background: var(--max-control-bg); }
454
455
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
456
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
455
457
  .max-button:where(:not([data-ui-variant])):not(.max-button-primary):not(.max-button-secondary):not(.max-button-danger):not(.max-button-warning):not(.max-button-ghost):not(.max-button-outline-heavy), .max-icon-button { background: var(--max-control-bg); }
456
458
  .max-button, .max-icon-button, .max-badge, .max-nav-link { font-family: var(--max-font-control); }
457
459
 
@@ -430,7 +430,10 @@
430
430
  font: inherit; font-weight: 700; line-height: 1; text-decoration: none; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; user-select: none;
431
431
  transition: color var(--saas-transition-fast), background var(--saas-transition-fast), border-color var(--saas-transition-fast), box-shadow var(--saas-transition-fast), transform var(--saas-transition-fast);
432
432
  }
433
- .saas-button:hover, .saas-icon-button:hover { transform: none; border-color: rgb(var(--saas-primary-rgb) / .48); background: var(--saas-surface-soft); }
433
+ /** Neutral hover paint must not replace a filled variant's paired background. */
434
+ .saas-button:hover, .saas-icon-button:hover { transform: none; border-color: rgb(var(--saas-primary-rgb) / .48); }
435
+ .saas-button:where(:not(.saas-button-primary):not(.saas-button-danger):not(.saas-button-warning)):hover,
436
+ .saas-icon-button:hover { background: var(--saas-surface-soft); color: var(--saas-text); }
434
437
  .saas-button:active, .saas-icon-button:active, .saas-button[aria-pressed="true"], .saas-icon-button[aria-pressed="true"], .saas-button.is-active, .saas-icon-button.is-active { transform: translateY(1px); box-shadow: inset 0 1px 2px rgb(var(--saas-text-rgb) / .12); }
435
438
  .saas-button-primary { background: linear-gradient(135deg, var(--saas-primary), var(--saas-brand-2)); color: var(--saas-on-primary); border-color: var(--saas-primary); }
436
439
  .saas-button-primary:hover { background: linear-gradient(135deg, var(--saas-brand-2), var(--saas-primary)); border-color: var(--saas-primary-hover); }
@@ -445,7 +448,8 @@
445
448
  .saas-card, .saas-panel { background: var(--saas-card-bg); }
446
449
  .saas-toolbar, .saas-table-wrap { background: var(--saas-control-bg); }
447
450
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
448
- .saas-button:where(:not([data-ui-variant])):not(.saas-button-primary):not(.saas-button-secondary):not(.saas-button-danger):not(.saas-button-warning):not(.saas-button-ghost), .saas-icon-button { background: var(--saas-control-bg); }
451
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
452
+ .saas-button:where(:not([data-ui-variant])):not(.saas-button-primary):not(.saas-button-secondary):not(.saas-button-danger):not(.saas-button-warning):not(.saas-button-ghost):not(.saas-button-outline-heavy), .saas-icon-button { background: var(--saas-control-bg); }
449
453
  .saas-button, .saas-icon-button, .saas-badge, .saas-nav-link { font-family: var(--saas-font-control); }
450
454
 
451
455
 
@@ -652,7 +656,7 @@
652
656
  .saas-button.saas-button-outline-heavy,
653
657
  .saas-button-outline-heavy {
654
658
  background: transparent;
655
- color: var(--usk-primary-ink, var(--saas-primary));
659
+ color: var(--usk-primary-ink, var(--saas-text));
656
660
  border-style: solid;
657
661
  border-width: 2px;
658
662
  border-color: var(--saas-primary);
@@ -856,3 +856,22 @@
856
856
  }
857
857
  }
858
858
  }
859
+
860
+ /** Native select affordances survive component background shorthands in the preset layer. */
861
+ @layer ui-style-kit.presets {
862
+ /** Keep functional chrome above native defaults while leaving component surface colors intact. */
863
+ [data-ui][data-mode] :where(select:not([multiple])) {
864
+ padding-inline-end: var(--usk-native-select-padding-inline-end);
865
+ background-image: var(--usk-native-select-indicator-image);
866
+ background-repeat: no-repeat;
867
+ background-position: var(--usk-native-select-indicator-position);
868
+ background-size: var(--usk-native-select-indicator-size);
869
+ }
870
+ }
871
+
872
+ /** Preset density may tune other edges, but text must retain the native indicator gutter. */
873
+ @layer ui-style-kit.clean_defaults {
874
+ [data-ui][data-mode] :where(select:not([multiple])) {
875
+ padding-inline-end: var(--usk-native-select-padding-inline-end);
876
+ }
877
+ }
@@ -437,7 +437,8 @@
437
437
  /* Theme-responsive component defaults */
438
438
  .noir-card, .noir-panel { background: var(--noir-card-bg); }
439
439
  .noir-toolbar, .noir-table-wrap { background: var(--noir-control-bg); }
440
- .noir-button:where(:not(.noir-button-primary):not(.noir-button-secondary):not(.noir-button-danger):not(.noir-button-warning):not(.noir-button-ghost)), .noir-icon-button { background: var(--noir-control-bg); }
440
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
441
+ .noir-button:where(:not(.noir-button-primary):not(.noir-button-secondary):not(.noir-button-danger):not(.noir-button-warning):not(.noir-button-ghost):not(.noir-button-outline-heavy)), .noir-icon-button { background: var(--noir-control-bg); }
441
442
  .noir-button, .noir-icon-button, .noir-badge, .noir-nav-link { font-family: var(--noir-font-control); }
442
443
 
443
444
 
@@ -629,17 +630,20 @@
629
630
  .noir-button.noir-button-outline-heavy,
630
631
  .noir-button-outline-heavy {
631
632
  background: transparent;
632
- color: var(--usk-primary-ink, var(--noir-primary));
633
+ color: var(--usk-primary-ink, var(--noir-text));
633
634
  border-style: solid;
634
635
  border-width: 2px;
635
636
  border-color: var(--noir-primary);
636
637
  box-shadow: none;
637
638
  }
639
+ /** Outlined hover paints the skewed face together with its on-primary label. */
638
640
  .noir-button.noir-button-outline-heavy:hover,
639
641
  .noir-button-outline-heavy:hover {
640
- background: var(--noir-primary);
642
+ background: transparent;
641
643
  color: var(--noir-on-primary);
642
644
  border-color: var(--noir-primary-hover);
645
+ --noir-action-fill: var(--noir-primary);
646
+ --noir-action-line: var(--noir-primary-hover);
643
647
  }
644
648
 
645
649
  .noir-badge-seal {
@@ -1088,7 +1092,8 @@
1088
1092
  color: var(--noir-text); background: var(--noir-control-bg); border: 1px solid var(--noir-border);
1089
1093
  border-radius: 0; clip-path: none; box-shadow: none; font: 11px/1.4 var(--noir-font-mono);
1090
1094
  }
1091
- .noir-select { appearance: auto; background-image: none; padding-right: .5rem; }
1095
+ /** Preserve the preset's browser-owned arrow when shared semantic fallback chrome is present. */
1096
+ .noir-select, [data-ui="neo-noir"][data-mode] .noir-select { appearance: auto; background-image: none; padding-right: .5rem; }
1092
1097
  .noir-input:focus, .noir-textarea:focus, .noir-select:focus, .noir-field-row[data-noir-state="focus"] :is(input,textarea) { border-color: var(--noir-focus); box-shadow: none; outline: 2px solid var(--noir-focus); outline-offset: 1px; }
1093
1098
  .noir-input[aria-invalid="true"], .noir-textarea[aria-invalid="true"] { border-color: var(--noir-danger); color: var(--noir-danger); box-shadow: none; }
1094
1099
  .noir-field-row[data-noir-state="success"] input { border-color: var(--noir-success); color: var(--noir-success); }
@@ -1300,7 +1305,10 @@
1300
1305
  [data-ui="neo-noir"][data-mode="contrast"] { --noir-grain: none; --noir-corner: none; --noir-border-alpha: 1; }
1301
1306
  /** Warning actions inherit preset geometry and use the paired semantic warning colors. */
1302
1307
  [data-ui="neo-noir"][data-mode] .noir-button.noir-button-warning {
1303
- background: var(--noir-warning);
1308
+ /** The skewed face owns the warning fill; a rectangular host fill sits behind it. */
1309
+ --noir-action-fill: var(--noir-warning);
1310
+ --noir-action-line: var(--noir-warning);
1311
+ background: transparent;
1304
1312
  color: var(--noir-on-warning);
1305
1313
  border-color: var(--noir-warning);
1306
1314
  text-shadow: none;
@@ -442,7 +442,8 @@
442
442
  .neo-card, .neo-panel { background: var(--neo-card-bg); }
443
443
  .neo-toolbar, .neo-table-wrap { background: var(--neo-control-bg); }
444
444
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
445
- .neo-button:where(:not([data-ui-variant])):not(.neo-button-primary):not(.neo-button-secondary):not(.neo-button-danger):not(.neo-button-warning):not(.neo-button-ghost), .neo-icon-button { background: var(--neo-control-bg); }
445
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
446
+ .neo-button:where(:not([data-ui-variant])):not(.neo-button-primary):not(.neo-button-secondary):not(.neo-button-danger):not(.neo-button-warning):not(.neo-button-ghost):not(.neo-button-outline-heavy), .neo-icon-button { background: var(--neo-control-bg); }
446
447
  .neo-button, .neo-icon-button, .neo-badge, .neo-nav-link { font-family: var(--neo-font-control); }
447
448
 
448
449
 
@@ -520,7 +521,8 @@
520
521
  .neo-table { width: 100%; border-collapse: collapse; }
521
522
  .neo-table th, .neo-table td { padding: .95rem 1rem; text-align: left; border-bottom: 1px solid var(--neo-border); }
522
523
  .neo-table th { color: var(--neo-text); font-size: .82rem; font-weight: 900; text-transform: uppercase; letter-spacing: .08em; background: rgb(var(--neo-primary-rgb) / .08); }
523
- .neo-table td { color: var(--neo-text-muted); }
524
+ /** Table values use surface text because the inset material can reduce muted-ink contrast. */
525
+ .neo-table td { color: var(--neo-text); }
524
526
  .neo-table tr:hover td { background: rgb(var(--neo-primary-rgb) / .045); }
525
527
 
526
528
  /* =========================================================
@@ -801,7 +803,8 @@
801
803
  .neo-button-primary,
802
804
  .neo-button-secondary,
803
805
  .neo-button-danger {
804
- background-image: linear-gradient(155deg, rgb(255 255 255 / .28), transparent 52%, rgb(0 0 0 / .08));
806
+ /** Keep the molded highlight at the edges, outside the central label lane. */
807
+ background-image: linear-gradient(155deg, rgb(255 255 255 / .28), transparent 20%, transparent 80%, rgb(0 0 0 / .08));
805
808
  }
806
809
 
807
810
  .neo-button-primary {
@@ -842,8 +845,10 @@
842
845
  box-shadow: inset .28rem .28rem .58rem rgb(0 0 0 / .34), inset -.22rem -.22rem .5rem rgb(255 255 255 / .22);
843
846
  }
844
847
 
848
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
849
+
845
850
  .neo-button-ghost,
846
- .neo-button:where(:not([data-ui-variant])):not(.neo-button-primary):not(.neo-button-secondary):not(.neo-button-danger):not(.neo-button-warning):not(.neo-button-ghost),
851
+ .neo-button:where(:not([data-ui-variant])):not(.neo-button-primary):not(.neo-button-secondary):not(.neo-button-danger):not(.neo-button-warning):not(.neo-button-ghost):not(.neo-button-outline-heavy),
847
852
  .neo-icon-button {
848
853
  background-color: var(--neo-material-raised);
849
854
  background-image: linear-gradient(145deg, var(--neo-material-top-light), transparent 52%);
@@ -863,7 +868,7 @@
863
868
  .neo-button-outline-heavy {
864
869
  background-color: var(--neo-material-raised);
865
870
  background-image: linear-gradient(145deg, var(--neo-material-top-light), transparent 52%);
866
- color: var(--usk-primary-ink, var(--neo-primary));
871
+ color: var(--usk-primary-ink, var(--neo-text));
867
872
  border: 1px solid var(--neo-material-edge);
868
873
  border-radius: var(--neo-radius-md);
869
874
  box-shadow: var(--neo-button-shadow);
@@ -630,7 +630,7 @@
630
630
  .organic-button.organic-button-outline-heavy,
631
631
  .organic-button-outline-heavy {
632
632
  background: transparent;
633
- color: var(--usk-primary-ink, var(--organic-primary));
633
+ color: var(--usk-primary-ink, var(--organic-text));
634
634
  border-style: solid;
635
635
  border-width: 2px;
636
636
  border-color: var(--organic-primary);
@@ -438,7 +438,8 @@
438
438
  .paper-card, .paper-panel { background: var(--paper-card-bg); }
439
439
  .paper-toolbar, .paper-table-wrap { background: var(--paper-control-bg); }
440
440
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
441
- .paper-button:where(:not([data-ui-variant])):not(.paper-button-primary):not(.paper-button-secondary):not(.paper-button-danger):not(.paper-button-warning):not(.paper-button-ghost), .paper-icon-button { background: var(--paper-control-bg); }
441
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
442
+ .paper-button:where(:not([data-ui-variant])):not(.paper-button-primary):not(.paper-button-secondary):not(.paper-button-danger):not(.paper-button-warning):not(.paper-button-ghost):not(.paper-button-outline-heavy), .paper-icon-button { background: var(--paper-control-bg); }
442
443
  .paper-button, .paper-icon-button, .paper-badge, .paper-nav-link { font-family: var(--paper-font-control); }
443
444
 
444
445
 
@@ -630,7 +631,7 @@
630
631
  .paper-button.paper-button-outline-heavy,
631
632
  .paper-button-outline-heavy {
632
633
  background: transparent;
633
- color: var(--usk-primary-ink, var(--paper-primary));
634
+ color: var(--usk-primary-ink, var(--paper-text));
634
635
  border-style: solid;
635
636
  border-width: 2px;
636
637
  border-color: var(--paper-primary);
@@ -942,7 +943,8 @@
942
943
  @media print {
943
944
  [data-ui="paper-editorial"] { background: #fff !important; color: #000 !important; }
944
945
  [data-ui="paper-editorial"] * { box-shadow: none !important; text-shadow: none !important; }
945
- [data-ui="paper-editorial"] a { color: #000 !important; text-decoration: underline; }
946
+ /** Inline-link ink must not override the foreground paired with an action surface. */
947
+ [data-ui="paper-editorial"] a { color: #000 !important; text-decoration: underline; }
946
948
  }
947
949
  }
948
950
 
@@ -1070,13 +1072,13 @@
1070
1072
 
1071
1073
  :where([data-ui="paper-editorial"]) :where(button,input,select,textarea) { font: inherit; }
1072
1074
 
1073
- [data-ui="paper-editorial"] a {
1075
+ [data-ui="paper-editorial"] a:where(:not(.paper-button):not(.paper-icon-button):not(.paper-nav-link)) {
1074
1076
  color: var(--paper-sheet-blue);
1075
1077
  text-decoration-thickness: 1px;
1076
1078
  text-underline-offset: 3px;
1077
1079
  }
1078
1080
 
1079
- [data-ui="paper-editorial"] a:hover { color: var(--paper-sheet-oxblood); }
1081
+ [data-ui="paper-editorial"] a:where(:not(.paper-button):not(.paper-icon-button):not(.paper-nav-link)):hover { color: var(--paper-sheet-oxblood); }
1080
1082
 
1081
1083
  .paper-kicker,
1082
1084
  .paper-label,
@@ -485,7 +485,8 @@
485
485
  .rg-card, .rg-panel { background: var(--rg-card-bg); }
486
486
  .rg-toolbar, .rg-table-wrap { background: var(--rg-control-bg); }
487
487
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
488
- .rg-button:where(:not([data-ui-variant])):not(.rg-button-primary):not(.rg-button-secondary):not(.rg-button-danger):not(.rg-button-warning):not(.rg-button-ghost), .rg-icon-button { background: var(--rg-control-bg); }
488
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
489
+ .rg-button:where(:not([data-ui-variant])):not(.rg-button-primary):not(.rg-button-secondary):not(.rg-button-danger):not(.rg-button-warning):not(.rg-button-ghost):not(.rg-button-outline-heavy), .rg-icon-button { background: var(--rg-control-bg); }
489
490
  .rg-button, .rg-icon-button, .rg-badge, .rg-nav-link { font-family: var(--rg-font-control); }
490
491
 
491
492
  /** All loader APIs share a complete circular track with one rotating accent. */
@@ -607,7 +608,7 @@
607
608
  .rg-button.rg-button-outline-heavy,
608
609
  .rg-button-outline-heavy {
609
610
  background: transparent;
610
- color: var(--usk-primary-ink, var(--rg-primary));
611
+ color: var(--usk-primary-ink, var(--rg-text));
611
612
  border-style: solid;
612
613
  border-width: 2px;
613
614
  border-color: var(--rg-primary);
@@ -995,7 +996,9 @@
995
996
  .rg-icon-button { inline-size: var(--rg-control-height); padding: 8px; aspect-ratio: 1; }
996
997
  .rg-button-primary { background: var(--rg-gloss); color: var(--rg-gloss-ink); border-color: var(--rg-primary); }
997
998
  .rg-button-secondary { background: var(--rg-control-material); color: var(--rg-text); border-color: var(--rg-line-strong); }
998
- .rg-button-danger { background: var(--rg-danger-gloss); color: rgb(var(--usk-danger-text-rgb, 255 255 255)); border-color: var(--rg-danger); }
999
+ /** Danger gloss retains its semantic foreground pair and confines reflection to the upper edge. */
1000
+ .rg-button-danger { background: linear-gradient(180deg, rgb(255 255 255 / .4), transparent 12%), var(--rg-danger); color: var(--rg-on-danger); border-color: var(--rg-danger); }
1001
+ .rg-button-primary:hover { background: var(--rg-gloss); color: var(--rg-gloss-ink); }
999
1002
  /**
1000
1003
  * Lets explicit runtime foreground edits win without changing the default
1001
1004
  * Retro Glass danger gloss treatment used by the reference specimen.
@@ -1007,7 +1010,8 @@
1007
1010
  .rg-button:disabled, .rg-icon-button:disabled, .rg-button.is-disabled { opacity: .4; filter: saturate(.45); cursor: not-allowed; box-shadow: none; }
1008
1011
  .rg-field { display: block; min-inline-size: 0; }
1009
1012
  .rg-input, .rg-select, .rg-textarea { inline-size: 100%; min-block-size: var(--rg-control-height); padding: 8px 11px; background: var(--rg-glass-inset); color: var(--rg-text); border: 1px solid var(--rg-line-strong); border-radius: var(--rg-radius-sm); box-shadow: inset 0 1px 3px var(--rg-recess), 0 1px 0 var(--rg-highlight); font: 14px/1.3 var(--rg-font-body); }
1010
- .rg-select { padding-inline-end: 32px; background-image: var(--usk-native-select-indicator-image), linear-gradient(180deg, rgb(0 0 0 / .12), transparent 18%); background-size: var(--usk-native-select-indicator-size), auto; background-position: var(--usk-native-select-indicator-position), center; background-repeat: no-repeat; }
1013
+ /** Native and semantic selects retain the same indicator above the recessed glass material. */
1014
+ .rg-select, [data-ui="retro-glass"][data-mode] :where(select:not([multiple])) { padding-inline-end: 32px; background-image: var(--usk-native-select-indicator-image), linear-gradient(180deg, rgb(0 0 0 / .12), transparent 18%); background-size: var(--usk-native-select-indicator-size), auto; background-position: var(--usk-native-select-indicator-position), center; background-repeat: no-repeat; }
1011
1015
  .rg-textarea { min-block-size: 64px; resize: vertical; }
1012
1016
  .rg-input::placeholder, .rg-textarea::placeholder { color: var(--rg-muted); opacity: 1; }
1013
1017
  .rg-input-wrap { display: flex; align-items: center; position: relative; }
@@ -1096,7 +1100,8 @@
1096
1100
  .rg-tab:hover, .rg-tab.is-active, .rg-tab[aria-selected="true"] { background: linear-gradient(rgb(var(--rg-primary-rgb) / .2), rgb(var(--rg-primary-rgb) / .2)), var(--rg-surface-input); border-bottom-color: var(--rg-primary); color: var(--rg-text); }
1097
1101
  .rg-pagination-page { min-inline-size: 36px; padding: 8px; font-size: 12px; }
1098
1102
  .rg-nav { padding: 0; background: transparent; border: 0; box-shadow: none; gap: 6px; }
1099
- .rg-nav-link { min-block-size: var(--rg-control-height); padding: 8px 12px; background: var(--rg-control-material); border: 1px solid var(--rg-line-strong); border-radius: var(--rg-radius-sm); color: var(--rg-text-soft); text-shadow: none; letter-spacing: 0; }
1103
+ /** Chrome reflections need full surface ink for ordinary navigation labels. */
1104
+ .rg-nav-link { min-block-size: var(--rg-control-height); padding: 8px 12px; background: var(--rg-control-material); border: 1px solid var(--rg-line-strong); border-radius: var(--rg-radius-sm); color: var(--rg-text); text-shadow: none; letter-spacing: 0; }
1100
1105
  .rg-nav-link:hover { color: var(--rg-text); background: var(--rg-control-material); }
1101
1106
  .rg-nav-link.is-active, .rg-nav-link[aria-current="page"] { background: var(--rg-gloss); color: var(--rg-gloss-ink); box-shadow: inset 0 1px 0 var(--rg-highlight); }
1102
1107
  .rg-table-wrap { background: transparent; border: 0; box-shadow: none; }
@@ -439,7 +439,8 @@
439
439
  .retro-card, .retro-panel { background: var(--retro-card-bg); }
440
440
  .retro-toolbar, .retro-table-wrap { background: var(--retro-control-bg); }
441
441
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
442
- .retro-button:where(:not([data-ui-variant])):not(.retro-button-primary):not(.retro-button-secondary):not(.retro-button-danger):not(.retro-button-warning):not(.retro-button-ghost), .retro-icon-button { background: var(--retro-control-bg); }
442
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
443
+ .retro-button:where(:not([data-ui-variant])):not(.retro-button-primary):not(.retro-button-secondary):not(.retro-button-danger):not(.retro-button-warning):not(.retro-button-ghost):not(.retro-button-outline-heavy), .retro-icon-button { background: var(--retro-control-bg); }
443
444
  .retro-button, .retro-icon-button, .retro-badge, .retro-nav-link { font-family: var(--retro-font-control); }
444
445
 
445
446
 
@@ -638,7 +639,7 @@
638
639
  .retro-button.retro-button-outline-heavy,
639
640
  .retro-button-outline-heavy {
640
641
  background: transparent;
641
- color: var(--usk-primary-ink, var(--retro-primary));
642
+ color: var(--usk-primary-ink, var(--retro-text));
642
643
  border-style: solid;
643
644
  border-width: 2px;
644
645
  border-color: var(--retro-primary);
@@ -1336,7 +1337,7 @@
1336
1337
 
1337
1338
  .retro-button.retro-button-outline-heavy, .retro-button-outline-heavy {
1338
1339
  background: var(--retro-enamel-bg);
1339
- color: var(--usk-primary-ink, var(--retro-primary));
1340
+ color: var(--usk-primary-ink, var(--retro-text));
1340
1341
  border: 4px double var(--retro-metal-edge);
1341
1342
  border-radius: var(--retro-radius-pill);
1342
1343
  clip-path: inset(0 round var(--retro-radius-pill));
@@ -468,7 +468,8 @@
468
468
  .tactile-card, .tactile-panel { background: var(--tactile-card-bg); }
469
469
  .tactile-toolbar, .tactile-table-wrap { background: var(--tactile-card-bg); }
470
470
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
471
- .tactile-button:where(:not([data-ui-variant])):not(.tactile-button-primary):not(.tactile-button-secondary):not(.tactile-button-danger):not(.tactile-button-warning):not(.tactile-button-ghost), .tactile-icon-button { background: var(--tactile-control-bg); }
471
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
472
+ .tactile-button:where(:not([data-ui-variant])):not(.tactile-button-primary):not(.tactile-button-secondary):not(.tactile-button-danger):not(.tactile-button-warning):not(.tactile-button-ghost):not(.tactile-button-outline-heavy), .tactile-icon-button { background: var(--tactile-control-bg); }
472
473
  .tactile-button, .tactile-icon-button, .tactile-badge, .tactile-nav-link { font-family: var(--tactile-font-control); }
473
474
 
474
475
 
@@ -664,7 +665,7 @@
664
665
  .tactile-button.tactile-button-outline-heavy,
665
666
  .tactile-button-outline-heavy {
666
667
  background: transparent;
667
- color: var(--usk-primary-ink, var(--tactile-primary));
668
+ color: var(--usk-primary-ink, var(--tactile-text));
668
669
  border-style: solid;
669
670
  border-width: 2px;
670
671
  border-color: var(--tactile-primary);
@@ -1552,7 +1553,8 @@
1552
1553
  /** Enhances supported browsers with the reference's light-to-dark enamel ramp. */
1553
1554
  @supports (color: color-mix(in srgb, black, white)) {
1554
1555
  .tactile-button-primary {
1555
- background: linear-gradient(180deg, color-mix(in srgb, var(--tactile-primary), white 16%), var(--tactile-primary) 48%, color-mix(in srgb, var(--tactile-primary), black 18%));
1556
+ /** Both enamel stops retain the same tested primary foreground pair. */
1557
+ background: linear-gradient(180deg, var(--tactile-primary-hover), var(--tactile-primary) 48%, var(--tactile-primary));
1556
1558
  border-color: color-mix(in srgb, var(--tactile-primary), black 34%);
1557
1559
  box-shadow: inset 0 1px 0 rgb(255 255 255 / .42), inset 0 -2px 0 rgb(0 0 0 / .25), 0 1px 2px rgb(var(--tactile-material-shadow-rgb) / .3);
1558
1560
  }
@@ -1705,7 +1707,8 @@
1705
1707
 
1706
1708
  .tactile-nav-link[aria-current="page"],
1707
1709
  .tactile-nav-link.is-active {
1708
- color: var(--tactile-brass);
1710
+ /** The copper rail carries selection; text retains the sidebar's paired foreground. */
1711
+ color: var(--tactile-sidebar-fg);
1709
1712
  background: rgb(var(--tactile-sidebar-text-rgb) / .06);
1710
1713
  border-color: rgb(var(--tactile-sidebar-text-rgb) / .18);
1711
1714
  box-shadow: inset .18rem 0 0 var(--tactile-copper), inset .08rem .08rem .18rem rgb(0 0 0 / .38);
@@ -556,7 +556,8 @@
556
556
  .blueprint-card, .blueprint-panel { background: var(--blueprint-card-bg); }
557
557
  .blueprint-toolbar, .blueprint-table-wrap { background: var(--blueprint-control-bg); }
558
558
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
559
- .blueprint-button:where(:not([data-ui-variant])):not(.blueprint-button-primary):not(.blueprint-button-secondary):not(.blueprint-button-danger):not(.blueprint-button-warning):not(.blueprint-button-ghost), .blueprint-icon-button { background: var(--blueprint-control-bg); }
559
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
560
+ .blueprint-button:where(:not([data-ui-variant])):not(.blueprint-button-primary):not(.blueprint-button-secondary):not(.blueprint-button-danger):not(.blueprint-button-warning):not(.blueprint-button-ghost):not(.blueprint-button-outline-heavy), .blueprint-icon-button { background: var(--blueprint-control-bg); }
560
561
  .blueprint-button, .blueprint-icon-button, .blueprint-badge, .blueprint-nav-link { font-family: var(--blueprint-font-control); }
561
562
 
562
563
 
@@ -748,7 +749,7 @@
748
749
  .blueprint-button.blueprint-button-outline-heavy,
749
750
  .blueprint-button-outline-heavy {
750
751
  background: transparent;
751
- color: var(--usk-primary-ink, var(--blueprint-primary));
752
+ color: var(--usk-primary-ink, var(--blueprint-text));
752
753
  border-style: solid;
753
754
  border-width: 2px;
754
755
  border-color: var(--blueprint-primary);
@@ -892,7 +893,8 @@
892
893
  .blueprint-surface, .blueprint-card, .blueprint-panel, .blueprint-toolbar, .blueprint-table-wrap { border-radius: 0; box-shadow: inset 0 0 0 1px rgb(var(--blueprint-primary-rgb) / .12); }
893
894
  .blueprint-card, .blueprint-panel, .blueprint-toolbar { background-image: linear-gradient(90deg, transparent calc(100% - .55rem), rgb(var(--blueprint-primary-rgb) / .3) calc(100% - .55rem), rgb(var(--blueprint-primary-rgb) / .3) calc(100% - .48rem), transparent calc(100% - .48rem)); }
894
895
  .blueprint-button, .blueprint-icon-button { border-radius: 0; box-shadow: none; font-family: var(--blueprint-font-control); text-transform: uppercase; letter-spacing: .06em; }
895
- .blueprint-button:where(:not([data-ui-variant])):not(.blueprint-button-primary):not(.blueprint-button-secondary):not(.blueprint-button-danger):not(.blueprint-button-warning) { background: transparent; }
896
+ /** Flat neutral paint yields to outlined CTA hover fills. */
897
+ .blueprint-button:where(:not([data-ui-variant])):not(.blueprint-button-primary):not(.blueprint-button-secondary):not(.blueprint-button-danger):not(.blueprint-button-warning):not(.blueprint-button-outline-heavy) { background: transparent; }
896
898
  .blueprint-nav { border-radius: 0; box-shadow: none; }
897
899
  .blueprint-nav-link { border-radius: 0; font-family: var(--blueprint-font-control); font-size: .75rem; text-transform: uppercase; }
898
900
  .blueprint-input, .blueprint-textarea, .blueprint-select, .blueprint-badge, .blueprint-alert, .blueprint-metric, .blueprint-well, .blueprint-inset { border-radius: 0; }
@@ -1103,7 +1105,7 @@
1103
1105
  --blueprint-fallback-border-rgb: 20 95 147;
1104
1106
  --blueprint-fallback-primary-rgb: 7 95 157;
1105
1107
  --blueprint-fallback-primary-hover-rgb: 6 76 124;
1106
- --blueprint-fallback-danger-rgb: 201 49 44;
1108
+ --blueprint-fallback-danger-rgb: 197 45 40;
1107
1109
  --blueprint-fallback-success-rgb: 24 111 64;
1108
1110
  --blueprint-fallback-warning-rgb: 132 76 0;
1109
1111
  --blueprint-fallback-warning-text-rgb: 255 255 255;
@@ -1171,6 +1173,8 @@
1171
1173
  }
1172
1174
  .blueprint-icon-button { inline-size: 36px; padding: 8px; aspect-ratio: 1; }
1173
1175
  .blueprint-button-primary { background: var(--blueprint-fill); color: var(--blueprint-fill-ink); border-color: var(--blueprint-primary); }
1176
+ /** The hover fill uses the primary role, so its label must use that role's foreground. */
1177
+ .blueprint-button-primary:hover { color: var(--blueprint-on-primary); }
1174
1178
  .blueprint-button-secondary { background: transparent; color: var(--blueprint-secondary); border-color: var(--blueprint-secondary); }
1175
1179
  .blueprint-button-ghost { border-style: dashed; color: var(--blueprint-text-soft); }
1176
1180
  .blueprint-button-danger { background: transparent; border-color: var(--blueprint-danger); color: var(--blueprint-danger); }
package/styles/y2k.css CHANGED
@@ -433,7 +433,8 @@
433
433
  }
434
434
  [data-ui="y2k"] *, [data-ui="y2k"] *::before, [data-ui="y2k"] *::after { box-sizing: border-box; }
435
435
  [data-ui="y2k"][data-mode] { background: var(--y2k-theme-bg); background-size: var(--y2k-theme-bg-size); }
436
- [data-ui="y2k"] a { color: var(--y2k-link); text-decoration-thickness: 0.11em; text-underline-offset: 0.18em; } [data-ui="y2k"] ::selection { background: var(--y2k-primary); color: var(--y2k-on-primary); }
436
+ /** Inline-link ink must not override the foreground paired with an action surface. */
437
+ [data-ui="y2k"] a:where(:not(.y2k-button):not(.y2k-icon-button)) { color: var(--y2k-link); text-decoration-thickness: 0.11em; text-underline-offset: 0.18em; } [data-ui="y2k"] ::selection { background: var(--y2k-primary); color: var(--y2k-on-primary); }
437
438
 
438
439
  .y2k-page { min-height: 100vh; padding: clamp(1rem, 4vw, 3rem); background-image: radial-gradient(rgb(var(--y2k-border-rgb) / var(--y2k-grid-alpha)) 1px, transparent 1px); background-size: 22px 22px; }
439
440
  .y2k-container { width: min(100% - 2rem, 1200px); margin-inline: auto; } .y2k-stack { display: flex; flex-direction: column; gap: var(--y2k-space-4); } .y2k-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--y2k-space-3); } .y2k-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: var(--y2k-space-5); } .y2k-section { padding: clamp(1.25rem, 4vw, 2.5rem); }
@@ -467,7 +468,8 @@
467
468
  .y2k-card, .y2k-panel { background: var(--y2k-card-bg); }
468
469
  .y2k-toolbar, .y2k-table-wrap { background: var(--y2k-control-bg); }
469
470
  /** Attribute-selected variants bypass the legacy neutral-only paint fallback. */
470
- .y2k-button:where(:not([data-ui-variant])):not(.y2k-button-primary):not(.y2k-button-secondary):not(.y2k-button-danger):not(.y2k-button-warning):not(.y2k-button-ghost), .y2k-icon-button { background: var(--y2k-control-bg); }
471
+ /** Neutral defaults exclude outlined actions so their hover fill and ink remain paired. */
472
+ .y2k-button:where(:not([data-ui-variant])):not(.y2k-button-primary):not(.y2k-button-secondary):not(.y2k-button-danger):not(.y2k-button-warning):not(.y2k-button-ghost):not(.y2k-button-outline-heavy), .y2k-icon-button { background: var(--y2k-control-bg); }
471
473
  .y2k-button, .y2k-icon-button, .y2k-badge, .y2k-nav-link { font-family: var(--y2k-font-control); }
472
474
 
473
475
  /* Spinner geometry follows the y2k preset's glossy plastic controls. */
@@ -568,7 +570,7 @@
568
570
  .y2k-button.y2k-button-outline-heavy,
569
571
  .y2k-button-outline-heavy {
570
572
  background: transparent;
571
- color: var(--usk-primary-ink, var(--y2k-primary));
573
+ color: var(--usk-primary-ink, var(--y2k-text));
572
574
  border-style: solid;
573
575
  border-width: 2px;
574
576
  border-color: var(--y2k-primary);
@@ -926,7 +928,7 @@
926
928
  font: 400 11px/1.2 Tahoma, Verdana, Arial, sans-serif;
927
929
  }
928
930
 
929
- [data-ui="y2k"] a {
931
+ [data-ui="y2k"] a:where(:not(.y2k-button):not(.y2k-icon-button)) {
930
932
  color: var(--y2k-link);
931
933
  text-decoration: underline;
932
934
  text-decoration-thickness: auto;
@@ -1098,10 +1100,11 @@
1098
1100
  padding: 0;
1099
1101
  }
1100
1102
 
1101
- .y2k-button:hover,
1103
+ /** Hovered neutral controls retain the foreground paired with their neutral surface. */
1104
+ .y2k-button:where(:not(.y2k-button-primary):not(.y2k-button-danger):not(.y2k-button-warning)):hover,
1102
1105
  .y2k-icon-button:hover {
1103
- background: var(--y2k-primary-hover);
1104
- color: var(--y2k-on-primary);
1106
+ background: var(--y2k-surface-soft);
1107
+ color: var(--y2k-text);
1105
1108
  transform: none;
1106
1109
  box-shadow: var(--y2k-bevel-raised);
1107
1110
  }
@@ -1118,11 +1121,17 @@
1118
1121
  }
1119
1122
 
1120
1123
  .y2k-button-primary {
1121
- background: linear-gradient(180deg, rgb(255 255 255 / .2), transparent 48%), var(--y2k-primary);
1124
+ /** Keep the raised bevel's reflection outside the label lane. */
1125
+ background: linear-gradient(180deg, rgb(255 255 255 / .2), transparent 20%), var(--y2k-primary);
1122
1126
  color: var(--y2k-on-primary);
1123
1127
  border-color: var(--y2k-border);
1124
1128
  }
1125
1129
 
1130
+ .y2k-button-primary:hover {
1131
+ background: var(--y2k-primary-hover);
1132
+ color: var(--y2k-on-primary);
1133
+ }
1134
+
1126
1135
  .y2k-button-secondary {
1127
1136
  background: var(--y2k-surface-soft);
1128
1137
  color: var(--y2k-text);
@@ -1131,8 +1140,9 @@
1131
1140
 
1132
1141
  .y2k-button-danger {
1133
1142
  background: var(--y2k-surface-soft);
1134
- color: var(--y2k-danger);
1135
- border-color: var(--y2k-border);
1143
+ /** The outline carries the danger signal while surface ink keeps its label readable. */
1144
+ color: var(--y2k-text);
1145
+ border-color: var(--y2k-danger);
1136
1146
  }
1137
1147
 
1138
1148
  /**
@@ -1157,12 +1167,16 @@
1157
1167
  .y2k-button.y2k-button-outline-heavy {
1158
1168
  min-inline-size: 0;
1159
1169
  min-block-size: 1.375rem;
1160
- background: var(--y2k-surface-soft);
1161
1170
  border: 1px outset var(--y2k-border);
1162
1171
  border-radius: 0;
1163
1172
  box-shadow: var(--y2k-bevel-raised);
1164
1173
  clip-path: none;
1165
1174
  }
1175
+ /** Compact CTA geometry preserves a primary action's filled paint and paired ink. */
1176
+ .y2k-button-cut:where(:not(.y2k-button-primary)),
1177
+ .y2k-button.y2k-button-cut:where(:not(.y2k-button-primary)),
1178
+ .y2k-button-outline-heavy,
1179
+ .y2k-button.y2k-button-outline-heavy { background: var(--y2k-surface-soft); }
1166
1180
 
1167
1181
  .y2k-field {
1168
1182
  gap: .125rem;
@@ -1380,6 +1394,11 @@
1380
1394
  text-align: center;
1381
1395
  }
1382
1396
 
1397
+ /** The two-line seal needs its own frame; compact icon dimensions clip its labels. */
1398
+ .y2k-badge-seal { inline-size: 4rem; min-inline-size: 4rem; block-size: 4rem; }
1399
+ /** Native inline spacing must not consume the compact seal's label tracks. */
1400
+ .y2k-badge-seal > strong, .y2k-badge-seal > small { margin: 0; padding: 0; white-space: nowrap; }
1401
+
1383
1402
  .y2k-feature-item > .y2k-icon-medallion,
1384
1403
  .y2k-callout-bar > .y2k-icon-medallion {
1385
1404
  min-inline-size: 2.75rem;