@helixui/library 3.2.0-next.76 → 3.2.0-next.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +390 -375
- package/dist/components/hx-button/hx-button.d.ts.map +1 -1
- package/dist/components/hx-button/hx-button.styles.d.ts.map +1 -1
- package/dist/components/hx-button/index.js +1 -1
- package/dist/components/hx-side-nav/hx-nav-item.d.ts +7 -5
- package/dist/components/hx-side-nav/hx-nav-item.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-nav-item.styles.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-side-nav.d.ts +5 -4
- package/dist/components/hx-side-nav/hx-side-nav.d.ts.map +1 -1
- package/dist/components/hx-side-nav/hx-side-nav.styles.d.ts.map +1 -1
- package/dist/components/hx-side-nav/index.js +1 -1
- package/dist/components/hx-text-input/hx-text-input.d.ts +5 -5
- package/dist/components/hx-text-input/hx-text-input.d.ts.map +1 -1
- package/dist/components/hx-text-input/index.js +1 -1
- package/dist/components/hx-toast/hx-toast.styles.d.ts.map +1 -1
- package/dist/components/hx-toast/index.js +1 -1
- package/dist/css/helix-all.css +95 -65
- package/dist/css/helix-core.css +56 -36
- package/dist/css/helix-feedback.css +18 -13
- package/dist/css/helix-forms.css +4 -4
- package/dist/css/helix-navigation.css +17 -12
- package/dist/css/helix-tokens.css +43 -0
- package/dist/css/hx-button.css +56 -36
- package/dist/css/hx-side-nav.css +17 -12
- package/dist/css/hx-text-input.css +4 -4
- package/dist/css/hx-toast.css +18 -13
- package/dist/css/index.css +1 -1
- package/dist/css/manifest.json +27 -16
- package/dist/index.js +4 -4
- package/dist/shared/{hx-button-modUSOpY.js → hx-button-kWxjKqo-.js} +79 -60
- package/dist/shared/hx-button-kWxjKqo-.js.map +1 -0
- package/dist/shared/{hx-nav-item-D8xHLVOs.js → hx-nav-item-CMyMv5Gv.js} +129 -88
- package/dist/shared/hx-nav-item-CMyMv5Gv.js.map +1 -0
- package/dist/shared/{hx-text-input-B-caO5fI.js → hx-text-input-ClrrmoE1.js} +20 -21
- package/dist/shared/hx-text-input-ClrrmoE1.js.map +1 -0
- package/dist/shared/{toast-factory-DvDRAh0l.js → toast-factory-CIiZDZGZ.js} +59 -54
- package/dist/shared/toast-factory-CIiZDZGZ.js.map +1 -0
- package/figma-inventory.json +80 -44
- package/package.json +2 -2
- package/dist/shared/hx-button-modUSOpY.js.map +0 -1
- package/dist/shared/hx-nav-item-D8xHLVOs.js.map +0 -1
- package/dist/shared/hx-text-input-B-caO5fI.js.map +0 -1
- package/dist/shared/toast-factory-DvDRAh0l.js.map +0 -1
package/dist/css/helix-core.css
CHANGED
|
@@ -395,10 +395,7 @@
|
|
|
395
395
|
|
|
396
396
|
.button:focus-visible {
|
|
397
397
|
outline: var(--hx-focus-ring-width, 2px) solid
|
|
398
|
-
var(
|
|
399
|
-
--hx-button-focus-ring-color,
|
|
400
|
-
var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))
|
|
401
|
-
);
|
|
398
|
+
var(--hx-button-focus-ring-color, var(--hx-focus-ring-color, #6ab1b1));
|
|
402
399
|
outline-offset: var(--hx-focus-ring-offset, 2px);
|
|
403
400
|
}
|
|
404
401
|
|
|
@@ -436,8 +433,11 @@
|
|
|
436
433
|
/* ─── Style Variants ─── */
|
|
437
434
|
|
|
438
435
|
.button--primary {
|
|
439
|
-
--hx-button-bg: var(--hx-color-primary-
|
|
440
|
-
|
|
436
|
+
--hx-button-bg: var(--hx-color-action-primary-bg, #429797);
|
|
437
|
+
/* Inline #0d1825 matches text.on-primary's resolved primitive (neutral-900);
|
|
438
|
+
cold-start without the semantic still paints AA-tuned dark-on-primary
|
|
439
|
+
rather than white-on-primary (3.43:1 fail). */
|
|
440
|
+
--hx-button-color: var(--hx-color-text-on-primary, #0d1825);
|
|
441
441
|
--hx-button-border-color: transparent;
|
|
442
442
|
}
|
|
443
443
|
|
|
@@ -445,12 +445,12 @@
|
|
|
445
445
|
--hx-button-bg: transparent;
|
|
446
446
|
/* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.
|
|
447
447
|
primary-600 (#0F7078) on white = 6.06:1 — AA pass. */
|
|
448
|
-
--hx-button-color: var(--hx-color-
|
|
449
|
-
--hx-button-border-color: var(--hx-color-
|
|
448
|
+
--hx-button-color: var(--hx-color-action-secondary-fg, #0f7078);
|
|
449
|
+
--hx-button-border-color: var(--hx-color-action-secondary-border, #0f7078);
|
|
450
450
|
}
|
|
451
451
|
|
|
452
452
|
.button--secondary:hover {
|
|
453
|
-
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-
|
|
453
|
+
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-secondary-bg-hover, #ebf8f8));
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
.button--tertiary {
|
|
@@ -464,30 +464,34 @@
|
|
|
464
464
|
}
|
|
465
465
|
|
|
466
466
|
.button--danger {
|
|
467
|
-
--hx-button-bg: var(--hx-color-
|
|
468
|
-
|
|
467
|
+
--hx-button-bg: var(--hx-color-action-danger-bg, #e5493e);
|
|
468
|
+
/* Inline #0d1825 matches text.on-error's resolved primitive (neutral-900);
|
|
469
|
+
cold-start without the semantic still paints AA-tuned dark-on-error
|
|
470
|
+
rather than white-on-error (3.92:1 fail). */
|
|
471
|
+
--hx-button-color: var(--hx-color-text-on-error, #0d1825);
|
|
469
472
|
--hx-button-border-color: transparent;
|
|
470
473
|
}
|
|
471
474
|
|
|
472
475
|
/* on-error tokens are tuned for error-500 (neutral-900 on #E5493E ≈ 4.59:1).
|
|
473
|
-
error-600 (#C92A2A) drops that to 2.25:1 — AA fail.
|
|
474
|
-
|
|
475
|
-
(commit 300e21ab0)
|
|
476
|
+
error-600 (#C92A2A) drops that to 2.25:1 — AA fail. text.on-error-strong
|
|
477
|
+
resolves to neutral-0 across modes (no dark flip) so the darker hover fill
|
|
478
|
+
stays legible. Mirrors hx-toast precedent (commit 300e21ab0); routed
|
|
479
|
+
through the semantic tier in 3.2.1 token-cascade remediation. */
|
|
476
480
|
.button--danger:hover {
|
|
477
|
-
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-
|
|
478
|
-
--hx-button-color: var(--hx-color-
|
|
481
|
+
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-hover, #c92a2a));
|
|
482
|
+
--hx-button-color: var(--hx-color-text-on-error-strong, #ffffff);
|
|
479
483
|
}
|
|
480
484
|
|
|
481
485
|
.button--ghost {
|
|
482
486
|
--hx-button-bg: transparent;
|
|
483
487
|
/* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.
|
|
484
488
|
primary-600 (#0F7078) on white = 6.06:1 — AA pass. */
|
|
485
|
-
--hx-button-color: var(--hx-color-
|
|
489
|
+
--hx-button-color: var(--hx-color-action-ghost-fg, #0f7078);
|
|
486
490
|
--hx-button-border-color: transparent;
|
|
487
491
|
}
|
|
488
492
|
|
|
489
493
|
.button--ghost:hover {
|
|
490
|
-
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-
|
|
494
|
+
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-ghost-bg-hover, #ebf8f8));
|
|
491
495
|
}
|
|
492
496
|
|
|
493
497
|
.button--outline {
|
|
@@ -501,12 +505,13 @@
|
|
|
501
505
|
}
|
|
502
506
|
|
|
503
507
|
/* on-primary token resolves to neutral-900 (#0D1825) — tuned for primary-500.
|
|
504
|
-
primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail.
|
|
505
|
-
neutral-0 for the darker hover fill.
|
|
506
|
-
(commit 300e21ab0)
|
|
508
|
+
primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail. text.on-primary-strong
|
|
509
|
+
resolves to neutral-0 across modes (no dark flip) for the darker hover fill.
|
|
510
|
+
Mirrors hx-toast precedent (commit 300e21ab0); routed through the semantic
|
|
511
|
+
tier in 3.2.1 token-cascade remediation. */
|
|
507
512
|
.button--primary:hover {
|
|
508
|
-
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-primary-
|
|
509
|
-
--hx-button-color: var(--hx-color-
|
|
513
|
+
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-hover, #0f7078));
|
|
514
|
+
--hx-button-color: var(--hx-color-text-on-primary-strong, #ffffff);
|
|
510
515
|
}
|
|
511
516
|
|
|
512
517
|
/* ─── Disabled ─── */
|
|
@@ -552,7 +557,7 @@
|
|
|
552
557
|
|
|
553
558
|
/* Override text color and filter-based hover/active for all variants */
|
|
554
559
|
:host([inverted]) .button {
|
|
555
|
-
color: var(--hx-button-inverted-color, var(--hx-color-
|
|
560
|
+
color: var(--hx-button-inverted-color, var(--hx-color-text-inverse, #ffffff));
|
|
556
561
|
filter: none;
|
|
557
562
|
}
|
|
558
563
|
|
|
@@ -565,37 +570,42 @@
|
|
|
565
570
|
}
|
|
566
571
|
|
|
567
572
|
:host([inverted]) .button:focus-visible {
|
|
573
|
+
/* WCAG 1.4.11: focus indicator needs ≥3:1 against adjacent colors.
|
|
574
|
+
border-on-dark-default (overlay-white-30) ≈ 2.7:1 on neutral-900 — fails.
|
|
575
|
+
border-on-dark-strong (overlay-white-70) ≈ 5:1 — passes. */
|
|
568
576
|
outline-color: var(
|
|
569
577
|
--hx-button-inverted-focus-ring-color,
|
|
570
|
-
var(--hx-
|
|
578
|
+
var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7))
|
|
571
579
|
);
|
|
572
580
|
}
|
|
573
581
|
|
|
574
582
|
/* Primary inverted — slight transparent white overlay on hover */
|
|
575
583
|
:host([inverted]) .button--primary:hover {
|
|
576
|
-
--hx-button-bg: var(--hx-color-primary-
|
|
584
|
+
--hx-button-bg: var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1);
|
|
577
585
|
}
|
|
578
586
|
|
|
579
|
-
/* Secondary inverted — white border and
|
|
587
|
+
/* Secondary inverted — white border and translucent hover fill */
|
|
580
588
|
:host([inverted]) .button--secondary {
|
|
581
|
-
--hx-button-border-color: var(--hx-
|
|
589
|
+
--hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
|
|
582
590
|
}
|
|
583
591
|
|
|
584
592
|
:host([inverted]) .button--secondary:hover {
|
|
585
|
-
--hx-button-bg: var(--hx-
|
|
593
|
+
--hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
|
|
586
594
|
}
|
|
587
595
|
|
|
588
|
-
/* Tertiary inverted
|
|
596
|
+
/* Tertiary inverted — resting at subtle (10%) lifts to default (30%) on hover
|
|
597
|
+
so the runtime hover delta is visually distinct, not collapsed onto a
|
|
598
|
+
single token. */
|
|
589
599
|
:host([inverted]) .button--tertiary {
|
|
590
|
-
--hx-button-bg: var(--hx-
|
|
600
|
+
--hx-button-bg: var(--hx-color-border-on-dark-subtle, rgba(255, 255, 255, 0.1));
|
|
591
601
|
--hx-button-border-color: transparent;
|
|
592
602
|
}
|
|
593
603
|
|
|
594
604
|
:host([inverted]) .button--tertiary:hover {
|
|
595
|
-
--hx-button-bg: var(--hx-
|
|
605
|
+
--hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
|
|
596
606
|
}
|
|
597
607
|
|
|
598
|
-
/* Ghost inverted — transparent base,
|
|
608
|
+
/* Ghost inverted — transparent base, translucent hover bg */
|
|
599
609
|
:host([inverted]) .button--ghost {
|
|
600
610
|
--hx-button-bg: transparent;
|
|
601
611
|
--hx-button-border-color: transparent;
|
|
@@ -604,17 +614,17 @@
|
|
|
604
614
|
:host([inverted]) .button--ghost:hover {
|
|
605
615
|
--hx-button-bg: var(
|
|
606
616
|
--hx-button-inverted-ghost-hover-bg,
|
|
607
|
-
var(--hx-
|
|
617
|
+
var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3))
|
|
608
618
|
);
|
|
609
619
|
}
|
|
610
620
|
|
|
611
621
|
/* Outline inverted — white border */
|
|
612
622
|
:host([inverted]) .button--outline {
|
|
613
|
-
--hx-button-border-color: var(--hx-
|
|
623
|
+
--hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
|
|
614
624
|
}
|
|
615
625
|
|
|
616
626
|
:host([inverted]) .button--outline:hover {
|
|
617
|
-
--hx-button-bg: var(--hx-
|
|
627
|
+
--hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
|
|
618
628
|
}
|
|
619
629
|
|
|
620
630
|
/* ─── Prefix / Suffix / Label ─── */
|
|
@@ -642,6 +652,16 @@
|
|
|
642
652
|
border: 2px solid ButtonText;
|
|
643
653
|
}
|
|
644
654
|
|
|
655
|
+
.button:hover {
|
|
656
|
+
/* Hover affordance must survive in HC. Highlight/HighlightText is the
|
|
657
|
+
OS-level "selected" pair, mirroring the forcedColorsInteractive mixin's
|
|
658
|
+
hover contract — kept inline since this component owns its bespoke HC
|
|
659
|
+
block (XOR rule). */
|
|
660
|
+
background-color: Highlight;
|
|
661
|
+
color: HighlightText;
|
|
662
|
+
border-color: Highlight;
|
|
663
|
+
}
|
|
664
|
+
|
|
645
665
|
.button:focus-visible {
|
|
646
666
|
outline: 3px solid Highlight;
|
|
647
667
|
outline-offset: 2px;
|
|
@@ -1233,33 +1233,38 @@
|
|
|
1233
1233
|
* error-600) because the lighter -500 fills can't pass AA against white
|
|
1234
1234
|
* text in the precision-cool palette. The neutral-900 on-{role} tokens
|
|
1235
1235
|
* are tuned for the lighter -500 surfaces and would fail here (e.g.
|
|
1236
|
-
* neutral-900 on primary-600 = 3.07:1), so
|
|
1237
|
-
*
|
|
1238
|
-
* -
|
|
1239
|
-
* -
|
|
1236
|
+
* neutral-900 on primary-600 = 3.07:1), so the on-{role}-strong tokens
|
|
1237
|
+
* (neutral-0, no dark-mode flip) keep fg legible on the darker fills.
|
|
1238
|
+
* - text.on-primary-strong on info.bg-strong (primary-600, #0F7078) = 5.39:1
|
|
1239
|
+
* - text.on-success-strong on success.bg-strong (success-700, #146831) = 6.88:1
|
|
1240
1240
|
* (success-600 #0E8A4A on white = 4.41:1 — drifts under AA at 14px)
|
|
1241
|
-
* -
|
|
1242
|
-
* -
|
|
1241
|
+
* - text.on-error-strong on danger.bg-strong (error-600, #C92A2A) = 5.92:1
|
|
1242
|
+
* - text.on-warning on warning.bg-strong (warning-500, #C2711C) = 4.83:1
|
|
1243
1243
|
* (warning stays on the lighter -500 surface so on-warning works)
|
|
1244
|
+
*
|
|
1245
|
+
* 3.2.1 token-cascade: bg variants now route through surface.{role}-strong
|
|
1246
|
+
* semantics; fg variants route through text.on-{role}-strong (or on-warning
|
|
1247
|
+
* for the warning variant). Component-tier tokens are NOT bypassed — the
|
|
1248
|
+
* --hx-toast-bg / --hx-toast-color slots remain the single override point.
|
|
1244
1249
|
*/
|
|
1245
1250
|
.toast--success {
|
|
1246
|
-
--hx-toast-bg: var(--hx-color-success-
|
|
1247
|
-
--hx-toast-color: var(--hx-color-
|
|
1251
|
+
--hx-toast-bg: var(--hx-color-surface-success-strong, #146831);
|
|
1252
|
+
--hx-toast-color: var(--hx-color-text-on-success-strong, #ffffff);
|
|
1248
1253
|
}
|
|
1249
1254
|
|
|
1250
1255
|
.toast--warning {
|
|
1251
|
-
--hx-toast-bg: var(--hx-color-warning-
|
|
1256
|
+
--hx-toast-bg: var(--hx-color-surface-warning-strong, #c2711c);
|
|
1252
1257
|
--hx-toast-color: var(--hx-color-text-on-warning, #0d1825);
|
|
1253
1258
|
}
|
|
1254
1259
|
|
|
1255
1260
|
.toast--danger {
|
|
1256
|
-
--hx-toast-bg: var(--hx-color-
|
|
1257
|
-
--hx-toast-color: var(--hx-color-
|
|
1261
|
+
--hx-toast-bg: var(--hx-color-surface-danger-strong, #c92a2a);
|
|
1262
|
+
--hx-toast-color: var(--hx-color-text-on-error-strong, #ffffff);
|
|
1258
1263
|
}
|
|
1259
1264
|
|
|
1260
1265
|
.toast--info {
|
|
1261
|
-
--hx-toast-bg: var(--hx-color-
|
|
1262
|
-
--hx-toast-color: var(--hx-color-
|
|
1266
|
+
--hx-toast-bg: var(--hx-color-surface-info-strong, #0f7078);
|
|
1267
|
+
--hx-toast-color: var(--hx-color-text-on-primary-strong, #ffffff);
|
|
1263
1268
|
}
|
|
1264
1269
|
|
|
1265
1270
|
/* ─── Severity Label (WCAG 1.4.1) ─── */
|
package/dist/css/helix-forms.css
CHANGED
|
@@ -3861,10 +3861,10 @@
|
|
|
3861
3861
|
|
|
3862
3862
|
/* ─── High Contrast Mode (forced-colors) ───
|
|
3863
3863
|
*
|
|
3864
|
-
*
|
|
3865
|
-
*
|
|
3866
|
-
*
|
|
3867
|
-
*
|
|
3864
|
+
* Bespoke block — sole owner of forced-colors deference for hx-text-input.
|
|
3865
|
+
* Covers wrapper/input/placeholder/focus/disabled/error/label/help-text;
|
|
3866
|
+
* strictly more than forcedColorsField. The mixin is intentionally NOT
|
|
3867
|
+
* composed (XOR rule — see styles/forced-colors.ts COMPOSITION RULES).
|
|
3868
3868
|
*/
|
|
3869
3869
|
|
|
3870
3870
|
@media (forced-colors: active) {
|
|
@@ -739,7 +739,7 @@
|
|
|
739
739
|
and evaluates their text against the page white background, producing
|
|
740
740
|
false-positive color-contrast violations (WCAG 2.1 AA). */
|
|
741
741
|
background-color: var(--hx-side-nav-bg, var(--hx-color-surface-inverse, #0d1825));
|
|
742
|
-
color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #
|
|
742
|
+
color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #ffffff));
|
|
743
743
|
}
|
|
744
744
|
|
|
745
745
|
* {
|
|
@@ -754,11 +754,11 @@
|
|
|
754
754
|
height: 100%;
|
|
755
755
|
width: var(--hx-side-nav-width, 16rem);
|
|
756
756
|
background-color: var(--hx-side-nav-bg, var(--hx-color-surface-inverse, #0d1825));
|
|
757
|
-
color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #
|
|
757
|
+
color: var(--hx-side-nav-color, var(--hx-color-text-inverse, #ffffff));
|
|
758
758
|
transition: width var(--hx-transition-normal, 300ms) ease;
|
|
759
759
|
overflow: hidden;
|
|
760
760
|
border-inline-end: var(--hx-border-width-thin, 1px) solid
|
|
761
|
-
var(--hx-side-nav-border-color, var(--hx-color-border-strong, #
|
|
761
|
+
var(--hx-side-nav-border-color, var(--hx-color-border-strong, #8e9c98));
|
|
762
762
|
}
|
|
763
763
|
|
|
764
764
|
/* ─── Collapsed State ─── */
|
|
@@ -776,7 +776,7 @@
|
|
|
776
776
|
flex-shrink: 0;
|
|
777
777
|
min-height: var(--hx-space-14, 3.5rem);
|
|
778
778
|
border-bottom: var(--hx-border-width-thin, 1px) solid
|
|
779
|
-
var(--hx-side-nav-border-color, var(--hx-color-border-strong, #
|
|
779
|
+
var(--hx-side-nav-border-color, var(--hx-color-border-strong, #8e9c98));
|
|
780
780
|
overflow: hidden;
|
|
781
781
|
}
|
|
782
782
|
|
|
@@ -803,7 +803,7 @@
|
|
|
803
803
|
flex-shrink: 0;
|
|
804
804
|
min-height: var(--hx-space-14, 3.5rem);
|
|
805
805
|
border-top: var(--hx-border-width-thin, 1px) solid
|
|
806
|
-
var(--hx-side-nav-border-color, var(--hx-color-border-strong, #
|
|
806
|
+
var(--hx-side-nav-border-color, var(--hx-color-border-strong, #8e9c98));
|
|
807
807
|
overflow: hidden;
|
|
808
808
|
}
|
|
809
809
|
|
|
@@ -826,7 +826,7 @@
|
|
|
826
826
|
border: none;
|
|
827
827
|
border-radius: var(--hx-border-radius-sm, 0.25rem);
|
|
828
828
|
background: transparent;
|
|
829
|
-
color: var(--hx-side-nav-toggle-color, var(--hx-color-text-inverse, #
|
|
829
|
+
color: var(--hx-side-nav-toggle-color, var(--hx-color-text-inverse, #ffffff));
|
|
830
830
|
cursor: pointer;
|
|
831
831
|
transition:
|
|
832
832
|
background-color var(--hx-transition-fast, 150ms) ease,
|
|
@@ -835,10 +835,10 @@
|
|
|
835
835
|
|
|
836
836
|
.side-nav__toggle:hover {
|
|
837
837
|
background-color: var(
|
|
838
|
-
--hx-
|
|
838
|
+
--hx-color-border-on-dark-subtle,
|
|
839
839
|
rgba(255, 255, 255, 0.1)
|
|
840
840
|
); /* fallback for browsers without color-mix() */
|
|
841
|
-
color: var(--hx-color-text-inverse, #
|
|
841
|
+
color: var(--hx-side-nav-toggle-hover-color, var(--hx-color-text-inverse, #ffffff));
|
|
842
842
|
}
|
|
843
843
|
|
|
844
844
|
@supports (color: color-mix(in srgb, red 50%, blue)) {
|
|
@@ -849,10 +849,7 @@
|
|
|
849
849
|
|
|
850
850
|
.side-nav__toggle:focus-visible {
|
|
851
851
|
outline: var(--hx-focus-ring-width, 2px) solid
|
|
852
|
-
var(
|
|
853
|
-
--hx-side-nav-focus-ring-color,
|
|
854
|
-
var(--hx-focus-ring-color, var(--hx-color-primary-400, #6ab1b1))
|
|
855
|
-
);
|
|
852
|
+
var(--hx-side-nav-focus-ring-color, var(--hx-focus-ring-color, #6ab1b1));
|
|
856
853
|
outline-offset: var(--hx-focus-ring-offset, 2px);
|
|
857
854
|
}
|
|
858
855
|
|
|
@@ -898,10 +895,18 @@
|
|
|
898
895
|
}
|
|
899
896
|
|
|
900
897
|
.side-nav__toggle {
|
|
898
|
+
forced-color-adjust: none;
|
|
899
|
+
background-color: ButtonFace;
|
|
901
900
|
color: ButtonText;
|
|
902
901
|
border: 1px solid ButtonText;
|
|
903
902
|
}
|
|
904
903
|
|
|
904
|
+
.side-nav__toggle:hover {
|
|
905
|
+
background-color: Highlight;
|
|
906
|
+
color: HighlightText;
|
|
907
|
+
border-color: Highlight;
|
|
908
|
+
}
|
|
909
|
+
|
|
905
910
|
.side-nav__toggle:focus-visible {
|
|
906
911
|
outline: 3px solid Highlight;
|
|
907
912
|
outline-offset: 2px;
|
|
@@ -101,6 +101,9 @@
|
|
|
101
101
|
--hx-color-text-on-success: var(--hx-color-neutral-900);
|
|
102
102
|
--hx-color-text-on-warning: var(--hx-color-neutral-900);
|
|
103
103
|
--hx-color-text-on-info: var(--hx-color-neutral-900);
|
|
104
|
+
--hx-color-text-on-primary-strong: var(--hx-color-neutral-0);
|
|
105
|
+
--hx-color-text-on-success-strong: var(--hx-color-neutral-0);
|
|
106
|
+
--hx-color-text-on-error-strong: var(--hx-color-neutral-0);
|
|
104
107
|
--hx-color-text-link: var(--hx-color-primary-600);
|
|
105
108
|
--hx-color-text-link-hover: var(--hx-color-primary-700);
|
|
106
109
|
--hx-color-text-link-visited: var(--hx-color-secondary-600);
|
|
@@ -112,13 +115,32 @@
|
|
|
112
115
|
--hx-color-surface-sunken: var(--hx-color-neutral-100);
|
|
113
116
|
--hx-color-surface-inverse: var(--hx-color-neutral-900);
|
|
114
117
|
--hx-color-surface-overlay: rgba(0, 0, 0, 0.75);
|
|
118
|
+
--hx-color-surface-success-strong: var(--hx-color-success-700);
|
|
119
|
+
--hx-color-surface-warning-strong: var(--hx-color-warning-500);
|
|
120
|
+
--hx-color-surface-danger-strong: var(--hx-color-error-600);
|
|
121
|
+
--hx-color-surface-info-strong: var(--hx-color-primary-600);
|
|
115
122
|
--hx-color-border-default: var(--hx-color-neutral-200);
|
|
116
123
|
--hx-color-border-subtle: var(--hx-color-neutral-100);
|
|
117
124
|
--hx-color-border-strong: var(--hx-color-neutral-400);
|
|
118
125
|
--hx-color-border-focus: var(--hx-color-primary-500);
|
|
126
|
+
--hx-color-border-on-dark-strong: var(--hx-overlay-white-70);
|
|
127
|
+
--hx-color-border-on-dark-default: var(--hx-overlay-white-30);
|
|
128
|
+
--hx-color-border-on-dark-subtle: var(--hx-overlay-white-10);
|
|
119
129
|
--hx-color-focus-ring: var(--hx-color-primary-400);
|
|
120
130
|
--hx-color-selection-bg: var(--hx-color-primary-200);
|
|
121
131
|
--hx-color-selection-color: var(--hx-color-neutral-900);
|
|
132
|
+
--hx-color-action-primary-bg: var(--hx-color-primary-500);
|
|
133
|
+
--hx-color-action-primary-bg-hover: var(--hx-color-primary-600);
|
|
134
|
+
--hx-color-action-primary-bg-active: var(--hx-color-primary-700);
|
|
135
|
+
--hx-color-action-primary-bg-inverted-hover: var(--hx-color-primary-400);
|
|
136
|
+
--hx-color-action-secondary-fg: var(--hx-color-primary-600);
|
|
137
|
+
--hx-color-action-secondary-border: var(--hx-color-primary-600);
|
|
138
|
+
--hx-color-action-secondary-bg-hover: var(--hx-color-primary-50);
|
|
139
|
+
--hx-color-action-ghost-fg: var(--hx-color-primary-600);
|
|
140
|
+
--hx-color-action-ghost-bg-hover: var(--hx-color-primary-50);
|
|
141
|
+
--hx-color-action-danger-bg: var(--hx-color-error-500);
|
|
142
|
+
--hx-color-action-danger-bg-hover: var(--hx-color-error-600);
|
|
143
|
+
--hx-color-action-danger-bg-active: var(--hx-color-error-700);
|
|
122
144
|
--hx-body-bg: var(--hx-color-surface-default);
|
|
123
145
|
--hx-body-color: var(--hx-color-text-primary);
|
|
124
146
|
--hx-body-font-family: var(--hx-font-family-sans);
|
|
@@ -351,6 +373,11 @@
|
|
|
351
373
|
--hx-color-focus-ring: var(--hx-color-primary-400);
|
|
352
374
|
--hx-color-selection-bg: var(--hx-color-primary-800);
|
|
353
375
|
--hx-color-selection-color: var(--hx-color-neutral-100);
|
|
376
|
+
--hx-color-action-secondary-fg: var(--hx-color-primary-400);
|
|
377
|
+
--hx-color-action-secondary-border: var(--hx-color-primary-400);
|
|
378
|
+
--hx-color-action-secondary-bg-hover: var(--hx-color-primary-900);
|
|
379
|
+
--hx-color-action-ghost-fg: var(--hx-color-primary-400);
|
|
380
|
+
--hx-color-action-ghost-bg-hover: var(--hx-color-primary-900);
|
|
354
381
|
--hx-body-bg: var(--hx-color-surface-default);
|
|
355
382
|
--hx-body-color: var(--hx-color-text-primary);
|
|
356
383
|
--hx-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3);
|
|
@@ -387,6 +414,11 @@
|
|
|
387
414
|
--hx-color-focus-ring: var(--hx-color-primary-400);
|
|
388
415
|
--hx-color-selection-bg: var(--hx-color-primary-800);
|
|
389
416
|
--hx-color-selection-color: var(--hx-color-neutral-100);
|
|
417
|
+
--hx-color-action-secondary-fg: var(--hx-color-primary-400);
|
|
418
|
+
--hx-color-action-secondary-border: var(--hx-color-primary-400);
|
|
419
|
+
--hx-color-action-secondary-bg-hover: var(--hx-color-primary-900);
|
|
420
|
+
--hx-color-action-ghost-fg: var(--hx-color-primary-400);
|
|
421
|
+
--hx-color-action-ghost-bg-hover: var(--hx-color-primary-900);
|
|
390
422
|
--hx-body-bg: var(--hx-color-surface-default);
|
|
391
423
|
--hx-body-color: var(--hx-color-text-primary);
|
|
392
424
|
--hx-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3);
|
|
@@ -426,6 +458,9 @@
|
|
|
426
458
|
--hx-color-text-on-success: #000000;
|
|
427
459
|
--hx-color-text-on-warning: #000000;
|
|
428
460
|
--hx-color-text-on-info: #000000;
|
|
461
|
+
--hx-color-text-on-primary-strong: #000000;
|
|
462
|
+
--hx-color-text-on-error-strong: #000000;
|
|
463
|
+
--hx-color-text-on-success-strong: #000000;
|
|
429
464
|
--hx-color-text-link: #FFFF00;
|
|
430
465
|
--hx-color-text-link-hover: #FFFF99;
|
|
431
466
|
--hx-color-text-link-visited: #FF80FF;
|
|
@@ -435,13 +470,21 @@
|
|
|
435
470
|
--hx-color-surface-sunken: #000000;
|
|
436
471
|
--hx-color-surface-inverse: #FFFFFF;
|
|
437
472
|
--hx-color-surface-overlay: rgba(0, 0, 0, 0.95);
|
|
473
|
+
--hx-color-surface-success-strong: var(--hx-color-success-500);
|
|
474
|
+
--hx-color-surface-warning-strong: var(--hx-color-warning-500);
|
|
475
|
+
--hx-color-surface-danger-strong: var(--hx-color-error-500);
|
|
476
|
+
--hx-color-surface-info-strong: var(--hx-color-primary-500);
|
|
438
477
|
--hx-color-border-default: #FFFFFF;
|
|
439
478
|
--hx-color-border-subtle: #C0C0C0;
|
|
440
479
|
--hx-color-border-strong: #FFFFFF;
|
|
441
480
|
--hx-color-border-focus: #FFFF00;
|
|
481
|
+
--hx-color-border-on-dark-strong: #FFFFFF;
|
|
482
|
+
--hx-color-border-on-dark-default: #FFFFFF;
|
|
483
|
+
--hx-color-border-on-dark-subtle: #C0C0C0;
|
|
442
484
|
--hx-color-focus-ring: #FFFF00;
|
|
443
485
|
--hx-color-selection-bg: #1AEBFF;
|
|
444
486
|
--hx-color-selection-color: #000000;
|
|
487
|
+
--hx-color-action-danger-bg-active: var(--hx-color-error-500);
|
|
445
488
|
--hx-body-bg: #000000;
|
|
446
489
|
--hx-body-color: #FFFFFF;
|
|
447
490
|
--hx-focus-ring-color: #FFFF00;
|
package/dist/css/hx-button.css
CHANGED
|
@@ -46,10 +46,7 @@
|
|
|
46
46
|
|
|
47
47
|
.button:focus-visible {
|
|
48
48
|
outline: var(--hx-focus-ring-width, 2px) solid
|
|
49
|
-
var(
|
|
50
|
-
--hx-button-focus-ring-color,
|
|
51
|
-
var(--hx-focus-ring-color, var(--hx-color-primary-500, #429797))
|
|
52
|
-
);
|
|
49
|
+
var(--hx-button-focus-ring-color, var(--hx-focus-ring-color, #6ab1b1));
|
|
53
50
|
outline-offset: var(--hx-focus-ring-offset, 2px);
|
|
54
51
|
}
|
|
55
52
|
|
|
@@ -87,8 +84,11 @@
|
|
|
87
84
|
/* ─── Style Variants ─── */
|
|
88
85
|
|
|
89
86
|
.button--primary {
|
|
90
|
-
--hx-button-bg: var(--hx-color-primary-
|
|
91
|
-
|
|
87
|
+
--hx-button-bg: var(--hx-color-action-primary-bg, #429797);
|
|
88
|
+
/* Inline #0d1825 matches text.on-primary's resolved primitive (neutral-900);
|
|
89
|
+
cold-start without the semantic still paints AA-tuned dark-on-primary
|
|
90
|
+
rather than white-on-primary (3.43:1 fail). */
|
|
91
|
+
--hx-button-color: var(--hx-color-text-on-primary, #0d1825);
|
|
92
92
|
--hx-button-border-color: transparent;
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -96,12 +96,12 @@
|
|
|
96
96
|
--hx-button-bg: transparent;
|
|
97
97
|
/* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.
|
|
98
98
|
primary-600 (#0F7078) on white = 6.06:1 — AA pass. */
|
|
99
|
-
--hx-button-color: var(--hx-color-
|
|
100
|
-
--hx-button-border-color: var(--hx-color-
|
|
99
|
+
--hx-button-color: var(--hx-color-action-secondary-fg, #0f7078);
|
|
100
|
+
--hx-button-border-color: var(--hx-color-action-secondary-border, #0f7078);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
.button--secondary:hover {
|
|
104
|
-
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-
|
|
104
|
+
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-secondary-bg-hover, #ebf8f8));
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
.button--tertiary {
|
|
@@ -115,30 +115,34 @@
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
.button--danger {
|
|
118
|
-
--hx-button-bg: var(--hx-color-
|
|
119
|
-
|
|
118
|
+
--hx-button-bg: var(--hx-color-action-danger-bg, #e5493e);
|
|
119
|
+
/* Inline #0d1825 matches text.on-error's resolved primitive (neutral-900);
|
|
120
|
+
cold-start without the semantic still paints AA-tuned dark-on-error
|
|
121
|
+
rather than white-on-error (3.92:1 fail). */
|
|
122
|
+
--hx-button-color: var(--hx-color-text-on-error, #0d1825);
|
|
120
123
|
--hx-button-border-color: transparent;
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
/* on-error tokens are tuned for error-500 (neutral-900 on #E5493E ≈ 4.59:1).
|
|
124
|
-
error-600 (#C92A2A) drops that to 2.25:1 — AA fail.
|
|
125
|
-
|
|
126
|
-
(commit 300e21ab0)
|
|
127
|
+
error-600 (#C92A2A) drops that to 2.25:1 — AA fail. text.on-error-strong
|
|
128
|
+
resolves to neutral-0 across modes (no dark flip) so the darker hover fill
|
|
129
|
+
stays legible. Mirrors hx-toast precedent (commit 300e21ab0); routed
|
|
130
|
+
through the semantic tier in 3.2.1 token-cascade remediation. */
|
|
127
131
|
.button--danger:hover {
|
|
128
|
-
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-
|
|
129
|
-
--hx-button-color: var(--hx-color-
|
|
132
|
+
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-danger-bg-hover, #c92a2a));
|
|
133
|
+
--hx-button-color: var(--hx-color-text-on-error-strong, #ffffff);
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
.button--ghost {
|
|
133
137
|
--hx-button-bg: transparent;
|
|
134
138
|
/* primary-500 (#429797) text on white surface = 3.43:1 — fails AA.
|
|
135
139
|
primary-600 (#0F7078) on white = 6.06:1 — AA pass. */
|
|
136
|
-
--hx-button-color: var(--hx-color-
|
|
140
|
+
--hx-button-color: var(--hx-color-action-ghost-fg, #0f7078);
|
|
137
141
|
--hx-button-border-color: transparent;
|
|
138
142
|
}
|
|
139
143
|
|
|
140
144
|
.button--ghost:hover {
|
|
141
|
-
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-
|
|
145
|
+
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-ghost-bg-hover, #ebf8f8));
|
|
142
146
|
}
|
|
143
147
|
|
|
144
148
|
.button--outline {
|
|
@@ -152,12 +156,13 @@
|
|
|
152
156
|
}
|
|
153
157
|
|
|
154
158
|
/* on-primary token resolves to neutral-900 (#0D1825) — tuned for primary-500.
|
|
155
|
-
primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail.
|
|
156
|
-
neutral-0 for the darker hover fill.
|
|
157
|
-
(commit 300e21ab0)
|
|
159
|
+
primary-600 (#0F7078) drops the pair to 3.07:1 — AA fail. text.on-primary-strong
|
|
160
|
+
resolves to neutral-0 across modes (no dark flip) for the darker hover fill.
|
|
161
|
+
Mirrors hx-toast precedent (commit 300e21ab0); routed through the semantic
|
|
162
|
+
tier in 3.2.1 token-cascade remediation. */
|
|
158
163
|
.button--primary:hover {
|
|
159
|
-
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-primary-
|
|
160
|
-
--hx-button-color: var(--hx-color-
|
|
164
|
+
--hx-button-bg: var(--hx-button-hover-bg, var(--hx-color-action-primary-bg-hover, #0f7078));
|
|
165
|
+
--hx-button-color: var(--hx-color-text-on-primary-strong, #ffffff);
|
|
161
166
|
}
|
|
162
167
|
|
|
163
168
|
/* ─── Disabled ─── */
|
|
@@ -203,7 +208,7 @@
|
|
|
203
208
|
|
|
204
209
|
/* Override text color and filter-based hover/active for all variants */
|
|
205
210
|
:host([inverted]) .button {
|
|
206
|
-
color: var(--hx-button-inverted-color, var(--hx-color-
|
|
211
|
+
color: var(--hx-button-inverted-color, var(--hx-color-text-inverse, #ffffff));
|
|
207
212
|
filter: none;
|
|
208
213
|
}
|
|
209
214
|
|
|
@@ -216,37 +221,42 @@
|
|
|
216
221
|
}
|
|
217
222
|
|
|
218
223
|
:host([inverted]) .button:focus-visible {
|
|
224
|
+
/* WCAG 1.4.11: focus indicator needs ≥3:1 against adjacent colors.
|
|
225
|
+
border-on-dark-default (overlay-white-30) ≈ 2.7:1 on neutral-900 — fails.
|
|
226
|
+
border-on-dark-strong (overlay-white-70) ≈ 5:1 — passes. */
|
|
219
227
|
outline-color: var(
|
|
220
228
|
--hx-button-inverted-focus-ring-color,
|
|
221
|
-
var(--hx-
|
|
229
|
+
var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7))
|
|
222
230
|
);
|
|
223
231
|
}
|
|
224
232
|
|
|
225
233
|
/* Primary inverted — slight transparent white overlay on hover */
|
|
226
234
|
:host([inverted]) .button--primary:hover {
|
|
227
|
-
--hx-button-bg: var(--hx-color-primary-
|
|
235
|
+
--hx-button-bg: var(--hx-color-action-primary-bg-inverted-hover, #6ab1b1);
|
|
228
236
|
}
|
|
229
237
|
|
|
230
|
-
/* Secondary inverted — white border and
|
|
238
|
+
/* Secondary inverted — white border and translucent hover fill */
|
|
231
239
|
:host([inverted]) .button--secondary {
|
|
232
|
-
--hx-button-border-color: var(--hx-
|
|
240
|
+
--hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
|
|
233
241
|
}
|
|
234
242
|
|
|
235
243
|
:host([inverted]) .button--secondary:hover {
|
|
236
|
-
--hx-button-bg: var(--hx-
|
|
244
|
+
--hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
|
|
237
245
|
}
|
|
238
246
|
|
|
239
|
-
/* Tertiary inverted
|
|
247
|
+
/* Tertiary inverted — resting at subtle (10%) lifts to default (30%) on hover
|
|
248
|
+
so the runtime hover delta is visually distinct, not collapsed onto a
|
|
249
|
+
single token. */
|
|
240
250
|
:host([inverted]) .button--tertiary {
|
|
241
|
-
--hx-button-bg: var(--hx-
|
|
251
|
+
--hx-button-bg: var(--hx-color-border-on-dark-subtle, rgba(255, 255, 255, 0.1));
|
|
242
252
|
--hx-button-border-color: transparent;
|
|
243
253
|
}
|
|
244
254
|
|
|
245
255
|
:host([inverted]) .button--tertiary:hover {
|
|
246
|
-
--hx-button-bg: var(--hx-
|
|
256
|
+
--hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
|
|
247
257
|
}
|
|
248
258
|
|
|
249
|
-
/* Ghost inverted — transparent base,
|
|
259
|
+
/* Ghost inverted — transparent base, translucent hover bg */
|
|
250
260
|
:host([inverted]) .button--ghost {
|
|
251
261
|
--hx-button-bg: transparent;
|
|
252
262
|
--hx-button-border-color: transparent;
|
|
@@ -255,17 +265,17 @@
|
|
|
255
265
|
:host([inverted]) .button--ghost:hover {
|
|
256
266
|
--hx-button-bg: var(
|
|
257
267
|
--hx-button-inverted-ghost-hover-bg,
|
|
258
|
-
var(--hx-
|
|
268
|
+
var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3))
|
|
259
269
|
);
|
|
260
270
|
}
|
|
261
271
|
|
|
262
272
|
/* Outline inverted — white border */
|
|
263
273
|
:host([inverted]) .button--outline {
|
|
264
|
-
--hx-button-border-color: var(--hx-
|
|
274
|
+
--hx-button-border-color: var(--hx-color-border-on-dark-strong, rgba(255, 255, 255, 0.7));
|
|
265
275
|
}
|
|
266
276
|
|
|
267
277
|
:host([inverted]) .button--outline:hover {
|
|
268
|
-
--hx-button-bg: var(--hx-
|
|
278
|
+
--hx-button-bg: var(--hx-color-border-on-dark-default, rgba(255, 255, 255, 0.3));
|
|
269
279
|
}
|
|
270
280
|
|
|
271
281
|
/* ─── Prefix / Suffix / Label ─── */
|
|
@@ -293,6 +303,16 @@
|
|
|
293
303
|
border: 2px solid ButtonText;
|
|
294
304
|
}
|
|
295
305
|
|
|
306
|
+
.button:hover {
|
|
307
|
+
/* Hover affordance must survive in HC. Highlight/HighlightText is the
|
|
308
|
+
OS-level "selected" pair, mirroring the forcedColorsInteractive mixin's
|
|
309
|
+
hover contract — kept inline since this component owns its bespoke HC
|
|
310
|
+
block (XOR rule). */
|
|
311
|
+
background-color: Highlight;
|
|
312
|
+
color: HighlightText;
|
|
313
|
+
border-color: Highlight;
|
|
314
|
+
}
|
|
315
|
+
|
|
296
316
|
.button:focus-visible {
|
|
297
317
|
outline: 3px solid Highlight;
|
|
298
318
|
outline-offset: 2px;
|