Americanizer is a tactile, mobile-first unit converter built to feel like a premium piece of physical hardware. The design is deliberately minimal — near-white canvas, pure-black ink, a single blue accent — and every interaction is engineered to feel satisfying, from the scrub trackpad to the pseudo-haptic click audio.
What It Does
- Full-area scrub trackpad — drag anywhere on the screen to adjust values; no knob, no slider
- Velocity-tiered steps — slow scrubs nudge by 0.1, fast flicks jump by 100
- Native keypad entry — tap the number to open the device's numeric keyboard directly
- Pseudo-haptic audio — a 25 ms square-wave click fires on every detent via Web Audio
- Context-aware motion — ambient gradient shifts with temperature, Inter's variable weight axis tracks mass, an accent fill rises with volume
- Per-category state — each category remembers its own units and value across switches
- PWA install prompt — detects iOS vs Android and surfaces the right A2HS instructions on first visit
Categories
| Category | Default | Notes |
|---|---|---|
| Temperature | 22 °C → 71.6 °F | Fixed axis; no swap; floor −273.15 °C |
| Weight | 70 kg → 154.3 lb | Variable font weight effect; floor 0 |
| Length | 1 m → 39.37 in | Floor 0 |
| Volume | 1 L → 33.81 fl oz | Culinary fractions (½, ¼, ⅛…); floor 0 |
| Speed | 100 km/h → 62.1 mph | Floor 0 |
| Area | 100 m² → 1076.4 ft² | Floor 0 |
| Currency | 1 USD → INR | Live exchange rates |
Tech Stack
Next.js 15 (App Router, Turbopack), TypeScript (strict), Tailwind CSS 4, Zustand 5 with persist middleware, Framer Motion 11 (motion values and springs), @use-gesture/react for the scrub trackpad, and Vaul for the unit picker bottom sheet.
State is persisted under americanizer:v1 via partialize to keep localStorage minimal. The displayed "to" value is always derived — convert(category, value, fromUnit, toUnit) — so the store holds a single source of truth.
Design Details
The scrub trackpad accumulates (mx − my) gesture input — up and right both increase, down and left both decrease — and fires a detent every 12 px of travel. Each detent plays a click and emits onDelta, which routes to the active zone's value setter.
Volume and culinary US units (cup, tbsp, tsp, floz) render fractional remainders as the nearest Unicode vulgar fraction rather than raw decimals. Everything else uses decimal display.
The entire context-aware motion pipeline runs through Framer Motion values — no React state updates, no re-renders. Category-specific useTransform chains drive the ambient gradient, font weight axis, and fill height entirely off a single spring.
