···11+# Haptic Feedback Implementation Plan
22+33+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
44+55+**Goal:** Add haptic feedback to bottom navigation taps for iOS 18+ and Android PWA users.
66+77+**Architecture:** A small utility module (`haptics.js`) that uses the iOS 18 checkbox-switch hack for Safari and falls back to `navigator.vibrate()` for Android. The bottom nav component imports and calls the trigger function in each navigation handler.
88+99+**Tech Stack:** Vanilla JS, Lit elements, Web Vibration API, iOS 18 checkbox switch attribute
1010+1111+---
1212+1313+### Task 1: Create Haptics Utility
1414+1515+**Files:**
1616+- Create: `src/utils/haptics.js`
1717+1818+**Step 1: Create the haptics utility file**
1919+2020+```js
2121+/**
2222+ * Haptic feedback utility for PWA
2323+ * - iOS 18+: Uses checkbox switch element hack
2424+ * - Android: Uses Vibration API
2525+ * - Other: Silently does nothing
2626+ */
2727+2828+// Platform detection
2929+const isIOS = /iPhone|iPad/.test(navigator.userAgent);
3030+const hasVibrate = 'vibrate' in navigator;
3131+3232+// Lazy-initialized hidden elements for iOS
3333+let checkbox = null;
3434+let label = null;
3535+3636+function ensureElements() {
3737+ if (checkbox) return;
3838+3939+ checkbox = document.createElement('input');
4040+ checkbox.type = 'checkbox';
4141+ checkbox.setAttribute('switch', '');
4242+ checkbox.id = 'haptic-trigger';
4343+ checkbox.style.cssText = 'position:fixed;left:-9999px;opacity:0;pointer-events:none;';
4444+4545+ label = document.createElement('label');
4646+ label.htmlFor = 'haptic-trigger';
4747+ label.style.cssText = 'position:fixed;left:-9999px;opacity:0;pointer-events:none;';
4848+4949+ document.body.append(checkbox, label);
5050+}
5151+5252+/**
5353+ * Trigger a light haptic tap
5454+ */
5555+export function trigger() {
5656+ if (isIOS) {
5757+ ensureElements();
5858+ label.click();
5959+ } else if (hasVibrate) {
6060+ navigator.vibrate(10);
6161+ }
6262+}
6363+6464+/**
6565+ * Check if haptics are supported on this device
6666+ */
6767+export function isSupported() {
6868+ return isIOS || hasVibrate;
6969+}
7070+```
7171+7272+**Step 2: Commit the utility**
7373+7474+```bash
7575+git add src/utils/haptics.js
7676+git commit -m "feat: add haptics utility for iOS 18+ and Android"
7777+```
7878+7979+---
8080+8181+### Task 2: Integrate Haptics into Bottom Nav
8282+8383+**Files:**
8484+- Modify: `src/components/organisms/grain-bottom-nav.js`
8585+8686+**Step 1: Add the import**
8787+8888+At the top of the file with other imports, add:
8989+9090+```js
9191+import { trigger as haptic } from '../../utils/haptics.js';
9292+```
9393+9494+**Step 2: Add haptic calls to navigation handlers**
9595+9696+Find each handler method and add `haptic();` as the first line:
9797+9898+```js
9999+#handleHome() {
100100+ haptic();
101101+ router.push('/');
102102+}
103103+104104+#handleProfile() {
105105+ haptic();
106106+ router.push(`/profile/${this._user.handle}`);
107107+}
108108+109109+#handleExplore() {
110110+ haptic();
111111+ router.push('/explore');
112112+}
113113+114114+#handleNotifications() {
115115+ haptic();
116116+ router.push('/notifications');
117117+}
118118+119119+#handleCreate() {
120120+ haptic();
121121+ this._fileInput.click();
122122+}
123123+```
124124+125125+**Step 3: Commit the integration**
126126+127127+```bash
128128+git add src/components/organisms/grain-bottom-nav.js
129129+git commit -m "feat: add haptic feedback to bottom nav taps"
130130+```
131131+132132+---
133133+134134+### Task 3: Manual Testing
135135+136136+**Step 1: Start the dev server**
137137+138138+```bash
139139+npm run dev
140140+```
141141+142142+**Step 2: Test on iOS 18+ device**
143143+144144+- Open the app in Safari on iPhone/iPad running iOS 18+
145145+- Add to Home Screen (PWA mode)
146146+- Tap each bottom nav item
147147+- Expected: Light haptic tap on each navigation
148148+149149+**Step 3: Test on Android device**
150150+151151+- Open the app in Chrome on Android
152152+- Add to Home Screen or test in browser
153153+- Tap each bottom nav item
154154+- Expected: Light vibration (10ms) on each navigation
155155+156156+**Step 4: Test on desktop**
157157+158158+- Open the app in any desktop browser
159159+- Click each bottom nav item
160160+- Expected: No errors, navigation works normally, no haptic (graceful degradation)
161161+162162+---
163163+164164+## Summary
165165+166166+| Task | Description | Files |
167167+|------|-------------|-------|
168168+| 1 | Create haptics utility | `src/utils/haptics.js` |
169169+| 2 | Integrate into bottom nav | `src/components/organisms/grain-bottom-nav.js` |
170170+| 3 | Manual testing | N/A |
171171+172172+**Total changes:** 2 files, ~40 lines of code