@orange-halo/components 1.0.0 → 2.0.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 (67) hide show
  1. package/dist/base.js +3 -3
  2. package/dist/oh-accordion.js +17 -17
  3. package/dist/oh-alert.js +15 -15
  4. package/dist/oh-badge.js +11 -11
  5. package/dist/oh-breadcrumb.js +8 -8
  6. package/dist/oh-button.d.ts +6 -0
  7. package/dist/oh-button.d.ts.map +1 -1
  8. package/dist/oh-button.js +105 -76
  9. package/dist/oh-button.js.map +1 -1
  10. package/dist/oh-card.js +28 -28
  11. package/dist/oh-checkbox-group.d.ts +8 -0
  12. package/dist/oh-checkbox-group.d.ts.map +1 -1
  13. package/dist/oh-checkbox-group.js +27 -13
  14. package/dist/oh-checkbox-group.js.map +1 -1
  15. package/dist/oh-checkbox.d.ts +9 -0
  16. package/dist/oh-checkbox.d.ts.map +1 -1
  17. package/dist/oh-checkbox.js +25 -9
  18. package/dist/oh-checkbox.js.map +1 -1
  19. package/dist/oh-container.d.ts +5 -5
  20. package/dist/oh-container.js +15 -15
  21. package/dist/oh-drawer.d.ts +7 -2
  22. package/dist/oh-drawer.d.ts.map +1 -1
  23. package/dist/oh-drawer.js +52 -25
  24. package/dist/oh-drawer.js.map +1 -1
  25. package/dist/oh-footer.js +4 -4
  26. package/dist/oh-hero.d.ts.map +1 -1
  27. package/dist/oh-hero.js +50 -51
  28. package/dist/oh-hero.js.map +1 -1
  29. package/dist/oh-icon.js +6 -6
  30. package/dist/oh-input.d.ts +9 -1
  31. package/dist/oh-input.d.ts.map +1 -1
  32. package/dist/oh-input.js +45 -33
  33. package/dist/oh-input.js.map +1 -1
  34. package/dist/oh-link.d.ts +1 -1
  35. package/dist/oh-link.js +15 -15
  36. package/dist/oh-modal.d.ts +8 -2
  37. package/dist/oh-modal.d.ts.map +1 -1
  38. package/dist/oh-modal.js +68 -65
  39. package/dist/oh-modal.js.map +1 -1
  40. package/dist/oh-navbar.d.ts.map +1 -1
  41. package/dist/oh-navbar.js +3 -4
  42. package/dist/oh-navbar.js.map +1 -1
  43. package/dist/oh-progress.d.ts.map +1 -1
  44. package/dist/oh-progress.js +20 -34
  45. package/dist/oh-progress.js.map +1 -1
  46. package/dist/oh-radio-group.d.ts +8 -0
  47. package/dist/oh-radio-group.d.ts.map +1 -1
  48. package/dist/oh-radio-group.js +27 -13
  49. package/dist/oh-radio-group.js.map +1 -1
  50. package/dist/oh-radio.d.ts +9 -0
  51. package/dist/oh-radio.d.ts.map +1 -1
  52. package/dist/oh-radio.js +26 -10
  53. package/dist/oh-radio.js.map +1 -1
  54. package/dist/oh-select.d.ts +8 -0
  55. package/dist/oh-select.d.ts.map +1 -1
  56. package/dist/oh-select.js +34 -20
  57. package/dist/oh-select.js.map +1 -1
  58. package/dist/oh-skip-link.d.ts.map +1 -1
  59. package/dist/oh-skip-link.js +13 -12
  60. package/dist/oh-skip-link.js.map +1 -1
  61. package/dist/oh-tabs.js +6 -6
  62. package/dist/oh-toggle.d.ts +5 -2
  63. package/dist/oh-toggle.d.ts.map +1 -1
  64. package/dist/oh-toggle.js +7 -9
  65. package/dist/oh-toggle.js.map +1 -1
  66. package/dist/styles/typography.js +46 -46
  67. package/package.json +7 -3
