@orange-halo/components 2.1.0 → 3.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 (130) hide show
  1. package/custom-elements.json +968 -362
  2. package/dist/base.d.ts.map +1 -1
  3. package/dist/base.js +1 -2
  4. package/dist/base.js.map +1 -1
  5. package/dist/index.d.ts +4 -8
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -4
  8. package/dist/index.js.map +1 -1
  9. package/dist/oh-accordion.d.ts +53 -8
  10. package/dist/oh-accordion.d.ts.map +1 -1
  11. package/dist/oh-accordion.js +99 -29
  12. package/dist/oh-accordion.js.map +1 -1
  13. package/dist/oh-alert.d.ts +26 -8
  14. package/dist/oh-alert.d.ts.map +1 -1
  15. package/dist/oh-alert.js +96 -36
  16. package/dist/oh-alert.js.map +1 -1
  17. package/dist/oh-badge.d.ts +32 -13
  18. package/dist/oh-badge.d.ts.map +1 -1
  19. package/dist/oh-badge.js +38 -19
  20. package/dist/oh-badge.js.map +1 -1
  21. package/dist/oh-breadcrumb.d.ts +39 -12
  22. package/dist/oh-breadcrumb.d.ts.map +1 -1
  23. package/dist/oh-breadcrumb.js +66 -25
  24. package/dist/oh-breadcrumb.js.map +1 -1
  25. package/dist/oh-button.d.ts +49 -23
  26. package/dist/oh-button.d.ts.map +1 -1
  27. package/dist/oh-button.figma.js +1 -3
  28. package/dist/oh-button.figma.js.map +1 -1
  29. package/dist/oh-button.js +133 -82
  30. package/dist/oh-button.js.map +1 -1
  31. package/dist/oh-card.d.ts +47 -19
  32. package/dist/oh-card.d.ts.map +1 -1
  33. package/dist/oh-card.js +143 -96
  34. package/dist/oh-card.js.map +1 -1
  35. package/dist/oh-checkbox-group.d.ts +56 -12
  36. package/dist/oh-checkbox-group.d.ts.map +1 -1
  37. package/dist/oh-checkbox-group.figma.js +4 -6
  38. package/dist/oh-checkbox-group.figma.js.map +1 -1
  39. package/dist/oh-checkbox-group.js +114 -49
  40. package/dist/oh-checkbox-group.js.map +1 -1
  41. package/dist/oh-checkbox.d.ts +54 -17
  42. package/dist/oh-checkbox.d.ts.map +1 -1
  43. package/dist/oh-checkbox.js +117 -60
  44. package/dist/oh-checkbox.js.map +1 -1
  45. package/dist/oh-cluster.d.ts +19 -14
  46. package/dist/oh-cluster.d.ts.map +1 -1
  47. package/dist/oh-cluster.js +19 -19
  48. package/dist/oh-cluster.js.map +1 -1
  49. package/dist/oh-container.d.ts +19 -16
  50. package/dist/oh-container.d.ts.map +1 -1
  51. package/dist/oh-container.js +21 -23
  52. package/dist/oh-container.js.map +1 -1
  53. package/dist/oh-drawer.d.ts +28 -11
  54. package/dist/oh-drawer.d.ts.map +1 -1
  55. package/dist/oh-drawer.js +52 -24
  56. package/dist/oh-drawer.js.map +1 -1
  57. package/dist/oh-footer.d.ts +37 -18
  58. package/dist/oh-footer.d.ts.map +1 -1
  59. package/dist/oh-footer.js +38 -19
  60. package/dist/oh-footer.js.map +1 -1
  61. package/dist/oh-grid.d.ts +27 -14
  62. package/dist/oh-grid.d.ts.map +1 -1
  63. package/dist/oh-grid.js +28 -21
  64. package/dist/oh-grid.js.map +1 -1
  65. package/dist/oh-icon.d.ts +21 -5
  66. package/dist/oh-icon.d.ts.map +1 -1
  67. package/dist/oh-icon.js +27 -9
  68. package/dist/oh-icon.js.map +1 -1
  69. package/dist/oh-input.d.ts +110 -21
  70. package/dist/oh-input.d.ts.map +1 -1
  71. package/dist/oh-input.figma.js +2 -2
  72. package/dist/oh-input.figma.js.map +1 -1
  73. package/dist/oh-input.js +227 -71
  74. package/dist/oh-input.js.map +1 -1
  75. package/dist/oh-link.d.ts +42 -19
  76. package/dist/oh-link.d.ts.map +1 -1
  77. package/dist/oh-link.js +83 -38
  78. package/dist/oh-link.js.map +1 -1
  79. package/dist/oh-modal.d.ts +35 -6
  80. package/dist/oh-modal.d.ts.map +1 -1
  81. package/dist/oh-modal.js +90 -39
  82. package/dist/oh-modal.js.map +1 -1
  83. package/dist/oh-navbar.d.ts +42 -19
  84. package/dist/oh-navbar.d.ts.map +1 -1
  85. package/dist/oh-navbar.js +44 -20
  86. package/dist/oh-navbar.js.map +1 -1
  87. package/dist/oh-progress.d.ts +26 -7
  88. package/dist/oh-progress.d.ts.map +1 -1
  89. package/dist/oh-progress.js +35 -14
  90. package/dist/oh-progress.js.map +1 -1
  91. package/dist/oh-radio-group.d.ts +55 -13
  92. package/dist/oh-radio-group.d.ts.map +1 -1
  93. package/dist/oh-radio-group.figma.js +2 -2
  94. package/dist/oh-radio-group.figma.js.map +1 -1
  95. package/dist/oh-radio-group.js +122 -51
  96. package/dist/oh-radio-group.js.map +1 -1
  97. package/dist/oh-radio.d.ts +55 -17
  98. package/dist/oh-radio.d.ts.map +1 -1
  99. package/dist/oh-radio.js +120 -61
  100. package/dist/oh-radio.js.map +1 -1
  101. package/dist/oh-select.d.ts +59 -16
  102. package/dist/oh-select.d.ts.map +1 -1
  103. package/dist/oh-select.js +141 -69
  104. package/dist/oh-select.js.map +1 -1
  105. package/dist/oh-skip-link.d.ts +33 -15
  106. package/dist/oh-skip-link.d.ts.map +1 -1
  107. package/dist/oh-skip-link.js +43 -32
  108. package/dist/oh-skip-link.js.map +1 -1
  109. package/dist/oh-stack.d.ts +17 -14
  110. package/dist/oh-stack.d.ts.map +1 -1
  111. package/dist/oh-stack.js +18 -20
  112. package/dist/oh-stack.js.map +1 -1
  113. package/dist/oh-tabs.d.ts +55 -30
  114. package/dist/oh-tabs.d.ts.map +1 -1
  115. package/dist/oh-tabs.js +100 -76
  116. package/dist/oh-tabs.js.map +1 -1
  117. package/dist/oh-textarea.d.ts +129 -0
  118. package/dist/oh-textarea.d.ts.map +1 -0
  119. package/dist/oh-textarea.js +401 -0
  120. package/dist/oh-textarea.js.map +1 -0
  121. package/dist/oh-toggle.d.ts +45 -12
  122. package/dist/oh-toggle.d.ts.map +1 -1
  123. package/dist/oh-toggle.js +84 -34
  124. package/dist/oh-toggle.js.map +1 -1
  125. package/dist/styles/typography.js +1 -1
  126. package/package.json +7 -7
  127. package/dist/oh-hero.d.ts +0 -33
  128. package/dist/oh-hero.d.ts.map +0 -1
  129. package/dist/oh-hero.js +0 -246
  130. package/dist/oh-hero.js.map +0 -1
