@pudge-ui/mcp-server 0.1.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.
- package/README.md +63 -0
- package/dist/__tests__/catalog.test.d.ts +1 -0
- package/dist/__tests__/catalog.test.js +50 -0
- package/dist/__tests__/search.test.d.ts +1 -0
- package/dist/__tests__/search.test.js +44 -0
- package/dist/__tests__/validation.test.d.ts +1 -0
- package/dist/__tests__/validation.test.js +34 -0
- package/dist/assembler.d.ts +6 -0
- package/dist/assembler.js +95 -0
- package/dist/catalog.d.ts +22 -0
- package/dist/catalog.js +10 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +33 -0
- package/dist/search.d.ts +5 -0
- package/dist/search.js +21 -0
- package/dist/tools.d.ts +105 -0
- package/dist/tools.js +129 -0
- package/package.json +55 -0
- package/spec/components/_index.yaml +822 -0
- package/spec/components/buttons/clear-button.md +89 -0
- package/spec/components/buttons/fn-grid.md +104 -0
- package/spec/components/buttons/gel-button.md +125 -0
- package/spec/components/buttons/icon-button.md +108 -0
- package/spec/components/buttons/keypad-button.md +123 -0
- package/spec/components/buttons/push-button.md +139 -0
- package/spec/components/buttons/rec-button.md +105 -0
- package/spec/components/buttons/rubber-button.md +100 -0
- package/spec/components/buttons/segmented-control.md +95 -0
- package/spec/components/data/assembled-panel.md +135 -0
- package/spec/components/data/data-table.md +116 -0
- package/spec/components/data/film-strip.md +110 -0
- package/spec/components/data/media-grid.md +98 -0
- package/spec/components/dials/click-wheel.md +115 -0
- package/spec/components/dials/cylindrical-horizontal.md +130 -0
- package/spec/components/dials/cylindrical-scroll.md +141 -0
- package/spec/components/dials/cylindrical-vertical.md +100 -0
- package/spec/components/dials/mode-dial.md +123 -0
- package/spec/components/dials/radial-knob.md +150 -0
- package/spec/components/dials/rotary-encoder.md +118 -0
- package/spec/components/forms/color-picker.md +99 -0
- package/spec/components/forms/file-input.md +105 -0
- package/spec/components/forms/search-bar.md +96 -0
- package/spec/components/forms/select.md +143 -0
- package/spec/components/forms/text-input.md +114 -0
- package/spec/components/forms/textarea.md +85 -0
- package/spec/components/indicators/accordion.md +137 -0
- package/spec/components/indicators/badges.md +87 -0
- package/spec/components/indicators/chips.md +93 -0
- package/spec/components/indicators/led-dots.md +103 -0
- package/spec/components/indicators/mode-badge.md +97 -0
- package/spec/components/indicators/profile-badge.md +99 -0
- package/spec/components/indicators/skeleton.md +94 -0
- package/spec/components/indicators/spinners.md +95 -0
- package/spec/components/indicators/status-chips.md +85 -0
- package/spec/components/indicators/transport-controls.md +114 -0
- package/spec/components/meters/battery-icon.md +104 -0
- package/spec/components/meters/eq-bars.md +93 -0
- package/spec/components/meters/ev-meter.md +96 -0
- package/spec/components/meters/exposure-scale.md +110 -0
- package/spec/components/meters/gauge-full.md +102 -0
- package/spec/components/meters/gauge-semi.md +113 -0
- package/spec/components/meters/histogram.md +70 -0
- package/spec/components/meters/level-indicator.md +95 -0
- package/spec/components/meters/oscilloscope.md +83 -0
- package/spec/components/meters/progress-bar.md +84 -0
- package/spec/components/meters/signal-bars.md +80 -0
- package/spec/components/meters/signal-meter.md +84 -0
- package/spec/components/meters/vu-meter.md +88 -0
- package/spec/components/meters/waveform.md +70 -0
- package/spec/components/navigation/breadcrumbs.md +94 -0
- package/spec/components/navigation/context-menu.md +94 -0
- package/spec/components/navigation/d-pad.md +121 -0
- package/spec/components/navigation/drawer.md +103 -0
- package/spec/components/navigation/menu-grid.md +113 -0
- package/spec/components/navigation/menu-list.md +134 -0
- package/spec/components/navigation/pagination.md +100 -0
- package/spec/components/navigation/rack-panel.md +124 -0
- package/spec/components/navigation/scrollbar.md +97 -0
- package/spec/components/navigation/status-bar.md +117 -0
- package/spec/components/navigation/tab-bar.md +104 -0
- package/spec/components/overlays/chassis-panel.md +94 -0
- package/spec/components/overlays/device-bezel.md +83 -0
- package/spec/components/overlays/dialog.md +100 -0
- package/spec/components/overlays/focus-brackets.md +124 -0
- package/spec/components/overlays/grid-overlay.md +93 -0
- package/spec/components/overlays/modal.md +89 -0
- package/spec/components/overlays/panel.md +114 -0
- package/spec/components/overlays/plastic-card.md +92 -0
- package/spec/components/overlays/popover.md +75 -0
- package/spec/components/overlays/toast.md +93 -0
- package/spec/components/overlays/tooltip.md +85 -0
- package/spec/components/readouts/camera-readout.md +123 -0
- package/spec/components/readouts/dot-matrix.md +88 -0
- package/spec/components/readouts/lcd-readout.md +116 -0
- package/spec/components/readouts/resource-monitor.md +98 -0
- package/spec/components/readouts/seven-segment.md +110 -0
- package/spec/components/readouts/signal-display.md +93 -0
- package/spec/components/readouts/timecode-display.md +94 -0
- package/spec/components/sliders/crossfader.md +102 -0
- package/spec/components/sliders/dual-range.md +97 -0
- package/spec/components/sliders/range-fader.md +100 -0
- package/spec/components/sliders/scrubber.md +104 -0
- package/spec/components/sliders/stepper.md +106 -0
- package/spec/components/sliders/vertical-fader.md +116 -0
- package/spec/components/sliders/volume-slider.md +107 -0
- package/spec/components/toggles/dip-switch.md +100 -0
- package/spec/components/toggles/led-checkbox.md +108 -0
- package/spec/components/toggles/power-toggle.md +93 -0
- package/spec/components/toggles/radio-button.md +106 -0
- package/spec/components/toggles/rocker-switch.md +92 -0
- package/spec/components/toggles/slide-switch.md +121 -0
- package/spec/components/toggles/toggle-switch.md +135 -0
- package/spec/compositions/audio-mixer-strip.md +62 -0
- package/spec/compositions/camera-viewfinder.md +66 -0
- package/spec/compositions/phone-interface.md +66 -0
- package/spec/foundation/accessibility.md +33 -0
- package/spec/foundation/canvas.md +20 -0
- package/spec/foundation/depth-model.md +82 -0
- package/spec/foundation/layout.md +33 -0
- package/spec/foundation/materials.md +68 -0
- package/spec/foundation/naming.md +33 -0
- package/spec/foundation/philosophy.md +27 -0
- package/spec/foundation/theme.md +39 -0
- package/spec/foundation/tokens.md +148 -0
- package/spec/guides/extension.md +189 -0
- package/spec/guides/for-llms.md +129 -0
- package/spec/guides/prompt-templates.md +143 -0
- package/spec/spec/components/_index.yaml +822 -0
- package/spec/spec/components/buttons/clear-button.md +89 -0
- package/spec/spec/components/buttons/fn-grid.md +104 -0
- package/spec/spec/components/buttons/gel-button.md +125 -0
- package/spec/spec/components/buttons/icon-button.md +108 -0
- package/spec/spec/components/buttons/keypad-button.md +123 -0
- package/spec/spec/components/buttons/push-button.md +139 -0
- package/spec/spec/components/buttons/rec-button.md +105 -0
- package/spec/spec/components/buttons/rubber-button.md +100 -0
- package/spec/spec/components/buttons/segmented-control.md +95 -0
- package/spec/spec/components/data/assembled-panel.md +135 -0
- package/spec/spec/components/data/data-table.md +116 -0
- package/spec/spec/components/data/film-strip.md +110 -0
- package/spec/spec/components/data/media-grid.md +98 -0
- package/spec/spec/components/dials/click-wheel.md +115 -0
- package/spec/spec/components/dials/cylindrical-horizontal.md +130 -0
- package/spec/spec/components/dials/cylindrical-scroll.md +141 -0
- package/spec/spec/components/dials/cylindrical-vertical.md +100 -0
- package/spec/spec/components/dials/mode-dial.md +123 -0
- package/spec/spec/components/dials/radial-knob.md +150 -0
- package/spec/spec/components/dials/rotary-encoder.md +118 -0
- package/spec/spec/components/forms/color-picker.md +99 -0
- package/spec/spec/components/forms/file-input.md +105 -0
- package/spec/spec/components/forms/search-bar.md +96 -0
- package/spec/spec/components/forms/select.md +143 -0
- package/spec/spec/components/forms/text-input.md +114 -0
- package/spec/spec/components/forms/textarea.md +85 -0
- package/spec/spec/components/indicators/accordion.md +137 -0
- package/spec/spec/components/indicators/badges.md +87 -0
- package/spec/spec/components/indicators/chips.md +93 -0
- package/spec/spec/components/indicators/led-dots.md +103 -0
- package/spec/spec/components/indicators/mode-badge.md +97 -0
- package/spec/spec/components/indicators/profile-badge.md +99 -0
- package/spec/spec/components/indicators/skeleton.md +94 -0
- package/spec/spec/components/indicators/spinners.md +95 -0
- package/spec/spec/components/indicators/status-chips.md +85 -0
- package/spec/spec/components/indicators/transport-controls.md +114 -0
- package/spec/spec/components/meters/battery-icon.md +104 -0
- package/spec/spec/components/meters/eq-bars.md +93 -0
- package/spec/spec/components/meters/ev-meter.md +96 -0
- package/spec/spec/components/meters/exposure-scale.md +110 -0
- package/spec/spec/components/meters/gauge-full.md +102 -0
- package/spec/spec/components/meters/gauge-semi.md +113 -0
- package/spec/spec/components/meters/histogram.md +70 -0
- package/spec/spec/components/meters/level-indicator.md +95 -0
- package/spec/spec/components/meters/oscilloscope.md +83 -0
- package/spec/spec/components/meters/progress-bar.md +84 -0
- package/spec/spec/components/meters/signal-bars.md +80 -0
- package/spec/spec/components/meters/signal-meter.md +84 -0
- package/spec/spec/components/meters/vu-meter.md +88 -0
- package/spec/spec/components/meters/waveform.md +70 -0
- package/spec/spec/components/navigation/breadcrumbs.md +94 -0
- package/spec/spec/components/navigation/context-menu.md +94 -0
- package/spec/spec/components/navigation/d-pad.md +121 -0
- package/spec/spec/components/navigation/drawer.md +103 -0
- package/spec/spec/components/navigation/menu-grid.md +113 -0
- package/spec/spec/components/navigation/menu-list.md +134 -0
- package/spec/spec/components/navigation/pagination.md +100 -0
- package/spec/spec/components/navigation/rack-panel.md +124 -0
- package/spec/spec/components/navigation/scrollbar.md +97 -0
- package/spec/spec/components/navigation/status-bar.md +117 -0
- package/spec/spec/components/navigation/tab-bar.md +104 -0
- package/spec/spec/components/overlays/chassis-panel.md +94 -0
- package/spec/spec/components/overlays/device-bezel.md +83 -0
- package/spec/spec/components/overlays/dialog.md +100 -0
- package/spec/spec/components/overlays/focus-brackets.md +124 -0
- package/spec/spec/components/overlays/grid-overlay.md +93 -0
- package/spec/spec/components/overlays/modal.md +89 -0
- package/spec/spec/components/overlays/panel.md +114 -0
- package/spec/spec/components/overlays/plastic-card.md +92 -0
- package/spec/spec/components/overlays/popover.md +75 -0
- package/spec/spec/components/overlays/toast.md +93 -0
- package/spec/spec/components/overlays/tooltip.md +85 -0
- package/spec/spec/components/readouts/camera-readout.md +123 -0
- package/spec/spec/components/readouts/dot-matrix.md +88 -0
- package/spec/spec/components/readouts/lcd-readout.md +116 -0
- package/spec/spec/components/readouts/resource-monitor.md +98 -0
- package/spec/spec/components/readouts/seven-segment.md +110 -0
- package/spec/spec/components/readouts/signal-display.md +93 -0
- package/spec/spec/components/readouts/timecode-display.md +94 -0
- package/spec/spec/components/sliders/crossfader.md +102 -0
- package/spec/spec/components/sliders/dual-range.md +97 -0
- package/spec/spec/components/sliders/range-fader.md +100 -0
- package/spec/spec/components/sliders/scrubber.md +104 -0
- package/spec/spec/components/sliders/stepper.md +106 -0
- package/spec/spec/components/sliders/vertical-fader.md +116 -0
- package/spec/spec/components/sliders/volume-slider.md +107 -0
- package/spec/spec/components/toggles/dip-switch.md +100 -0
- package/spec/spec/components/toggles/led-checkbox.md +108 -0
- package/spec/spec/components/toggles/power-toggle.md +93 -0
- package/spec/spec/components/toggles/radio-button.md +106 -0
- package/spec/spec/components/toggles/rocker-switch.md +92 -0
- package/spec/spec/components/toggles/slide-switch.md +121 -0
- package/spec/spec/components/toggles/toggle-switch.md +135 -0
- package/spec/spec/compositions/audio-mixer-strip.md +62 -0
- package/spec/spec/compositions/camera-viewfinder.md +66 -0
- package/spec/spec/compositions/phone-interface.md +66 -0
- package/spec/spec/foundation/accessibility.md +33 -0
- package/spec/spec/foundation/canvas.md +20 -0
- package/spec/spec/foundation/depth-model.md +82 -0
- package/spec/spec/foundation/layout.md +33 -0
- package/spec/spec/foundation/materials.md +68 -0
- package/spec/spec/foundation/naming.md +33 -0
- package/spec/spec/foundation/philosophy.md +27 -0
- package/spec/spec/foundation/theme.md +39 -0
- package/spec/spec/foundation/tokens.md +148 -0
- package/spec/spec/guides/extension.md +189 -0
- package/spec/spec/guides/for-llms.md +129 -0
- package/spec/spec/guides/prompt-templates.md +143 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Select / Dropdown
|
|
3
|
+
id: select
|
|
4
|
+
class: .select-wrap
|
|
5
|
+
category: forms
|
|
6
|
+
index: 4
|
|
7
|
+
materials: [glossy-polycarbonate]
|
|
8
|
+
sizes: [default]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: true
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Select / Dropdown
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Camera menu item selectors, audio equipment preset browsers.
|
|
18
|
+
**Mechanism**: A mechanical selector switch adapted to digital form. In hardware, this was a rotary switch with labeled positions or a push-button that cycled through options. The UI version shows the currently selected value in a raised trigger element (resembling a button), and reveals all options in a dropdown panel (resembling the iPod menu list G2) when activated. The arrow indicator rotates 180 degrees on open, mimicking the flip direction of a mechanical indicator flag.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Width | 180px |
|
|
25
|
+
| Trigger height | 36px |
|
|
26
|
+
| Trigger padding | 0 12px |
|
|
27
|
+
| Dropdown margin-top | 4px |
|
|
28
|
+
| Font size | 11px |
|
|
29
|
+
| Option padding | 8px 12px |
|
|
30
|
+
| Arrow font size | 8px |
|
|
31
|
+
|
|
32
|
+
## CSS Recipe
|
|
33
|
+
|
|
34
|
+
### Wrapper (`.select-wrap`)
|
|
35
|
+
```css
|
|
36
|
+
.select-wrap { position: relative; width: 180px; }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Trigger (`.select-trigger`)
|
|
40
|
+
```css
|
|
41
|
+
.select-trigger {
|
|
42
|
+
width: 100%; height: 36px; padding: 0 12px; display: flex;
|
|
43
|
+
align-items: center; justify-content: space-between;
|
|
44
|
+
background: var(--bg-surface); border: 1px solid var(--border-mid);
|
|
45
|
+
border-radius: var(--radius-md); cursor: pointer;
|
|
46
|
+
font-family: var(--font-ui); font-size: 11px; font-weight: 500;
|
|
47
|
+
color: var(--text-primary); letter-spacing: 0.5px;
|
|
48
|
+
box-shadow: 0 2px 0 var(--border-deep), inset 0 1px 0 var(--glossy-hi);
|
|
49
|
+
transition: border-color 0.15s;
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Trigger hover
|
|
54
|
+
```css
|
|
55
|
+
.select-trigger:hover { border-color: var(--border-hi); }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Arrow (`.select-arrow`)
|
|
59
|
+
```css
|
|
60
|
+
.select-arrow { font-size: 8px; color: var(--text-muted); transition: transform 0.2s; }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Dropdown (`.select-dropdown`)
|
|
64
|
+
```css
|
|
65
|
+
.select-dropdown {
|
|
66
|
+
position: absolute; top: 100%; left: 0; right: 0; margin-top: 4px;
|
|
67
|
+
background: var(--bg-raised); border: 1px solid var(--border-mid);
|
|
68
|
+
border-radius: var(--radius-md); overflow: hidden;
|
|
69
|
+
box-shadow: 0 4px 16px rgba(0,0,0,0.3); z-index: 10;
|
|
70
|
+
display: none;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Open state
|
|
75
|
+
```css
|
|
76
|
+
.select-wrap.open .select-dropdown { display: block; }
|
|
77
|
+
.select-wrap.open .select-arrow { transform: rotate(180deg); }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Option (`.select-option`)
|
|
81
|
+
```css
|
|
82
|
+
.select-option {
|
|
83
|
+
padding: 8px 12px; cursor: pointer;
|
|
84
|
+
font-family: var(--font-ui); font-size: 11px; font-weight: 500;
|
|
85
|
+
color: var(--text-secondary); transition: background 0.1s;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Option hover
|
|
90
|
+
```css
|
|
91
|
+
.select-option:hover { background: var(--glow-color); color: var(--text-primary); }
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Option selected
|
|
95
|
+
```css
|
|
96
|
+
.select-option.selected { color: var(--amber); background: rgba(245,166,35,0.06); }
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## HTML Structure
|
|
100
|
+
```html
|
|
101
|
+
<div class="select-wrap" id="selectDemo">
|
|
102
|
+
<div class="select-trigger" onclick="document.getElementById('selectDemo').classList.toggle('open')">
|
|
103
|
+
<span>JPEG Fine</span>
|
|
104
|
+
<span class="select-arrow">▼</span>
|
|
105
|
+
</div>
|
|
106
|
+
<div class="select-dropdown">
|
|
107
|
+
<div class="select-option selected">JPEG Fine</div>
|
|
108
|
+
<div class="select-option">JPEG Normal</div>
|
|
109
|
+
<div class="select-option">RAW</div>
|
|
110
|
+
<div class="select-option">RAW + JPEG</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Size Variants
|
|
116
|
+
No size variants defined.
|
|
117
|
+
|
|
118
|
+
## Material Variants
|
|
119
|
+
- Trigger uses raised surface (Tier 2 depth: 2px bottom shadow + glossy highlight)
|
|
120
|
+
- Dropdown uses elevated surface (`--bg-raised` + floating shadow)
|
|
121
|
+
|
|
122
|
+
## Theme Behavior
|
|
123
|
+
- Trigger background swaps via `--bg-surface`
|
|
124
|
+
- Dropdown background swaps via `--bg-raised`
|
|
125
|
+
- Selected option uses amber with amber-tinted background
|
|
126
|
+
- Shadow depth reduces in light mode
|
|
127
|
+
|
|
128
|
+
## Constraints
|
|
129
|
+
1. Trigger MUST look like a button (raised shadow, glossy highlight)
|
|
130
|
+
2. Arrow MUST rotate 180 degrees when dropdown opens
|
|
131
|
+
3. Dropdown MUST appear below trigger with 4px gap
|
|
132
|
+
4. Dropdown MUST use z-index: 10 to overlay other content
|
|
133
|
+
5. Selected option MUST be amber with subtle amber background
|
|
134
|
+
6. MUST toggle via `.open` class on `.select-wrap`
|
|
135
|
+
7. Only ONE option can be `.selected` at a time
|
|
136
|
+
|
|
137
|
+
## Accessibility
|
|
138
|
+
- Trigger should have `role="combobox"` or `role="button"` with `aria-haspopup="listbox"`
|
|
139
|
+
- Trigger should have `aria-expanded="true/false"`
|
|
140
|
+
- Dropdown should have `role="listbox"`
|
|
141
|
+
- Options should have `role="option"` with `aria-selected`
|
|
142
|
+
- Support Up/Down arrow keys, Enter to select, Escape to close
|
|
143
|
+
- Home/End keys should jump to first/last option
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Text Input
|
|
3
|
+
id: text-input
|
|
4
|
+
class: .text-input
|
|
5
|
+
category: forms
|
|
6
|
+
index: 1
|
|
7
|
+
materials: [phosphor-screen]
|
|
8
|
+
sizes: [sm, default, lg]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: false
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Text Input
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: LCD text entry fields on pro audio equipment (Tascam, Zoom), camera file naming dialogs, synthesizer patch naming.
|
|
18
|
+
**Mechanism**: Styled as a recessed phosphor display field -- the same cavity used for readout displays, but editable. The text is entered via an external input method. The recessed appearance (inset shadow) communicates that this area accepts input, rather than merely displaying a value. On focus, the border illuminates amber -- simulating an "active channel" indicator LED strip around the input field.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Default width | 200px |
|
|
25
|
+
| Default height | 36px |
|
|
26
|
+
| Padding | 0 12px |
|
|
27
|
+
| Border radius | `--radius-md` (8px) |
|
|
28
|
+
| Font size | 12px |
|
|
29
|
+
| Font family | `--font-mono` |
|
|
30
|
+
|
|
31
|
+
## CSS Recipe
|
|
32
|
+
|
|
33
|
+
### Default state
|
|
34
|
+
```css
|
|
35
|
+
.text-input {
|
|
36
|
+
width: 200px; height: 36px; padding: 0 12px;
|
|
37
|
+
background: var(--bg-inset); border: 1px solid var(--border-mid);
|
|
38
|
+
border-radius: var(--radius-md); color: var(--text-primary);
|
|
39
|
+
font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.5px;
|
|
40
|
+
box-shadow: var(--shadow-inset); outline: none;
|
|
41
|
+
transition: border-color 0.15s, box-shadow 0.15s;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Placeholder
|
|
46
|
+
```css
|
|
47
|
+
.text-input::placeholder { color: var(--text-muted); }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Focus
|
|
51
|
+
```css
|
|
52
|
+
.text-input:focus { border-color: var(--amber); box-shadow: var(--shadow-inset), 0 0 0 1px var(--amber-dim); }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Error
|
|
56
|
+
```css
|
|
57
|
+
.text-input.error { border-color: var(--red-alert); }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Size: Small
|
|
61
|
+
```css
|
|
62
|
+
.text-input.sm { height: 28px; font-size: 10px; width: 140px; }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Size: Large
|
|
66
|
+
```css
|
|
67
|
+
.text-input.lg { height: 42px; font-size: 14px; width: 260px; }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## HTML Structure
|
|
71
|
+
```html
|
|
72
|
+
<!-- Standard -->
|
|
73
|
+
<input class="text-input" placeholder="Standard input...">
|
|
74
|
+
|
|
75
|
+
<!-- Small -->
|
|
76
|
+
<input class="text-input sm" placeholder="Small input...">
|
|
77
|
+
|
|
78
|
+
<!-- Large -->
|
|
79
|
+
<input class="text-input lg" placeholder="Large input...">
|
|
80
|
+
|
|
81
|
+
<!-- Error state -->
|
|
82
|
+
<input class="text-input error" placeholder="Error state..." value="Invalid">
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Size Variants
|
|
86
|
+
|
|
87
|
+
| Size | Height | Width | Font Size |
|
|
88
|
+
|------|--------|-------|-----------|
|
|
89
|
+
| `.sm` | 28px | 140px | 10px |
|
|
90
|
+
| default | 36px | 200px | 12px |
|
|
91
|
+
| `.lg` | 42px | 260px | 14px |
|
|
92
|
+
|
|
93
|
+
## Material Variants
|
|
94
|
+
No material variants. Uses phosphor screen (recessed display cavity) styling.
|
|
95
|
+
|
|
96
|
+
## Theme Behavior
|
|
97
|
+
- Background uses `--bg-inset` (deep recessed cavity)
|
|
98
|
+
- Inset shadow: dark mode `rgba(0,0,0,0.6)`, light mode `rgba(0,0,0,0.08)`
|
|
99
|
+
- Focus border always amber
|
|
100
|
+
- Error border always red
|
|
101
|
+
|
|
102
|
+
## Constraints
|
|
103
|
+
1. MUST use recessed styling (inset shadow + `--bg-inset` background)
|
|
104
|
+
2. MUST use monospace font (`--font-mono`) for data entry consistency
|
|
105
|
+
3. Focus state MUST illuminate amber border with amber outer ring glow
|
|
106
|
+
4. Error state MUST use `--red-alert` border color
|
|
107
|
+
5. MUST NOT use outline -- use border-color transition instead
|
|
108
|
+
6. Placeholder text MUST use `--text-muted`
|
|
109
|
+
|
|
110
|
+
## Accessibility
|
|
111
|
+
- Use native `<input>` element
|
|
112
|
+
- Include associated `<label>` element
|
|
113
|
+
- Error state should include `aria-invalid="true"` and `aria-describedby` pointing to error message
|
|
114
|
+
- Focus ring is provided by amber border glow (no separate outline needed)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Textarea
|
|
3
|
+
id: textarea
|
|
4
|
+
class: .text-area
|
|
5
|
+
category: forms
|
|
6
|
+
index: 2
|
|
7
|
+
materials: [phosphor-screen]
|
|
8
|
+
sizes: [default]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: false
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Textarea
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: LCD text entry fields on pro audio equipment (Tascam, Zoom), camera file naming dialogs, synthesizer patch naming.
|
|
18
|
+
**Mechanism**: Same mechanical principle as the Text Input (H1), but taller to accept multi-line content. Uses the same recessed phosphor screen styling.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Width | 240px |
|
|
25
|
+
| Height | 80px |
|
|
26
|
+
| Padding | 10px 12px |
|
|
27
|
+
| Border radius | `--radius-md` (8px) |
|
|
28
|
+
| Font size | 12px |
|
|
29
|
+
| Font family | `--font-mono` |
|
|
30
|
+
| Resize | vertical |
|
|
31
|
+
|
|
32
|
+
## CSS Recipe
|
|
33
|
+
|
|
34
|
+
### Default state
|
|
35
|
+
```css
|
|
36
|
+
.text-area {
|
|
37
|
+
width: 240px; height: 80px; padding: 10px 12px;
|
|
38
|
+
background: var(--bg-inset); border: 1px solid var(--border-mid);
|
|
39
|
+
border-radius: var(--radius-md); color: var(--text-primary);
|
|
40
|
+
font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.5px;
|
|
41
|
+
box-shadow: var(--shadow-inset); outline: none; resize: vertical;
|
|
42
|
+
transition: border-color 0.15s;
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Placeholder
|
|
47
|
+
```css
|
|
48
|
+
.text-area::placeholder { color: var(--text-muted); }
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Focus
|
|
52
|
+
```css
|
|
53
|
+
.text-area:focus { border-color: var(--amber); }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## HTML Structure
|
|
57
|
+
```html
|
|
58
|
+
<textarea class="text-area" placeholder="Multi-line entry..."></textarea>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Size Variants
|
|
62
|
+
No size variants defined. Height is adjustable via `resize: vertical`.
|
|
63
|
+
|
|
64
|
+
## Material Variants
|
|
65
|
+
No material variants. Uses phosphor screen (recessed display cavity) styling.
|
|
66
|
+
|
|
67
|
+
## Theme Behavior
|
|
68
|
+
- Background uses `--bg-inset` (deep recessed cavity)
|
|
69
|
+
- Inset shadow adapts: strong in dark mode, subtle in light mode
|
|
70
|
+
- Focus border always amber
|
|
71
|
+
- Text and placeholder colors swap via theme tokens
|
|
72
|
+
|
|
73
|
+
## Constraints
|
|
74
|
+
1. MUST use recessed styling (inset shadow + `--bg-inset` background)
|
|
75
|
+
2. MUST use monospace font (`--font-mono`)
|
|
76
|
+
3. Focus state MUST illuminate amber border
|
|
77
|
+
4. MUST allow vertical resize only (`resize: vertical`)
|
|
78
|
+
5. MUST NOT use outline
|
|
79
|
+
6. MUST have top padding (10px) for comfortable text entry
|
|
80
|
+
|
|
81
|
+
## Accessibility
|
|
82
|
+
- Use native `<textarea>` element
|
|
83
|
+
- Include associated `<label>` element
|
|
84
|
+
- Support standard textarea keyboard behavior (Enter for newline, Tab to move focus)
|
|
85
|
+
- Focus ring is provided by amber border (no separate outline needed)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Accordion
|
|
3
|
+
id: accordion
|
|
4
|
+
class: .accordion
|
|
5
|
+
category: indicators
|
|
6
|
+
index: 9
|
|
7
|
+
materials: [glossy-polycarbonate]
|
|
8
|
+
sizes: [default]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: true
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Accordion
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Camera menu subsections, audio equipment nested parameter groups, phone settings menus.
|
|
18
|
+
**Mechanism**: A vertically stacking fold mechanism -- like the bellows of an accordion or a folding display. Each section header is clickable; clicking it expands the body content below (revealing hidden settings) while other sections remain collapsed. The chevron arrow rotates 90 degrees to indicate the expanded state.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Min width | 200px |
|
|
25
|
+
| Header padding | 8px 12px |
|
|
26
|
+
| Body padding (open) | 4px 12px 10px |
|
|
27
|
+
| Header font size | 10px |
|
|
28
|
+
| Body font size | 9px |
|
|
29
|
+
| Arrow font size | 8px |
|
|
30
|
+
| Max body height | 80px |
|
|
31
|
+
| Expand duration | 0.25s |
|
|
32
|
+
| Easing | `--ease-out` |
|
|
33
|
+
|
|
34
|
+
## CSS Recipe
|
|
35
|
+
|
|
36
|
+
### Container (`.accordion`)
|
|
37
|
+
```css
|
|
38
|
+
.accordion {
|
|
39
|
+
background: var(--bg-raised); border: 1px solid var(--border-subtle);
|
|
40
|
+
border-radius: var(--radius-md); overflow: hidden; min-width: 200px;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Item (`.accordion-item`)
|
|
45
|
+
```css
|
|
46
|
+
.accordion-item { border-bottom: 1px solid var(--border-subtle); }
|
|
47
|
+
.accordion-item:last-child { border-bottom: none; }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Header (`.accordion-header`)
|
|
51
|
+
```css
|
|
52
|
+
.accordion-header {
|
|
53
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
54
|
+
padding: 8px 12px; cursor: pointer;
|
|
55
|
+
font-family: var(--font-ui); font-size: 10px; font-weight: 500;
|
|
56
|
+
color: var(--text-primary); letter-spacing: 1px; transition: background 0.12s;
|
|
57
|
+
}
|
|
58
|
+
.accordion-header:hover { background: var(--glow-color); }
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Arrow (`.acc-arrow`)
|
|
62
|
+
```css
|
|
63
|
+
.acc-arrow { font-size: 8px; color: var(--text-muted); transition: transform 0.2s; }
|
|
64
|
+
.accordion-item.open .acc-arrow { transform: rotate(90deg); }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Body (`.accordion-body`)
|
|
68
|
+
```css
|
|
69
|
+
.accordion-body {
|
|
70
|
+
padding: 0 12px; max-height: 0; overflow: hidden;
|
|
71
|
+
transition: max-height 0.25s var(--ease-out), padding 0.25s var(--ease-out);
|
|
72
|
+
}
|
|
73
|
+
.accordion-item.open .accordion-body { max-height: 80px; padding: 4px 12px 10px; }
|
|
74
|
+
.accordion-body p { font-family: var(--font-ui); font-size: 9px; color: var(--text-secondary); line-height: 1.6; }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## HTML Structure
|
|
78
|
+
```html
|
|
79
|
+
<div class="accordion">
|
|
80
|
+
<div class="accordion-item open">
|
|
81
|
+
<div class="accordion-header" onclick="this.parentElement.classList.toggle('open')">
|
|
82
|
+
<span>Display Settings</span>
|
|
83
|
+
<span class="acc-arrow">▶</span>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="accordion-body">
|
|
86
|
+
<p>Brightness, contrast, and color temperature controls for the main display output.</p>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="accordion-item">
|
|
90
|
+
<div class="accordion-header" onclick="this.parentElement.classList.toggle('open')">
|
|
91
|
+
<span>Audio Settings</span>
|
|
92
|
+
<span class="acc-arrow">▶</span>
|
|
93
|
+
</div>
|
|
94
|
+
<div class="accordion-body">
|
|
95
|
+
<p>Master volume, channel balance, and output routing configuration.</p>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
<div class="accordion-item">
|
|
99
|
+
<div class="accordion-header" onclick="this.parentElement.classList.toggle('open')">
|
|
100
|
+
<span>Network</span>
|
|
101
|
+
<span class="acc-arrow">▶</span>
|
|
102
|
+
</div>
|
|
103
|
+
<div class="accordion-body">
|
|
104
|
+
<p>Wi-Fi, Bluetooth, and wired connection settings.</p>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Size Variants
|
|
111
|
+
No size variants defined.
|
|
112
|
+
|
|
113
|
+
## Material Variants
|
|
114
|
+
No material variants. Uses standard raised surface.
|
|
115
|
+
|
|
116
|
+
## Theme Behavior
|
|
117
|
+
- Background swaps via `--bg-raised`
|
|
118
|
+
- Separators swap via `--border-subtle`
|
|
119
|
+
- Hover highlight uses `--glow-color`
|
|
120
|
+
- Body text uses `--text-secondary`
|
|
121
|
+
- Arrow uses `--text-muted`
|
|
122
|
+
|
|
123
|
+
## Constraints
|
|
124
|
+
1. MUST use `max-height` animation for expand/collapse (not display toggle)
|
|
125
|
+
2. Arrow MUST rotate 90 degrees when open (right-pointing to down-pointing)
|
|
126
|
+
3. Transition MUST use `--ease-out` easing for smooth deceleration
|
|
127
|
+
4. Multiple items CAN be open simultaneously
|
|
128
|
+
5. Items MUST be separated by `--border-subtle` borders
|
|
129
|
+
6. Last item MUST NOT have a bottom border
|
|
130
|
+
7. Body max-height when open is 80px (adjust for content needs)
|
|
131
|
+
|
|
132
|
+
## Accessibility
|
|
133
|
+
- Use `<details>` and `<summary>` for native behavior, or implement ARIA:
|
|
134
|
+
- Headers: `role="button"`, `aria-expanded="true/false"`, `aria-controls="body-id"`
|
|
135
|
+
- Body: `role="region"`, `aria-labelledby="header-id"`
|
|
136
|
+
- Support Enter/Space to toggle on focused header
|
|
137
|
+
- Support Up/Down to navigate between headers
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Badges
|
|
3
|
+
id: badges
|
|
4
|
+
class: .badge
|
|
5
|
+
category: indicators
|
|
6
|
+
index: 3
|
|
7
|
+
materials: [glossy-polycarbonate]
|
|
8
|
+
sizes: [default]
|
|
9
|
+
interactive: false
|
|
10
|
+
requires_js: false
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Badges
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Software version labels, notification count badges, iOS-style app icon badges.
|
|
18
|
+
**Mechanism**: Small, high-contrast labels. The colored background (blue, green, red, amber) fills the entire pill shape, derived from the colored button caps used on broadcast equipment (red = ON AIR, green = STANDBY, etc.).
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Padding | 2px 8px |
|
|
25
|
+
| Border radius | `--radius-pill` (100px) |
|
|
26
|
+
| Font size | 9px |
|
|
27
|
+
| Font weight | 600 |
|
|
28
|
+
| Letter spacing | 1px |
|
|
29
|
+
|
|
30
|
+
## CSS Recipe
|
|
31
|
+
|
|
32
|
+
### Base (`.badge`)
|
|
33
|
+
```css
|
|
34
|
+
.badge {
|
|
35
|
+
display: inline-flex; align-items: center; gap: 4px;
|
|
36
|
+
padding: 2px 8px; border-radius: var(--radius-pill);
|
|
37
|
+
font-family: var(--font-ui); font-size: 9px; font-weight: 600; letter-spacing: 1px;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Color variants
|
|
42
|
+
```css
|
|
43
|
+
.badge.blue { background: var(--blue-info); color: #fff; }
|
|
44
|
+
.badge.green { background: var(--green-on); color: #fff; }
|
|
45
|
+
.badge.red { background: var(--red-alert); color: #fff; }
|
|
46
|
+
.badge.amber { background: var(--amber); color: #1a1a1a; }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## HTML Structure
|
|
50
|
+
```html
|
|
51
|
+
<span class="badge blue">NEW</span>
|
|
52
|
+
<span class="badge green">ONLINE</span>
|
|
53
|
+
<span class="badge red">LIVE</span>
|
|
54
|
+
<span class="badge amber">PRO</span>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Size Variants
|
|
58
|
+
No size variants defined.
|
|
59
|
+
|
|
60
|
+
## Material Variants
|
|
61
|
+
|
|
62
|
+
| Variant | Class | Background | Text Color |
|
|
63
|
+
|---------|-------|------------|------------|
|
|
64
|
+
| Blue | `.badge.blue` | `--blue-info` | White |
|
|
65
|
+
| Green | `.badge.green` | `--green-on` | White |
|
|
66
|
+
| Red | `.badge.red` | `--red-alert` | White |
|
|
67
|
+
| Amber | `.badge.amber` | `--amber` | Dark (#1a1a1a) |
|
|
68
|
+
|
|
69
|
+
## Theme Behavior
|
|
70
|
+
- Badge colors are constant across themes (accent colors don't change)
|
|
71
|
+
- Amber badge uses dark text (high contrast against bright amber)
|
|
72
|
+
- Other badges use white text
|
|
73
|
+
|
|
74
|
+
## Constraints
|
|
75
|
+
1. MUST use pill border-radius (`--radius-pill`)
|
|
76
|
+
2. MUST use filled background (not outlined)
|
|
77
|
+
3. Amber badge MUST use dark text (#1a1a1a) for contrast
|
|
78
|
+
4. All other badges MUST use white text
|
|
79
|
+
5. Font weight MUST be 600 (bold for small size readability)
|
|
80
|
+
6. Padding is minimal (2px 8px) -- badges should be compact
|
|
81
|
+
7. MUST NOT be interactive (badges are read-only labels)
|
|
82
|
+
|
|
83
|
+
## Accessibility
|
|
84
|
+
- Use `<span>` element (inline, non-interactive)
|
|
85
|
+
- If badge conveys status, include `role="status"` or equivalent
|
|
86
|
+
- Color alone should not be the only indicator -- include descriptive text
|
|
87
|
+
- Ensure sufficient color contrast (all variants meet WCAG AA)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Selectable Chips
|
|
3
|
+
id: chips
|
|
4
|
+
class: .chip
|
|
5
|
+
category: indicators
|
|
6
|
+
index: 2
|
|
7
|
+
materials: [glossy-polycarbonate]
|
|
8
|
+
sizes: [default]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: true
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Selectable Chips
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: iPod genre/playlist tags, camera filter selectors.
|
|
18
|
+
**Mechanism**: Interactive chip elements that the user can toggle to filter or select options. Distinguished from status chips (J1) by being interactive. The pill shape with optional colored dot comes from the physical form factor of panel-mounted indicator LEDs with silk-screened labels.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Padding | 4px 10px |
|
|
25
|
+
| Border radius | `--radius-pill` (100px) |
|
|
26
|
+
| Font size | 9px |
|
|
27
|
+
| Letter spacing | 1px |
|
|
28
|
+
| Dot size | 6x6px |
|
|
29
|
+
| Dot-label gap | 4px |
|
|
30
|
+
|
|
31
|
+
## CSS Recipe
|
|
32
|
+
|
|
33
|
+
### Default state
|
|
34
|
+
```css
|
|
35
|
+
.chip {
|
|
36
|
+
display: inline-flex; align-items: center; gap: 4px;
|
|
37
|
+
padding: 4px 10px; border-radius: var(--radius-pill);
|
|
38
|
+
font-family: var(--font-ui); font-size: 9px; font-weight: 500;
|
|
39
|
+
letter-spacing: 1px; background: var(--bg-surface);
|
|
40
|
+
border: 1px solid var(--border-subtle); color: var(--text-secondary);
|
|
41
|
+
cursor: pointer; transition: all 0.15s;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Hover
|
|
46
|
+
```css
|
|
47
|
+
.chip:hover { border-color: var(--border-mid); }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Active (selected)
|
|
51
|
+
```css
|
|
52
|
+
.chip.active { background: rgba(68,119,204,0.1); border-color: var(--blue-info); color: var(--blue-info); }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Dot indicator (`.chip-dot`)
|
|
56
|
+
```css
|
|
57
|
+
.chip .chip-dot { width: 6px; height: 6px; border-radius: 50%; display: inline-block; }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## HTML Structure
|
|
61
|
+
```html
|
|
62
|
+
<div class="flex-row" style="gap:6px">
|
|
63
|
+
<div class="chip active"><span class="chip-dot" style="background:var(--blue-info)"></span>4K</div>
|
|
64
|
+
<div class="chip">1080p</div>
|
|
65
|
+
<div class="chip">720p</div>
|
|
66
|
+
</div>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Size Variants
|
|
70
|
+
No size variants defined.
|
|
71
|
+
|
|
72
|
+
## Material Variants
|
|
73
|
+
No material variants. Uses surface background with subtle border.
|
|
74
|
+
|
|
75
|
+
## Theme Behavior
|
|
76
|
+
- Background swaps via `--bg-surface`
|
|
77
|
+
- Border swaps via `--border-subtle`
|
|
78
|
+
- Active state uses blue with blue-tinted background (constant across themes)
|
|
79
|
+
- Dot color is set inline or via accent color classes
|
|
80
|
+
|
|
81
|
+
## Constraints
|
|
82
|
+
1. MUST use pill border-radius (`--radius-pill`, 100px) -- distinguishes from status chips
|
|
83
|
+
2. Active state MUST use `--blue-info` (not amber like status chips)
|
|
84
|
+
3. Active background MUST be semi-transparent blue (10% opacity)
|
|
85
|
+
4. MUST be interactive (cursor pointer, hover state)
|
|
86
|
+
5. Optional dot indicator MUST be 6x6px circle
|
|
87
|
+
6. Multiple chips CAN be active simultaneously (multi-select, unlike segmented control)
|
|
88
|
+
|
|
89
|
+
## Accessibility
|
|
90
|
+
- Each chip should be a `<button>` or have `role="checkbox"` / `role="option"`
|
|
91
|
+
- Active state: `aria-pressed="true"` (for toggle) or `aria-selected="true"` (for selection)
|
|
92
|
+
- If used as filter group, container should have `role="group"` with `aria-label`
|
|
93
|
+
- Support Space/Enter to toggle
|