@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,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Media Grid
|
|
3
|
+
id: media-grid
|
|
4
|
+
class: .media-grid
|
|
5
|
+
category: data
|
|
6
|
+
index: 2
|
|
7
|
+
materials: [glossy-polycarbonate]
|
|
8
|
+
sizes: [default]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: true
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Media Grid
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Camera image review grid (3x3 or 4x4 thumbnail view), contact sheet from film photography.
|
|
18
|
+
**Mechanism**: Derived from the photographic contact sheet -- a print made by placing developed negatives directly on photographic paper and exposing. The resulting sheet shows small positive images in a grid, each representing one frame from the roll. The selected image (`.selected`) has an amber border glow representing the loupe highlight used to examine a specific frame on a light table.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Columns | 4 (via `repeat(4, 1fr)`) |
|
|
25
|
+
| Gap | 4px |
|
|
26
|
+
| Thumbnail aspect ratio | 1:1 (square) |
|
|
27
|
+
| Border radius | `--radius-sm` (4px) |
|
|
28
|
+
| Selection glow radius | 8px |
|
|
29
|
+
|
|
30
|
+
## CSS Recipe
|
|
31
|
+
|
|
32
|
+
### Grid (`.media-grid`)
|
|
33
|
+
```css
|
|
34
|
+
.media-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Thumbnail (`.media-thumb`)
|
|
38
|
+
```css
|
|
39
|
+
.media-thumb {
|
|
40
|
+
aspect-ratio: 1; background: var(--bg-surface);
|
|
41
|
+
border: 1px solid var(--border-subtle); border-radius: var(--radius-sm);
|
|
42
|
+
cursor: pointer; transition: border-color 0.12s;
|
|
43
|
+
display: flex; align-items: center; justify-content: center;
|
|
44
|
+
font-size: 10px; color: var(--text-muted);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Hover
|
|
49
|
+
```css
|
|
50
|
+
.media-thumb:hover { border-color: var(--border-mid); }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Selected
|
|
54
|
+
```css
|
|
55
|
+
.media-thumb.selected { border-color: var(--amber); box-shadow: 0 0 8px var(--amber-glow); }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## HTML Structure
|
|
59
|
+
```html
|
|
60
|
+
<div class="media-grid" style="width:240px">
|
|
61
|
+
<div class="media-thumb">01</div>
|
|
62
|
+
<div class="media-thumb selected">02</div>
|
|
63
|
+
<div class="media-thumb">03</div>
|
|
64
|
+
<div class="media-thumb">04</div>
|
|
65
|
+
<div class="media-thumb">05</div>
|
|
66
|
+
<div class="media-thumb">06</div>
|
|
67
|
+
<div class="media-thumb selected">07</div>
|
|
68
|
+
<div class="media-thumb">08</div>
|
|
69
|
+
</div>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Size Variants
|
|
73
|
+
No size variants defined. Grid columns and thumbnail size adapt to container width.
|
|
74
|
+
|
|
75
|
+
## Material Variants
|
|
76
|
+
No material variants. Uses surface background for placeholder thumbnails.
|
|
77
|
+
|
|
78
|
+
## Theme Behavior
|
|
79
|
+
- Thumbnail backgrounds swap via `--bg-surface`
|
|
80
|
+
- Border colors swap via `--border-subtle`
|
|
81
|
+
- Selected glow always uses amber (constant across themes)
|
|
82
|
+
- Hover border brightens via `--border-mid`
|
|
83
|
+
|
|
84
|
+
## Constraints
|
|
85
|
+
1. MUST use 4-column grid (standard contact sheet layout)
|
|
86
|
+
2. Thumbnails MUST be square (`aspect-ratio: 1`)
|
|
87
|
+
3. Selected thumbnails MUST have amber border AND amber glow
|
|
88
|
+
4. Glow radius MUST be 8px (standard active indicator glow)
|
|
89
|
+
5. Gap MUST be 4px (tight spacing like a real contact sheet)
|
|
90
|
+
6. Multiple thumbnails CAN be selected simultaneously
|
|
91
|
+
7. MUST use `--radius-sm` for small, film-frame-like corners
|
|
92
|
+
|
|
93
|
+
## Accessibility
|
|
94
|
+
- Each thumbnail should be a `<button>` or have `role="gridcell"`
|
|
95
|
+
- Grid container should have `role="grid"` with `aria-label="Image gallery"`
|
|
96
|
+
- Selected items: `aria-selected="true"`
|
|
97
|
+
- Support arrow key navigation within the grid
|
|
98
|
+
- Include `aria-label` or `alt` text describing each image
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Click Wheel
|
|
3
|
+
id: clickwheel
|
|
4
|
+
class: .clickwheel
|
|
5
|
+
category: dials
|
|
6
|
+
index: 7
|
|
7
|
+
materials: [panel, glossy]
|
|
8
|
+
sizes: [md]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: true
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Click Wheel
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: iPod Classic (3rd-5th generation), iPod Mini, iPod Photo.
|
|
18
|
+
**Mechanism**: Capacitive touch sensor with mechanical center button. NOT a physical rotating part -- flat circular capacitive surface detects angular position of finger. "Scroll" generated by tracking angular velocity. Polycarbonate disc bonded to capacitive sensor PCB. Four cardinal positions (Menu, Next, Play/Pause, Previous) double as mechanical dome switch presses.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Outer diameter | 150px (46mm real) |
|
|
25
|
+
| Touch ring width | ~12mm annular region |
|
|
26
|
+
| Center button | inset 36px from all sides |
|
|
27
|
+
| Cardinal buttons | 4 positions at N/S/E/W |
|
|
28
|
+
| Surface | Smooth satin finish |
|
|
29
|
+
|
|
30
|
+
## CSS Recipe
|
|
31
|
+
|
|
32
|
+
### Wrapper
|
|
33
|
+
```css
|
|
34
|
+
.clickwheel-wrap { display: flex; flex-direction: column; align-items: center; gap: 10px; }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Wheel Body
|
|
38
|
+
```css
|
|
39
|
+
.clickwheel {
|
|
40
|
+
width: 150px; height: 150px; border-radius: 50%;
|
|
41
|
+
background: linear-gradient(145deg, #3a3835, #1c1a18);
|
|
42
|
+
box-shadow: 0 4px 0 var(--border-deep), 0 8px 24px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.1);
|
|
43
|
+
position: relative; cursor: pointer;
|
|
44
|
+
}
|
|
45
|
+
[data-theme="light"] .clickwheel { background: linear-gradient(145deg, #e0ded8, #c8c6c0); }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Center Select Button
|
|
49
|
+
```css
|
|
50
|
+
.clickwheel-center {
|
|
51
|
+
position: absolute; inset: 36px; border-radius: 50%;
|
|
52
|
+
background: linear-gradient(145deg, var(--bg-surface), var(--bg-panel));
|
|
53
|
+
border: 1px solid var(--border-deep);
|
|
54
|
+
box-shadow: inset 0 1px 0 var(--glossy-hi), 0 2px 4px rgba(0,0,0,0.3);
|
|
55
|
+
display: flex; align-items: center; justify-content: center;
|
|
56
|
+
cursor: pointer; transition: transform 0.1s var(--snap-fast); z-index: 3;
|
|
57
|
+
}
|
|
58
|
+
.clickwheel-center:active { transform: scale(0.94); }
|
|
59
|
+
.clickwheel-center span { font-family: var(--font-display); font-size: 8px; color: var(--blue-info); letter-spacing: 1px; }
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Cardinal Direction Buttons
|
|
63
|
+
```css
|
|
64
|
+
.clickwheel-btn {
|
|
65
|
+
position: absolute; border: none; background: transparent;
|
|
66
|
+
cursor: pointer; display: flex; align-items: center; justify-content: center;
|
|
67
|
+
font-family: var(--font-ui); font-size: 8px; font-weight: 600;
|
|
68
|
+
letter-spacing: 1px; color: var(--text-muted); transition: color 0.1s; z-index: 3;
|
|
69
|
+
}
|
|
70
|
+
.clickwheel-btn:hover { color: var(--text-primary); }
|
|
71
|
+
.clickwheel-btn.menu { top: 16px; left: 50%; transform: translateX(-50%); }
|
|
72
|
+
.clickwheel-btn.prev { left: 16px; top: 50%; transform: translateY(-50%); }
|
|
73
|
+
.clickwheel-btn.next { right: 16px; top: 50%; transform: translateY(-50%); }
|
|
74
|
+
.clickwheel-btn.playpause { bottom: 16px; left: 50%; transform: translateX(-50%); }
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## HTML Structure
|
|
78
|
+
```html
|
|
79
|
+
<div class="clickwheel-wrap">
|
|
80
|
+
<div class="clickwheel">
|
|
81
|
+
<button class="clickwheel-btn menu">MENU</button>
|
|
82
|
+
<button class="clickwheel-btn prev">◀◀</button>
|
|
83
|
+
<button class="clickwheel-btn next">▶▶</button>
|
|
84
|
+
<button class="clickwheel-btn playpause">▶❙❙</button>
|
|
85
|
+
<div class="clickwheel-center"><span>SELECT</span></div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Size Variants
|
|
91
|
+
No explicit size variants. Fixed at 150x150px.
|
|
92
|
+
|
|
93
|
+
## Material Variants
|
|
94
|
+
- Wheel surface: Panel material with subtle domed gradient
|
|
95
|
+
- Center button: Glossy surface with specular highlight
|
|
96
|
+
|
|
97
|
+
## Theme Behavior
|
|
98
|
+
- Dark: `linear-gradient(145deg, #3a3835, #1c1a18)` wheel body
|
|
99
|
+
- Light: `linear-gradient(145deg, #e0ded8, #c8c6c0)` wheel body
|
|
100
|
+
- Center button uses surface tokens, adapting automatically
|
|
101
|
+
- Shadow intensity reduces in light theme
|
|
102
|
+
|
|
103
|
+
## Constraints
|
|
104
|
+
1. Center button press feedback MUST be `scale(0.94)` (slight depression).
|
|
105
|
+
2. Shadow stack MUST include Tier 3 pattern: `0 4px 0 border-deep`, `0 8px 24px rgba(0,0,0,0.4)`.
|
|
106
|
+
3. Cardinal buttons are positioned absolutely at N/S/E/W positions.
|
|
107
|
+
4. The annular ring between outer edge and center button IS the touch-sensitive zone.
|
|
108
|
+
5. Center button is slightly recessed below the touch ring surface (`inset 36px`).
|
|
109
|
+
|
|
110
|
+
## Accessibility
|
|
111
|
+
- Cardinal buttons use native `<button>` elements
|
|
112
|
+
- Center button should have `role="button"` or use `<button>`
|
|
113
|
+
- Keyboard: Tab to navigate between cardinal buttons and center
|
|
114
|
+
- ARIA labels on each cardinal button for direction
|
|
115
|
+
- Requires JS for scroll interaction on the ring
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Cylindrical Dial Horizontal
|
|
3
|
+
id: dial-h-body
|
|
4
|
+
class: .dial-h-body
|
|
5
|
+
category: dials
|
|
6
|
+
index: 5
|
|
7
|
+
materials: [panel, brushed-metal, chrome]
|
|
8
|
+
sizes: [md]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: true
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Cylindrical Dial Horizontal
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Nikon D850 front/rear command dials, Sony Alpha front dial, Canon EOS main dial (landscape orientation).
|
|
18
|
+
**Mechanism**: Identical encoder mechanism to cylindrical scroll, but oriented horizontally. Main command dial on camera grip, operated by index finger. User rolls barrel forward/backward to change values.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Barrel | 168x44px (wide and short) |
|
|
25
|
+
| Knurl pattern | Diamond crosshatch (two sets of diagonal grooves at 60-75 degrees) |
|
|
26
|
+
| Top bevel cap | 13px bright-to-transparent gradient |
|
|
27
|
+
| Badge | Centered value display |
|
|
28
|
+
|
|
29
|
+
## CSS Recipe
|
|
30
|
+
|
|
31
|
+
### Wrapper
|
|
32
|
+
```css
|
|
33
|
+
.dial-h { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 100%; max-width: 190px; }
|
|
34
|
+
.dial-h-label { font-family: var(--font-ui); font-size: 7px; font-weight: 700; letter-spacing: 2px; color: var(--text-muted); text-transform: uppercase; }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Body
|
|
38
|
+
```css
|
|
39
|
+
.dial-h-body {
|
|
40
|
+
width: 168px; height: 44px; border-radius: 6px;
|
|
41
|
+
position: relative; cursor: ew-resize; user-select: none;
|
|
42
|
+
background: linear-gradient(180deg, #4a4845, #2a2826);
|
|
43
|
+
border: 1px solid var(--border-mid);
|
|
44
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.3); overflow: hidden;
|
|
45
|
+
}
|
|
46
|
+
[data-theme="light"] .dial-h-body { background: linear-gradient(180deg, #d0cec8, #b0aea8); border-color: #aaa; }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Diamond Knurl Pattern
|
|
50
|
+
```css
|
|
51
|
+
.dial-h-body .knurl-cross {
|
|
52
|
+
position: absolute; inset: 0; pointer-events: none;
|
|
53
|
+
background-image:
|
|
54
|
+
repeating-linear-gradient(75deg, transparent 0px, transparent 2px, rgba(0,0,0,0.06) 2px, rgba(0,0,0,0.06) 3px, transparent 3px, transparent 6px),
|
|
55
|
+
repeating-linear-gradient(-75deg, transparent 0px, transparent 2px, rgba(0,0,0,0.06) 2px, rgba(0,0,0,0.06) 3px, transparent 3px, transparent 6px);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Top Bevel Cap
|
|
60
|
+
```css
|
|
61
|
+
.dial-h-body .dial-cap {
|
|
62
|
+
position: absolute; top: 0; left: 0; right: 0; height: 13px;
|
|
63
|
+
background: linear-gradient(180deg, rgba(255,255,255,0.12) 0%, transparent 100%);
|
|
64
|
+
border-bottom: 1px solid rgba(0,0,0,0.12); pointer-events: none;
|
|
65
|
+
border-radius: 6px 6px 0 0;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Value Badge
|
|
70
|
+
```css
|
|
71
|
+
.dial-h-body .dial-badge {
|
|
72
|
+
position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
|
|
73
|
+
font-family: var(--font-display); font-size: 11px; letter-spacing: 1px;
|
|
74
|
+
color: var(--text-primary); z-index: 3; pointer-events: none;
|
|
75
|
+
background: var(--bg-surface); padding: 2px 8px; border-radius: 3px;
|
|
76
|
+
border: 1px solid var(--border-subtle);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Material Variants
|
|
81
|
+
```css
|
|
82
|
+
.dial-h-body.variant-silver {
|
|
83
|
+
background: linear-gradient(180deg, #d8d6d0, #b8b6b0);
|
|
84
|
+
border-color: #a8a6a0;
|
|
85
|
+
}
|
|
86
|
+
.dial-h-body.variant-chrome {
|
|
87
|
+
background: linear-gradient(180deg, #5a5855, #3a3835);
|
|
88
|
+
border-color: #666;
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## HTML Structure
|
|
93
|
+
```html
|
|
94
|
+
<div class="dial-h">
|
|
95
|
+
<div class="dial-h-label">EXPOSURE COMP</div>
|
|
96
|
+
<div class="dial-h-body">
|
|
97
|
+
<div class="knurl-cross"></div>
|
|
98
|
+
<div class="dial-cap"></div>
|
|
99
|
+
<div class="dial-badge">+0.7</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Size Variants
|
|
105
|
+
No explicit size variants. Fixed at 168x44px.
|
|
106
|
+
|
|
107
|
+
## Material Variants
|
|
108
|
+
|
|
109
|
+
| Variant | Background | Border |
|
|
110
|
+
|---------|-----------|--------|
|
|
111
|
+
| default | `linear-gradient(180deg, #4a4845, #2a2826)` | `var(--border-mid)` |
|
|
112
|
+
| `.variant-silver` | `linear-gradient(180deg, #d8d6d0, #b8b6b0)` | `#a8a6a0` |
|
|
113
|
+
| `.variant-chrome` | `linear-gradient(180deg, #5a5855, #3a3835)` | `#666` |
|
|
114
|
+
|
|
115
|
+
## Theme Behavior
|
|
116
|
+
- Dark default: dark metallic gradient
|
|
117
|
+
- Light default: light metallic gradient (`#d0cec8` to `#b0aea8`)
|
|
118
|
+
- Silver and chrome variants are fixed (metal doesn't change with theme)
|
|
119
|
+
- Badge uses surface tokens for adaptive background
|
|
120
|
+
|
|
121
|
+
## Constraints
|
|
122
|
+
1. Diamond knurl MUST use two overlapping `repeating-linear-gradient` at +75deg and -75deg.
|
|
123
|
+
2. Top bevel cap provides the bright line where barrel enters camera body.
|
|
124
|
+
3. Cursor MUST be `ew-resize` (horizontal scroll interaction).
|
|
125
|
+
4. Badge is centered and positioned above the knurl texture (z-index: 3).
|
|
126
|
+
|
|
127
|
+
## Accessibility
|
|
128
|
+
- Add `tabindex="0"` and `role="slider"`
|
|
129
|
+
- Keyboard: Arrow Left/Right to adjust value
|
|
130
|
+
- Requires JS for interaction
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Cylindrical Scroll Dial
|
|
3
|
+
id: dial-cylinder
|
|
4
|
+
class: .dial-cylinder
|
|
5
|
+
category: dials
|
|
6
|
+
index: 4
|
|
7
|
+
materials: [panel, chrome]
|
|
8
|
+
sizes: [md]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: true
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Cylindrical Scroll Dial
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Sony Alpha rear command dial (vertical barrel), Nikon sub-command dial, Canon quick control dial.
|
|
18
|
+
**Mechanism**: Incremental encoder packaged as cylindrical barrel rolled with thumb/finger. Textured cylinder partially recessed into camera body. Linear rolling motion on barrel surface, not twisting. Internal mechanism identical to rotary encoder.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Barrel | 92x110px |
|
|
25
|
+
| Knurl strips | 13px wide on left and right edges |
|
|
26
|
+
| Knurl pattern | Longitudinal grip ribs at 5px pitch |
|
|
27
|
+
| Value ticks | 28px height each |
|
|
28
|
+
| Center bar | 1px amber line at vertical center |
|
|
29
|
+
|
|
30
|
+
## CSS Recipe
|
|
31
|
+
|
|
32
|
+
### Wrapper
|
|
33
|
+
```css
|
|
34
|
+
.dial-cyl-wrap { display: flex; flex-direction: column; align-items: center; gap: 6px; }
|
|
35
|
+
.dial-cyl-title { font-size: 8px; letter-spacing: 3px; color: var(--text-muted); text-transform: uppercase; font-family: var(--font-ui); font-weight: 600; }
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Barrel Body
|
|
39
|
+
```css
|
|
40
|
+
.dial-cylinder {
|
|
41
|
+
width: 92px; height: 110px; background: #1e1e1e;
|
|
42
|
+
border-radius: var(--radius-sm); border: 1px solid #111;
|
|
43
|
+
overflow: hidden; position: relative; cursor: ns-resize; user-select: none;
|
|
44
|
+
box-shadow: inset 10px 0 16px rgba(0,0,0,0.5), inset -10px 0 16px rgba(0,0,0,0.5),
|
|
45
|
+
0 2px 0 var(--border-deep), inset 0 1px 0 #2a2a2a;
|
|
46
|
+
}
|
|
47
|
+
[data-theme="light"] .dial-cylinder { background: #e0dcd4; box-shadow: inset 10px 0 16px rgba(0,0,0,0.08), inset -10px 0 16px rgba(0,0,0,0.08), 0 2px 0 var(--border-deep); }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Knurl Grip Strips
|
|
51
|
+
```css
|
|
52
|
+
.dial-knurl {
|
|
53
|
+
position: absolute; top: 0; bottom: 0; width: 13px; z-index: 3; pointer-events: none;
|
|
54
|
+
background: repeating-linear-gradient(to bottom, #252525 0px, #252525 2px, #0d0d0d 2px, #0d0d0d 5px);
|
|
55
|
+
border: 1px solid #0a0a0a;
|
|
56
|
+
}
|
|
57
|
+
[data-theme="light"] .dial-knurl { background: repeating-linear-gradient(to bottom, #ccc 0px, #ccc 2px, #aaa 2px, #aaa 5px); border-color: #999; }
|
|
58
|
+
.dial-knurl.left { left: 0; border-radius: var(--radius-sm) 0 0 var(--radius-sm); box-shadow: inset -1px 0 4px rgba(0,0,0,0.4); }
|
|
59
|
+
.dial-knurl.right { right: 0; border-radius: 0 var(--radius-sm) var(--radius-sm) 0; box-shadow: inset 1px 0 4px rgba(0,0,0,0.4); }
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Inner Value List
|
|
63
|
+
```css
|
|
64
|
+
.dial-inner {
|
|
65
|
+
position: absolute; width: 100%; display: flex; flex-direction: column;
|
|
66
|
+
align-items: center; will-change: top;
|
|
67
|
+
}
|
|
68
|
+
.dial-tick {
|
|
69
|
+
height: 28px; width: 100%; display: flex; align-items: center; justify-content: center;
|
|
70
|
+
font-family: var(--font-mono); font-size: 13px; font-weight: 400;
|
|
71
|
+
letter-spacing: 1px; color: var(--text-muted); flex-shrink: 0;
|
|
72
|
+
transition: color 0.1s, font-size 0.1s; padding: 0 16px;
|
|
73
|
+
}
|
|
74
|
+
.dial-tick.near { color: var(--text-secondary); }
|
|
75
|
+
.dial-tick.active { color: var(--amber); font-size: 15px; font-weight: 500; }
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Center Selection Bar
|
|
79
|
+
```css
|
|
80
|
+
.dial-center-bar {
|
|
81
|
+
position: absolute; top: calc(50% - 1px); left: 14px; right: 14px;
|
|
82
|
+
height: 1px; background: var(--amber); opacity: 0.7; z-index: 4;
|
|
83
|
+
pointer-events: none; box-shadow: 0 0 8px var(--amber-glow);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Vignette (Top/Bottom Fade)
|
|
88
|
+
```css
|
|
89
|
+
.dial-vignette {
|
|
90
|
+
position: absolute; inset: 0; z-index: 5; pointer-events: none;
|
|
91
|
+
background: linear-gradient(to bottom, #1e1e1ef0 0%, transparent 35%, transparent 65%, #1e1e1ef0 100%);
|
|
92
|
+
}
|
|
93
|
+
[data-theme="light"] .dial-vignette { background: linear-gradient(to bottom, #e0dcd4f0 0%, transparent 35%, transparent 65%, #e0dcd4f0 100%); }
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## HTML Structure
|
|
97
|
+
```html
|
|
98
|
+
<div class="dial-cyl-wrap">
|
|
99
|
+
<div class="dial-cyl-title">SHUTTER</div>
|
|
100
|
+
<div class="dial-cylinder">
|
|
101
|
+
<div class="dial-knurl left"></div>
|
|
102
|
+
<div class="dial-knurl right"></div>
|
|
103
|
+
<div class="dial-inner" style="top: -28px;">
|
|
104
|
+
<div class="dial-tick">1/30</div>
|
|
105
|
+
<div class="dial-tick">1/60</div>
|
|
106
|
+
<div class="dial-tick near">1/125</div>
|
|
107
|
+
<div class="dial-tick active">1/250</div>
|
|
108
|
+
<div class="dial-tick near">1/500</div>
|
|
109
|
+
<div class="dial-tick">1/1000</div>
|
|
110
|
+
<div class="dial-tick">1/2000</div>
|
|
111
|
+
</div>
|
|
112
|
+
<div class="dial-center-bar"></div>
|
|
113
|
+
<div class="dial-vignette"></div>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Size Variants
|
|
119
|
+
No explicit size variants. Fixed at 92x110px.
|
|
120
|
+
|
|
121
|
+
## Material Variants
|
|
122
|
+
Default barrel material with knurled grip strips.
|
|
123
|
+
|
|
124
|
+
## Theme Behavior
|
|
125
|
+
- Dark: `#1e1e1e` barrel, dark knurl pattern, dark vignette
|
|
126
|
+
- Light: `#e0dcd4` barrel, light knurl pattern, light vignette
|
|
127
|
+
- Vignette gradient MUST exactly match barrel background color for seamless fade
|
|
128
|
+
- Side shadow intensity drops from 0.5 to 0.08 in light theme
|
|
129
|
+
|
|
130
|
+
## Constraints
|
|
131
|
+
1. Curvature illusion DEPENDS on side inset shadows. Without them the barrel looks flat. Shadow intensity MUST be 50%+ opacity in dark theme.
|
|
132
|
+
2. Vignette gradient MUST exactly match cylinder body background color for seamless fade.
|
|
133
|
+
3. Distance-based text hierarchy: `.active` = amber full size, `.near` = secondary, default = muted smaller.
|
|
134
|
+
4. Center bar is a FIXED selection indicator (does not scroll with values).
|
|
135
|
+
5. Values scroll by moving `.dial-inner` `top` property via JS.
|
|
136
|
+
|
|
137
|
+
## Accessibility
|
|
138
|
+
- Add `tabindex="0"` and `role="slider"` with `aria-valuenow`
|
|
139
|
+
- Keyboard: Arrow Up/Down to scroll values
|
|
140
|
+
- Cursor: `ns-resize` indicates vertical scroll interaction
|
|
141
|
+
- Requires JS for scroll interaction
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Cylindrical Dial Vertical
|
|
3
|
+
id: dial-v-body
|
|
4
|
+
class: .dial-v-body
|
|
5
|
+
category: dials
|
|
6
|
+
index: 6
|
|
7
|
+
materials: [panel, brushed-metal]
|
|
8
|
+
sizes: [md]
|
|
9
|
+
interactive: true
|
|
10
|
+
requires_js: true
|
|
11
|
+
canvas: false
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Cylindrical Dial Vertical
|
|
15
|
+
|
|
16
|
+
## Physical Analog
|
|
17
|
+
**Reference devices**: Sony Alpha rear thumb wheel, Fujifilm X-T series rear wheel, some Blackmagic camera controls.
|
|
18
|
+
**Mechanism**: Same encoder mechanism as horizontal cylindrical dial but oriented vertically and operated by thumb. Thinner profile (8-12mm wide physical) to fit comfortably under thumb pad.
|
|
19
|
+
|
|
20
|
+
## Geometry
|
|
21
|
+
|
|
22
|
+
| Property | Value |
|
|
23
|
+
|----------|-------|
|
|
24
|
+
| Body | 44x120px (narrow and tall) |
|
|
25
|
+
| Knurl pattern | Diagonal crosshatch at +/-20 degrees |
|
|
26
|
+
| Badge | Centered value display |
|
|
27
|
+
|
|
28
|
+
## CSS Recipe
|
|
29
|
+
|
|
30
|
+
### Wrapper
|
|
31
|
+
```css
|
|
32
|
+
.dial-v-wrap { display: flex; flex-direction: column; align-items: center; position: relative; padding-bottom: 22px; }
|
|
33
|
+
.dial-v-label { font-family: var(--font-ui); font-size: 7px; font-weight: 700; letter-spacing: 2px; color: var(--text-muted); text-transform: uppercase; position: absolute; bottom: 0; }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Body
|
|
37
|
+
```css
|
|
38
|
+
.dial-v-body {
|
|
39
|
+
width: 44px; height: 120px; border-radius: 6px;
|
|
40
|
+
position: relative; cursor: ns-resize; user-select: none;
|
|
41
|
+
background: linear-gradient(90deg, #4a4845, #2a2826);
|
|
42
|
+
border: 1px solid var(--border-mid);
|
|
43
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.3); overflow: hidden;
|
|
44
|
+
}
|
|
45
|
+
[data-theme="light"] .dial-v-body { background: linear-gradient(90deg, #d0cec8, #b0aea8); }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Knurl Pattern
|
|
49
|
+
```css
|
|
50
|
+
.dial-v-body .knurl-cross {
|
|
51
|
+
position: absolute; inset: 0; pointer-events: none;
|
|
52
|
+
background-image:
|
|
53
|
+
repeating-linear-gradient(20deg, transparent 0px, transparent 2px, rgba(0,0,0,0.06) 2px, rgba(0,0,0,0.06) 3px, transparent 3px, transparent 6px),
|
|
54
|
+
repeating-linear-gradient(-20deg, transparent 0px, transparent 2px, rgba(0,0,0,0.06) 2px, rgba(0,0,0,0.06) 3px, transparent 3px, transparent 6px);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Value Badge
|
|
59
|
+
```css
|
|
60
|
+
.dial-v-body .dial-badge {
|
|
61
|
+
position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
|
|
62
|
+
font-family: var(--font-display); font-size: 10px; color: var(--text-primary);
|
|
63
|
+
z-index: 3; pointer-events: none;
|
|
64
|
+
background: var(--bg-surface); padding: 2px 6px; border-radius: 3px;
|
|
65
|
+
border: 1px solid var(--border-subtle);
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## HTML Structure
|
|
70
|
+
```html
|
|
71
|
+
<div class="dial-v-wrap">
|
|
72
|
+
<div class="dial-v-body">
|
|
73
|
+
<div class="knurl-cross"></div>
|
|
74
|
+
<div class="dial-badge">50</div>
|
|
75
|
+
</div>
|
|
76
|
+
<div class="dial-v-label">ISO</div>
|
|
77
|
+
</div>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Size Variants
|
|
81
|
+
No explicit size variants. Fixed at 44x120px.
|
|
82
|
+
|
|
83
|
+
## Material Variants
|
|
84
|
+
Default metallic surface. No explicit variant classes, but gradient direction is 90deg (horizontal) to simulate curvature of vertical barrel.
|
|
85
|
+
|
|
86
|
+
## Theme Behavior
|
|
87
|
+
- Dark: `linear-gradient(90deg, #4a4845, #2a2826)` -- gradient runs left-to-right for vertical barrel curvature
|
|
88
|
+
- Light: `linear-gradient(90deg, #d0cec8, #b0aea8)`
|
|
89
|
+
- Badge adapts via surface tokens
|
|
90
|
+
|
|
91
|
+
## Constraints
|
|
92
|
+
1. Gradient MUST run 90deg (horizontal) -- this creates curvature illusion on a vertical barrel.
|
|
93
|
+
2. Knurl pattern angles are +/-20deg (shallower than horizontal dial's +/-75deg) for vertical orientation.
|
|
94
|
+
3. Cursor MUST be `ns-resize` (vertical scroll interaction).
|
|
95
|
+
4. Label is positioned absolutely at bottom of wrapper.
|
|
96
|
+
|
|
97
|
+
## Accessibility
|
|
98
|
+
- Add `tabindex="0"` and `role="slider"`
|
|
99
|
+
- Keyboard: Arrow Up/Down to adjust value
|
|
100
|
+
- Requires JS for interaction
|