package/dist/oh-button.js CHANGED
@@ -1,32 +1,23 @@
1
1
  /**
2
2
  * oh-button
3
3
  *
4
- * A chunky, confident button with playful personality.
5
- * Inspired by hand-crafted, illustrative UI — not corporate SaaS.
6
- *
7
4
  * DESIGN DECISIONS:
8
5
  * ─────────────────
9
- * 1. CHUNKY & CONFIDENT
10
- * - Thick border (stroke.control) that feels illustrative
11
- * - Solid fills, no subtle gradients
12
- * - Generous padding, substantial presence
13
- *
14
- * 2. OFFSET SHADOW (STICKER EFFECT)
15
- * - Shadow offset to bottom-right
16
- * - Feels like a physical sticker or stamp
17
- * - Not a generic centered drop shadow
18
- *
19
- * 3. PLAYFUL INTERACTIONS
20
- * - Hover: slight upward lift + shadow grows
21
- * - Active: pressed down, shadow shrinks (stamp effect)
22
- * - Focus: warm glow + accessible underline
23
- *
24
- * 4. HAND-CRAFTED FEEL
25
- * - Bold, defined edges
26
- * - Confident color choices
27
- * - Personality over polish
28
- *
29
- * @element oh-button
6
+ * 1. Renders a native <button>, or an <a> when `href` is set, inside the
7
+ * shadow root, so keyboard and screen reader behaviour come from the
8
+ * platform. `accessible-label` is forwarded to it (an aria-label on the
9
+ * host isn't).
10
+ * 2. Look comes from button.* component tokens: button.base.borderWidth
11
+ * (stroke.control), button.base.borderRadius (shape.control),
12
+ * button.variant.<variant>.* for fills, text, border and shadow colour,
13
+ * button.size.<size>.* for type, padding and height.
14
+ * 3. Hover and active move the button by lift.hoverMd / lift.pressMd and set
15
+ * the shadow offset to elevation.offset.2xl / elevation.offset.xs (rest is
16
+ * elevation.offset.lg).
17
+ * 4. Focus is a solid underline on the label (an underline the button draws
18
+ * itself for icon-only and loading buttons, whose text is hidden).
19
+ * 5. Loading uses aria-disabled + aria-busy, not disabled, so focus stays on
20
+ * the button.
30
21
  */
