@fpkit/acss 1.0.0-beta.1 → 1.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 (43) hide show
  1. package/README.md +32 -0
  2. package/docs/README.md +325 -0
  3. package/docs/guides/accessibility.md +764 -0
  4. package/docs/guides/architecture.md +705 -0
  5. package/docs/guides/composition.md +688 -0
  6. package/docs/guides/css-variables.md +522 -0
  7. package/docs/guides/storybook.md +828 -0
  8. package/docs/guides/testing.md +817 -0
  9. package/docs/testing/focus-indicator-testing.md +437 -0
  10. package/libs/components/buttons/button.css +1 -1
  11. package/libs/components/buttons/button.css.map +1 -1
  12. package/libs/components/buttons/button.min.css +2 -2
  13. package/libs/components/icons/icon.d.cts +32 -32
  14. package/libs/components/icons/icon.d.ts +32 -32
  15. package/libs/components/list/list.css +1 -1
  16. package/libs/components/list/list.min.css +1 -1
  17. package/libs/index.css +1 -1
  18. package/libs/index.css.map +1 -1
  19. package/package.json +4 -3
  20. package/src/components/README.mdx +1 -1
  21. package/src/components/buttons/button.scss +5 -0
  22. package/src/components/buttons/button.stories.tsx +8 -5
  23. package/src/components/cards/card.stories.tsx +1 -1
  24. package/src/components/details/details.stories.tsx +1 -1
  25. package/src/components/form/form.stories.tsx +1 -1
  26. package/src/components/form/input.stories.tsx +1 -1
  27. package/src/components/form/select.stories.tsx +1 -1
  28. package/src/components/heading/README.mdx +292 -0
  29. package/src/components/icons/icon.stories.tsx +1 -1
  30. package/src/components/list/list.scss +1 -1
  31. package/src/components/nav/nav.stories.tsx +1 -1
  32. package/src/components/ui.stories.tsx +53 -19
  33. package/src/docs/accessibility.mdx +484 -0
  34. package/src/docs/composition.mdx +549 -0
  35. package/src/docs/css-variables.mdx +380 -0
  36. package/src/docs/fpkit-developer.mdx +545 -0
  37. package/src/introduction.mdx +356 -0
  38. package/src/styles/buttons/button.css +4 -0
  39. package/src/styles/buttons/button.css.map +1 -1
  40. package/src/styles/index.css +9 -3
  41. package/src/styles/index.css.map +1 -1
  42. package/src/styles/list/list.css +1 -1
  43. package/src/styles/utilities/_disabled.scss +5 -4