package/dist/oh-button.js CHANGED
@@ -64,9 +64,9 @@ let OhButton = class OhButton extends OhElement {
64
64
 
65
65
  .button {
66
66
  /* Typography: friendly, not shouty */
67
- font-family: var(--oh-font-family-sans);
68
- font-weight: var(--oh-font-weight-semibold);
69
- letter-spacing: var(--oh-font-letter-spacing-wide);
67
+ font-family: var(--oh-button-base-font-family);
68
+ font-weight: var(--oh-button-base-font-weight);
69
+ letter-spacing: var(--oh-button-base-letter-spacing);
70
70
  text-decoration: none;
71
71
 
72
72
  /* Layout */
@@ -76,7 +76,7 @@ let OhButton = class OhButton extends OhElement {
76
76
  gap: var(--oh-spacing-2);
77
77
 
78
78
  /* Shape: chunky rounded corners, not pills */
79
- border-radius: var(--oh-radius-md);
79
+ border-radius: var(--oh-button-base-border-radius);
80
80
 
81
81
  /* Thick illustrative border */
82
82
  border: var(--oh-button-base-border-width) solid;
@@ -98,30 +98,30 @@ let OhButton = class OhButton extends OhElement {
98
98
  PRIMARY VARIANT
99
99
  Signature orange — bold and warm
100
100
  Filled button: color + shadow define shape (no visible border)
101
- Contrast: #FFFFFF on #C54300 = 5.0:1 ✓ (WCAG AA)
101
+ Contrast: white on brand primary = 5.0:1 ✓ (WCAG AA)
102
102
  ═══════════════════════════════════════════════════════════════ */
103
103
 
104
104
  .button--primary {
105
- background-color: var(--oh-color-brand-primary);
106
- border-color: var(--oh-color-brand-primary);
107
- color: var(--oh-color-text-on-brand);
105
+ background-color: var(--oh-button-variant-primary-background);
106
+ border-color: var(--oh-button-variant-primary-border-color);
107
+ color: var(--oh-button-variant-primary-color);
108
108
 
109
109
  /* Light offset shadow: makes button pop forward */
110
- box-shadow: 4px 4px 0 0 var(--oh-shadow-primary);
110
+ box-shadow: 4px 4px 0 0 var(--oh-button-variant-primary-shadow-color);
111
111
  }
112
112
 
113
113
  .button--primary:hover {
114
- background-color: var(--oh-color-brand-primary-hover);
115
- border-color: var(--oh-color-brand-primary-hover);
114
+ background-color: var(--oh-button-variant-primary-background-hover);
115
+ border-color: var(--oh-button-variant-primary-background-hover);
116
116
  transform: translate(-2px, -2px);
117
- box-shadow: 6px 6px 0 0 var(--oh-shadow-primary);
117
+ box-shadow: 6px 6px 0 0 var(--oh-button-variant-primary-shadow-color);
118
118
  }
119
119
 
120
120
  .button--primary:active {
121
- background-color: var(--oh-color-brand-primary-active);
122
- border-color: var(--oh-color-brand-primary-active);
121
+ background-color: var(--oh-button-variant-primary-background-active);
122
+ border-color: var(--oh-button-variant-primary-background-active);
123
123
  transform: translate(2px, 2px);
124
- box-shadow: 1px 1px 0 0 var(--oh-shadow-primary);
124
+ box-shadow: 1px 1px 0 0 var(--oh-button-variant-primary-shadow-color);
125
125
  }
126
126
 
127
127
  /* ═══════════════════════════════════════════════════════════════
@@ -130,23 +130,23 @@ let OhButton = class OhButton extends OhElement {
130
130
  ═══════════════════════════════════════════════════════════════ */
131
131
 
132
132
  .button--secondary {
133
- background-color: var(--oh-color-surface-base);
134
- border-color: var(--oh-color-border-emphasis);
135
- color: var(--oh-color-text-primary);
133
+ background-color: var(--oh-button-variant-secondary-background);
134
+ border-color: var(--oh-button-variant-secondary-border-color);
135
+ color: var(--oh-button-variant-secondary-color);
136
136
 
137
- box-shadow: 4px 4px 0 0 var(--oh-shadow-secondary);
137
+ box-shadow: 4px 4px 0 0 var(--oh-button-variant-secondary-shadow-color);
138
138
  }
139
139
 
140
140
  .button--secondary:hover {
141
- background-color: var(--oh-color-surface-hover);
141
+ background-color: var(--oh-button-variant-secondary-background-hover);
142
142
  transform: translate(-2px, -2px);
143
- box-shadow: 6px 6px 0 0 var(--oh-shadow-secondary);
143
+ box-shadow: 6px 6px 0 0 var(--oh-button-variant-secondary-shadow-color);
144
144
  }
145
145
 
146
146
  .button--secondary:active {
147
- background-color: var(--oh-color-surface-active-pressed);
147
+ background-color: var(--oh-button-variant-secondary-background-active);
148
148
  transform: translate(2px, 2px);
149
- box-shadow: 1px 1px 0 0 var(--oh-shadow-secondary);
149
+ box-shadow: 1px 1px 0 0 var(--oh-button-variant-secondary-shadow-color);
150
150
  }
151
151
 
152
152
  /* ═══════════════════════════════════════════════════════════════
@@ -156,25 +156,25 @@ let OhButton = class OhButton extends OhElement {
156
156
  ═══════════════════════════════════════════════════════════════ */
157
157
 
158
158
  .button--accent {
159
- background-color: var(--oh-color-accent-default);
160
- border-color: var(--oh-color-accent-default);
161
- color: var(--oh-color-text-on-accent);
159
+ background-color: var(--oh-button-variant-accent-background);
160
+ border-color: var(--oh-button-variant-accent-border-color);
161
+ color: var(--oh-button-variant-accent-color);
162
162
 
163
- box-shadow: 4px 4px 0 0 var(--oh-shadow-accent);
163
+ box-shadow: 4px 4px 0 0 var(--oh-button-variant-accent-shadow-color);
164
164
  }
165
165
 
166
166
  .button--accent:hover {
167
- background-color: var(--oh-color-accent-hover);
168
- border-color: var(--oh-color-accent-hover);
167
+ background-color: var(--oh-button-variant-accent-background-hover);
168
+ border-color: var(--oh-button-variant-accent-background-hover);
169
169
  transform: translate(-2px, -2px);
170
- box-shadow: 6px 6px 0 0 var(--oh-shadow-accent);
170
+ box-shadow: 6px 6px 0 0 var(--oh-button-variant-accent-shadow-color);
171
171
  }
172
172
 
173
173
  .button--accent:active {
174
- background-color: var(--oh-color-accent-active);
175
- border-color: var(--oh-color-accent-active);
174
+ background-color: var(--oh-button-variant-accent-background-active);
175
+ border-color: var(--oh-button-variant-accent-background-active);
176
176
  transform: translate(2px, 2px);
177
- box-shadow: 1px 1px 0 0 var(--oh-shadow-accent);
177
+ box-shadow: 1px 1px 0 0 var(--oh-button-variant-accent-shadow-color);
178
178
  }
179
179
 
180
180
  /* ═══════════════════════════════════════════════════════════════
@@ -189,42 +189,42 @@ let OhButton = class OhButton extends OhElement {
189
189
  }
190
190
 
191
191
  .button--primary:focus-visible {
192
- box-shadow: 4px 4px 0 0 var(--oh-shadow-primary);
192
+ box-shadow: 4px 4px 0 0 var(--oh-button-variant-primary-shadow-color);
193
193
  }
194
194
 
195
195
  .button--secondary:focus-visible {
196
- box-shadow: 4px 4px 0 0 var(--oh-shadow-secondary);
196
+ box-shadow: 4px 4px 0 0 var(--oh-button-variant-secondary-shadow-color);
197
197
  }
198
198
 
199
199
  .button--accent:focus-visible {
200
- box-shadow: 4px 4px 0 0 var(--oh-shadow-accent);
200
+ box-shadow: 4px 4px 0 0 var(--oh-button-variant-accent-shadow-color);
201
201
  }
202
202
 
203
203
  /* ═══════════════════════════════════════════════════════════════
204
204
  SIZE VARIANTS
205
205
  Minimum 16px (1rem) for WCAG readability
206
- Scale: sm=16px, md=18px, lg=20px
206
+ Values: button.size.* tokens
207
207
  ═══════════════════════════════════════════════════════════════ */
208
208
 
209
209
  .button--sm {
210
- font-size: var(--oh-font-size-base);
211
- padding: var(--oh-spacing-2) var(--oh-spacing-4);
212
- min-height: 40px;
213
- gap: var(--oh-spacing-2);
210
+ font-size: var(--oh-button-size-sm-font-size);
211
+ padding: var(--oh-button-size-sm-padding-y) var(--oh-button-size-sm-padding-x);
212
+ min-height: var(--oh-button-size-sm-min-height);
213
+ gap: var(--oh-button-size-sm-gap);
214
214
  }
215
215
 
216
216
  .button--md {
217
- font-size: var(--oh-font-size-lg);
218
- padding: var(--oh-spacing-3) var(--oh-spacing-6);
219
- min-height: 48px;
220
- gap: var(--oh-spacing-2);
217
+ font-size: var(--oh-button-size-md-font-size);
218
+ padding: var(--oh-button-size-md-padding-y) var(--oh-button-size-md-padding-x);
219
+ min-height: var(--oh-button-size-md-min-height);
220
+ gap: var(--oh-button-size-md-gap);
221
221
  }
222
222
 
223
223
  .button--lg {
224
- font-size: var(--oh-font-size-xl);
225
- padding: var(--oh-spacing-4) var(--oh-spacing-8);
226
- min-height: 56px;
227
- gap: var(--oh-spacing-2-5);
224
+ font-size: var(--oh-button-size-lg-font-size);
225
+ padding: var(--oh-button-size-lg-padding-y) var(--oh-button-size-lg-padding-x);
226
+ min-height: var(--oh-button-size-lg-min-height);
227
+ gap: var(--oh-button-size-lg-gap);
228
228
  }
229
229
 
230
230
  /* ═══════════════════════════════════════════════════════════════
@@ -259,12 +259,15 @@ let OhButton = class OhButton extends OhElement {
259
259
  min-width: 56px;
260
260
  }
261
261
 
262
- /* Icon-only focus underline */
263
- :host([icon-only]) .button {
262
+ /* Focus underline drawn by the button itself, for icon-only buttons and
263
+ loading buttons, whose text is hidden so text-decoration shows nothing */
264
+ :host([icon-only]) .button,
265
+ .button--loading {
264
266
  position: relative;
265
267
  }
266
268
 
267
- :host([icon-only]) .button::after {
269
+ :host([icon-only]) .button::after,
270
+ .button--loading::after {
268
271
  content: '';
269
272
  position: absolute;
270
273
  bottom: 4px;
@@ -274,14 +277,15 @@ let OhButton = class OhButton extends OhElement {
274
277
  height: 2px;
275
278
  background-color: currentColor;
276
279
  opacity: 0;
277
- transition: opacity var(--oh-motion-snappy, 150ms) var(--oh-motion-ease-gentle, ease);
280
+ transition: opacity var(--oh-motion-snappy) var(--oh-motion-ease-gentle);
278
281
  }
279
282
 
280
283
  :host([icon-only]) .button:focus-visible {
281
284
  text-decoration: none;
282
285
  }
283
286
 
284
- :host([icon-only]) .button:focus-visible::after {
287
+ :host([icon-only]) .button:focus-visible::after,
288
+ .button--loading:focus-visible::after {
285
289
  opacity: 1;
286
290
  }
287
291
 
@@ -307,6 +311,18 @@ let OhButton = class OhButton extends OhElement {
307
311
  to { transform: rotate(360deg); }
308
312
  }
309
313
 
314
+ .visually-hidden {
315
+ position: absolute;
316
+ width: 1px;
317
+ height: 1px;
318
+ padding: 0;
319
+ margin: -1px;
320
+ overflow: hidden;
321
+ clip: rect(0, 0, 0, 0);
322
+ white-space: nowrap;
323
+ border: 0;
324
+ }
325
+
310
326
  /* ═══════════════════════════════════════════════════════════════
311
327
  REDUCED MOTION
312
328
  ═══════════════════════════════════════════════════════════════ */
@@ -332,18 +348,18 @@ let OhButton = class OhButton extends OhElement {
332
348
 
333
349
  /* Primary - Forced Hover */
334
350
  :host([force-state="hover"]) .button--primary {
335
- background-color: var(--oh-color-brand-primary-hover);
336
- border-color: var(--oh-color-brand-primary-hover);
351
+ background-color: var(--oh-button-variant-primary-background-hover);
352
+ border-color: var(--oh-button-variant-primary-background-hover);
337
353
  transform: translate(-2px, -2px);
338
- box-shadow: 6px 6px 0 0 var(--oh-shadow-primary);
354
+ box-shadow: 6px 6px 0 0 var(--oh-button-variant-primary-shadow-color);
339
355
  }
340
356
 
341
357
  /* Primary - Forced Active */
342
358
  :host([force-state="active"]) .button--primary {
343
- background-color: var(--oh-color-brand-primary-active);
344
- border-color: var(--oh-color-brand-primary-active);
359
+ background-color: var(--oh-button-variant-primary-background-active);
360
+ border-color: var(--oh-button-variant-primary-background-active);
345
361
  transform: translate(2px, 2px);
346
- box-shadow: 1px 1px 0 0 var(--oh-shadow-primary);
362
+ box-shadow: 1px 1px 0 0 var(--oh-button-variant-primary-shadow-color);
347
363
  }
348
364
 
349
365
  /* Primary - Forced Focus */
@@ -351,21 +367,21 @@ let OhButton = class OhButton extends OhElement {
351
367
  outline: none;
352
368
  text-decoration: underline;
353
369
  text-underline-offset: var(--oh-spacing-1);
354
- box-shadow: 4px 4px 0 0 var(--oh-shadow-primary);
370
+ box-shadow: 4px 4px 0 0 var(--oh-button-variant-primary-shadow-color);
355
371
  }
356
372
 
357
373
  /* Secondary - Forced Hover */
358
374
  :host([force-state="hover"]) .button--secondary {
359
- background-color: var(--oh-color-surface-hover);
375
+ background-color: var(--oh-button-variant-secondary-background-hover);
360
376
  transform: translate(-2px, -2px);
361
- box-shadow: 6px 6px 0 0 var(--oh-shadow-secondary);
377
+ box-shadow: 6px 6px 0 0 var(--oh-button-variant-secondary-shadow-color);
362
378
  }
363
379
 
364
380
  /* Secondary - Forced Active */
365
381
  :host([force-state="active"]) .button--secondary {
366
- background-color: var(--oh-color-surface-active-pressed);
382
+ background-color: var(--oh-button-variant-secondary-background-active);
367
383
  transform: translate(2px, 2px);
368
- box-shadow: 1px 1px 0 0 var(--oh-shadow-secondary);
384
+ box-shadow: 1px 1px 0 0 var(--oh-button-variant-secondary-shadow-color);
369
385
  }
370
386
 
371
387
  /* Secondary - Forced Focus */
@@ -373,23 +389,23 @@ let OhButton = class OhButton extends OhElement {
373
389
  outline: none;
374
390
  text-decoration: underline;
375
391
  text-underline-offset: var(--oh-spacing-1);
376
- box-shadow: 4px 4px 0 0 var(--oh-shadow-secondary);
392
+ box-shadow: 4px 4px 0 0 var(--oh-button-variant-secondary-shadow-color);
377
393
  }
378
394
 
379
395
  /* Accent - Forced Hover */
380
396
  :host([force-state="hover"]) .button--accent {
381
- background-color: var(--oh-color-accent-hover);
382
- border-color: var(--oh-color-accent-hover);
397
+ background-color: var(--oh-button-variant-accent-background-hover);
398
+ border-color: var(--oh-button-variant-accent-background-hover);
383
399
  transform: translate(-2px, -2px);
384
- box-shadow: 6px 6px 0 0 var(--oh-shadow-accent);
400
+ box-shadow: 6px 6px 0 0 var(--oh-button-variant-accent-shadow-color);
385
401
  }
386
402
 
387
403
  /* Accent - Forced Active */
388
404
  :host([force-state="active"]) .button--accent {
389
- background-color: var(--oh-color-accent-active);
390
- border-color: var(--oh-color-accent-active);
405
+ background-color: var(--oh-button-variant-accent-background-active);
406
+ border-color: var(--oh-button-variant-accent-background-active);
391
407
  transform: translate(2px, 2px);
392
- box-shadow: 1px 1px 0 0 var(--oh-shadow-accent);
408
+ box-shadow: 1px 1px 0 0 var(--oh-button-variant-accent-shadow-color);
393
409
  }
394
410
 
395
411
  /* Accent - Forced Focus */
@@ -397,7 +413,7 @@ let OhButton = class OhButton extends OhElement {
397
413
  outline: none;
398
414
  text-decoration: underline;
399
415
  text-underline-offset: var(--oh-spacing-1);
400
- box-shadow: 4px 4px 0 0 var(--oh-shadow-accent);
416
+ box-shadow: 4px 4px 0 0 var(--oh-button-variant-accent-shadow-color);
401
417
  }
402
418
  `,
403
419
  ]; }
@@ -426,8 +442,13 @@ let OhButton = class OhButton extends OhElement {
426
442
  [`button--${this.size}`]: true,
427
443
  "button--loading": this.loading,
428
444
  });
445
+ // While loading, the label stays in the DOM (visually hidden) so the
446
+ // button keeps its accessible name.
429
447
  const content = this.loading
430
- ? html `<span class="spinner" aria-hidden="true"></span>`
448
+ ? html `
449
+ <span class="spinner" aria-hidden="true"></span>
450
+ <span class="visually-hidden"><slot></slot></span>
451
+ `
431
452
  : html `
432
453
  <slot name="icon-left"></slot>
433
454
  <slot></slot>
@@ -443,18 +464,23 @@ let OhButton = class OhButton extends OhElement {
443
464
  href=${this.href}
444
465
  target=${this.target || nothing}
445
466
  rel=${rel || nothing}
467
+ aria-label=${this.accessibleLabel || nothing}
446
468
  >
447
469
  ${content}
448
470
  </a>
449
471
  `;
450
472
  }
451
- // Render as button
473
+ // Render as button. Loading uses aria-disabled, not disabled: a disabled
474
+ // button drops out of the tab order, so pressing a button that starts
475
+ // loading would throw keyboard focus back to the page. _handleClick
476
+ // ignores clicks while loading.
452
477
  return html `
453
478
  <button
454
479
  part="button"
455
480
  class=${classes}
456
- ?disabled=${this.loading}
481
+ aria-disabled=${this.loading ? "true" : nothing}
457
482
  aria-busy=${this.loading ? "true" : nothing}
483
+ aria-label=${this.accessibleLabel || nothing}
458
484
  @click=${this._handleClick}
459
485
  >
460
486
  ${content}
@@ -474,6 +500,9 @@ __decorate([
474
500
  __decorate([
475
501
  property({ type: Boolean, reflect: true, attribute: "icon-only" })
476
502
  ], OhButton.prototype, "iconOnly", void 0);
503
+ __decorate([
504
+ property({ type: String, attribute: "accessible-label" })
505
+ ], OhButton.prototype, "accessibleLabel", void 0);
477
506
  __decorate([
478
507
  property({ type: String, reflect: true, attribute: "force-state" })
479
508
  ], OhButton.prototype, "forceState", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"oh-button.js","sourceRoot":"","sources":["../src/oh-button.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oh-button.js","sourceRoot":"","sources":["../src/oh-button.ts"],"names":[],"mappings":"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"}
package/dist/oh-card.js CHANGED
@@ -50,6 +50,8 @@ let OhCard = class OhCard extends OhElement {
50
50
 
51
51
  :host {
52
52
  display: block;
53
+ /* Card surfaces fade to linen, where text.link falls below 4.5:1 */
54
+ --oh-color-text-link: var(--oh-color-text-link-raised);
53
55
  }
54
56
 
55
57
  /* ═══════════════════════════════════════════════════════════════
@@ -59,7 +61,7 @@ let OhCard = class OhCard extends OhElement {
59
61
 
60
62
  .card {
61
63
  /* Shape: friendly rounded corners */
62
- border-radius: var(--oh-radius-lg);
64
+ border-radius: var(--oh-shape-large);
63
65
  overflow: hidden;
64
66
 
65
67
  transition:
@@ -77,13 +79,13 @@ let OhCard = class OhCard extends OhElement {
77
79
  /* Surface: subtle gradient for depth */
78
80
  background: linear-gradient(
79
81
  180deg,
80
- #FFFFFF 0%,
81
- #FAF7F2 40%,
82
- #F5F0E8 100%
82
+ var(--oh-card-raised-gradient-start) 0%,
83
+ var(--oh-card-raised-gradient-mid) 40%,
84
+ var(--oh-card-raised-gradient-end) 100%
83
85
  );
84
86
 
85
87
  /* Border: visible warm edge */
86
- border: 1px solid #E2D5C8;
88
+ border: 1px solid var(--oh-card-raised-border-color);
87
89
 
88
90
  /* Layered shadows:
89
91
  1. Outer: soft, offset shadow (tactile)
@@ -104,13 +106,13 @@ let OhCard = class OhCard extends OhElement {
104
106
  /* Surface: warm sunlit gradient */
105
107
  background: linear-gradient(
106
108
  180deg,
107
- #FFFBF5 0%,
108
- #FDF6EE 30%,
109
- #F8EFE4 100%
109
+ var(--oh-card-sunlit-gradient-start) 0%,
110
+ var(--oh-card-sunlit-gradient-mid) 30%,
111
+ var(--oh-card-sunlit-gradient-end) 100%
110
112
  );
111
113
 
112
114
  /* Border: warm tinted edge */
113
- border: 1px solid rgba(197, 67, 0, 0.2);
115
+ border: 1px solid var(--oh-card-sunlit-border-color);
114
116
 
115
117
  /* Layered shadows with warm glow */
116
118
  box-shadow:
@@ -129,12 +131,12 @@ let OhCard = class OhCard extends OhElement {
129
131
  /* Surface: subtle gradient */
130
132
  background: linear-gradient(
131
133
  180deg,
132
- #FAFAF8 0%,
133
- #F5F2EE 100%
134
+ var(--oh-card-flat-gradient-start) 0%,
135
+ var(--oh-card-flat-gradient-end) 100%
134
136
  );
135
137
 
136
138
  /* Border: visible edge */
137
- border: 1px solid #E2DCD2;
139
+ border: 1px solid var(--oh-card-flat-border-color);
138
140
 
139
141
  /* Minimal shadow */
140
142
  box-shadow:
@@ -144,7 +146,7 @@ let OhCard = class OhCard extends OhElement {
144
146
 
145
147
  /* ═══════════════════════════════════════════════════════════════
146
148
  INTERACTIVE STATES
147
- Hover lifts, focus shows warm glow
149
+ Hover lifts; focus is a solid outline, with a warm glow as decoration
148
150
  ═══════════════════════════════════════════════════════════════ */
149
151
 
150
152
  .card--interactive {
@@ -153,7 +155,7 @@ let OhCard = class OhCard extends OhElement {
153
155
 
154
156
  /* Hover: warm light, lifted */
155
157
  .card--interactive.card--raised:hover {
156
- border-color: var(--oh-color-warm-dune);
158
+ border-color: var(--oh-color-border-strong);
157
159
  box-shadow:
158
160
  0 4px 12px rgba(61, 50, 41, 0.1),
159
161
  0 12px 28px rgba(61, 50, 41, 0.08),
@@ -162,7 +164,7 @@ let OhCard = class OhCard extends OhElement {
162
164
  }
163
165
 
164
166
  .card--interactive.card--sunlit:hover {
165
- border-color: rgba(197, 67, 0, 0.35);
167
+ border-color: var(--oh-card-sunlit-border-color-hover);
166
168
  box-shadow:
167
169
  0 4px 12px rgba(139, 69, 19, 0.12),
168
170
  0 12px 32px rgba(139, 69, 19, 0.08),
@@ -172,7 +174,7 @@ let OhCard = class OhCard extends OhElement {
172
174
  }
173
175
 
174
176
  .card--interactive.card--flat:hover {
175
- border-color: var(--oh-color-warm-dune);
177
+ border-color: var(--oh-color-border-strong);
176
178
  box-shadow:
177
179
  0 2px 6px rgba(61, 50, 41, 0.08),
178
180
  0 6px 16px rgba(61, 50, 41, 0.05),
@@ -192,26 +194,24 @@ let OhCard = class OhCard extends OhElement {
192
194
  inset 0 1px 2px rgba(61, 50, 41, 0.04);
193
195
  }
194
196
 
195
- /* Focus: warm glow ring */
197
+ /* Focus: solid outline is the indicator; the glow is decoration only */
196
198
  .card--interactive:focus-visible {
197
- outline: none;
199
+ outline: var(--oh-focus-ring-width) solid var(--oh-focus-ring-color);
200
+ outline-offset: var(--oh-focus-ring-offset);
201
+ border-color: var(--oh-color-brand-primary);
198
202
  }
199
203
 
200
204
  .card--interactive.card--raised:focus-visible,
201
205
  .card--interactive.card--flat:focus-visible {
202
- border-color: var(--oh-color-brand-primary);
203
206
  box-shadow:
204
- 0 0 0 3px rgba(197, 67, 0, 0.25),
205
- 0 0 16px rgba(197, 67, 0, 0.1),
207
+ 0 0 16px var(--oh-focus-glow-color),
206
208
  0 2px 6px rgba(61, 50, 41, 0.08),
207
209
  inset 0 1px 0 rgba(255, 255, 255, 0.8);
208
210
  }
209
211
 
210
212
  .card--interactive.card--sunlit:focus-visible {
211
- border-color: rgba(197, 67, 0, 0.5);
212
213
  box-shadow:
213
- 0 0 0 3px rgba(197, 67, 0, 0.3),
214
- 0 0 20px rgba(197, 67, 0, 0.15),
214
+ 0 0 20px var(--oh-focus-glow-color),
215
215
  0 2px 8px rgba(139, 69, 19, 0.08),
216
216
  inset 0 1px 0 rgba(255, 255, 255, 0.9);
217
217
  }
@@ -230,11 +230,11 @@ let OhCard = class OhCard extends OhElement {
230
230
 
231
231
  .header {
232
232
  padding: var(--oh-spacing-4) var(--oh-spacing-5);
233
- border-bottom: 1px solid rgba(226, 213, 200, 0.6);
233
+ border-bottom: 1px solid var(--oh-card-section-divider-color);
234
234
  background: linear-gradient(
235
235
  180deg,
236
- rgba(255, 255, 255, 0.5) 0%,
237
- rgba(255, 255, 255, 0) 100%
236
+ var(--oh-card-section-header-gradient-start) 0%,
237
+ var(--oh-card-section-header-gradient-end) 100%
238
238
  );
239
239
  }
240
240
 
@@ -246,7 +246,7 @@ let OhCard = class OhCard extends OhElement {
246
246
 
247
247
  .footer {
248
248
  padding: var(--oh-spacing-4) var(--oh-spacing-5);
249
- border-top: 1px solid rgba(226, 213, 200, 0.6);
249
+ border-top: 1px solid var(--oh-card-section-divider-color);
250
250
  background: linear-gradient(
251
251
  180deg,
252
252
  var(--oh-color-surface-raised) 0%,
@@ -13,6 +13,7 @@
13
13
  *
14
14
  * @element oh-checkbox-group
15
15
  */
16
+ import { type PropertyValues } from "lit";
16
17
  import { OhElement } from "./base.js";
17
18
  export interface CheckboxOption {
18
19
  label: string;
@@ -29,6 +30,13 @@ export declare class OhCheckboxGroup extends OhElement {
29
30
  error: boolean;
30
31
  errorMessage: string;
31
32
  private _handleChange;
33
+ /**
34
+ * Errors that appear after first render (e.g. on submit) are announced via
35
+ * role="alert". Errors present on page load are only linked with
36
+ * aria-describedby, so they aren't read out unprompted.
37
+ */
38
+ private _announceError;
39
+ willUpdate(changed: PropertyValues): void;
32
40
  render(): import("lit").TemplateResult<1>;
33
41
  }
34
42
  declare global {
@@ -1 +1 @@
1
- {"version":3,"file":"oh-checkbox-group.d.ts","sourceRoot":"","sources":["../src/oh-checkbox-group.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAE,SAAS,EAAc,MAAM,WAAW,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBACa,eAAgB,SAAQ,SAAS;IAC5C,OAAgB,MAAM,4BAgMpB;IAGF,MAAM,SAAM;IAGZ,IAAI,SAAM;IAGV,OAAO,EAAE,cAAc,EAAE,CAAM;IAG/B,KAAK,EAAE,MAAM,EAAE,CAAM;IAGrB,QAAQ,UAAS;IAGjB,KAAK,UAAS;IAGd,YAAY,SAAM;IAElB,OAAO,CAAC,aAAa;IAYrB,MAAM;CA8CP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
1
+ {"version":3,"file":"oh-checkbox-group.d.ts","sourceRoot":"","sources":["../src/oh-checkbox-group.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAc,MAAM,WAAW,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBACa,eAAgB,SAAQ,SAAS;IAC5C,OAAgB,MAAM,4BAgMpB;IAGF,MAAM,SAAM;IAGZ,IAAI,SAAM;IAGV,OAAO,EAAE,cAAc,EAAE,CAAM;IAG/B,KAAK,EAAE,MAAM,EAAE,CAAM;IAGrB,QAAQ,UAAS;IAGjB,KAAK,UAAS;IAGd,YAAY,SAAM;IAElB,OAAO,CAAC,aAAa;IAYrB;;;;OAIG;IAEH,OAAO,CAAC,cAAc,CAAS;IAE/B,UAAU,CAAC,OAAO,EAAE,cAAc;IAMlC,MAAM;CA8CP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}