No.70 · Buttons· New
Field Button
A pill with a living background inside it — storm smoke, neon veins, strands of light, velvet grain, a blade of light or fire plumes, taken from the backgrounds library — drifting slowly at rest. Point at it and the field wakes: it quickens, brightens and turns towards your pointer, under a thin rim of glass and a soft glow in its own colour.
The prompt
Written for the variant you picked above: Smoke
Build a pill button whose fill is a live WebGL background. Props: children, field (which shader), zoom (3.2), onClick, type and motion. The shader runs on a canvas filling the button, through a small harness: DPR capped at 2, paused offscreen and in hidden tabs, one still frame under reduced motion, a smoothed pointer (uMouse, uPress), context-lost handling and a CSS gradient fallback. Two additions make a full-screen background work inside a 56px pill: a zoom, so the shader sees a canvas that many times bigger (uRes is multiplied, and the shader reads its fragment coordinate through a macro FC = gl_FragCoord.xy × uZoom), which makes the pill a slice of the field rather than one giant blob; and a rate, a multiplier on the speed of time read every frame, eased towards 0.6 at rest and 3 while the button is hovered or focused, so the field drifts quietly and wakes up smoothly. Each field is one of the library's full-screen backgrounds with its first palette, and reacts to the pointer just as it does at full size. Over the canvas: a soft radial dark bed under the label (42% at the centre fading out), a top sheen, a hairline glass rim and a top highlight; the label is white with a small shadow, so it reads on any frame. Hover lifts the pill 1px, brightens and saturates the field over 420ms, and adds a glow in the field's colour; press dips it. The focus ring is a 2px white outline 4px out. Selected variant — Smoke (smoke): Storm smoke: navy #323e62 smoke with #a3b4dd light on #010209, cover 0.29. This selection takes precedence over references to other themes or options in the general brief. Implement this selected appearance; do not add a variant picker or alternative appearances unless requested. Implementation requirements: Use React and TypeScript. Keep the component self-contained, with uniquely scoped CSS and no animation libraries. Include required imports, styles and font setup in the result. Interaction: Point at the button or focus it and the field wakes and turns towards the pointer; press it as usual. Motion: The field drifts at 0.6× and eases up to 3× on hover; brightness and glow ease over 420ms. Reduced motion draws one still frame. Accessibility: A real button with its text label; the canvas is decorative and hidden. A dark bed and text shadow keep the white label readable on every frame. One WebGL context per button, paused offscreen. Responsive behavior: At least 200px wide and 56px tall; the field fills whatever size the label needs. Touch: The field drifts on its own; tapping works as usual. Preserve keyboard access, visible focus and reduced-motion behavior. Keep fictional demo data and simulated service calls in a separate usage example; expose callbacks for real actions and recover from rejected requests. Keep usage-example links inside the demo: use local buttons or prevent navigation. Demonstration links must not navigate to Vitrine routes or open other pages; preserve real URL support in the reusable component itself. Verify the result at narrow and wide viewport sizes, with keyboard input and reduced motion enabled.
Notes
- Interaction
- Point at the button or focus it and the field wakes and turns towards the pointer; press it as usual.
- Motion
- The field drifts at 0.6× and eases up to 3× on hover; brightness and glow ease over 420ms. Reduced motion draws one still frame.
- Accessibility
- A real button with its text label; the canvas is decorative and hidden. A dark bed and text shadow keep the white label readable on every frame. One WebGL context per button, paused offscreen.
- Responsive
- At least 200px wide and 56px tall; the field fills whatever size the label needs.
- On touch
- The field drifts on its own; tapping works as usual.