# Shopping Swipe Gestures Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Add left-swipe-to-toggle and right-swipe-to-delete touch gestures to Shopping list items on mobile, replacing the visible × delete button on small screens. **Architecture:** Shared swipe base CSS is moved from `tasks.css` to `layout.css` so both modules can use it. Shopping-specific styles (delete reveal, mobile button hiding) go in `shopping.css`. `shopping.js` wraps each item in a `swipe-row` and registers touch handlers via a new `wireSwipeGestures()` function, called after every list re-render. **Tech Stack:** Vanilla JS (ES modules), Touch Events API, CSS custom properties, Node.js built-in test runner (regression tests only — no DOM test framework in this project). --- ## File Map | File | Change | |------|--------| | `public/styles/tasks.css` | Remove `.swipe-row`, `.swipe-reveal`, `.swipe-reveal--done` (moved to layout.css) | | `public/styles/layout.css` | Add moved shared swipe styles + `.swipe-reveal--done` | | `public/styles/shopping.css` | Add `.swipe-reveal--delete`, `.swipe-row .shopping-item`, `.swipe-row--swiping .shopping-item`, mobile hide for `.item-delete` | | `public/pages/shopping.js` | Wrap `renderItem()` output in swipe-row, add `wireSwipeGestures(container)`, call it from `updateItemsList()` | --- ### Task 1: Move shared swipe CSS from tasks.css to layout.css **Files:** - Modify: `public/styles/tasks.css` (lines 170–229) - Modify: `public/styles/layout.css` (append before Print section) - [ ] **Step 1: Remove base swipe styles from tasks.css** In `public/styles/tasks.css`, delete the block from `/* Swipe-Wrapper (Mobil-Gesten) */` through `.swipe-reveal--done { ... }` (lines 170–216). Keep only the task-specific rules that follow: ```css /* Kein Margin mehr am Task-Card selbst (übernimmt swipe-row) */ .swipe-row .task-card { margin-bottom: 0; border-radius: var(--radius-md); position: relative; z-index: 1; will-change: transform; } /* Rechts hinter der Karte = Bearbeiten (Swipe nach rechts) */ .swipe-reveal--edit { left: 0; background-color: var(--color-accent); color: #fff; border-radius: var(--radius-md) 0 0 var(--radius-md); } /* Touch-Feedback: leichte Hervorhebung während Swipe */ .swipe-row--swiping .task-card { box-shadow: var(--shadow-lg); } ``` Add a comment header so the section remains clear: ```css /* -------------------------------------------------------- * Swipe-Wrapper — Task-spezifische Styles * Basis-Styles (.swipe-row, .swipe-reveal, .swipe-reveal--done) * liegen in layout.css * -------------------------------------------------------- */ ``` - [ ] **Step 2: Add shared swipe styles to layout.css** In `public/styles/layout.css`, find the Print section (`/* Print-Styles */`) and insert the following block **directly before it**: ```css /* -------------------------------------------------------- * Swipe-Wrapper — Gemeinsame Basis (Tasks + Shopping) * Modul-spezifische Styles (.swipe-reveal--edit, .swipe-reveal--delete, * .swipe-row .task-card, .swipe-row .shopping-item) liegen in den Modul-CSS. * -------------------------------------------------------- */ .swipe-row { position: relative; overflow: hidden; border-radius: var(--radius-md); margin-bottom: var(--space-2); /* Verhindert ungewolltes Flackern auf iOS */ -webkit-backface-visibility: hidden; } /* Reveal-Panels hinter der Karte */ .swipe-reveal { position: absolute; top: 0; bottom: 0; width: 50%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-1); font-size: var(--text-xs); font-weight: var(--font-weight-semibold); opacity: 0; pointer-events: none; z-index: 0; transition: opacity 0.05s linear; } /* Gemeinsam: Erledigt / Abhaken (Swipe nach links) */ .swipe-reveal--done { right: 0; background-color: var(--color-success); color: #fff; border-radius: 0 var(--radius-md) var(--radius-md) 0; } ``` - [ ] **Step 3: Run regression tests** ```bash npm test ``` Expected: `# pass 12` and `# fail 0` - [ ] **Step 4: Verify tasks swipe still works visually** Open the app in a browser (or mobile DevTools touch emulation), go to Tasks list, swipe an item left and right. The green "Erledigt" and blue "Bearbeiten" panels must still appear correctly. - [ ] **Step 5: Commit** ```bash git add public/styles/tasks.css public/styles/layout.css git commit -m "refactor: move shared swipe CSS from tasks.css to layout.css" ``` --- ### Task 2: Add shopping-specific swipe CSS **Files:** - Modify: `public/styles/shopping.css` - [ ] **Step 1: Find the correct insertion point in shopping.css** In `public/styles/shopping.css`, locate the section for `.shopping-item` styles. The new swipe styles go **after** the existing `.shopping-item` block. - [ ] **Step 2: Add the styles** Append the following after the existing `.shopping-item` rules in `public/styles/shopping.css`: ```css /* -------------------------------------------------------- * Swipe-Wrapper — Shopping-spezifische Styles * -------------------------------------------------------- */ /* Kein Margin mehr am shopping-item selbst (übernimmt swipe-row) */ .swipe-row .shopping-item { margin-bottom: 0; border-radius: var(--radius-md); position: relative; z-index: 1; will-change: transform; } /* Rechts hinter der Karte = Löschen (Swipe nach rechts) */ .swipe-reveal--delete { left: 0; background-color: var(--color-danger); color: #fff; border-radius: var(--radius-md) 0 0 var(--radius-md); } /* Touch-Feedback: leichte Hervorhebung während Swipe */ .swipe-row--swiping .shopping-item { box-shadow: var(--shadow-lg); } /* × Löschen-Button auf Mobile ausblenden — Swipe übernimmt */ @media (max-width: 1023px) { .item-delete { display: none; } } ``` - [ ] **Step 3: Run regression tests** ```bash npm test ``` Expected: `# pass 12` and `# fail 0` - [ ] **Step 4: Commit** ```bash git add public/styles/shopping.css git commit -m "feat: add shopping swipe CSS (delete reveal, mobile button hide)" ``` --- ### Task 3: Wrap renderItem with swipe-row in shopping.js **Files:** - Modify: `public/pages/shopping.js` - [ ] **Step 1: Update renderItem()** Find `function renderItem(item)` in `public/pages/shopping.js` (currently returns a `.shopping-item` div). Replace the entire function with: ```js function renderItem(item) { const isDone = Boolean(item.is_checked); return `