Files
mealprep/specs/frontend/j2-plan-the-week.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

1086 lines
101 KiB
HTML
Raw 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>Recipe App — J2 Plan the Week · Journey Spec</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);--space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:20px;--space-6:24px;--space-8:32px;}
*,*::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 (screen-specs shared) */
.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;}
/* ── Planner-spec CSS: phone (p-*), tablet (t-*), desktop (d-*) ── */
/* Mobile planner */
.p-status{padding:10px 20px 0;display:flex;justify-content:space-between;align-items:center;background:var(--color-page);}
.p-time{font-size:12px;font-weight:600;color:var(--color-text);}
.p-icons{font-size:10px;color:var(--color-text);}
.p-nav{padding:8px 12px;border-bottom:1px solid var(--color-border);display:flex;justify-content:space-between;align-items:center;}
.p-nav-title{font-family:var(--font-display);font-size:16px;font-weight:500;letter-spacing:-.02em;}
.p-nav-acts{display:flex;gap:4px;}
.p-bi{width:24px;height:24px;border-radius:4px;border:1px solid var(--color-border);background:var(--color-surface);display:flex;align-items:center;justify-content:center;font-size:10px;color:var(--color-text-muted);}.p-bi.pr{background:var(--green);border-color:var(--green);color:#fff;}
.p-variety{margin:8px 12px 0;background:var(--yellow-tint);border:1px solid var(--yellow-light);border-radius:8px;padding:8px 10px;display:flex;align-items:center;gap:8px;}
.p-vnum{font-family:var(--font-display);font-size:20px;font-weight:300;color:var(--color-text);line-height:1;}
.p-vbody{flex:1;}
.p-veye{font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--yellow-text);}
.p-vmsg{font-size:9px;color:var(--color-text-muted);}
.p-vwarn{font-size:9px;color:var(--yellow-text);display:flex;align-items:center;gap:3px;}
.p-vdot{width:4px;height:4px;border-radius:50%;background:var(--yellow);flex-shrink:0;}
.p-bwrap{width:40px;}
.p-bt{height:3px;background:var(--yellow-light);border-radius:99px;overflow:hidden;}
.p-bf{height:100%;width:80%;background:var(--yellow);border-radius:99px;}
.p-wkhdr{padding:8px 12px 4px;display:flex;justify-content:space-between;align-items:center;}
.p-wkr{font-size:10px;font-weight:500;color:var(--color-text);}
.p-wknav{display:flex;gap:2px;}
.p-wkb{font-size:9px;padding:2px 5px;border-radius:3px;background:var(--color-subtle);border:1px solid var(--color-border);color:var(--color-text-muted);}
.p-strip{padding:0 12px 8px;display:grid;grid-template-columns:repeat(7,1fr);gap:2px;}
.p-chip{display:flex;flex-direction:column;align-items:center;gap:1px;padding:5px 1px;border-radius:4px;border:1px solid transparent;}
.p-chip.today{background:var(--yellow-tint);border-color:var(--yellow-light);}
.p-chip.sel{background:var(--green-tint);border-color:var(--green-light);}
.p-ca{font-size:7px;font-weight:500;letter-spacing:.05em;text-transform:uppercase;color:var(--color-text-muted);}
.p-chip.today .p-ca{color:var(--yellow-text);}
.p-chip.sel .p-ca{color:var(--green-dark);}
.p-cn{font-size:11px;font-weight:500;color:var(--color-text);line-height:1;}
.p-cd{width:3px;height:3px;border-radius:50%;background:var(--color-border);}
.p-chip.hm .p-cd{background:var(--green);}
.p-chip.today .p-cd{background:var(--yellow-text);}
.p-chip.sel .p-cd{background:var(--green-dark);}
.p-rule{height:1px;background:var(--color-border);margin:0 12px;}
.p-sel{padding:10px 12px;}
.p-selhdr{display:flex;justify-content:space-between;margin-bottom:8px;}
.p-sellbl{font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--color-text-muted);}
.p-seldate{font-size:9px;color:var(--color-text-muted);}
.p-mc{background:var(--color-surface);border:1px solid var(--color-border);border-radius:8px;padding:10px;box-shadow:var(--shadow-card);}
.p-mn{font-family:var(--font-display);font-size:15px;font-weight:400;letter-spacing:-.01em;color:var(--color-text);line-height:1.25;margin-bottom:6px;}
.p-mtags{display:flex;flex-wrap:wrap;gap:3px;margin-bottom:8px;}
.p-b{font-size:9px;font-weight:500;padding:2px 5px;border-radius:3px;}
.p-bg{background:var(--green-tint);color:var(--green-dark);}
.p-by{background:var(--yellow-tint);color:var(--yellow-text);}
.p-bmu{background:var(--color-subtle);color:var(--color-text-muted);}
.p-macts{display:flex;gap:5px;}
.p-mbtn{flex:1;font-size:9px;font-weight:500;padding:5px;border-radius:4px;border:none;text-align:center;}
.p-mbtn.pr{background:var(--green);color:#fff;}
.p-mbtn.gh{background:var(--color-subtle);color:var(--color-text-muted);border:1px solid var(--color-border);}
.p-uplbl{padding:6px 12px 4px;font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--color-text-muted);}
.p-mlist{padding:0 12px;}
.p-mrow{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid var(--color-subtle);}
.p-mrow:last-child{border-bottom:none;}
.p-rday{width:26px;flex-shrink:0;}
.p-ra{font-size:7px;font-weight:500;text-transform:uppercase;color:var(--color-text-muted);}
.p-rn{font-family:var(--font-display);font-size:13px;font-weight:300;color:var(--color-text);line-height:1;}
.p-rc{flex:1;min-width:0;}
.p-rname{font-family:var(--font-display);font-size:11px;font-weight:400;color:var(--color-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.p-rmeta{font-size:9px;color:var(--color-text-muted);}
.p-rswap{font-size:9px;padding:3px 6px;border-radius:3px;border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-text-muted);}
.p-tabs{border-top:1px solid var(--color-border);background:var(--color-surface);padding:6px 12px 16px;display:flex;justify-content:space-around;}
.p-tab{display:flex;flex-direction:column;align-items:center;gap:2px;}
.p-ti{width:18px;height:18px;border-radius:3px;background:var(--color-subtle);display:flex;align-items:center;justify-content:center;font-size:10px;}
.p-tab.act .p-ti{background:var(--green-tint);}
.p-tl{font-size:8px;font-weight:500;color:var(--color-text-muted);}
.p-tab.act .p-tl{color:var(--green-dark);}
/* Tablet planner */
.tablet{width:100%;max-width:640px;background:var(--color-page);border-radius:20px;overflow:hidden;box-shadow:var(--shadow-overlay),0 0 0 1px rgba(0,0,0,.06);display:flex;flex-direction:column;}
.t-nav{padding:14px 20px;border-bottom:1px solid var(--color-border);display:flex;justify-content:space-between;align-items:center;}
.t-ntitle{font-family:var(--font-display);font-size:18px;font-weight:500;letter-spacing:-.02em;}
.t-nr{display:flex;gap:6px;align-items:center;}
.t-bi{width:30px;height:30px;border-radius:5px;border:1px solid var(--color-border);background:var(--color-surface);display:flex;align-items:center;justify-content:center;font-size:12px;color:var(--color-text-muted);}
.t-add{font-family:var(--font-sans);font-size:12px;font-weight:500;padding:7px 14px;border-radius:5px;background:var(--green);color:#fff;border:none;}
.t-var{margin:14px 20px 0;background:var(--yellow-tint);border:1px solid var(--yellow-light);border-radius:var(--radius-lg);padding:12px 16px;display:flex;align-items:center;gap:14px;}
.t-vn{font-family:var(--font-display);font-size:28px;font-weight:300;color:var(--color-text);line-height:1;}
.t-vd{font-size:12px;color:var(--color-text-muted);}
.t-vb{flex:1;}
.t-ve{font-size:9px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--yellow-text);}
.t-vm{font-size:11px;color:var(--color-text-muted);margin-top:1px;}
.t-vw{font-size:11px;color:var(--yellow-text);margin-top:2px;display:flex;align-items:center;gap:4px;}
.t-wd{width:5px;height:5px;border-radius:50%;background:var(--yellow);flex-shrink:0;}
.t-bc{min-width:80px;}
.t-bl{font-size:10px;color:var(--color-text-muted);text-align:right;margin-bottom:4px;}
.t-bt{height:4px;background:var(--yellow-light);border-radius:99px;overflow:hidden;}
.t-bf{height:100%;width:80%;background:var(--yellow);border-radius:99px;}
.t-wkhdr{padding:14px 20px 8px;display:flex;justify-content:space-between;align-items:center;}
.t-wkr{font-size:13px;font-weight:500;color:var(--color-text);}
.t-wknav{display:flex;gap:6px;align-items:center;}
.t-wkb{font-size:11px;padding:4px 10px;border-radius:4px;background:var(--color-subtle);border:1px solid var(--color-border);color:var(--color-text-muted);}
.t-tdc{font-size:10px;font-weight:500;padding:3px 8px;border-radius:4px;background:var(--color-subtle);color:var(--color-text-muted);border:1px solid var(--color-border);}
.t-strip{padding:0 20px 12px;display:grid;grid-template-columns:repeat(7,1fr);gap:5px;}
.t-chip{display:flex;flex-direction:column;align-items:center;gap:2px;padding:8px 4px;border-radius:7px;border:1px solid transparent;}
.t-chip.today{background:var(--yellow-tint);border-color:var(--yellow-light);}
.t-chip.sel{background:var(--green-tint);border-color:var(--green-light);}
.t-ca{font-size:9px;font-weight:500;letter-spacing:.06em;text-transform:uppercase;color:var(--color-text-muted);}
.t-chip.today .t-ca{color:var(--yellow-text);}
.t-chip.sel .t-ca{color:var(--green-dark);}
.t-cn{font-size:14px;font-weight:500;color:var(--color-text);}
.t-cd{width:4px;height:4px;border-radius:50%;background:var(--color-border);}
.t-chip.hm .t-cd{background:var(--green);}
.t-chip.today .t-cd{background:var(--yellow-text);}
.t-chip.sel .t-cd{background:var(--green-dark);}
.t-rule{height:1px;background:var(--color-border);margin:0 20px;}
.t-sel{padding:14px 20px;}
.t-shdr{display:flex;justify-content:space-between;margin-bottom:10px;}
.t-slbl{font-size:9px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--color-text-muted);}
.t-sdate{font-size:11px;color:var(--color-text-muted);}
.t-mc{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:14px 16px;box-shadow:var(--shadow-card);display:flex;gap:16px;align-items:flex-start;}
.t-ml{flex:1;}
.t-mr{display:flex;flex-direction:column;gap:6px;min-width:120px;}
.t-mn{font-family:var(--font-display);font-size:18px;font-weight:400;letter-spacing:-.02em;color:var(--color-text);line-height:1.3;margin-bottom:8px;}
.t-mtags{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:8px;}
.t-mdesc{font-size:11px;color:var(--color-text-muted);line-height:1.5;}
.t-btn{font-family:var(--font-sans);font-size:12px;font-weight:500;padding:7px 12px;border-radius:5px;border:none;text-align:center;width:100%;}
.t-bpr{background:var(--green);color:#fff;}
.t-bol{background:transparent;color:var(--green);border:1px solid var(--green);}
.t-bgh{background:var(--color-subtle);color:var(--color-text-muted);border:1px solid var(--color-border);}
.t-uplbl{padding:12px 20px 8px;font-size:9px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--color-text-muted);}
.t-grid{padding:0 20px 16px;display:grid;grid-template-columns:1fr 1fr;gap:8px;}
.t-rcard{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:10px 12px;box-shadow:var(--shadow-card);display:flex;align-items:center;gap:10px;}
.t-rday{width:30px;flex-shrink:0;text-align:center;}
.t-ra{font-size:8px;font-weight:500;text-transform:uppercase;letter-spacing:.06em;color:var(--color-text-muted);}
.t-rn{font-family:var(--font-display);font-size:15px;font-weight:300;color:var(--color-text);line-height:1;}
.t-rdiv{width:1px;height:28px;background:var(--color-border);flex-shrink:0;}
.t-rc{flex:1;min-width:0;}
.t-rname{font-family:var(--font-display);font-size:12px;font-weight:400;color:var(--color-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.t-rmeta{font-size:10px;color:var(--color-text-muted);margin-top:1px;}
.t-rarrow{font-size:12px;color:var(--color-border);flex-shrink:0;}
.t-empty{border-style:dashed;background:transparent;box-shadow:none;}
.t-navb{border-top:1px solid var(--color-border);background:var(--color-surface);padding:10px 20px 14px;display:flex;justify-content:center;gap:6px;}
.t-ni{display:flex;align-items:center;gap:6px;padding:7px 14px;border-radius:5px;font-size:12px;font-weight:500;color:var(--color-text-muted);}
.t-ni.act{background:var(--green-tint);color:var(--green-dark);}
/* Desktop planner */
.d-sb{width:196px;flex-shrink:0;background:var(--color-surface);border-right:1px solid var(--color-border);display:flex;flex-direction:column;height:100%;overflow-y:auto;}
.d-logo{padding:18px 14px 14px;border-bottom:1px solid var(--color-border);}
.d-lmark{display:flex;align-items:center;gap:6px;margin-bottom:2px;}
.d-licon{width:22px;height:22px;border-radius:4px;background:var(--green);display:flex;align-items:center;justify-content:center;font-size:11px;}
.d-lname{font-family:var(--font-display);font-size:15px;font-weight:500;letter-spacing:-.02em;}
.d-lsub{font-size:10px;color:var(--color-text-muted);padding-left:28px;}
.d-nav{padding:10px 8px;flex:1;}
.d-nsec{margin-bottom:14px;}
.d-nlbl{font-size:8px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--color-text-muted);padding:0 6px;margin-bottom:4px;}
.d-ni{display:flex;align-items:center;gap:6px;padding:6px 6px;border-radius:5px;font-size:12px;color:var(--color-text-muted);margin-bottom:1px;}
.d-ni.act{background:var(--green-tint);color:var(--green-dark);font-weight:500;}
.d-nic{font-size:12px;width:16px;text-align:center;}
.d-nbadge{margin-left:auto;font-size:9px;font-weight:500;background:var(--yellow);color:var(--color-text);padding:1px 5px;border-radius:3px;}
.d-var{margin:0 8px 14px;padding:10px 12px;background:var(--yellow-tint);border:1px solid var(--yellow-light);border-radius:var(--radius-lg);}
.dv-e{font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--yellow-text);margin-bottom:4px;}
.dv-sr{display:flex;align-items:baseline;gap:3px;margin-bottom:4px;}
.dv-n{font-family:var(--font-display);font-size:30px;font-weight:300;letter-spacing:-.02em;color:var(--color-text);line-height:1;}
.dv-d{font-size:12px;color:var(--color-text-muted);}
.dv-bt{height:4px;background:var(--yellow-light);border-radius:99px;overflow:hidden;margin-bottom:6px;}
.dv-bf{height:100%;width:80%;background:var(--yellow);border-radius:99px;}
.dv-m{font-size:10px;color:var(--color-text-muted);line-height:1.45;margin-bottom:4px;}
.dv-w{font-size:10px;color:var(--yellow-text);display:flex;align-items:flex-start;gap:4px;line-height:1.35;}
.dv-wd{width:4px;height:4px;border-radius:50%;background:var(--yellow);flex-shrink:0;margin-top:3px;}
.dv-cta{margin-top:8px;width:100%;font-family:var(--font-sans);font-size:10px;font-weight:500;padding:5px;border-radius:4px;background:var(--color-page);border:1px solid var(--yellow-light);color:var(--yellow-text);}
.d-main{flex:1;display:flex;flex-direction:column;min-width:0;}
.d-tb{padding:10px 16px;border-bottom:1px solid var(--color-border);display:flex;justify-content:space-between;align-items:center;flex-shrink:0;}
.d-tbl{display:flex;align-items:center;gap:14px;}
.d-ttitle{font-family:var(--font-display);font-size:16px;font-weight:500;letter-spacing:-.02em;}
.d-wn{display:flex;align-items:center;gap:5px;}
.d-wb{font-size:11px;padding:4px 8px;border-radius:4px;background:var(--color-subtle);border:1px solid var(--color-border);color:var(--color-text-muted);font-family:var(--font-sans);}
.d-wr{font-size:12px;font-weight:500;color:var(--color-text);min-width:130px;text-align:center;}
.d-tbr{display:flex;align-items:center;gap:6px;}
.d-tdb{font-size:11px;font-weight:500;padding:4px 10px;border-radius:4px;border:1px solid var(--color-border);background:var(--color-surface);color:var(--color-text-muted);font-family:var(--font-sans);}
.d-ab{font-family:var(--font-sans);font-size:12px;font-weight:500;padding:5px 12px;border-radius:4px;background:var(--green);color:#fff;border:none;}
.d-content{flex:1;display:flex;overflow:hidden;}
.d-cal{flex:1;overflow-y:auto;padding:12px;}
.d-cg{display:grid;grid-template-columns:repeat(7,1fr);gap:7px;min-height:430px;}
.d-cc{display:flex;flex-direction:column;}
.d-ch{text-align:center;padding-bottom:7px;margin-bottom:7px;border-bottom:2px solid var(--color-border);}
.d-ch.th{border-bottom-color:var(--yellow);}
.d-ch.sh{border-bottom-color:var(--green);}
.d-dn{font-size:9px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--color-text-muted);margin-bottom:3px;}
.d-db{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;font-size:12px;font-weight:500;color:var(--color-text);}
.d-ch.th .d-db{background:var(--yellow);}
.d-ch.sh .d-db{background:var(--green-tint);color:var(--green-dark);}
.d-tile{flex:1;background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:7px 7px 9px;cursor:pointer;box-shadow:var(--shadow-card);display:flex;flex-direction:column;gap:3px;}
.d-tile.tt{border-color:var(--yellow);border-width:2px;background:var(--yellow-tint);}
.d-tile.st{border-color:var(--green);border-width:2px;background:var(--green-tint);}
.d-te{font-size:8px;font-weight:500;letter-spacing:.06em;text-transform:uppercase;color:var(--color-text-muted);}
.d-tile.tt .d-te{color:var(--yellow-text);}
.d-tile.st .d-te{color:var(--green-dark);}
.d-tn{font-family:var(--font-display);font-size:11px;font-weight:400;letter-spacing:-.01em;color:var(--color-text);line-height:1.3;}
.d-ttags{display:flex;flex-wrap:wrap;gap:2px;}
.d-tm{font-size:9px;color:var(--color-text-muted);margin-top:1px;}
.d-et{flex:1;border:1px dashed var(--color-border);border-radius:var(--radius-lg);display:flex;align-items:center;justify-content:center;min-height:60px;flex-direction:column;gap:3px;}
.d-ep{font-size:16px;color:var(--color-border);}
.d-el{font-size:9px;color:var(--color-border);}
.d-dp{width:216px;flex-shrink:0;background:var(--color-surface);border-left:1px solid var(--color-border);display:flex;flex-direction:column;overflow-y:auto;}
.d-dph{padding:12px 14px 10px;border-bottom:1px solid var(--color-border);}
.d-dpd{font-family:var(--font-display);font-size:16px;font-weight:500;letter-spacing:-.02em;}
.d-dpdt{font-size:10px;color:var(--color-text-muted);margin-top:1px;}
.d-dpm{padding:12px 14px;border-bottom:1px solid var(--color-border);}
.d-dpmn{font-family:var(--font-display);font-size:14px;font-weight:400;letter-spacing:-.01em;line-height:1.3;margin-bottom:6px;}
.d-dptags{display:flex;flex-wrap:wrap;gap:3px;margin-bottom:10px;}
.d-dpacts{display:flex;flex-direction:column;gap:5px;}
.d-dpb{font-family:var(--font-sans);font-size:11px;font-weight:500;padding:6px;border-radius:4px;border:none;text-align:center;}
.d-dpbpr{background:var(--green);color:#fff;}
.d-dpbol{background:transparent;color:var(--green);border:1px solid var(--green);}
.d-dpbgh{background:var(--color-subtle);color:var(--color-text-muted);border:1px solid var(--color-border);}
.d-ing{padding:12px 14px;}
.d-ingl{font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--color-text-muted);margin-bottom:8px;}
.d-ir{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--color-subtle);font-size:11px;}
.d-ir:last-child{border-bottom:none;}
.d-iq{font-size:10px;color:var(--color-text-muted);}
.d-ir.rep{color:var(--yellow-text);}
.d-ir.rep .d-iq{color:var(--yellow-text);}
/* Planner-spec annotation cards */
.ann{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:20px 24px;margin-bottom:12px;}
.ann h3{font-size:13px;font-weight:500;color:var(--color-text);margin-bottom:8px;}
.ann p{font-size:13px;color:var(--color-text-muted);line-height:1.65;}
.ann p+p{margin-top:8px;}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px;}
.grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;margin-top:20px;}
.note{background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:16px 20px;}
.note h4{font-size:11px;font-weight:500;letter-spacing:.06em;text-transform:uppercase;color:var(--color-text-muted);margin-bottom:8px;}
.note p{font-size:13px;color:var(--color-text-muted);line-height:1.6;}
.note.hl{border-color:var(--green-light);background:var(--green-tint);}
.note.hl h4{color:var(--green-dark);}
.note.hl p{color:var(--green-deeper);}
.note.warn{border-color:var(--yellow-light);background:var(--yellow-tint);}
.note.warn h4{color:var(--yellow-text);}
.note.warn p{color:var(--yellow-text);}
/* Planner-spec badge overrides */
.bsm{font-size:10px;padding:2px 6px;border-radius:3px;}
.by{background:var(--yellow-tint);color:var(--yellow-text);}
.bw{background:rgba(242,193,46,.25);color:var(--yellow-text);}
.bm{background:var(--color-subtle);color:var(--color-text-muted);border:1px solid var(--color-border);}
/* Planner-spec agent section overrides */
.agent h2{font-size:10px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:#6B6A63;margin-bottom:6px;}
.agent > p{font-size:13px;color:#9A9990;margin-bottom:28px;line-height:1.6;}
.spec-cmt{font-family:var(--font-mono);font-size:11px;color:#444440;margin-bottom:28px;line-height:1.8;white-space:pre-wrap;}
/* Planner-spec desk override for fixed height */
.desk-c1{height:640px;}
/* LLM section */
.llm{background:var(--color-text);color:#E8E8E2;padding:36px 44px;border-radius:var(--radius-lg);margin-top:80px;}
.llm h2{font-size:10px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:#6B6A63;margin-bottom:16px;}
.llm h3{font-size:12px;font-weight:500;color:#9A9990;margin:24px 0 8px;letter-spacing:.04em;text-transform:uppercase;}
.llm p,.llm li{font-size:12px;color:#9A9990;line-height:1.7;}
.llm ul{margin-left:16px;margin-bottom:8px;}
.llm strong{color:#E8E8E2;}
@media(max-width:900px){.doc{padding:24px 16px 80px;}}
</style>
</head>
<body>
<div class="doc">
<div class="doc-header">
<div>
<h1>J2 — Plan the Week</h1>
<p>Journey spec · Screens C1, C2, C3 · All breakpoints</p>
</div>
<div class="doc-meta">
Journey: J2<br>
Screens: C1 · C2 · C3<br>
Status: approved<br>
Version: 1.0<br>
Updated: 2026-04
</div>
</div>
<!-- ═══ JOURNEY HEADER ═══ -->
<div class="jh jh-y">
<div class="jn">J2</div>
<div><h2>Plan the week</h2><p>Fill day slots, get variety-aware suggestions, review score. C1 is the app home screen.</p><div class="fl">C1 → C2 → C1 → C3 → C1 · Variety score always visible</div></div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════ -->
<!-- SCREEN C1 — WEEKLY PLANNER (full planner-spec content) -->
<!-- ═══════════════════════════════════════════════════════════════════ -->
<div class="scr" id="c1">
<div class="scr-head"><h3>Weekly planner</h3><span class="scr-id">C1</span></div>
<div class="scr-desc">App home screen with all 3 breakpoints. Mobile: day strip + selected card + remaining list. Tablet: same stack, wider, 2-col remaining grid, inline nav pills. Desktop: 3-panel (sidebar 224px + 7-col calendar grid + detail panel 280px). Variety score always visible on all breakpoints.</div>
<div class="scr-var"><strong>V1 mobile · V2 tablet · V3 desktop</strong> — three fundamentally different layouts, not a scaled-up mobile</div>
<!-- Purpose -->
<div class="section">
<div class="section-title">Purpose &amp; design rationale</div>
<div class="grid2">
<div class="ann">
<h3>What this screen does</h3>
<p>The weekly planner is the app home screen. It lets the planner see all seven dinner slots for the current week at a glance, select any day to view the full meal, and access swap and cook actions without leaving the screen. For household members (read-only role) all edit and swap actions are hidden — the rest of the layout is identical.</p>
</div>
<div class="ann">
<h3>The variety problem is always visible</h3>
<p>The core pain point this app solves is meal repetition across the week. The variety score is therefore always on screen on all three breakpoints — it never hides in a tab, modal, or collapsed region. Ingredient repeat warnings appear inline at the tile level on desktop and in the detail panel across all breakpoints.</p>
</div>
</div>
</div>
<!-- ── MOBILE ── -->
<div class="section">
<div class="section-title">Breakpoint 1 — Mobile · &lt; 768px</div>
<div style="display:flex;gap:40px;align-items:flex-start;margin-bottom:32px;">
<div class="phone">
<div class="p-status"><span class="p-time">9:41</span><span class="p-icons">●●● WiFi 🔋</span></div>
<div class="p-nav">
<div class="p-nav-title">This week</div>
<div class="p-nav-acts">
<div class="p-bi"></div><div class="p-bi"></div><div class="p-bi pr">+</div>
</div>
</div>
<div class="p-variety">
<div><span class="p-vnum">8</span></div>
<div class="p-vbody">
<div class="p-veye">Variety score</div>
<div class="p-vmsg">Good variety this week</div>
<div class="p-vwarn"><div class="p-vdot"></div>Chicken in 2 meals</div>
</div>
<div class="p-bwrap"><div class="p-bt"><div class="p-bf"></div></div></div>
</div>
<div class="p-wkhdr">
<span class="p-wkr">31 Mar 6 Apr</span>
<div class="p-wknav"><span class="p-wkb"></span><span class="p-wkb"></span></div>
</div>
<div class="p-strip">
<div class="p-chip hm"><span class="p-ca">Mo</span><span class="p-cn">31</span><div class="p-cd"></div></div>
<div class="p-chip today"><span class="p-ca">Tu</span><span class="p-cn">1</span><div class="p-cd"></div></div>
<div class="p-chip sel hm"><span class="p-ca">We</span><span class="p-cn">2</span><div class="p-cd"></div></div>
<div class="p-chip hm"><span class="p-ca">Th</span><span class="p-cn">3</span><div class="p-cd"></div></div>
<div class="p-chip hm"><span class="p-ca">Fr</span><span class="p-cn">4</span><div class="p-cd"></div></div>
<div class="p-chip"><span class="p-ca">Sa</span><span class="p-cn">5</span><div class="p-cd"></div></div>
<div class="p-chip hm"><span class="p-ca">Su</span><span class="p-cn">6</span><div class="p-cd"></div></div>
</div>
<div class="p-rule"></div>
<div class="p-sel">
<div class="p-selhdr"><span class="p-sellbl">Wed · dinner</span><span class="p-seldate">2 Apr</span></div>
<div class="p-mc">
<div class="p-mn">Slow-roasted tomato pasta</div>
<div class="p-mtags">
<span class="p-b p-bg">45 min</span>
<span class="p-b p-by">Easy</span>
<span class="p-b p-bg">Child-friendly</span>
</div>
<div class="p-macts">
<div class="p-mbtn pr">Cook now</div>
<div class="p-mbtn gh">Swap</div>
</div>
</div>
</div>
<div class="p-uplbl">Rest of the week</div>
<div class="p-mlist">
<div class="p-mrow">
<div class="p-rday"><div class="p-ra">Thu</div><div class="p-rn">3</div></div>
<div class="p-rc"><div class="p-rname">Chicken stir-fry</div><div class="p-rmeta">25 min · Easy</div></div>
<div class="p-rswap">Swap</div>
</div>
<div class="p-mrow">
<div class="p-rday"><div class="p-ra">Fri</div><div class="p-rn">4</div></div>
<div class="p-rc"><div class="p-rname">Chicken curry</div><div class="p-rmeta">40 min · Child-friendly</div></div>
<div class="p-rswap">Swap</div>
</div>
<div class="p-mrow">
<div class="p-rday"><div class="p-ra">Sun</div><div class="p-rn">6</div></div>
<div class="p-rc"><div class="p-rname">Lentil soup</div><div class="p-rmeta">45 min · Vegetarian</div></div>
<div class="p-rswap">Swap</div>
</div>
</div>
<div class="p-tabs">
<div class="p-tab act"><div class="p-ti">📅</div><span class="p-tl">Planner</span></div>
<div class="p-tab"><div class="p-ti">📖</div><span class="p-tl">Recipes</span></div>
<div class="p-tab"><div class="p-ti">🛒</div><span class="p-tl">Shopping</span></div>
<div class="p-tab"><div class="p-ti">⚙️</div><span class="p-tl">Settings</span></div>
</div>
</div>
<div style="flex:1;display:flex;flex-direction:column;gap:12px;">
<div class="note hl">
<h4>Layout pattern</h4>
<p>Five stacked fixed-height regions: top nav → variety banner → week strip → selected day card → scrollable remaining list. The tab bar is position: fixed at the bottom. Only the remaining days list scrolls.</p>
</div>
<div class="note">
<h4>Day strip</h4>
<p>7-column grid, each chip 8px top+bottom padding. A 4px dot below the date is the only meal indicator: grey = no meal, green = meal planned, yellow-text = today, green-dark = selected. Today chip: yellow-tint bg + yellow-light border. Selected: green-tint + green-light. Tapping any chip updates the selected day panel immediately below.</p>
</div>
<div class="note">
<h4>Selected day card</h4>
<p>Meal name in Fraunces 20px weight 400. Tags row (time, effort, attributes) then two equal-width action buttons. shadow-card elevation. When today is selected: 2px yellow border + yellow-tint background — the only 2px border in the system.</p>
</div>
<div class="note warn">
<h4>Variety banner</h4>
<p>Always the first element below the nav. Never collapses. Score in Fraunces 28px weight 300. Warning row (yellow-text colour, yellow dot) appears when any ingredient appears in 2+ meals this week.</p>
</div>
<div class="note">
<h4>Remaining days list</h4>
<p>Shows only days after the selected day. Date column: 36px wide. Meal name: Fraunces 14px. Meta: 11px muted DM Sans. Swap button: right-aligned 11px. Rows separated by 1px color-subtle dividers. Empty days are not shown — their absence is visible only via the dot in the strip.</p>
</div>
</div>
</div>
</div>
<!-- ── TABLET ── -->
<div class="section">
<div class="section-title">Breakpoint 2 — Tablet · 768px 1024px</div>
<div class="ann" style="margin-bottom:20px;">
<h3>Relationship to mobile</h3>
<p>The tablet uses the same five-region stack and the same interaction model as mobile. Key differences: the selected meal card expands to a two-column layout (info left, action buttons right); the remaining days list becomes a 2-column card grid; the variety banner gains a labelled progress bar; and the bottom navigation becomes an inline horizontal pill bar rather than a fixed screen overlay. A "Today" shortcut chip appears between the prev/next week buttons.</p>
</div>
<div style="overflow-x:auto;margin-bottom:24px;">
<div class="tablet">
<div class="t-nav">
<div class="t-ntitle">This week</div>
<div class="t-nr"><div class="t-bi"></div><div class="t-bi"></div><button class="t-add">+ Add meal</button></div>
</div>
<div class="t-var">
<div><span class="t-vn">8</span><span class="t-vd">/10</span></div>
<div class="t-vb">
<div class="t-ve">Variety score</div>
<div class="t-vm">Good variety — no ingredient repeats more than twice</div>
<div class="t-vw"><div class="t-wd"></div>Chicken in 2 meals — consider swapping Friday</div>
</div>
<div class="t-bc"><div class="t-bl">80%</div><div class="t-bt"><div class="t-bf"></div></div></div>
</div>
<div class="t-wkhdr">
<span class="t-wkr">31 Mar 6 Apr 2026</span>
<div class="t-wknav"><span class="t-wkb"> Prev</span><span class="t-tdc">Today</span><span class="t-wkb">Next </span></div>
</div>
<div class="t-strip">
<div class="t-chip hm"><span class="t-ca">Mon</span><span class="t-cn">31</span><div class="t-cd"></div></div>
<div class="t-chip today"><span class="t-ca">Tue</span><span class="t-cn">1</span><div class="t-cd"></div></div>
<div class="t-chip sel hm"><span class="t-ca">Wed</span><span class="t-cn">2</span><div class="t-cd"></div></div>
<div class="t-chip hm"><span class="t-ca">Thu</span><span class="t-cn">3</span><div class="t-cd"></div></div>
<div class="t-chip hm"><span class="t-ca">Fri</span><span class="t-cn">4</span><div class="t-cd"></div></div>
<div class="t-chip"><span class="t-ca">Sat</span><span class="t-cn">5</span><div class="t-cd"></div></div>
<div class="t-chip hm"><span class="t-ca">Sun</span><span class="t-cn">6</span><div class="t-cd"></div></div>
</div>
<div class="t-rule"></div>
<div class="t-sel">
<div class="t-shdr"><span class="t-slbl">Wednesday · dinner</span><span class="t-sdate">2 April 2026</span></div>
<div class="t-mc">
<div class="t-ml">
<div class="t-mn">Slow-roasted tomato pasta</div>
<div class="t-mtags">
<span class="badge bg bsm">45 min</span>
<span class="badge by bsm">Easy</span>
<span class="badge bg bsm">Child-friendly</span>
<span class="badge bg bsm">Vegetarian</span>
</div>
<div class="t-mdesc">Roasting the tomatoes concentrates their sweetness — great for the kids and easy to batch.</div>
</div>
<div class="t-mr">
<button class="t-btn t-bpr">Cook now</button>
<button class="t-btn t-bol">View recipe</button>
<button class="t-btn t-bgh">Swap meal</button>
</div>
</div>
</div>
<div class="t-uplbl">Rest of the week</div>
<div class="t-grid">
<div class="t-rcard"><div class="t-rday"><div class="t-ra">Thu</div><div class="t-rn">3</div></div><div class="t-rdiv"></div><div class="t-rc"><div class="t-rname">Chicken stir-fry</div><div class="t-rmeta">25 min · Easy</div></div><div class="t-rarrow"></div></div>
<div class="t-rcard"><div class="t-rday"><div class="t-ra">Fri</div><div class="t-rn">4</div></div><div class="t-rdiv"></div><div class="t-rc"><div class="t-rname">Chicken curry</div><div class="t-rmeta">40 min · Child-friendly</div></div><div class="t-rarrow"></div></div>
<div class="t-rcard t-empty"><div class="t-rday"><div class="t-ra">Sat</div><div class="t-rn">5</div></div><div class="t-rdiv"></div><div class="t-rc" style="color:var(--color-text-muted);font-size:12px;">No meal planned</div><div style="font-size:16px;color:var(--color-border);">+</div></div>
<div class="t-rcard"><div class="t-rday"><div class="t-ra">Sun</div><div class="t-rn">6</div></div><div class="t-rdiv"></div><div class="t-rc"><div class="t-rname">Lentil soup</div><div class="t-rmeta">45 min · Vegetarian</div></div><div class="t-rarrow"></div></div>
</div>
<div class="t-navb">
<div class="t-ni act">📅 Planner</div>
<div class="t-ni">📖 Recipes</div>
<div class="t-ni">🛒 Shopping</div>
<div class="t-ni">⚙️ Settings</div>
</div>
</div>
</div>
<div class="grid3">
<div class="note hl"><h4>Selected meal card</h4><p>Two-column layout: meal info (name 22px, tags, description) on the left, three stacked full-width action buttons on the right (min-width 120px). Description line is tablet and desktop only.</p></div>
<div class="note"><h4>Remaining days grid</h4><p>2-column CSS grid with 8px gap. Each card: date column (30px) + 1px vertical divider + meal name + meta + right arrow. Empty slots: dashed border, transparent bg, + icon right-aligned.</p></div>
<div class="note"><h4>Navigation</h4><p>Bottom nav becomes inline (not fixed), rendered as horizontal labelled pill items. Active item: green-tint bg + green-dark text. A "Today" shortcut chip sits between the prev/next week buttons.</p></div>
</div>
</div>
<!-- ── DESKTOP ── -->
<div class="section">
<div class="section-title">Breakpoint 3 — Desktop · &gt; 1024px</div>
<div class="ann" style="margin-bottom:20px;">
<h3>Layout model change — not a scaled-up mobile</h3>
<p>Desktop is a fundamentally different layout. The screen switches from a vertical single-column stack to a three-panel horizontal model: left sidebar (224px, fixed height, sticky), main calendar area (flex 1, only panel that scrolls), and right detail panel (280px, fixed). The day strip is replaced entirely by a 7-column calendar grid. The bottom tab bar is replaced by a persistent left sidebar nav. This is a deliberate layout change — not responsive scaling.</p>
</div>
<div style="overflow-x:auto;margin-bottom:24px;">
<div class="desk desk-c1">
<div class="d-sb">
<div class="d-logo">
<div class="d-lmark"><div class="d-licon">🥗</div><div class="d-lname">Mealplan</div></div>
<div class="d-lsub">Smith household</div>
</div>
<nav class="d-nav">
<div class="d-nsec">
<div class="d-nlbl">Plan</div>
<div class="d-ni act"><span class="d-nic">📅</span> Planner</div>
<div class="d-ni"><span class="d-nic">📖</span> Recipes</div>
<div class="d-ni"><span class="d-nic">🛒</span> Shopping <span class="d-nbadge">New</span></div>
</div>
<div class="d-nsec">
<div class="d-nlbl">Household</div>
<div class="d-ni"><span class="d-nic">👨‍👩‍👧‍👦</span> Members</div>
<div class="d-ni"><span class="d-nic">⚙️</span> Settings</div>
</div>
</nav>
<div class="d-var">
<div class="dv-e">Variety score</div>
<div class="dv-sr"><span class="dv-n">8</span><span class="dv-d">/10</span></div>
<div class="dv-bt"><div class="dv-bf"></div></div>
<div class="dv-m">Good variety. No ingredient repeats more than twice.</div>
<div class="dv-w"><div class="dv-wd"></div>Chicken on Thu + Fri — consider swapping</div>
<button class="dv-cta">Review variety →</button>
</div>
</div>
<div class="d-main">
<div class="d-tb">
<div class="d-tbl">
<div class="d-ttitle">Weekly planner</div>
<div class="d-wn"><button class="d-wb"> Prev</button><span class="d-wr">31 Mar 6 Apr 2026</span><button class="d-wb">Next </button></div>
</div>
<div class="d-tbr"><button class="d-tdb">Today</button><button class="d-ab">+ Add meal</button></div>
</div>
<div class="d-content">
<div class="d-cal">
<div class="d-cg">
<div class="d-cc"><div class="d-ch"><div class="d-dn">Monday</div><div class="d-db">31</div></div><div class="d-tile"><div class="d-te">Dinner</div><div class="d-tn">Pasta al forno</div><div class="d-ttags"><span class="badge bg bsm">30 min</span></div><div class="d-tm">Easy · Child-friendly</div></div></div>
<div class="d-cc"><div class="d-ch th"><div class="d-dn">Tuesday</div><div class="d-db">1</div></div><div class="d-tile tt"><div class="d-te">Today · dinner</div><div class="d-tn">Grilled salmon</div><div class="d-ttags"><span class="badge bg bsm">25 min</span></div><div class="d-tm">Easy</div></div></div>
<div class="d-cc"><div class="d-ch sh"><div class="d-dn">Wednesday</div><div class="d-db">2</div></div><div class="d-tile st"><div class="d-te">Dinner · selected</div><div class="d-tn">Slow-roasted tomato pasta</div><div class="d-ttags"><span class="badge by bsm">Easy</span></div><div class="d-tm">45 min · Vegetarian</div></div></div>
<div class="d-cc"><div class="d-ch"><div class="d-dn">Thursday</div><div class="d-db">3</div></div><div class="d-tile"><div class="d-te">Dinner</div><div class="d-tn">Chicken stir-fry</div><div class="d-ttags"><span class="badge bw bsm">⚠ Chicken</span></div><div class="d-tm">25 min</div></div></div>
<div class="d-cc"><div class="d-ch"><div class="d-dn">Friday</div><div class="d-db">4</div></div><div class="d-tile"><div class="d-te">Dinner</div><div class="d-tn">Chicken curry</div><div class="d-ttags"><span class="badge bw bsm">⚠ Chicken</span></div><div class="d-tm">40 min</div></div></div>
<div class="d-cc"><div class="d-ch"><div class="d-dn">Saturday</div><div class="d-db">5</div></div><div class="d-et"><div class="d-ep">+</div><div class="d-el">Add meal</div></div></div>
<div class="d-cc"><div class="d-ch"><div class="d-dn">Sunday</div><div class="d-db">6</div></div><div class="d-tile"><div class="d-te">Dinner</div><div class="d-tn">Lentil soup</div><div class="d-ttags"><span class="badge bg bsm">Vegetarian</span></div><div class="d-tm">45 min</div></div></div>
</div>
</div>
<div class="d-dp">
<div class="d-dph"><div class="d-dpd">Wednesday</div><div class="d-dpdt">2 April 2026 · dinner</div></div>
<div class="d-dpm">
<div class="d-dpmn">Slow-roasted tomato pasta</div>
<div class="d-dptags">
<span class="badge bg bsm">45 min</span>
<span class="badge by bsm">Easy</span>
<span class="badge bg bsm">Vegetarian</span>
<span class="badge bg bsm">Child-friendly</span>
</div>
<div class="d-dpacts">
<button class="d-dpb d-dpbpr">View recipe</button>
<button class="d-dpb d-dpbol">Cook mode</button>
<button class="d-dpb d-dpbgh">Swap meal</button>
</div>
</div>
<div class="d-ing">
<div class="d-ingl">Ingredients · serves 4</div>
<div class="d-ir"><span>Cherry tomatoes</span><span class="d-iq">500 g</span></div>
<div class="d-ir"><span>Rigatoni</span><span class="d-iq">320 g</span></div>
<div class="d-ir"><span>Garlic cloves</span><span class="d-iq">4, sliced</span></div>
<div class="d-ir rep"><span>Olive oil ↻ Mon+Wed</span><span class="d-iq">4 tbsp</span></div>
<div class="d-ir"><span>Fresh basil</span><span class="d-iq">1 handful</span></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="grid3">
<div class="note hl"><h4>Three-panel structure</h4><p>Sidebar 224px fixed + calendar flex 1 scrollable + detail panel 280px fixed. Sidebar and detail panel never scroll. Only the calendar area scrolls vertically. All three are 100% viewport height.</p></div>
<div class="note"><h4>Calendar tiles</h4><p>Each tile uses flex: 1 to fill its column. Column header has a 2px bottom border — yellow for today, green for selected. Tiles with repeated ingredients show a badge-warn chip (rgba(242,193,46,.25) bg). Empty slots: dashed border, centred + icon.</p></div>
<div class="note warn"><h4>Variety — always visible</h4><p>Bottom of the sidebar. Never scrolls out of view. Includes score, bar, message, ingredient-specific warning, and a "Review variety" button linking to screen C3.</p></div>
</div>
</div>
<!-- C1 Agent Table -->
<div class="agent" style="padding:36px 44px;">
<h2>Machine-readable spec — C1 Weekly Planner</h2>
<p style="font-size:13px;color:#9A9990;margin-bottom:28px;line-height:1.6;">All values are real production sizes. Previews above are scaled for visual presentation only — never measure from them. Use tokens from color-palette-spec v1.0, typography-spec v1.0, and spacing-shape-spec v1.0.</p>
<pre class="spec-cmt">/* C1 Implementation rules
* 1. Default route on first load. App home screen.
* 2. Variety score ALWAYS VISIBLE on all breakpoints. Never hidden or in a tab/modal.
* 3. Today chip: background yellow-tint (#FDF6D8), border 1px yellow-light (#F9E08A).
* 4. Selected chip: background green-tint (#E8F5EA), border 1px green-light (#AEDCB0).
* 5. Today meal card (mobile/tablet): 2px solid yellow (#F2C12E) border + yellow-tint bg.
* Today tile (desktop): same 2px yellow border. This is the ONLY 2px border in the system.
* 6. Meal names: always --font-display (Fraunces). All UI chrome: --font-sans (DM Sans).
* 7. Chip dot: --color-border = no meal. --green = meal. --yellow-text = today. --green-dark = selected.
* 8. Desktop: sidebar position sticky, height 100vh. Detail panel also sticky. Only cal-area scrolls.
* 9. Ingredient repeat warnings: badge-warn (rgba(242,193,46,.25) bg + --yellow-text color) on tiles.
* In detail panel: repeat rows use --yellow-text for name AND quantity text.
* 10. Household member role: hide swap buttons, hide "+ Add meal" button. Show read-only badge.
* 11. Empty day slot mobile: not shown in the remaining days list (only shown via dot in strip).
* Empty day slot tablet/desktop: dashed 1px --color-border, transparent bg, centred + (18px --color-border).
* 12. Meal description text (13px DM Sans muted, line-height 1.5): tablet + desktop only. Hidden on mobile.
*/</pre>
<table class="at" style="font-size:12px;">
<thead>
<tr><th>Region / element</th><th>Real production value</th><th>Notes</th><th>Breakpoints</th></tr>
</thead>
<tbody>
<tr class="grp"><td colspan="4">Layout &amp; breakpoints</td></tr>
<tr><td>Mobile breakpoint</td><td>&lt; 768px</td><td>Single-column vertical stack, fixed bottom tab bar, body full-width</td><td>mobile</td></tr>
<tr><td>Tablet breakpoint</td><td>768px 1024px</td><td>Same stack structure, wider panels, inline bottom nav. No fixed tab bar.</td><td>tablet</td></tr>
<tr><td>Desktop breakpoint</td><td>&gt; 1024px</td><td>3-panel horizontal: sidebar + calendar + detail panel</td><td>desktop</td></tr>
<tr><td>Desktop sidebar width</td><td>224px fixed</td><td>position: sticky; height: 100vh. Contains logo, nav, variety score.</td><td>desktop</td></tr>
<tr><td>Desktop detail panel width</td><td>280px fixed</td><td>position: sticky; height: 100vh. Hidden on mobile and tablet.</td><td>desktop</td></tr>
<tr><td>Desktop calendar gap</td><td>gap: 8px between columns (--space-2)</td><td>grid-template-columns: repeat(7, 1fr)</td><td>desktop</td></tr>
<tr><td>Desktop calendar padding</td><td>20px all sides (--space-5)</td><td>Inside the scrollable cal-area div</td><td>desktop</td></tr>
<tr><td>Mobile page gutter</td><td>16px each side (--space-4)</td><td>Applied to all content regions individually, not a wrapper</td><td>mobile</td></tr>
<tr><td>Tablet page gutter</td><td>20px24px each side (--space-5 / --space-6)</td><td>Variety banner and selected card: 20px. Week header and strip: 20px.</td><td>tablet</td></tr>
<tr><td>Tablet remaining grid gap</td><td>8px (--space-2)</td><td>2-column CSS grid</td><td>tablet</td></tr>
<tr class="grp"><td colspan="4">Navigation</td></tr>
<tr><td>Mobile top nav padding</td><td>10px 16px (--space-2 --space-4)</td><td>position: sticky; top: 0; z-index: 10; border-bottom: --border-default</td><td>mobile</td></tr>
<tr><td>Mobile top nav title</td><td>Fraunces 20px weight 500, letter-spacing -0.02em</td><td>"This week" — updates to week range on scroll if implemented</td><td>mobile</td></tr>
<tr><td>Tablet top nav padding</td><td>14px 20px (--space-3 --space-5)</td><td>Title: Fraunces 24px weight 500. Right side adds "+ Add meal" button.</td><td>tablet</td></tr>
<tr><td>Desktop topbar padding</td><td>10px 24px (--space-2 --space-6)</td><td>Title: Fraunces 20px weight 500. Week nav inline left. Today + Add meal right.</td><td>desktop</td></tr>
<tr><td>Desktop sidebar nav item</td><td>padding: 7px 6px; font-size: 13px; border-radius: --radius-md (6px)</td><td>Active: green-tint bg + green-dark text + weight 500. Icon 16px, 20px wide.</td><td>desktop</td></tr>
<tr><td>Mobile tab bar</td><td>position: fixed; bottom: 0; padding-bottom: 20px (safe area)</td><td>4 items. Active icon: green-tint bg. Active label: green-dark color. Label: 10px DM Sans weight 500.</td><td>mobile</td></tr>
<tr><td>Tablet nav bar</td><td>position: static; inline at bottom; padding: 10px 20px 14px</td><td>Horizontal labelled pills. Active: green-tint bg + green-dark text.</td><td>tablet</td></tr>
<tr><td>Nav prev/next buttons</td><td>DM Sans 1112px, padding: 45px 810px, radius-sm (4px), color-subtle bg, border-default</td><td>Mobile: icon-only (⟨ ⟩) 32x32px. Tablet/desktop: text " Prev" / "Next ".</td><td>all</td></tr>
<tr><td>"Today" shortcut chip</td><td>DM Sans 1011px weight 500, color-subtle bg, border-default, radius-sm</td><td>Between prev/next buttons. Tablet and desktop only.</td><td>tablet, desktop</td></tr>
<tr><td>"+ Add meal" button</td><td>DM Sans 1213px weight 500, green bg (#3D8C4A), white text, radius-md (6px), padding 78px 1418px</td><td>Planner role only. Hidden for household members.</td><td>tablet, desktop</td></tr>
<tr class="grp"><td colspan="4">Variety score</td></tr>
<tr><td>Component background</td><td>yellow-tint (#FDF6D8) bg, 1px yellow-light (#F9E08A) border, radius-lg (10px)</td><td>Identical on all breakpoints</td><td>all</td></tr>
<tr><td>Mobile position</td><td>margin: 16px 16px 0 (top + sides). First content after nav.</td><td>padding: 8px 16px (--space-2 --space-4). Never collapses.</td><td>mobile</td></tr>
<tr><td>Tablet position</td><td>margin: 14px 20px 0. padding: 12px 16px.</td><td>Same structure, slightly larger</td><td>tablet</td></tr>
<tr><td>Desktop position</td><td>Bottom of sidebar. margin: 0 8px 14px. padding: 10px 12px.</td><td>Always visible. Never scrolled by any panel.</td><td>desktop</td></tr>
<tr><td>Score number</td><td>Fraunces 28px mobile / 28px tablet / 40px desktop, weight 300, letter-spacing -0.02em, line-height 1</td><td>Followed inline by denominator "/10" in DM Sans 1216px muted</td><td>all</td></tr>
<tr><td>Eyebrow label</td><td>DM Sans 810px, weight 500, letter-spacing 0.080.1em, uppercase, --yellow-text (#8A6800)</td><td>Always first text inside the component</td><td>all</td></tr>
<tr><td>Status message</td><td>DM Sans 911px, --color-text-muted</td><td>E.g. "Good variety this week"</td><td>all</td></tr>
<tr><td>Warning row</td><td>DM Sans 911px, --yellow-text, flex row, 45px yellow dot (border-radius 50%)</td><td>Only shown when any ingredient appears in 2 or more meals</td><td>all</td></tr>
<tr><td>Progress bar</td><td>height: 35px, track: yellow-light, fill: yellow, radius: 99px</td><td>Width = variety score as percentage (score 8 = 80%)</td><td>all</td></tr>
<tr><td>"Review variety" button</td><td>DM Sans 10px weight 500, color-page bg, yellow-light border, yellow-text color, radius-sm, padding 5px</td><td>Desktop sidebar only. Links to screen C3 (variety review).</td><td>desktop</td></tr>
<tr class="grp"><td colspan="4">Day strip (mobile + tablet)</td></tr>
<tr><td>Strip grid</td><td>grid-template-columns: repeat(7, 1fr); gap: 23px mobile / 56px tablet</td><td>padding: 0 16px 812px</td><td>mobile, tablet</td></tr>
<tr><td>Chip padding</td><td>58px top+bottom / 14px left+right</td><td>border-radius: --radius-md (6px) mobile / --radius-lg (10px) tablet</td><td>mobile, tablet</td></tr>
<tr><td>Chip abbreviation</td><td>DM Sans 79px, weight 500, tracking 0.050.06em, uppercase, --color-text-muted</td><td>2 letters on mobile (Mo Tu), 3 letters on tablet (Mon Tue)</td><td>mobile, tablet</td></tr>
<tr><td>Chip date number</td><td>DM Sans 1114px, weight 500, --color-text, line-height 11.1</td><td></td><td>mobile, tablet</td></tr>
<tr><td>Chip dot</td><td>34px diameter circle, border-radius: 50%</td><td>No meal: --color-border. Has meal: --green (#3D8C4A). Today: --yellow-text (#8A6800). Selected: --green-dark (#2E6E39).</td><td>mobile, tablet</td></tr>
<tr><td>Today chip</td><td>background: --yellow-tint (#FDF6D8); border: 1px solid --yellow-light (#F9E08A)</td><td>Abbreviation colour: --yellow-text. Dot colour: --yellow-text.</td><td>mobile, tablet</td></tr>
<tr><td>Selected chip</td><td>background: --green-tint (#E8F5EA); border: 1px solid --green-light (#AEDCB0)</td><td>Abbreviation colour: --green-dark. Dot colour: --green-dark.</td><td>mobile, tablet</td></tr>
<tr class="grp"><td colspan="4">Calendar grid (desktop only)</td></tr>
<tr><td>Column header day name</td><td>DM Sans 910px, weight 500, tracking 0.08em, uppercase, --color-text-muted</td><td>margin-bottom: 3px</td><td>desktop</td></tr>
<tr><td>Column header date badge</td><td>24x24px, border-radius: 4px (--radius-sm), DM Sans 1214px weight 500, --color-text</td><td>Today col: yellow (#F2C12E) bg. Selected col: green-tint bg + green-dark text. Default: no bg.</td><td>desktop</td></tr>
<tr><td>Column header bottom border</td><td>2px solid</td><td>Default: --color-border. Today column: --yellow (#F2C12E). Selected column: --green (#3D8C4A).</td><td>desktop</td></tr>
<tr><td>Tile padding</td><td>8px 8px 10px (top / sides / bottom)</td><td>border-radius: --radius-lg (10px). flex: 1 to fill column height.</td><td>desktop</td></tr>
<tr><td>Tile eyebrow</td><td>DM Sans 89px, weight 500, tracking 0.060.08em, uppercase</td><td>Default: --color-text-muted. Today tile: --yellow-text. Selected tile: --green-dark.</td><td>desktop</td></tr>
<tr><td>Tile meal name</td><td>Fraunces 1113px, weight 400, letter-spacing -0.01em, line-height 1.3</td><td>No text truncation — tile height grows to fit</td><td>desktop</td></tr>
<tr><td>Tile at rest</td><td>background: --color-surface; border: 1px --color-border; box-shadow: --shadow-card</td><td>Hover: border-color --green-light; box-shadow: --shadow-raised</td><td>desktop</td></tr>
<tr><td>Today tile</td><td>border: 2px solid --yellow (#F2C12E); background: --yellow-tint (#FDF6D8)</td><td>ONLY 2px border in the system</td><td>desktop</td></tr>
<tr><td>Selected tile</td><td>border: 2px solid --green (#3D8C4A); background: --green-tint (#E8F5EA)</td><td>Also 2px — matches today tile treatment</td><td>desktop</td></tr>
<tr><td>Ingredient repeat badge</td><td>background: rgba(242,193,46,0.25); color: --yellow-text (#8A6800); DM Sans 10px weight 500; padding: 2px 6px; border-radius: 3px</td><td>Replaces or supplements normal tags. Shows "⚠ [ingredient]".</td><td>desktop</td></tr>
<tr><td>Empty day tile</td><td>border: 1px dashed --color-border; background: transparent; box-shadow: none; min-height: 60px</td><td>Centred content: + icon (1618px --color-border) + "Add meal" label (910px --color-border)</td><td>desktop</td></tr>
<tr class="grp"><td colspan="4">Selected day / detail panel</td></tr>
<tr><td>Mobile: selected area padding</td><td>16px all sides (--space-4)</td><td>Section above rule: eyebrow label left, date right</td><td>mobile</td></tr>
<tr><td>Mobile: meal card padding</td><td>1016px all sides</td><td>background: --color-surface; border: 1px --color-border; radius: --radius-lg (10px); box-shadow: --shadow-card</td><td>mobile</td></tr>
<tr><td>Meal name — mobile</td><td>Fraunces 20px, weight 400, letter-spacing -0.02em, line-height 1.25, margin-bottom: 8px</td><td>--color-text</td><td>mobile</td></tr>
<tr><td>Meal name — tablet</td><td>Fraunces 22px, weight 400, same other values</td><td>--color-text</td><td>tablet</td></tr>
<tr><td>Meal name — desktop detail panel</td><td>Fraunces 17px, weight 400, line-height 1.3, margin-bottom: 6px</td><td>Smaller because panel is narrower (280px)</td><td>desktop</td></tr>
<tr><td>Meal description</td><td>DM Sans 13px, --color-text-muted, line-height 1.5</td><td>Tablet + desktop only. Hidden on mobile.</td><td>tablet, desktop</td></tr>
<tr><td>Actions — mobile</td><td>2 buttons, flex row, equal width, DM Sans 12px weight 500, padding: 8px 12px, radius-md</td><td>"Cook now" (green primary) + "Swap meal" (ghost)</td><td>mobile</td></tr>
<tr><td>Actions — tablet</td><td>3 buttons, stacked column in right half of card (min-width 120px), DM Sans 12px, padding: 7px 12px</td><td>"Cook now" (primary) + "View recipe" (outline) + "Swap meal" (ghost)</td><td>tablet</td></tr>
<tr><td>Actions — desktop</td><td>3 buttons, stacked column, full panel width (280px minus padding), DM Sans 11px, padding: 6px</td><td>"View recipe" (primary) + "Cook mode" (outline) + "Swap meal" (ghost)</td><td>desktop</td></tr>
<tr><td>Desktop ingredient rows</td><td>padding: 4px 0 per row; border-bottom: 1px --color-subtle; DM Sans 11px name + 10px muted qty</td><td>Repeat ingredient rows: both name and qty use --yellow-text (#8A6800)</td><td>desktop</td></tr>
<tr class="grp"><td colspan="4">Remaining days list / grid</td></tr>
<tr><td>Mobile list item padding</td><td>612px top + bottom (--space-2 / --space-3)</td><td>Separated by 1px --color-subtle bottom border. No left/right border.</td><td>mobile</td></tr>
<tr><td>Date column — mobile list</td><td>width: 2636px, flex-shrink: 0</td><td>Abbreviation: 79px DM Sans uppercase muted. Number: Fraunces 1317px weight 300.</td><td>mobile</td></tr>
<tr><td>Row meal name — mobile</td><td>Fraunces 1114px, weight 400, letter-spacing -0.01em, --color-text</td><td>white-space: nowrap; overflow: hidden; text-overflow: ellipsis</td><td>mobile</td></tr>
<tr><td>Row metadata — mobile</td><td>DM Sans 911px, --color-text-muted</td><td>Format: "{time} · {attribute}" e.g. "25 min · Easy"</td><td>mobile</td></tr>
<tr><td>Swap button</td><td>DM Sans 911px, padding: 34px 68px, radius-sm (4px), border-default, color-surface bg</td><td>Right-aligned. Planner role only — hidden for household members.</td><td>mobile, tablet</td></tr>
<tr><td>Tablet grid</td><td>grid-template-columns: 1fr 1fr; gap: 8px (--space-2); padding: 0 20px 16px</td><td>Each card: radius-lg, shadow-card, flex row. Date col (30px) + 1px vertical divider + content + arrow.</td><td>tablet</td></tr>
<tr><td>Empty slot — tablet grid</td><td>border: 1px dashed --color-border; background: transparent; box-shadow: none</td><td>Right side: + icon (16px --color-border). Left: date col + divider as normal.</td><td>tablet</td></tr>
<tr><td>Empty slot — mobile</td><td>Not shown in the remaining list</td><td>Absence is communicated via grey dot in the day strip only.</td><td>mobile</td></tr>
</tbody>
</table>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════ -->
<!-- SCREEN C2 — MEAL SUGGESTIONS -->
<!-- ═══════════════════════════════════════════════════════════════════ -->
<div class="scr" id="c2">
<div class="scr-head"><h3>Meal suggestions</h3><span class="scr-id">C2</span></div>
<div class="scr-desc">Mobile: V1 ranked list with context banner + reasoning per suggestion. Desktop: V4 sidebar + topbar + split content (week context left panel, ranked suggestions right). The week context panel shows what's already planned and why certain recipes are filtered.</div>
<div class="scr-var"><strong>V1 ranked list (mobile) · V4 split context (desktop)</strong></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="padding:10px 16px;border-bottom:1px solid var(--color-border);display:flex;justify-content:space-between;align-items:center;">
<div style="font-size:13px;color:var(--green);font-weight:500;">← Planner</div>
<div style="font-family:var(--font-display);font-size:16px;font-weight:500;">Suggestions</div>
<div style="width:50px;"></div>
</div>
<div style="padding:10px 12px;">
<div style="background:var(--green-tint);border:1px solid var(--green-light);border-radius:var(--radius-lg);padding:10px 12px;margin-bottom:12px;">
<div class="eye" style="color:var(--green-dark);margin-bottom:2px;">Suggesting for Wednesday, 2 Apr</div>
<div style="font-size:11px;color:var(--green-dark);">Avoiding: chicken (Mon), tomato (Tue). Balancing effort.</div>
</div>
<div class="sg"><div class="sg-r">1</div><div class="sg-b"><div class="sg-n">Salmon teriyaki with rice</div><div class="sg-i">35 min · Medium · Fish</div><div class="sg-w">✓ No fish this week · different protein</div></div><div class="sg-p">Pick →</div></div>
<div class="sg"><div class="sg-r">2</div><div class="sg-b"><div class="sg-n">Mushroom risotto</div><div class="sg-i">50 min · Medium · Vegetarian</div><div class="sg-w">✓ No veggie since last week</div></div><div class="sg-p">Pick →</div></div>
<div class="sg"><div class="sg-r">3</div><div class="sg-b"><div class="sg-n">Thai green curry</div><div class="sg-i">40 min · Medium · Chicken</div><div class="sg-w" style="background:var(--yellow-tint);color:var(--yellow-text);">⚠ Chicken again — 2 days apart</div></div><div class="sg-p">Pick →</div></div>
<div class="sg"><div class="sg-r">4</div><div class="sg-b"><div class="sg-n">Beef bourguignon</div><div class="sg-i">2h 30m · Hard · Beef</div><div class="sg-w">✓ Never cooked — try something new!</div></div><div class="sg-p">Pick →</div></div>
<div style="text-align:center;margin-top:12px;"><span style="font-size:12px;color:var(--green);font-weight:500;cursor:pointer;">Browse full library →</span></div>
</div>
</div>
</div>
</div>
<div class="prev-col">
<div class="bp-lbl">Desktop · 1040px</div>
<div class="desk">
<div class="dsb">
<div class="dsb-logo"><div class="dsb-lm"><div class="dsb-ic">🥗</div><div class="dsb-nm">Mealplan</div></div><div class="dsb-sub">Smith household</div></div>
<div class="dsb-nav"><div><div class="dsb-nl">Plan</div><div class="dsb-ni a"><span class="dsb-nc">📅</span>Planner</div><div class="dsb-ni"><span class="dsb-nc">📖</span>Recipes</div><div class="dsb-ni"><span class="dsb-nc">🛒</span>Shopping</div></div></div>
<!-- Variety score widget at bottom of sidebar -->
<div style="margin:auto 10px 14px;padding:10px 12px;background:var(--yellow-tint);border:1px solid var(--yellow-light);border-radius:var(--radius-lg);">
<div style="font-size:8px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;color:var(--yellow-text);margin-bottom:3px;">Variety score</div>
<div style="display:flex;align-items:baseline;gap:3px;"><span style="font-family:var(--font-display);font-size:28px;font-weight:300;line-height:1;">8</span><span style="font-size:11px;color:var(--color-text-muted);">/10</span></div>
</div>
</div>
<div class="dm">
<div class="dtb"><div class="dtb-t">Suggestions for Wednesday, 2 Apr</div><div style="font-size:13px;color:var(--green);font-weight:500;cursor:pointer;">← Back to planner</div></div>
<div style="flex:1;display:flex;overflow:hidden;">
<!-- Left: week context -->
<div style="width:280px;flex-shrink:0;padding:20px;border-right:1px solid var(--color-border);background:var(--color-surface);overflow-y:auto;">
<div class="eye" style="margin-bottom:10px;">This week so far</div>
<div style="margin-bottom:8px;padding:10px;background:var(--color-page);border:1px solid var(--color-border);border-radius:var(--radius-md);">
<div style="font-size:12px;font-weight:500;">Mon — Chicken stir-fry</div><div style="font-size:10px;color:var(--color-text-muted);">Chicken · Easy · 25 min</div>
</div>
<div style="margin-bottom:8px;padding:10px;background:var(--color-page);border:1px solid var(--color-border);border-radius:var(--radius-md);">
<div style="font-size:12px;font-weight:500;">Tue — Tomato pasta</div><div style="font-size:10px;color:var(--color-text-muted);">Veggie · Easy · 45 min</div>
</div>
<div style="margin-bottom:8px;padding:10px;background:var(--yellow-tint);border:1px solid var(--yellow-light);border-radius:var(--radius-md);">
<div style="font-size:12px;font-weight:500;color:var(--yellow-text);">Wed — ?</div><div style="font-size:10px;color:var(--yellow-text);">Picking now</div>
</div>
<div style="padding:10px;border:1px dashed var(--color-border);border-radius:var(--radius-md);">
<div style="font-size:12px;color:var(--color-text-muted);">ThuSun — empty</div>
</div>
<div class="eye" style="margin:20px 0 8px;">Filter reasons</div>
<div style="font-size:11px;color:var(--color-text-muted);line-height:1.6;">
<div style="margin-bottom:4px;">• Avoiding chicken (Mon)</div>
<div style="margin-bottom:4px;">• Avoiding tomato-heavy (Tue)</div>
<div>• Preferring medium effort (2 easy in a row)</div>
</div>
</div>
<!-- Right: suggestions -->
<div style="flex:1;padding:20px;overflow-y:auto;">
<div class="sg"><div class="sg-r">1</div><div class="sg-b"><div class="sg-n">Salmon teriyaki with rice</div><div class="sg-i">35 min · Medium · Fish</div><div class="sg-w">✓ Fresh protein · effort balance</div></div><div class="sg-p">Pick →</div></div>
<div class="sg"><div class="sg-r">2</div><div class="sg-b"><div class="sg-n">Mushroom risotto</div><div class="sg-i">50 min · Medium · Vegetarian</div><div class="sg-w">✓ No veggie for 10 days</div></div><div class="sg-p">Pick →</div></div>
<div class="sg"><div class="sg-r">3</div><div class="sg-b"><div class="sg-n">Beef bourguignon</div><div class="sg-i">2h 30m · Hard · Beef</div><div class="sg-w">✓ Never cooked — try it!</div></div><div class="sg-p">Pick →</div></div>
<div class="sg"><div class="sg-r">4</div><div class="sg-b"><div class="sg-n">Thai green curry</div><div class="sg-i">40 min · Medium · Chicken</div><div class="sg-w" style="background:var(--yellow-tint);color:var(--yellow-text);">⚠ Chicken 2 days apart</div></div><div class="sg-p">Pick →</div></div>
<div style="text-align:center;margin-top:16px;"><span style="font-size:13px;color:var(--green);font-weight:500;cursor:pointer;">Browse full library instead →</span></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="agent">
<h4>C2 · Meal suggestions</h4>
<pre>/* Desktop: 224px sidebar (variety score at bottom) + topbar + split content:
* Left panel (280px, surface bg): week-so-far mini cards + filter reason bullets
* Right panel (flex:1, page bg): ranked suggestion cards with Pick action
* The context panel is a page section, not a floating card.
* Mobile: context banner (green-tint, collapsible) + ranked list below.
* Pick → writes week_plan_slot → returns to C1.
* "Browse full library" → B1 in selection mode. */</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>Context panel</td><td>280px, surface bg, border-right</td><td>Week meals + current slot (yellow) + filter reasons</td></tr>
<tr><td>Suggestions</td><td>flex:1, page bg, 20px padding</td><td>Same sg-card component as mobile but wider</td></tr>
<tr class="grp"><td colspan="3">Mobile</td></tr>
<tr><td>Context banner</td><td>green-tint, radius-lg, 10px 12px pad</td><td>Day label + filter summary. Collapsed on mobile.</td></tr>
</tbody></table>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════ -->
<!-- SCREEN C3 — VARIETY REVIEW -->
<!-- ═══════════════════════════════════════════════════════════════════ -->
<div class="scr" id="c3">
<div class="scr-head"><h3>Variety review</h3><span class="scr-id">C3</span></div>
<div class="scr-desc">V1 Score breakdown. Desktop: sidebar + topbar + content with score hero area and sub-scores on the left, a 7-day protein distribution visual on the right, and warnings spanning the full width below.</div>
<div class="scr-var"><strong>V1 · Score breakdown</strong> — big score → sub-scores → protein grid → warnings</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="padding:10px 16px;border-bottom:1px solid var(--color-border);display:flex;justify-content:space-between;align-items:center;">
<div style="font-size:13px;color:var(--green);font-weight:500;">← Planner</div>
<div style="font-family:var(--font-display);font-size:16px;font-weight:500;">Variety review</div>
<div style="width:50px;"></div>
</div>
<div style="padding:16px;">
<div style="text-align:center;margin-bottom:20px;">
<div style="font-family:var(--font-display);font-size:56px;font-weight:300;line-height:1;">8</div>
<div style="font-size:12px;color:var(--color-text-muted);">out of 10 · Good variety</div>
<div style="width:120px;height:6px;background:var(--yellow-light);border-radius:3px;margin:10px auto;overflow:hidden;"><div style="width:80%;height:100%;background:var(--yellow);border-radius:3px;"></div></div>
</div>
<div class="eye" style="margin-bottom:8px;">Score breakdown</div>
<div style="background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-lg);padding:4px 0;margin-bottom:12px;">
<div style="display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-subtle);"><span style="font-size:12px;flex:1;">Protein diversity</span><span style="font-size:12px;font-weight:500;color:var(--green-dark);">9/10</span></div>
<div style="display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-subtle);"><span style="font-size:12px;flex:1;">Ingredient overlap</span><span style="font-size:12px;font-weight:500;color:var(--yellow-text);">7/10</span></div>
<div style="display:flex;align-items:center;padding:8px 12px;"><span style="font-size:12px;flex:1;">Effort balance</span><span style="font-size:12px;font-weight:500;color:var(--green-dark);">8/10</span></div>
</div>
<div class="eye" style="color:var(--yellow-text);margin-bottom:8px;">Warnings</div>
<div style="background:var(--yellow-tint);border:1px solid var(--yellow-light);border-radius:var(--radius-lg);padding:10px 12px;">
<div style="font-size:12px;color:var(--yellow-text);font-weight:500;margin-bottom:2px;">Chicken appears twice</div>
<div style="font-size:11px;color:var(--yellow-text);opacity:.8;">Monday and Thursday — 3 days apart is acceptable but reduces your score.</div>
</div>
</div>
</div>
</div>
</div>
<div class="prev-col">
<div class="bp-lbl">Desktop · 1040px</div>
<div class="desk" style="min-height:500px;">
<div class="dsb">
<div class="dsb-logo"><div class="dsb-lm"><div class="dsb-ic">🥗</div><div class="dsb-nm">Mealplan</div></div><div class="dsb-sub">Smith household</div></div>
<div class="dsb-nav"><div><div class="dsb-nl">Plan</div><div class="dsb-ni a"><span class="dsb-nc">📅</span>Planner</div><div class="dsb-ni"><span class="dsb-nc">📖</span>Recipes</div><div class="dsb-ni"><span class="dsb-nc">🛒</span>Shopping</div></div></div>
</div>
<div class="dm">
<div class="dtb"><div style="display:flex;align-items:center;gap:8px;"><span style="font-size:13px;color:var(--color-text-muted);">← Planner</span><span style="color:var(--color-border);">/</span><span class="dtb-t">Variety review</span></div></div>
<div style="flex:1;padding:28px 32px;overflow-y:auto;">
<!-- Two-column: score + protein grid -->
<div style="display:flex;gap:32px;margin-bottom:28px;">
<!-- Left: score + sub-scores -->
<div style="flex:1;">
<div style="display:flex;align-items:baseline;gap:8px;margin-bottom:16px;">
<div style="font-family:var(--font-display);font-size:72px;font-weight:300;line-height:1;">8</div>
<div><div style="font-size:14px;color:var(--color-text-muted);">out of 10</div><div style="font-size:13px;color:var(--color-text);">Good variety this week</div></div>
</div>
<div style="width:200px;height:6px;background:var(--yellow-light);border-radius:3px;margin-bottom:20px;overflow:hidden;"><div style="width:80%;height:100%;background:var(--yellow);border-radius:3px;"></div></div>
<div class="eye" style="margin-bottom:10px;">Score breakdown</div>
<div style="display:flex;flex-direction:column;gap:8px;">
<div style="display:flex;align-items:center;padding:10px 14px;border:1px solid var(--color-border);border-radius:var(--radius-md);"><span style="font-size:13px;flex:1;">Protein diversity</span><span style="font-size:13px;font-weight:500;color:var(--green-dark);">9/10</span></div>
<div style="display:flex;align-items:center;padding:10px 14px;border:1px solid var(--color-border);border-radius:var(--radius-md);"><span style="font-size:13px;flex:1;">Ingredient overlap</span><span style="font-size:13px;font-weight:500;color:var(--yellow-text);">7/10</span></div>
<div style="display:flex;align-items:center;padding:10px 14px;border:1px solid var(--color-border);border-radius:var(--radius-md);"><span style="font-size:13px;flex:1;">Effort balance</span><span style="font-size:13px;font-weight:500;color:var(--green-dark);">8/10</span></div>
</div>
</div>
<!-- Right: 7-day protein visual -->
<div style="width:320px;flex-shrink:0;">
<div class="eye" style="margin-bottom:10px;">Protein spread</div>
<div style="display:grid;grid-template-columns:repeat(7,1fr);gap:6px;">
<div style="text-align:center;"><div style="font-size:9px;color:var(--color-text-muted);margin-bottom:4px;">Mon</div><div style="height:44px;border-radius:var(--radius-md);background:var(--yellow-tint);border:1px solid var(--yellow-light);display:flex;align-items:center;justify-content:center;font-size:14px;">🍗</div></div>
<div style="text-align:center;"><div style="font-size:9px;color:var(--color-text-muted);margin-bottom:4px;">Tue</div><div style="height:44px;border-radius:var(--radius-md);background:var(--green-tint);border:1px solid var(--green-light);display:flex;align-items:center;justify-content:center;font-size:14px;">🥬</div></div>
<div style="text-align:center;"><div style="font-size:9px;color:var(--color-text-muted);margin-bottom:4px;">Wed</div><div style="height:44px;border-radius:var(--radius-md);background:var(--blue-tint);border:1px solid var(--blue-light);display:flex;align-items:center;justify-content:center;font-size:14px;">🐟</div></div>
<div style="text-align:center;"><div style="font-size:9px;color:var(--yellow-text);font-weight:500;margin-bottom:4px;">Thu</div><div style="height:44px;border-radius:var(--radius-md);background:var(--yellow-tint);border:2px solid var(--yellow);display:flex;align-items:center;justify-content:center;font-size:14px;">🍗</div></div>
<div style="text-align:center;"><div style="font-size:9px;color:var(--color-text-muted);margin-bottom:4px;">Fri</div><div style="height:44px;border-radius:var(--radius-md);background:#FDEAEA;border:1px solid #F4ACA4;display:flex;align-items:center;justify-content:center;font-size:14px;">🥩</div></div>
<div style="text-align:center;"><div style="font-size:9px;color:var(--color-text-muted);margin-bottom:4px;">Sat</div><div style="height:44px;border-radius:var(--radius-md);border:1px dashed var(--color-border);display:flex;align-items:center;justify-content:center;font-size:12px;color:var(--color-border);"></div></div>
<div style="text-align:center;"><div style="font-size:9px;color:var(--color-text-muted);margin-bottom:4px;">Sun</div><div style="height:44px;border-radius:var(--radius-md);background:var(--green-tint);border:1px solid var(--green-light);display:flex;align-items:center;justify-content:center;font-size:14px;">🍝</div></div>
</div>
<div class="eye" style="margin:16px 0 8px;">Effort balance</div>
<div style="display:flex;gap:4px;">
<div style="flex:3;background:var(--green-tint);border-radius:var(--radius-sm);padding:8px;text-align:center;font-size:11px;font-weight:500;color:var(--green-dark);">Easy ×3</div>
<div style="flex:3;background:var(--yellow-tint);border-radius:var(--radius-sm);padding:8px;text-align:center;font-size:11px;font-weight:500;color:var(--yellow-text);">Medium ×3</div>
<div style="flex:1;background:#FDEAEA;border-radius:var(--radius-sm);padding:8px;text-align:center;font-size:11px;font-weight:500;color:#B03020;">Hard ×1</div>
</div>
</div>
</div>
<!-- Warnings: full width -->
<div class="eye" style="color:var(--yellow-text);margin-bottom:8px;">Warnings</div>
<div style="background:var(--yellow-tint);border:1px solid var(--yellow-light);border-radius:var(--radius-lg);padding:14px 18px;margin-bottom:10px;">
<div style="font-size:13px;color:var(--yellow-text);font-weight:500;margin-bottom:3px;">Chicken appears twice</div>
<div style="font-size:12px;color:var(--yellow-text);opacity:.8;">Monday (stir-fry) and Thursday (curry) — 3 days apart is acceptable but reduces your score. Swap Thursday to improve to 9.</div>
</div>
<div style="background:var(--yellow-tint);border:1px solid var(--yellow-light);border-radius:var(--radius-lg);padding:14px 18px;">
<div style="font-size:13px;color:var(--yellow-text);font-weight:500;margin-bottom:3px;">Garlic in 5 of 7 meals</div>
<div style="font-size:12px;color:var(--yellow-text);opacity:.8;">Consider a garlic-free recipe for variety. This has minor impact on score.</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="agent">
<h4>C3 · Variety review</h4>
<pre>/* Desktop: sidebar + topbar (breadcrumb ← Planner / Variety review) + content:
* Top area: 2-col flex. Left: big score (72px) + progress bar + sub-score rows. Right: 7-day protein grid + effort bar.
* Bottom area: full-width warning cards.
* Content sits directly on page bg — no wrapper card.
* Mobile: stacked. Score → sub-scores → warnings. No protein grid (too small).
* Score is COMPUTED (variety CTE from data model), never stored. */</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>Score area</td><td>flex:1. Score: Fraunces 72px/300. Bar: 200px wide, 6px, yellow.</td><td>Sub-scores: bordered rows, not in a card.</td></tr>
<tr><td>Protein grid</td><td>320px. 7-col grid, 6px gap. Cells: 44px height, colored by protein.</td><td>Repeated protein: 2px yellow border on matched cells (Mon + Thu chicken).</td></tr>
<tr><td>Effort bar</td><td>Proportional flex row. Green/yellow/red segments.</td><td>Labels: "Easy ×3", "Medium ×3", "Hard ×1"</td></tr>
<tr><td>Warnings</td><td>Full width, yellow-tint, radius-lg</td><td>Title 13px/500 + body 12px. Below the 2-col area.</td></tr>
</tbody></table>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════════════ -->
<!-- LLM CONTEXT SECTION -->
<!-- ═══════════════════════════════════════════════════════════════════ -->
<div class="llm">
<h2>LLM Context — J2 Plan the Week</h2>
<h3>1. Journey Flow</h3>
<p>C1 (planner) → C2 (suggestions) → C1 → C3 (variety review) → C1. The actor is the <strong>Planner</strong> only. Household members see C1 in <strong>read-only mode</strong> (all action buttons hidden). C1 is the app home screen and the default route.</p>
<h3>2. Screen C1 — Weekly Planner (HOME SCREEN)</h3>
<ul>
<li><strong>Three fundamentally different layouts</strong> — NOT a scaled-up mobile. Each breakpoint has a distinct layout model.</li>
<li><strong>Mobile (&lt; 768px):</strong> day strip (7-col grid) + selected day card + remaining list + fixed bottom tabs. Five stacked regions, only the remaining list scrolls.</li>
<li><strong>Tablet (7681024px):</strong> same stack, wider. 2-col remaining grid. Inline nav pills (not fixed tab bar). Progress bar appears on the variety banner. "Today" shortcut chip between prev/next week buttons.</li>
<li><strong>Desktop (&gt; 1024px):</strong> 3-panel layout — sidebar 224px (position: sticky, 100vh) + calendar (flex:1, scrollable, 7-col grid) + detail panel 280px (position: sticky, 100vh). Only the calendar area scrolls.</li>
<li><strong>VARIETY SCORE ALWAYS VISIBLE</strong> on all breakpoints — never hidden, tabbed, or collapsed. Mobile: banner below nav. Tablet: banner with progress bar. Desktop: bottom of sidebar.</li>
<li><strong>Today:</strong> yellow treatment — 2px border (the ONLY 2px border in the system) + yellow-tint background.</li>
<li><strong>Selected:</strong> green treatment — 2px border + green-tint background.</li>
<li><strong>Ingredient repeat warnings:</strong> shown on tiles as badge-warn chips (desktop) and in the detail panel as yellow-text ingredient rows (all breakpoints).</li>
<li><strong>Household members:</strong> all action buttons hidden (swap, add meal, cook now). Read-only view, layout otherwise identical.</li>
</ul>
<h3>3. Screen C2 — Meal Suggestions</h3>
<ul>
<li>Suggestions are sorted by the <strong>VARIETY ALGORITHM</strong> (not effort): avoids ingredients from past 3 days, avoids same-protein on adjacent days, balances effort across the week.</li>
<li><strong>Reasoning badges:</strong> green background (good match, e.g. "No fish this week") or yellow background (warning, e.g. "Chicken again — 2 days apart").</li>
<li><strong>Mobile:</strong> context banner (green-tint, collapsible) at top showing day + filter summary, then ranked suggestion list below.</li>
<li><strong>Desktop:</strong> context panel (280px, surface bg, border-right) showing week-so-far cards + filter reasons, plus suggestions panel (flex:1, page bg).</li>
<li><strong>Pick action:</strong> writes <strong>week_plan_slot</strong> → returns to C1. "Browse full library" links to B1 in selection mode.</li>
</ul>
<h3>4. Screen C3 — Variety Review</h3>
<ul>
<li><strong>Score breakdown:</strong> protein diversity (x/10), ingredient overlap (x/10), effort balance (x/10).</li>
<li><strong>Desktop layout:</strong> score + sub-scores on the left (flex:1) + 7-day protein grid (320px) + effort bar on the right. Warnings span full width below.</li>
<li><strong>Protein grid:</strong> 7 columns, each cell 44px height, colored by protein type. Repeated proteins get a <strong>2px yellow border</strong> on matched cells (e.g. Mon + Thu chicken).</li>
<li><strong>Effort bar:</strong> proportional flex segments — easy = green-tint, medium = yellow-tint, hard = red (#FDEAEA). Labels like "Easy ×3".</li>
<li><strong>Mobile:</strong> stacked vertically — score → sub-scores → warnings. No protein grid (too small for 320px viewport).</li>
</ul>
<h3>5. Critical Design Rules</h3>
<ul>
<li><strong>Variety score is the core value proposition</strong> — always visible on every screen, every breakpoint. Never hidden behind a tab, modal, or collapse.</li>
<li><strong>Meal names:</strong> always Fraunces (--font-display). <strong>UI chrome:</strong> always DM Sans (--font-sans).</li>
<li><strong>2px borders ONLY</strong> on today/selected states. Everything else uses 1px borders.</li>
<li><strong>Desktop:</strong> only the calendar area scrolls. Sidebar and detail panel are both position: sticky, height: 100vh.</li>
<li><strong>J3 "mark as cooked" feeds variety history</strong> which filters J2 suggestions — this feedback loop is critical. Cooking history from J3 informs the variety algorithm that ranks suggestions in C2.</li>
</ul>
<h3>6. Data Operations</h3>
<ul>
<li>The variety score is <strong>COMPUTED</strong> via a CTE (Common Table Expression) from the data model. It is <strong>never stored</strong> as a column — always derived at query time from the week's planned meals and cooking history.</li>
<li>C2 Pick action writes to the <strong>week_plan_slot</strong> table and returns to C1.</li>
<li>C3 reads the same computed variety CTE to break down the score into its three components.</li>
</ul>
</div>
</div>
</body>
</html>