[object Object]

← back to Norma

feat(inbox): +16 themes (v17-v32) — total 32 live + dropdown-wired

dfa8907c92ca73cfb30d885b939b924f1ad4cf82 · 2026-05-20 13:24:37 -0700 · Steve Abrams

v17 Ottoman Tile · v18 Brutalist Concrete · v19 Library Catalog ·
v20 Wabi-Sabi · v21 Cyberpunk Rain · v22 Bauhaus · v23 Memphis 80s ·
v24 Vellum Manuscript · v25 Solarpunk · v26 Frutiger Aero ·
v27 Crossword Grid · v28 8-Bit Pixel · v29 Watercolor · v30 Sakura ·
v31 Forest Walk · v32 Botanical Print

Each: standalone HTML mockup + matching .gmail-crm-tab[data-inbox-theme=...]
CSS skin in globals.css + entry in INBOX_THEMES dropdown. All 32 selectable
live from the GmailCRMTab toolbar. Persisted in localStorage as
norma.inbox-theme.

Gallery updated to 32 cards at /mockups/inbox/index.html.

Files touched

Diff

commit dfa8907c92ca73cfb30d885b939b924f1ad4cf82
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed May 20 13:24:37 2026 -0700

    feat(inbox): +16 themes (v17-v32) — total 32 live + dropdown-wired
    
    v17 Ottoman Tile · v18 Brutalist Concrete · v19 Library Catalog ·
    v20 Wabi-Sabi · v21 Cyberpunk Rain · v22 Bauhaus · v23 Memphis 80s ·
    v24 Vellum Manuscript · v25 Solarpunk · v26 Frutiger Aero ·
    v27 Crossword Grid · v28 8-Bit Pixel · v29 Watercolor · v30 Sakura ·
    v31 Forest Walk · v32 Botanical Print
    
    Each: standalone HTML mockup + matching .gmail-crm-tab[data-inbox-theme=...]
    CSS skin in globals.css + entry in INBOX_THEMES dropdown. All 32 selectable
    live from the GmailCRMTab toolbar. Persisted in localStorage as
    norma.inbox-theme.
    
    Gallery updated to 32 cards at /mockups/inbox/index.html.
---
 app/globals.css                               | 130 ++++++++++++++++++++++++++
 components/gmail/GmailCRMTab.tsx              |  16 ++++
 public/mockups/inbox/index.html               |  84 ++++++++++++++++-
 public/mockups/inbox/v17-ottoman-tile.html    |  60 ++++++++++++
 public/mockups/inbox/v18-brutalist.html       |  53 +++++++++++
 public/mockups/inbox/v19-library-catalog.html |  59 ++++++++++++
 public/mockups/inbox/v20-wabi-sabi.html       |  63 +++++++++++++
 public/mockups/inbox/v21-cyberpunk-rain.html  |  70 ++++++++++++++
 public/mockups/inbox/v22-bauhaus.html         |  59 ++++++++++++
 public/mockups/inbox/v23-memphis.html         |  64 +++++++++++++
 public/mockups/inbox/v24-vellum.html          |  72 ++++++++++++++
 public/mockups/inbox/v25-solarpunk.html       |  66 +++++++++++++
 public/mockups/inbox/v26-frutiger-aero.html   |  60 ++++++++++++
 public/mockups/inbox/v27-crossword.html       |  68 ++++++++++++++
 public/mockups/inbox/v28-pixel-8bit.html      |  62 ++++++++++++
 public/mockups/inbox/v29-watercolor.html      |  74 +++++++++++++++
 public/mockups/inbox/v30-sakura.html          |  63 +++++++++++++
 public/mockups/inbox/v31-forest-walk.html     |  58 ++++++++++++
 public/mockups/inbox/v32-botanical.html       |  71 ++++++++++++++
 19 files changed, 1250 insertions(+), 2 deletions(-)

diff --git a/app/globals.css b/app/globals.css
index 6c5688e..5c06338 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1411,3 +1411,133 @@ body { transition: background-color 0.3s, color 0.3s; }
   --color-border: #dfe1e6; --color-primary: #0052cc; --color-primary-hover: #003d99;
   font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
 }
+
+/* ─── INBOX THEMES v17–v32 ─────────────────────────────────────────────── */
+
+/* v17 Ottoman Tile — navy + gold + teal, serif */
+.gmail-crm-tab[data-inbox-theme="ottoman-tile"] {
+  --color-bg: #0a1f33; --color-surface: #102845; --color-surface-el: #19385f;
+  --color-text: #fef0c8; --color-text-secondary: #e4c290; --color-text-muted: #c4a16a;
+  --color-border: #3a5278; --color-primary: #d4a437; --color-primary-hover: #b88c20;
+  font-family: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;
+}
+
+/* v18 Brutalist Concrete — raw gray + hot orange */
+.gmail-crm-tab[data-inbox-theme="brutalist"] {
+  --color-bg: #d4d4d0; --color-surface: #c0c0bc; --color-surface-el: #b4b4b0;
+  --color-text: #1a1a18; --color-text-secondary: #2a2a28; --color-text-muted: #5a5a55;
+  --color-border: #1a1a18; --color-primary: #ff5400; --color-primary-hover: #cc4300;
+  font-family: "Helvetica Neue", Arial, sans-serif; letter-spacing: -0.005em;
+}
+
+/* v19 Library Catalog — manila + typewriter */
+.gmail-crm-tab[data-inbox-theme="library-catalog"] {
+  --color-bg: #f3e6c8; --color-surface: #e8d8b0; --color-surface-el: #dec99a;
+  --color-text: #2a1f10; --color-text-secondary: #4e3f24; --color-text-muted: #6e5a3a;
+  --color-border: #8a6f44; --color-primary: #992014; --color-primary-hover: #7a1810;
+  font-family: "Courier Prime", "Courier New", "American Typewriter", monospace;
+}
+
+/* v20 Wabi-Sabi — earthy clay + sage */
+.gmail-crm-tab[data-inbox-theme="wabi-sabi"] {
+  --color-bg: #ece4d6; --color-surface: #f4ede0; --color-surface-el: #dccfb8;
+  --color-text: #3a2f24; --color-text-secondary: #5a4a3a; --color-text-muted: #8a7a6a;
+  --color-border: #a89a82; --color-primary: #a85a3a; --color-primary-hover: #8a4828;
+  font-family: "Cormorant Garamond", "Iowan Old Style", Georgia, serif;
+}
+
+/* v21 Cyberpunk Rain — black + acid green + hot pink */
+.gmail-crm-tab[data-inbox-theme="cyberpunk-rain"] {
+  --color-bg: #000; --color-surface: #0a0a14; --color-surface-el: #10101e;
+  --color-text: #00ff41; --color-text-secondary: #6acc70; --color-text-muted: #3a8a4a;
+  --color-border: #143514; --color-primary: #ff003c; --color-primary-hover: #cc0030;
+  font-family: "Berkeley Mono", "Share Tech Mono", "JetBrains Mono", ui-monospace, monospace;
+}
+
+/* v22 Bauhaus — cream + primary colors */
+.gmail-crm-tab[data-inbox-theme="bauhaus"] {
+  --color-bg: #f4f0e6; --color-surface: #fff; --color-surface-el: #ece6d4;
+  --color-text: #1a1a1a; --color-text-secondary: #333; --color-text-muted: #666;
+  --color-border: #1a1a1a; --color-primary: #e63946; --color-primary-hover: #c62939;
+  font-family: "Futura", "Avenir Next", "Helvetica Neue", sans-serif; letter-spacing: -0.01em;
+}
+
+/* v23 Memphis 80s — playful pink/teal/yellow, dotted bg */
+.gmail-crm-tab[data-inbox-theme="memphis"] {
+  --color-bg: #f5f4eb; --color-surface: #fff; --color-surface-el: #fff2d4;
+  --color-text: #1a1a26; --color-text-secondary: #3a3a4a; --color-text-muted: #5e5e6e;
+  --color-border: #1a1a26; --color-primary: #ff5fa2; --color-primary-hover: #e0438a;
+  font-family: "Futura", "Avenir Next", sans-serif;
+}
+
+/* v24 Vellum Manuscript — parchment + illuminated */
+.gmail-crm-tab[data-inbox-theme="vellum"] {
+  --color-bg: #f7eed0; --color-surface: #fcf6dc; --color-surface-el: #eadda3;
+  --color-text: #3a1f0c; --color-text-secondary: #5a3818; --color-text-muted: #8a6840;
+  --color-border: #c4a060; --color-primary: #a8201a; --color-primary-hover: #881810;
+  font-family: "Cormorant Garamond", "EB Garamond", Georgia, serif;
+}
+
+/* v25 Solarpunk — sage + ochre */
+.gmail-crm-tab[data-inbox-theme="solarpunk"] {
+  --color-bg: #f0ead2; --color-surface: #fffbeb; --color-surface-el: #e0e0bc;
+  --color-text: #1f3320; --color-text-secondary: #3f5040; --color-text-muted: #5d7553;
+  --color-border: #90a878; --color-primary: #578a4a; --color-primary-hover: #467038;
+  font-family: "Quattrocento Sans", "Open Sans", -apple-system, sans-serif;
+}
+
+/* v26 Frutiger Aero — y2k glossy blue */
+.gmail-crm-tab[data-inbox-theme="frutiger-aero"] {
+  --color-bg: #d6edff; --color-surface: #fff; --color-surface-el: #eaf4ff;
+  --color-text: #1c3a5c; --color-text-secondary: #3a5e80; --color-text-muted: #5e7a98;
+  --color-border: #a8c8e8; --color-primary: #34b5e8; --color-primary-hover: #1c9ad0;
+  font-family: "Segoe UI", "Frutiger", -apple-system, sans-serif;
+}
+
+/* v27 Crossword Grid — pure b&w, courier */
+.gmail-crm-tab[data-inbox-theme="crossword"] {
+  --color-bg: #fff; --color-surface: #fff; --color-surface-el: #f2f2f2;
+  --color-text: #000; --color-text-secondary: #2a2a2a; --color-text-muted: #666;
+  --color-border: #000; --color-primary: #1856ad; --color-primary-hover: #134290;
+  font-family: "Courier Prime", "Courier New", "American Typewriter", monospace;
+}
+
+/* v28 8-Bit Pixel — NES palette */
+.gmail-crm-tab[data-inbox-theme="pixel-8bit"] {
+  --color-bg: #2c3e50; --color-surface: #34495e; --color-surface-el: #1a252f;
+  --color-text: #ecf0f1; --color-text-secondary: #bdc3c7; --color-text-muted: #95a5a6;
+  --color-border: #000; --color-primary: #f1c40f; --color-primary-hover: #d4a800;
+  font-family: "Press Start 2P", "VT323", "Courier New", monospace;
+}
+
+/* v29 Watercolor — soft pastels with painterly bg */
+.gmail-crm-tab[data-inbox-theme="watercolor"] {
+  --color-bg: #f8f4ed; --color-surface: #fefcf7; --color-surface-el: #f0eadb;
+  --color-text: #3a4a52; --color-text-secondary: #5a6a72; --color-text-muted: #7a8a93;
+  --color-border: #c8c0b0; --color-primary: #d68a99; --color-primary-hover: #c06a7c;
+  font-family: "EB Garamond", "Cormorant Garamond", Georgia, serif;
+}
+
+/* v30 Sakura — pink + white + black, minimal japanese */
+.gmail-crm-tab[data-inbox-theme="sakura"] {
+  --color-bg: #fff9fa; --color-surface: #fff; --color-surface-el: #fdf0f2;
+  --color-text: #1a0a14; --color-text-secondary: #4a3a44; --color-text-muted: #8a6878;
+  --color-border: #f2c8d2; --color-primary: #e8597c; --color-primary-hover: #c8395c;
+  font-family: "Shippori Mincho", "Noto Serif JP", "Hiragino Mincho ProN", "Yu Mincho", serif;
+}
+
+/* v31 Forest Walk — mossy green + bark */
+.gmail-crm-tab[data-inbox-theme="forest-walk"] {
+  --color-bg: #1c2418; --color-surface: #2a3424; --color-surface-el: #3a4632;
+  --color-text: #e8e0c8; --color-text-secondary: #c4ba9a; --color-text-muted: #9aa080;
+  --color-border: #4a5638; --color-primary: #7a9c48; --color-primary-hover: #5a7c30;
+  font-family: "Lora", "Iowan Old Style", Georgia, serif;
+}
+
+/* v32 Botanical Print — field-guide cream + leaf green + copper */
+.gmail-crm-tab[data-inbox-theme="botanical"] {
+  --color-bg: #f4ede0; --color-surface: #fdfaf0; --color-surface-el: #e6d8c0;
+  --color-text: #1a2818; --color-text-secondary: #3a4628; --color-text-muted: #5a6648;
+  --color-border: #8a9a78; --color-primary: #2a5028; --color-primary-hover: #1a3a18;
+  font-family: "Cormorant Garamond", "EB Garamond", Georgia, serif;
+}
diff --git a/components/gmail/GmailCRMTab.tsx b/components/gmail/GmailCRMTab.tsx
index a6cf6f0..1e22489 100644
--- a/components/gmail/GmailCRMTab.tsx
+++ b/components/gmail/GmailCRMTab.tsx
@@ -271,6 +271,22 @@ export default function GmailCRMTab() {
     { id: 'material',            label: '14 · Material 3',           description: 'Purple primary, rounded' },
     { id: 'synthwave',           label: '15 · Synthwave',            description: 'Magenta+cyan on indigo, retro 80s' },
     { id: 'kanban-lanes',        label: '16 · Kanban Lanes',         description: 'Trello palette (lane layout in mockup)' },
+    { id: 'ottoman-tile',        label: '17 · Ottoman Tile',         description: 'Navy + gold + teal, serif, calligraphic' },
+    { id: 'brutalist',           label: '18 · Brutalist Concrete',   description: 'Raw gray + hot orange, hard edges' },
+    { id: 'library-catalog',     label: '19 · Library Catalog',      description: 'Manila + typewriter, card-catalog feel' },
+    { id: 'wabi-sabi',           label: '20 · Wabi-Sabi',            description: 'Earthy clay + sage, Japanese minimalism' },
+    { id: 'cyberpunk-rain',      label: '21 · Cyberpunk Rain',       description: 'Black + acid green + hot pink' },
+    { id: 'bauhaus',             label: '22 · Bauhaus',              description: 'Primary red/blue/yellow, geometric' },
+    { id: 'memphis',             label: '23 · Memphis 80s',          description: 'Pink/teal/yellow, dotted bg, playful' },
+    { id: 'vellum',              label: '24 · Vellum Manuscript',    description: 'Parchment, illuminated drop caps' },
+    { id: 'solarpunk',           label: '25 · Solarpunk',            description: 'Sage + ochre, organic optimism' },
+    { id: 'frutiger-aero',       label: '26 · Frutiger Aero',        description: 'Y2K glossy sky-blue, glassy buttons' },
+    { id: 'crossword',           label: '27 · Crossword Grid',       description: 'Pure b&w, courier, grid cells' },
+    { id: 'pixel-8bit',          label: '28 · 8-Bit Pixel',          description: 'NES palette, blocky, retro gaming' },
+    { id: 'watercolor',          label: '29 · Watercolor',           description: 'Soft pastel splotches, painterly feel' },
+    { id: 'sakura',              label: '30 · Sakura',               description: 'Pink + white + black, minimal Japanese' },
+    { id: 'forest-walk',         label: '31 · Forest Walk',          description: 'Mossy green + bark + cream, woodland' },
+    { id: 'botanical',           label: '32 · Botanical Print',      description: 'Field-guide cream + leaf green + copper' },
   ];
   const [inboxTheme, setInboxTheme] = useState<string>('classic-dense');
   // Hydrate from localStorage post-mount
diff --git a/public/mockups/inbox/index.html b/public/mockups/inbox/index.html
index 5728194..362d27c 100644
--- a/public/mockups/inbox/index.html
+++ b/public/mockups/inbox/index.html
@@ -24,8 +24,8 @@
 </head>
 <body>
 <header>
-  <h1>Inbox UI Variants — 16 directions</h1>
-  <p class="sub">Each variant includes the assign-to dropdown, per-user read receipts, and inline-expand reading pane. All 16 are wired as live themes inside Norma (GmailCRMTab → Theme dropdown).</p>
+  <h1>Inbox UI Variants — 32 directions</h1>
+  <p class="sub">Each variant includes the assign-to dropdown, per-user read receipts, and inline-expand reading pane. All 32 are wired as live themes inside Norma (GmailCRMTab → Theme dropdown).</p>
 </header>
 <div class="grid">
 
@@ -109,6 +109,86 @@
   <div class="meta"><div class="name">16 — Kanban Lanes</div><p class="desc">Trello-style horizontal lanes: Unassigned / Triage / Working / Waiting / Replied. Drag cards.</p><div class="badges"><span class="badge">kanban</span><span class="badge">trello-vibe</span></div></div>
 </a></div>
 
