@hearthsound/design 0.0.0-stage → 0.1.1

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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +132 -2
  3. package/THIRD-PARTY.md +46 -0
  4. package/css/base.css +245 -0
  5. package/css/components/admin.css +257 -0
  6. package/css/components/banner.css +140 -0
  7. package/css/components/button.css +309 -0
  8. package/css/components/card.css +339 -0
  9. package/css/components/check.css +202 -0
  10. package/css/components/dialog.css +85 -0
  11. package/css/components/field.css +298 -0
  12. package/css/components/list.css +260 -0
  13. package/css/components/menu.css +335 -0
  14. package/css/components/page-header.css +230 -0
  15. package/css/components/pill.css +101 -0
  16. package/css/components/player.css +524 -0
  17. package/css/components/progress.css +173 -0
  18. package/css/components/section.css +86 -0
  19. package/css/components/segmented.css +64 -0
  20. package/css/components/shell.css +281 -0
  21. package/css/components/sidebar.css +170 -0
  22. package/css/components/slider.css +92 -0
  23. package/css/components/status-page.css +48 -0
  24. package/css/components/stepper.css +130 -0
  25. package/css/components/toast.css +88 -0
  26. package/css/components/tooltip.css +29 -0
  27. package/css/components/track.css +336 -0
  28. package/css/components/upload.css +70 -0
  29. package/css/index.css +35 -0
  30. package/css/tokens.css +375 -0
  31. package/dist/icons.d.ts +56 -0
  32. package/dist/icons.js +56 -0
  33. package/dist/icons.svg +55 -0
  34. package/fonts/OFL-BricolageGrotesque.txt +93 -0
  35. package/fonts/OFL-Geist.txt +92 -0
  36. package/fonts/bricolage-var.woff2 +0 -0
  37. package/fonts/geist-mono.woff2 +0 -0
  38. package/fonts/geist-var.woff2 +0 -0
  39. package/icons/LICENSE +10 -0
  40. package/icons/adwaita-account.svg +1 -0
  41. package/icons/adwaita-acquire.svg +1 -0
  42. package/icons/adwaita-add.svg +1 -0
  43. package/icons/adwaita-album.svg +1 -0
  44. package/icons/adwaita-artist.svg +1 -0
  45. package/icons/adwaita-back.svg +1 -0
  46. package/icons/adwaita-check.svg +1 -0
  47. package/icons/adwaita-close.svg +1 -0
  48. package/icons/adwaita-collapse.svg +1 -0
  49. package/icons/adwaita-dark-mode.svg +1 -0
  50. package/icons/adwaita-delete.svg +1 -0
  51. package/icons/adwaita-drag.svg +1 -0
  52. package/icons/adwaita-edit.svg +1 -0
  53. package/icons/adwaita-error.svg +1 -0
  54. package/icons/adwaita-expand.svg +1 -0
  55. package/icons/adwaita-folder.svg +1 -0
  56. package/icons/adwaita-forward.svg +1 -0
  57. package/icons/adwaita-home.svg +1 -0
  58. package/icons/adwaita-layers.svg +1 -0
  59. package/icons/adwaita-like.svg +1 -0
  60. package/icons/adwaita-lock.svg +1 -0
  61. package/icons/adwaita-menu.svg +1 -0
  62. package/icons/adwaita-more.svg +1 -0
  63. package/icons/adwaita-mute.svg +1 -0
  64. package/icons/adwaita-next.svg +1 -0
  65. package/icons/adwaita-pause.svg +1 -0
  66. package/icons/adwaita-play.svg +1 -0
  67. package/icons/adwaita-playlist.svg +1 -0
  68. package/icons/adwaita-plugin.svg +1 -0
  69. package/icons/adwaita-previous.svg +1 -0
  70. package/icons/adwaita-queue.svg +1 -0
  71. package/icons/adwaita-rating-outline.svg +1 -0
  72. package/icons/adwaita-rating.svg +1 -0
  73. package/icons/adwaita-refresh.svg +1 -0
  74. package/icons/adwaita-remote.svg +1 -0
  75. package/icons/adwaita-remove.svg +1 -0
  76. package/icons/adwaita-repeat.svg +1 -0
  77. package/icons/adwaita-reveal.svg +1 -0
  78. package/icons/adwaita-search.svg +1 -0
  79. package/icons/adwaita-settings.svg +1 -0
  80. package/icons/adwaita-shuffle.svg +1 -0
  81. package/icons/adwaita-sign-out.svg +1 -0
  82. package/icons/adwaita-song.svg +1 -0
  83. package/icons/adwaita-sort.svg +1 -0
  84. package/icons/adwaita-storage.svg +1 -0
  85. package/icons/adwaita-users.svg +1 -0
  86. package/icons/adwaita-volume.svg +1 -0
  87. package/icons/adwaita-warning.svg +1 -0
  88. package/icons/custom-dislike-outline.svg +1 -0
  89. package/icons/custom-dislike.svg +1 -0
  90. package/icons/custom-like-outline.svg +1 -0
  91. package/icons/custom-unknown.svg +1 -0
  92. package/icons/custom-upload.svg +1 -0
  93. package/identity/icons/app-icon-dark-16.png +0 -0
  94. package/identity/icons/app-icon-dark-180.png +0 -0
  95. package/identity/icons/app-icon-dark-192.png +0 -0
  96. package/identity/icons/app-icon-dark-32.png +0 -0
  97. package/identity/icons/app-icon-dark-512.png +0 -0
  98. package/identity/icons/app-icon-dark.svg +1 -0
  99. package/identity/icons/app-icon-light-16.png +0 -0
  100. package/identity/icons/app-icon-light-180.png +0 -0
  101. package/identity/icons/app-icon-light-192.png +0 -0
  102. package/identity/icons/app-icon-light-32.png +0 -0
  103. package/identity/icons/app-icon-light-512.png +0 -0
  104. package/identity/icons/app-icon-light.svg +1 -0
  105. package/identity/icons/favicon.svg +1 -0
  106. package/identity/mark/mark-dark.svg +1 -0
  107. package/identity/mark/mark-light.svg +1 -0
  108. package/identity/mark/mark-symbolic.svg +1 -0
  109. package/package.json +35 -4
