Swap trigger
C1 overlay
Mobile: tap meal → bottom action sheet (Swap / Cook / View / Cancel). Desktop: no action sheet needed — the C1 detail panel already has a "Swap meal" button. Clicking it transitions the detail panel content to show swap suggestions inline.
V4 · Action sheet (mobile) · Detail panel button (desktop)
Mobile · Action sheet
17:15●●● WiFi 🔋
Mon · Chicken stir-fry
Tue · Tomato pasta
Tuesday — Tomato pasta
45 min · Easy · Vegetarian
↻ Swap this meal
🍳 Cook now
👁 View recipe
Cancel
Swap trigger
/* Mobile: tap meal card → bottom action sheet. Planner dims to 40%.
* Sheet: drag handle + meal name + meta + 4 action buttons stacked.
* Swap = orange-tint. Cook = green-tint. View = subtle. Cancel = no bg.
* Desktop: no action sheet. C1 detail panel has "Swap meal" ghost button (per planner-spec).
* Clicking "Swap meal" transitions the detail panel to show swap suggestions inline.
* Tap count: Mobile 3 (card → Swap → Pick). Desktop 2 (Swap → Pick). */
C2 in swap context
C2 swap
Mobile: bottom sheet over C1 with "Replacing" banner + easiest-first suggestions. Desktop: swap suggestions render inline in the C1 detail panel (replacing the meal detail) — the calendar grid stays visible alongside. No page navigation needed.
V1 · Quick swap sheet (mobile) · Inline detail panel (desktop)
Mobile · Swap sheet
17:16●●● WiFi 🔋
This week
Replacing Tuesday's meal
Tomato pasta · 45 min · Easy
Swap to (easiest first)
Quick carbonara
20 min · Easy · Pasta
Pick
Chicken stir-fry
25 min · Easy
⚠ Already on Mon
Pick
Mushroom risotto
50 min · Medium · Veggie
Pick
Cancel
C2 swap context
/* Mobile: bottom sheet over dimmed C1. "Replacing" banner + suggestion list.
* Sorted EASIEST FIRST (effort ASC, cook_time ASC) — different from J2.
* "Pick" → UPDATE week_plan_slot. Dismiss sheet. No confirmation dialog (undo toast instead).
* Desktop: detail panel (280px) transitions in-place. Calendar grid stays visible.
* Replacing header: orange-tint, old meal struck through.
* Suggestion cards: compact, fitting panel width. Name + meta + "Pick" link.
* Tap count: Mobile 3. Desktop 2 (faster — no action sheet intermediary). */
LLM Implementation Instructions — J4 Adapt on the Fly
1. Journey Flow
C1 → action sheet (mobile) or detail panel button (desktop) → swap suggestions → pick → C1.
Actor: Planner. Frequency: 1-2x/week. Urgency: HIGH.
2. Constraint: 3 taps maximum
From "Swap" to updated plan in no more than 3 taps.
- Mobile: 3 taps — card → Swap → Pick
- Desktop: 2 taps — Swap → Pick (no action sheet intermediary)
3. Mobile: Action Sheet
- Bottom sheet pulls up on meal tap; background dims to 40% opacity.
- Drag handle: 32px wide, 4px height,
var(--color-border) background.
- Meal title in 15px display font + metadata in 11px muted text.
- 4 stacked buttons:
- "Swap this meal" —
orange-tint bg / orange-dark text
- "Cook now" —
green-tint bg / green-dark text
- "View recipe" —
subtle bg / muted text
- "Cancel" — no background, muted text
4. Mobile: Swap Suggestions (Bottom Sheet)
- "Replacing" banner:
orange-tint background, old meal name struck through.
- "Swap to (easiest first)" eyebrow label above suggestion list.
- Compact suggestion cards: recipe name + time/effort/tag + "Pick" link on the right.
- Sorted EASIEST FIRST —
effort ASC, cook_time ASC. This is DIFFERENT from C2 in J2, which sorts by variety score.
- "Pick" action:
UPDATE week_plan_slot with new recipe_id → dismiss sheet → show undo toast (NOT a confirmation dialog).
5. Desktop: Inline Panel
- No action sheet needed — the C1 detail panel (280px wide) already has a "Swap meal" ghost button.
- Clicking the button transitions the detail panel content in-place to show swap suggestions.
- Calendar grid stays visible alongside the panel at all times.
- Same sorting (
effort ASC, cook_time ASC) and "Replacing" header as mobile.
6. Why Easiest First
Mid-week swaps typically happen because the original plan was too ambitious. Sorting by effort makes the fastest, lowest-effort options most visible, matching the user's intent to simplify.
7. Data Operations
- Writes:
week_plan_slot UPDATE — sets new recipe_id on the slot.
- Swap is logged: both the original meal (marked as not cooked) and the replacement are recorded.
- Original uncooked meal remains in the recipe library for future weeks.
- Variety score recalculates immediately after swap.
8. Design Constraints
- Speed over deliberation — undo toast instead of confirmation dialog. The user is in a hurry mid-week.
- Orange accent color for swap context:
orange-tint background, orange-dark text on banners and primary action.
- Variety filter still applies to suggestions (duplicates get a warning), just sorted differently than J2.