+<div class="card"><a href="v17-ottoman-tile.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v17-ottoman-tile.html"></iframe></div>
+  <div class="meta"><div class="name">17 — Ottoman Tile</div><p class="desc">Navy + gold + teal. Calligraphic Cormorant serif. Tile-pattern undertone, regal accents.</p><div class="badges"><span class="badge">ornate</span><span class="badge">serif</span></div></div>
+</a></div>
+
+<div class="card"><a href="v18-brutalist.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v18-brutalist.html"></iframe></div>
+  <div class="meta"><div class="name">18 — Brutalist Concrete</div><p class="desc">Raw gray + hot orange. Hard edges, oversized type, no rounding. Industrial.</p><div class="badges"><span class="badge">brutalist</span><span class="badge">raw</span></div></div>
+</a></div>
+
+<div class="card"><a href="v19-library-catalog.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v19-library-catalog.html"></iframe></div>
+  <div class="meta"><div class="name">19 — Library Catalog</div><p class="desc">Manila card stock + typewriter font. Ruled lines, card-catalog drawer feel.</p><div class="badges"><span class="badge">typewriter</span><span class="badge">archival</span></div></div>
+</a></div>
+
+<div class="card"><a href="v20-wabi-sabi.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v20-wabi-sabi.html"></iframe></div>
+  <div class="meta"><div class="name">20 — Wabi-Sabi</div><p class="desc">Earthy clay + sage. Asymmetric padding, italic serif, Japanese minimalism.</p><div class="badges"><span class="badge">minimal</span><span class="badge">earthen</span></div></div>
+</a></div>
+
+<div class="card"><a href="v21-cyberpunk-rain.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v21-cyberpunk-rain.html"></iframe></div>
+  <div class="meta"><div class="name">21 — Cyberpunk Rain</div><p class="desc">Black + acid green + hot pink. Scanline overlay, terminal vibe with neon.</p><div class="badges"><span class="badge">neon</span><span class="badge">terminal</span></div></div>
+</a></div>
+
+<div class="card"><a href="v22-bauhaus.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v22-bauhaus.html"></iframe></div>
+  <div class="meta"><div class="name">22 — Bauhaus</div><p class="desc">Primary red/blue/yellow on cream. Geometric shapes as avatars. Futura.</p><div class="badges"><span class="badge">geometric</span><span class="badge">primary-colors</span></div></div>
+</a></div>
+
+<div class="card"><a href="v23-memphis.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v23-memphis.html"></iframe></div>
+  <div class="meta"><div class="name">23 — Memphis 80s</div><p class="desc">Pink/teal/yellow with dotted background. Hard drop-shadows. Playful.</p><div class="badges"><span class="badge">playful</span><span class="badge">retro-80s</span></div></div>
+</a></div>
+
+<div class="card"><a href="v24-vellum.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v24-vellum.html"></iframe></div>
+  <div class="meta"><div class="name">24 — Vellum Manuscript</div><p class="desc">Parchment cream with illuminated drop-caps. Garamond serif, scribed feel.</p><div class="badges"><span class="badge">illuminated</span><span class="badge">medieval</span></div></div>
+</a></div>
+
+<div class="card"><a href="v25-solarpunk.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v25-solarpunk.html"></iframe></div>
+  <div class="meta"><div class="name">25 — Solarpunk</div><p class="desc">Sage + ochre + sky blue. Optimistic, organic, rounded cards.</p><div class="badges"><span class="badge">optimistic</span><span class="badge">organic</span></div></div>
+</a></div>
+
+<div class="card"><a href="v26-frutiger-aero.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v26-frutiger-aero.html"></iframe></div>
+  <div class="meta"><div class="name">26 — Frutiger Aero</div><p class="desc">Y2K glossy sky-blue gradients. Glassy bubble orbs, soft drop-shadows.</p><div class="badges"><span class="badge">y2k</span><span class="badge">glossy</span></div></div>
+</a></div>
+
+<div class="card"><a href="v27-crossword.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v27-crossword.html"></iframe></div>
+  <div class="meta"><div class="name">27 — Crossword Grid</div><p class="desc">Pure b&w grid cells, courier, NYT-puzzle aesthetic. Across/Down framing.</p><div class="badges"><span class="badge">puzzle</span><span class="badge">b&w</span></div></div>
+</a></div>
+
+<div class="card"><a href="v28-pixel-8bit.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v28-pixel-8bit.html"></iframe></div>
+  <div class="meta"><div class="name">28 — 8-Bit Pixel</div><p class="desc">NES palette, blocky borders, HP bar + score. Retro gaming inbox.</p><div class="badges"><span class="badge">retro-gaming</span><span class="badge">pixel</span></div></div>
+</a></div>
+
+<div class="card"><a href="v29-watercolor.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v29-watercolor.html"></iframe></div>
+  <div class="meta"><div class="name">29 — Watercolor</div><p class="desc">Soft splotches of rose / lavender / sage / peach. Painterly, gentle.</p><div class="badges"><span class="badge">painterly</span><span class="badge">soft</span></div></div>
+</a></div>
+
+<div class="card"><a href="v30-sakura.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v30-sakura.html"></iframe></div>
+  <div class="meta"><div class="name">30 — Sakura</div><p class="desc">Pink + white + black. Japanese mincho serif, single-stroke kanji accents.</p><div class="badges"><span class="badge">japanese</span><span class="badge">minimal</span></div></div>
+</a></div>
+
+<div class="card"><a href="v31-forest-walk.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v31-forest-walk.html"></iframe></div>
+  <div class="meta"><div class="name">31 — Forest Walk</div><p class="desc">Mossy green + bark + cream. Woodland calm, italic serif, leaf glyphs.</p><div class="badges"><span class="badge">woodland</span><span class="badge">natural</span></div></div>
+</a></div>
+
+<div class="card"><a href="v32-botanical.html" target="_blank">
+  <div class="frame-wrap"><iframe class="preview" src="v32-botanical.html"></iframe></div>
+  <div class="meta"><div class="name">32 — Botanical Print</div><p class="desc">Field-guide plate per message. Cream + leaf green + copper. Victorian scientific.</p><div class="badges"><span class="badge">field-guide</span><span class="badge">victorian</span></div></div>
+</a></div>
+
 </div>
 </body>
 </html>
