PUDGE/UI v0.2.1 2025-07
  • + 5 new hardware compositions: Walkman Deck (Sony WM-D6C), Game Boy (Nintendo DMG-01), DJ Controller Deck (Pioneer DDJ), Synthesizer Panel (Roland SH-101 / Moog Minimoog)
  • + Changelog page at /changelog with full version history
  • + Animated NEW badge on recently added specs and compositions
  • + LCD-style version update banner with per-version dismiss
dials .clickwheel

Click Wheel

iPod Classic capacitive touch wheel with mechanical center button

Size
Material
SELECT
<div class="clickwheel-wrap">
  <div class="clickwheel">
    <button class="clickwheel-btn menu">MENU</button>
    <button class="clickwheel-btn prev">&#9664;&#9664;</button>
    <button class="clickwheel-btn next">&#9654;&#9654;</button>
    <button class="clickwheel-btn playpause">&#9654;&#10073;&#10073;</button>
    <div class="clickwheel-center"><span>SELECT</span></div>
  </div>
</div>
.clickwheel-wrap { display: flex; flex-direction: column; align-items: center; gap: 10px; }

.clickwheel {
  width: 150px; height: 150px; border-radius: 50%;
  background: linear-gradient(145deg, #3a3835, #1c1a18);
  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);
  position: relative; cursor: pointer;
}
[data-theme="light"] .clickwheel { background: linear-gradient(145deg, #e0ded8, #c8c6c0); }

.clickwheel-center {
  position: absolute; inset: 36px; border-radius: 50%;
  background: linear-gradient(145deg, var(--bg-surface), var(--bg-panel));
  border: 1px solid var(--border-deep);
  box-shadow: inset 0 1px 0 var(--glossy-hi), 0 2px 4px rgba(0,0,0,0.3);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: transform 0.1s var(--snap-fast); z-index: 3;
}
.clickwheel-center:active { transform: scale(0.94); }
.clickwheel-center span { font-family: var(--font-display); font-size: 8px; color: var(--blue-info); letter-spacing: 1px; }

.clickwheel-btn {
  position: absolute; border: none; background: transparent;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui); font-size: 8px; font-weight: 600;
  letter-spacing: 1px; color: var(--text-muted); transition: color 0.1s; z-index: 3;
}
.clickwheel-btn:hover { color: var(--text-primary); }
.clickwheel-btn.menu { top: 16px; left: 50%; transform: translateX(-50%); }
.clickwheel-btn.prev { left: 16px; top: 50%; transform: translateY(-50%); }
.clickwheel-btn.next { right: 16px; top: 50%; transform: translateY(-50%); }
.clickwheel-btn.playpause { bottom: 16px; left: 50%; transform: translateX(-50%); }

API

Class Type Description
.clickwheel Base Primary component class
.md Size Medium (default) variant
.glossy Material Glossy surface variant

Design Notes

Physical Analog

Reference devices: iPod Classic (3rd-5th generation), iPod Mini, iPod Photo. 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.

Geometry

Property Value
Outer diameter 150px (46mm real)
Touch ring width ~12mm annular region
Center button inset 36px from all sides
Cardinal buttons 4 positions at N/S/E/W
Surface Smooth satin finish

CSS Recipe

Wrapper

.clickwheel-wrap { display: flex; flex-direction: column; align-items: center; gap: 10px; }

Wheel Body

.clickwheel {
  width: 150px; height: 150px; border-radius: 50%;
  background: linear-gradient(145deg, #3a3835, #1c1a18);
  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);
  position: relative; cursor: pointer;
}
[data-theme="light"] .clickwheel { background: linear-gradient(145deg, #e0ded8, #c8c6c0); }

Center Select Button

.clickwheel-center {
  position: absolute; inset: 36px; border-radius: 50%;
  background: linear-gradient(145deg, var(--bg-surface), var(--bg-panel));
  border: 1px solid var(--border-deep);
  box-shadow: inset 0 1px 0 var(--glossy-hi), 0 2px 4px rgba(0,0,0,0.3);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: transform 0.1s var(--snap-fast); z-index: 3;
}
.clickwheel-center:active { transform: scale(0.94); }
.clickwheel-center span { font-family: var(--font-display); font-size: 8px; color: var(--blue-info); letter-spacing: 1px; }

Cardinal Direction Buttons

.clickwheel-btn {
  position: absolute; border: none; background: transparent;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-ui); font-size: 8px; font-weight: 600;
  letter-spacing: 1px; color: var(--text-muted); transition: color 0.1s; z-index: 3;
}
.clickwheel-btn:hover { color: var(--text-primary); }
.clickwheel-btn.menu { top: 16px; left: 50%; transform: translateX(-50%); }
.clickwheel-btn.prev { left: 16px; top: 50%; transform: translateY(-50%); }
.clickwheel-btn.next { right: 16px; top: 50%; transform: translateY(-50%); }
.clickwheel-btn.playpause { bottom: 16px; left: 50%; transform: translateX(-50%); }

HTML Structure

<div class="clickwheel-wrap">
  <div class="clickwheel">
    <button class="clickwheel-btn menu">MENU</button>
    <button class="clickwheel-btn prev">&#9664;&#9664;</button>
    <button class="clickwheel-btn next">&#9654;&#9654;</button>
    <button class="clickwheel-btn playpause">&#9654;&#10073;&#10073;</button>
    <div class="clickwheel-center"><span>SELECT</span></div>
  </div>
</div>

Size Variants

No explicit size variants. Fixed at 150x150px.

Material Variants

  • Wheel surface: Panel material with subtle domed gradient
  • Center button: Glossy surface with specular highlight

Theme Behavior

  • Dark: linear-gradient(145deg, #3a3835, #1c1a18) wheel body
  • Light: linear-gradient(145deg, #e0ded8, #c8c6c0) wheel body
  • Center button uses surface tokens, adapting automatically
  • Shadow intensity reduces in light theme

Constraints

  1. Center button press feedback MUST be scale(0.94) (slight depression).
  2. Shadow stack MUST include Tier 3 pattern: 0 4px 0 border-deep, 0 8px 24px rgba(0,0,0,0.4).
  3. Cardinal buttons are positioned absolutely at N/S/E/W positions.
  4. The annular ring between outer edge and center button IS the touch-sensitive zone.
  5. Center button is slightly recessed below the touch ring surface (inset 36px).

Accessibility

  • Cardinal buttons use native <button> elements
  • Center button should have role="button" or use <button>
  • Keyboard: Tab to navigate between cardinal buttons and center
  • ARIA labels on each cardinal button for direction
  • Requires JS for scroll interaction on the ring
♿ Accessibility
Element
Use semantic HTML with appropriate ARIA roles
Keyboard
Arrow keys to adjust value
Focus
Visible focus indicator required. Use native browser focus ring or custom :focus-visible styles.

Hand it to your agent

pudge-ui is a spec, not a package — there's nothing to npm install. Pick your stack, copy the prompt, and your coding agent builds this component from the spec.

—
—

The click wheel is the crown jewel — capacitive touch meets mechanical center button.

Depth model →
Pudge