@@ -0,0 +1,437 @@
1
+ # Focus Indicator Testing Guide
2
+
3
+ ## Overview
4
+
5
+ This guide provides manual testing procedures for verifying that focus indicators meet WCAG 2.4.7 (Focus Visible) Level AA requirements. Focus indicators must have at least **3:1 contrast ratio** against both the background and adjacent colors.
6
+
7
+ ## WCAG 2.4.7 Requirements
8
+
9
+ **Success Criterion:** Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.
10
+
11
+ **Level AA Requirements:**
12
+ - Focus indicators must be visible when an element receives keyboard focus
13
+ - Minimum **3:1 contrast ratio** against:
14
+ - The background color
15
+ - Adjacent (non-focused) component colors
16
+ - Minimum **2px thick** or equivalent area coverage
17
+
18
+ **Reference:** [WCAG 2.4.7 Focus Visible](https://www.w3.org/WAI/WCAG21/Understanding/focus-visible)
19
+
20
+ ---
21
+
22
+ ## Testing Tools
23
+
24
+ ### Required Tools
25
+
26
+ 1. **Keyboard** - For navigation testing
27
+ 2. **Chrome DevTools** or **Firefox DevTools** - For contrast measurement
28
+ 3. **axe DevTools Browser Extension** (Recommended)
29
+ - [Chrome](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd)
30
+ - [Firefox](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/)
31
+
32
+ ### Optional Tools
33
+
34
+ - **WAVE Browser Extension** - Additional accessibility scanning
35
+ - **Color Contrast Analyzer** - Desktop app for detailed contrast checking
36
+ - **Screen Readers:**
37
+ - NVDA (Windows) - [Download](https://www.nvaccess.org/download/)
38
+ - VoiceOver (macOS) - Built-in
39
+ - JAWS (Windows) - Commercial
40
+
41
+ ---
42
+
43
+ ## Test Procedures
44
+
45
+ ### 1. Keyboard Navigation Test
46
+
47
+ **Objective:** Verify all interactive elements show visible focus indicators when navigated with keyboard.
48
+
49
+ **Steps:**
50
+
51
+ 1. **Open the component/page** in your browser
52
+ 2. **Click in the address bar** to ensure page loses focus
53
+ 3. **Press Tab key** to start keyboard navigation
54
+ 4. **Continue pressing Tab** through all interactive elements
55
+ 5. **Press Shift+Tab** to navigate backwards
56
+
57
+ **Pass Criteria:**
58
+ - ✅ Every interactive element (buttons, inputs, links, selects) shows a visible outline when focused
59
+ - ✅ Focus indicator is clearly distinguishable from the non-focused state
60
+ - ✅ Disabled elements are focusable and show focus indicators
61
+ - ✅ Focus order follows logical reading order
62
+
63
+ **Common Issues:**
64
+ - ❌ No visible outline on focused elements
65
+ - ❌ Outline color matches background (invisible)
66
+ - ❌ Disabled elements skip in tab order (should NOT happen with aria-disabled pattern)
67
+
68
+ ---
69
+
70
+ ### 2. Contrast Verification Test
71
+
72
+ **Objective:** Verify focus indicators meet 3:1 contrast ratio requirement.
73
+
74
+ #### Method 1: Chrome DevTools (Recommended)
75
+
76
+ **Steps:**
77
+
78
+ 1. **Open DevTools** (F12 or Right-click → Inspect)
79
+ 2. **Navigate to element** using Tab key until it's focused
80
+ 3. **Click on the element** in the Elements panel
81
+ 4. **In the Styles panel**, find the `:focus-visible` styles
82
+ 5. **Click the color swatch** next to `outline-color`
83
+ 6. **Check the Contrast Ratio section** in the color picker
84
+
85
+ **Pass Criteria:**
86
+ - ✅ Contrast ratio shows **≥ 3.0:1** against background
87
+ - ✅ Both AA and AAA indicators show checkmarks (for UI components)
88
+
89
+ **Example Screenshot Interpretation:**
90
+ ```
91
+ Contrast Ratio:
92
+ AA ✓ 4.5 (Pass - Text contrast)
93
+ AAA ✓ 7.1 (Pass - Enhanced contrast)
94
+
95
+ UI Components:
96
+ AA ✓ 3.2 (Pass - Meets 3:1 minimum)
97
+ ```
98
+
99
+ #### Method 2: axe DevTools Browser Extension
100
+
101
+ **Steps:**
102
+
103
+ 1. **Install axe DevTools** browser extension
104
+ 2. **Open the page** with your components
105
+ 3. **Open DevTools** and select the **axe DevTools** tab
106
+ 4. **Click "Scan ALL of my page"**
107
+ 5. **Review Issues** section for focus indicator violations
108
+
109
+ **Pass Criteria:**
110
+ - ✅ No violations related to "Focus Visible" or "Color Contrast"
111
+ - ✅ Disabled elements appear in "Needs Review" (expected, manual verification needed)
112
+
113
+ #### Method 3: Manual Color Contrast Calculation
114
+
115
+ **Steps:**
116
+
117
+ 1. **Identify focus indicator color** (e.g., from DevTools Computed styles)
118
+ 2. **Identify background color** of the page/container
119
+ 3. **Use WebAIM Contrast Checker:** https://webaim.org/resources/contrastchecker/
120
+ 4. **Enter foreground color** (focus indicator color)
121
+ 5. **Enter background color** (page/container background)
122
+ 6. **Check "Graphical Objects and UI Components" section**
123
+
124
+ **Pass Criteria:**
125
+ - ✅ Contrast ratio shows **≥ 3:1** in the UI Components section
126
+
127
+ **Example Values:**
128
+ ```
129
+ Foreground: #005fcc (example custom --focus-color)
130
+ Background: #ffffff (white)
131
+ Result: 8.59:1 - PASS ✓
132
+
133
+ Foreground: #666666 (disabled color, currentColor fallback)
134
+ Background: #ffffff (white)
135
+ Result: 4.54:1 - PASS ✓
136
+
137
+ Foreground: #666666 (disabled color)
138
+ Background: #999999 (gray container)
139
+ Result: 1.54:1 - FAIL ✗ (This is why --focus-color override is needed!)
140
+ ```
141
+
142
+ ---
143
+
144
+ ### 3. Theme Testing
145
+
146
+ **Objective:** Verify focus indicators work correctly across different themes and backgrounds.
147
+
148
+ **Test Matrix:**
149
+
150
+ | Background | Focus Color | Expected Contrast | Pass/Fail |
151
+ |------------|-------------|-------------------|-----------|
152
+ | `#ffffff` (white) | `currentColor` (#666) | 4.54:1 | ✅ Pass |
153
+ | `#ffffff` (white) | `--focus-color` (#005fcc) | 8.59:1 | ✅ Pass |
154
+ | `#f5f5f5` (light gray) | `currentColor` (#666) | 3.84:1 | ✅ Pass |
155
+ | `#999999` (gray) | `currentColor` (#666) | 1.54:1 | ⚠️ **Needs --focus-color** |
156
+ | `#333333` (dark) | `currentColor` (#666) | 2.4:1 | ⚠️ **Needs --focus-color** |
157
+
158
+ **Steps:**
159
+
160
+ 1. **Test on white background** (default theme)
161
+ - Navigate with Tab
162
+ - Verify focus indicator is visible
163
+ - Measure contrast with DevTools
164
+
165
+ 2. **Test on gray backgrounds** (if your theme uses gray containers)
166
+ - Add test component to gray container
167
+ - Navigate with Tab
168
+ - Measure contrast - if < 3:1, add `--focus-color` override
169
+
170
+ 3. **Test in dark mode** (if your theme supports it)
171
+ - Switch to dark mode
172
+ - Verify focus indicators are visible
173
+ - Measure contrast against dark backgrounds
174
+
175
+ **Pass Criteria:**
176
+ - ✅ All backgrounds show focus indicators with ≥ 3:1 contrast
177
+ - ✅ Custom themes define `--focus-color` when needed
178
+
179
+ **Fix for Failing Themes:**
180
+
181
+ If contrast fails on certain backgrounds, add theme-specific `--focus-color`:
182
+
183
+ ```css
184
+ /* Light theme (default) - currentColor (#666) works fine */
185
+ :root {
186
+ /* No override needed, currentColor provides 4.54:1 on white */
187
+ }
188
+
189
+ /* Gray theme - needs custom focus color */
190
+ .theme-gray {
191
+ --focus-color: #005fcc; /* 8.59:1 on white, 3.2:1 on #999 */
192
+ }
193
+
194
+ /* Dark theme - needs lighter focus color */
195
+ .theme-dark {
196
+ --focus-color: #4da6ff; /* Lighter blue for dark backgrounds */
197
+ }
198
+ ```
199
+
200
+ ---
201
+
202
+ ### 4. Disabled Element Focus Test
203
+
204
+ **Objective:** Verify disabled elements remain focusable and show focus indicators (aria-disabled pattern).
205
+
206
+ **Steps:**
207
+
208
+ 1. **Create test form** with disabled elements:
209
+ ```tsx
210
+ <form>
211
+ <Input id="name" name="name" placeholder="Name" />
212
+ <Input id="email" name="email" disabled={true} placeholder="Email (disabled)" />
213
+ <Button type="button" disabled={true}>Disabled Button</Button>
214
+ <Button type="submit">Submit</Button>
215
+ </form>
216
+ ```
217
+
218
+ 2. **Press Tab** to navigate through the form
219
+ 3. **Verify disabled elements receive focus** (tab stops on them)
220
+ 4. **Verify focus indicator is visible** on disabled elements
221
+ 5. **Measure contrast** of focus indicator on disabled elements
222
+
223
+ **Pass Criteria:**
224
+ - ✅ Disabled elements receive keyboard focus (tab stops on them)
225
+ - ✅ Focus indicator is visible with ≥ 3:1 contrast
226
+ - ✅ Disabled elements have `.is-disabled` class or `aria-disabled="true"`
227
+ - ✅ Visual disabled styling (opacity, color) is applied
228
+ - ✅ Clicking or pressing Enter/Space does NOT trigger actions
229
+
230
+ **Common Issues:**
231
+ - ❌ Disabled elements not in tab order (indicates native `disabled` attribute used instead of `aria-disabled`)
232
+ - ❌ No focus indicator on disabled elements
233
+ - ❌ Focus indicator has insufficient contrast due to disabled opacity
234
+
235
+ ---
236
+
237
+ ### 5. Screen Reader Announcement Test
238
+
239
+ **Objective:** Verify screen readers properly announce focus indicators and disabled states.
240
+
241
+ #### Windows - NVDA
242
+
243
+ **Steps:**
244
+
245
+ 1. **Start NVDA** (Control+Alt+N)
246
+ 2. **Navigate to test page**
247
+ 3. **Press Tab** to focus on disabled element
248
+ 4. **Listen for announcement**
249
+
250
+ **Expected Announcement:**
251
+ ```
252
+ "Email, edit, disabled, blank"
253
+ or
254
+ "Submit, button, disabled"
255
+ ```
256
+
257
+ **Key Commands:**
258
+ - `Tab` - Navigate to next element
259
+ - `Shift+Tab` - Navigate to previous element
260
+ - `Insert+↓` - Read current element
261
+ - `Insert+F7` - List all form fields
262
+
263
+ **Pass Criteria:**
264
+ - ✅ Screen reader announces "disabled" state
265
+ - ✅ Element type is announced (button, edit, etc.)
266
+ - ✅ Label or placeholder is announced
267
+
268
+ #### macOS - VoiceOver
269
+
270
+ **Steps:**
271
+
272
+ 1. **Start VoiceOver** (Cmd+F5)
273
+ 2. **Navigate to test page**
274
+ 3. **Press Tab** to focus on disabled element
275
+ 4. **Listen for announcement**
276
+
277
+ **Expected Announcement:**
278
+ ```
279
+ "Email, dimmed, edit text"
280
+ or
281
+ "Submit, dimmed, button"
282
+ ```
283
+
284
+ **Key Commands:**
285
+ - `Tab` - Navigate to next element
286
+ - `Shift+Tab` - Navigate to previous element
287
+ - `Control+Option+A` - Read element attributes
288
+ - `Control+Option+Shift+H` - Read hint
289
+
290
+ **Pass Criteria:**
291
+ - ✅ Screen reader announces "dimmed" or "disabled" state
292
+ - ✅ Element type is announced (button, edit text, etc.)
293
+ - ✅ Label or placeholder is announced
294
+
295
+ ---
296
+
297
+ ## Testing Checklist
298
+
299
+ Use this checklist for comprehensive focus indicator testing:
300
+
301
+ ### Basic Functionality
302
+ - [ ] All interactive elements are keyboard accessible
303
+ - [ ] Tab key navigates through all elements in logical order
304
+ - [ ] Shift+Tab navigates backwards
305
+ - [ ] Disabled elements remain in tab order (aria-disabled pattern)
306
+ - [ ] Focus indicator is visible on all focused elements
307
+
308
+ ### Contrast Requirements
309
+ - [ ] Focus indicator has ≥ 3:1 contrast against white background
310
+ - [ ] Focus indicator has ≥ 3:1 contrast against light gray backgrounds
311
+ - [ ] Focus indicator has ≥ 3:1 contrast against dark backgrounds (if applicable)
312
+ - [ ] Focus indicator is visible on disabled elements
313
+ - [ ] No information conveyed by focus indicator color alone
314
+
315
+ ### Theme Compatibility
316
+ - [ ] Focus indicator works in default light theme
317
+ - [ ] Focus indicator works in dark mode (if supported)
318
+ - [ ] Custom themes define `--focus-color` when needed
319
+ - [ ] Focus indicator contrast verified with DevTools
320
+
321
+ ### Screen Reader Compatibility
322
+ - [ ] NVDA announces disabled state correctly
323
+ - [ ] VoiceOver announces disabled state correctly
324
+ - [ ] Element labels are read by screen readers
325
+ - [ ] Form structure is understandable without visual cues
326
+
327
+ ### Component-Specific Tests
328
+ - [ ] Buttons: Visible focus indicator, "disabled" announced
329
+ - [ ] Inputs: Visible focus indicator, "disabled" announced
330
+ - [ ] Selects: Visible focus indicator, "disabled" announced
331
+ - [ ] Textareas: Visible focus indicator, "disabled" announced
332
+ - [ ] Links: Visible focus indicator (if used in disabled state)
333
+
334
+ ---
335
+
336
+ ## Reporting Issues
337
+
338
+ When reporting focus indicator issues, include:
339
+
340
+ 1. **Component name and state** (e.g., "Button, disabled state")
341
+ 2. **Browser and version** (e.g., "Chrome 120")
342
+ 3. **Theme/background** (e.g., "Gray container background #999999")
343
+ 4. **Measured contrast ratio** (e.g., "1.54:1 - FAIL")
344
+ 5. **Screenshot** showing the focused element
345
+ 6. **DevTools screenshot** showing the contrast measurement
346
+
347
+ **Example Issue Report:**
348
+
349
+ ```markdown
350
+ ## Focus Indicator Contrast Failure
351
+
352
+ **Component:** Input (disabled)
353
+ **Browser:** Chrome 120
354
+ **Background:** Gray container (#999999)
355
+ **Measured Contrast:** 1.54:1 (FAIL - requires 3:1 minimum)
356
+
357
+ **Screenshot:** [attach screenshot]
358
+
359
+ **Recommendation:** Add custom --focus-color for gray theme:
360
+ .theme-gray {
361
+ --focus-color: #005fcc; /* Provides 3.2:1 on gray */
362
+ }
363
+ ```
364
+
365
+ ---
366
+
367
+ ## Automated Testing Recommendations
368
+
369
+ While this guide focuses on manual testing, consider adding these automated tests:
370
+
371
+ ### jest-axe Integration
372
+
373
+ ```typescript
374
+ import { axe, toHaveNoViolations } from 'jest-axe';
375
+
376
+ expect.extend(toHaveNoViolations);
377
+
378
+ describe('Focus Indicator Accessibility', () => {
379
+ it('should not have focus indicator violations', async () => {
380
+ const { container } = render(
381
+ <Button type="button" disabled={true}>
382
+ Disabled Button
383
+ </Button>
384
+ );
385
+ const results = await axe(container);
386
+ expect(results).toHaveNoViolations();
387
+ });
388
+ });
389
+ ```
390
+
391
+ ### Keyboard Navigation Test
392
+
393
+ ```typescript
394
+ it('should be focusable when disabled', () => {
395
+ render(<Button type="button" disabled={true}>Disabled</Button>);
396
+ const button = screen.getByRole('button');
397
+
398
+ button.focus();
399
+ expect(button).toHaveFocus();
400
+ expect(button).toHaveAttribute('aria-disabled', 'true');
401
+ });
402
+ ```
403
+
404
+ ### Visual Regression Testing
405
+
406
+ Consider using tools like:
407
+ - **Chromatic** - Visual regression testing for Storybook
408
+ - **Percy** - Visual testing platform
409
+ - **BackstopJS** - Visual regression testing
410
+
411
+ ---
412
+
413
+ ## Additional Resources
414
+
415
+ ### WCAG References
416
+ - [WCAG 2.4.7 Focus Visible](https://www.w3.org/WAI/WCAG21/Understanding/focus-visible)
417
+ - [WCAG 2.1.1 Keyboard](https://www.w3.org/WAI/WCAG21/Understanding/keyboard)
418
+ - [WCAG 1.4.11 Non-text Contrast](https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast)
419
+
420
+ ### Tools
421
+ - [WebAIM Contrast Checker](https://webaim.org/resources/contrastchecker/)
422
+ - [Chrome DevTools](https://developer.chrome.com/docs/devtools/)
423
+ - [axe DevTools Extension](https://www.deque.com/axe/devtools/)
424
+ - [WAVE Browser Extension](https://wave.webaim.org/extension/)
425
+
426
+ ### Articles
427
+ - [Understanding Focus Indicators](https://www.sarasoueidan.com/blog/focus-indicators/)
428
+ - [Accessible Focus Indicators](https://www.deque.com/blog/give-site-focus-tips-designing-usable-focus-indicators/)
429
+ - [The :focus-visible Selector](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible)
430
+
431
+ ---
432
+
433
+ ## Changelog
434
+
435
+ | Date | Version | Changes |
436
+ |------|---------|---------|
437
+ | 2025-11-02 | 1.0.0 | Initial focus indicator testing guide |
@@ -1 +1 @@
1
- button{--btn-size-xs: 0.6875rem;--btn-size-sm: 0.8125rem;--btn-size-md: 0.9375rem;--btn-size-lg: 1.125rem;--btn-pill: 100rem;--btn-fs: var(--btn-size-md);--btn-height: calc(var(--btn-fs) * 2.25);--btn-bg: lightgray;--btn-width: max-content;font-size:var(--btn-fs);font-weight:var(--btn-fw, 500);height:var(--btn-height);place-items:var(--btn-place, center);padding-inline:var(--btn-padding-inline, calc(var(--btn-fs) * 1.5));padding-block:var(--btn-padding-block, calc(var(--btn-fs) * 0.5));border:var(--btn-border, none);border-radius:var(--btn-radius, 0.375rem);text-decoration:var(--btn-deco, none);color:var(--btn-color, currentColor);display:var(--btn-display, inline-flex);gap:var(--btn-gap, 0.2rem);white-space:var(--btn-whitespace, inherit);margin:var(--btn-spacing, 0);transition:var(--btn-transition, var(--tran-all, all 0.3s cubic-bezier(0.4, 0, 0.2, 1)));background-color:var(--btn-bg, var(--btn));outline:none;width:var(--btn-width);display:inline-flex;align-items:center;line-height:0cap}button[type]{background-color:var(--btn-bg, var(--neutral-300));--btn-border: solid var(--btn-sg)}button[type=submit],button[style*=submit]{--btn-bg: var(--primary-500, royal-blue);--btn-color: white}button[disabled],button[aria-disabled=true]{cursor:var(--btn-cursor, not-allowed)}button[disabled]:is(:hover,:focus),button[aria-disabled=true]:is(:hover,:focus){transform:none}button:is(:hover,:focus){filter:var(--btn-hover-filter, brightness(0.85));transform:var(--btn-hover-transform, scale(1.03));outline:var(--btn-hover-outline, thin);outline-offset:var(--line-offset, 1px)}button:is(:hover,:focus)[aria-disabled=true]{transform:none;opacity:var(--btn-opacity, 0.5);filter:none}button[type=reset]{--btn-bg: transparent;--btn-color: gray;--btn-border: gray thin solid}button[type=submit]{--btn-bg: var(--primary-700, blue);--btn-color: #fff;--btn-border: none}button[data-fp-btn~=pill],button[data-btn~=pill],button[data-style~=pill]{border-radius:var(--btn-pill, 100rem)}button[data-btn~=xs],button .btn-xs{--btn-fs: var(--btn-size-xs);text-transform:uppercase}button[data-btn~=sm],button .btn-sm{--btn-fs: var(--btn-size-sm)}button[data-btn~=md],button .btn-md{--btn-fs: var(--btn-size-md)}button[data-btn~=lg],button .btn-lg{--btn-fs: var(--btn-size-lg)}button[data-btn~=icon],button .btn-icon{padding:unset;height:unset;--btn-bg: transparent;min-width:1.5rem;min-height:1.5rem;text-align:center;display:inline-flex;align-items:center;justify-content:center}button[data-btn~=text],button .btn-text{--btn-bg: transparent;--btn-color: currentColor;--btn-border: none;--btn-height: unset;--btn-width: unset;--btn-padding-block: 0.75rem;--btn-padding-inline: 0.75rem}button[data-btn~=text]:is(:hover,:focus),button .btn-text:is(:hover,:focus){background-color:color-mix(in srgb, var(--btn-color) 10%, transparent);outline:.025rem solid var(--btn-color);outline-offset:0;filter:none}/*# sourceMappingURL=button.css.map */
1
+ button{--btn-size-xs: 0.6875rem;--btn-size-sm: 0.8125rem;--btn-size-md: 0.9375rem;--btn-size-lg: 1.125rem;--btn-pill: 100rem;--btn-fs: var(--btn-size-md);--btn-height: calc(var(--btn-fs) * 2.25);--btn-bg: lightgray;--btn-width: max-content;font-size:var(--btn-fs);font-weight:var(--btn-fw, 500);height:var(--btn-height);place-items:var(--btn-place, center);padding-inline:var(--btn-padding-inline, calc(var(--btn-fs) * 1.5));padding-block:var(--btn-padding-block, calc(var(--btn-fs) * 0.5));border:var(--btn-border, none);border-radius:var(--btn-radius, 0.375rem);text-decoration:var(--btn-deco, none);color:var(--btn-color, currentColor);display:var(--btn-display, inline-flex);gap:var(--btn-gap, 0.2rem);white-space:var(--btn-whitespace, inherit);margin:var(--btn-spacing, 0);transition:var(--btn-transition, var(--tran-all, all 0.3s cubic-bezier(0.4, 0, 0.2, 1)));background-color:var(--btn-bg, var(--btn));outline:none;width:var(--btn-width);display:inline-flex;align-items:center;line-height:0cap}button[type]{background-color:var(--btn-bg, var(--neutral-300));--btn-border: solid var(--btn-sg)}button[type=submit],button[style*=submit]{--btn-bg: var(--primary-500, royal-blue);--btn-color: white}button[disabled],button[aria-disabled=true]{cursor:var(--btn-cursor, not-allowed)}button[disabled]:is(:hover,:focus),button[aria-disabled=true]:is(:hover,:focus){transform:none}button:is(:hover,:focus){filter:var(--btn-hover-filter, brightness(0.85));transform:var(--btn-hover-transform, scale(1.03));outline:var(--btn-hover-outline, thin);outline-offset:var(--line-offset, 1px)}button:is(:hover,:focus)[aria-disabled=true]{transform:none;opacity:var(--btn-opacity, 0.5);filter:none}button:focus-visible{outline:var(--btn-focus-outline, 2px solid currentColor);outline-offset:var(--btn-focus-outline-offset, 1px)}button[type=reset]{--btn-bg: transparent;--btn-color: gray;--btn-border: gray thin solid}button[type=submit]{--btn-bg: var(--primary-700, blue);--btn-color: #fff;--btn-border: none}button[data-fp-btn~=pill],button[data-btn~=pill],button[data-style~=pill]{border-radius:var(--btn-pill, 100rem)}button[data-btn~=xs],button .btn-xs{--btn-fs: var(--btn-size-xs);text-transform:uppercase}button[data-btn~=sm],button .btn-sm{--btn-fs: var(--btn-size-sm)}button[data-btn~=md],button .btn-md{--btn-fs: var(--btn-size-md)}button[data-btn~=lg],button .btn-lg{--btn-fs: var(--btn-size-lg)}button[data-btn~=icon],button .btn-icon{padding:unset;height:unset;--btn-bg: transparent;min-width:1.5rem;min-height:1.5rem;text-align:center;display:inline-flex;align-items:center;justify-content:center}button[data-btn~=text],button .btn-text{--btn-bg: transparent;--btn-color: currentColor;--btn-border: none;--btn-height: unset;--btn-width: unset;--btn-padding-block: 0.75rem;--btn-padding-inline: 0.75rem}button[data-btn~=text]:is(:hover,:focus),button .btn-text:is(:hover,:focus){background-color:color-mix(in srgb, var(--btn-color) 10%, transparent);outline:.025rem solid var(--btn-color);outline-offset:0;filter:none}/*# sourceMappingURL=button.css.map */
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../../../src/components/buttons/button.scss"],"names":[],"mappings":"AAAA,OAEE,yBACA,yBACA,yBACA,wBACA,mBACA,6BACA,yCACA,oBACA,yBAEA,wBACA,+BACA,yBACA,qCACA,oEACA,kEACA,+BACA,0CACA,sCACA,qCACA,wCACA,2BACA,2CACA,6BACA,yFAIA,2CACA,aACA,uBACA,oBACA,mBACA,iBAEA,aACE,mDACA,kCAGF,0CAEE,yCACA,mBAGF,4CAEE,sCAGA,gFACE,eAOJ,yBAEE,iDACA,kDACA,uCACA,uCAGA,6CACE,eACA,gCACA,YAIJ,mBACE,sBACA,kBACA,8BAGF,oBACE,mCACA,kBACA,mBAGF,0EAGE,sCAGF,oCAEE,6BACA,yBAGF,oCAEE,6BAGF,oCAEE,6BAGF,oCAEE,6BAGF,wCAEE,cACA,aACA,sBACA,iBACA,kBACA,kBACA,oBACA,mBACA,uBAGF,wCAEE,sBACA,0BACA,mBACA,oBACA,mBACA,6BACA,8BACA,4EACE,uEACA,uCACA,iBACA","file":"button.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../../../src/components/buttons/button.scss"],"names":[],"mappings":"AAAA,OAEE,yBACA,yBACA,yBACA,wBACA,mBACA,6BACA,yCACA,oBACA,yBAEA,wBACA,+BACA,yBACA,qCACA,oEACA,kEACA,+BACA,0CACA,sCACA,qCACA,wCACA,2BACA,2CACA,6BACA,yFAIA,2CACA,aACA,uBACA,oBACA,mBACA,iBAEA,aACE,mDACA,kCAGF,0CAEE,yCACA,mBAGF,4CAEE,sCAGA,gFACE,eAOJ,yBAEE,iDACA,kDACA,uCACA,uCAGA,6CACE,eACA,gCACA,YAIJ,qBACE,yDACA,oDAGF,mBACE,sBACA,kBACA,8BAGF,oBACE,mCACA,kBACA,mBAGF,0EAGE,sCAGF,oCAEE,6BACA,yBAGF,oCAEE,6BAGF,oCAEE,6BAGF,oCAEE,6BAGF,wCAEE,cACA,aACA,sBACA,iBACA,kBACA,kBACA,oBACA,mBACA,uBAGF,wCAEE,sBACA,0BACA,mBACA,oBACA,mBACA,6BACA,8BACA,4EACE,uEACA,uCACA,iBACA","file":"button.css"}
@@ -1,3 +1,3 @@
1
- button{--btn-size-xs: 0.6875rem;--btn-size-sm: 0.8125rem;--btn-size-md: 0.9375rem;--btn-size-lg: 1.125rem;--btn-pill: 100rem;--btn-fs: var(--btn-size-md);--btn-height: calc(var(--btn-fs) * 2.25);--btn-bg: lightgray;--btn-width: max-content;font-size:var(--btn-fs);font-weight:var(--btn-fw, 500);height:var(--btn-height);place-items:var(--btn-place, center);padding-inline:var(--btn-padding-inline, calc(var(--btn-fs) * 1.5));padding-block:var(--btn-padding-block, calc(var(--btn-fs) * 0.5));border:var(--btn-border, none);border-radius:var(--btn-radius, 0.375rem);-webkit-text-decoration:var(--btn-deco, none);text-decoration:var(--btn-deco, none);color:var(--btn-color, currentColor);display:var(--btn-display, inline-flex);gap:var(--btn-gap, 0.2rem);white-space:var(--btn-whitespace, inherit);margin:var(--btn-spacing, 0);transition:var(--btn-transition, var(--tran-all, all 0.3s cubic-bezier(0.4, 0, 0.2, 1)));background-color:var(--btn-bg, var(--btn));outline:none;width:var(--btn-width);display:inline-flex;align-items:center;line-height:0cap}button[type]{background-color:var(--btn-bg, var(--neutral-300));--btn-border: solid var(--btn-sg)}button[type=submit],button[style*=submit]{--btn-bg: var(--primary-500, royal-blue);--btn-color: white}button[disabled],button[aria-disabled=true]{cursor:var(--btn-cursor, not-allowed)}button[disabled]:is(:hover,:focus),button[aria-disabled=true]:is(:hover,:focus){transform:none}button:is(:hover,:focus){filter:var(--btn-hover-filter, brightness(0.85));transform:var(--btn-hover-transform, scale(1.03));outline:var(--btn-hover-outline, thin);outline-offset:var(--line-offset, 1px)}button:is(:hover,:focus)[aria-disabled=true]{transform:none;opacity:var(--btn-opacity, 0.5);filter:none}button[type=reset]{--btn-bg: transparent;--btn-color: gray;--btn-border: gray thin solid}button[type=submit]{--btn-bg: var(--primary-700, blue);--btn-color: #fff;--btn-border: none}button[data-fp-btn~=pill],button[data-btn~=pill],button[data-style~=pill]{border-radius:var(--btn-pill, 100rem)}button[data-btn~=xs],button .btn-xs{--btn-fs: var(--btn-size-xs);text-transform:uppercase}button[data-btn~=sm],button .btn-sm{--btn-fs: var(--btn-size-sm)}button[data-btn~=md],button .btn-md{--btn-fs: var(--btn-size-md)}button[data-btn~=lg],button .btn-lg{--btn-fs: var(--btn-size-lg)}button[data-btn~=icon],button .btn-icon{padding:unset;height:unset;--btn-bg: transparent;min-width:1.5rem;min-height:1.5rem;text-align:center;display:inline-flex;align-items:center;justify-content:center}button[data-btn~=text],button .btn-text{--btn-bg: transparent;--btn-color: currentColor;--btn-border: none;--btn-height: unset;--btn-width: unset;--btn-padding-block: 0.75rem;--btn-padding-inline: 0.75rem}button[data-btn~=text]:is(:hover,:focus),button .btn-text:is(:hover,:focus){background-color:color-mix(in srgb, var(--btn-color) 10%, transparent);outline:.025rem solid var(--btn-color);outline-offset:0;filter:none}
1
+ button{--btn-size-xs: 0.6875rem;--btn-size-sm: 0.8125rem;--btn-size-md: 0.9375rem;--btn-size-lg: 1.125rem;--btn-pill: 100rem;--btn-fs: var(--btn-size-md);--btn-height: calc(var(--btn-fs) * 2.25);--btn-bg: lightgray;--btn-width: max-content;font-size:var(--btn-fs);font-weight:var(--btn-fw, 500);height:var(--btn-height);place-items:var(--btn-place, center);padding-inline:var(--btn-padding-inline, calc(var(--btn-fs) * 1.5));padding-block:var(--btn-padding-block, calc(var(--btn-fs) * 0.5));border:var(--btn-border, none);border-radius:var(--btn-radius, 0.375rem);-webkit-text-decoration:var(--btn-deco, none);text-decoration:var(--btn-deco, none);color:var(--btn-color, currentColor);display:var(--btn-display, inline-flex);gap:var(--btn-gap, 0.2rem);white-space:var(--btn-whitespace, inherit);margin:var(--btn-spacing, 0);transition:var(--btn-transition, var(--tran-all, all 0.3s cubic-bezier(0.4, 0, 0.2, 1)));background-color:var(--btn-bg, var(--btn));outline:none;width:var(--btn-width);display:inline-flex;align-items:center;line-height:0cap}button[type]{background-color:var(--btn-bg, var(--neutral-300));--btn-border: solid var(--btn-sg)}button[type=submit],button[style*=submit]{--btn-bg: var(--primary-500, royal-blue);--btn-color: white}button[disabled],button[aria-disabled=true]{cursor:var(--btn-cursor, not-allowed)}button[disabled]:is(:hover,:focus),button[aria-disabled=true]:is(:hover,:focus){transform:none}button:is(:hover,:focus){filter:var(--btn-hover-filter, brightness(0.85));transform:var(--btn-hover-transform, scale(1.03));outline:var(--btn-hover-outline, thin);outline-offset:var(--line-offset, 1px)}button:is(:hover,:focus)[aria-disabled=true]{transform:none;opacity:var(--btn-opacity, 0.5);filter:none}button:focus-visible{outline:var(--btn-focus-outline, 2px solid currentColor);outline-offset:var(--btn-focus-outline-offset, 1px)}button[type=reset]{--btn-bg: transparent;--btn-color: gray;--btn-border: gray thin solid}button[type=submit]{--btn-bg: var(--primary-700, blue);--btn-color: #fff;--btn-border: none}button[data-fp-btn~=pill],button[data-btn~=pill],button[data-style~=pill]{border-radius:var(--btn-pill, 100rem)}button[data-btn~=xs],button .btn-xs{--btn-fs: var(--btn-size-xs);text-transform:uppercase}button[data-btn~=sm],button .btn-sm{--btn-fs: var(--btn-size-sm)}button[data-btn~=md],button .btn-md{--btn-fs: var(--btn-size-md)}button[data-btn~=lg],button .btn-lg{--btn-fs: var(--btn-size-lg)}button[data-btn~=icon],button .btn-icon{padding:unset;height:unset;--btn-bg: transparent;min-width:1.5rem;min-height:1.5rem;text-align:center;display:inline-flex;align-items:center;justify-content:center}button[data-btn~=text],button .btn-text{--btn-bg: transparent;--btn-color: currentColor;--btn-border: none;--btn-height: unset;--btn-width: unset;--btn-padding-block: 0.75rem;--btn-padding-inline: 0.75rem}button[data-btn~=text]:is(:hover,:focus),button .btn-text:is(:hover,:focus){background-color:color-mix(in srgb, var(--btn-color) 10%, transparent);outline:.025rem solid var(--btn-color);outline-offset:0;filter:none}
2
2
 
3
- /*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2J1dHRvbnMvYnV0dG9uLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FFRSx3QkFBQSxDQUNBLHdCQUFBLENBQ0Esd0JBQUEsQ0FDQSx1QkFBQSxDQUNBLGtCQUFBLENBQ0EsNEJBQUEsQ0FDQSx3Q0FBQSxDQUNBLG1CQUFBLENBQ0Esd0JBQUEsQ0FFQSx1QkFBQSxDQUNBLDhCQUFBLENBQ0Esd0JBQUEsQ0FDQSxvQ0FBQSxDQUNBLG1FQUFBLENBQ0EsaUVBQUEsQ0FDQSw4QkFBQSxDQUNBLHlDQUFBLENBQ0EsNkNBQUEsQ0FBQSxxQ0FBQSxDQUNBLG9DQUFBLENBQ0EsdUNBQUEsQ0FDQSwwQkFBQSxDQUNBLDBDQUFBLENBQ0EsNEJBQUEsQ0FDQSx3RkFBQSxDQUlBLDBDQUFBLENBQ0EsWUFBQSxDQUNBLHNCQUFBLENBQ0EsbUJBQUEsQ0FDQSxrQkFBQSxDQUNBLGdCQUFBLENBRUEsYUFDRSxrREFBQSxDQUNBLGlDQUFBLENBR0YsMENBRUUsd0NBQUEsQ0FDQSxrQkFBQSxDQUdGLDRDQUVFLHFDQUFBLENBR0EsZ0ZBQ0UsY0FBQSxDQU9KLHlCQUVFLGdEQUFBLENBQ0EsaURBQUEsQ0FDQSxzQ0FBQSxDQUNBLHNDQUFBLENBR0EsNkNBQ0UsY0FBQSxDQUNBLCtCQUFBLENBQ0EsV0FBQSxDQUlKLG1CQUNFLHFCQUFBLENBQ0EsaUJBQUEsQ0FDQSw2QkFBQSxDQUdGLG9CQUNFLGtDQUFBLENBQ0EsaUJBQUEsQ0FDQSxrQkFBQSxDQUdGLDBFQUdFLHFDQUFBLENBR0Ysb0NBRUUsNEJBQUEsQ0FDQSx3QkFBQSxDQUdGLG9DQUVFLDRCQUFBLENBR0Ysb0NBRUUsNEJBQUEsQ0FHRixvQ0FFRSw0QkFBQSxDQUdGLHdDQUVFLGFBQUEsQ0FDQSxZQUFBLENBQ0EscUJBQUEsQ0FDQSxnQkFBQSxDQUNBLGlCQUFBLENBQ0EsaUJBQUEsQ0FDQSxtQkFBQSxDQUNBLGtCQUFBLENBQ0Esc0JBQUEsQ0FHRix3Q0FFRSxxQkFBQSxDQUNBLHlCQUFBLENBQ0Esa0JBQUEsQ0FDQSxtQkFBQSxDQUNBLGtCQUFBLENBQ0EsNEJBQUEsQ0FDQSw2QkFBQSxDQUNBLDRFQUNFLHNFQUFBLENBQ0Esc0NBQUEsQ0FDQSxnQkFBQSxDQUNBLFdBQUEiLCJmaWxlIjoiYnV0dG9uLm1pbi5jc3MifQ== */
3
+ /*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21wb25lbnRzL2J1dHRvbnMvYnV0dG9uLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FFRSx3QkFBQSxDQUNBLHdCQUFBLENBQ0Esd0JBQUEsQ0FDQSx1QkFBQSxDQUNBLGtCQUFBLENBQ0EsNEJBQUEsQ0FDQSx3Q0FBQSxDQUNBLG1CQUFBLENBQ0Esd0JBQUEsQ0FFQSx1QkFBQSxDQUNBLDhCQUFBLENBQ0Esd0JBQUEsQ0FDQSxvQ0FBQSxDQUNBLG1FQUFBLENBQ0EsaUVBQUEsQ0FDQSw4QkFBQSxDQUNBLHlDQUFBLENBQ0EsNkNBQUEsQ0FBQSxxQ0FBQSxDQUNBLG9DQUFBLENBQ0EsdUNBQUEsQ0FDQSwwQkFBQSxDQUNBLDBDQUFBLENBQ0EsNEJBQUEsQ0FDQSx3RkFBQSxDQUlBLDBDQUFBLENBQ0EsWUFBQSxDQUNBLHNCQUFBLENBQ0EsbUJBQUEsQ0FDQSxrQkFBQSxDQUNBLGdCQUFBLENBRUEsYUFDRSxrREFBQSxDQUNBLGlDQUFBLENBR0YsMENBRUUsd0NBQUEsQ0FDQSxrQkFBQSxDQUdGLDRDQUVFLHFDQUFBLENBR0EsZ0ZBQ0UsY0FBQSxDQU9KLHlCQUVFLGdEQUFBLENBQ0EsaURBQUEsQ0FDQSxzQ0FBQSxDQUNBLHNDQUFBLENBR0EsNkNBQ0UsY0FBQSxDQUNBLCtCQUFBLENBQ0EsV0FBQSxDQUlKLHFCQUNFLHdEQUFBLENBQ0EsbURBQUEsQ0FHRixtQkFDRSxxQkFBQSxDQUNBLGlCQUFBLENBQ0EsNkJBQUEsQ0FHRixvQkFDRSxrQ0FBQSxDQUNBLGlCQUFBLENBQ0Esa0JBQUEsQ0FHRiwwRUFHRSxxQ0FBQSxDQUdGLG9DQUVFLDRCQUFBLENBQ0Esd0JBQUEsQ0FHRixvQ0FFRSw0QkFBQSxDQUdGLG9DQUVFLDRCQUFBLENBR0Ysb0NBRUUsNEJBQUEsQ0FHRix3Q0FFRSxhQUFBLENBQ0EsWUFBQSxDQUNBLHFCQUFBLENBQ0EsZ0JBQUEsQ0FDQSxpQkFBQSxDQUNBLGlCQUFBLENBQ0EsbUJBQUEsQ0FDQSxrQkFBQSxDQUNBLHNCQUFBLENBR0Ysd0NBRUUscUJBQUEsQ0FDQSx5QkFBQSxDQUNBLGtCQUFBLENBQ0EsbUJBQUEsQ0FDQSxrQkFBQSxDQUNBLDRCQUFBLENBQ0EsNkJBQUEsQ0FDQSw0RUFDRSxzRUFBQSxDQUNBLHNDQUFBLENBQ0EsZ0JBQUEsQ0FDQSxXQUFBIiwiZmlsZSI6ImJ1dHRvbi5taW4uY3NzIn0= */