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>
1086 lines
101 KiB
HTML
1086 lines
101 KiB
HTML
<!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 & 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 · < 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 · > 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 & breakpoints</td></tr>
|
||
<tr><td>Mobile breakpoint</td><td>< 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>> 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>20px–24px 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 11–12px, padding: 4–5px 8–10px, 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 10–11px 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 12–13px weight 500, green bg (#3D8C4A), white text, radius-md (6px), padding 7–8px 14–18px</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 12–16px muted</td><td>all</td></tr>
|
||
<tr><td>Eyebrow label</td><td>DM Sans 8–10px, weight 500, letter-spacing 0.08–0.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 9–11px, --color-text-muted</td><td>E.g. "Good variety this week"</td><td>all</td></tr>
|
||
<tr><td>Warning row</td><td>DM Sans 9–11px, --yellow-text, flex row, 4–5px 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: 3–5px, 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: 2–3px mobile / 5–6px tablet</td><td>padding: 0 16px 8–12px</td><td>mobile, tablet</td></tr>
|
||
<tr><td>Chip padding</td><td>5–8px top+bottom / 1–4px 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 7–9px, weight 500, tracking 0.05–0.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 11–14px, weight 500, --color-text, line-height 1–1.1</td><td></td><td>mobile, tablet</td></tr>
|
||
<tr><td>Chip dot</td><td>3–4px 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 9–10px, 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 12–14px 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 8–9px, weight 500, tracking 0.06–0.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 11–13px, 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 (16–18px --color-border) + "Add meal" label (9–10px --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>10–16px 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>6–12px 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: 26–36px, flex-shrink: 0</td><td>Abbreviation: 7–9px DM Sans uppercase muted. Number: Fraunces 13–17px weight 300.</td><td>mobile</td></tr>
|
||
<tr><td>Row meal name — mobile</td><td>Fraunces 11–14px, 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 9–11px, --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 9–11px, padding: 3–4px 6–8px, 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);">Thu–Sun — 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 (< 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 (768–1024px):</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 (> 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>
|