Files
mealprep/specs/frontend/j6-household-setup.html
Marcel Raddatz b36d4c731d Add frontend journey specs with visual previews and LLM instructions
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>
2026-04-02 12:17:47 +02:00

473 lines
42 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>J6 — Household Setup · Screen Specs</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;}
.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);}
.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;}
.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);}
.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);}
.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{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;}
.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;}
.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;}
.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);}
.eye{font-size:10px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--color-text-muted);}
.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 section */
.llm{background:var(--color-page);border:2px solid var(--green);border-radius:var(--radius-xl);padding:32px 40px;margin-top:64px;}
.llm h2{font-family:var(--font-display);font-size:22px;font-weight:500;letter-spacing:-.02em;margin-bottom:8px;color:var(--green-dark);}
.llm h3{font-size:14px;font-weight:600;margin:20px 0 8px;color:var(--color-text);}
.llm p,.llm li{font-size:13px;color:var(--color-text-muted);line-height:1.65;}
.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(--color-surface);padding:1px 5px;border-radius:3px;}
.llm table{width:100%;border-collapse:collapse;margin:12px 0;font-size:12px;}
.llm th,.llm td{text-align:left;padding:6px 10px;border-bottom:1px solid var(--color-border);}
.llm th{font-weight:500;color:var(--color-text);font-size:11px;text-transform:uppercase;letter-spacing:.05em;}
.llm td{color:var(--color-text-muted);}
@media(max-width:900px){.doc{padding:24px 16px 80px;}}
</style>
</head>
<body>
<div class="doc">
<div class="doc-header">
<div>
<h1>J6 — Household setup</h1>
<p>One-time onboarding journey · Screens A1, A2, A3/D3, A4</p>
</div>
<div class="doc-meta">
<span class="pill">v1.0</span><br>
Screens: 4<br>
Flow: A1 → A2 → A3 → A2 → [invite] → A4
</div>
</div>
<div class="jh jh-p">
<div class="jn">J6</div>
<div><h2>Household setup</h2><p>One-time onboarding. Account creation → household naming → staples → invite.</p><div class="fl">A1 → A2 → A3 → A2 → [invite] → A4</div></div>
</div>
<!-- ═══ A1 SIGN UP ═══ -->
<div class="scr" id="a1">
<div class="scr-head"><h3>Sign up</h3><span class="scr-id">A1</span></div>
<div class="scr-desc">First screen. Creates user_account. No navigation chrome (pre-auth). Desktop: full-viewport split — brand identity left, signup form right. Not a centered card — the brand section fills the entire left half.</div>
<div class="scr-var"><strong>V2 · Split layout</strong> — brand left fills viewport height, form right</div>
<div class="previews">
<div class="prev-col">
<div class="bp-lbl">Mobile · 320px</div>
<div class="phone">
<div class="pst"><b>9:41</b><span>●●● WiFi 🔋</span></div>
<div class="pb">
<div style="background:var(--green-dark);padding:28px 24px;text-align:center;">
<div style="font-size:28px;margin-bottom:8px;">🥗</div>
<div style="font-family:var(--font-display);font-size:22px;font-weight:500;color:#fff;">Mealplan</div>
<div style="font-size:12px;color:var(--green-light);margin-top:4px;">Plan meals, eat well, waste less</div>
</div>
<div style="padding:24px 20px;">
<div style="font-family:var(--font-display);font-size:18px;font-weight:500;margin-bottom:4px;">Create your account</div>
<div style="font-size:12px;color:var(--color-text-muted);margin-bottom:20px;">You'll set up your household next.</div>
<div class="fg"><label class="fl">Your name</label><input class="fi" placeholder="e.g. Sarah"/></div>
<div class="fg"><label class="fl">Email</label><input class="fi" placeholder="you@example.com"/></div>
<div class="fg"><label class="fl">Password</label><input class="fi" type="password" placeholder="At least 8 characters"/></div>
<button class="bp">Create account →</button>
<div style="text-align:center;margin-top:16px;font-size:12px;color:var(--color-text-muted);">Already have an account? <span style="color:var(--green);font-weight:500;">Log in</span></div>
</div>
</div>
</div>
</div>
<div class="prev-col">
<div class="bp-lbl">Desktop · 1040px</div>
<div class="desk" style="min-height:500px;">
<div style="width:440px;flex-shrink:0;background:var(--green-dark);display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 40px;">
<div style="font-size:64px;margin-bottom:20px;">🥗</div>
<div style="font-family:var(--font-display);font-size:36px;font-weight:500;color:#fff;letter-spacing:-.02em;margin-bottom:10px;">Mealplan</div>
<div style="font-size:15px;color:var(--green-light);text-align:center;line-height:1.6;max-width:280px;">Plan your week's dinners. Get variety-aware suggestions. Shop together as a household.</div>
<div style="margin-top:32px;display:flex;gap:12px;">
<div style="background:rgba(255,255,255,.1);border-radius:8px;padding:12px 16px;text-align:center;"><div style="font-size:18px;margin-bottom:4px;">📅</div><div style="font-size:10px;color:var(--green-light);">Plan</div></div>
<div style="background:rgba(255,255,255,.1);border-radius:8px;padding:12px 16px;text-align:center;"><div style="font-size:18px;margin-bottom:4px;">🍳</div><div style="font-size:10px;color:var(--green-light);">Cook</div></div>
<div style="background:rgba(255,255,255,.1);border-radius:8px;padding:12px 16px;text-align:center;"><div style="font-size:18px;margin-bottom:4px;">🛒</div><div style="font-size:10px;color:var(--green-light);">Shop</div></div>
</div>
</div>
<div style="flex:1;display:flex;flex-direction:column;justify-content:center;padding:48px 56px;">
<div style="max-width:380px;">
<div style="font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-.02em;margin-bottom:6px;">Create your account</div>
<div style="font-size:14px;color:var(--color-text-muted);margin-bottom:32px;">You'll set up your household next.</div>
<div class="fg"><label class="fl">Your name</label><input class="fi" placeholder="e.g. Sarah"/></div>
<div class="fg"><label class="fl">Email</label><input class="fi" placeholder="you@example.com"/></div>
<div class="fg"><label class="fl">Password</label><input class="fi" type="password" placeholder="At least 8 characters"/></div>
<button class="bp" style="margin-top:8px;">Create account →</button>
<div style="text-align:center;margin-top:20px;font-size:13px;color:var(--color-text-muted);">Already have an account? <span style="color:var(--green);font-weight:500;cursor:pointer;">Log in</span></div>
</div>
</div>
</div>
</div>
</div>
<div class="agent">
<h4>A1 · Sign up</h4>
<pre>/* Pre-auth. No nav chrome. Desktop: full-viewport 2-col split. Brand ~42% / Form ~58%.
* Mobile: brand as ~120px banner, form below.
* Brand section: green-dark bg. Contains logo, tagline, 3 feature icons.
* Form section: page bg. Form max-width 380px. Not a card — just content on the page.
* Writes: user_account INSERT → redirect A2 */</pre>
<table class="at"><thead><tr><th>Element</th><th>Value</th><th>Notes</th></tr></thead><tbody>
<tr class="grp"><td colspan="3">Desktop layout</td></tr>
<tr><td>Brand panel</td><td>440px fixed, green-dark bg, content centered vertically</td><td>Logo 64px + name Fraunces 36px + tagline 15px + 3 feature icons</td></tr>
<tr><td>Form panel</td><td>flex:1, page bg, content centered vertically, 48px 56px padding</td><td>Form max-width 380px. Not wrapped in a card.</td></tr>
<tr class="grp"><td colspan="3">Mobile layout</td></tr>
<tr><td>Brand banner</td><td>~120px, green-dark bg, centered</td><td>Logo 28px + name 22px + tagline 12px</td></tr>
<tr><td>Form</td><td>Full width, 24px 20px padding</td><td>Same fields, smaller type sizes</td></tr>
<tr class="grp"><td colspan="3">Data</td></tr>
<tr><td>Writes</td><td>user_account INSERT</td><td>system_role='user', is_active=true → A2</td></tr>
</tbody></table>
</div>
</div>
<!-- ═══ A2 HOUSEHOLD SETUP ═══ -->
<div class="scr" id="a2">
<div class="scr-head"><h3>Household setup</h3><span class="scr-id">A2</span></div>
<div class="scr-desc">Name household + optional member invite. Desktop: full-page layout with a left illustration/progress column and the form on the right. Not a floating card — a structured page with clear sections.</div>
<div class="scr-var"><strong>V1 · Simple form</strong> — desktop: progress sidebar left, form right</div>
<div class="previews">
<div class="prev-col">
<div class="bp-lbl">Mobile · 320px</div>
<div class="phone">
<div class="pst"><b>9:42</b><span>●●● WiFi 🔋</span></div>
<div class="pb">
<div style="padding:24px 20px;">
<div class="eye" style="margin-bottom:4px;">Step 1 of 3</div>
<div style="font-family:var(--font-display);font-size:20px;font-weight:500;margin-bottom:6px;">Name your household</div>
<div style="font-size:12px;color:var(--color-text-muted);margin-bottom:20px;">This appears in the sidebar and is shared with all members.</div>
<div class="fg"><label class="fl">Household name</label><input class="fi" value="Smith family"/></div>
<div style="border-top:1px solid var(--color-border);padding-top:20px;margin-top:8px;">
<div class="eye" style="margin-bottom:8px;">Invite members (optional)</div>
<div style="font-size:12px;color:var(--color-text-muted);margin-bottom:12px;">You can skip this and invite people later from settings.</div>
<button class="bg" style="width:100%;font-size:12px;">+ Generate invite link</button>
</div>
<div style="margin-top:24px;"><button class="bp">Continue → Set up staples</button></div>
</div>
</div>
</div>
</div>
<div class="prev-col">
<div class="bp-lbl">Desktop · 1040px</div>
<div class="desk" style="min-height:480px;">
<!-- Left: progress / branding strip -->
<div style="width:300px;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);padding:40px 28px;display:flex;flex-direction:column;">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:40px;">
<div style="width:28px;height:28px;border-radius:6px;background:var(--green);display:flex;align-items:center;justify-content:center;font-size:14px;">🥗</div>
<div style="font-family:var(--font-display);font-size:16px;font-weight:500;">Mealplan</div>
</div>
<!-- Progress steps -->
<div style="display:flex;flex-direction:column;gap:24px;flex:1;">
<div style="display:flex;gap:12px;align-items:flex-start;">
<div style="width:28px;height:28px;border-radius:50%;background:var(--green);color:#fff;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;flex-shrink:0;">1</div>
<div><div style="font-size:13px;font-weight:500;color:var(--color-text);">Name your household</div><div style="font-size:11px;color:var(--color-text-muted);margin-top:2px;">Give your family a name</div></div>
</div>
<div style="display:flex;gap:12px;align-items:flex-start;">
<div style="width:28px;height:28px;border-radius:50%;background:var(--color-subtle);color:var(--color-text-muted);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;flex-shrink:0;">2</div>
<div><div style="font-size:13px;color:var(--color-text-muted);">Set up pantry staples</div><div style="font-size:11px;color:var(--color-text-muted);margin-top:2px;">What you always have at home</div></div>
</div>
<div style="display:flex;gap:12px;align-items:flex-start;">
<div style="width:28px;height:28px;border-radius:50%;background:var(--color-subtle);color:var(--color-text-muted);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;flex-shrink:0;">3</div>
<div><div style="font-size:13px;color:var(--color-text-muted);">Invite members</div><div style="font-size:11px;color:var(--color-text-muted);margin-top:2px;">Share with your household</div></div>
</div>
</div>
</div>
<!-- Right: form content -->
<div style="flex:1;padding:48px 56px;display:flex;flex-direction:column;justify-content:center;">
<div style="max-width:420px;">
<div style="font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-.02em;margin-bottom:6px;">Name your household</div>
<div style="font-size:14px;color:var(--color-text-muted);margin-bottom:28px;">This name appears in the sidebar and is shared with all members.</div>
<div class="fg"><label class="fl">Household name</label><input class="fi" value="Smith family" style="font-size:16px;padding:12px 14px;"/></div>
<div style="border-top:1px solid var(--color-border);padding-top:24px;margin-top:8px;">
<div class="eye" style="margin-bottom:10px;">Invite members (optional)</div>
<div style="font-size:13px;color:var(--color-text-muted);margin-bottom:14px;">You can skip this and invite people later from settings.</div>
<button class="bg" style="width:100%;font-size:13px;padding:12px;">+ Generate invite link</button>
</div>
<div style="margin-top:32px;"><button class="bp" style="font-size:15px;padding:14px;">Continue → Set up staples</button></div>
</div>
</div>
</div>
</div>
</div>
<div class="agent">
<h4>A2 · Household setup</h4>
<pre>/* Desktop: progress sidebar (300px, surface bg) + form area (flex:1, page bg).
* Progress sidebar shows: app logo + 3 numbered steps (current = green circle, future = subtle).
* Form area: content centered vertically, max-width 420px. Not a card — content on page bg.
* Mobile: full-width form with step indicator text at top. No progress sidebar.
* Writes: household INSERT + household_member INSERT (role=planner) → A3 */</pre>
<table class="at"><thead><tr><th>Element</th><th>Value</th><th>Notes</th></tr></thead><tbody>
<tr class="grp"><td colspan="3">Desktop layout</td></tr>
<tr><td>Progress sidebar</td><td>300px, surface bg, border-right</td><td>App logo top + numbered steps. Current step: green circle.</td></tr>
<tr><td>Form area</td><td>flex:1, page bg, centered content</td><td>max-width 420px. Larger input (16px, 12px padding).</td></tr>
<tr><td>Step circles</td><td>28px diameter. Active: green bg #fff text. Future: subtle bg muted text.</td><td>Labels: 13px name + 11px description below</td></tr>
<tr class="grp"><td colspan="3">Mobile</td></tr>
<tr><td>Step indicator</td><td>"Step 1 of 3" eyebrow text</td><td>No sidebar, text-only progress</td></tr>
<tr><td>Form</td><td>Full width, 24px 20px padding</td><td>Same fields</td></tr>
</tbody></table>
</div>
</div>
<!-- ═══ A3 PANTRY STAPLES ═══ -->
<div class="scr" id="a3">
<div class="scr-head"><h3>Pantry staples</h3><span class="scr-id">A3 / D3</span></div>
<div class="scr-desc">Toggle staple ingredients by category. Desktop: same progress sidebar as A2 (step 2 active) + content area with a multi-column chip grid. The chips flow naturally across the full content width — no card wrapper needed.</div>
<div class="scr-var"><strong>V2 · Categorized list</strong> — desktop: progress sidebar + 2-col category grid</div>
<div class="previews">
<div class="prev-col">
<div class="bp-lbl">Mobile · 320px</div>
<div class="phone">
<div class="pst"><b>9:43</b><span>●●● WiFi 🔋</span></div>
<div class="pb">
<div style="padding:20px;">
<div class="eye" style="margin-bottom:4px;">Step 2 of 3</div>
<div style="font-family:var(--font-display);font-size:20px;font-weight:500;margin-bottom:6px;">Your pantry staples</div>
<div style="font-size:12px;color:var(--color-text-muted);margin-bottom:16px;">These won't appear on your shopping list. Tap to toggle.</div>
<div class="eye" style="margin:12px 0 6px;">Oils &amp; fats</div>
<div><span class="tc s" onclick="this.classList.toggle('s')">Olive oil</span><span class="tc s" onclick="this.classList.toggle('s')">Butter</span><span class="tc" onclick="this.classList.toggle('s')">Coconut oil</span></div>
<div class="eye" style="margin:16px 0 6px;">Spices</div>
<div><span class="tc s" onclick="this.classList.toggle('s')">Salt</span><span class="tc s" onclick="this.classList.toggle('s')">Pepper</span><span class="tc s" onclick="this.classList.toggle('s')">Garlic</span><span class="tc" onclick="this.classList.toggle('s')">Cumin</span><span class="tc" onclick="this.classList.toggle('s')">Paprika</span></div>
<div class="eye" style="margin:16px 0 6px;">Grains &amp; pasta</div>
<div><span class="tc s" onclick="this.classList.toggle('s')">Rice</span><span class="tc s" onclick="this.classList.toggle('s')">Pasta</span><span class="tc" onclick="this.classList.toggle('s')">Flour</span></div>
<div class="eye" style="margin:16px 0 6px;">Sauces</div>
<div><span class="tc s" onclick="this.classList.toggle('s')">Soy sauce</span><span class="tc" onclick="this.classList.toggle('s')">Fish sauce</span><span class="tc s" onclick="this.classList.toggle('s')">Vinegar</span></div>
<div style="margin-top:20px;"><button class="bp">Continue → Invite members</button></div>
</div>
</div>
</div>
</div>
<div class="prev-col">
<div class="bp-lbl">Desktop · 1040px</div>
<div class="desk" style="min-height:500px;">
<!-- Progress sidebar (same as A2 but step 2 active) -->
<div style="width:300px;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);padding:40px 28px;display:flex;flex-direction:column;">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:40px;"><div style="width:28px;height:28px;border-radius:6px;background:var(--green);display:flex;align-items:center;justify-content:center;font-size:14px;">🥗</div><div style="font-family:var(--font-display);font-size:16px;font-weight:500;">Mealplan</div></div>
<div style="display:flex;flex-direction:column;gap:24px;">
<div style="display:flex;gap:12px;align-items:flex-start;"><div style="width:28px;height:28px;border-radius:50%;background:var(--green-tint);color:var(--green-dark);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;flex-shrink:0;"></div><div><div style="font-size:13px;color:var(--green-dark);">Name your household</div><div style="font-size:11px;color:var(--green-dark);margin-top:2px;">Smith family</div></div></div>
<div style="display:flex;gap:12px;align-items:flex-start;"><div style="width:28px;height:28px;border-radius:50%;background:var(--green);color:#fff;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;flex-shrink:0;">2</div><div><div style="font-size:13px;font-weight:500;color:var(--color-text);">Set up pantry staples</div><div style="font-size:11px;color:var(--color-text-muted);margin-top:2px;">What you always have at home</div></div></div>
<div style="display:flex;gap:12px;align-items:flex-start;"><div style="width:28px;height:28px;border-radius:50%;background:var(--color-subtle);color:var(--color-text-muted);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;flex-shrink:0;">3</div><div><div style="font-size:13px;color:var(--color-text-muted);">Invite members</div></div></div>
</div>
</div>
<!-- Content: chips in natural 2-column flow -->
<div style="flex:1;padding:48px 56px;overflow-y:auto;">
<div style="font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-.02em;margin-bottom:6px;">Your pantry staples</div>
<div style="font-size:14px;color:var(--color-text-muted);margin-bottom:28px;max-width:500px;">These items won't appear on your shopping list. Click to toggle. You can always change these later in settings.</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:24px 32px;margin-bottom:32px;">
<div><div class="eye" style="margin-bottom:8px;">Oils &amp; fats</div><div><span class="tc s">Olive oil</span><span class="tc s">Butter</span><span class="tc">Coconut oil</span><span class="tc s">Vegetable oil</span></div></div>
<div><div class="eye" style="margin-bottom:8px;">Spices &amp; seasonings</div><div><span class="tc s">Salt</span><span class="tc s">Pepper</span><span class="tc s">Garlic</span><span class="tc">Cumin</span><span class="tc">Paprika</span><span class="tc s">Chili flakes</span><span class="tc">Oregano</span><span class="tc">Cinnamon</span></div></div>
<div><div class="eye" style="margin-bottom:8px;">Grains &amp; pasta</div><div><span class="tc s">Rice</span><span class="tc s">Pasta</span><span class="tc">Flour</span><span class="tc">Breadcrumbs</span><span class="tc">Couscous</span></div></div>
<div><div class="eye" style="margin-bottom:8px;">Sauces &amp; condiments</div><div><span class="tc s">Soy sauce</span><span class="tc">Fish sauce</span><span class="tc s">Vinegar</span><span class="tc">Mustard</span><span class="tc">Ketchup</span></div></div>
<div><div class="eye" style="margin-bottom:8px;">Baking</div><div><span class="tc s">Sugar</span><span class="tc">Baking powder</span><span class="tc">Vanilla extract</span></div></div>
<div><div class="eye" style="margin-bottom:8px;">Dairy &amp; basics</div><div><span class="tc s">Eggs</span><span class="tc s">Milk</span><span class="tc">Cream</span><span class="tc">Cheese</span></div></div>
</div>
<button class="bp" style="max-width:320px;font-size:15px;padding:14px;">Continue → Invite members</button>
<div style="margin-top:10px;font-size:12px;color:var(--color-text-muted);cursor:pointer;">Skip for now</div>
</div>
</div>
</div>
</div>
<div class="agent">
<h4>A3/D3 · Pantry staples</h4>
<pre>/* Desktop onboarding: progress sidebar (300px, step 2 active) + content area with 2-col category grid.
* Categories flow in a CSS grid (2 columns, 24px row gap, 32px col gap).
* Chips sit directly on the page bg — no card wrappers.
* Desktop settings (D3): same chip grid but inside sidebar+topbar layout (no progress sidebar).
* Mobile: single-column chip list, full width.
* Chip toggle: UPDATE ingredient SET is_staple. Debounced 300ms. */</pre>
<table class="at"><thead><tr><th>Element</th><th>Value</th><th>Notes</th></tr></thead><tbody>
<tr class="grp"><td colspan="3">Desktop onboarding</td></tr>
<tr><td>Progress sidebar</td><td>300px, surface bg. Step 1 = ✓ completed. Step 2 = green active.</td><td>Same sidebar as A2, reused component.</td></tr>
<tr><td>Category grid</td><td>grid-template-columns: 1fr 1fr. gap: 24px 32px.</td><td>Categories from ingredient_category, sorted by sort_order.</td></tr>
<tr><td>Chips</td><td>12px/500, 6px 12px pad, 20px radius. Selected: green-tint/green-light/green-dark.</td><td>Direct on page bg. No card wrapper.</td></tr>
<tr class="grp"><td colspan="3">Desktop settings (D3)</td></tr>
<tr><td>Layout</td><td>App sidebar (224px) + topbar ("Staples") + content with 3-col grid</td><td>Wider content area → 3 columns for categories.</td></tr>
</tbody></table>
</div>
</div>
<!-- ═══ A4 JOIN HOUSEHOLD ═══ -->
<div class="scr" id="a4">
<div class="scr-head"><h3>Join household</h3><span class="scr-id">A4</span></div>
<div class="scr-desc">Member accepts invite. Desktop: split layout like A1 — left side shows the household identity (name, who invited), right side has the signup form. The left panel uses green-tint (not green-dark) since this is a welcoming join screen, not a brand-first screen.</div>
<div class="scr-var"><strong>V2 · Welcome card</strong> — desktop: household identity left, join form right</div>
<div class="previews">
<div class="prev-col">
<div class="bp-lbl">Mobile · 320px</div>
<div class="phone">
<div class="pst"><b>10:15</b><span>●●● WiFi 🔋</span></div>
<div class="pb">
<div style="background:var(--green-tint);padding:28px 24px;text-align:center;border-bottom:1px solid var(--green-light);">
<div style="width:48px;height:48px;border-radius:12px;background:var(--green);display:flex;align-items:center;justify-content:center;font-size:22px;margin:0 auto 12px;">🥗</div>
<div style="font-family:var(--font-display);font-size:22px;font-weight:500;color:var(--green-deeper);margin-bottom:4px;">Smith family</div>
<div style="font-size:12px;color:var(--green-dark);">Sarah invited you to join their meal planner</div>
</div>
<div style="padding:24px 20px;">
<div style="background:var(--green-tint);border:1px solid var(--green-light);border-radius:var(--radius-lg);padding:10px 12px;margin-bottom:20px;font-size:11px;color:var(--green-dark);line-height:1.5;">You'll be able to view the weekly meal plan and check off items on the shared shopping list.</div>
<div class="fg"><label class="fl">Your name</label><input class="fi" placeholder="e.g. Tom"/></div>
<div class="fg"><label class="fl">Email</label><input class="fi" placeholder="you@example.com"/></div>
<div class="fg"><label class="fl">Password</label><input class="fi" type="password" placeholder="At least 8 characters"/></div>
<button class="bp">Join household</button>
</div>
</div>
</div>
</div>
<div class="prev-col">
<div class="bp-lbl">Desktop · 1040px</div>
<div class="desk" style="min-height:480px;">
<!-- Left: household identity -->
<div style="width:400px;flex-shrink:0;background:var(--green-tint);border-right:1px solid var(--green-light);display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 40px;text-align:center;">
<div style="width:64px;height:64px;border-radius:16px;background:var(--green);display:flex;align-items:center;justify-content:center;font-size:32px;margin-bottom:20px;">🥗</div>
<div style="font-family:var(--font-display);font-size:32px;font-weight:500;color:var(--green-deeper);letter-spacing:-.02em;margin-bottom:8px;">Smith family</div>
<div style="font-size:14px;color:var(--green-dark);margin-bottom:24px;">Sarah invited you to join</div>
<div style="background:rgba(255,255,255,.5);border-radius:var(--radius-lg);padding:16px 20px;max-width:280px;">
<div style="font-size:12px;font-weight:500;color:var(--green-dark);margin-bottom:8px;">What you'll be able to do:</div>
<div style="font-size:12px;color:var(--green-dark);line-height:1.6;text-align:left;">
<div style="padding:3px 0;">📅 View the weekly meal plan</div>
<div style="padding:3px 0;">🛒 Check off shopping list items</div>
<div style="padding:3px 0;"> Add items to the list</div>
</div>
</div>
</div>
<!-- Right: form -->
<div style="flex:1;display:flex;flex-direction:column;justify-content:center;padding:48px 56px;">
<div style="max-width:380px;">
<div style="font-family:var(--font-display);font-size:28px;font-weight:500;letter-spacing:-.02em;margin-bottom:6px;">Join the household</div>
<div style="font-size:14px;color:var(--color-text-muted);margin-bottom:28px;">Create your account to get started.</div>
<div class="fg"><label class="fl">Your name</label><input class="fi" placeholder="e.g. Tom"/></div>
<div class="fg"><label class="fl">Email</label><input class="fi" placeholder="you@example.com"/></div>
<div class="fg"><label class="fl">Password</label><input class="fi" type="password" placeholder="At least 8 characters"/></div>
<button class="bp">Join household</button>
<div style="margin-top:16px;font-size:12px;color:var(--color-text-muted);">Already have an account? <span style="color:var(--green);font-weight:500;">Log in instead</span></div>
</div>
</div>
</div>
</div>
</div>
<div class="agent">
<h4>A4 · Join household</h4>
<pre>/* Desktop: split layout. Left (400px, green-tint bg): household identity + permissions list.
* Right (flex:1, page bg): signup form max-width 380px.
* Left panel uses green-tint (welcoming) not green-dark (brand-first).
* Mobile: green-tint banner at top + form below.
* Transaction: user_account INSERT + household_member INSERT (role=member) + household_invite UPDATE → C1 */</pre>
<table class="at"><thead><tr><th>Element</th><th>Value</th><th>Notes</th></tr></thead><tbody>
<tr class="grp"><td colspan="3">Desktop</td></tr>
<tr><td>Identity panel</td><td>400px, green-tint bg, centered content</td><td>Logo 64px + name Fraunces 32px + inviter + permissions list</td></tr>
<tr><td>Form panel</td><td>flex:1, page bg, max-width 380px</td><td>Same signup fields as A1</td></tr>
</tbody></table>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════
LLM IMPLEMENTATION GUIDE
═══════════════════════════════════════════════════════════════ -->
<div class="llm">
<h2>Implementation Guide — J6 Household Setup</h2>
<p>This journey is completed once when the app is first used. The planner creates an account, names the household, defines pantry staples, and invites household members.</p>
<h3>Journey Flow</h3>
<ol>
<li><strong>A1 — Sign up:</strong> New user creates account with name, email, password. Writes <code>user_account</code> → redirects to A2.</li>
<li><strong>A2 — Household setup:</strong> Planner names household (e.g. "Smith family"), optionally generates invite link. Writes <code>household</code> + <code>household_member</code> (role=planner) → redirects to A3.</li>
<li><strong>A3 — Pantry staples:</strong> Toggle staple ingredients by category. Debounced 300ms save. Updates <code>ingredient.is_staple</code>. Same component as D3 in settings.</li>
<li><strong>A4 — Join household:</strong> Invited member opens link, sees household identity, creates account. Writes <code>user_account</code> + <code>household_member</code> (role=member) + updates <code>household_invite</code> → redirects to C1.</li>
</ol>
<h3>Roles</h3>
<table>
<tr><th>Role</th><th>Created at</th><th>Access</th></tr>
<tr><td><code>planner</code></td><td>A2 (automatic)</td><td>Full access to all 15 screens</td></tr>
<tr><td><code>member</code></td><td>A4 (on invite accept)</td><td>C1 read-only + D1 view/check/add</td></tr>
</table>
<h3>Layout Rules</h3>
<ul>
<li><strong>All screens are pre-auth</strong> — no sidebar, no tab bar, no navigation chrome.</li>
<li><strong>A1, A4 desktop:</strong> Full-viewport 2-column split. Brand/identity left (fixed width), form right (flex:1).</li>
<li><strong>A2, A3 desktop:</strong> Progress sidebar (300px) left + form/content right (flex:1).</li>
<li><strong>Mobile:</strong> All screens are stacked single-column. Brand/identity as a banner at top, form below.</li>
</ul>
<h3>Design Constraints</h3>
<ul>
<li>A1 brand panel: <code>--green-dark</code> bg (brand-first). A4 identity panel: <code>--green-tint</code> bg (welcoming).</li>
<li>A3 = D3 — single component, two contexts. Onboarding (progress sidebar + 2-col grid) vs settings (app sidebar + 3-col grid).</li>
<li>Chip toggle: selected = <code>--green-tint</code> bg + <code>--green-light</code> border + <code>--green-dark</code> text.</li>
<li>Progress steps: current = green circle, completed = green-tint + checkmark, future = subtle circle.</li>
<li>Invite mechanism: link or short code. No in-app email system. Planner shares via messaging app.</li>
<li>Form max-width: 380px (A1, A4) or 420px (A2). Never wider.</li>
</ul>
<h3>Data Operations</h3>
<table>
<tr><th>Screen</th><th>Writes</th><th>Reads</th></tr>
<tr><td>A1</td><td><code>user_account INSERT</code></td><td></td></tr>
<tr><td>A2</td><td><code>household INSERT</code>, <code>household_member INSERT (role=planner)</code>, <code>household_invite INSERT</code> (optional)</td><td></td></tr>
<tr><td>A3/D3</td><td><code>ingredient UPDATE (is_staple)</code> — debounced 300ms</td><td><code>ingredient SELECT</code> grouped by <code>ingredient_category</code></td></tr>
<tr><td>A4</td><td><code>user_account INSERT</code>, <code>household_member INSERT (role=member)</code>, <code>household_invite UPDATE</code></td><td><code>household_invite SELECT</code> (validates code), <code>household SELECT</code> (name, inviter)</td></tr>
</table>
<h3>Accessibility</h3>
<ul>
<li>All forms: semantic <code>&lt;form&gt;</code>, <code>&lt;label&gt;</code> with <code>for</code>, visible focus indicators.</li>
<li>Chip toggles (A3): use <code>role="checkbox"</code> or <code>&lt;input type="checkbox"&gt;</code> with visual styling.</li>
<li>Progress steps (A2, A3): use <code>aria-current="step"</code> on the active step.</li>
<li>Contrast: all text meets WCAG 2.2 AA (4.5:1 normal, 3:1 large).</li>
</ul>
<h3>Preconditions &amp; Dependencies</h3>
<ul>
<li>J6 is a <strong>precondition for all other journeys</strong> — user must have an account and household.</li>
<li>J6 is a precondition for J5 shared list — household members must be invited before the list is shared.</li>
<li>A3 configures staples that J5 (shopping list) uses for smart filtering.</li>
<li>No other screens are accessible to household members in v1 besides C1 (read-only) and D1.</li>
</ul>
</div>
</div>
</body>
</html>