Six self-contained HTML documents, one per user journey, each combining mobile/desktop previews with machine-readable implementation guides: - j1-add-recipe.html (B1, B3) - j2-plan-the-week.html (C1, C2, C3) - j3-cook-tonight.html (B2, B4) - j4-adapt-on-the-fly.html (swap trigger, C2 swap) - j5-shopping-list.html (D1) - j6-household-setup.html (A1, A2, A3/D3, A4) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
296 lines
26 KiB
HTML
296 lines
26 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
<title>J4 — Adapt on the Fly</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,300;9..144,400;9..144,500&family=DM+Sans:wght@300;400;500;600&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet"/>
|
|
<style>
|
|
:root{--color-page:#FAFAF7;--color-surface:#F5F4EE;--color-subtle:#EDECEA;--color-border:#D8D7D0;--color-text-muted:#6B6A63;--color-text:#1C1C18;--green-tint:#E8F5EA;--green-light:#AEDCB0;--green:#3D8C4A;--green-dark:#2E6E39;--green-deeper:#1E4A26;--yellow-tint:#FDF6D8;--yellow-light:#F9E08A;--yellow:#F2C12E;--yellow-dark:#C49610;--yellow-text:#8A6800;--blue-tint:#E6F1FB;--blue-light:#A4CFF4;--blue:#2D7DD2;--blue-dark:#185FA5;--purple-tint:#EEEDFE;--purple:#534AB7;--purple-dark:#3C3489;--orange-tint:#FEF0E6;--orange:#E8862A;--orange-dark:#B46820;--color-error:#DC4C3E;--font-display:'Fraunces',Georgia,serif;--font-sans:'DM Sans',system-ui,sans-serif;--font-mono:'DM Mono',monospace;--radius-sm:4px;--radius-md:6px;--radius-lg:10px;--radius-xl:16px;--shadow-card:0 1px 3px rgba(28,28,24,.06),0 1px 2px rgba(28,28,24,.04);--shadow-raised:0 4px 12px rgba(28,28,24,.08),0 2px 4px rgba(28,28,24,.04);--shadow-overlay:0 8px 32px rgba(28,28,24,.12),0 2px 8px rgba(28,28,24,.06);}
|
|
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
|
|
body{font-family:var(--font-sans);background:#E8E7E2;color:var(--color-text);font-size:14px;line-height:1.6;}
|
|
.doc{max-width:1200px;margin:0 auto;padding:48px 40px 120px;}
|
|
|
|
/* Header */
|
|
.doc-header{display:flex;justify-content:space-between;align-items:flex-end;padding-bottom:28px;border-bottom:1px solid var(--color-border);margin-bottom:48px;background:var(--color-page);margin:-48px -40px 48px;padding:48px 40px 28px;border-radius:var(--radius-xl) var(--radius-xl) 0 0;}
|
|
.doc-header h1{font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-.02em;margin-bottom:4px;}
|
|
.doc-header p{font-size:13px;color:var(--color-text-muted);}
|
|
.doc-meta{font-family:var(--font-mono);font-size:11px;color:var(--color-text-muted);text-align:right;line-height:1.9;}
|
|
.pill{display:inline-block;padding:2px 8px;border-radius:var(--radius-sm);font-size:10px;font-weight:500;letter-spacing:.05em;background:var(--green-tint);color:var(--green-dark);}
|
|
|
|
/* Sections */
|
|
.section{margin-bottom:64px;}
|
|
.section-title{font-size:10px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--color-text-muted);padding-bottom:10px;border-bottom:1px solid var(--color-border);margin-bottom:24px;}
|
|
.prose{font-size:13px;color:var(--color-text-muted);line-height:1.65;max-width:720px;margin-bottom:20px;}
|
|
|
|
/* Journey headers */
|
|
.jh{padding:20px 24px;border-radius:var(--radius-xl);margin-bottom:40px;display:flex;align-items:center;gap:16px;}
|
|
.jh .jn{font-family:var(--font-display);font-size:48px;font-weight:300;line-height:1;opacity:.5;}
|
|
.jh h2{font-family:var(--font-display);font-size:22px;font-weight:500;letter-spacing:-.02em;margin-bottom:4px;}
|
|
.jh p{font-size:13px;line-height:1.5;}.jh .fl{font-family:var(--font-mono);font-size:11px;margin-top:6px;opacity:.7;}
|
|
.jh-p{background:var(--purple-tint);border:1px solid #CECBF6;}.jh-p .jn{color:var(--purple);}.jh-p p,.jh-p .fl{color:var(--purple-dark);}
|
|
.jh-g{background:var(--green-tint);border:1px solid var(--green-light);}.jh-g .jn{color:var(--green);}.jh-g p,.jh-g .fl{color:var(--green-dark);}
|
|
.jh-y{background:var(--yellow-tint);border:1px solid var(--yellow-light);}.jh-y .jn{color:var(--yellow-dark);}.jh-y p,.jh-y .fl{color:var(--yellow-text);}
|
|
.jh-o{background:var(--orange-tint);border:1px solid #FBCDA4;}.jh-o .jn{color:var(--orange);}.jh-o p,.jh-o .fl{color:var(--orange-dark);}
|
|
.jh-b{background:var(--blue-tint);border:1px solid var(--blue-light);}.jh-b .jn{color:var(--blue);}.jh-b p,.jh-b .fl{color:var(--blue-dark);}
|
|
|
|
/* Screen block */
|
|
.scr{margin-bottom:56px;}
|
|
.scr-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px;}
|
|
.scr-head h3{font-family:var(--font-display);font-size:20px;font-weight:500;letter-spacing:-.02em;}
|
|
.scr-id{font-family:var(--font-mono);font-size:11px;color:var(--color-text-muted);padding:2px 8px;border:1px solid var(--color-border);border-radius:var(--radius-sm);background:var(--color-page);}
|
|
.scr-desc{font-size:12px;color:var(--color-text-muted);line-height:1.6;max-width:720px;margin-bottom:6px;}
|
|
.scr-var{font-size:11px;color:var(--color-text-muted);margin-bottom:20px;}.scr-var strong{color:var(--color-text);}
|
|
|
|
/* Preview container */
|
|
.previews{display:flex;gap:32px;flex-wrap:wrap;justify-content:center;align-items:flex-start;margin-bottom:20px;}
|
|
.prev-col{display:flex;flex-direction:column;align-items:center;gap:10px;}
|
|
.bp-lbl{font-family:var(--font-mono);font-size:10px;color:var(--color-text-muted);}
|
|
|
|
/* Phone frame - 320px */
|
|
.phone{width:320px;flex-shrink:0;background:var(--color-page);border-radius:36px;overflow:hidden;box-shadow:var(--shadow-overlay),0 0 0 1px rgba(0,0,0,.07);display:flex;flex-direction:column;border:6px solid #1C1C18;}
|
|
.pst{padding:10px 20px 0;display:flex;justify-content:space-between;align-items:center;font-size:12px;background:var(--color-page);}.pst b{font-weight:600;}.pst span{font-size:10px;}
|
|
.pb{flex:1;overflow-y:auto;display:flex;flex-direction:column;}
|
|
|
|
/* Desktop frame - 1040px */
|
|
.desk{width:100%;max-width:1040px;background:var(--color-page);border-radius:var(--radius-xl);overflow:hidden;box-shadow:var(--shadow-overlay),0 0 0 1px rgba(0,0,0,.06);display:flex;min-height:520px;}
|
|
|
|
/* Shared nav components */
|
|
.mtb{padding:10px 16px;background:var(--color-page);border-bottom:1px solid var(--color-border);display:flex;justify-content:space-between;align-items:center;}
|
|
.mtb-t{font-family:var(--font-display);font-size:20px;font-weight:500;letter-spacing:-.02em;}
|
|
.mi{width:32px;height:32px;border-radius:var(--radius-md);border:1px solid var(--color-border);background:var(--color-surface);display:flex;align-items:center;justify-content:center;font-size:13px;color:var(--color-text-muted);flex-shrink:0;}.mi.gn{background:var(--green);border-color:var(--green);color:#fff;}
|
|
.mbt{border-top:1px solid var(--color-border);background:var(--color-surface);padding:8px 16px 28px;display:flex;justify-content:space-around;}
|
|
.mt-i{display:flex;flex-direction:column;align-items:center;gap:2px;}.mt-ic{width:20px;height:20px;border-radius:4px;background:var(--color-subtle);display:flex;align-items:center;justify-content:center;font-size:11px;}.mt-i.a .mt-ic{background:var(--green-tint);}.mt-l{font-size:9px;font-weight:500;color:var(--color-text-muted);}.mt-i.a .mt-l{color:var(--green-dark);}
|
|
|
|
/* Desktop sidebar - 224px per nav-spec */
|
|
.dsb{width:224px;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);display:flex;flex-direction:column;}
|
|
.dsb-logo{padding:20px 16px 16px;border-bottom:1px solid var(--color-border);}
|
|
.dsb-lm{display:flex;align-items:center;gap:8px;margin-bottom:2px;}.dsb-ic{width:24px;height:24px;border-radius:5px;background:var(--green);display:flex;align-items:center;justify-content:center;font-size:12px;}.dsb-nm{font-family:var(--font-display);font-size:16px;font-weight:500;letter-spacing:-.02em;}.dsb-sub{font-size:10px;color:var(--color-text-muted);padding-left:32px;}
|
|
.dsb-nav{padding:12px 10px;flex:1;}.dsb-nl{font-size:8px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--color-text-muted);padding:0 8px;margin-bottom:4px;}.dsb-ni{display:flex;align-items:center;gap:8px;padding:7px 8px;border-radius:var(--radius-md);font-size:13px;color:var(--color-text-muted);margin-bottom:2px;cursor:default;}.dsb-ni.a{background:var(--green-tint);color:var(--green-dark);font-weight:500;}.dsb-nc{font-size:13px;width:18px;text-align:center;}
|
|
.dm{flex:1;display:flex;flex-direction:column;min-width:0;}
|
|
.dtb{padding:12px 24px;border-bottom:1px solid var(--color-border);display:flex;justify-content:space-between;align-items:center;flex-shrink:0;}
|
|
.dtb-t{font-family:var(--font-display);font-size:18px;font-weight:500;letter-spacing:-.02em;}
|
|
.dtb-r{display:flex;align-items:center;gap:8px;}
|
|
.dab{font-family:var(--font-sans);font-size:13px;font-weight:500;padding:7px 16px;border-radius:var(--radius-md);background:var(--green);color:#fff;border:none;}
|
|
.dab-b{background:var(--blue);}
|
|
|
|
/* Shared form */
|
|
.fi{width:100%;font-family:var(--font-sans);font-size:14px;padding:10px 12px;border-radius:var(--radius-md);border:1px solid var(--color-border);background:var(--color-page);color:var(--color-text);outline:none;}
|
|
.fl{font-size:12px;font-weight:500;color:var(--color-text);margin-bottom:6px;display:block;}
|
|
.fg{margin-bottom:16px;}
|
|
.bp{font-family:var(--font-sans);font-size:14px;font-weight:500;padding:12px 24px;border-radius:var(--radius-md);background:var(--green);color:#fff;border:none;cursor:pointer;width:100%;}
|
|
.bg{font-family:var(--font-sans);font-size:13px;font-weight:500;padding:10px 20px;border-radius:var(--radius-md);background:var(--color-subtle);color:var(--color-text-muted);border:1px solid var(--color-border);cursor:pointer;}
|
|
|
|
/* Tags */
|
|
.tc{display:inline-flex;font-size:12px;font-weight:500;padding:6px 12px;border-radius:20px;border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-text-muted);cursor:pointer;margin:0 4px 4px 0;user-select:none;}.tc.s{background:var(--green-tint);color:var(--green-dark);border-color:var(--green-light);}
|
|
.badge{font-size:9px;font-weight:500;padding:2px 6px;border-radius:3px;display:inline-block;}.badge-g{background:var(--green-tint);color:var(--green-dark);}.badge-y{background:var(--yellow-tint);color:var(--yellow-text);}.badge-m{background:var(--color-subtle);color:var(--color-text-muted);}
|
|
|
|
/* Ingredient rows */
|
|
.ir{display:flex;align-items:center;gap:8px;padding:8px 0;border-bottom:1px solid var(--color-subtle);}.ir:last-child{border-bottom:none;}.ir-q{font-family:var(--font-mono);font-size:12px;color:var(--color-text-muted);width:55px;flex-shrink:0;text-align:right;}.ir-n{font-size:13px;color:var(--color-text);flex:1;}.ir-x{font-size:14px;color:var(--color-border);cursor:pointer;width:20px;text-align:center;}
|
|
|
|
/* Checklist */
|
|
.ck{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--color-subtle);cursor:pointer;}.ck:last-child{border-bottom:none;}.ck-b{width:22px;height:22px;border-radius:4px;border:2px solid var(--color-border);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:11px;}.ck.d .ck-b{background:var(--green);border-color:var(--green);color:#fff;}.ck-c{flex:1;}.ck-n{font-size:14px;color:var(--color-text);}.ck.d .ck-n{text-decoration:line-through;color:var(--color-text-muted);}.ck-s{font-size:10px;color:var(--color-text-muted);}.ck-q{font-family:var(--font-mono);font-size:12px;color:var(--color-text-muted);flex-shrink:0;}
|
|
|
|
/* Suggestion cards */
|
|
.sg{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:12px;margin-bottom:8px;display:flex;align-items:center;gap:10px;}.sg-r{font-family:var(--font-display);font-size:16px;font-weight:300;color:var(--color-text-muted);width:20px;text-align:center;flex-shrink:0;}.sg-b{flex:1;}.sg-n{font-family:var(--font-display);font-size:13px;font-weight:400;color:var(--color-text);margin-bottom:2px;}.sg-i{font-size:10px;color:var(--color-text-muted);}.sg-w{font-size:9px;color:var(--green-dark);background:var(--green-tint);padding:2px 6px;border-radius:3px;display:inline-block;margin-top:3px;}.sg-p{font-size:11px;font-weight:500;color:var(--green);flex-shrink:0;}
|
|
|
|
/* Eyebrow labels */
|
|
.eye{font-size:10px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--color-text-muted);}
|
|
|
|
/* Agent table */
|
|
.agent{background:var(--color-text);color:#E8E8E2;padding:24px;border-radius:var(--radius-lg);margin-top:20px;}
|
|
.agent h4{font-size:9px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:#5A5A55;margin-bottom:12px;}
|
|
.agent pre{font-family:var(--font-mono);font-size:10px;color:#444440;margin-bottom:16px;line-height:1.8;white-space:pre-wrap;}
|
|
.at{width:100%;border-collapse:collapse;font-family:var(--font-mono);font-size:10px;}
|
|
.at thead tr{border-bottom:1px solid #2A2A26;}.at th{text-align:left;padding:6px 10px;font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:#5A5A55;font-family:var(--font-sans);}.at td{padding:5px 10px;border-bottom:1px solid #1E1E1A;vertical-align:top;line-height:1.5;}.at tr:last-child td{border-bottom:none;}.at td:first-child{color:#7A7A72;}.at td:nth-child(2){color:#E8E8E2;font-weight:500;}.at td:nth-child(3){color:#5A5A55;}.at .grp td{padding-top:14px;font-family:var(--font-sans);font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:#3A3A36;}
|
|
|
|
/* LLM instruction box */
|
|
.llm{background:var(--color-page);border:2px solid var(--green-light);border-radius:var(--radius-lg);padding:28px 24px;margin-top:64px;}
|
|
.llm h3{font-family:var(--font-display);font-size:18px;font-weight:500;letter-spacing:-.02em;color:var(--green-dark);margin-bottom:16px;}
|
|
.llm h4{font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--green-dark);margin-top:20px;margin-bottom:8px;}
|
|
.llm p,.llm li{font-size:12px;color:var(--color-text-muted);line-height:1.7;}
|
|
.llm ul,.llm ol{padding-left:20px;margin-bottom:12px;}
|
|
.llm li{margin-bottom:4px;}
|
|
.llm code{font-family:var(--font-mono);font-size:11px;background:var(--green-tint);color:var(--green-dark);padding:1px 5px;border-radius:3px;}
|
|
|
|
@media(max-width:900px){.doc{padding:24px 16px 80px;}}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="doc">
|
|
|
|
<!-- ═══ J4 SWAP ═══ -->
|
|
<div class="jh jh-o">
|
|
<div class="jn">J4</div>
|
|
<div><h2>Adapt on the fly</h2><p>Mid-week swap in ≤ 3 taps. Action sheet → pick replacement → done.</p><div class="fl">C1 → action sheet → C2 swap → C1 · Easiest first</div></div>
|
|
</div>
|
|
|
|
<!-- ═══ SWAP TRIGGER ═══ -->
|
|
<div class="scr" id="swap-trigger">
|
|
<div class="scr-head"><h3>Swap trigger</h3><span class="scr-id">C1 overlay</span></div>
|
|
<div class="scr-desc">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.</div>
|
|
<div class="scr-var"><strong>V4 · Action sheet</strong> (mobile) · Detail panel button (desktop)</div>
|
|
|
|
<div class="previews">
|
|
<div class="prev-col">
|
|
<div class="bp-lbl">Mobile · Action sheet</div>
|
|
<div class="phone">
|
|
<div class="pst"><b>17:15</b><span>●●● WiFi 🔋</span></div>
|
|
<div class="pb">
|
|
<div class="mtb" style="opacity:.4;"><div class="mtb-t" style="font-size:16px;">This week</div></div>
|
|
<div style="padding:8px 12px;opacity:.4;">
|
|
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:10px;margin-bottom:6px;font-family:var(--font-display);font-size:12px;">Mon · Chicken stir-fry</div>
|
|
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:10px;font-family:var(--font-display);font-size:12px;">Tue · Tomato pasta</div>
|
|
</div>
|
|
<div style="flex:1;display:flex;flex-direction:column;justify-content:flex-end;">
|
|
<div style="background:var(--color-page);border-top:1px solid var(--color-border);border-radius:var(--radius-xl) var(--radius-xl) 0 0;padding:16px;box-shadow:0 -4px 20px rgba(0,0,0,.12);">
|
|
<div style="width:32px;height:4px;border-radius:2px;background:var(--color-border);margin:0 auto 12px;"></div>
|
|
<div style="font-family:var(--font-display);font-size:15px;font-weight:500;margin-bottom:4px;">Tuesday — Tomato pasta</div>
|
|
<div style="font-size:11px;color:var(--color-text-muted);margin-bottom:12px;">45 min · Easy · Vegetarian</div>
|
|
<div style="display:flex;flex-direction:column;gap:6px;">
|
|
<div style="padding:12px;border-radius:var(--radius-lg);background:var(--orange-tint);border:1px solid #FBCDA4;font-size:13px;font-weight:500;color:var(--orange-dark);text-align:center;">↻ Swap this meal</div>
|
|
<div style="padding:12px;border-radius:var(--radius-lg);background:var(--green-tint);border:1px solid var(--green-light);font-size:13px;font-weight:500;color:var(--green-dark);text-align:center;">🍳 Cook now</div>
|
|
<div style="padding:12px;border-radius:var(--radius-lg);background:var(--color-subtle);border:1px solid var(--color-border);font-size:13px;font-weight:500;color:var(--color-text-muted);text-align:center;">👁 View recipe</div>
|
|
<div style="padding:12px;font-size:13px;color:var(--color-text-muted);text-align:center;">Cancel</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="agent">
|
|
<h4>Swap trigger</h4>
|
|
<pre>/* 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). */</pre>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- ═══ C2 SWAP CONTEXT ═══ -->
|
|
<div class="scr" id="swap-context">
|
|
<div class="scr-head"><h3>C2 in swap context</h3><span class="scr-id">C2 swap</span></div>
|
|
<div class="scr-desc">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.</div>
|
|
<div class="scr-var"><strong>V1 · Quick swap sheet</strong> (mobile) · Inline detail panel (desktop)</div>
|
|
|
|
<div class="previews">
|
|
<div class="prev-col">
|
|
<div class="bp-lbl">Mobile · Swap sheet</div>
|
|
<div class="phone">
|
|
<div class="pst"><b>17:16</b><span>●●● WiFi 🔋</span></div>
|
|
<div class="pb">
|
|
<div style="opacity:.3;padding:10px 16px;border-bottom:1px solid var(--color-border);font-family:var(--font-display);font-size:16px;font-weight:500;">This week</div>
|
|
<div style="flex:1;display:flex;flex-direction:column;justify-content:flex-end;">
|
|
<div style="background:var(--color-page);border-top:1px solid var(--color-border);border-radius:var(--radius-xl) var(--radius-xl) 0 0;padding:16px;box-shadow:0 -4px 20px rgba(0,0,0,.12);">
|
|
<div style="width:32px;height:4px;border-radius:2px;background:var(--color-border);margin:0 auto 10px;"></div>
|
|
<div style="background:var(--orange-tint);border:1px solid #FBCDA4;border-radius:var(--radius-lg);padding:10px 12px;margin-bottom:14px;">
|
|
<div class="eye" style="color:var(--orange-dark);margin-bottom:4px;">Replacing Tuesday's meal</div>
|
|
<div style="font-family:var(--font-display);font-size:14px;text-decoration:line-through;opacity:.6;">Tomato pasta · 45 min · Easy</div>
|
|
</div>
|
|
<div class="eye" style="margin-bottom:6px;">Swap to (easiest first)</div>
|
|
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:10px 12px;margin-bottom:6px;display:flex;align-items:center;gap:8px;">
|
|
<div style="flex:1;"><div style="font-family:var(--font-display);font-size:13px;">Quick carbonara</div><div style="font-size:9px;color:var(--color-text-muted);">20 min · Easy · Pasta</div></div>
|
|
<div style="font-size:11px;color:var(--green);font-weight:500;">Pick</div>
|
|
</div>
|
|
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:10px 12px;margin-bottom:6px;display:flex;align-items:center;gap:8px;">
|
|
<div style="flex:1;"><div style="font-family:var(--font-display);font-size:13px;">Chicken stir-fry</div><div style="font-size:9px;color:var(--color-text-muted);">25 min · Easy</div><div style="font-size:9px;color:var(--yellow-text);">⚠ Already on Mon</div></div>
|
|
<div style="font-size:11px;color:var(--green);font-weight:500;">Pick</div>
|
|
</div>
|
|
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:10px 12px;margin-bottom:6px;display:flex;align-items:center;gap:8px;">
|
|
<div style="flex:1;"><div style="font-family:var(--font-display);font-size:13px;">Mushroom risotto</div><div style="font-size:9px;color:var(--color-text-muted);">50 min · Medium · Veggie</div></div>
|
|
<div style="font-size:11px;color:var(--green);font-weight:500;">Pick</div>
|
|
</div>
|
|
<div style="text-align:center;padding:8px 0;font-size:11px;color:var(--color-text-muted);">Cancel</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="agent">
|
|
<h4>C2 swap context</h4>
|
|
<pre>/* 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). */</pre>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<!-- ═══ LLM INSTRUCTIONS ═══ -->
|
|
<div class="llm">
|
|
<h3>LLM Implementation Instructions — J4 Adapt on the Fly</h3>
|
|
|
|
<h4>1. Journey Flow</h4>
|
|
<p>C1 → action sheet (mobile) or detail panel button (desktop) → swap suggestions → pick → C1.
|
|
Actor: <strong>Planner</strong>. Frequency: 1-2x/week. Urgency: <strong>HIGH</strong>.</p>
|
|
|
|
<h4>2. Constraint: 3 taps maximum</h4>
|
|
<p>From "Swap" to updated plan in no more than 3 taps.</p>
|
|
<ul>
|
|
<li><strong>Mobile: 3 taps</strong> — card → Swap → Pick</li>
|
|
<li><strong>Desktop: 2 taps</strong> — Swap → Pick (no action sheet intermediary)</li>
|
|
</ul>
|
|
|
|
<h4>3. Mobile: Action Sheet</h4>
|
|
<ul>
|
|
<li>Bottom sheet pulls up on meal tap; background dims to <strong>40% opacity</strong>.</li>
|
|
<li>Drag handle: 32px wide, 4px height, <code>var(--color-border)</code> background.</li>
|
|
<li>Meal title in 15px display font + metadata in 11px muted text.</li>
|
|
<li>4 stacked buttons:
|
|
<ol>
|
|
<li><strong>"Swap this meal"</strong> — <code>orange-tint</code> bg / <code>orange-dark</code> text</li>
|
|
<li><strong>"Cook now"</strong> — <code>green-tint</code> bg / <code>green-dark</code> text</li>
|
|
<li><strong>"View recipe"</strong> — <code>subtle</code> bg / <code>muted</code> text</li>
|
|
<li><strong>"Cancel"</strong> — no background, muted text</li>
|
|
</ol>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>4. Mobile: Swap Suggestions (Bottom Sheet)</h4>
|
|
<ul>
|
|
<li>"Replacing" banner: <code>orange-tint</code> background, old meal name struck through.</li>
|
|
<li>"Swap to (easiest first)" eyebrow label above suggestion list.</li>
|
|
<li>Compact suggestion cards: recipe name + time/effort/tag + "Pick" link on the right.</li>
|
|
<li><strong>Sorted EASIEST FIRST</strong> — <code>effort ASC, cook_time ASC</code>. This is DIFFERENT from C2 in J2, which sorts by variety score.</li>
|
|
<li>"Pick" action: <code>UPDATE week_plan_slot</code> with new <code>recipe_id</code> → dismiss sheet → show <strong>undo toast</strong> (NOT a confirmation dialog).</li>
|
|
</ul>
|
|
|
|
<h4>5. Desktop: Inline Panel</h4>
|
|
<ul>
|
|
<li>No action sheet needed — the C1 detail panel (280px wide) already has a "Swap meal" ghost button.</li>
|
|
<li>Clicking the button transitions the detail panel content <strong>in-place</strong> to show swap suggestions.</li>
|
|
<li>Calendar grid stays visible alongside the panel at all times.</li>
|
|
<li>Same sorting (<code>effort ASC, cook_time ASC</code>) and "Replacing" header as mobile.</li>
|
|
</ul>
|
|
|
|
<h4>6. Why Easiest First</h4>
|
|
<p>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.</p>
|
|
|
|
<h4>7. Data Operations</h4>
|
|
<ul>
|
|
<li><strong>Writes:</strong> <code>week_plan_slot UPDATE</code> — sets new <code>recipe_id</code> on the slot.</li>
|
|
<li>Swap is logged: both the original meal (marked as not cooked) and the replacement are recorded.</li>
|
|
<li>Original uncooked meal remains in the recipe library for future weeks.</li>
|
|
<li>Variety score recalculates immediately after swap.</li>
|
|
</ul>
|
|
|
|
<h4>8. Design Constraints</h4>
|
|
<ul>
|
|
<li><strong>Speed over deliberation</strong> — undo toast instead of confirmation dialog. The user is in a hurry mid-week.</li>
|
|
<li>Orange accent color for swap context: <code>orange-tint</code> background, <code>orange-dark</code> text on banners and primary action.</li>
|
|
<li>Variety filter still applies to suggestions (duplicates get a warning), just sorted differently than J2.</li>
|
|
</ul>
|
|
</div>
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|