@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,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Clear/Glass Button
|
|
3
|
+
id: clear-btn
|
|
4
|
+
class: .clear-btn
|
|
5
|
+
category: buttons
|
|
6
|
+
index: 4
|
|
7
|
+
materials: [glass]
|
|
8
|
+
sizes: [md]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: false
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Clear/Glass Button
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: iMac G3 (1998) power button, clear PSP UMD door latch, transparent phone cases (2003-2006 era).
|
|
18
|
+
**Mechanism**: Dome switch underneath with optically clear or frosted PMMA (acrylic) / polycarbonate keycap. Chemically etched or bead-blasted surface scatters light creating translucent diffusion effect.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Material | Clear or frosted PMMA / polycarbonate |
|
|
25
|
+
| Surface | Transparent with light scattering |
|
|
26
|
+
| Shadow | None (glass sits flush, minimal edge profile) |
|
|
27
|
+
| Blur | 4px backdrop-filter for frosted glass effect |
|
|
28
|
+
|
|
29
|
+
## CSS Recipe
|
|
30
|
+
|
|
31
|
+
### Default State
|
|
32
|
+
```css
|
|
33
|
+
.clear-btn {
|
|
34
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
35
|
+
font-family: var(--font-ui); font-size: 10px; font-weight: 500;
|
|
36
|
+
letter-spacing: 1px; color: var(--text-secondary);
|
|
37
|
+
background: var(--clear-glass);
|
|
38
|
+
border: 1px solid var(--border-subtle); border-radius: var(--radius-md);
|
|
39
|
+
cursor: pointer; backdrop-filter: blur(4px);
|
|
40
|
+
height: 36px; min-width: 60px; padding: 0 12px;
|
|
41
|
+
transition: background 0.15s, border-color 0.15s;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Hover State
|
|
46
|
+
```css
|
|
47
|
+
.clear-btn:hover { background: var(--glossy-md); border-color: var(--border-mid); }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Active (Pressed) State
|
|
51
|
+
```css
|
|
52
|
+
.clear-btn:active { transform: translateY(1px); }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Active (Selected) State
|
|
56
|
+
```css
|
|
57
|
+
.clear-btn.active { border-color: var(--blue-info); color: var(--blue-info); }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## HTML Structure
|
|
61
|
+
```html
|
|
62
|
+
<!-- Basic -->
|
|
63
|
+
<button class="clear-btn">CLEAR</button>
|
|
64
|
+
|
|
65
|
+
<!-- Active -->
|
|
66
|
+
<button class="clear-btn active">ACTIVE</button>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Size Variants
|
|
70
|
+
No explicit size variants defined. Default only.
|
|
71
|
+
|
|
72
|
+
## Material Variants
|
|
73
|
+
Single material: glass (translucent). No gradient, flat transparency with `backdrop-filter`.
|
|
74
|
+
|
|
75
|
+
## Theme Behavior
|
|
76
|
+
- Dark: `--clear-glass: rgba(255,255,255,0.08)` -- mostly transparent
|
|
77
|
+
- Light: `--clear-glass: rgba(255,255,255,0.5)` -- more opaque frosted effect
|
|
78
|
+
- Border colors swap via `--border-subtle` token
|
|
79
|
+
|
|
80
|
+
## Constraints
|
|
81
|
+
1. Background MUST be flat `rgba` (no gradient). Glass does not have gradient appearance.
|
|
82
|
+
2. `backdrop-filter: blur(4px)` is REQUIRED for the frosted glass effect.
|
|
83
|
+
3. MUST NOT have a bottom-edge shadow (`0 Npx 0`). Glass does not cast the same hard edge as plastic.
|
|
84
|
+
4. Border MUST be subtle (1px solid border-subtle). Glass edges are thin.
|
|
85
|
+
|
|
86
|
+
## Accessibility
|
|
87
|
+
- Uses native `<button>` element
|
|
88
|
+
- Keyboard: Enter/Space to activate
|
|
89
|
+
- Focus: Browser default focus ring preserved
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Function Grid
|
|
3
|
+
id: fn-btn
|
|
4
|
+
class: .fn-btn
|
|
5
|
+
category: buttons
|
|
6
|
+
index: 7
|
|
7
|
+
materials: [panel]
|
|
8
|
+
sizes: [md]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: false
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Function Grid
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Sony Alpha custom button matrix (C1-C4), Fujifilm X-T4 Fn button grid, Nikon Z9 illuminated button panel.
|
|
18
|
+
**Mechanism**: Identical dome switches to push-btn, arranged in a 2x2 or 2x3 grid on a sub-panel. Each button has a printed icon and label. On pro cameras, buttons often have backlit legends -- a small LED behind translucent legend text illuminates the active function.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Grid layout | 2 or 3 columns |
|
|
25
|
+
| Button height | 52px |
|
|
26
|
+
| Gap | 8px |
|
|
27
|
+
| Icon size | 20x20px SVG |
|
|
28
|
+
| Label font | 8px, 1.5px letter-spacing |
|
|
29
|
+
|
|
30
|
+
## CSS Recipe
|
|
31
|
+
|
|
32
|
+
### Grid Container
|
|
33
|
+
```css
|
|
34
|
+
.fn-grid { display: grid; gap: 8px; }
|
|
35
|
+
.fn-grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
|
|
36
|
+
.fn-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Button Default State
|
|
40
|
+
```css
|
|
41
|
+
.fn-btn {
|
|
42
|
+
height: 52px; background: var(--bg-surface);
|
|
43
|
+
border: 1px solid var(--border-deep); border-radius: var(--radius-md);
|
|
44
|
+
cursor: pointer; display: flex; align-items: center; justify-content: center;
|
|
45
|
+
flex-direction: column; gap: 4px;
|
|
46
|
+
box-shadow: 0 2px 0 var(--border-deep), inset 0 1px 0 var(--border-hi);
|
|
47
|
+
transition: transform 0.07s, box-shadow 0.07s, background 0.1s;
|
|
48
|
+
color: var(--text-secondary); outline: none;
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Active (Pressed) State
|
|
53
|
+
```css
|
|
54
|
+
.fn-btn:active {
|
|
55
|
+
transform: translateY(1px);
|
|
56
|
+
box-shadow: 0 1px 0 var(--border-deep); background: var(--bg-panel);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Active (Selected/Backlit) State
|
|
61
|
+
```css
|
|
62
|
+
.fn-btn.fn-active { background: #1c1a14; border-color: #3a3000; color: var(--amber); }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Child Elements
|
|
66
|
+
```css
|
|
67
|
+
.fn-btn svg { width: 20px; height: 20px; flex-shrink: 0; }
|
|
68
|
+
.fn-btn span { font-size: 8px; letter-spacing: 1.5px; color: inherit; text-transform: uppercase; }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## HTML Structure
|
|
72
|
+
```html
|
|
73
|
+
<div class="fn-grid cols-3" style="width:180px">
|
|
74
|
+
<button class="fn-btn fn-active"><span>WB</span></button>
|
|
75
|
+
<button class="fn-btn"><span>ISO</span></button>
|
|
76
|
+
<button class="fn-btn"><span>AF</span></button>
|
|
77
|
+
<button class="fn-btn"><span>DR</span></button>
|
|
78
|
+
<button class="fn-btn"><span>EV</span></button>
|
|
79
|
+
<button class="fn-btn"><span>MF</span></button>
|
|
80
|
+
</div>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Size Variants
|
|
84
|
+
No explicit size variants. Button height is fixed at 52px; grid width is set by container.
|
|
85
|
+
|
|
86
|
+
## Material Variants
|
|
87
|
+
Default material is panel surface. Active state uses a warm dark background with amber border.
|
|
88
|
+
|
|
89
|
+
## Theme Behavior
|
|
90
|
+
- Surface colors swap via `--bg-surface` token
|
|
91
|
+
- Active state uses hardcoded dark tones (`#1c1a14`, `#3a3000`) -- may need light theme override
|
|
92
|
+
- Text color inherits, swapping with theme
|
|
93
|
+
|
|
94
|
+
## Constraints
|
|
95
|
+
1. Grid MUST use CSS Grid with explicit column count classes (`.cols-2`, `.cols-3`).
|
|
96
|
+
2. Active button legend MUST turn amber to simulate backlit LED.
|
|
97
|
+
3. Label text MUST be uppercase, 8px, with wide letter-spacing.
|
|
98
|
+
4. Icons and labels stack vertically (flex-direction: column).
|
|
99
|
+
|
|
100
|
+
## Accessibility
|
|
101
|
+
- Uses native `<button>` elements
|
|
102
|
+
- Keyboard: Enter/Space to activate, Tab to navigate between buttons
|
|
103
|
+
- Focus: Browser default focus ring preserved
|
|
104
|
+
- Grid semantics could use `role="group"` on container
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Gel Button
|
|
3
|
+
id: gel-btn
|
|
4
|
+
class: .gel-btn
|
|
5
|
+
category: buttons
|
|
6
|
+
index: 2
|
|
7
|
+
materials: [glossy-polycarbonate]
|
|
8
|
+
sizes: [xs, sm, md, lg]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: false
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Gel Button
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: iPod Nano 3rd gen click buttons, Sony Ericsson W800i keys, PSP face buttons.
|
|
18
|
+
**Mechanism**: Dome-switch mechanism with transparent/translucent polycarbonate (Lexan) keycap, injection-molded with high-gloss finish. 2-3mm thick, slightly convex. Strong specular highlight from Fresnel reflection at air-plastic interface.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Keycap material | Transparent/translucent polycarbonate |
|
|
25
|
+
| Surface | High-gloss, slightly convex |
|
|
26
|
+
| Catch-light | Concentrated bright reflection on upper third, fading to transparent |
|
|
27
|
+
| Thickness | 2-3mm polycarbonate |
|
|
28
|
+
| Shadow depth | 3px (taller than push-btn's 2px) |
|
|
29
|
+
|
|
30
|
+
## CSS Recipe
|
|
31
|
+
|
|
32
|
+
### Default State
|
|
33
|
+
```css
|
|
34
|
+
.gel-btn {
|
|
35
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
36
|
+
flex-direction: column; gap: 2px;
|
|
37
|
+
font-family: var(--font-ui); font-size: 11px; font-weight: 500;
|
|
38
|
+
letter-spacing: 1px; color: var(--text-primary);
|
|
39
|
+
background: linear-gradient(180deg, var(--clear-glass), transparent 50%),
|
|
40
|
+
linear-gradient(180deg, var(--bg-surface), var(--bg-panel));
|
|
41
|
+
border: none; border-radius: var(--radius-md); cursor: pointer;
|
|
42
|
+
position: relative; outline: none; user-select: none;
|
|
43
|
+
height: 38px; min-width: 64px; padding: 0 16px;
|
|
44
|
+
box-shadow: 0 3px 0 var(--border-deep), inset 0 1px 0 var(--glossy-hi);
|
|
45
|
+
transition: transform 0.07s var(--snap-fast), box-shadow 0.07s var(--snap-fast);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Active (Pressed) State
|
|
50
|
+
```css
|
|
51
|
+
.gel-btn:active {
|
|
52
|
+
transform: translateY(2px);
|
|
53
|
+
box-shadow: 0 1px 0 var(--border-deep), inset 0 1px 0 transparent;
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Selected State
|
|
58
|
+
```css
|
|
59
|
+
.gel-btn.active { color: var(--blue-info); }
|
|
60
|
+
.gel-btn.active::after {
|
|
61
|
+
content: ''; position: absolute; bottom: 5px;
|
|
62
|
+
left: 50%; transform: translateX(-50%);
|
|
63
|
+
width: 18px; height: 2px; background: var(--blue-info); border-radius: 1px;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Color Variants
|
|
68
|
+
```css
|
|
69
|
+
.gel-btn.blue { color: var(--blue-info); }
|
|
70
|
+
.gel-btn.green { color: var(--green-on); }
|
|
71
|
+
.gel-btn.pink { color: var(--pink-action); }
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Disabled State
|
|
75
|
+
```css
|
|
76
|
+
.gel-btn[disabled] { opacity: 0.4; pointer-events: none; }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## HTML Structure
|
|
80
|
+
```html
|
|
81
|
+
<!-- Basic -->
|
|
82
|
+
<button class="gel-btn">GEL</button>
|
|
83
|
+
|
|
84
|
+
<!-- Color variants -->
|
|
85
|
+
<button class="gel-btn blue">BLUE</button>
|
|
86
|
+
<button class="gel-btn green">GREEN</button>
|
|
87
|
+
<button class="gel-btn pink">PINK</button>
|
|
88
|
+
|
|
89
|
+
<!-- Selected -->
|
|
90
|
+
<button class="gel-btn active">SELECTED</button>
|
|
91
|
+
|
|
92
|
+
<!-- Sizes -->
|
|
93
|
+
<button class="gel-btn xs">XS</button>
|
|
94
|
+
<button class="gel-btn lg">LARGE</button>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Size Variants
|
|
98
|
+
|
|
99
|
+
| Size | Height | Min-Width | Font-Size | Padding |
|
|
100
|
+
|------|--------|-----------|-----------|---------|
|
|
101
|
+
| `.xs` | 28px | 44px | 9px | 0 10px |
|
|
102
|
+
| `.sm` | 32px | 52px | 10px | 0 12px |
|
|
103
|
+
| default | 38px | 64px | 11px | 0 16px |
|
|
104
|
+
| `.lg` | 44px | 80px | 13px | 0 20px |
|
|
105
|
+
|
|
106
|
+
## Material Variants
|
|
107
|
+
Single material: glossy polycarbonate. The two-layer background is the defining characteristic.
|
|
108
|
+
|
|
109
|
+
## Theme Behavior
|
|
110
|
+
- `--clear-glass` swaps: dark = `rgba(255,255,255,0.08)`, light = `rgba(255,255,255,0.5)`
|
|
111
|
+
- `--glossy-hi` remains constant at `rgba(255,255,255,0.14)`
|
|
112
|
+
- Surface colors swap via tokens
|
|
113
|
+
|
|
114
|
+
## Constraints
|
|
115
|
+
1. The two-layer background is MANDATORY. A single gradient cannot produce the gel look.
|
|
116
|
+
2. The catch-light MUST fade to `transparent` (not to a color) so the underlying body gradient shows through.
|
|
117
|
+
3. `glossy-hi` MUST be `0.14` opacity, not `0.06`. This is the primary differentiator from rubber buttons.
|
|
118
|
+
4. Bottom shadow MUST be 3px (not 2px) because polycarbonate buttons sit taller than panel buttons.
|
|
119
|
+
5. Press travel is 2px (not 1px like push-btn) due to the thicker keycap.
|
|
120
|
+
|
|
121
|
+
## Accessibility
|
|
122
|
+
- Uses native `<button>` element
|
|
123
|
+
- Keyboard: Enter/Space to activate
|
|
124
|
+
- Focus: Browser default focus ring preserved
|
|
125
|
+
- Color variants are decorative; do not rely on color alone for state
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Icon Button
|
|
3
|
+
id: icon-btn
|
|
4
|
+
class: .icon-btn
|
|
5
|
+
category: buttons
|
|
6
|
+
index: 8
|
|
7
|
+
materials: [panel]
|
|
8
|
+
sizes: [sm, md, lg]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: false
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Icon Button
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Toolbar buttons on audio equipment (Tascam portastudio, Roland SP-404 sampler), camera viewfinder controls.
|
|
18
|
+
**Mechanism**: Small tactile buttons with a single icon/symbol instead of text label. Typically smaller than labeled buttons (8-10mm). Round variants appear on devices where the button also serves as an indicator light (LED underneath translucent cap).
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Default size | 36x36px |
|
|
25
|
+
| Small size | 28x28px |
|
|
26
|
+
| Large size | 44x44px |
|
|
27
|
+
| Icon font-size | 14px (default) |
|
|
28
|
+
| Border-radius | var(--radius-md) or 50% for round |
|
|
29
|
+
|
|
30
|
+
## CSS Recipe
|
|
31
|
+
|
|
32
|
+
### Default State
|
|
33
|
+
```css
|
|
34
|
+
.icon-btn {
|
|
35
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
36
|
+
width: 36px; height: 36px; border-radius: var(--radius-md);
|
|
37
|
+
background: var(--bg-surface); border: 1px solid var(--border-subtle);
|
|
38
|
+
cursor: pointer; color: var(--text-secondary); font-size: 14px;
|
|
39
|
+
box-shadow: 0 2px 0 var(--border-deep), inset 0 1px 0 var(--glossy-hi);
|
|
40
|
+
transition: transform 0.07s var(--snap-fast), box-shadow 0.07s, color 0.12s;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Hover State
|
|
45
|
+
```css
|
|
46
|
+
.icon-btn:hover { color: var(--text-primary); }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Active (Pressed) State
|
|
50
|
+
```css
|
|
51
|
+
.icon-btn:active {
|
|
52
|
+
transform: translateY(1px);
|
|
53
|
+
box-shadow: 0 1px 0 var(--border-deep);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Active (Selected) State
|
|
58
|
+
```css
|
|
59
|
+
.icon-btn.active { color: var(--amber); border-color: rgba(245,166,35,0.3); }
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Round Variant
|
|
63
|
+
```css
|
|
64
|
+
.icon-btn.round { border-radius: 50%; }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## HTML Structure
|
|
68
|
+
```html
|
|
69
|
+
<!-- Default -->
|
|
70
|
+
<button class="icon-btn">■</button>
|
|
71
|
+
|
|
72
|
+
<!-- Small -->
|
|
73
|
+
<button class="icon-btn sm">▶</button>
|
|
74
|
+
|
|
75
|
+
<!-- Active -->
|
|
76
|
+
<button class="icon-btn active">★</button>
|
|
77
|
+
|
|
78
|
+
<!-- Large round -->
|
|
79
|
+
<button class="icon-btn lg round">⚙</button>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Size Variants
|
|
83
|
+
|
|
84
|
+
| Size | Width/Height | Font-Size |
|
|
85
|
+
|------|-------------|-----------|
|
|
86
|
+
| `.sm` | 28px | 12px |
|
|
87
|
+
| default | 36px | 14px |
|
|
88
|
+
| `.lg` | 44px | 18px |
|
|
89
|
+
|
|
90
|
+
## Material Variants
|
|
91
|
+
Default panel material. No explicit material variant classes.
|
|
92
|
+
|
|
93
|
+
## Theme Behavior
|
|
94
|
+
- Surface and border colors swap via tokens
|
|
95
|
+
- `--glossy-hi` remains constant
|
|
96
|
+
- Text colors swap via `--text-secondary` and `--text-primary`
|
|
97
|
+
|
|
98
|
+
## Constraints
|
|
99
|
+
1. MUST be square (width equals height).
|
|
100
|
+
2. Icon MUST be centered both horizontally and vertically.
|
|
101
|
+
3. Shadow stack follows standard Tier 2 pattern.
|
|
102
|
+
4. Round variant uses `border-radius: 50%` for circular shape.
|
|
103
|
+
|
|
104
|
+
## Accessibility
|
|
105
|
+
- Uses native `<button>` element
|
|
106
|
+
- Keyboard: Enter/Space to activate
|
|
107
|
+
- ARIA: Should include `aria-label` since there is no visible text
|
|
108
|
+
- Focus: Browser default focus ring preserved
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Keypad Button
|
|
3
|
+
id: keypad-btn
|
|
4
|
+
class: .keypad-btn
|
|
5
|
+
category: buttons
|
|
6
|
+
index: 5
|
|
7
|
+
materials: [panel, rubber]
|
|
8
|
+
sizes: [md]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: false
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Keypad Button
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Nokia 3210/3310/6600 keypads, Sony Ericsson T610, Motorola RAZR V3.
|
|
18
|
+
**Mechanism**: Rubber dome arrays (single silicone sheet with multiple domes) or individual metal domes on PCB, with rigid plastic keycap overlay. Each key has primary number and secondary T9/multi-tap letters.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Grid layout | 3 columns x 4 rows |
|
|
25
|
+
| Key size | ~10-12mm square (physical) / 48x44px (UI) |
|
|
26
|
+
| Spacing | 1-2mm gaps (physical) / 6px gap (UI) |
|
|
27
|
+
| Primary digit | Centered, 16px Michroma |
|
|
28
|
+
| T9 letters | 7px, positioned absolute at bottom |
|
|
29
|
+
|
|
30
|
+
## CSS Recipe
|
|
31
|
+
|
|
32
|
+
### Default State
|
|
33
|
+
```css
|
|
34
|
+
.keypad-btn {
|
|
35
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
36
|
+
font-family: var(--font-display); font-size: 16px; font-weight: 400;
|
|
37
|
+
color: var(--text-primary);
|
|
38
|
+
background: linear-gradient(180deg, var(--bg-surface), var(--bg-panel));
|
|
39
|
+
border: none; border-radius: var(--radius-sm); cursor: pointer;
|
|
40
|
+
width: 48px; height: 44px; position: relative;
|
|
41
|
+
box-shadow: 0 2px 0 var(--border-deep), inset 0 1px 0 var(--glossy-hi);
|
|
42
|
+
transition: transform 0.05s var(--snap-fast), box-shadow 0.05s var(--snap-fast);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Active (Pressed) State
|
|
47
|
+
```css
|
|
48
|
+
.keypad-btn:active {
|
|
49
|
+
transform: translateY(1px);
|
|
50
|
+
box-shadow: 0 1px 0 var(--border-deep);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### T9 Letters Element
|
|
55
|
+
```css
|
|
56
|
+
.keypad-btn .kbd-letters {
|
|
57
|
+
font-family: var(--font-ui); font-size: 7px; color: var(--text-muted);
|
|
58
|
+
letter-spacing: 1px; position: absolute; bottom: 3px;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Special & Call Variants
|
|
63
|
+
```css
|
|
64
|
+
.keypad-btn.special { background: var(--rubber-bg); font-size: 12px; }
|
|
65
|
+
.keypad-btn.call {
|
|
66
|
+
background: linear-gradient(180deg, #228833, #116622);
|
|
67
|
+
color: #fff; font-size: 10px; font-family: var(--font-ui); font-weight: 600;
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Keypad Grid Container
|
|
72
|
+
```css
|
|
73
|
+
.keypad {
|
|
74
|
+
display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px;
|
|
75
|
+
padding: 12px; background: var(--bg-raised);
|
|
76
|
+
border-radius: var(--radius-lg); border: 1px solid var(--border-subtle);
|
|
77
|
+
box-shadow: var(--shadow-deep); max-width: 168px;
|
|
78
|
+
}
|
|
79
|
+
.keypad .keypad-btn { width: 100%; height: 40px; }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## HTML Structure
|
|
83
|
+
```html
|
|
84
|
+
<!-- Individual keys -->
|
|
85
|
+
<button class="keypad-btn">1</button>
|
|
86
|
+
<button class="keypad-btn">2<span class="kbd-letters">ABC</span></button>
|
|
87
|
+
<button class="keypad-btn">3<span class="kbd-letters">DEF</span></button>
|
|
88
|
+
|
|
89
|
+
<!-- Call key -->
|
|
90
|
+
<button class="keypad-btn call">CALL</button>
|
|
91
|
+
|
|
92
|
+
<!-- Full keypad grid -->
|
|
93
|
+
<div class="keypad">
|
|
94
|
+
<button class="keypad-btn">1</button>
|
|
95
|
+
<button class="keypad-btn">2<span class="kbd-letters">ABC</span></button>
|
|
96
|
+
<button class="keypad-btn">3<span class="kbd-letters">DEF</span></button>
|
|
97
|
+
<!-- ... -->
|
|
98
|
+
</div>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Size Variants
|
|
102
|
+
No explicit size variants. Fixed at 48x44px (or 100% width inside `.keypad` container).
|
|
103
|
+
|
|
104
|
+
## Material Variants
|
|
105
|
+
- Default: Panel gradient (bg-surface to bg-panel)
|
|
106
|
+
- `.special`: Rubber background for * and # keys
|
|
107
|
+
- `.call`: Green-dyed keycap plastic
|
|
108
|
+
|
|
109
|
+
## Theme Behavior
|
|
110
|
+
- Surface gradients swap via tokens
|
|
111
|
+
- Call button green gradient is fixed (not theme-dependent)
|
|
112
|
+
- Rubber background for special keys swaps via `--rubber-bg`
|
|
113
|
+
|
|
114
|
+
## Constraints
|
|
115
|
+
1. Primary digit font MUST be `--font-display` (Michroma) at 16px -- prominent, centered.
|
|
116
|
+
2. T9 letters MUST be `--font-ui` at 7px, positioned absolute at bottom -- secondary information hierarchy.
|
|
117
|
+
3. Grid MUST be 3 columns when inside `.keypad` container.
|
|
118
|
+
4. Green call key gradient is fixed regardless of theme.
|
|
119
|
+
|
|
120
|
+
## Accessibility
|
|
121
|
+
- Uses native `<button>` element
|
|
122
|
+
- Keyboard: Enter/Space to activate
|
|
123
|
+
- T9 letters are visible but secondary to primary digit
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Push Button
|
|
3
|
+
id: push-btn
|
|
4
|
+
class: .push-btn
|
|
5
|
+
category: buttons
|
|
6
|
+
index: 1
|
|
7
|
+
materials: [panel, rubber, glossy]
|
|
8
|
+
sizes: [xs, sm, md, lg, xl]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: false
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Push Button
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Sony Alpha rear panel buttons, Nikon D-series function buttons, Canon EOS rear controls.
|
|
18
|
+
**Mechanism**: Tactile dome switch (phosphor-bronze or stainless steel dome over PCB contact pad). Dome collapses at 160-260gf, creating an abrupt click and closing the circuit. Dome spring memory restores shape on release.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Keycap | Injection-molded ABS or polycarbonate, 6-12mm wide, 2-3mm proud |
|
|
25
|
+
| Surface | Slightly convex (domed) so finger naturally centers |
|
|
26
|
+
| Chamfer | 30-45 degree CNC-milled bevel |
|
|
27
|
+
| Travel | 0.3-0.5mm (extremely short) |
|
|
28
|
+
| Gap beneath | 1-2mm proud of panel surface |
|
|
29
|
+
|
|
30
|
+
## CSS Recipe
|
|
31
|
+
|
|
32
|
+
### Default State
|
|
33
|
+
```css
|
|
34
|
+
.push-btn {
|
|
35
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
36
|
+
flex-direction: column; gap: 2px;
|
|
37
|
+
font-family: var(--font-mono); font-size: 10px; font-weight: 500;
|
|
38
|
+
letter-spacing: 1px; color: var(--text-primary);
|
|
39
|
+
background: linear-gradient(180deg, var(--bg-surface), var(--bg-panel));
|
|
40
|
+
border: none; border-radius: var(--radius-md); cursor: pointer;
|
|
41
|
+
position: relative; outline: none; user-select: none;
|
|
42
|
+
height: 36px; min-width: 64px; padding: 0 16px;
|
|
43
|
+
box-shadow: 0 2px 0 var(--border-deep), inset 0 1px 0 var(--border-hi), inset 0 -1px 0 #111;
|
|
44
|
+
transition: transform 0.07s ease, box-shadow 0.07s ease, color 0.12s ease;
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Hover State
|
|
49
|
+
```css
|
|
50
|
+
.push-btn:hover { color: #fff; }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Active / Pressed State
|
|
54
|
+
```css
|
|
55
|
+
.push-btn:active, .push-btn.pressed {
|
|
56
|
+
transform: translateY(1px);
|
|
57
|
+
box-shadow: 0 1px 0 var(--border-deep), inset 0 1px 0 #1a1a1a, inset 0 -1px 0 #111;
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Active (Selected) State
|
|
62
|
+
```css
|
|
63
|
+
.push-btn.active { color: var(--amber); }
|
|
64
|
+
.push-btn.active::after {
|
|
65
|
+
content: ''; position: absolute; bottom: 5px;
|
|
66
|
+
left: 50%; transform: translateX(-50%);
|
|
67
|
+
width: 20px; height: 2px; background: var(--amber);
|
|
68
|
+
border-radius: 1px; box-shadow: 0 0 6px var(--amber-glow);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Disabled State
|
|
73
|
+
```css
|
|
74
|
+
.push-btn.disabled, .push-btn[disabled] { opacity: 0.35; pointer-events: none; }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Error & Special States
|
|
78
|
+
```css
|
|
79
|
+
.push-btn.state-amber { color: var(--amber); border-top: 1px solid rgba(245,166,35,0.2); }
|
|
80
|
+
.push-btn.error { color: var(--red-alert); border-top: 1px solid rgba(204,34,0,0.2); }
|
|
81
|
+
.push-btn.round { border-radius: 50%; width: 44px; height: 44px; min-width: auto; padding: 0; }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Light Theme Override
|
|
85
|
+
```css
|
|
86
|
+
[data-theme="light"] .push-btn {
|
|
87
|
+
box-shadow: 0 2px 0 var(--border-deep), inset 0 1px 0 rgba(255,255,255,0.6), inset 0 -1px 0 var(--border-mid);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## HTML Structure
|
|
92
|
+
```html
|
|
93
|
+
<!-- Basic -->
|
|
94
|
+
<button class="push-btn">LABEL</button>
|
|
95
|
+
|
|
96
|
+
<!-- With size -->
|
|
97
|
+
<button class="push-btn sm">SM</button>
|
|
98
|
+
|
|
99
|
+
<!-- Active state -->
|
|
100
|
+
<button class="push-btn active">ACTIVE</button>
|
|
101
|
+
|
|
102
|
+
<!-- Round variant -->
|
|
103
|
+
<button class="push-btn round">Fn</button>
|
|
104
|
+
|
|
105
|
+
<!-- Disabled -->
|
|
106
|
+
<button class="push-btn disabled">DISABLED</button>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Size Variants
|
|
110
|
+
|
|
111
|
+
| Size | Analog | Height | Min-Width | Font-Size | Padding |
|
|
112
|
+
|------|--------|--------|-----------|-----------|---------|
|
|
113
|
+
| `.xs` | Tiny Fn buttons on Sony A7 shoulder | 26px | 36px | 9px | 0 10px |
|
|
114
|
+
| `.sm` | Standard rear panel button | 32px | 48px | 10px | 0 12px |
|
|
115
|
+
| default | Main function button | 36px | 64px | 10px | 0 16px |
|
|
116
|
+
| `.lg` | Menu/Play button | 40px | 80px | 11px | 0 20px |
|
|
117
|
+
| `.xl` | Large labeled button (pro video cameras) | 44px | 96px | 12px | 0 24px |
|
|
118
|
+
|
|
119
|
+
## Material Variants
|
|
120
|
+
Default material is panel (linear-gradient from bg-surface to bg-panel). No explicit material variant classes on this component.
|
|
121
|
+
|
|
122
|
+
## Theme Behavior
|
|
123
|
+
- Dark: `box-shadow` uses `var(--border-deep)` + `var(--border-hi)` + `#111`
|
|
124
|
+
- Light: `box-shadow` uses `var(--border-deep)` + `rgba(255,255,255,0.6)` + `var(--border-mid)`
|
|
125
|
+
- All surface colors swap via CSS custom properties
|
|
126
|
+
|
|
127
|
+
## Constraints
|
|
128
|
+
1. Travel MUST be 1-2px maximum (`translateY(1px)`). More feels like a keyboard key, not a camera button.
|
|
129
|
+
2. Bottom shadow MUST be hard-edged `0 Npx 0` (no blur) -- the gap between keycap and chassis is a sharp physical edge.
|
|
130
|
+
3. On press, bottom shadow MUST collapse to `0 1px 0` -- the gap nearly closes as the dome compresses.
|
|
131
|
+
4. Hover state MUST subtly brighten text to white, simulating finger shadow changing light on keycap.
|
|
132
|
+
5. The three-plane shadow stack (bottom edge + top chamfer + bottom chamfer) MUST NOT be simplified.
|
|
133
|
+
|
|
134
|
+
## Accessibility
|
|
135
|
+
- Uses native `<button>` element
|
|
136
|
+
- Keyboard: Enter/Space to activate
|
|
137
|
+
- Focus: Browser default focus ring preserved
|
|
138
|
+
- Disabled state uses `pointer-events: none` and `opacity: 0.35`
|
|
139
|
+
- ARIA: No additional ARIA needed (native button semantics)
|