@kwtv/components 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +35 -0
  2. package/package.json +2 -2
  3. package/src/astro/Accordion.astro +10 -6
  4. package/src/astro/AccordionItem.astro +47 -43
  5. package/src/astro/ActiveFilterTags.astro +29 -25
  6. package/src/astro/Alert.astro +46 -41
  7. package/src/astro/Badge.astro +80 -76
  8. package/src/astro/Band.astro +104 -58
  9. package/src/astro/Breadcrumb.astro +33 -29
  10. package/src/astro/Button.astro +132 -128
  11. package/src/astro/Card.astro +64 -60
  12. package/src/astro/CartLine.astro +59 -55
  13. package/src/astro/Checkbox.astro +37 -32
  14. package/src/astro/Chip.astro +68 -64
  15. package/src/astro/DotGrid.astro +50 -46
  16. package/src/astro/EmptyState.astro +26 -22
  17. package/src/astro/FilterGroup.astro +29 -25
  18. package/src/astro/Filters.astro +50 -46
  19. package/src/astro/Footer.astro +179 -175
  20. package/src/astro/FooterColumn.astro +39 -35
  21. package/src/astro/Header.astro +67 -63
  22. package/src/astro/Icon.astro +1 -1
  23. package/src/astro/IconButton.astro +64 -60
  24. package/src/astro/Marquee.astro +33 -29
  25. package/src/astro/NavDropdown.astro +120 -116
  26. package/src/astro/NavLink.astro +59 -55
  27. package/src/astro/Newsletter.astro +58 -54
  28. package/src/astro/Pager.astro +43 -39
  29. package/src/astro/PickCard.astro +72 -68
  30. package/src/astro/ProductCard.astro +120 -116
  31. package/src/astro/Radio.astro +36 -32
  32. package/src/astro/Skeleton.astro +43 -39
  33. package/src/astro/Social.astro +26 -22
  34. package/src/astro/StepIndicator.astro +55 -51
  35. package/src/astro/Sticker.astro +50 -46
  36. package/src/astro/Swatch.astro +44 -40
  37. package/src/astro/Table.astro +58 -54
  38. package/src/astro/TableCard.astro +39 -35
  39. package/src/astro/TextField.astro +92 -88
  40. package/src/astro/Totals.astro +39 -35
  41. package/src/react/Drawer.css +60 -56
  42. package/src/react/Modal.css +97 -93
  43. package/src/react/NewsCarousel.css +108 -104
  44. package/src/react/QuantityStepper.css +84 -80
  45. package/src/react/Select.css +159 -155
  46. package/src/react/Toast.css +128 -124
  47. package/src/styles/base.css +30 -26
  48. package/src/styles/controls.css +183 -179
  49. package/src/styles/motion.css +203 -199
@@ -50,72 +50,76 @@ const hasFooter = Astro.slots.has("footer");
50
50
  </div>
51
51
 
52
52
  <style>
53
- .ui-card {
54
- display: flex;
55
- flex-direction: column;
56
- gap: var(--space-2);
57
- padding: var(--space-5);
58
- border: 1px solid var(--border);
59
- border-radius: var(--radius-lg);
60
- background: var(--surface);
61
- color: var(--text);
62
- }
53
+ @layer reset, tokens, base, components, motion, utilities;
63
54
 