@@ -0,0 +1,298 @@
1
+ /*
2
+ * k03 text fields and search (k03 C tonal field and pill search, k03f B focused fields stay
3
+ * grey), k04 A number entry, k04b C textarea, k05 A drop-down trigger, k32 B form field and
4
+ * the l14 sidebar search.
5
+ *
6
+ * Text-type fields (text, search, number, password, textarea) never change their grey rest
7
+ * surface on focus and carry no focus shadow (k03f). Focus is shown by the caret in
8
+ * --hs-accent-text and, in a form field, by the accent label.
9
+ */
10
+
11
+ /* ------------------------------------------------------------------ */
12
+ /* k03 - anatomy */
13
+ /* ------------------------------------------------------------------ */
14
+
15
+ .hs-field,
16
+ .hs-select {
17
+ display: inline-flex;
18
+ align-items: center;
19
+ gap: 8px;
20
+ height: 36px;
21
+ padding: 0 6px 0 12px;
22
+ box-sizing: border-box;
23
+ width: 100%;
24
+ border-radius: var(--hs-radius-control);
25
+ font: 400 14px var(--hs-font-body);
26
+ color: var(--hs-fg);
27
+ background: var(--hs-control-tone);
28
+ transition:
29
+ background var(--hs-duration-hover) var(--hs-ease),
30
+ box-shadow var(--hs-duration-hover) var(--hs-ease);
31
+ }
32
+
33
+ .hs-field__lead {
34
+ --hs-icon-size: 16px;
35
+ color: var(--hs-fg-muted);
36
+ }
37
+
38
+ .hs-field__value {
39
+ flex: 1;
40
+ min-width: 0;
41
+ white-space: nowrap;
42
+ overflow: hidden;
43
+ }
44
+
45
+ .hs-field__input {
46
+ all: unset;
47
+ flex: 1;
48
+ min-width: 0;
49
+ caret-color: var(--hs-accent-text);
50
+ }
51
+
52
+ .hs-field__input::placeholder {
53
+ color: var(--hs-fg-muted);
54
+ }
55
+
56
+ /* Inner actions: reveal, clear and the number steps. 28 px square, 14 px glyphs, muted. */
57
+ .hs-field__action,
58
+ .hs-field__step {
59
+ display: inline-flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ flex: none;
63
+ width: 28px;
64
+ height: 28px;
65
+ padding: 0;
66
+ margin: 0;
67
+ border: 0;
68
+ border-radius: 6px;
69
+ background: transparent;
70
+ color: var(--hs-fg-muted);
71
+ cursor: default;
72
+ appearance: none;
73
+ transition:
74
+ background var(--hs-duration-hover) var(--hs-ease),
75
+ color var(--hs-duration-hover) var(--hs-ease);
76
+ }
77
+
78
+ .hs-field__action .hs-icon,
79
+ .hs-field__step .hs-icon {
80
+ --hs-icon-size: 14px;
81
+ }
82
+
83
+ .hs-field__action:hover,
84
+ .hs-field__step:hover {
85
+ background: var(--hs-control-tone);
86
+ color: var(--hs-fg);
87
+ }
88
+
89
+ /* Password reveal while the password is shown: the k01 toggle-on tone. */
90
+ .hs-field__action[aria-pressed='true'] {
91
+ color: var(--hs-fg);
92
+ background: color-mix(in srgb, var(--hs-fg) 24%, transparent);
93
+ }
94
+
95
+ .hs-field__action:disabled,
96
+ .hs-field__action[aria-disabled='true'],
97
+ .hs-field__step:disabled,
98
+ .hs-field__step[aria-disabled='true'] {
99
+ opacity: 0.4;
100
+ pointer-events: none;
101
+ }
102
+
103
+ /* Search: fully round, tighter padding at the leading edge, round inner actions. */
104
+ .hs-field--search {
105
+ border-radius: var(--hs-radius-full);
106
+ padding-left: 14px;
107
+ padding-right: 4px;
108
+ }
109
+
110
+ .hs-field--search .hs-field__action {
111
+ border-radius: var(--hs-radius-full);
112
+ }
113
+
114
+ /* ------------------------------------------------------------------ */
115
+ /* k03 - states */
116
+ /* ------------------------------------------------------------------ */
117
+
118
+ :is(.hs-field, .hs-select):hover:not(:focus-within):not(.hs-field--invalid):not([aria-invalid='true']) {
119
+ background: color-mix(in srgb, var(--hs-fg) 13%, transparent);
120
+ }
121
+
122
+ /* k03f B: a focused field keeps the grey surface and no shadow. */
123
+ :is(.hs-field, .hs-select):focus-within {
124
+ background: var(--hs-control-tone);
125
+ box-shadow: none;
126
+ }
127
+
128
+ /* Declared after focus: the invalid tint is not a focus treatment and stays while the
129
+ * field is focused or hovered. The doubled class matches the focus rule's specificity. */
130
+ .hs-field.hs-field--invalid,
131
+ .hs-field[aria-invalid='true'],
132
+ .hs-select.hs-field--invalid,
133
+ .hs-select[aria-invalid='true'] {
134
+ background: color-mix(in srgb, var(--hs-error) 12%, transparent);
135
+ }
136
+
137
+ .hs-field--disabled,
138
+ .hs-field[aria-disabled='true'],
139
+ .hs-field:has(.hs-field__input:disabled),
140
+ .hs-select:disabled,
141
+ .hs-select[aria-disabled='true'] {
142
+ opacity: 0.4;
143
+ pointer-events: none;
144
+ }
145
+
146
+ /* ------------------------------------------------------------------ */
147
+ /* k04 - number entry: minus and plus at the end */
148
+ /* ------------------------------------------------------------------ */
149
+
150
+ .hs-field--number {
151
+ font-variant-numeric: tabular-nums;
152
+ }
153
+
154
+ .hs-field__unit {
155
+ color: var(--hs-fg-muted);
156
+ font-size: 13px;
157
+ }
158
+
159
+ /* ------------------------------------------------------------------ */
160
+ /* k04b - textarea: fixed three lines, scrolls */
161
+ /* ------------------------------------------------------------------ */
162
+
163
+ .hs-field--textarea {
164
+ height: 84px;
165
+ align-items: stretch;
166
+ padding: 9px 18px 9px 12px;
167
+ line-height: 22px;
168
+ overflow: auto;
169
+ }
170
+
171
+ .hs-field--textarea .hs-field__input {
172
+ white-space: pre-wrap;
173
+ resize: none;
174
+ }
175
+
176
+ /* ------------------------------------------------------------------ */
177
+ /* k05 - drop-down trigger */
178
+ /* ------------------------------------------------------------------ */
179
+
180
+ /* k05 A: a tonal field with a trailing 14 px chevron; the open trigger sits at the hover
181
+ * tone and the chevron turns over. The list and its options are hs-listbox / hs-option
182
+ * in menu.css. The trigger is a button named by its visible label plus the current
183
+ * value, with aria-haspopup="listbox" and aria-expanded. */
184
+ .hs-select {
185
+ margin: 0;
186
+ border: 0;
187
+ padding-right: 10px;
188
+ text-align: left;
189
+ cursor: default;
190
+ appearance: none;
191
+ }
192
+
193
+ .hs-select .hs-icon:last-child {
194
+ --hs-icon-size: 14px;
195
+ color: var(--hs-fg-muted);
196
+ transition: transform var(--hs-duration-popover) var(--hs-ease);
197
+ }
198
+
199
+ .hs-select[aria-expanded='true'] .hs-icon:last-child {
200
+ transform: rotate(180deg);
201
+ }
202
+
203
+ .hs-select[aria-expanded='true'] {
204
+ background: color-mix(in srgb, var(--hs-fg) 13%, transparent);
205
+ }
206
+
207
+ /* ------------------------------------------------------------------ */
208
+ /* l14 - sidebar search field */
209
+ /* ------------------------------------------------------------------ */
210
+
211
+ /* The sidebar field is the same pill at 34 px, with 2 px side margins and 8 px below the
212
+ * lockup. Markup carries both .hs-field--search and .hs-search-field. */
213
+ .hs-search-field {
214
+ margin: 0 2px 8px;
215
+ width: auto;
216
+ height: 34px;
217
+ }
218
+
219
+ /* p18 board: the results page puts the search pill in the page header at 40 px. */
220
+ .hs-page-header .hs-field--search {
221
+ height: 40px;
222
+ }
223
+
224
+ /* ------------------------------------------------------------------ */
225
+ /* k32 - form field */
226
+ /* ------------------------------------------------------------------ */
227
+
228
+ .hs-form {
229
+ display: flex;
230
+ flex-direction: column;
231
+ gap: 18px;
232
+ max-width: 560px;
233
+ }
234
+
235
+ .hs-form-field {
236
+ display: flex;
237
+ flex-direction: column;
238
+ gap: 6px;
239
+ }
240
+
241
+ .hs-form-field__label {
242
+ display: flex;
243
+ align-items: baseline;
244
+ gap: 6px;
245
+ font: 500 13px var(--hs-font-body);
246
+ color: var(--hs-fg-muted);
247
+ }
248
+
249
+ /* The label turns accent while its field holds focus. */
250
+ .hs-form-field:focus-within > .hs-form-field__label {
251
+ color: var(--hs-accent-text);
252
+ }
253
+
254
+ .hs-form-field__optional {
255
+ font-weight: 400;
256
+ font-size: 12px;
257
+ color: var(--hs-fg-muted);
258
+ }
259
+
260
+ .hs-form-field__hint {
261
+ margin: 0;
262
+ font-size: 12.5px;
263
+ color: var(--hs-fg-muted);
264
+ }
265
+
266
+ .hs-form-field__error {
267
+ display: flex;
268
+ align-items: center;
269
+ gap: 6px;
270
+ margin: 0;
271
+ font-size: 12.5px;
272
+ color: var(--hs-error);
273
+ }
274
+
275
+ .hs-form-field__error .hs-icon {
276
+ --hs-icon-size: 14px;
277
+ }
278
+
279
+ /* p26c: a row pinned by the configuration file or the environment shows its value with
280
+ * this muted lock line instead of a control. */
281
+ .hs-form-field__pinned {
282
+ display: inline-flex;
283
+ align-items: center;
284
+ gap: 5px;
285
+ font-size: 13px;
286
+ color: var(--hs-fg-muted);
287
+ }
288
+
289
+ .hs-form-field__pinned .hs-icon {
290
+ --hs-icon-size: 12px;
291
+ }
292
+
293
+ /* k32 B: footer buttons right-aligned (the form's own buttons, not the dialog footer). */
294
+ .hs-form__footer {
295
+ display: flex;
296
+ justify-content: flex-end;
297
+ gap: 8px;
298
+ }
@@ -0,0 +1,260 @@
1
+ /*
2
+ * @hearthsound/design - lists
3
+ *
4
+ * k11-r1 boxed lists and settings rows (C: white page, deeper grey group),
5
+ * k28 admin tables, k30 / k30-r1 reorderable lists.
6
+ * Values from shared/approved/components.css (k11-r1, k28, k30) and
7
+ * spec/components.md. Board classes used there are mapped in components.md.
8
+ */
9
+
10
+ /* ------------------------------------------------------------------ */
11
+ /* k11-r1 - boxed lists (settings groups) */
12
+ /* ------------------------------------------------------------------ */
13
+
14
+ .hs-settings-group {
15
+ background: var(--hs-group-bg);
16
+ box-shadow: var(--hs-group-shadow);
17
+ border-radius: var(--hs-radius-card);
18
+ overflow: hidden;
19
+ }
20
+
21
+ .hs-setting-row {
22
+ display: flex;
23
+ align-items: center;
24
+ gap: 12px;
25
+ min-height: var(--hs-row-comfortable);
26
+ padding: 8px 16px;
27
+ position: relative;
28
+ font: 400 14px/1.4 var(--hs-font-body);
29
+ color: var(--hs-fg);
30
+ transition: background var(--hs-duration-hover) var(--hs-ease);
31
+ }
32
+
33
+ /* k11-r1 - a 1 px hairline drawn as an inset shadow, so rows keep their height. */
34
+ .hs-settings-group .hs-setting-row + .hs-setting-row {
35
+ box-shadow: inset 0 1px 0 var(--hs-separator);
36
+ }
37
+
38
+ .hs-setting-row--two-line {
39
+ min-height: 60px;
40
+ }
41
+
42
+ /* B08 - compact admin density. */
43
+ .hs-setting-row--compact {
44
+ min-height: var(--hs-row-compact);
45
+ padding: var(--hs-row-pad-compact) 16px;
46
+ }
47
+
48
+ .hs-setting-row__text {
49
+ flex: 1;
50
+ min-width: 0;
51
+ display: flex;
52
+ flex-direction: column;
53
+ gap: 3px;
54
+ }
55
+
56
+ .hs-setting-row__subtitle {
57
+ color: var(--hs-fg-muted);
58
+ font-size: 13px;
59
+ }
60
+
61
+ .hs-setting-row__value {
62
+ color: var(--hs-fg-muted);
63
+ }
64
+
65
+ .hs-setting-row__icon {
66
+ color: var(--hs-fg-muted);
67
+ width: 16px;
68
+ height: 16px;
69
+ }
70
+
71
+ /* Button row: centred label with an icon, the icon in the text colour. */
72
+ .hs-setting-row--button {
73
+ justify-content: center;
74
+ font-weight: 600;
75
+ gap: 8px;
76
+ }
77
+
78
+ .hs-setting-row--button .hs-setting-row__icon {
79
+ color: var(--hs-fg);
80
+ }
81
+
82
+ /* Property row: a muted 12 px key line over the value. */
83
+ .hs-setting-row--property .hs-setting-row__text {
84
+ gap: 2px;
85
+ }
86
+
87
+ .hs-setting-row__key {
88
+ color: var(--hs-fg-muted);
89
+ font-size: 12px;
90
+ }
91
+
92
+ /* Expander row: the trailing chevron turns when the row is open. */
93
+ .hs-setting-row--expander > .hs-setting-row__icon:last-child {
94
+ transition: transform var(--hs-duration-popover) var(--hs-ease);
95
+ }
96
+
97
+ .hs-setting-row--expander[aria-expanded='true'] > .hs-setting-row__icon:last-child {
98
+ transform: rotate(180deg);
99
+ }
100
+
101
+ .hs-setting-row--nested {
102
+ padding-left: 32px;
103
+ }
104
+
105
+ .hs-setting-row--interactive:hover {
106
+ background: var(--hs-control-tone);
107
+ }
108
+
109
+ .hs-setting-row--interactive:active {
110
+ background: color-mix(in srgb, var(--hs-fg) 15%, transparent);
111
+ }
112
+
113
+ /* f13-r3 - tint and lift, first text span in the accent text at weight 600. */
114
+ .hs-setting-row:focus-visible {
115
+ outline: none;
116
+ background: var(--hs-accent-tint);
117
+ box-shadow: var(--hs-focus-shadow) !important;
118
+ z-index: 1;
119
+ }
120
+
121
+ .hs-setting-row:focus-visible .hs-setting-row__text > :first-child {
122
+ color: var(--hs-accent-text);
123
+ font-weight: 600;
124
+ }
125
+
126
+ .hs-setting-row[aria-disabled='true'] {
127
+ opacity: 0.4;
128
+ pointer-events: none;
129
+ }
130
+
131
+ @media (prefers-reduced-motion: reduce) {
132
+ .hs-setting-row,
133
+ .hs-setting-row--expander > .hs-setting-row__icon:last-child {
134
+ transition: none;
135
+ }
136
+ }
137
+
138
+ /* ------------------------------------------------------------------ */
139
+ /* k30 / k30-r1 - reorderable lists */
140
+ /* ------------------------------------------------------------------ */
141
+
142
+ .hs-reorder-list .hs-setting-row__number {
143
+ width: 20px;
144
+ color: var(--hs-fg-muted);
145
+ font-variant-numeric: tabular-nums;
146
+ }
147
+
148
+ .hs-reorder-list .hs-setting-row__subtitle--mono {
149
+ font: 400 12px var(--hs-font-mono);
150
+ }
151
+
152
+ .hs-reorder-handle {
153
+ width: 16px;
154
+ height: 16px;
155
+ color: var(--hs-fg-muted);
156
+ cursor: grab;
157
+ display: none;
158
+ }
159
+
160
+ /* Reorder mode (k30-r1: entered from a "Reorder" menu item) or an
161
+ * always-handles list (setup Order p05b-r1, Customize Home p07b, Layers p25b). */
162
+ .hs-reorder-list--reordering .hs-reorder-handle,
163
+ .hs-reorder-list--handles .hs-reorder-handle {
164
+ display: inline-flex;
165
+ }
166
+
167
+ .hs-setting-row--lifted {
168
+ background: var(--hs-popover-bg);
169
+ box-shadow: var(--hs-elevation-2) !important;
170
+ border-radius: var(--hs-radius-row);
171
+ transform: translateY(-8px);
172
+ z-index: 3;
173
+ }
174
+
175
+ .hs-reorder-slot {
176
+ display: block;
177
+ height: 52px;
178
+ background: color-mix(in srgb, var(--hs-accent-bg) 14%, transparent);
179
+ }
180
+
181
+ .hs-setting-row--grabbed {
182
+ background: var(--hs-accent-tint);
183
+ box-shadow: var(--hs-focus-shadow) !important;
184
+ }
185
+
186
+ .hs-setting-row--grabbed .hs-setting-row__text > :first-child {
187
+ font-weight: 600;
188
+ }
189
+
190
+ /* ------------------------------------------------------------------ */
191
+ /* k28 - admin tables */
192
+ /* ------------------------------------------------------------------ */
193
+
194
+ .hs-table {
195
+ width: 100%;
196
+ border-collapse: collapse;
197
+ font: 400 14px var(--hs-font-body);
198
+ color: var(--hs-fg);
199
+ }
200
+
201
+ .hs-table th {
202
+ text-align: left;
203
+ font: 600 12px var(--hs-font-body);
204
+ color: var(--hs-fg-muted);
205
+ height: 34px;
206
+ padding: 0 10px;
207
+ white-space: nowrap;
208
+ }
209
+
210
+ .hs-table th[aria-sort] {
211
+ color: var(--hs-fg);
212
+ }
213
+
214
+ .hs-table th .hs-icon {
215
+ width: 12px;
216
+ height: 12px;
217
+ vertical-align: -1px;
218
+ margin-left: 4px;
219
+ }
220
+
221
+ .hs-table td {
222
+ height: 36px;
223
+ padding: 0 10px;
224
+ box-shadow: inset 0 1px 0 var(--hs-separator);
225
+ white-space: nowrap;
226
+ }
227
+
228
+ .hs-table .hs-table__cell--numeric {
229
+ text-align: right;
230
+ }
231
+
232
+ .hs-sort-button {
233
+ display: inline-flex;
234
+ align-items: center;
235
+ padding: 0;
236
+ border: 0;
237
+ background: none;
238
+ font: inherit;
239
+ color: inherit;
240
+ cursor: default;
241
+ }
242
+
243
+ .hs-sort-button:focus-visible {
244
+ outline: none;
245
+ background: var(--hs-accent-tint);
246
+ color: var(--hs-accent-text);
247
+ box-shadow: var(--hs-focus-shadow);
248
+ }
249
+
250
+ .hs-table__scroll {
251
+ position: relative;
252
+ overflow-x: auto;
253
+ }
254
+
255
+ /* k28 - phones scroll sideways with a right-edge fade. */
256
+ @media (max-width: 720px) {
257
+ .hs-table__scroll {
258
+ mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent);
259
+ }
260
+ }