31
22
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
32
23
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -37,6 +28,41 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
37
28
  import { html, css, nothing } from "lit";
38
29
  import { customElement, property } from "lit/decorators.js";
39
30
  import { OhElement, baseStyles } from "./base.js";
31
+ /**
32
+ * A button that starts an action, or a link styled as a button when `href` is set.
33
+ *
34
+ * **Use it for** actions: submitting, saving, opening a dialog, confirming.
35
+ * **Don't use it for** links inside running text (use `oh-link`).
36
+ *
37
+ * **Variants:** `primary` for the main action, `secondary` for the others,
38
+ * `accent` for an action that takes the accent colour role. **Sizes:** `sm`, `md` (default), `lg`.
39
+ * **States:** rest, hover, active, focus and `loading`.
40
+ *
41
+ * **Behaviour:** fires `oh-click` when the inner `<button>` is clicked, except
42
+ * while `loading`. `loading` shows a spinner, keeps the label for screen
43
+ * readers, sets `aria-busy` and `aria-disabled` and ignores clicks, while the
44
+ * button stays focusable. With `href` it renders an `<a>` (and
45
+ * `target="_blank"` adds `rel="noopener noreferrer"`); link buttons don't fire
46
+ * `oh-click`. It has no `disabled` property and doesn't submit a form by
47
+ * itself: handle `oh-click`. Under `prefers-reduced-motion` it doesn't move.
48
+ *
49
+ * **Accessibility:** focus shows a solid underline on the label. An
50
+ * `icon-only` button has no visible text, so always set `accessible-label`
51
+ * (not `aria-label`, which isn't forwarded into the shadow root).
52
+ *
53
+ * **Look:** set by tokens — `stroke.control` (border width), `shape.control`
54
+ * (corners), `typography.control.*` (type), `button.variant.<variant>.*`
55
+ * (background, text, border and shadow colour per state), `button.size.<size>.*`
56
+ * (font size, padding, minimum height), `elevation.offset.*` (shadow offset)
57
+ * and `lift.hoverMd` / `lift.pressMd` (movement on hover and press).
58
+ *
59
+ * @element oh-button
60
+ * @fires oh-click - The button was clicked (not while loading). `detail.originalEvent` is the click.
61
+ * @slot - The label.
62
+ * @slot icon-left - An icon before the label.
63
+ * @slot icon-right - An icon after the label.
64
+ * @csspart button - The inner `<button>` or `<a>`.
65
+ */
40
66
  let OhButton = class OhButton extends OhElement {
41
67
  constructor() {
42
68
  super(...arguments);
@@ -53,128 +79,133 @@ let OhButton = class OhButton extends OhElement {
53
79
  static { this.styles = [
54
80
  baseStyles,
55
81
  css `
56
- /* ═══════════════════════════════════════════════════════════════
57
- ORANGE HALO BUTTON
58
- Chunky • Playful • Confident • Hand-crafted
59
- ═══════════════════════════════════════════════════════════════ */
60
-
61
82
  :host {
62
83
  display: inline-block;
63
84
  }
64
85
 
65
86
  .button {
66
- /* Typography: friendly, not shouty */
87
+ /* Typography: button.base.* (from typography.control.*) */
67
88
  font-family: var(--oh-button-base-font-family);
68
89
  font-weight: var(--oh-button-base-font-weight);
69
90
  letter-spacing: var(--oh-button-base-letter-spacing);
70
91
  text-decoration: none;
71
-
92
+
72
93
  /* Layout */
73
94
  display: inline-flex;
74
95
  align-items: center;
75
96
  justify-content: center;
76
97
  gap: var(--oh-spacing-2);
77
-
78
- /* Shape: chunky rounded corners, not pills */
98
+
99
+ /* Corners: button.base.borderRadius (shape.control) */
79
100
  border-radius: var(--oh-button-base-border-radius);
80
-
81
- /* Thick illustrative border */
101
+
102
+ /* Border width: button.base.borderWidth (stroke.control) */
82
103
  border: var(--oh-button-base-border-width) solid;
83
-
104
+
84
105
  /* Remove default button styles */
85
106
  cursor: pointer;
86
107
  -webkit-appearance: none;
87
108
  -moz-appearance: none;
88
109
  appearance: none;
89
-
90
- /* Smooth but snappy transitions */
91
- transition:
92
- transform var(--oh-motion-snappy) var(--oh-motion-ease-playful),
93
- box-shadow var(--oh-motion-snappy) var(--oh-motion-ease-playful),
110
+
111
+ /* Transitions: motion.snappy / motion.quick */
112
+ transition:
113
+ transform var(--oh-motion-snappy) var(--oh-motion-ease-emphasized),
114
+ box-shadow var(--oh-motion-snappy) var(--oh-motion-ease-emphasized),
94
115
  background-color var(--oh-motion-quick) ease;
95
116
  }
96
117
 
97
118
  /* ═══════════════════════════════════════════════════════════════
98
119
  PRIMARY VARIANT
99
- Signature orange — bold and warm
100
- Filled button: color + shadow define shape (no visible border)
101
- Contrast: white on brand primary = 5.0:1 ✓ (WCAG AA)
120
+ Filled: button.variant.primary.* (border matches the fill)
102
121
  ═══════════════════════════════════════════════════════════════ */
103
122
 
104
123
  .button--primary {
105
124
  background-color: var(--oh-button-variant-primary-background);
106
125
  border-color: var(--oh-button-variant-primary-border-color);
107
126
  color: var(--oh-button-variant-primary-color);
108
-
109
- /* Light offset shadow: makes button pop forward */
110
- box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg) 0 0 var(--oh-button-variant-primary-shadow-color);
127
+
128
+ /* Offset shadow: elevation.offset.lg at rest */
129
+ box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
130
+ 0 0 var(--oh-button-variant-primary-shadow-color);
111
131
  }
112
132
 
113
133
  .button--primary:hover {
114
134
  background-color: var(--oh-button-variant-primary-background-hover);
115
135
  border-color: var(--oh-button-variant-primary-background-hover);
116
136
  transform: translate(var(--oh-lift-hover-md), var(--oh-lift-hover-md));
117
- box-shadow: var(--oh-elevation-offset-2xl) var(--oh-elevation-offset-2xl) 0 0 var(--oh-button-variant-primary-shadow-color);
137
+ box-shadow: var(--oh-elevation-offset-2xl)
138
+ var(--oh-elevation-offset-2xl) 0 0
139
+ var(--oh-button-variant-primary-shadow-color);
118
140
  }
119
141
 
120
142
  .button--primary:active {
121
143
  background-color: var(--oh-button-variant-primary-background-active);
122
144
  border-color: var(--oh-button-variant-primary-background-active);
123
145
  transform: translate(var(--oh-lift-press-md), var(--oh-lift-press-md));
124
- box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs) 0 0 var(--oh-button-variant-primary-shadow-color);
146
+ box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
147
+ 0 0 var(--oh-button-variant-primary-shadow-color);
125
148
  }
126
149
 
127
150
  /* ═══════════════════════════════════════════════════════════════
128
151
  SECONDARY VARIANT
129
- Light button: NEEDS visible border for definition
152
+ button.variant.secondary.*: its border (borderColor) defines the
153
+ button's edge against the page, so it must stay visible
130
154
  ═══════════════════════════════════════════════════════════════ */
131
155
 
132
156
  .button--secondary {
133
157
  background-color: var(--oh-button-variant-secondary-background);
134
158
  border-color: var(--oh-button-variant-secondary-border-color);
135
159
  color: var(--oh-button-variant-secondary-color);
136
-
137
- box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg) 0 0 var(--oh-button-variant-secondary-shadow-color);
160
+
161
+ box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
162
+ 0 0 var(--oh-button-variant-secondary-shadow-color);
138
163
  }
139
164
 
140
165
  .button--secondary:hover {
141
166
  background-color: var(--oh-button-variant-secondary-background-hover);
142
167
  transform: translate(var(--oh-lift-hover-md), var(--oh-lift-hover-md));
143
- box-shadow: var(--oh-elevation-offset-2xl) var(--oh-elevation-offset-2xl) 0 0 var(--oh-button-variant-secondary-shadow-color);
168
+ box-shadow: var(--oh-elevation-offset-2xl)
169
+ var(--oh-elevation-offset-2xl) 0 0
170
+ var(--oh-button-variant-secondary-shadow-color);
144
171
  }
145
172
 
146
173
  .button--secondary:active {
147
174
  background-color: var(--oh-button-variant-secondary-background-active);
148
175
  transform: translate(var(--oh-lift-press-md), var(--oh-lift-press-md));
149
- box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs) 0 0 var(--oh-button-variant-secondary-shadow-color);
176
+ box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
177
+ 0 0 var(--oh-button-variant-secondary-shadow-color);
150
178
  }
151
179
 
152
180
  /* ═══════════════════════════════════════════════════════════════
153
181
  ACCENT VARIANT
154
- Calm blue — modern counterbalance to warm orange
155
- Filled button: color + shadow define shape (no visible border)
182
+ Filled: button.variant.accent.* (border matches the fill)
156
183
  ═══════════════════════════════════════════════════════════════ */
157
184
 
158
185
  .button--accent {
159
186
  background-color: var(--oh-button-variant-accent-background);
160
187
  border-color: var(--oh-button-variant-accent-border-color);
161
188
  color: var(--oh-button-variant-accent-color);
162
-
163
- box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg) 0 0 var(--oh-button-variant-accent-shadow-color);
189
+
190
+ box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
191
+ 0 0 var(--oh-button-variant-accent-shadow-color);
164
192
  }
165
193
 
166
194
  .button--accent:hover {
167
195
  background-color: var(--oh-button-variant-accent-background-hover);
168
196
  border-color: var(--oh-button-variant-accent-background-hover);
169
197
  transform: translate(var(--oh-lift-hover-md), var(--oh-lift-hover-md));
170
- box-shadow: var(--oh-elevation-offset-2xl) var(--oh-elevation-offset-2xl) 0 0 var(--oh-button-variant-accent-shadow-color);
198
+ box-shadow: var(--oh-elevation-offset-2xl)
199
+ var(--oh-elevation-offset-2xl) 0 0
200
+ var(--oh-button-variant-accent-shadow-color);
171
201
  }
172
202
 
173
203
  .button--accent:active {
174
204
  background-color: var(--oh-button-variant-accent-background-active);
175
205
  border-color: var(--oh-button-variant-accent-background-active);
176
206
  transform: translate(var(--oh-lift-press-md), var(--oh-lift-press-md));
177
- box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs) 0 0 var(--oh-button-variant-accent-shadow-color);
207
+ box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
208
+ 0 0 var(--oh-button-variant-accent-shadow-color);
178
209
  }
179
210
 
180
211
  /* ═══════════════════════════════════════════════════════════════
@@ -189,40 +220,46 @@ let OhButton = class OhButton extends OhElement {
189
220
  }
190
221
 
191
222
  .button--primary:focus-visible {
192
- box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg) 0 0 var(--oh-button-variant-primary-shadow-color);
223
+ box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
224
+ 0 0 var(--oh-button-variant-primary-shadow-color);
193
225
  }
194
226
 
195
227
  .button--secondary:focus-visible {
196
- box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg) 0 0 var(--oh-button-variant-secondary-shadow-color);
228
+ box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
229
+ 0 0 var(--oh-button-variant-secondary-shadow-color);
197
230
  }
198
231
 
199
232
  .button--accent:focus-visible {
200
- box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg) 0 0 var(--oh-button-variant-accent-shadow-color);
233
+ box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
234
+ 0 0 var(--oh-button-variant-accent-shadow-color);
201
235
  }
202
236
 
203
237
  /* ═══════════════════════════════════════════════════════════════
204
238
  SIZE VARIANTS
205
- Minimum 16px (1rem) for WCAG readability
206
- Values: button.size.* tokens
239
+ Values: button.size.* tokens. Font sizes come from
240
+ typography.control.fontSize.*, never below font.size.base
207
241
  ═══════════════════════════════════════════════════════════════ */
208
242
 
209
243
  .button--sm {
210
244
  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);
245
+ padding: var(--oh-button-size-sm-padding-y)
246
+ var(--oh-button-size-sm-padding-x);
212
247
  min-height: var(--oh-button-size-sm-min-height);
213
248
  gap: var(--oh-button-size-sm-gap);
214
249
  }
215
250
 
216
251
  .button--md {
217
252
  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);
253
+ padding: var(--oh-button-size-md-padding-y)
254
+ var(--oh-button-size-md-padding-x);
219
255
  min-height: var(--oh-button-size-md-min-height);
220
256
  gap: var(--oh-button-size-md-gap);
221
257
  }
222
258
 
223
259
  .button--lg {
224
260
  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);
261
+ padding: var(--oh-button-size-lg-padding-y)
262
+ var(--oh-button-size-lg-padding-x);
226
263
  min-height: var(--oh-button-size-lg-min-height);
227
264
  gap: var(--oh-button-size-lg-gap);
228
265
  }
@@ -268,7 +305,7 @@ let OhButton = class OhButton extends OhElement {
268
305
 
269
306
  :host([icon-only]) .button::after,
270
307
  .button--loading::after {
271
- content: '';
308
+ content: "";
272
309
  position: absolute;
273
310
  bottom: 4px;
274
311
  left: 50%;
@@ -308,7 +345,9 @@ let OhButton = class OhButton extends OhElement {
308
345
  }
309
346
 
310
347
  @keyframes spin {
311
- to { transform: rotate(360deg); }
348
+ to {
349
+ transform: rotate(360deg);
350
+ }
312
351
  }
313
352
 
314
353
  .visually-hidden {
@@ -331,7 +370,7 @@ let OhButton = class OhButton extends OhElement {
331
370
  .button {
332
371
  transition-duration: 0.01ms !important;
333
372
  }
334
-
373
+
335
374
  .button:hover,
336
375
  .button:active {
337
376
  transform: none !important;
@@ -351,7 +390,9 @@ let OhButton = class OhButton extends OhElement {
351
390
  background-color: var(--oh-button-variant-primary-background-hover);
352
391
  border-color: var(--oh-button-variant-primary-background-hover);
353
392
  transform: translate(var(--oh-lift-hover-md), var(--oh-lift-hover-md));
354
- box-shadow: var(--oh-elevation-offset-2xl) var(--oh-elevation-offset-2xl) 0 0 var(--oh-button-variant-primary-shadow-color);
393
+ box-shadow: var(--oh-elevation-offset-2xl)
394
+ var(--oh-elevation-offset-2xl) 0 0
395
+ var(--oh-button-variant-primary-shadow-color);
355
396
  }
356
397
 
357
398
  /* Primary - Forced Active */
@@ -359,7 +400,8 @@ let OhButton = class OhButton extends OhElement {
359
400
  background-color: var(--oh-button-variant-primary-background-active);
360
401
  border-color: var(--oh-button-variant-primary-background-active);
361
402
  transform: translate(var(--oh-lift-press-md), var(--oh-lift-press-md));
362
- box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs) 0 0 var(--oh-button-variant-primary-shadow-color);
403
+ box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
404
+ 0 0 var(--oh-button-variant-primary-shadow-color);
363
405
  }
364
406
 
365
407
  /* Primary - Forced Focus */
@@ -367,21 +409,25 @@ let OhButton = class OhButton extends OhElement {
367
409
  outline: none;
368
410
  text-decoration: underline;
369
411
  text-underline-offset: var(--oh-spacing-1);
370
- box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg) 0 0 var(--oh-button-variant-primary-shadow-color);
412
+ box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
413
+ 0 0 var(--oh-button-variant-primary-shadow-color);
371
414
  }
372
415
 
373
416
  /* Secondary - Forced Hover */
374
417
  :host([force-state="hover"]) .button--secondary {
375
418
  background-color: var(--oh-button-variant-secondary-background-hover);
376
419
  transform: translate(var(--oh-lift-hover-md), var(--oh-lift-hover-md));
377
- box-shadow: var(--oh-elevation-offset-2xl) var(--oh-elevation-offset-2xl) 0 0 var(--oh-button-variant-secondary-shadow-color);
420
+ box-shadow: var(--oh-elevation-offset-2xl)
421
+ var(--oh-elevation-offset-2xl) 0 0
422
+ var(--oh-button-variant-secondary-shadow-color);
378
423
  }
379
424
 
380
425
  /* Secondary - Forced Active */
381
426
  :host([force-state="active"]) .button--secondary {
382
427
  background-color: var(--oh-button-variant-secondary-background-active);
383
428
  transform: translate(var(--oh-lift-press-md), var(--oh-lift-press-md));
384
- box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs) 0 0 var(--oh-button-variant-secondary-shadow-color);
429
+ box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
430
+ 0 0 var(--oh-button-variant-secondary-shadow-color);
385
431
  }
386
432
 
387
433
  /* Secondary - Forced Focus */
@@ -389,7 +435,8 @@ let OhButton = class OhButton extends OhElement {
389
435
  outline: none;
390
436
  text-decoration: underline;
391
437
  text-underline-offset: var(--oh-spacing-1);
392
- box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg) 0 0 var(--oh-button-variant-secondary-shadow-color);
438
+ box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
439
+ 0 0 var(--oh-button-variant-secondary-shadow-color);
393
440
  }
394
441
 
395
442
  /* Accent - Forced Hover */
@@ -397,7 +444,9 @@ let OhButton = class OhButton extends OhElement {
397
444
  background-color: var(--oh-button-variant-accent-background-hover);
398
445
  border-color: var(--oh-button-variant-accent-background-hover);
399
446
  transform: translate(var(--oh-lift-hover-md), var(--oh-lift-hover-md));
400
- box-shadow: var(--oh-elevation-offset-2xl) var(--oh-elevation-offset-2xl) 0 0 var(--oh-button-variant-accent-shadow-color);
447
+ box-shadow: var(--oh-elevation-offset-2xl)
448
+ var(--oh-elevation-offset-2xl) 0 0
449
+ var(--oh-button-variant-accent-shadow-color);
401
450
  }
402
451
 
403
452
  /* Accent - Forced Active */
@@ -405,7 +454,8 @@ let OhButton = class OhButton extends OhElement {
405
454
  background-color: var(--oh-button-variant-accent-background-active);
406
455
  border-color: var(--oh-button-variant-accent-background-active);
407
456
  transform: translate(var(--oh-lift-press-md), var(--oh-lift-press-md));
408
- box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs) 0 0 var(--oh-button-variant-accent-shadow-color);
457
+ box-shadow: var(--oh-elevation-offset-xs) var(--oh-elevation-offset-xs)
458
+ 0 0 var(--oh-button-variant-accent-shadow-color);
409
459
  }
410
460
 
411
461
  /* Accent - Forced Focus */
@@ -413,7 +463,8 @@ let OhButton = class OhButton extends OhElement {
413
463
  outline: none;
414
464
  text-decoration: underline;
415
465
  text-underline-offset: var(--oh-spacing-1);
416
- box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg) 0 0 var(--oh-button-variant-accent-shadow-color);
466
+ box-shadow: var(--oh-elevation-offset-lg) var(--oh-elevation-offset-lg)
467
+ 0 0 var(--oh-button-variant-accent-shadow-color);
417
468
  }
418
469
  `,
419
470
  ]; }
@@ -427,12 +478,12 @@ let OhButton = class OhButton extends OhElement {
427
478
  }
428
479
  /** Focus the internal button/anchor element */
429
480
  focus(options) {
430
- const inner = this.shadowRoot?.querySelector('.button');
481
+ const inner = this.shadowRoot?.querySelector(".button");
431
482
  inner?.focus(options);
432
483
  }
433
484
  /** Blur the internal button/anchor element */
434
485
  blur() {
435
- const inner = this.shadowRoot?.querySelector('.button');
486
+ const inner = this.shadowRoot?.querySelector(".button");
436
487
  inner?.blur();
437
488
  }
438
489
  render() {
@@ -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.d.ts CHANGED
@@ -1,37 +1,65 @@
1
1
  /**
2
2
  * oh-card
3
3
  *
4
- * A tactile, raised surface with visible frame.
5
- * Designed with the same layered construction as oh-button.
4
+ * A surface that groups related content, with optional header and footer.
6
5
  *
7
6
  * DESIGN DECISIONS:
8
7
  * ─────────────────
9
- * 1. LAYERED CONSTRUCTION
10
- * - Surface: subtle gradient for depth
11
- * - Border: visible warm edge
12
- * - Inner highlight: sunlit top edge
13
- * - Outer shadow: soft, slightly offset
14
- *
15
- * 2. RETRO-MODERN DETAILS
16
- * - Warm, tactile shadows (never harsh)
17
- * - Visible border that warms on hover
18
- * - Subtle gradient background
19
- *
20
- * 3. VARIANTS
21
- * - Raised: default with layered depth
22
- * - Sunlit: featured with warm gradient
23
- * - Flat: border-only, minimal shadow
8
+ * 1. THREE PARTS: header, content and footer are separate parts so each can
9
+ * be styled.
24
10
  *
25
- * @element oh-card
11
+ * 2. VARIANTS BY ROLE, LOOK FROM TOKENS
12
+ * - default, featured (the one card that should stand out), subtle (quieter)
13
+ * - Each variant's surface, border and shadow come from its own
14
+ * card.variant.<variant>.* tokens and an elevation.surface.* token, so a brand
15
+ * changes the look without touching this file.
16
+ *
17
+ * 3. INTERACTIVE MODE: role="button" on the inner card, Enter/Space and
18
+ * click fire oh-click. Focus is a solid focus.ring* outline; any
19
+ * focus.glowColor shadow is decoration only.
20
+ *
21
+ * 4. CONTRAST: card surfaces remap color.text.link to color.text.linkRaised
22
+ * so links inside keep 4.5:1.
26
23
  */
27
24
  import { OhElement } from "./base.js";
28
- export type CardVariant = "raised" | "sunlit" | "flat";
25
+ export type CardVariant = "default" | "featured" | "subtle";
29
26
  export type CardPadding = "none" | "sm" | "md" | "lg";
27
+ /**
28
+ * A surface that groups related content (a summary, a teaser, a settings group), with optional header and footer.
29
+ *
30
+ * **Use it for** a self-contained block of content among others, or a whole-card link to more detail (`interactive`). **Don't use it for** page layout or spacing alone (use `oh-stack`, `oh-grid`); for a message that needs attention (use `oh-alert`); or for a single action (use `oh-button`).
31
+ *
32
+ * **Variants:** `default`, the standard card; `featured`, for the one card that should stand out; `subtle`, a quieter card, for dense layouts. **Padding:** `none`, `sm`, `md` (default), `lg` set the content padding (and the header and footer padding to match). With `none`, the content sets its own padding.
33
+ *
34
+ * **States (interactive only):** rest, hover, active (pressed) and focus-visible.
35
+ *
36
+ * **Behaviour:** with `interactive`, the card is focusable (`tabindex="0"`), has `role="button"`, and fires `oh-click` on click, Enter or Space. Hover movement is turned off under `prefers-reduced-motion`.
37
+ *
38
+ * **Accessibility:** focus shows a solid outline (`focus.ringWidth`, `focus.ringColor`, `focus.ringOffset`). Links inside use `color.text.linkRaised`, which keeps contrast on card surfaces. An interactive card is one button: give it a short heading so its accessible name makes sense, and don't put other buttons or links inside it.
39
+ *
40
+ * **Look:** set by tokens. `card.variant.<variant>.gradientStart`/`gradientMid`/`gradientEnd` set each variant's surface, `card.variant.<variant>.borderColor` and `card.base.borderWidth` its border, `shape.large` the corners, and `elevation.surface.default`/`subtle`/`featured` its shadow. Hover uses `color.border.strong` (or `card.variant.featured.borderColorHover`), `elevation.surface.hover`/`featuredHover` and `lift.hoverMd`/`lift.hoverSm`; active uses `elevation.surface.active`; focus sets the border to `color.brand.primary` and adds `focus.glowColor` with `elevation.surface.focus`/`featuredFocus`. Header and footer dividers use `card.section.dividerColor` and `stroke.divider`; the header surface uses `card.section.headerGradientStart`/`End`, the footer `color.surface.raised` to `color.surface.inset`; motion uses `motion.gentle` and `motion.easeGentle`.
41
+ *
42
+ * @element oh-card
43
+ * @slot - The card's main content.
44
+ * @slot header - Optional header, above the content, with a divider below. Not drawn when nothing is slotted.
45
+ * @slot footer - Optional footer, below the content, with a divider above (e.g. actions). Not drawn when nothing is slotted.
46
+ * @csspart card - The card surface (the button when `interactive`).
47
+ * @csspart header - The header wrapper.
48
+ * @csspart content - The content wrapper.
49
+ * @csspart footer - The footer wrapper.
50
+ * @fires oh-click - When an `interactive` card is clicked or activated with Enter or Space. `detail.originalEvent` holds the source event.
51
+ */
30
52
  export declare class OhCard extends OhElement {
31
53
  static styles: import("lit").CSSResult[];
32
54
  variant: CardVariant;
33
55
  interactive: boolean;
34
56
  padding: CardPadding;
57
+ private _hasHeader;
58
+ private _hasFooter;
59
+ /** True when the slot holds an element or non-whitespace text */
60
+ private _slotHasContent;
61
+ private _onHeaderSlotChange;
62
+ private _onFooterSlotChange;
35
63
  private _handleClick;
36
64
  private _handleKeyDown;
37
65
  render(): import("lit").TemplateResult<1>;
@@ -1 +1 @@
1
- {"version":3,"file":"oh-card.d.ts","sourceRoot":"","sources":["../src/oh-card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,EAAE,SAAS,EAAc,MAAM,WAAW,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AACvD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtD,qBACa,MAAO,SAAQ,SAAS;IACnC,OAAgB,MAAM,4BAqNpB;IAGF,OAAO,EAAE,WAAW,CAAY;IAGhC,WAAW,UAAS;IAGpB,OAAO,EAAE,WAAW,CAAQ;IAE5B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,cAAc;IAOtB,MAAM;CA+BP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}
1
+ {"version":3,"file":"oh-card.d.ts","sourceRoot":"","sources":["../src/oh-card.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EAAE,SAAS,EAAc,MAAM,WAAW,CAAC;AAElD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;AAC5D,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBACa,MAAO,SAAQ,SAAS;IACnC,OAAgB,MAAM,4BAyNpB;IAGF,OAAO,EAAE,WAAW,CAAa;IAGjC,WAAW,UAAS;IAGpB,OAAO,EAAE,WAAW,CAAQ;IAEnB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAS;IAEpC,iEAAiE;IACjE,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,cAAc;IAOtB,MAAM;CA+BP;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,MAAM,CAAC;KACnB;CACF"}