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.