diff --git a/public/mockups/inbox/v17-ottoman-tile.html b/public/mockups/inbox/v17-ottoman-tile.html
new file mode 100644
index 0000000..fa2a602
--- /dev/null
+++ b/public/mockups/inbox/v17-ottoman-tile.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v17 — Ottoman Tile — Norma Inbox</title>
+<style>
+  :root { --bg:#0a1f33; --panel:#102845; --el:#19385f; --fg:#fef0c8; --muted:#c4a16a; --line:#3a5278; --gold:#d4a437; --teal:#5fa8aa; --crimson:#a03030; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.55 "Cormorant Garamond", "Iowan Old Style", Georgia, serif; min-height:100vh;
+    background-image: radial-gradient(circle at 25% 0, rgba(212,164,55,0.05) 0%, transparent 40%), radial-gradient(circle at 75% 100%, rgba(95,168,170,0.05) 0%, transparent 40%); }
+  .top { padding:18px 28px; border-bottom:2px solid var(--gold); display:flex; gap:16px; align-items:center;
+    background:linear-gradient(180deg, var(--panel), transparent); }
+  .top h1 { margin:0; font-size:26px; font-weight:500; letter-spacing:0.04em; flex:1; color:var(--gold); }
+  .top h1::before { content:"❖ "; color:var(--teal); }
+  .pill { font-size:12px; padding:6px 14px; border:1px solid var(--gold); color:var(--gold); background:transparent; cursor:pointer; letter-spacing:0.08em; }
+  .pill.on { background:var(--gold); color:var(--bg); }
+  .list { padding:18px 28px; }
+  .row { display:grid; grid-template-columns:48px 1fr 130px 70px; gap:14px; padding:14px 16px; border:1px solid var(--line); background:rgba(255,255,255,0.02); margin-bottom:8px; cursor:pointer; align-items:center;
+    background-image:linear-gradient(135deg, transparent 60%, rgba(212,164,55,0.04) 100%); }
+  .row:hover { border-color:var(--gold); }
+  .row.on { border-color:var(--gold); background:rgba(212,164,55,0.06); box-shadow:inset 0 0 0 1px var(--gold); }
+  .seal { width:42px; height:42px; border-radius:50%; background:radial-gradient(circle, var(--teal), var(--bg)); display:flex; align-items:center; justify-content:center; color:var(--gold); font-family:"Cormorant Garamond", serif; font-weight:600; font-size:18px; border:2px solid var(--gold); }
+  .from { font-weight:600; font-size:15px; }
+  .subj { color:var(--muted); font-size:13.5px; font-style:italic; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+  .subj strong { color:var(--fg); font-style:normal; }
+  .meta-r { font-size:11px; letter-spacing:0.1em; text-transform:uppercase; color:var(--gold); }
+  .chip { padding:1px 9px; border:1px solid var(--line); }
+  .when { font-size:11px; color:var(--muted); text-align:right; }
+  /* expand */
+  .expand { padding:22px 26px 26px; margin:10px 0; border:1px solid var(--gold); background:rgba(212,164,55,0.04);
+    background-image: linear-gradient(135deg, rgba(95,168,170,0.04) 0%, transparent 50%); }
+  .expand h2 { margin:0; font-size:24px; font-weight:500; color:var(--gold); }
+  .expand h2::before { content:"⟵ ❖ ⟶ "; color:var(--teal); font-size:14px; vertical-align:middle; }
+  .meta-grid { display:grid; grid-template-columns:100px 1fr; gap:5px 14px; font-size:13px; margin:14px 0 18px; padding:12px 0; border-top:1px solid var(--gold); border-bottom:1px solid var(--gold); color:var(--muted); letter-spacing:0.04em; text-transform:uppercase; font-size:11px; }
+  .meta-grid > span:nth-child(even) { color:var(--fg); text-transform:none; font-size:13px; letter-spacing:0; }
+  select.assign { background:var(--panel); border:1px solid var(--gold); color:var(--gold); font:13px inherit; padding:4px 10px; }
+  .seen-pill { font-size:11px; padding:3px 11px; border:1px solid var(--teal); color:var(--teal); margin-right:5px; letter-spacing:0.06em; }
+  .body { font-size:15.5px; line-height:1.75; color:var(--fg); padding:6px 0 14px; }
+  textarea { width:100%; background:var(--panel); border:1px solid var(--gold); color:var(--fg); font:14.5px/1.65 inherit; padding:12px 14px; resize:vertical; min-height:90px; }
+  .act { display:flex; gap:8px; margin-top:12px; }
+  .btn { font:12px inherit; padding:7px 16px; border:1px solid var(--gold); color:var(--gold); background:transparent; cursor:pointer; letter-spacing:0.08em; text-transform:uppercase; }
+  .btn.pri { background:var(--gold); color:var(--bg); margin-left:auto; font-weight:600; }
+</style>
+</head><body>
+<div class="top"><h1>The Inbox · بريد</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><button class="pill">⟲ Sync</button></div>
+<div class="list">
+  <div class="row"><div class="seal">B</div><div><div class="from">Sen. Bernie Sanders Office</div><div class="subj"><strong>RE: Markup tomorrow — borrower bill.</strong> Quick call before 9am ET.</div></div><div class="meta-r"><span class="chip">Policy</span></div><div class="when">14m</div></div>
+  <div class="row on"><div class="seal">E</div><div><div class="from">Erica Werner · Washington Post</div><div class="subj"><strong>Quote request — PSLF guidance.</strong></div></div><div class="meta-r"><span class="chip">Press</span></div><div class="when">42m</div></div>
+  <div class="expand">
+    <h2>Quote request — Dept of Ed PSLF guidance</h2>
+    <div class="meta-grid">
+      <span>From</span><span>Erica Werner · Washington Post</span>
+      <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+      <span>Seen by</span><span><span class="seen-pill">✦ Natalia · 3:21</span><span class="seen-pill">✦ Cody · 3:24</span></span>
+    </div>
+    <div class="body">
+      Honored Madam,<br>—Running a piece tomorrow on the new PSLF buyback guidance. Two questions if 20 minutes can be granted before four post meridiem:<br>1) Whether borrowers between 100–120 months gain meaningful benefit, or whether buyback math wipes it.<br>2) Any data on the 100–120 window?<br>— Erica
+    </div>
+    <textarea>Hi Erica — quick call at 3:45pm ET; I'll text. Our cohort: 12k PSLF, 23% in the 100–120 window. Buyback math wipes the gain above income cap — design flaw. — Natalia</textarea>
+    <div class="act"><button class="btn">Copy</button><button class="btn">Save Draft</button><button class="btn pri">Dispatch ⟶</button></div>
+  </div>
+  <div class="row"><div class="seal">A</div><div><div class="from">Astra Taylor · Debt Collective</div><div class="subj">Reading the ED memo together?</div></div><div class="meta-r"><span class="chip">Partners</span></div><div class="when">2h</div></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v18-brutalist.html b/public/mockups/inbox/v18-brutalist.html
new file mode 100644
index 0000000..0b120d5
--- /dev/null
+++ b/public/mockups/inbox/v18-brutalist.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v18 — Brutalist — Norma Inbox</title>
+<style>
+  :root { --bg:#d4d4d0; --panel:#c0c0bc; --el:#b4b4b0; --fg:#1a1a18; --muted:#5a5a55; --line:#1a1a18; --hi:#ff5400; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.4 "Helvetica Neue", Arial, sans-serif; }
+  .top { padding:18px 24px; background:var(--fg); color:var(--bg); display:flex; gap:14px; align-items:center; }
+  .top h1 { margin:0; font-size:30px; font-weight:900; letter-spacing:-0.04em; text-transform:uppercase; flex:1; }
+  .pill { padding:6px 14px; background:transparent; border:2px solid var(--bg); color:var(--bg); cursor:pointer; font-weight:700; font-size:12px; text-transform:uppercase; letter-spacing:0.06em; }
+  .pill.on { background:var(--hi); border-color:var(--hi); color:var(--fg); }
+  .toolbar { padding:10px 24px; background:var(--el); display:flex; gap:10px; font-size:12px; text-transform:uppercase; letter-spacing:0.08em; color:var(--muted); border-bottom:2px solid var(--fg); }
+  .list { padding:0; }
+  .row { padding:18px 24px; border-bottom:2px solid var(--fg); cursor:pointer; display:grid; grid-template-columns:80px 1fr 120px 80px; gap:18px; align-items:center; }
+  .row:hover { background:var(--el); }
+  .row.on { background:var(--hi); }
+  .row .id { font-weight:900; font-size:32px; line-height:1; letter-spacing:-0.05em; }
+  .from { font-weight:900; font-size:16px; text-transform:uppercase; letter-spacing:-0.01em; }
+  .subj { font-size:13px; color:var(--muted); margin-top:2px; }
+  .row.on .subj { color:var(--fg); }
+  .chip { font-size:10px; font-weight:900; text-transform:uppercase; letter-spacing:0.1em; padding:3px 8px; background:var(--fg); color:var(--bg); display:inline-block; }
+  .when { font-family:"Courier New", monospace; font-size:13px; text-align:right; font-weight:700; }
+  /* expand */
+  .expand { padding:32px 28px; background:var(--fg); color:var(--bg); border-bottom:2px solid var(--fg); }
+  .expand h2 { margin:0; font-size:36px; font-weight:900; letter-spacing:-0.04em; line-height:1.05; text-transform:uppercase; }
+  .meta-strip { padding:14px 0; border-top:1px solid var(--bg); border-bottom:1px solid var(--bg); margin:18px 0; font-size:13px; display:grid; grid-template-columns:100px 1fr; gap:8px 14px; }
+  .meta-strip > span:nth-child(odd) { font-weight:900; text-transform:uppercase; letter-spacing:0.1em; font-size:11px; padding-top:3px; }
+  select.assign { background:var(--bg); color:var(--fg); border:none; padding:4px 8px; font:13px inherit; font-weight:700; }
+  .seen-pill { font-family:"Courier New", monospace; padding:2px 8px; background:var(--hi); color:var(--fg); font-weight:700; font-size:12px; margin-right:5px; }
+  .body { font-size:16px; line-height:1.65; }
+  textarea { width:100%; background:var(--bg); color:var(--fg); border:none; padding:14px 16px; font:14.5px/1.55 inherit; resize:vertical; min-height:100px; }
+  .act { display:flex; gap:8px; margin-top:12px; }
+  .btn { font:12px inherit; padding:10px 22px; background:transparent; color:var(--bg); border:2px solid var(--bg); cursor:pointer; font-weight:900; text-transform:uppercase; letter-spacing:0.08em; }
+  .btn.pri { background:var(--hi); color:var(--fg); border:none; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>I N B O X.</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><button class="pill" style="background:var(--hi);border-color:var(--hi);color:var(--fg)">↻ Sync</button></div>
+<div class="toolbar"><span>12 messages · sorted newest first · 8 unread</span></div>
+<div class="list">
+  <div class="row"><span class="id">01</span><div><div class="from">Sanders Office</div><div class="subj">RE: MARKUP TOMORROW — BORROWER BILL</div></div><span class="chip">Policy</span><span class="when">14m</span></div>
+  <div class="row on"><span class="id">02</span><div><div class="from">Erica Werner / WP</div><div class="subj">QUOTE REQUEST — PSLF GUIDANCE</div></div><span class="chip">Press</span><span class="when">42m</span></div>
+  <div class="expand">
+    <h2>Quote Request — PSLF Guidance</h2>
+    <div class="meta-strip">
+      <span>From</span><span>Erica Werner · WashPost · erica@washpost.com</span>
+      <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+      <span>Seen</span><span><span class="seen-pill">N · 3:21</span><span class="seen-pill">C · 3:24</span></span>
+    </div>
+    <div class="body">Running a piece tomorrow on PSLF buyback. 20 min by 4pm ET. Two Qs:<br>1) Borrowers in months 100–120 — meaningful benefit, or buyback math wipes?<br>2) SDCC data on the 100–120 window?</div>
+    <textarea>Hi Erica — quick call at 3:45pm ET. ~12k PSLF in cohort, 23% in 100–120. Buyback wipes gain above income cap. — N</textarea>
+    <div class="act"><button class="btn">Copy</button><button class="btn">Save</button><button class="btn pri">SEND →</button></div>
+  </div>
+  <div class="row"><span class="id">03</span><div><div class="from">Astra Taylor</div><div class="subj">READING THE ED MEMO TOGETHER?</div></div><span class="chip">Partners</span><span class="when">2h</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v19-library-catalog.html b/public/mockups/inbox/v19-library-catalog.html
new file mode 100644
index 0000000..ad65fb2
--- /dev/null
+++ b/public/mockups/inbox/v19-library-catalog.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v19 — Library Catalog — Norma Inbox</title>
+<style>
+  :root { --bg:#f3e6c8; --panel:#e8d8b0; --el:#dec99a; --fg:#2a1f10; --muted:#6e5a3a; --line:#8a6f44; --red:#992014; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:15px/1.55 "Courier Prime", "Courier New", "American Typewriter", monospace; }
+  body::before { content:""; position:fixed; inset:0; background-image:repeating-linear-gradient(0deg, transparent 0 27px, rgba(138,111,68,0.18) 27px 28px); pointer-events:none; z-index:0; }
+  body > * { position:relative; z-index:1; }
+  .top { padding:18px 28px 12px; border-bottom:3px double var(--fg); display:flex; gap:14px; align-items:flex-end; }
+  .top h1 { margin:0; font-size:24px; font-weight:700; letter-spacing:0.04em; flex:1; }
+  .top h1 small { display:block; font-size:11px; font-weight:400; letter-spacing:0.12em; text-transform:uppercase; color:var(--muted); margin-top:2px; }
+  .pill { font-size:12px; padding:5px 12px; border:1px solid var(--fg); background:transparent; color:var(--fg); cursor:pointer; }
+  .pill.on { background:var(--fg); color:var(--bg); }
+  .list { padding:14px 28px 60px; }
+  .row { display:grid; grid-template-columns:90px 1fr 130px 80px; gap:14px; padding:14px 0 14px; border-bottom:1px solid var(--line); cursor:pointer; align-items:center; }
+  .row:hover { background:rgba(138,111,68,0.08); margin:0 -10px; padding-left:10px; padding-right:10px; }
+  .row .id { font-size:11px; letter-spacing:0.1em; color:var(--muted); border:1px solid var(--line); padding:5px 8px; text-align:center; background:var(--panel); }
+  .from { font-weight:700; font-size:14px; }
+  .subj { font-size:13.5px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+  .subj strong { color:var(--fg); font-weight:400; text-decoration:underline; }
+  .row.on .id { background:var(--fg); color:var(--bg); border-color:var(--fg); }
+  .meta-r { font-size:11px; text-transform:uppercase; letter-spacing:0.1em; color:var(--muted); }
+  .when { font-size:12px; text-align:right; color:var(--muted); }
+  /* expand */
+  .expand { margin:14px -28px 0; padding:24px 32px 30px; background:var(--panel); border-top:2px solid var(--fg); border-bottom:2px solid var(--fg);
+    box-shadow:inset 0 0 0 3px var(--bg), inset 0 0 0 4px var(--fg); }
+  .card-head { display:grid; grid-template-columns:140px 1fr; gap:6px 14px; font-size:13px; margin-bottom:14px; }
+  .card-head > span:nth-child(odd) { color:var(--muted); letter-spacing:0.06em; text-transform:uppercase; font-size:11px; padding-top:3px; }
+  .card-head strong { font-weight:700; }
+  .expand h2 { margin:14px 0 6px; font-size:22px; font-weight:700; }
+  select.assign { background:var(--bg); border:1px solid var(--line); color:var(--fg); font:13px inherit; padding:3px 9px; }
+  .seen-pill { display:inline-block; padding:1px 7px; border:1px dashed var(--fg); margin-right:5px; font-size:12px; }
+  .body { font-size:14.5px; line-height:1.7; padding:14px 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); margin:10px 0 14px; }
+  textarea { width:100%; background:var(--bg); border:1px solid var(--fg); color:var(--fg); font:14px/1.6 inherit; padding:11px 13px; resize:vertical; min-height:90px; }
+  .act { display:flex; gap:8px; margin-top:10px; }
+  .btn { font:12px inherit; padding:6px 16px; background:var(--bg); border:1px solid var(--fg); color:var(--fg); cursor:pointer; text-transform:uppercase; letter-spacing:0.06em; font-weight:700; }
+  .btn.pri { background:var(--red); border-color:var(--red); color:var(--bg); margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>CARD CATALOG <small>· SDCC Correspondence · Drawer N — natalia@</small></h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><button class="pill">↻ Sync</button></div>
+<div class="list">
+  <div class="row"><span class="id">N-001</span><div><div class="from">Sanders Office, Sen. Bernie</div><div class="subj"><strong>RE: Markup tomorrow — borrower bill.</strong> Senator can do a quick call before 9am ET.</div></div><span class="meta-r">Policy · Hi.</span><span class="when">14m</span></div>
+  <div class="row on"><span class="id">N-002</span><div><div class="from">Werner, Erica · Washington Post</div><div class="subj"><strong>Quote request — Dept of Ed PSLF guidance.</strong> Story for tomorrow on PSLF buyback option.</div></div><span class="meta-r">Press · Hi.</span><span class="when">42m</span></div>
+  <div class="expand">
+    <div class="card-head">
+      <span>Call No.</span><span><strong>N-002</strong> · Press · 2026-05-20T15:18Z</span>
+      <span>Author</span><span><strong>Werner, Erica</strong> · The Washington Post</span>
+      <span>Owner</span><span><select class="assign"><option>Abrams, Natalia (Admin)</option><option>Lin, Cody (Staff)</option><option>Park, Jess (Intern)</option></select></span>
+      <span>Charged Out To</span><span><span class="seen-pill">Abrams · 3:21 PM</span><span class="seen-pill">Lin · 3:24 PM</span></span>
+    </div>
+    <h2>Quote request — Dept of Ed PSLF guidance</h2>
+    <div class="body">
+      Hi Natalia,<br>Running a piece tomorrow on the new PSLF buyback guidance. Two Qs by 4pm ET:<br>1) Read on whether borrowers in months 100–120 get a meaningful benefit, or buyback wipes it.<br>2) SDCC data on the 100–120 window?<br>— Erica
+    </div>
+    <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text. Our cohort: ~12k PSLF, 23% in the 100–120 window. Buyback wipes the gain above income cap — design flaw. — Natalia</textarea>
+    <div class="act"><button class="btn">Copy</button><button class="btn">Save Draft</button><button class="btn pri">Stamp & Send</button></div>
+  </div>
+  <div class="row"><span class="id">N-003</span><div><div class="from">Taylor, Astra · Debt Collective</div><div class="subj">Reading the new ED memo together?</div></div><span class="meta-r">Partners · Hi.</span><span class="when">2h</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v20-wabi-sabi.html b/public/mockups/inbox/v20-wabi-sabi.html
new file mode 100644
index 0000000..ce1ce6c
--- /dev/null
+++ b/public/mockups/inbox/v20-wabi-sabi.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v20 — Wabi-Sabi — Norma Inbox</title>
+<style>
+  :root { --bg:#ece4d6; --panel:#f4ede0; --el:#dccfb8; --fg:#3a2f24; --muted:#8a7a6a; --line:#a89a82; --clay:#a85a3a; --sage:#7a8068; --ink:#1a1410; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:15px/1.7 "Cormorant Garamond", "Iowan Old Style", Georgia, serif; }
+  .top { padding:30px 36px 16px; display:flex; gap:18px; align-items:flex-end; }
+  .top h1 { margin:0; font-size:32px; font-weight:400; flex:1; letter-spacing:0.02em; font-style:italic; }
+  .pill { font-size:12px; padding:5px 0; border-bottom:1px solid transparent; color:var(--muted); cursor:pointer; letter-spacing:0.1em; text-transform:uppercase; }
+  .pill.on { color:var(--fg); border-bottom-color:var(--fg); }
+  .top hr { display:none; }
+  .divider { height:1px; background:var(--line); margin:0 36px 0; transform:rotate(-0.3deg); transform-origin:left; }
+  .list { padding:24px 36px 60px; max-width:760px; margin:0 auto; }
+  .row { padding:22px 0; border-bottom:1px solid var(--line); cursor:pointer; }
+  .row:nth-child(even) { padding-left:24px; }
+  .row:nth-child(odd) { padding-right:24px; }
+  .head { display:flex; gap:14px; align-items:baseline; font-size:13px; color:var(--muted); }
+  .head .name { color:var(--fg); font-size:16px; font-weight:600; font-style:italic; }
+  .head .when { margin-left:auto; font-size:12px; }
+  .subj { font-size:19px; margin:4px 0 4px; line-height:1.35; font-weight:500; }
+  .prev { font-size:14px; color:var(--muted); margin:0; line-height:1.6; }
+  .chips { margin-top:10px; display:flex; gap:14px; flex-wrap:wrap; font-size:11px; letter-spacing:0.1em; text-transform:uppercase; color:var(--muted); }
+  .chips .ch { padding-bottom:1px; border-bottom:1px solid var(--clay); color:var(--clay); }
+  .chips .ch-seen { color:var(--sage); border-bottom-color:var(--sage); }
+
+  /* expand */
+  .expand { margin:14px 0; padding:32px 30px 36px; background:var(--panel); border:1px solid var(--line); position:relative; }
+  .expand::before { content:""; position:absolute; top:8px; right:8px; bottom:8px; left:8px; border:1px solid var(--clay); opacity:0.25; pointer-events:none; }
+  .expand h2 { margin:0 0 4px; font-size:28px; font-weight:500; letter-spacing:-0.005em; line-height:1.25; font-style:italic; }
+  .byline { color:var(--muted); font-size:13.5px; margin-bottom:14px; }
+  .meta-grid { display:grid; grid-template-columns:90px 1fr; gap:8px 18px; font-size:13px; margin:18px 0 22px; padding:14px 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); }
+  .meta-grid > span:nth-child(odd) { color:var(--muted); font-size:11px; letter-spacing:0.08em; text-transform:uppercase; padding-top:3px; }
+  select.assign { background:transparent; border:none; border-bottom:1px solid var(--fg); color:var(--fg); font:14px inherit; padding:2px 0; font-style:italic; }
+  .seen-pill { display:inline-block; margin-right:14px; padding:0 0 1px; border-bottom:1px solid var(--sage); color:var(--sage); font-size:13px; font-style:italic; }
+  .body { font-size:16.5px; line-height:1.8; max-width:560px; }
+  .body p { margin:0 0 14px; }
+  textarea { width:100%; max-width:580px; background:var(--bg); border:1px solid var(--line); color:var(--fg); padding:14px 16px; font:15.5px/1.7 "Cormorant Garamond", Georgia, serif; resize:vertical; min-height:110px; }
+  .act { display:flex; gap:16px; margin-top:14px; align-items:center; max-width:580px; }
+  .btn { font:13px inherit; padding:6px 0; background:transparent; border:none; border-bottom:1px solid var(--fg); color:var(--fg); cursor:pointer; letter-spacing:0.05em; font-style:italic; }
+  .btn.pri { background:var(--clay); color:#fff; padding:8px 22px; border:none; border-radius:0; font-style:normal; font-weight:600; letter-spacing:0.08em; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>Quiet inbox.</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><span class="pill">— sync</span></div>
+<div class="divider"></div>
+<div class="list">
+  <div class="row"><div class="head"><span class="name">Sen. Bernie Sanders Office</span><span class="when">14 minutes</span></div><h3 class="subj">RE: Markup tomorrow — borrower bill</h3><p class="prev">Senator can do a quick call before 9am ET. Aide on this thread.</p><div class="chips"><span class="ch">policy</span></div></div>
+  <div class="expand">
+    <h2>Quote request — Dept of Ed PSLF guidance</h2>
+    <div class="byline">Erica Werner · The Washington Post · this afternoon, 3:18 PM</div>
+    <div class="meta-grid">
+      <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+      <span>Seen by</span><span><span class="seen-pill">Natalia · 3:21</span><span class="seen-pill">Cody · 3:24</span></span>
+    </div>
+    <div class="body">
+      <p>Hi Natalia — running a piece tomorrow on the new PSLF buyback guidance. Two questions if you have 20 minutes by 4pm ET.</p>
+      <p>Your read on whether borrowers between months 100–120 actually get meaningful benefit, or whether the buyback math wipes it out. And any SDCC data on the 100–120 window.</p>
+      <p>Happy to do email if a call doesn't work. — Erica</p>
+    </div>
+    <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text the number. Our cohort: ~12k PSLF, 23% in the 100–120 window. Buyback wipes the gain above income cap — design flaw worth surfacing. — Natalia</textarea>
+    <div class="act"><button class="btn">copy</button><button class="btn">save draft</button><button class="btn pri">Send →</button></div>
+  </div>
+  <div class="row"><div class="head"><span class="name">Astra Taylor · Debt Collective</span><span class="when">2 hours</span></div><h3 class="subj">Reading the new ED memo together?</h3><p class="prev">Want to do a joint statement if it lands the way we think.</p><div class="chips"><span class="ch">partners</span></div></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v21-cyberpunk-rain.html b/public/mockups/inbox/v21-cyberpunk-rain.html
new file mode 100644
index 0000000..8897f60
--- /dev/null
+++ b/public/mockups/inbox/v21-cyberpunk-rain.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v21 — Cyberpunk Rain — Norma Inbox</title>
+<style>
+  :root { --bg:#000; --panel:#0a0a14; --el:#10101e; --fg:#00ff41; --muted:#3a8a4a; --line:#143514; --hot:#ff003c; --ice:#00d4ff; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:13px/1.5 "Berkeley Mono", "Share Tech Mono", "JetBrains Mono", ui-monospace, monospace; min-height:100vh; }
+  body::before { content:""; position:fixed; inset:0; background:linear-gradient(transparent 0px, transparent 1px, rgba(0,255,65,0.03) 2px, transparent 3px); pointer-events:none; z-index:0; }
+  body > * { position:relative; z-index:1; }
+  .top { padding:14px 24px; border-bottom:1px solid var(--fg); display:flex; gap:14px; align-items:center; background:linear-gradient(180deg, rgba(0,255,65,0.05), transparent); }
+  .top h1 { margin:0; font-size:15px; font-weight:700; letter-spacing:0.15em; flex:1; text-transform:uppercase; }
+  .top h1::before { content:"// "; color:var(--hot); }
+  .top h1::after { content:" //"; color:var(--hot); }
+  .pill { font-size:11px; padding:5px 12px; background:transparent; border:1px solid var(--fg); color:var(--fg); cursor:pointer; text-transform:uppercase; letter-spacing:0.1em; }
+  .pill.on { background:var(--fg); color:var(--bg); }
+  .pill.hot { border-color:var(--hot); color:var(--hot); }
+  .list { padding:14px 24px; }
+  .row { padding:8px 14px; display:grid; grid-template-columns:30px 1fr 100px 50px; gap:12px; align-items:center; cursor:pointer; border-bottom:1px dashed var(--line); }
+  .row:hover { background:rgba(0,255,65,0.04); }
+  .row.on { background:rgba(255,0,60,0.08); border-left:3px solid var(--hot); padding-left:11px; }
+  .row .id { color:var(--muted); }
+  .from { font-weight:700; }
+  .subj { color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+  .subj strong { color:var(--fg); font-weight:400; }
+  .row.on .subj strong { color:var(--hot); }
+  .chip { padding:1px 7px; border:1px solid var(--fg); font-size:10px; text-transform:uppercase; letter-spacing:0.08em; }
+  .chip.hot { color:var(--hot); border-color:var(--hot); }
+  .when { color:var(--muted); text-align:right; font-size:11.5px; }
+  /* expand */
+  .expand { padding:18px 22px 22px; background:var(--panel); border:1px solid var(--hot); margin:8px 0; box-shadow:0 0 20px rgba(255,0,60,0.2); }
+  .expand h2 { margin:0 0 4px; font-size:18px; font-weight:700; letter-spacing:0.04em; color:var(--hot); }
+  .expand h2::before { content:"[ "; color:var(--ice); }
+  .expand h2::after { content:" ]"; color:var(--ice); }
+  .meta-block { font-size:12.5px; line-height:1.8; margin:14px 0 14px; padding:10px 0; border-top:1px solid var(--fg); border-bottom:1px solid var(--fg); }
+  .meta-block .k { color:var(--muted); display:inline-block; min-width:110px; }
+  .meta-block .k::before { content:"$ "; color:var(--ice); }
+  select.assign { background:var(--bg); color:var(--fg); border:1px solid var(--fg); padding:2px 8px; font:12px inherit; }
+  .seen-pill { display:inline-block; padding:1px 7px; border:1px solid var(--ice); color:var(--ice); margin-right:5px; font-size:11.5px; }
+  .body { background:var(--bg); border:1px solid var(--line); padding:12px 14px; font-size:13px; line-height:1.65; color:#9affb0; }
+  .body::before { content:"--- payload begin ---\A"; color:var(--muted); white-space:pre; font-size:10.5px; }
+  .body::after { content:"\A--- payload end ---"; color:var(--muted); white-space:pre; font-size:10.5px; }
+  textarea { width:100%; background:var(--bg); border:1px solid var(--fg); color:var(--fg); font:13px/1.55 inherit; padding:9px 12px; resize:vertical; min-height:90px; margin-top:8px; }
+  .act { display:flex; gap:8px; margin-top:10px; }
+  .btn { font:11.5px inherit; padding:5px 14px; background:transparent; border:1px solid var(--fg); color:var(--fg); cursor:pointer; text-transform:uppercase; letter-spacing:0.08em; font-weight:700; }
+  .btn:hover { background:var(--fg); color:var(--bg); }
+  .btn.pri { border-color:var(--hot); color:var(--hot); margin-left:auto; }
+  .btn.pri:hover { background:var(--hot); color:var(--bg); }
+</style>
+</head><body>
+<div class="top"><h1>norma.inbox</h1><span class="pill on">all</span><span class="pill">unread</span><span class="pill">mine</span><button class="pill hot">↻ sync</button></div>
+<div class="list">
+  <div class="row"><span class="id">001</span><div><div class="from">sanders.senate.gov</div><div class="subj"><strong>RE: markup tomorrow — borrower bill</strong></div></div><span class="chip">policy</span><span class="when">14m</span></div>
+  <div class="row on"><span class="id">002</span><div><div class="from">erica@washpost.com</div><div class="subj"><strong>quote_request_pslf_guidance.txt</strong></div></div><span class="chip hot">PRESS</span><span class="when">42m</span></div>
+  <div class="expand">
+    <h2>quote_request_pslf_guidance.txt</h2>
+    <div class="meta-block">
+      <div><span class="k">from</span> Erica Werner &lt;erica@washpost.com&gt;</div>
+      <div><span class="k">owner</span> <select class="assign"><option>natalia.admin</option><option>cody.staff</option><option>jess.intern</option></select></div>
+      <div><span class="k">seen_by[2]</span><span class="seen-pill">✓ natalia · 3:21</span><span class="seen-pill">✓ cody · 3:24</span></div>
+      <div><span class="k">priority</span> <span style="color:var(--hot)">HIGH</span></div>
+    </div>
+    <div class="body">Hi Natalia — story for tomorrow on PSLF buyback. 20 min by 4pm ET.
+1) Borrowers in months 100–120 — meaningful benefit, or buyback wipes it?
+2) SDCC data on 100–120 window?
+— Erica</div>
+    <textarea>$ reply --tone professional
+Hi Erica — call at 3:45pm ET. Our cohort: ~12k PSLF, 23% in 100–120 window. Buyback wipes gain above income cap. — N</textarea>
+    <div class="act"><button class="btn">copy</button><button class="btn">save</button><button class="btn pri">▶ exec send</button></div>
+  </div>
+  <div class="row"><span class="id">003</span><div><div class="from">astra@debtcollective.org</div><div class="subj">reading the new ed memo together?</div></div><span class="chip">partner</span><span class="when">2h</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v22-bauhaus.html b/public/mockups/inbox/v22-bauhaus.html
new file mode 100644
index 0000000..ae4a8a8
--- /dev/null
+++ b/public/mockups/inbox/v22-bauhaus.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v22 — Bauhaus — Norma Inbox</title>
+<style>
+  :root { --bg:#f4f0e6; --panel:#fff; --el:#ece6d4; --fg:#1a1a1a; --muted:#666; --line:#1a1a1a; --red:#e63946; --blue:#1d4ed8; --yellow:#fde047; --black:#000; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.55 "Futura", "Avenir Next", "Helvetica Neue", sans-serif; }
+  .top { padding:24px 32px; background:var(--yellow); border-bottom:4px solid var(--black); display:flex; gap:18px; align-items:center; position:relative; }
+  .top::after { content:""; position:absolute; right:32px; top:24px; width:48px; height:48px; border-radius:50%; background:var(--red); }
+  .top h1 { margin:0; font-size:30px; font-weight:900; letter-spacing:-0.02em; flex:1; text-transform:lowercase; }
+  .pill { padding:6px 14px; background:var(--bg); border:2px solid var(--black); color:var(--black); cursor:pointer; font-weight:700; font-size:12px; text-transform:lowercase; }
+  .pill.on { background:var(--blue); color:#fff; border-color:var(--blue); }
+  .list { padding:0; }
+  .row { padding:18px 32px; border-bottom:2px solid var(--black); cursor:pointer; display:grid; grid-template-columns:54px 1fr 120px 80px; gap:18px; align-items:center; }
+  .row:hover { background:var(--el); }
+  .row.on { background:var(--bg); }
+  .shape { width:42px; height:42px; flex-shrink:0; }
+  .shape.circle { border-radius:50%; background:var(--red); }
+  .shape.square { background:var(--blue); }
+  .shape.triangle { width:0; height:0; border-left:21px solid transparent; border-right:21px solid transparent; border-bottom:42px solid var(--yellow); background:transparent; }
+  .from { font-weight:700; font-size:16px; }
+  .subj { font-size:13.5px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+  .row.on .subj { color:var(--fg); }
+  .chip { font-size:10.5px; padding:3px 9px; background:var(--black); color:#fff; font-weight:700; text-transform:lowercase; display:inline-block; }
+  .chip.red { background:var(--red); }
+  .chip.blue { background:var(--blue); }
+  .chip.yellow { background:var(--yellow); color:var(--black); }
+  .when { text-align:right; font-weight:700; font-family:"Futura", "Avenir Next", sans-serif; font-size:14px; }
+  /* expand */
+  .expand { padding:32px 36px; background:var(--bg); border-bottom:4px solid var(--black); position:relative; }
+  .expand::before { content:""; position:absolute; left:0; top:0; bottom:0; width:8px; background:var(--red); }
+  .expand h2 { margin:0; font-size:32px; font-weight:900; letter-spacing:-0.02em; line-height:1.1; text-transform:lowercase; }
+  .meta-strip { padding:16px 0; border-top:2px solid var(--black); border-bottom:2px solid var(--black); margin:18px 0 22px; display:grid; grid-template-columns:90px 1fr; gap:6px 14px; font-size:13px; }
+  .meta-strip > span:nth-child(odd) { font-weight:900; text-transform:lowercase; font-size:11px; letter-spacing:0.06em; padding-top:3px; }
+  select.assign { background:var(--panel); color:var(--fg); border:2px solid var(--black); padding:4px 10px; font:13px inherit; font-weight:700; }
+  .seen-pill { padding:3px 9px; background:var(--blue); color:#fff; font-weight:700; font-size:11px; margin-right:5px; text-transform:lowercase; display:inline-block; }
+  .body { font-size:15.5px; line-height:1.7; max-width:580px; }
+  textarea { width:100%; background:var(--panel); border:2px solid var(--black); color:var(--fg); padding:12px 14px; font:14px/1.6 inherit; resize:vertical; min-height:100px; max-width:580px; }
+  .act { display:flex; gap:10px; margin-top:14px; max-width:580px; }
+  .btn { font:12.5px inherit; padding:10px 24px; background:var(--panel); border:2px solid var(--black); color:var(--fg); cursor:pointer; font-weight:900; text-transform:lowercase; }
+  .btn.pri { background:var(--red); color:#fff; border:none; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>inbox</h1><span class="pill on">all</span><span class="pill">unread</span><span class="pill">mine</span><button class="pill" style="background:var(--red);color:#fff;border-color:var(--red)">↻ sync</button></div>
+<div class="list">
+  <div class="row"><div class="shape circle"></div><div><div class="from">sen. bernie sanders office</div><div class="subj">RE: markup tomorrow — borrower bill. quick call before 9am ET.</div></div><div><span class="chip blue">policy</span></div><span class="when">14m</span></div>
+  <div class="row on"><div class="shape square"></div><div><div class="from">erica werner · washington post</div><div class="subj">quote request — PSLF guidance.</div></div><div><span class="chip red">press</span></div><span class="when">42m</span></div>
+  <div class="expand">
+    <h2>quote request — pslf guidance</h2>
+    <div class="meta-strip">
+      <span>from</span><span><strong>Erica Werner</strong> · Washington Post · 3:18 PM</span>
+      <span>owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+      <span>seen by</span><span><span class="seen-pill">✓ natalia · 3:21</span><span class="seen-pill">✓ cody · 3:24</span></span>
+    </div>
+    <div class="body">Hi Natalia — running a piece tomorrow on the new PSLF buyback guidance. Two questions if you have 20 min by 4pm ET:<br><br>1) Borrowers in months 100–120 — meaningful benefit, or buyback wipes?<br>2) SDCC data on the 100–120 window?<br>— Erica</div>
+    <textarea>Hi Erica — call at 3:45pm ET. Our cohort: ~12k PSLF, 23% in 100–120. Buyback wipes gain above income cap. — Natalia</textarea>
+    <div class="act"><button class="btn">copy</button><button class="btn">save</button><button class="btn pri">send →</button></div>
+  </div>
+  <div class="row"><div class="shape triangle"></div><div><div class="from">astra taylor · debt collective</div><div class="subj">reading the new ED memo together?</div></div><div><span class="chip yellow">partners</span></div><span class="when">2h</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v23-memphis.html b/public/mockups/inbox/v23-memphis.html
new file mode 100644
index 0000000..2040758
--- /dev/null
+++ b/public/mockups/inbox/v23-memphis.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v23 — Memphis 80s — Norma Inbox</title>
+<style>
+  :root { --bg:#f5f4eb; --panel:#fff; --el:#fff2d4; --fg:#1a1a26; --muted:#5e5e6e; --line:#1a1a26; --pink:#ff5fa2; --teal:#1ec5c5; --yellow:#ffd23f; --black:#1a1a26; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.55 "Futura", "Avenir Next", sans-serif; background-image:
+    radial-gradient(circle, var(--black) 1.5px, transparent 1.5px),
+    radial-gradient(circle, var(--black) 1.5px, transparent 1.5px);
+    background-position:0 0, 18px 18px; background-size:36px 36px; }
+  .top { padding:20px 28px; background:var(--bg); border-bottom:3px solid var(--black); display:flex; gap:14px; align-items:center; position:relative; }
+  .top h1 { margin:0; font-size:28px; font-weight:900; letter-spacing:-0.01em; flex:1; transform:rotate(-1deg); transform-origin:left; }
+  .top h1 span { color:var(--pink); }
+  .pill { padding:6px 14px; background:var(--panel); border:2.5px solid var(--black); color:var(--fg); cursor:pointer; font-weight:700; font-size:12px; box-shadow:3px 3px 0 var(--black); transition:transform 0.1s; }
+  .pill:hover { transform:translate(1px, 1px); box-shadow:2px 2px 0 var(--black); }
+  .pill.on { background:var(--yellow); }
+  .list { padding:24px 28px 60px; }
+  .row { padding:14px 18px; background:var(--panel); border:2.5px solid var(--black); margin:0 0 10px; cursor:pointer; display:grid; grid-template-columns:42px 1fr 120px 70px; gap:14px; align-items:center; box-shadow:5px 5px 0 var(--black); transition:transform 0.12s, box-shadow 0.12s; }
+  .row:hover { transform:translate(2px,2px); box-shadow:3px 3px 0 var(--black); }
+  .row.on { background:var(--el); transform:translate(2px,2px); box-shadow:3px 3px 0 var(--pink); border-color:var(--pink); }
+  .ava { width:36px; height:36px; border:2.5px solid var(--black); display:flex; align-items:center; justify-content:center; font-weight:900; font-size:13.5px; }
+  .ava.pink { background:var(--pink); color:#fff; }
+  .ava.teal { background:var(--teal); color:#fff; border-radius:50%; }
+  .ava.yellow { background:var(--yellow); color:var(--black); transform:rotate(45deg); }
+  .ava.yellow span { display:block; transform:rotate(-45deg); }
+  .from { font-weight:800; font-size:14.5px; }
+  .subj { font-size:13px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+  .chip { padding:2px 8px; border:2px solid var(--black); background:var(--yellow); font-size:10.5px; font-weight:800; text-transform:uppercase; letter-spacing:0.04em; display:inline-block; }
+  .chip.pink { background:var(--pink); color:#fff; }
+  .chip.teal { background:var(--teal); color:#fff; }
+  .when { font-size:11.5px; font-weight:700; text-align:right; }
+  /* expand */
+  .expand { padding:24px 26px 26px; background:var(--panel); border:3px solid var(--black); margin:14px 0; box-shadow:8px 8px 0 var(--pink); position:relative; }
+  .expand::before { content:""; position:absolute; top:-8px; left:-8px; width:48px; height:48px; background:var(--teal); border:3px solid var(--black); border-radius:50%; z-index:-1; }
+  .expand h2 { margin:0 0 4px; font-size:22px; font-weight:900; letter-spacing:-0.01em; line-height:1.2; }
+  .byline { color:var(--muted); font-size:13px; margin-bottom:12px; font-weight:600; }
+  .meta-grid { display:grid; grid-template-columns:90px 1fr; gap:6px 14px; font-size:13px; padding:12px 0; border-top:2px solid var(--black); border-bottom:2px solid var(--black); margin-bottom:16px; }
+  .meta-grid > span:nth-child(odd) { font-weight:900; text-transform:uppercase; font-size:11px; letter-spacing:0.06em; }
+  select.assign { background:var(--panel); border:2px solid var(--black); padding:4px 9px; font:13px inherit; font-weight:700; box-shadow:2px 2px 0 var(--black); }
+  .seen-pill { padding:2px 9px; background:var(--teal); color:#fff; border:2px solid var(--black); font-weight:800; font-size:11px; margin-right:5px; display:inline-block; }
+  .body { font-size:14.5px; line-height:1.7; padding:0 0 14px; }
+  textarea { width:100%; background:var(--el); border:2.5px solid var(--black); color:var(--fg); padding:11px 13px; font:13.5px/1.55 inherit; resize:vertical; min-height:90px; box-shadow:3px 3px 0 var(--black); }
+  .act { display:flex; gap:8px; margin-top:14px; }
+  .btn { font:12px inherit; padding:8px 18px; background:var(--panel); border:2.5px solid var(--black); color:var(--fg); cursor:pointer; font-weight:800; text-transform:uppercase; letter-spacing:0.04em; box-shadow:3px 3px 0 var(--black); }
+  .btn:hover { transform:translate(1px,1px); box-shadow:2px 2px 0 var(--black); }
+  .btn.pri { background:var(--pink); color:#fff; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>norma's <span>inbox</span></h1><span class="pill on">all</span><span class="pill">unread</span><span class="pill">mine</span><button class="pill" style="background:var(--teal);color:#fff">↻ sync</button></div>
+<div class="list">
+  <div class="row"><div class="ava pink">BS</div><div><div class="from">Sen. Bernie Sanders Office</div><div class="subj">RE: Markup tomorrow — borrower bill</div></div><span class="chip">policy</span><span class="when">14m</span></div>
+  <div class="row on"><div class="ava yellow"><span>EW</span></div><div><div class="from">Erica Werner · Washington Post</div><div class="subj">Quote request — PSLF guidance</div></div><span class="chip pink">press!</span><span class="when">42m</span></div>
+  <div class="expand">
+    <h2>Quote request — Dept of Ed PSLF guidance</h2>
+    <div class="byline">Erica Werner · Washington Post · 3:18 PM</div>
+    <div class="meta-grid">
+      <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+      <span>Seen by</span><span><span class="seen-pill">✓ Natalia</span><span class="seen-pill">✓ Cody</span></span>
+    </div>
+    <div class="body">Hi Natalia — story for tomorrow on PSLF buyback. 20 min by 4pm ET. Two Qs:<br>1) Borrowers in 100–120 months — meaningful benefit, or buyback wipes?<br>2) SDCC data on the 100–120 window?<br>— Erica</div>
+    <textarea>Hi Erica — call at 3:45pm ET. ~12k PSLF, 23% in 100–120. Buyback wipes the gain above income cap. — Natalia</textarea>
+    <div class="act"><button class="btn">copy</button><button class="btn">save</button><button class="btn pri">SEND IT →</button></div>
+  </div>
+  <div class="row"><div class="ava teal">AT</div><div><div class="from">Astra Taylor · Debt Collective</div><div class="subj">Reading the new ED memo together?</div></div><span class="chip teal">partners</span><span class="when">2h</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v24-vellum.html b/public/mockups/inbox/v24-vellum.html
new file mode 100644
index 0000000..78db744
--- /dev/null
+++ b/public/mockups/inbox/v24-vellum.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v24 — Vellum Manuscript — Norma Inbox</title>
+<style>
+  :root { --bg:#f7eed0; --panel:#fcf6dc; --el:#eadda3; --fg:#3a1f0c; --muted:#8a6840; --line:#c4a060; --red:#a8201a; --blue:#1a3e8a; --gold:#b8862c; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:15px/1.65 "Cormorant Garamond", "EB Garamond", "Iowan Old Style", Georgia, serif; min-height:100vh;
+    background-image:radial-gradient(circle at 15% 30%, rgba(184,134,44,0.05) 0%, transparent 40%), radial-gradient(circle at 85% 70%, rgba(168,32,26,0.04) 0%, transparent 40%); }
+  .top { padding:24px 32px; text-align:center; border-bottom:3px double var(--gold); }
+  .top h1 { margin:0; font-size:30px; font-weight:600; letter-spacing:0.05em; }
+  .top h1 .ill { color:var(--red); font-weight:700; }
+  .top .sub { font-style:italic; color:var(--muted); font-size:13px; margin-top:4px; letter-spacing:0.05em; }
+  .toolbar { padding:10px 32px; text-align:center; font-size:12px; letter-spacing:0.1em; text-transform:uppercase; color:var(--muted); border-bottom:1px solid var(--line); }
+  .toolbar span { margin:0 14px; cursor:pointer; }
+  .toolbar span.on { color:var(--fg); border-bottom:1px solid var(--fg); padding-bottom:2px; }
+  .grid { display:grid; grid-template-columns:1fr 2fr; gap:30px; padding:30px 36px; }
+  .list { border-right:1px solid var(--gold); padding-right:28px; }
+  .item { padding:14px 0; border-bottom:1px solid var(--line); cursor:pointer; }
+  .item:hover { background:rgba(184,134,44,0.05); margin:0 -8px; padding-left:8px; padding-right:8px; }
+  .item h3 { margin:0 0 4px; font-size:17px; font-weight:600; line-height:1.3; }
+  .item h3 .ill { color:var(--red); font-weight:700; font-size:24px; line-height:1; float:left; padding-right:6px; }
+  .item .by { font-style:italic; color:var(--muted); font-size:13px; }
+  .item .prev { margin:6px 0 0; font-size:13.5px; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
+  /* expanded "page" */
+  .feature .label { font-size:11px; letter-spacing:0.18em; text-transform:uppercase; color:var(--red); font-weight:700; margin-bottom:6px; }
+  .feature h2 { margin:0 0 6px; font-size:30px; font-weight:600; line-height:1.2; }
+  .feature h2 .ill { color:var(--blue); font-weight:700; font-size:48px; line-height:1; float:left; padding:0 10px 4px 0; font-family:"Cormorant Garamond", serif; }
+  .feature .byline { font-style:italic; font-size:14px; color:var(--muted); margin-bottom:14px; padding-bottom:14px; border-bottom:1px solid var(--line); }
+  .meta-strip { display:grid; grid-template-columns:90px 1fr; gap:5px 14px; font-size:13px; padding-bottom:18px; border-bottom:1px solid var(--line); margin-bottom:22px; }
+  .meta-strip > span:nth-child(odd) { color:var(--muted); font-style:italic; }
+  select.assign { background:var(--panel); border:1px solid var(--line); color:var(--fg); font:14px inherit; padding:3px 9px; font-family:inherit; }
+  .seen-pill { font-size:12.5px; padding:1px 9px; border:1px solid var(--gold); color:var(--gold); display:inline-block; margin-right:5px; font-style:italic; }
+  .body { font-size:16px; line-height:1.85; }
+  .body p { margin:0 0 16px; text-indent:1.6em; }
+  .body p:first-child { text-indent:0; }
+  .body p:first-child::first-letter { font-size:300%; font-weight:700; color:var(--blue); padding:8px 4px 0 0; float:left; line-height:0.85; font-family:"Cormorant Garamond", serif; }
+  .reply { margin-top:24px; padding-top:18px; border-top:3px double var(--gold); }
+  .reply label { font-size:11px; letter-spacing:0.15em; text-transform:uppercase; color:var(--red); font-weight:700; }
+  textarea { width:100%; background:var(--panel); border:1px solid var(--line); padding:14px 16px; font:15px/1.7 inherit; resize:vertical; min-height:100px; margin-top:8px; color:var(--fg); }
+  .act { display:flex; gap:14px; margin-top:14px; }
+  .btn { font:12.5px inherit; padding:7px 16px; background:transparent; border:1px solid var(--fg); color:var(--fg); cursor:pointer; text-transform:uppercase; letter-spacing:0.1em; font-weight:600; }
+  .btn.pri { background:var(--red); border-color:var(--red); color:var(--bg); margin-left:auto; font-weight:700; }
+</style>
+</head><body>
+<div class="top"><h1><span class="ill">N</span>orma · <span class="ill">C</span>orrespondence</h1><div class="sub">Anno Domini · MMXXVI · Maius XX</div></div>
+<div class="toolbar"><span class="on">Whole Inbox</span><span>Unread</span><span>Mine</span><span>↻ Sync</span></div>
+<div class="grid">
+  <div class="list">
+    <div class="item"><h3><span class="ill">¶</span>Markup forward, call at dawn</h3><div class="by">Sen. Bernie Sanders Office · 14m</div><p class="prev">Senator can do a quick call before 9am ET. Aide on this thread.</p></div>
+    <div class="item"><h3><span class="ill">¶</span>Joint statement, perhaps?</h3><div class="by">Astra Taylor · 2h</div><p class="prev">Want to do a joint statement if the ED memo lands the way we think.</p></div>
+    <div class="item"><h3><span class="ill">¶</span>A borrower's tale</h3><div class="by">Marcus Huang · 1d</div><p class="prev">Saw your work on PBS NewsHour. I'd like to share my story.</p></div>
+  </div>
+  <div class="feature">
+    <div class="label">Press · The Lead Petition</div>
+    <h2><span class="ill">Q</span>uote request — Dept. of Ed. PSLF Guidance</h2>
+    <div class="byline">By <strong>Erica Werner</strong>, of the Washington Post · this 20 May at 3:18 hours post meridiem</div>
+    <div class="meta-strip">
+      <span>Owner</span><span><select class="assign"><option>Natalia Abrams (admin)</option><option>Cody Lin (staff)</option><option>Jess Park (intern)</option></select></span>
+      <span>Seen by</span><span><span class="seen-pill">✦ Natalia · 3:21</span><span class="seen-pill">✦ Cody · 3:24</span></span>
+      <span>Priority</span><span><em>High — same-day deadline</em></span>
+    </div>
+    <div class="body">
+      <p>Honored Madam — Running a piece on the morrow concerning the new PSLF buyback guidance, which came out this morning. Two questions, if twenty minutes might be granted before four post meridiem.</p>
+      <p>First, your read on whether borrowers between months 100 and 120 of payment receive meaningful benefit, or whether the buyback math wipes it out. Second, any data points from SDCC on how many borrowers are caught in this 100–120 window.</p>
+      <p>Most gratefully, — Erica</p>
+    </div>
+    <div class="reply">
+      <label>Reply — Manuscript</label>
+      <textarea>Madam Werner — happy to assist. A brief call at three quarters past three, post meridiem; the number will follow by message. Of our cohort: some 12,000 PSLF borrowers, of which 23 in the hundred sit in the 100–120 window. The buyback math wipes the gain above the income cap, a known design flaw worth surfacing. — N. Abrams</textarea>
+      <div class="act"><button class="btn">Transcribe</button><button class="btn">Save</button><button class="btn pri">Dispatch ⟶</button></div>
+    </div>
+  </div>
+</div></body></html>
diff --git a/public/mockups/inbox/v25-solarpunk.html b/public/mockups/inbox/v25-solarpunk.html
new file mode 100644
index 0000000..cb7fd2f
--- /dev/null
+++ b/public/mockups/inbox/v25-solarpunk.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v25 — Solarpunk — Norma Inbox</title>
+<style>
+  :root { --bg:#f0ead2; --panel:#fffbeb; --el:#e0e0bc; --fg:#1f3320; --muted:#5d7553; --line:#90a878; --sage:#578a4a; --sun:#e5a630; --sky:#7eb8d4; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14.5px/1.6 "Quattrocento Sans", "Open Sans", -apple-system, sans-serif; min-height:100vh;
+    background-image:radial-gradient(circle at 10% 100%, rgba(126,184,212,0.15) 0%, transparent 50%), radial-gradient(circle at 90% 0%, rgba(229,166,48,0.15) 0%, transparent 50%); }
+  .top { padding:18px 28px; background:linear-gradient(180deg, rgba(229,166,48,0.15), transparent); border-bottom:1px solid var(--sage); display:flex; gap:14px; align-items:center; }
+  .top h1 { margin:0; font-size:24px; font-weight:600; flex:1; letter-spacing:-0.005em; color:var(--sage); }
+  .top h1::before { content:"☘ "; color:var(--sun); }
+  .pill { font-size:12px; padding:6px 14px; border-radius:999px; background:transparent; border:1.5px solid var(--sage); color:var(--sage); cursor:pointer; font-weight:600; }
+  .pill.on { background:var(--sage); color:#fff; }
+  .pill.sun { background:var(--sun); border-color:var(--sun); color:#fff; }
+  .stack { padding:20px 28px 60px; display:flex; flex-direction:column; gap:10px; max-width:880px; margin:0 auto; }
+  .card { background:var(--panel); border-radius:16px; padding:16px 20px; border:1px solid var(--line); cursor:pointer; transition:transform 0.15s, box-shadow 0.15s; }
+  .card:hover { transform:translateY(-1px); box-shadow:0 6px 18px rgba(87,138,74,0.12); }
+  .card.on { border-color:var(--sun); border-width:1.5px; box-shadow:0 6px 24px rgba(229,166,48,0.18); }
+  .meta { display:flex; gap:10px; align-items:center; font-size:12.5px; color:var(--muted); margin-bottom:4px; }
+  .ava { width:32px; height:32px; border-radius:50%; background:linear-gradient(135deg, var(--sage), var(--sun)); color:#fff; display:flex; align-items:center; justify-content:center; font-weight:700; font-size:12.5px; }
+  .name { color:var(--fg); font-weight:700; font-size:14px; }
+  .when { margin-left:auto; }
+  .subj { font-size:15.5px; font-weight:600; margin:2px 0; }
+  .prev { font-size:13.5px; color:var(--muted); overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
+  .chips { display:flex; gap:5px; margin-top:8px; flex-wrap:wrap; }
+  .chip { font-size:10.5px; padding:2px 9px; border-radius:999px; font-weight:600; }
+  .c-press { background:rgba(229,166,48,0.2); color:#a87016; }
+  .c-policy { background:rgba(126,184,212,0.25); color:#3d6e88; }
+  .c-partner { background:rgba(87,138,74,0.2); color:var(--sage); }
+  .c-assign { background:var(--el); color:var(--fg); display:inline-flex; gap:4px; align-items:center; padding-left:3px; }
+  .c-seen { background:rgba(87,138,74,0.18); color:var(--sage); }
+  .mini { width:18px; height:18px; border-radius:50%; background:var(--sage); color:#fff; font-size:9.5px; display:flex; align-items:center; justify-content:center; font-weight:700; }
+  /* expand */
+  .expand { padding:22px 24px 24px; }
+  .expand h2 { margin:0 0 4px; font-size:22px; font-weight:600; line-height:1.3; }
+  .meta-grid { display:grid; grid-template-columns:80px 1fr; gap:5px 14px; font-size:13px; margin:14px 0 18px; color:var(--muted); }
+  .meta-grid strong { color:var(--fg); font-weight:600; }
+  select.assign { background:var(--bg); border:1.5px solid var(--line); color:var(--fg); font:13px inherit; padding:4px 11px; border-radius:999px; font-weight:600; }
+  .seen-pill { font-size:12px; padding:2px 10px; border-radius:999px; background:rgba(87,138,74,0.2); color:var(--sage); display:inline-flex; gap:4px; align-items:center; font-weight:600; margin-right:5px; }
+  .body { background:var(--el); border-radius:12px; padding:16px 18px; font-size:14.5px; line-height:1.7; }
+  .ai { margin-top:14px; padding:16px 18px; border-radius:12px; background:linear-gradient(135deg, rgba(229,166,48,0.1), rgba(87,138,74,0.1)); border:1px solid var(--line); }
+  .ai h4 { margin:0 0 8px; font-size:13px; font-weight:700; color:var(--sage); display:flex; align-items:center; gap:6px; }
+  textarea { width:100%; background:var(--panel); border:1.5px solid var(--line); color:var(--fg); padding:11px 14px; border-radius:10px; font:13.5px inherit; resize:vertical; min-height:90px; }
+  .act { display:flex; gap:8px; margin-top:12px; }
+  .btn { font:12.5px inherit; padding:7px 16px; border-radius:999px; background:var(--panel); border:1.5px solid var(--line); color:var(--fg); cursor:pointer; font-weight:600; }
+  .btn.pri { background:var(--sage); border-color:var(--sage); color:#fff; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>Grove · Inbox</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><button class="pill sun">↻ Sync</button></div>
+<div class="stack">
+  <div class="card"><div class="meta"><div class="ava">BS</div><span class="name">Sen. Bernie Sanders Office</span><span class="when">14m ago</span></div><div class="subj">RE: Markup tomorrow — borrower bill</div><div class="prev">Senator can do a quick call before 9am ET.</div><div class="chips"><span class="chip c-policy">policy</span><span class="chip c-assign"><span class="mini">N</span> Natalia</span></div></div>
+  <div class="card on"><div class="meta"><div class="ava" style="background:linear-gradient(135deg, var(--sun), #c47611)">EW</div><span class="name">Erica Werner · Washington Post</span><span class="when">42m ago</span></div><div class="subj">Quote request — PSLF guidance</div><div class="prev">Hi Natalia — running a story for tomorrow.</div><div class="chips"><span class="chip c-press">press</span><span class="chip c-seen">☘ Seen ×2</span></div>
+    <div class="expand">
+      <h2>Quote request — Dept of Ed PSLF guidance</h2>
+      <div class="meta-grid">
+        <span>From</span><strong>Erica Werner · Washington Post · 3:18 PM</strong>
+        <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+        <span>Seen by</span><span><span class="seen-pill">☘ Natalia · 3:21</span><span class="seen-pill">☘ Cody · 3:24</span></span>
+      </div>
+      <div class="body">Hi Natalia — story for tomorrow on PSLF buyback. 20 min by 4pm ET. 1) Borrowers in 100–120 months — meaningful benefit, or buyback wipes? 2) SDCC data on the 100–120 window? — Erica</div>
+      <div class="ai"><h4>☘ Suggested reply</h4>
+      <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET. Our cohort: ~12k PSLF, 23% in 100–120. Buyback wipes the gain above income cap. — Natalia</textarea>
+      <div class="act"><button class="btn">Copy</button><button class="btn">Save Draft</button><button class="btn pri">Send →</button></div></div>
+    </div>
+  </div>
+  <div class="card"><div class="meta"><div class="ava" style="background:linear-gradient(135deg, var(--sky), #4f8aa8)">AT</div><span class="name">Astra Taylor · Debt Collective</span><span class="when">2h ago</span></div><div class="subj">Reading the new ED memo together?</div><div class="prev">Want to do a joint statement if it lands.</div><div class="chips"><span class="chip c-partner">partners</span><span class="chip c-assign"><span class="mini" style="background:var(--sun)">C</span> Cody</span></div></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v26-frutiger-aero.html b/public/mockups/inbox/v26-frutiger-aero.html
new file mode 100644
index 0000000..6021f6e
--- /dev/null
+++ b/public/mockups/inbox/v26-frutiger-aero.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v26 — Frutiger Aero — Norma Inbox</title>
+<style>
+  :root { --bg:#d6edff; --panel:#fff; --el:#eaf4ff; --fg:#1c3a5c; --muted:#5e7a98; --line:#a8c8e8; --aqua:#34b5e8; --bubble:#88d8ff; --green:#5cd86a; --orange:#ff9933; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.5 "Segoe UI", "Frutiger", -apple-system, sans-serif; min-height:100vh;
+    background-image:linear-gradient(180deg, #b8e0ff 0%, #d6edff 40%, #f4f9ff 100%); }
+  .top { padding:14px 24px; background:linear-gradient(180deg, rgba(255,255,255,0.85), rgba(255,255,255,0.65)); backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px); border-bottom:1px solid var(--line); display:flex; gap:12px; align-items:center; box-shadow:0 2px 8px rgba(28,58,92,0.08); }
+  .top h1 { margin:0; font-size:22px; font-weight:600; flex:1; letter-spacing:-0.02em;
+    background:linear-gradient(180deg, #4a8ad4, #1c3a5c); -webkit-background-clip:text; background-clip:text; color:transparent; }
+  .pill { font-size:12px; padding:7px 16px; border-radius:999px; background:linear-gradient(180deg, #fff, #d8e8f4); border:1px solid var(--line); color:var(--fg); cursor:pointer; font-weight:600; box-shadow:inset 0 1px 0 rgba(255,255,255,0.8), 0 1px 2px rgba(28,58,92,0.1); }
+  .pill.on { background:linear-gradient(180deg, var(--bubble), var(--aqua)); border-color:var(--aqua); color:#fff; }
+  .pill.go { background:linear-gradient(180deg, #88e88c, var(--green)); border-color:var(--green); color:#fff; }
+  .list { padding:18px 24px 60px; max-width:920px; margin:0 auto; }
+  .row { display:grid; grid-template-columns:42px 1fr 130px 70px; gap:14px; padding:14px 18px; background:linear-gradient(180deg, rgba(255,255,255,0.9), rgba(234,244,255,0.7)); border:1px solid var(--line); border-radius:12px; margin-bottom:8px; cursor:pointer; align-items:center; backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px); box-shadow:inset 0 1px 0 rgba(255,255,255,0.9), 0 2px 6px rgba(28,58,92,0.06); transition:transform 0.15s; }
+  .row:hover { transform:translateY(-1px); }
+  .row.on { background:linear-gradient(180deg, rgba(136,216,255,0.4), rgba(52,181,232,0.2)); border-color:var(--aqua); }
+  .orb { width:34px; height:34px; border-radius:50%; background:radial-gradient(circle at 30% 25%, #fff, var(--aqua) 50%, #1a6094); position:relative; }
+  .orb::after { content:""; position:absolute; top:3px; left:5px; width:10px; height:6px; background:rgba(255,255,255,0.7); border-radius:50%; }
+  .orb.green { background:radial-gradient(circle at 30% 25%, #fff, var(--green) 50%, #1a8024); }
+  .orb.orange { background:radial-gradient(circle at 30% 25%, #fff, var(--orange) 50%, #aa6010); }
+  .from { font-weight:700; font-size:14.5px; }
+  .subj { font-size:13px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+  .subj strong { color:var(--fg); font-weight:600; }
+  .chip { font-size:10.5px; padding:2px 9px; border-radius:999px; background:linear-gradient(180deg, #fff, #d8e8f4); border:1px solid var(--line); font-weight:700; display:inline-block; }
+  .chip.aqua { background:linear-gradient(180deg, var(--bubble), var(--aqua)); color:#fff; border:none; }
+  .chip.green { background:linear-gradient(180deg, #88e88c, var(--green)); color:#fff; border:none; }
+  .when { font-size:11.5px; color:var(--muted); text-align:right; }
+  /* expand */
+  .expand { padding:20px 24px 24px; background:linear-gradient(180deg, rgba(255,255,255,0.95), rgba(234,244,255,0.85)); border-radius:14px; border:1px solid var(--aqua); margin:10px 0; backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px); box-shadow:0 8px 24px rgba(52,181,232,0.2); }
+  .expand h2 { margin:0 0 4px; font-size:22px; font-weight:700; line-height:1.25; color:var(--fg); }
+  .meta-grid { display:grid; grid-template-columns:80px 1fr; gap:6px 14px; font-size:13px; padding:12px 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); margin:14px 0; color:var(--muted); }
+  .meta-grid strong { color:var(--fg); }
+  select.assign { background:linear-gradient(180deg, #fff, #e8f0fc); border:1px solid var(--line); color:var(--fg); font:13px inherit; padding:4px 11px; border-radius:8px; font-weight:600; }
+  .seen-pill { font-size:11.5px; padding:2px 10px; border-radius:999px; background:linear-gradient(180deg, #88e88c, var(--green)); color:#fff; display:inline-flex; gap:4px; align-items:center; font-weight:700; margin-right:5px; }
+  .body { background:var(--bg); border-radius:10px; padding:14px 16px; font-size:14px; line-height:1.65; border:1px solid var(--line); }
+  textarea { width:100%; background:#fff; border:1px solid var(--line); color:var(--fg); padding:11px 14px; border-radius:10px; font:13.5px inherit; resize:vertical; min-height:90px; box-shadow:inset 0 2px 4px rgba(28,58,92,0.06); }
+  .act { display:flex; gap:8px; margin-top:12px; }
+  .btn { font:13px inherit; padding:9px 22px; border-radius:999px; background:linear-gradient(180deg, #fff, #d8e8f4); border:1px solid var(--line); color:var(--fg); cursor:pointer; font-weight:700; box-shadow:inset 0 1px 0 rgba(255,255,255,0.9), 0 2px 4px rgba(28,58,92,0.1); }
+  .btn.pri { background:linear-gradient(180deg, var(--bubble), var(--aqua)); border-color:var(--aqua); color:#fff; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>◯ Inbox</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><button class="pill go">↻ Sync</button></div>
+<div class="list">
+  <div class="row"><div class="orb green"></div><div><div class="from">Sen. Bernie Sanders Office</div><div class="subj"><strong>RE: Markup tomorrow — borrower bill</strong></div></div><span class="chip aqua">policy</span><span class="when">14m</span></div>
+  <div class="row on"><div class="orb orange"></div><div><div class="from">Erica Werner · Washington Post</div><div class="subj"><strong>Quote request — PSLF guidance</strong></div></div><span class="chip" style="background:linear-gradient(180deg, #ffb060, var(--orange));color:#fff;border:none">press</span><span class="when">42m</span></div>
+  <div class="expand">
+    <h2>Quote request — PSLF guidance</h2>
+    <div class="meta-grid">
+      <span>From</span><strong>Erica Werner · Washington Post · 3:18 PM</strong>
+      <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+      <span>Seen by</span><span><span class="seen-pill">✓ Natalia</span><span class="seen-pill">✓ Cody</span></span>
+    </div>
+    <div class="body">Hi Natalia — story for tomorrow on PSLF buyback. 20 min by 4pm ET. 1) Borrowers in 100–120 months — meaningful benefit, or buyback wipes? 2) SDCC data on the 100–120 window? — Erica</div>
+    <div style="margin-top:14px"><div style="font-size:11.5px;font-weight:700;color:var(--aqua);text-transform:uppercase;letter-spacing:0.08em;margin-bottom:6px">◇ AI suggested reply</div>
+    <textarea>Hi Erica — call at 3:45pm ET. Our cohort: ~12k PSLF, 23% in 100–120. Buyback wipes the gain above income cap. — Natalia</textarea>
+    <div class="act"><button class="btn">Copy</button><button class="btn">Save Draft</button><button class="btn pri">Send ▸</button></div></div>
+  </div>
+  <div class="row"><div class="orb"></div><div><div class="from">Astra Taylor · Debt Collective</div><div class="subj">Reading the new ED memo together?</div></div><span class="chip green">partners</span><span class="when">2h</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v27-crossword.html b/public/mockups/inbox/v27-crossword.html
new file mode 100644
index 0000000..ceee242
--- /dev/null
+++ b/public/mockups/inbox/v27-crossword.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v27 — Crossword Grid — Norma Inbox</title>
+<style>
+  :root { --bg:#fff; --panel:#fff; --el:#f2f2f2; --fg:#000; --muted:#666; --line:#000; --blue:#1856ad; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.45 "Courier Prime", "Courier New", "American Typewriter", monospace; }
+  .top { padding:14px 22px; border-bottom:3px solid var(--fg); display:flex; gap:14px; align-items:center; }
+  .top h1 { margin:0; font-size:24px; font-weight:900; letter-spacing:0.04em; flex:1; text-transform:uppercase; }
+  .pill { font-size:11px; padding:4px 10px; border:2px solid var(--fg); background:transparent; color:var(--fg); cursor:pointer; text-transform:uppercase; font-weight:700; letter-spacing:0.08em; }
+  .pill.on { background:var(--fg); color:#fff; }
+  .pill.blue { border-color:var(--blue); color:var(--blue); }
+  .pill.blue.on { background:var(--blue); color:#fff; }
+  .list { padding:0; }
+  .row { display:grid; grid-template-columns:48px 1fr 130px 60px; gap:0; padding:0; align-items:stretch; cursor:pointer; border-bottom:2px solid var(--fg); }
+  .row > * { padding:14px 14px; border-right:2px solid var(--fg); }
+  .row > *:last-child { border-right:none; }
+  .row:hover { background:var(--el); }
+  .row.on { background:#fffacc; }
+  .row .id { background:var(--fg); color:#fff; font-weight:900; font-size:16px; display:flex; align-items:center; justify-content:center; }
+  .row .id::after { content:""; }
+  .row.acr .id { background:var(--blue); }
+  .from { font-weight:700; font-size:15px; }
+  .subj { font-size:13px; color:var(--muted); margin-top:2px; }
+  .subj strong { color:var(--fg); font-weight:400; }
+  .meta-r { display:flex; align-items:center; font-size:11px; text-transform:uppercase; letter-spacing:0.08em; }
+  .when { display:flex; align-items:center; justify-content:flex-end; font-size:12px; }
+  /* expand */
+  .expand { padding:24px 28px; background:#fffacc; border-bottom:3px double var(--fg); }
+  .expand .clue { font-size:11px; text-transform:uppercase; letter-spacing:0.15em; color:var(--blue); font-weight:900; margin-bottom:4px; }
+  .expand h2 { margin:0 0 4px; font-size:24px; font-weight:900; letter-spacing:0.01em; text-transform:uppercase; }
+  .expand .answer-grid { display:flex; gap:3px; margin:6px 0 18px; flex-wrap:wrap; }
+  .cell { width:28px; height:28px; background:#fff; border:2px solid var(--fg); display:flex; align-items:flex-end; justify-content:center; padding-bottom:2px; font-weight:700; font-size:13px; }
+  .cell.blk { background:var(--fg); border-color:var(--fg); }
+  .cell .num { position:absolute; font-size:8px; font-weight:400; }
+  .meta-strip { padding:12px 0; border-top:2px solid var(--fg); border-bottom:2px solid var(--fg); margin:14px 0 18px; display:grid; grid-template-columns:90px 1fr; gap:6px 14px; font-size:13px; }
+  .meta-strip > span:nth-child(odd) { font-weight:900; text-transform:uppercase; font-size:11px; letter-spacing:0.06em; padding-top:3px; }
+  select.assign { background:#fff; border:2px solid var(--fg); padding:4px 10px; font:13px inherit; font-weight:700; }
+  .seen-pill { padding:2px 8px; background:var(--blue); color:#fff; font-weight:700; font-size:11.5px; margin-right:5px; text-transform:uppercase; display:inline-block; }
+  .body { font-size:14.5px; line-height:1.65; padding:6px 0 14px; }
+  textarea { width:100%; background:#fff; border:2px solid var(--fg); color:var(--fg); padding:12px 14px; font:13.5px/1.55 inherit; resize:vertical; min-height:90px; }
+  .act { display:flex; gap:8px; margin-top:12px; }
+  .btn { font:12px inherit; padding:7px 16px; background:#fff; border:2px solid var(--fg); color:var(--fg); cursor:pointer; font-weight:900; text-transform:uppercase; letter-spacing:0.06em; }
+  .btn.pri { background:var(--blue); border-color:var(--blue); color:#fff; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>The Inbox · 20 May 2026</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill blue">Mine</span><button class="pill">↻ Sync</button></div>
+<div class="list">
+  <div class="row"><span class="id">1</span><div><div class="from">SANDERS</div><div class="subj"><strong>RE: Markup tomorrow — borrower bill</strong></div></div><div class="meta-r">Down · Policy</div><span class="when">14m</span></div>
+  <div class="row acr on"><span class="id">2</span><div><div class="from">WERNER</div><div class="subj"><strong>Quote request — PSLF guidance</strong></div></div><div class="meta-r">Across · Press</div><span class="when">42m</span></div>
+  <div class="expand">
+    <div class="clue">2 Across — Press · High Priority</div>
+    <h2>Quote Request — PSLF Guidance</h2>
+    <div class="answer-grid">
+      <div class="cell">Q</div><div class="cell">U</div><div class="cell">O</div><div class="cell">T</div><div class="cell">E</div>
+      <div class="cell blk"></div>
+      <div class="cell">R</div><div class="cell">E</div><div class="cell">Q</div><div class="cell">U</div><div class="cell">E</div><div class="cell">S</div><div class="cell">T</div>
+    </div>
+    <div class="meta-strip">
+      <span>From</span><span><strong>Erica Werner</strong> · Washington Post · 3:18 PM</span>
+      <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+      <span>Seen by</span><span><span class="seen-pill">✓ Natalia · 3:21</span><span class="seen-pill">✓ Cody · 3:24</span></span>
+    </div>
+    <div class="body">Hi Natalia — story for tomorrow on PSLF buyback. 20 min by 4pm ET. 1) Borrowers in 100–120 months — meaningful benefit, or buyback wipes? 2) SDCC data on the 100–120 window? — Erica</div>
+    <textarea>Hi Erica — call at 3:45pm ET. ~12k PSLF, 23% in 100–120. Buyback wipes gain above income cap. — N</textarea>
+    <div class="act"><button class="btn">Copy</button><button class="btn">Save</button><button class="btn pri">Send →</button></div>
+  </div>
+  <div class="row"><span class="id">3</span><div><div class="from">TAYLOR</div><div class="subj"><strong>Reading the new ED memo together?</strong></div></div><div class="meta-r">Down · Partners</div><span class="when">2h</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v28-pixel-8bit.html b/public/mockups/inbox/v28-pixel-8bit.html
new file mode 100644
index 0000000..b4da749
--- /dev/null
+++ b/public/mockups/inbox/v28-pixel-8bit.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v28 — 8-Bit Pixel — Norma Inbox</title>
+<style>
+  :root { --bg:#2c3e50; --panel:#34495e; --el:#1a252f; --fg:#ecf0f1; --muted:#95a5a6; --line:#000; --green:#2ecc71; --red:#e74c3c; --yellow:#f1c40f; --blue:#3498db; }
+  * { box-sizing:border-box; image-rendering:pixelated; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.4 "Press Start 2P", "VT323", "Courier New", monospace; min-height:100vh; }
+  .top { padding:14px 18px; background:var(--panel); border-bottom:4px solid var(--line); box-shadow:0 4px 0 var(--line); display:flex; gap:10px; align-items:center; }
+  .top h1 { margin:0; font-size:15px; font-weight:700; flex:1; letter-spacing:0.04em; color:var(--yellow); text-shadow:2px 2px 0 var(--line); }
+  .top h1::before { content:"★ "; }
+  .pill { padding:7px 14px; background:var(--bg); border:3px solid var(--line); color:var(--fg); cursor:pointer; font:11px inherit; box-shadow:3px 3px 0 var(--line); }
+  .pill.on { background:var(--yellow); color:var(--line); }
+  .pill.green { background:var(--green); color:var(--line); border-color:var(--line); }
+  .stat-bar { padding:6px 18px; background:var(--el); border-bottom:2px solid var(--line); font-size:11px; display:flex; gap:18px; color:var(--muted); }
+  .stat-bar strong { color:var(--yellow); }
+  .list { padding:14px 18px; display:flex; flex-direction:column; gap:6px; }
+  .row { display:grid; grid-template-columns:32px 1fr 100px 60px; gap:10px; padding:10px 14px; background:var(--panel); border:3px solid var(--line); cursor:pointer; align-items:center; box-shadow:4px 4px 0 var(--line); font-size:11.5px; }
+  .row:hover { transform:translate(1px, 1px); box-shadow:3px 3px 0 var(--line); }
+  .row.on { background:var(--blue); box-shadow:4px 4px 0 var(--yellow); }
+  .row .sprite { width:24px; height:24px; background:var(--green); border:2px solid var(--line); display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; color:var(--line); }
+  .sprite.red { background:var(--red); }
+  .sprite.yel { background:var(--yellow); }
+  .from { font-weight:700; font-size:12px; }
+  .subj { color:var(--muted); margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:10.5px; }
+  .row.on .subj { color:var(--fg); }
+  .chip { padding:2px 7px; background:var(--green); color:var(--line); border:2px solid var(--line); font-size:10px; font-weight:700; display:inline-block; }
+  .chip.red { background:var(--red); color:var(--fg); }
+  .chip.yel { background:var(--yellow); color:var(--line); }
+  .when { font-size:10.5px; text-align:right; color:var(--yellow); }
+  /* expand */
+  .expand { padding:18px 22px 22px; background:var(--el); border:3px solid var(--yellow); margin:6px 0; box-shadow:5px 5px 0 var(--line); }
+  .expand h2 { margin:0 0 4px; font-size:14px; font-weight:700; color:var(--yellow); text-shadow:2px 2px 0 var(--line); line-height:1.4; }
+  .meta { font-size:11px; line-height:1.9; margin:14px 0 14px; padding:10px 0; border-top:2px dashed var(--muted); border-bottom:2px dashed var(--muted); }
+  .meta .k { color:var(--yellow); display:inline-block; min-width:90px; }
+  select.assign { background:var(--bg); border:2px solid var(--line); color:var(--fg); padding:3px 8px; font:11px inherit; }
+  .seen-pill { padding:2px 7px; background:var(--green); color:var(--line); border:2px solid var(--line); font-size:10px; font-weight:700; margin-right:4px; display:inline-block; }
+  .body { background:var(--bg); border:2px solid var(--line); padding:12px 14px; font-size:11.5px; line-height:1.65; }
+  textarea { width:100%; background:var(--bg); border:3px solid var(--line); color:var(--fg); padding:10px 12px; font:11.5px/1.55 inherit; resize:vertical; min-height:80px; margin-top:8px; box-shadow:3px 3px 0 var(--line); }
+  .act { display:flex; gap:8px; margin-top:10px; }
+  .btn { font:10.5px inherit; padding:8px 14px; background:var(--bg); border:3px solid var(--line); color:var(--fg); cursor:pointer; box-shadow:3px 3px 0 var(--line); }
+  .btn:hover { transform:translate(1px, 1px); box-shadow:2px 2px 0 var(--line); }
+  .btn.pri { background:var(--green); color:var(--line); margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>NORMA INBOX</h1><span class="pill on">ALL</span><span class="pill">UNREAD</span><span class="pill">MINE</span><button class="pill green">↻ SYNC</button></div>
+<div class="stat-bar"><span>HP <strong>♥♥♥♥♥</strong></span><span>SCORE <strong>12,840</strong></span><span>LEVEL <strong>3</strong></span><span>UNREAD <strong>8</strong></span><span>NEW! <strong>2</strong></span></div>
+<div class="list">
+  <div class="row"><div class="sprite">!</div><div><div class="from">SANDERS</div><div class="subj">RE: MARKUP TOMORROW</div></div><span class="chip">POLICY</span><span class="when">14M</span></div>
+  <div class="row on"><div class="sprite red">★</div><div><div class="from">E.WERNER · WAPO</div><div class="subj">QUOTE REQUEST · PSLF</div></div><span class="chip red">!PRESS!</span><span class="when">42M</span></div>
+  <div class="expand">
+    <h2>★ QUOTE REQUEST — PSLF GUIDANCE</h2>
+    <div class="meta">
+      <div><span class="k">FROM</span> E. WERNER (WAPO)</div>
+      <div><span class="k">OWNER</span> <select class="assign"><option>NATALIA (ADMIN)</option><option>CODY (STAFF)</option><option>JESS (INTERN)</option></select></div>
+      <div><span class="k">SEEN BY</span><span class="seen-pill">N · 3:21</span><span class="seen-pill">C · 3:24</span></div>
+      <div><span class="k">PRIORITY</span> <span style="color:var(--red)">!!HIGH!!</span></div>
+    </div>
+    <div class="body">HI NATALIA — STORY FOR TOMORROW ON PSLF BUYBACK. 20 MIN BY 4PM ET.<br>Q1: BORROWERS IN 100–120 MONTHS — MEANINGFUL BENEFIT OR BUYBACK WIPES?<br>Q2: SDCC DATA ON 100–120 WINDOW?<br>— ERICA</div>
+    <textarea>HI ERICA — CALL @ 3:45PM ET. COHORT ~12K, 23% IN 100–120. BUYBACK WIPES GAIN > INCOME CAP. — N</textarea>
+    <div class="act"><button class="btn">COPY</button><button class="btn">SAVE</button><button class="btn pri">▶ SEND!</button></div>
+  </div>
+  <div class="row"><div class="sprite yel">?</div><div><div class="from">A.TAYLOR · DC</div><div class="subj">READING THE ED MEMO TOGETHER?</div></div><span class="chip yel">PARTNERS</span><span class="when">2H</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v29-watercolor.html b/public/mockups/inbox/v29-watercolor.html
new file mode 100644
index 0000000..82e4c0b
--- /dev/null
+++ b/public/mockups/inbox/v29-watercolor.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v29 — Watercolor — Norma Inbox</title>
+<style>
+  :root { --bg:#f8f4ed; --panel:#fefcf7; --el:#f0eadb; --fg:#3a4a52; --muted:#7a8a93; --line:#c8c0b0; --rose:#d68a99; --lavender:#a8a0c8; --sage:#90a888; --peach:#e8b890; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14.5px/1.65 "EB Garamond", "Cormorant Garamond", Georgia, serif; min-height:100vh;
+    background-image:
+      radial-gradient(circle at 8% 12%, rgba(214,138,153,0.16) 0%, transparent 28%),
+      radial-gradient(circle at 88% 28%, rgba(168,160,200,0.16) 0%, transparent 30%),
+      radial-gradient(circle at 22% 88%, rgba(144,168,136,0.14) 0%, transparent 32%),
+      radial-gradient(circle at 92% 78%, rgba(232,184,144,0.15) 0%, transparent 30%); }
+  .top { padding:22px 32px 16px; display:flex; gap:14px; align-items:flex-end; }
+  .top h1 { margin:0; font-size:30px; font-weight:500; letter-spacing:0.01em; flex:1; font-style:italic; color:var(--fg); }
+  .pill { font-size:12.5px; padding:5px 14px; border-radius:999px; background:rgba(255,255,255,0.5); border:1px solid var(--line); color:var(--muted); cursor:pointer; font-style:italic; }
+  .pill.on { background:var(--rose); border-color:var(--rose); color:#fff; font-style:normal; font-weight:600; }
+  .divider { height:2px; background:linear-gradient(90deg, transparent, var(--line), transparent); margin:0 32px; }
+  .list { padding:24px 36px 60px; max-width:820px; margin:0 auto; }
+  .row { padding:18px 22px; background:linear-gradient(180deg, rgba(254,252,247,0.85), rgba(254,252,247,0.65)); border:1px solid var(--line); border-radius:12px; margin-bottom:10px; cursor:pointer; backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
+  .row:hover { background:rgba(254,252,247,0.95); }
+  .row.on { background:rgba(254,252,247,0.95); border-color:var(--rose); box-shadow:0 6px 24px rgba(214,138,153,0.18); }
+  .head { display:flex; gap:10px; align-items:baseline; margin-bottom:4px; }
+  .ava-blot { width:32px; height:32px; border-radius:50%; flex-shrink:0;
+    background:radial-gradient(circle at 30% 30%, var(--rose), transparent 70%);
+    display:flex; align-items:center; justify-content:center; font-weight:600; font-size:13px; color:#7a3340; }
+  .ava-blot.lav { background:radial-gradient(circle at 30% 30%, var(--lavender), transparent 70%); color:#544a78; }
+  .ava-blot.sage { background:radial-gradient(circle at 30% 30%, var(--sage), transparent 70%); color:#3a4a32; }
+  .name { font-weight:600; font-size:14.5px; font-style:italic; }
+  .when { margin-left:auto; font-size:12px; color:var(--muted); font-style:italic; }
+  .subj { font-size:17px; font-weight:500; margin:2px 0 4px; }
+  .prev { font-size:13.5px; color:var(--muted); font-style:italic; line-height:1.6; }
+  .chips { margin-top:8px; display:flex; gap:10px; flex-wrap:wrap; font-size:11.5px; }
+  .chips .ch { padding:1px 9px; border-radius:999px; font-style:italic; font-weight:500; }
+  .chips .ch-press { background:rgba(214,138,153,0.25); color:#8a3040; }
+  .chips .ch-policy { background:rgba(168,160,200,0.25); color:#544a78; }
+  .chips .ch-partner { background:rgba(144,168,136,0.25); color:#3a4a32; }
+  .chips .ch-seen { background:rgba(144,168,136,0.18); color:var(--sage); }
+  /* expand */
+  .expand { padding:24px 26px 28px; }
+  .expand h2 { margin:0 0 4px; font-size:24px; font-weight:500; line-height:1.3; font-style:italic; }
+  .byline { font-style:italic; color:var(--muted); font-size:13.5px; margin-bottom:10px; }
+  .meta-grid { display:grid; grid-template-columns:80px 1fr; gap:6px 14px; font-size:13.5px; padding:12px 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); margin:14px 0 18px; }
+  .meta-grid > span:nth-child(odd) { font-style:italic; color:var(--muted); font-size:12px; padding-top:3px; }
+  select.assign { background:transparent; border:1px solid var(--line); color:var(--fg); font:13.5px inherit; padding:3px 9px; border-radius:6px; font-style:italic; }
+  .seen-pill { font-size:12px; padding:1px 9px; border-radius:999px; background:rgba(144,168,136,0.2); color:#3a5a30; display:inline-block; margin-right:5px; font-style:italic; }
+  .body { font-size:15.5px; line-height:1.8; max-width:580px; }
+  .body p { margin:0 0 14px; }
+  textarea { width:100%; max-width:580px; background:rgba(255,255,255,0.7); border:1px solid var(--line); color:var(--fg); padding:14px 16px; font:14.5px/1.7 inherit; resize:vertical; min-height:100px; border-radius:10px; }
+  .act { display:flex; gap:12px; margin-top:14px; max-width:580px; align-items:center; }
+  .btn { font:13px inherit; padding:6px 14px; background:transparent; border:1px solid var(--line); color:var(--fg); border-radius:999px; cursor:pointer; font-style:italic; }
+  .btn.pri { background:var(--rose); color:#fff; border-color:var(--rose); font-style:normal; font-weight:600; margin-left:auto; padding:8px 22px; }
+</style>
+</head><body>
+<div class="top"><h1>Quiet correspondence</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><button class="pill">— sync</button></div>
+<div class="divider"></div>
+<div class="list">
+  <div class="row"><div class="head"><div class="ava-blot lav">BS</div><span class="name">Sen. Bernie Sanders Office</span><span class="when">14 min</span></div><div class="subj">RE: Markup tomorrow — borrower bill</div><div class="prev">Senator can do a quick call before 9am ET. Aide on this thread.</div><div class="chips"><span class="ch ch-policy">policy</span></div></div>
+  <div class="row on"><div class="head"><div class="ava-blot">EW</div><span class="name">Erica Werner · Washington Post</span><span class="when">42 min</span></div><div class="subj">Quote request — Dept of Ed PSLF guidance</div><div class="prev">Hi Natalia — running a story for tomorrow on the new PSLF buyback option.</div>
+    <div class="expand">
+      <div class="byline">Erica Werner · Washington Post · this afternoon, 3:18 PM</div>
+      <div class="meta-grid">
+        <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+        <span>Seen by</span><span><span class="seen-pill">✿ Natalia · 3:21</span><span class="seen-pill">✿ Cody · 3:24</span></span>
+      </div>
+      <div class="body">
+        <p>Hi Natalia — running a piece tomorrow on the new PSLF buyback guidance. Two questions if you have twenty minutes by 4pm Eastern.</p>
+        <p>Your read on whether borrowers between months 100–120 of payment actually get a meaningful benefit, or whether the buyback math wipes it out. And any data points from SDCC on how many borrowers are caught in this 100–120 window.</p>
+        <p>Happy to do email if a call doesn't work. — Erica</p>
+      </div>
+      <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text the number. Our cohort: ~12k PSLF borrowers, 23% are in the 100–120 window. Buyback math wipes the gain above income cap — a design flaw worth surfacing. — Natalia</textarea>
+      <div class="act"><button class="btn">copy</button><button class="btn">save draft</button><button class="btn pri">Send →</button></div>
+    </div>
+  </div>
+  <div class="row"><div class="head"><div class="ava-blot sage">AT</div><span class="name">Astra Taylor · Debt Collective</span><span class="when">2 hr</span></div><div class="subj">Reading the new ED memo together?</div><div class="prev">Want to do a joint statement if it lands the way we think it will.</div><div class="chips"><span class="ch ch-partner">partners</span></div></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v30-sakura.html b/public/mockups/inbox/v30-sakura.html
new file mode 100644
index 0000000..0f5e163
--- /dev/null
+++ b/public/mockups/inbox/v30-sakura.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v30 — Sakura — Norma Inbox</title>
+<style>
+  :root { --bg:#fff9fa; --panel:#fff; --el:#fdf0f2; --fg:#1a0a14; --muted:#8a6878; --line:#f2c8d2; --pink:#e8597c; --dark-pink:#a83055; --gold:#c4a464; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.6 "Shippori Mincho", "Noto Serif JP", "Hiragino Mincho ProN", "Yu Mincho", serif; min-height:100vh;
+    background-image:radial-gradient(circle at 90% 5%, rgba(232,89,124,0.06) 0%, transparent 35%), radial-gradient(circle at 8% 95%, rgba(232,89,124,0.08) 0%, transparent 35%); }
+  .top { padding:24px 36px 14px; display:flex; gap:18px; align-items:flex-end; border-bottom:1px solid var(--line); }
+  .top h1 { margin:0; font-size:24px; font-weight:500; flex:1; letter-spacing:0.06em; }
+  .top h1 .jp { color:var(--pink); margin-right:8px; font-weight:400; }
+  .top .sub { font-size:11px; letter-spacing:0.2em; color:var(--muted); text-transform:uppercase; }
+  .pill { font-size:11px; padding:5px 12px; background:transparent; border:1px solid var(--line); color:var(--muted); cursor:pointer; letter-spacing:0.08em; }
+  .pill.on { background:var(--pink); border-color:var(--pink); color:#fff; }
+  .list { padding:24px 36px 60px; max-width:840px; margin:0 auto; }
+  .row { padding:18px 0; border-bottom:1px solid var(--line); cursor:pointer; }
+  .row:hover { background:rgba(232,89,124,0.03); margin:0 -10px; padding-left:10px; padding-right:10px; }
+  .head { display:flex; gap:14px; align-items:baseline; }
+  .head .name { font-size:16px; font-weight:500; color:var(--dark-pink); }
+  .head .when { margin-left:auto; font-size:12px; color:var(--muted); letter-spacing:0.08em; }
+  .subj { font-size:18px; font-weight:500; margin:4px 0; line-height:1.4; }
+  .prev { font-size:13.5px; color:var(--muted); }
+  .chips { margin-top:8px; display:flex; gap:14px; flex-wrap:wrap; font-size:11px; color:var(--muted); letter-spacing:0.1em; text-transform:uppercase; }
+  .chips .ch { padding-bottom:1px; border-bottom:1px solid var(--pink); color:var(--pink); }
+  .chips .ch-seen { color:var(--gold); border-bottom-color:var(--gold); }
+  /* expand */
+  .expand { margin:14px 0; padding:30px 32px 32px; background:var(--panel); border-left:3px solid var(--pink); position:relative; }
+  .expand::before { content:"❀"; position:absolute; top:14px; right:18px; color:var(--pink); font-size:22px; opacity:0.7; }
+  .expand h2 { margin:0 0 4px; font-size:24px; font-weight:500; line-height:1.35; }
+  .byline { font-size:13px; color:var(--muted); padding-bottom:14px; border-bottom:1px solid var(--line); margin-bottom:14px; letter-spacing:0.02em; }
+  .meta-grid { display:grid; grid-template-columns:90px 1fr; gap:6px 14px; font-size:13px; margin-bottom:18px; }
+  .meta-grid > span:nth-child(odd) { color:var(--muted); font-size:11px; letter-spacing:0.1em; text-transform:uppercase; padding-top:3px; }
+  select.assign { background:transparent; border:none; border-bottom:1px solid var(--fg); color:var(--fg); font:14px inherit; padding:2px 0; }
+  .seen-pill { display:inline-block; margin-right:12px; padding-bottom:1px; border-bottom:1px solid var(--gold); color:var(--gold); font-size:13px; }
+  .body { font-size:15.5px; line-height:1.85; max-width:560px; padding:6px 0 14px; }
+  .body p { margin:0 0 14px; }
+  textarea { width:100%; max-width:580px; background:var(--el); border:1px solid var(--line); color:var(--fg); padding:14px 18px; font:15px/1.75 inherit; resize:vertical; min-height:110px; }
+  .act { display:flex; gap:18px; margin-top:14px; max-width:580px; align-items:center; }
+  .btn { font:12.5px inherit; padding:6px 0; background:transparent; border:none; border-bottom:1px solid var(--fg); color:var(--fg); cursor:pointer; letter-spacing:0.04em; }
+  .btn.pri { background:var(--pink); color:#fff; padding:9px 26px; border:none; border-radius:0; letter-spacing:0.1em; font-weight:500; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1><span class="jp">桜</span>Inbox</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><span class="pill" style="color:var(--pink);border-color:var(--pink)">— sync</span></div>
+<div class="list">
+  <div class="row"><div class="head"><span class="name">Sen. Bernie Sanders Office</span><span class="when">14 min · today</span></div><h3 class="subj">RE: Markup tomorrow — borrower bill</h3><p class="prev">Senator can do a quick call before 9am ET. Aide on this thread.</p><div class="chips"><span class="ch">policy</span></div></div>
+  <div class="row on">
+    <div class="head"><span class="name">Erica Werner · Washington Post</span><span class="when">42 min · today</span></div>
+    <h3 class="subj">Quote request — Dept of Ed PSLF guidance</h3>
+    <div class="expand">
+      <div class="byline">From <strong>Erica Werner</strong> · Washington Post · today at 3:18 PM</div>
+      <div class="meta-grid">
+        <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+        <span>Seen by</span><span><span class="seen-pill">❀ Natalia · 3:21</span><span class="seen-pill">❀ Cody · 3:24</span></span>
+      </div>
+      <div class="body">
+        <p>Hi Natalia — running a piece tomorrow on the new PSLF buyback guidance. Two questions if you have 20 minutes by 4pm ET.</p>
+        <p>Whether borrowers between 100–120 months actually get a meaningful benefit. And SDCC data on how many borrowers are in that window. — Erica</p>
+      </div>
+      <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text the number. Our cohort: ~12k PSLF borrowers, 23% in the 100–120 window. Buyback wipes the gain above income cap — design flaw. — Natalia</textarea>
+      <div class="act"><button class="btn">copy</button><button class="btn">save draft</button><button class="btn pri">Send →</button></div>
+    </div>
+  </div>
+  <div class="row"><div class="head"><span class="name">Astra Taylor · Debt Collective</span><span class="when">2 hr · today</span></div><h3 class="subj">Reading the new ED memo together?</h3><p class="prev">Want to do a joint statement if it lands the way we think.</p><div class="chips"><span class="ch">partners</span></div></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v31-forest-walk.html b/public/mockups/inbox/v31-forest-walk.html
new file mode 100644
index 0000000..85a5f63
--- /dev/null
+++ b/public/mockups/inbox/v31-forest-walk.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v31 — Forest Walk — Norma Inbox</title>
+<style>
+  :root { --bg:#1c2418; --panel:#2a3424; --el:#3a4632; --fg:#e8e0c8; --muted:#9aa080; --line:#4a5638; --moss:#7a9c48; --bark:#8a6438; --cream:#e8d8a0; --mush:#c4a874; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14.5px/1.6 "Lora", "Iowan Old Style", Georgia, serif; min-height:100vh;
+    background-image:radial-gradient(circle at 20% 100%, rgba(122,156,72,0.1) 0%, transparent 50%), radial-gradient(circle at 80% 0%, rgba(138,100,56,0.08) 0%, transparent 50%); }
+  .top { padding:18px 28px; border-bottom:1px solid var(--moss); display:flex; gap:14px; align-items:center;
+    background:linear-gradient(180deg, rgba(122,156,72,0.08), transparent); }
+  .top h1 { margin:0; font-size:24px; font-weight:500; flex:1; letter-spacing:0.01em; color:var(--cream); }
+  .top h1::before { content:"❦ "; color:var(--moss); }
+  .pill { font-size:12px; padding:5px 13px; border:1px solid var(--moss); color:var(--moss); background:transparent; cursor:pointer; letter-spacing:0.06em; font-style:italic; }
+  .pill.on { background:var(--moss); color:#fff; font-style:normal; font-weight:500; }
+  .list { padding:20px 28px; max-width:900px; margin:0 auto; }
+  .row { padding:16px 0; border-bottom:1px solid var(--line); cursor:pointer; }
+  .head { display:flex; gap:12px; align-items:baseline; }
+  .head .leaf { color:var(--moss); }
+  .head .name { font-weight:600; font-size:15px; color:var(--cream); }
+  .head .when { margin-left:auto; color:var(--muted); font-size:12px; font-style:italic; }
+  .subj { font-size:17px; font-weight:500; margin:4px 0 4px; line-height:1.4; }
+  .prev { font-size:13.5px; color:var(--muted); }
+  .chips { margin-top:8px; display:flex; gap:12px; flex-wrap:wrap; font-size:11px; color:var(--muted); letter-spacing:0.08em; }
+  .chips .ch { color:var(--mush); }
+  .chips .ch.seen { color:var(--moss); }
+  /* expand */
+  .expand { margin:14px 0; padding:24px 30px 28px; background:var(--panel); border:1px solid var(--moss); border-left-width:4px; }
+  .expand h2 { margin:0 0 4px; font-size:22px; font-weight:500; line-height:1.35; color:var(--cream); }
+  .byline { color:var(--muted); font-style:italic; font-size:13px; padding-bottom:14px; border-bottom:1px solid var(--line); margin-bottom:16px; }
+  .meta-grid { display:grid; grid-template-columns:90px 1fr; gap:6px 14px; font-size:13px; margin-bottom:18px; }
+  .meta-grid > span:nth-child(odd) { color:var(--muted); font-size:11px; letter-spacing:0.08em; text-transform:uppercase; padding-top:3px; }
+  select.assign { background:var(--el); border:1px solid var(--moss); color:var(--fg); font:13px inherit; padding:4px 10px; }
+  .seen-pill { font-size:12px; padding:1px 9px; border:1px solid var(--moss); color:var(--moss); display:inline-block; margin-right:5px; font-style:italic; }
+  .body { font-size:15.5px; line-height:1.8; max-width:560px; color:var(--fg); padding:0 0 14px; }
+  textarea { width:100%; max-width:580px; background:var(--el); border:1px solid var(--moss); color:var(--fg); padding:14px 16px; font:14.5px/1.7 inherit; resize:vertical; min-height:100px; }
+  .act { display:flex; gap:14px; margin-top:14px; max-width:580px; align-items:center; }
+  .btn { font:12.5px inherit; padding:6px 14px; background:transparent; border:1px solid var(--moss); color:var(--moss); cursor:pointer; font-style:italic; letter-spacing:0.04em; }
+  .btn.pri { background:var(--moss); color:var(--bg); font-style:normal; font-weight:600; margin-left:auto; padding:8px 22px; letter-spacing:0.08em; }
+</style>
+</head><body>
+<div class="top"><h1>Forest correspondence</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><span class="pill" style="color:var(--mush);border-color:var(--mush)">— sync</span></div>
+<div class="list">
+  <div class="row"><div class="head"><span class="leaf">❦</span><span class="name">Sen. Bernie Sanders Office</span><span class="when">14 minutes</span></div><h3 class="subj">RE: Markup tomorrow — borrower bill</h3><p class="prev">Senator can do a quick call before 9am ET. Aide on this thread.</p><div class="chips"><span class="ch">policy</span></div></div>
+  <div class="row on">
+    <div class="head"><span class="leaf">❦</span><span class="name">Erica Werner · Washington Post</span><span class="when">42 minutes</span></div>
+    <h3 class="subj">Quote request — Dept of Ed PSLF guidance</h3>
+    <div class="expand">
+      <div class="byline">Erica Werner · Washington Post · this afternoon at 3:18 PM</div>
+      <div class="meta-grid">
+        <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+        <span>Seen by</span><span><span class="seen-pill">❦ Natalia · 3:21</span><span class="seen-pill">❦ Cody · 3:24</span></span>
+      </div>
+      <div class="body">Hi Natalia — running a piece tomorrow on the new PSLF buyback guidance. Two questions if you have 20 minutes by 4pm Eastern. Whether borrowers in months 100–120 actually get a meaningful benefit, or whether the buyback math wipes it out. And any SDCC data on the 100–120 window. — Erica</div>
+      <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text the number. Our cohort: ~12k PSLF, 23% in the 100–120 window. Buyback wipes the gain above income cap — design flaw worth surfacing. — Natalia</textarea>
+      <div class="act"><button class="btn">copy</button><button class="btn">save draft</button><button class="btn pri">Send →</button></div>
+    </div>
+  </div>
+  <div class="row"><div class="head"><span class="leaf">❦</span><span class="name">Astra Taylor · Debt Collective</span><span class="when">2 hours</span></div><h3 class="subj">Reading the new ED memo together?</h3><p class="prev">Want to do a joint statement if it lands the way we think.</p><div class="chips"><span class="ch">partners</span></div></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v32-botanical.html b/public/mockups/inbox/v32-botanical.html
new file mode 100644
index 0000000..306e3b1
--- /dev/null
+++ b/public/mockups/inbox/v32-botanical.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v32 — Botanical Print — Norma Inbox</title>
+<style>
+  :root { --bg:#f4ede0; --panel:#fdfaf0; --el:#e6d8c0; --fg:#1a2818; --muted:#5a6648; --line:#8a9a78; --leaf:#2a5028; --copper:#a85a24; --gold:#c4a437; }
+  * { box-sizing:border-box; }
+  body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.6 "Cormorant Garamond", "EB Garamond", Georgia, serif; min-height:100vh; }
+  .top { padding:18px 32px 14px; border-bottom:2px solid var(--leaf); display:flex; gap:14px; align-items:flex-end;
+    background:linear-gradient(180deg, rgba(42,80,40,0.04), transparent); }
+  .top h1 { margin:0; font-size:26px; font-weight:500; flex:1; letter-spacing:0.015em; color:var(--leaf); font-style:italic; }
+  .top .sub { font-size:11px; letter-spacing:0.15em; color:var(--muted); text-transform:uppercase; font-style:normal; }
+  .pill { font-size:11.5px; padding:5px 12px; border:1px solid var(--leaf); color:var(--leaf); background:transparent; cursor:pointer; letter-spacing:0.08em; text-transform:uppercase; }
+  .pill.on { background:var(--leaf); color:#fff; }
+  .list { padding:18px 36px; max-width:880px; margin:0 auto; }
+  .row { display:grid; grid-template-columns:90px 1fr 130px; gap:18px; padding:18px 0; border-bottom:1px solid var(--line); cursor:pointer; align-items:start; }
+  .row:hover { background:rgba(196,164,55,0.06); margin:0 -10px; padding-left:10px; padding-right:10px; }
+  .plate { width:80px; height:80px; border:1.5px solid var(--leaf); background:var(--panel); display:flex; align-items:center; justify-content:center; flex-direction:column; padding:4px;
+    background-image:radial-gradient(circle at 50% 50%, var(--bg) 0%, transparent 70%); }
+  .plate .num { font-size:9px; letter-spacing:0.15em; color:var(--muted); text-transform:uppercase; }
+  .plate .glyph { font-size:24px; color:var(--leaf); font-style:italic; line-height:1; }
+  .row.on .plate { border-color:var(--copper); border-width:2px; }
+  .row.on .plate .glyph { color:var(--copper); }
+  .head { display:flex; gap:10px; align-items:baseline; }
+  .head .name { font-weight:500; font-size:15.5px; font-style:italic; }
+  .head .latin { font-size:11px; letter-spacing:0.06em; color:var(--muted); font-style:italic; }
+  .subj { font-size:17px; font-weight:500; margin:4px 0 4px; line-height:1.35; }
+  .prev { font-size:13px; color:var(--muted); }
+  .chips { margin-top:8px; display:flex; gap:14px; font-size:10.5px; color:var(--muted); letter-spacing:0.1em; text-transform:uppercase; }
+  .chips .ch { color:var(--copper); }
+  .when { text-align:right; font-size:12px; color:var(--muted); font-style:italic; padding-top:4px; }
+  /* expand */
+  .expand { padding:30px 36px 34px; background:var(--panel); border:1.5px solid var(--leaf); margin:14px 0; position:relative; }
+  .expand::before { content:""; position:absolute; top:8px; right:8px; bottom:8px; left:8px; border:1px solid var(--copper); opacity:0.3; pointer-events:none; }
+  .expand h2 { margin:14px 0 4px; font-size:28px; font-weight:500; line-height:1.25; font-style:italic; color:var(--leaf); }
+  .expand .label { font-size:11px; letter-spacing:0.18em; text-transform:uppercase; color:var(--copper); font-weight:600; }
+  .byline { font-style:italic; font-size:13.5px; color:var(--muted); padding-bottom:14px; border-bottom:1px solid var(--line); margin-bottom:18px; margin-top:10px; }
+  .meta-grid { display:grid; grid-template-columns:100px 1fr; gap:6px 14px; font-size:13.5px; margin-bottom:18px; }
+  .meta-grid > span:nth-child(odd) { color:var(--muted); font-size:11px; letter-spacing:0.1em; text-transform:uppercase; padding-top:4px; }
+  select.assign { background:var(--bg); border:1px solid var(--leaf); color:var(--fg); font:13.5px inherit; padding:3px 10px; font-style:italic; }
+  .seen-pill { font-size:12px; padding:1px 10px; border:1px solid var(--copper); color:var(--copper); display:inline-block; margin-right:5px; font-style:italic; }
+  .body { font-size:15.5px; line-height:1.85; max-width:560px; }
+  .body p { margin:0 0 14px; }
+  textarea { width:100%; max-width:580px; background:var(--bg); border:1px solid var(--leaf); color:var(--fg); padding:14px 16px; font:15px/1.75 inherit; resize:vertical; min-height:110px; }
+  .act { display:flex; gap:14px; margin-top:14px; max-width:580px; align-items:center; }
+  .btn { font:12.5px inherit; padding:7px 16px; background:transparent; border:1px solid var(--leaf); color:var(--leaf); cursor:pointer; text-transform:uppercase; letter-spacing:0.1em; font-weight:500; }
+  .btn.pri { background:var(--copper); border-color:var(--copper); color:var(--bg); font-weight:600; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>Norma · <span style="color:var(--muted);font-style:normal;font-size:11px;letter-spacing:0.15em">FIELD GUIDE TO CORRESPONDENCE</span></h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><button class="pill">↻ Sync</button></div>
+<div class="list">
+  <div class="row"><div class="plate"><span class="num">Fig. 1</span><span class="glyph">❦</span><span class="num" style="margin-top:4px;color:var(--leaf)">Polit.</span></div><div><div class="head"><span class="name">Sen. Bernie Sanders Office</span><span class="latin">— senatus americanus</span></div><h3 class="subj">RE: Markup tomorrow — borrower bill</h3><p class="prev">Senator can do a quick call before 9am ET. Aide on this thread.</p><div class="chips"><span class="ch">policy</span></div></div><div class="when">14 min</div></div>
+
+  <div class="row on"><div class="plate"><span class="num">Fig. 2</span><span class="glyph">✦</span><span class="num" style="margin-top:4px;color:var(--copper)">Press</span></div><div><div class="head"><span class="name">Erica Werner · Washington Post</span><span class="latin">— scriba diurna</span></div><h3 class="subj">Quote request — PSLF guidance</h3></div><div class="when">42 min</div></div>
+
+  <div class="expand">
+    <div class="label">Fig. 2 · Press · Specimen of the Day</div>
+    <h2>Quote request — Dept of Ed PSLF guidance</h2>
+    <div class="byline">Collected from <strong style="font-style:normal">Erica Werner</strong> · Washington Post · this 20 May at 3:18 PM</div>
+    <div class="meta-grid">
+      <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option></select></span>
+      <span>Observed by</span><span><span class="seen-pill">✦ Natalia · 3:21</span><span class="seen-pill">✦ Cody · 3:24</span></span>
+    </div>
+    <div class="body">
+      <p>Hi Natalia — running a piece tomorrow on the new PSLF buyback guidance. Two questions if you have 20 minutes by 4pm ET.</p>
+      <p>Whether borrowers in months 100–120 actually get a meaningful benefit, or whether the buyback math wipes it out. And SDCC data on the 100–120 window. — Erica</p>
+    </div>
+    <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text the number. Our cohort: ~12k PSLF borrowers, 23% in the 100–120 window. Buyback wipes the gain above income cap — design flaw worth surfacing. — Natalia</textarea>
+    <div class="act"><button class="btn">Copy</button><button class="btn">Save Draft</button><button class="btn pri">Dispatch →</button></div>
+  </div>
+
+  <div class="row"><div class="plate"><span class="num">Fig. 3</span><span class="glyph">❀</span><span class="num" style="margin-top:4px;color:var(--leaf)">Partner</span></div><div><div class="head"><span class="name">Astra Taylor · Debt Collective</span><span class="latin">— soc. resistentia</span></div><h3 class="subj">Reading the new ED memo together?</h3><p class="prev">Want to do a joint statement if it lands the way we think.</p><div class="chips"><span class="ch">partners</span></div></div><div class="when">2 hr</div></div>
+</div></body></html>

← 93205f4 feat(inbox): 10 more theme mockups (v7-v16) + live theme dro  ·  back to Norma  ·  feat(modals): fan out ResizableModal to 22 modals across 15 ee9135a →