64
- .ui-card__eyebrow {
65
- font-family: var(--font-mono);
66
- font-size: var(--text-2xs);
67
- line-height: var(--leading-2xs);
68
- font-weight: var(--weight-medium);
69
- letter-spacing: var(--tracking-widest);
70
- text-transform: uppercase;
71
- color: var(--text-muted);
72
- }
55
+ @layer components {
56
+ .ui-card {
57
+ display: flex;
58
+ flex-direction: column;
59
+ gap: var(--space-2);
60
+ padding: var(--space-5);
61
+ border: 1px solid var(--border);
62
+ border-radius: var(--radius-lg);
63
+ background: var(--surface);
64
+ color: var(--text);
65
+ }
73
66
 
74
- .ui-card__title {
75
- margin: 0;
76
- font-size: var(--text-lg);
77
- line-height: var(--leading-lg);
78
- font-weight: var(--weight-semibold);
79
- letter-spacing: var(--tracking-tight);
80
- color: var(--text);
81
- }
67
+ .ui-card__eyebrow {
68
+ font-family: var(--font-mono);
69
+ font-size: var(--text-2xs);
70
+ line-height: var(--leading-2xs);
71
+ font-weight: var(--weight-medium);
72
+ letter-spacing: var(--tracking-widest);
73
+ text-transform: uppercase;
74
+ color: var(--text-muted);
75
+ }
82
76
 
83
- .ui-card__body {
84
- font-size: var(--text-sm);
85
- line-height: var(--leading-sm);
86
- color: var(--text-muted);
87
- }
77
+ .ui-card__title {
78
+ margin: 0;
79
+ font-size: var(--text-lg);
80
+ line-height: var(--leading-lg);
81
+ font-weight: var(--weight-semibold);
82
+ letter-spacing: var(--tracking-tight);
83
+ color: var(--text);
84
+ }
88
85
 
89
- .ui-card__footer {
90
- display: flex;
91
- flex-wrap: wrap;
92
- gap: var(--space-2);
93
- margin-top: var(--space-2);
94
- }
86
+ .ui-card__body {
87
+ font-size: var(--text-sm);
88
+ line-height: var(--leading-sm);
89
+ color: var(--text-muted);
90
+ }
95
91
 
96
- /* Raised: cart summary, order total. */
97
- .ui-card--raised {
98
- border-color: transparent;
99
- box-shadow: var(--shadow-lg);
100
- }
92
+ .ui-card__footer {
93
+ display: flex;
94
+ flex-wrap: wrap;
95
+ gap: var(--space-2);
96
+ margin-top: var(--space-2);
97
+ }
101
98
 
102
- /* Accent: sage surface, ink-dark text kept at 4.5:1. Buttons inside keep
103
- their own foreground colour. */
104
- .ui-card--accent {
105
- background: var(--surface-accent);
106
- border-color: var(--border-strong);
107
- color: var(--surface-accent-fg);
108
- }
109
- .ui-card--accent .ui-card__eyebrow,
110
- .ui-card--accent .ui-card__title,
111
- .ui-card--accent .ui-card__body {
112
- color: var(--surface-accent-fg);
113
- }
99
+ /* Raised: cart summary, order total. */
100
+ .ui-card--raised {
101
+ border-color: transparent;
102
+ box-shadow: var(--shadow-lg);
103
+ }
104
+
105
+ /* Accent: sage surface, ink-dark text kept at 4.5:1. Buttons inside keep */
106
+ /* their own foreground colour. */
107
+ .ui-card--accent {
108
+ background: var(--surface-accent);
109
+ border-color: var(--border-strong);
110
+ color: var(--surface-accent-fg);
111
+ }
112
+ .ui-card--accent .ui-card__eyebrow,
113
+ .ui-card--accent .ui-card__title,
114
+ .ui-card--accent .ui-card__body {
115
+ color: var(--surface-accent-fg);
116
+ }
114
117
 
115
- /* Flat: no fill, grouping only. */
116
- .ui-card--flat {
117
- background: transparent;
118
- border-color: transparent;
119
- padding-inline: 0;
118
+ /* Flat: no fill, grouping only. */
119
+ .ui-card--flat {
120
+ background: transparent;
121
+ border-color: transparent;
122
+ padding-inline: 0;
123
+ }
120
124
  }
121
125
  </style>
@@ -56,67 +56,71 @@ const classes = ["ui-line", className].filter(Boolean).join(" ");
56
56
  </div>
57
57
 
58
58
  <style>
59
- .ui-line {
60
- display: flex;
61
- align-items: flex-start;
62
- gap: var(--space-4);
63
- padding-block: var(--space-4-5);
64
- border-top: 1px solid var(--border);
65
- }
59
+ @layer reset, tokens, base, components, motion, utilities;
66
60
 
67
- .ui-line__thumb {
68
- flex-shrink: 0;
69
- width: 72px;
70
- height: 72px;
71
- object-fit: cover;
72
- border-radius: var(--radius-md);
73
- border: 1px solid var(--border);
74
- }
61
+ @layer components {
62
+ .ui-line {
63
+ display: flex;
64
+ align-items: flex-start;
65
+ gap: var(--space-4);
66
+ padding-block: var(--space-4-5);
67
+ border-top: 1px solid var(--border);
68
+ }
75
69
 
76
- .ui-line__grow {
77
- display: flex;
78
- flex-direction: column;
79
- gap: var(--space-1);
80
- flex: 1 1 auto;
81
- min-width: 0;
82
- }
70
+ .ui-line__thumb {
71
+ flex-shrink: 0;
72
+ width: 72px;
73
+ height: 72px;
74
+ object-fit: cover;
75
+ border-radius: var(--radius-md);
76
+ border: 1px solid var(--border);
77
+ }
83
78
 
84
- .ui-line__title {
85
- font-family: var(--font-sans);
86
- font-size: var(--text-base);
87
- font-weight: var(--weight-semibold);
88
- color: var(--text);
89
- }
79
+ .ui-line__grow {
80
+ display: flex;
81
+ flex-direction: column;
82
+ gap: var(--space-1);
83
+ flex: 1 1 auto;
84
+ min-width: 0;
85
+ }
90
86
 
91
- .ui-line__note {
92
- font-size: var(--text-sm);
93
- color: var(--text-muted);
94
- }
87
+ .ui-line__title {
88
+ font-family: var(--font-sans);
89
+ font-size: var(--text-base);
90
+ font-weight: var(--weight-semibold);
91
+ color: var(--text);
92
+ }
95
93
 
96
- .ui-line__remove {
97
- align-self: flex-start;
98
- font-size: var(--text-xs);
99
- color: var(--link);
100
- }
101
- .ui-line__remove:hover {
102
- color: var(--link-hover);
103
- }
104
- .ui-line__remove:focus-visible {
105
- outline: 2px solid var(--focus);
106
- outline-offset: 2px;
107
- box-shadow: 0 0 0 4px var(--focus-outer);
108
- border-radius: var(--radius-sm);
109
- }
94
+ .ui-line__note {
95
+ font-size: var(--text-sm);
96
+ color: var(--text-muted);
97
+ }
110
98
 
111
- .ui-line__qty {
112
- flex-shrink: 0;
113
- }
99
+ .ui-line__remove {
100
+ align-self: flex-start;
101
+ font-size: var(--text-xs);
102
+ color: var(--link);
103
+ }
104
+ .ui-line__remove:hover {
105
+ color: var(--link-hover);
106
+ }
107
+ .ui-line__remove:focus-visible {
108
+ outline: 2px solid var(--focus);
109
+ outline-offset: 2px;
110
+ box-shadow: 0 0 0 4px var(--focus-outer);
111
+ border-radius: var(--radius-sm);
112
+ }
113
+
114
+ .ui-line__qty {
115
+ flex-shrink: 0;
116
+ }
114
117
 
115
- .ui-line__price {
116
- flex-shrink: 0;
117
- font-size: var(--text-base);
118
- font-weight: var(--weight-semibold);
119
- font-variant-numeric: tabular-nums;
120
- color: var(--text);
118
+ .ui-line__price {
119
+ flex-shrink: 0;
120
+ font-size: var(--text-base);
121
+ font-weight: var(--weight-semibold);
122
+ font-variant-numeric: tabular-nums;
123
+ color: var(--text);
124
+ }
121
125
  }
122
126
  </style>
@@ -47,43 +47,48 @@ const classes = ["ui-check", disabled && "is-disabled", className]
47
47
  </label>
48
48
 
49
49
  <style>
50
- .ui-check {
51
- display: flex;
52
- align-items: center;
53
- gap: var(--space-2);
54
- min-height: 32px;
55
- font-family: var(--font-sans);
56
- font-size: var(--text-sm);
57
- color: var(--text);
58
- cursor: pointer;
59
- }
50
+ @layer reset, tokens, base, components, motion, utilities;
60
51
 
61
- .ui-check input {
62
- width: 17px;
63
- height: 17px;
64
- flex-shrink: 0;
65
- accent-color: var(--primary);
66
- cursor: pointer;
67
- }
52
+ @layer components {
53
+ .ui-check {
54
+ display: flex;
55
+ align-items: flex-start;
56
+ gap: var(--space-2);
57
+ min-height: 32px;
58
+ font-family: var(--font-sans);
59
+ font-size: var(--text-sm);
60
+ color: var(--text);
61
+ cursor: pointer;
62
+ }
68
63
 
69
- .ui-check input:focus-visible {
70
- outline: 2px solid var(--focus);
71
- outline-offset: 2px;
72
- box-shadow: 0 0 0 4px var(--focus-outer);
73
- }
64
+ .ui-check input {
65
+ width: 17px;
66
+ height: 17px;
67
+ flex-shrink: 0;
68
+ margin-top: calc((var(--leading-sm, 1.375rem) - 17px) / 2);
69
+ accent-color: var(--primary);
70
+ cursor: pointer;
71
+ }
74
72
 
75
- .ui-check.is-disabled {
76
- cursor: not-allowed;
77
- color: var(--text-muted);
78
- }
73
+ .ui-check input:focus-visible {
74
+ outline: 2px solid var(--focus);
75
+ outline-offset: 2px;
76
+ box-shadow: 0 0 0 4px var(--focus-outer);
77
+ }
79
78
 
80
- .ui-check.is-disabled input {
81
- cursor: not-allowed;
82
- }
79
+ .ui-check.is-disabled {
80
+ cursor: not-allowed;
81
+ color: var(--text-muted);
82
+ }
83
83
 
84
- @media (max-width: 700px), (pointer: coarse) {
85
- .ui-check {
86
- min-height: 40px;
84
+ .ui-check.is-disabled input {
85
+ cursor: not-allowed;
86
+ }
87
+
88
+ @media (max-width: 700px), (pointer: coarse) {
89
+ .ui-check {
90
+ min-height: 40px;
91
+ }
87
92
  }
88
93
  }
89
94
  </style>
@@ -50,81 +50,85 @@ const classes = [
50
50
  </button>
51
51
 
52
52
  <style>
53
- .ui-chip {
54
- display: inline-flex;
55
- align-items: center;
56
- justify-content: center;
57
- min-height: 36px;
58
- padding: 0 var(--space-4);
59
- background: var(--surface);
60
- border: 1px solid var(--border);
61
- border-radius: var(--radius-md);
62
- font-family: var(--font-sans);
63
- font-size: var(--text-sm);
64
- font-weight: var(--weight-medium);
65
- color: var(--text);
66
- cursor: pointer;
67
- transition:
68
- border-color var(--duration-fast) var(--ease-standard),
69
- background-color var(--duration-fast) var(--ease-standard);
70
- }
53
+ @layer reset, tokens, base, components, motion, utilities;
71
54
 
72
- .ui-chip:hover,
73
- .ui-chip.is-hover {
74
- border-color: var(--border-strong);
75
- }
55
+ @layer components {
56
+ .ui-chip {
57
+ display: inline-flex;
58
+ align-items: center;
59
+ justify-content: center;
60
+ min-height: 36px;
61
+ padding: 0 var(--space-4);
62
+ background: var(--surface);
63
+ border: 1px solid var(--border);
64
+ border-radius: var(--radius-md);
65
+ font-family: var(--font-sans);
66
+ font-size: var(--text-sm);
67
+ font-weight: var(--weight-medium);
68
+ color: var(--text);
69
+ cursor: pointer;
70
+ transition:
71
+ border-color var(--duration-fast) var(--ease-standard),
72
+ background-color var(--duration-fast) var(--ease-standard);
73
+ }
76
74
 
77
- .ui-chip:focus-visible,
78
- .ui-chip.is-focus {
79
- outline: 2px solid var(--focus);
80
- outline-offset: 2px;
81
- box-shadow: 0 0 0 4px var(--focus-outer);
82
- }
75
+ .ui-chip:hover,
76
+ .ui-chip.is-hover {
77
+ border-color: var(--border-strong);
78
+ }
83
79
 
84
- /* Selected: 2 px border plus the accent surface, readable without colour. */
85
- .ui-chip.is-selected,
86
- .ui-chip[aria-pressed="true"] {
87
- border-width: 2px;
88
- border-color: var(--border-strong);
89
- background: var(--surface-accent);
90
- color: var(--surface-accent-fg, var(--text));
91
- font-weight: var(--weight-semibold);
92
- }
80
+ .ui-chip:focus-visible,
81
+ .ui-chip.is-focus {
82
+ outline: 2px solid var(--focus);
83
+ outline-offset: 2px;
84
+ box-shadow: 0 0 0 4px var(--focus-outer);
85
+ }
93
86
 
94
- .ui-chip.is-disabled,
95
- .ui-chip:disabled {
96
- opacity: 0.5;
97
- cursor: not-allowed;
98
- }
87
+ /* Selected: 2 px border plus the accent surface, readable without colour. */
88
+ .ui-chip.is-selected,
89
+ .ui-chip[aria-pressed="true"] {
90
+ border-width: 2px;
91
+ border-color: var(--border-strong);
92
+ background: var(--surface-accent);
93
+ color: var(--surface-accent-fg, var(--text));
94
+ font-weight: var(--weight-semibold);
95
+ }
99
96
 
100
- .ui-chip--struck {
101
- text-decoration: line-through;
102
- }
97
+ .ui-chip.is-disabled,
98
+ .ui-chip:disabled {
99
+ opacity: 0.5;
100
+ cursor: not-allowed;
101
+ }
103
102
 
104
- /* Filter chip: 32 px. */
105
- .ui-chip--filter {
106
- min-height: 32px;
107
- border-radius: var(--radius-full);
108
- padding: 0 var(--space-3);
109
- }
103
+ .ui-chip--struck {
104
+ text-decoration: line-through;
105
+ }
110
106
 
111
- .ui-chip--filter.is-selected,
112
- .ui-chip--filter[aria-pressed="true"] {
113
- background: var(--surface-accent);
114
- }
107
+ /* Filter chip: 32 px. */
108
+ .ui-chip--filter {
109
+ min-height: 32px;
110
+ border-radius: var(--radius-full);
111
+ padding: 0 var(--space-3);
112
+ }
115
113
 
116
- @media (prefers-reduced-motion: reduce) {
117
- .ui-chip {
118
- transition: none;
114
+ .ui-chip--filter.is-selected,
115
+ .ui-chip--filter[aria-pressed="true"] {
116
+ background: var(--surface-accent);
119
117
  }
120
- }
121
118
 
122
- @media (max-width: 700px), (pointer: coarse) {
123
- .ui-chip {
124
- min-height: 36px;
119
+ @media (prefers-reduced-motion: reduce) {
120
+ .ui-chip {
121
+ transition: none;
122
+ }
125
123
  }
126
- .ui-chip--filter {
127
- min-height: 40px;
124
+
125
+ @media (max-width: 700px), (pointer: coarse) {
126
+ .ui-chip {
127
+ min-height: 36px;
128
+ }
129
+ .ui-chip--filter {
130
+ min-height: 40px;
131
+ }
128
132
  }
129
133
  }
130
134
  </style>
@@ -22,59 +22,63 @@ const classes = ["pl-dotgrid", compact && "pl-dotgrid--compact", className]
22
22
  </div>
23
23
 
24
24
  <style>
25
- .pl-dotgrid {
26
- position: relative;
27
- min-height: 132px;
28
- overflow: hidden;
29
- border: 1px solid var(--border);
30
- border-radius: var(--radius-lg);
31
- background: var(--surface);
32
- }
25
+ @layer reset, tokens, base, components, motion, utilities;
33
26
 
34
- .pl-dotgrid__dots {
35
- position: absolute;
36
- inset: 0;
37
- background-image: radial-gradient(
38
- var(--dotgrid-color, var(--sage-light)) 1.4px,
39
- transparent 1.6px
40
- );
41
- background-size: 28px 28px;
42
- opacity: var(--dotgrid-opacity, var(--dotgrid-theme-opacity, 0.7));
43
- animation: pl-drift 6s linear infinite;
44
- }
27
+ @layer components {
28
+ .pl-dotgrid {
29
+ position: relative;
30
+ min-height: 132px;
31
+ overflow: hidden;
32
+ border: 1px solid var(--border);
33
+ border-radius: var(--radius-lg);
34
+ background: var(--surface);
35
+ }
45
36
 
46
- .pl-dotgrid__content {
47
- position: relative;
48
- display: block;
49
- padding: var(--space-5);
50
- font-size: var(--text-lg);
51
- font-weight: var(--weight-semibold);
52
- }
37
+ .pl-dotgrid__dots {
38
+ position: absolute;
39
+ inset: 0;
40
+ background-image: radial-gradient(
41
+ var(--dotgrid-color, var(--sage-light)) 1.4px,
42
+ transparent 1.6px
43
+ );
44
+ background-size: 28px 28px;
45
+ opacity: var(--dotgrid-opacity, var(--dotgrid-theme-opacity, 0.7));
46
+ animation: pl-drift 6s linear infinite;
47
+ }
53
48
 
54
- .pl-dotgrid--compact {
55
- border: 0;
56
- border-radius: 0;
57
- }
58
- .pl-dotgrid--compact .pl-dotgrid__dots {
59
- background-size: 24px 24px;
60
- }
61
- .pl-dotgrid--compact .pl-dotgrid__content {
62
- font-size: var(--text-base);
63
- }
49
+ .pl-dotgrid__content {
50
+ position: relative;
51
+ display: block;
52
+ padding: var(--space-5);
53
+ font-size: var(--text-lg);
54
+ font-weight: var(--weight-semibold);
55
+ }
64
56
 
65
- /* Explicit themes win over OS preference, as in the token cascade. */
66
- :global([data-theme="dark"]) .pl-dotgrid {
67
- --dotgrid-theme-opacity: 0.2;
68
- }
69
- @media (prefers-color-scheme: dark) {
70
- :global(:root:not([data-theme])) .pl-dotgrid {
57
+ .pl-dotgrid--compact {
58
+ border: 0;
59
+ border-radius: 0;
60
+ }
61
+ .pl-dotgrid--compact .pl-dotgrid__dots {
62
+ background-size: 24px 24px;
63
+ }
64
+ .pl-dotgrid--compact .pl-dotgrid__content {
65
+ font-size: var(--text-base);
66
+ }
67
+
68
+ /* Explicit themes win over OS preference, as in the token cascade. */
69
+ :global([data-theme="dark"]) .pl-dotgrid {
71
70
  --dotgrid-theme-opacity: 0.2;
72
71
  }
73
- }
72
+ @media (prefers-color-scheme: dark) {
73
+ :global(:root:not([data-theme])) .pl-dotgrid {
74
+ --dotgrid-theme-opacity: 0.2;
75
+ }
76
+ }
74
77
 
75
- @media (prefers-reduced-motion: reduce) {
76
- .pl-dotgrid__dots {
77
- animation: none;
78
+ @media (prefers-reduced-motion: reduce) {
79
+ .pl-dotgrid__dots {
80
+ animation: none;
81
+ }
78
82
  }
79
83
  }
80
84
  </style>
@@ -26,29 +26,33 @@ const hasAction = Astro.slots.has("action");
26
26
  </div>
27
27
 
28
28
  <style>
29
- .ui-empty {
30
- display: flex;
31
- flex-direction: column;
32
- align-items: flex-start;
33
- gap: var(--space-2);
34
- padding: var(--space-8) var(--space-6);
35
- border: 1px dashed var(--border-strong);
36
- border-radius: var(--radius-lg);
37
- background: var(--surface);
38
- }
29
+ @layer reset, tokens, base, components, motion, utilities;
39
30
 
40
- .ui-empty__title {
41
- font-size: var(--text-lg);
42
- font-weight: var(--weight-semibold);
43
- color: var(--text);
44
- }
31
+ @layer components {
32
+ .ui-empty {
33
+ display: flex;
34
+ flex-direction: column;
35
+ align-items: flex-start;
36
+ gap: var(--space-2);
37
+ padding: var(--space-8) var(--space-6);
38
+ border: 1px dashed var(--border-strong);
39
+ border-radius: var(--radius-lg);
40
+ background: var(--surface);
41
+ }
45
42
 
46
- .ui-empty__body {
47
- font-size: var(--text-sm);
48
- line-height: var(--leading-sm);
49
- color: var(--text-muted);
50
- }
43
+ .ui-empty__title {
44
+ font-size: var(--text-lg);
45
+ font-weight: var(--weight-semibold);
46
+ color: var(--text);
47
+ }
51
48
 
52
- /* The flex `gap` above already spaces the action from the body; an added
53
- margin here doubled that gap and threw off the rhythm between the two. */
49
+ .ui-empty__body {
50
+ font-size: var(--text-sm);
51
+ line-height: var(--leading-sm);
52
+ color: var(--text-muted);
53
+ }
54
+
55
+ /* The flex `gap` above already spaces the action from the body; an added */
56
+ /* margin here doubled that gap and threw off the rhythm between the two. */
57
+ }
54
58
  </style>