← back to Norma
feat(inbox): 10 more theme mockups (v7-v16) + live theme dropdown in GmailCRMTab
93205f4947f567855410d498f2a45f379ec15613 · 2026-05-20 13:00:56 -0700 · Steve Abrams
10 new visual directions, all wired as live themes:
v7 Spotify Dark — pure black, green accent
v8 Minimal Mono — black on white, Helvetica
v9 Newsprint — sepia broadsheet, drop-cap serif body
v10 Glassmorphism — frosted panels, cyan+pink neon on purple
v11 Terminal — green phosphor, monospace, scanline overlay
v12 Mochi Pastel — blush+lavender+mint, Nunito rounded
v13 High-Contrast A11y — Atkinson Hyperlegible, 18px floor, ≥48px tap
v14 Material 3 — purple primary, rounded, FAB send button
v15 Synthwave — magenta+cyan on indigo, retro-grid horizon
v16 Kanban Lanes — Trello palette (lane layout in mockup only)
All 16 (v1-v16) now selectable from a Theme dropdown in the GmailCRMTab
toolbar. Each option rewrites the Norma CSS tokens FOR THE INBOX ONLY
via .gmail-crm-tab[data-inbox-theme='…'] in globals.css — the rest of
the app keeps its base theme. Choice persists to localStorage as
norma.inbox-theme.
Note: structural layouts (3-pane v4, kanban v16, conversation v5) are
palette+typography swaps in the live toggle; the structural reshape
remains a future-prop component refactor. Full pixel-perfect mockups
stay at /mockups/inbox/v1-v16.html for reference.
Gallery: /mockups/inbox/index.html with all 16 in a side-by-side grid.
Files touched
M app/globals.cssM components/gmail/GmailCRMTab.tsxM public/mockups/inbox/index.htmlA public/mockups/inbox/v10-glassmorphism.htmlA public/mockups/inbox/v11-terminal.htmlA public/mockups/inbox/v12-mochi-pastel.htmlA public/mockups/inbox/v13-a11y-high-contrast.htmlA public/mockups/inbox/v14-material.htmlA public/mockups/inbox/v15-synthwave.htmlA public/mockups/inbox/v16-kanban-lanes.htmlA public/mockups/inbox/v7-spotify-dark.htmlA public/mockups/inbox/v8-minimal-mono.htmlA public/mockups/inbox/v9-newsprint.html
Diff
commit 93205f4947f567855410d498f2a45f379ec15613
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed May 20 13:00:56 2026 -0700
feat(inbox): 10 more theme mockups (v7-v16) + live theme dropdown in GmailCRMTab
10 new visual directions, all wired as live themes:
v7 Spotify Dark — pure black, green accent
v8 Minimal Mono — black on white, Helvetica
v9 Newsprint — sepia broadsheet, drop-cap serif body
v10 Glassmorphism — frosted panels, cyan+pink neon on purple
v11 Terminal — green phosphor, monospace, scanline overlay
v12 Mochi Pastel — blush+lavender+mint, Nunito rounded
v13 High-Contrast A11y — Atkinson Hyperlegible, 18px floor, ≥48px tap
v14 Material 3 — purple primary, rounded, FAB send button
v15 Synthwave — magenta+cyan on indigo, retro-grid horizon
v16 Kanban Lanes — Trello palette (lane layout in mockup only)
All 16 (v1-v16) now selectable from a Theme dropdown in the GmailCRMTab
toolbar. Each option rewrites the Norma CSS tokens FOR THE INBOX ONLY
via .gmail-crm-tab[data-inbox-theme='…'] in globals.css — the rest of
the app keeps its base theme. Choice persists to localStorage as
norma.inbox-theme.
Note: structural layouts (3-pane v4, kanban v16, conversation v5) are
palette+typography swaps in the live toggle; the structural reshape
remains a future-prop component refactor. Full pixel-perfect mockups
stay at /mockups/inbox/v1-v16.html for reference.
Gallery: /mockups/inbox/index.html with all 16 in a side-by-side grid.
---
app/globals.css | 134 ++++++++++++++++++++++
components/gmail/GmailCRMTab.tsx | 58 +++++++++-
public/mockups/inbox/index.html | 140 ++++++++++++-----------
public/mockups/inbox/v10-glassmorphism.html | 96 ++++++++++++++++
public/mockups/inbox/v11-terminal.html | 92 +++++++++++++++
public/mockups/inbox/v12-mochi-pastel.html | 100 ++++++++++++++++
public/mockups/inbox/v13-a11y-high-contrast.html | 97 ++++++++++++++++
public/mockups/inbox/v14-material.html | 129 +++++++++++++++++++++
public/mockups/inbox/v15-synthwave.html | 92 +++++++++++++++
public/mockups/inbox/v16-kanban-lanes.html | 124 ++++++++++++++++++++
public/mockups/inbox/v7-spotify-dark.html | 74 ++++++++++++
public/mockups/inbox/v8-minimal-mono.html | 71 ++++++++++++
public/mockups/inbox/v9-newsprint.html | 93 +++++++++++++++
13 files changed, 1233 insertions(+), 67 deletions(-)
diff --git a/app/globals.css b/app/globals.css
index 776c8d4..6c5688e 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1277,3 +1277,137 @@ body[data-band="elder"] button, body[data-band="elder"] .btn { min-height: 56px;
/* Smooth transitions when sliding the age bar */
body { transition: background-color 0.3s, color 0.3s; }
+
+/* ─────────────────────────────────────────────────────────────────────
+ INBOX THEMES — 16 live skins for GmailCRMTab.
+ Activated by data-inbox-theme on the .gmail-crm-tab wrapper from the
+ Theme dropdown inside the inbox toolbar. Each block re-scopes the Norma
+ CSS tokens FOR THE INBOX ONLY, so the rest of the app keeps its theme.
+ Source mockups: /public/mockups/inbox/v1-v16.html
+ ───────────────────────────────────────────────────────────────────── */
+
+/* v1 Classic Dense — current defaults, no overrides */
+
+/* v2 Notion Cards — light, generous, indigo accent */
+.gmail-crm-tab[data-inbox-theme="notion-cards"] {
+ --color-bg: #fafafa; --color-surface: #fff; --color-surface-el: #f4f4f5;
+ --color-text: #27272a; --color-text-secondary: #52525b; --color-text-muted: #71717a;
+ --color-border: #e4e4e7; --color-primary: #059669; --color-primary-hover: #047857;
+ font-family: -apple-system, BlinkMacSystemFont, "Inter", system-ui, sans-serif;
+}
+
+/* v3 Linear Keyboard — mono dark, purple accent */
+.gmail-crm-tab[data-inbox-theme="linear-keyboard"] {
+ --color-bg: #08090b; --color-surface: #0e0f12; --color-surface-el: #16181c;
+ --color-text: #e6e6eb; --color-text-secondary: #b4b6bc; --color-text-muted: #7a7d85;
+ --color-border: #22252b; --color-primary: #5e6ad2; --color-primary-hover: #4e58b8;
+ font-family: ui-sans-serif, "Inter", system-ui, sans-serif; letter-spacing: -0.005em;
+}
+
+/* v4 Apple Mail — light, sans, blue accent */
+.gmail-crm-tab[data-inbox-theme="apple-mail"] {
+ --color-bg: #f5f5f7; --color-surface: #fff; --color-surface-el: #f9f9fc;
+ --color-text: #1d1d1f; --color-text-secondary: #424245; --color-text-muted: #86868b;
+ --color-border: #d2d2d7; --color-primary: #0070f3; --color-primary-hover: #005bcb;
+ font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
+}
+
+/* v5 Front Conversation — dark teal */
+.gmail-crm-tab[data-inbox-theme="front-conversation"] {
+ --color-bg: #0d1119; --color-surface: #141925; --color-surface-el: #1d2434;
+ --color-text: #ebebef; --color-text-secondary: #b5bcd0; --color-text-muted: #8a92a8;
+ --color-border: #2a3148; --color-primary: #00d4ae; --color-primary-hover: #00b894;
+}
+
+/* v6 Hey Zero — warm cream + serif */
+.gmail-crm-tab[data-inbox-theme="hey-zero"] {
+ --color-bg: #faf8f3; --color-surface: #fff; --color-surface-el: #f1ede4;
+ --color-text: #1b1814; --color-text-secondary: #43382d; --color-text-muted: #7a6e5a;
+ --color-border: #e6dfd1; --color-primary: #c33; --color-primary-hover: #a82424;
+ font-family: "Source Serif Pro", Georgia, "Iowan Old Style", serif;
+}
+
+/* v7 Spotify Dark */
+.gmail-crm-tab[data-inbox-theme="spotify-dark"] {
+ --color-bg: #121212; --color-surface: #181818; --color-surface-el: #282828;
+ --color-text: #fff; --color-text-secondary: #d4d4d4; --color-text-muted: #a7a7a7;
+ --color-border: #2a2a2a; --color-primary: #1db954; --color-primary-hover: #1ed760;
+ font-family: "Circular", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
+}
+
+/* v8 Minimal Mono — black on white, Helvetica */
+.gmail-crm-tab[data-inbox-theme="minimal-mono"] {
+ --color-bg: #fff; --color-surface: #fff; --color-surface-el: #fafafa;
+ --color-text: #000; --color-text-secondary: #333; --color-text-muted: #666;
+ --color-border: #000; --color-primary: #000; --color-primary-hover: #333;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; letter-spacing: -0.005em;
+}
+
+/* v9 Newsprint — sepia broadsheet */
+.gmail-crm-tab[data-inbox-theme="newsprint"] {
+ --color-bg: #f1ebdc; --color-surface: #faf5e6; --color-surface-el: #ebe3cf;
+ --color-text: #1c1410; --color-text-secondary: #443a30; --color-text-muted: #6b5e4f;
+ --color-border: #a89678; --color-primary: #a8221c; --color-primary-hover: #8a1816;
+ font-family: "Adobe Caslon Pro", "Caslon", "Hoefler Text", Georgia, serif;
+}
+
+/* v10 Glassmorphism — translucent on purple gradient */
+.gmail-crm-tab[data-inbox-theme="glassmorphism"] {
+ --color-bg: #1a0a3a; --color-surface: rgba(255,255,255,0.06); --color-surface-el: rgba(255,255,255,0.10);
+ --color-text: #fff; --color-text-secondary: #d8d8ff; --color-text-muted: #c8c8ff;
+ --color-border: rgba(255,255,255,0.15); --color-primary: #7df9ff; --color-primary-hover: #5dd5dc;
+ background-image: radial-gradient(ellipse at 30% 20%, #4a1f8a 0%, #1a0a3a 50%, #050020 100%);
+}
+
+/* v11 Terminal — green phosphor, monospace */
+.gmail-crm-tab[data-inbox-theme="terminal"] {
+ --color-bg: #001100; --color-surface: #002211; --color-surface-el: #003322;
+ --color-text: #33ff66; --color-text-secondary: #28cc52; --color-text-muted: #1a7a33;
+ --color-border: #1a4a26; --color-primary: #33ff66; --color-primary-hover: #66ff99;
+ font-family: "Berkeley Mono", "JetBrains Mono", "SF Mono", ui-monospace, Menlo, monospace;
+ text-shadow: 0 0 3px rgba(51,255,102,0.3);
+}
+
+/* v12 Mochi Pastel — blush + lavender + mint */
+.gmail-crm-tab[data-inbox-theme="mochi-pastel"] {
+ --color-bg: #fdf6f3; --color-surface: #fff; --color-surface-el: #fef0eb;
+ --color-text: #3a2e2a; --color-text-secondary: #6a5a52; --color-text-muted: #9a8a82;
+ --color-border: #f0e0d8; --color-primary: #f0a3a3; --color-primary-hover: #e08a8a;
+ font-family: "Nunito", "Avenir Next", -apple-system, sans-serif;
+}
+
+/* v13 High-Contrast A11y — Atkinson Hyperlegible, 18px floor */
+.gmail-crm-tab[data-inbox-theme="a11y-high-contrast"] {
+ --color-bg: #fff; --color-surface: #fff; --color-surface-el: #fffacc;
+ --color-text: #000; --color-text-secondary: #000; --color-text-muted: #000;
+ --color-border: #000; --color-primary: #0030c8; --color-primary-hover: #001f88;
+ font-family: "Atkinson Hyperlegible", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 18px; line-height: 1.6;
+}
+.gmail-crm-tab[data-inbox-theme="a11y-high-contrast"] button { min-height: 48px; }
+
+/* v14 Material 3 — purple primary, rounded */
+.gmail-crm-tab[data-inbox-theme="material"] {
+ --color-bg: #f8f6fd; --color-surface: #fff; --color-surface-el: #ece7f4;
+ --color-text: #1c1b1f; --color-text-secondary: #313033; --color-text-muted: #49454f;
+ --color-border: #cac4d0; --color-primary: #6750a4; --color-primary-hover: #7c69b8;
+ font-family: "Roboto", "Roboto Flex", -apple-system, sans-serif;
+}
+
+/* v15 Synthwave — magenta + cyan on indigo */
+.gmail-crm-tab[data-inbox-theme="synthwave"] {
+ --color-bg: #1a0033; --color-surface: #2a005a; --color-surface-el: #3d0080;
+ --color-text: #ffd5ff; --color-text-secondary: #d8a8e8; --color-text-muted: #aa8acc;
+ --color-border: #5a0a8c; --color-primary: #ff2bff; --color-primary-hover: #ff66ff;
+ font-family: "Space Grotesk", "VT323", monospace, sans-serif;
+}
+
+/* v16 Kanban Lanes — Trello palette, light. Note: structural lane layout
+ is NOT applied via CSS-only; this theme provides palette+typography only.
+ To get the actual horizontal lanes, see /mockups/inbox/v16-kanban-lanes.html. */
+.gmail-crm-tab[data-inbox-theme="kanban-lanes"] {
+ --color-bg: #f4f5f7; --color-surface: #fff; --color-surface-el: #ebecf0;
+ --color-text: #172b4d; --color-text-secondary: #344563; --color-text-muted: #5e6c84;
+ --color-border: #dfe1e6; --color-primary: #0052cc; --color-primary-hover: #003d99;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
+}
diff --git a/components/gmail/GmailCRMTab.tsx b/components/gmail/GmailCRMTab.tsx
index 713b3d3..a6cf6f0 100644
--- a/components/gmail/GmailCRMTab.tsx
+++ b/components/gmail/GmailCRMTab.tsx
@@ -250,6 +250,37 @@ export default function GmailCRMTab() {
// today". Toggle stays in the toolbar so users can open it on demand.
const [showContacts, setShowContacts] = useState(false);
+ // 16 inbox theme skins keyed by data-inbox-theme. Persisted in localStorage.
+ // Each option rewrites the Norma CSS tokens FOR THE INBOX TAB ONLY via
+ // app/globals.css → .gmail-crm-tab[data-inbox-theme="..."] { ... }.
+ // Mockups live at /mockups/inbox/v1-v16.html for visual reference.
+ const INBOX_THEMES: Array<{ id: string; label: string; description: string }> = [
+ { id: 'classic-dense', label: '1 · Classic Dense', description: "Today's pattern, dark + dense" },
+ { id: 'notion-cards', label: '2 · Notion Cards', description: 'Light, generous, card-based' },
+ { id: 'linear-keyboard', label: '3 · Linear Keyboard', description: 'Mono dark, purple accent' },
+ { id: 'apple-mail', label: '4 · Apple Mail', description: 'Light, blue accent, traditional' },
+ { id: 'front-conversation', label: '5 · Front Conversation', description: 'Dark teal, assignee-first' },
+ { id: 'hey-zero', label: '6 · Hey Zero-Distraction', description: 'Editorial serif, warm cream' },
+ { id: 'spotify-dark', label: '7 · Spotify Dark', description: 'Pure black, green accent' },
+ { id: 'minimal-mono', label: '8 · Minimal Mono', description: 'Black on white, Helvetica' },
+ { id: 'newsprint', label: '9 · Newsprint', description: 'Sepia broadsheet, serif' },
+ { id: 'glassmorphism', label: '10 · Glassmorphism', description: 'Translucent on purple gradient' },
+ { id: 'terminal', label: '11 · Terminal', description: 'Green phosphor, monospace' },
+ { id: 'mochi-pastel', label: '12 · Mochi Pastel', description: 'Soft pastels, Nunito rounded' },
+ { id: 'a11y-high-contrast', label: '13 · High-Contrast A11y', description: 'Atkinson Hyperlegible, 18px floor' },
+ { 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)' },
+ ];
+ const [inboxTheme, setInboxTheme] = useState<string>('classic-dense');
+ // Hydrate from localStorage post-mount
+ useEffect(() => {
+ try { const s = localStorage.getItem('norma.inbox-theme'); if (s) setInboxTheme(s); } catch {}
+ }, []);
+ useEffect(() => {
+ try { localStorage.setItem('norma.inbox-theme', inboxTheme); } catch {}
+ }, [inboxTheme]);
+
const searchTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
/* ── Fetch sync status ──────────────────────────────────────────────────── */
@@ -520,7 +551,19 @@ export default function GmailCRMTab() {
const currentPage = Math.floor(offset / limit) + 1;
return (
- <div style={{ display: 'flex', flexDirection: 'column', height: 'calc(100vh - 56px)', overflow: 'hidden' }}>
+ <div
+ className="gmail-crm-tab"
+ data-inbox-theme={inboxTheme}
+ style={{
+ display: 'flex',
+ flexDirection: 'column',
+ height: 'calc(100vh - 56px)',
+ overflow: 'hidden',
+ // The CSS skin sets --color-bg, so this pulls the chosen theme background.
+ backgroundColor: 'var(--color-bg)',
+ color: 'var(--color-text)',
+ }}
+ >
{/* ── Top Bar ────────────────────────────────────────────────────────── */}
<div
style={{
@@ -874,6 +917,19 @@ export default function GmailCRMTab() {
</select>
)}
+ {/* Inbox theme dropdown — 16 visual treatments swappable live */}
+ <select
+ value={inboxTheme}
+ onChange={e => setInboxTheme(e.target.value)}
+ className="input"
+ style={{ fontSize: 12, padding: '4px 8px', minWidth: 200, maxWidth: 240 }}
+ title={INBOX_THEMES.find(t => t.id === inboxTheme)?.description || 'Inbox theme'}
+ >
+ {INBOX_THEMES.map(t => (
+ <option key={t.id} value={t.id}>🎨 Theme: {t.label}</option>
+ ))}
+ </select>
+
{/* Contacts toggle */}
<button
onClick={() => setShowContacts(p => !p)}
diff --git a/public/mockups/inbox/index.html b/public/mockups/inbox/index.html
index 96cad8b..5728194 100644
--- a/public/mockups/inbox/index.html
+++ b/public/mockups/inbox/index.html
@@ -4,103 +4,111 @@
<meta charset="utf-8">
<title>Inbox UI Variants — Norma</title>
<style>
- :root {
- --bg: #0c0f1a; --panel: #131829; --el: #1c2237;
- --fg: #f0f0f5; --muted: #a1a1b5; --line: #2a3048;
- --emerald: #10b981; --rose: #f43f5e; --amber: #f59e0b;
- }
- body { margin: 0; background: var(--bg); color: var(--fg); font: 14px/1.5 -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif; }
- header { padding: 32px 32px 12px; border-bottom: 1px solid var(--line); }
- h1 { margin: 0 0 6px; font-size: 24px; font-weight: 700; }
- .sub { color: var(--muted); font-size: 13px; }
- .grid {
- display: grid; gap: 16px; padding: 24px 32px;
- grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
- }
- .card {
- background: var(--panel); border: 1px solid var(--line);
- border-radius: 12px; padding: 0; overflow: hidden;
- transition: transform 0.18s, border-color 0.18s;
- }
- .card:hover { transform: translateY(-2px); border-color: var(--emerald); }
- .card a { display: block; color: inherit; text-decoration: none; }
- .frame {
- width: 100%; aspect-ratio: 16 / 10;
- background: linear-gradient(180deg, var(--el), #161a2c);
- display: flex; align-items: center; justify-content: center;
- color: var(--muted); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
- }
- iframe.preview { width: 100%; aspect-ratio: 16 / 10; border: 0; pointer-events: none; transform: scale(0.5); transform-origin: 0 0; width: 200%; height: 200%; }
- .frame-wrap { width: 100%; aspect-ratio: 16/10; overflow: hidden; position: relative; background: #fff; }
- .meta { padding: 14px 16px; }
- .name { font-size: 14px; font-weight: 700; margin: 0 0 4px; }
- .desc { color: var(--muted); font-size: 12px; line-height: 1.45; margin: 0; }
- .badges { margin-top: 8px; display: flex; gap: 6px; flex-wrap: wrap; }
- .badge { font-size: 10px; padding: 2px 8px; border-radius: 999px; background: var(--el); color: var(--muted); font-weight: 600; }
+ :root { --bg:#0c0f1a; --panel:#131829; --el:#1c2237; --fg:#f0f0f5; --muted:#a1a1b5; --line:#2a3048; --emerald:#10b981; }
+ body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.5 -apple-system,BlinkMacSystemFont,system-ui,sans-serif; }
+ header { padding:32px 32px 12px; border-bottom:1px solid var(--line); }
+ h1 { margin:0 0 6px; font-size:24px; font-weight:700; }
+ .sub { color:var(--muted); font-size:13px; }
+ .grid { display:grid; gap:16px; padding:24px 32px; grid-template-columns:repeat(auto-fill, minmax(360px, 1fr)); }
+ .card { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:0; overflow:hidden; transition:transform 0.18s, border-color 0.18s; }
+ .card:hover { transform:translateY(-2px); border-color:var(--emerald); }
+ .card a { display:block; color:inherit; text-decoration:none; }
+ .frame-wrap { width:100%; aspect-ratio:16/10; overflow:hidden; position:relative; background:#fff; }
+ iframe.preview { border:0; pointer-events:none; transform:scale(0.5); transform-origin:0 0; width:200%; height:200%; }
+ .meta { padding:14px 16px; }
+ .name { font-size:14px; font-weight:700; margin:0 0 4px; }
+ .desc { color:var(--muted); font-size:12px; line-height:1.45; margin:0; }
+ .badges { margin-top:8px; display:flex; gap:6px; flex-wrap:wrap; }
+ .badge { font-size:10px; padding:2px 8px; border-radius:999px; background:var(--el); color:var(--muted); font-weight:600; }
</style>
</head>
<body>
<header>
- <h1>Inbox UI Variants — 6 directions</h1>
- <p class="sub">Each mockup includes Assign-to dropdown, Read-by chips, inline-expand on click. Pick a direction or mix elements across them.</p>
+ <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>
</header>
<div class="grid">
<div class="card"><a href="v1-classic-dense.html" target="_blank">
<div class="frame-wrap"><iframe class="preview" src="v1-classic-dense.html"></iframe></div>
- <div class="meta">
- <div class="name">1 — Classic Dense</div>
- <p class="desc">Today's pattern, refined. Tight rows, full-bleed inline expansion, indigo assign chip + emerald seen pills. Familiar to anyone who's used Gmail.</p>
- <div class="badges"><span class="badge">familiar</span><span class="badge">dense</span><span class="badge">production-safe</span></div>
- </div>
+ <div class="meta"><div class="name">1 — Classic Dense</div><p class="desc">Today's pattern, refined. Tight rows, dark theme, indigo + emerald accents. Familiar to Gmail users.</p><div class="badges"><span class="badge">familiar</span><span class="badge">production-safe</span></div></div>
</a></div>
<div class="card"><a href="v2-notion-cards.html" target="_blank">
<div class="frame-wrap"><iframe class="preview" src="v2-notion-cards.html"></iframe></div>
- <div class="meta">
- <div class="name">2 — Notion Cards</div>
- <p class="desc">Each message is its own elevated card with generous padding. Tags and metadata live in the bottom strip. Best when each email is a "thing" being worked on.</p>
- <div class="badges"><span class="badge">generous</span><span class="badge">card-based</span><span class="badge">notion-vibe</span></div>
- </div>
+ <div class="meta"><div class="name">2 — Notion Cards</div><p class="desc">Light theme, elevated cards, generous whitespace. Each email feels like a thing being worked on.</p><div class="badges"><span class="badge">generous</span><span class="badge">notion-vibe</span></div></div>
</a></div>
<div class="card"><a href="v3-linear-keyboard.html" target="_blank">
<div class="frame-wrap"><iframe class="preview" src="v3-linear-keyboard.html"></iframe></div>
- <div class="meta">
- <div class="name">3 — Linear Keyboard</div>
- <p class="desc">Monochrome, keyboard-driven, status badge per message (Triage / Working / Replied / Snoozed). Type J/K to navigate, A to assign. Feels like a bug tracker for mail.</p>
- <div class="badges"><span class="badge">keyboard-first</span><span class="badge">status-machine</span><span class="badge">linear-vibe</span></div>
- </div>
+ <div class="meta"><div class="name">3 — Linear Keyboard</div><p class="desc">Monochrome, status-machine (Triage/Working/Replied/Snoozed), J/K nav. Bug-tracker for mail.</p><div class="badges"><span class="badge">keyboard-first</span><span class="badge">linear-vibe</span></div></div>
</a></div>
<div class="card"><a href="v4-apple-mail.html" target="_blank">
<div class="frame-wrap"><iframe class="preview" src="v4-apple-mail.html"></iframe></div>
- <div class="meta">
- <div class="name">4 — Apple Mail</div>
- <p class="desc">Three-pane classic: mailboxes left, conversation list center, reading pane right. Best for high volume + multi-mailbox future where natalia@/info@/donors@ each need their own column.</p>
- <div class="badges"><span class="badge">3-pane</span><span class="badge">multi-mailbox</span><span class="badge">traditional</span></div>
- </div>
+ <div class="meta"><div class="name">4 — Apple Mail</div><p class="desc">3-pane (mailboxes | list | reading). Best for multi-mailbox (natalia@/info@/donors@).</p><div class="badges"><span class="badge">3-pane</span><span class="badge">traditional</span></div></div>
</a></div>
<div class="card"><a href="v5-front-conversation.html" target="_blank">
<div class="frame-wrap"><iframe class="preview" src="v5-front-conversation.html"></iframe></div>
- <div class="meta">
- <div class="name">5 — Front Conversation</div>
- <p class="desc">Assignee is THE primary axis — every row leads with the assignee's avatar. Group inbox view (Unassigned / Mine / Team). Thread-of-conversation reading pane with collision detection.</p>
- <div class="badges"><span class="badge">assignee-first</span><span class="badge">team-inbox</span><span class="badge">front-vibe</span></div>
- </div>
+ <div class="meta"><div class="name">5 — Front Conversation</div><p class="desc">Assignee avatar leads every row. Team inbox, internal notes, collision detection.</p><div class="badges"><span class="badge">assignee-first</span><span class="badge">team-inbox</span></div></div>
</a></div>
<div class="card"><a href="v6-hey-zero.html" target="_blank">
<div class="frame-wrap"><iframe class="preview" src="v6-hey-zero.html"></iframe></div>
- <div class="meta">
- <div class="name">6 — Hey Zero-Distraction</div>
- <p class="desc">Big typography, white background, sender-name dominant. "Imbox" → "Feed" → "Paper Trail" buckets. Reply Later stack. Focus over volume — for the slow inbox.</p>
- <div class="badges"><span class="badge">editorial</span><span class="badge">light-mode</span><span class="badge">hey.com-vibe</span></div>
- </div>
+ <div class="meta"><div class="name">6 — Hey Zero-Distraction</div><p class="desc">Editorial serif, Imbox/Feed/Paper Trail buckets, slow-mail vibe.</p><div class="badges"><span class="badge">editorial</span><span class="badge">hey-vibe</span></div></div>
</a></div>
-</div>
+<div class="card"><a href="v7-spotify-dark.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v7-spotify-dark.html"></iframe></div>
+ <div class="meta"><div class="name">7 — Spotify Dark</div><p class="desc">Pure black, big square avatars, signature green CTA. Reading pane like an album-page.</p><div class="badges"><span class="badge">music-app-vibe</span><span class="badge">media-rich</span></div></div>
+</a></div>
+
+<div class="card"><a href="v8-minimal-mono.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v8-minimal-mono.html"></iframe></div>
+ <div class="meta"><div class="name">8 — Minimal Mono</div><p class="desc">Black on white. Helvetica. No accent color. Tight, brutalist-minimal.</p><div class="badges"><span class="badge">monochrome</span><span class="badge">brutalist-minimal</span></div></div>
+</a></div>
+
+<div class="card"><a href="v9-newsprint.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v9-newsprint.html"></iframe></div>
+ <div class="meta"><div class="name">9 — Newsprint</div><p class="desc">Old-school broadsheet masthead. Serif body, drop caps, sepia. The Daily Norma.</p><div class="badges"><span class="badge">editorial</span><span class="badge">vintage</span></div></div>
+</a></div>
+<div class="card"><a href="v10-glassmorphism.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v10-glassmorphism.html"></iframe></div>
+ <div class="meta"><div class="name">10 — Glassmorphism</div><p class="desc">Translucent frosted panels, neon edges (cyan + pink), gradient text. Vision-OS feel.</p><div class="badges"><span class="badge">frosted</span><span class="badge">visionos-vibe</span></div></div>
+</a></div>
+
+<div class="card"><a href="v11-terminal.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v11-terminal.html"></iframe></div>
+ <div class="meta"><div class="name">11 — Terminal</div><p class="desc">Green phosphor on black, monospace, scanline overlay. Hacker-aesthetic. Power users only.</p><div class="badges"><span class="badge">terminal</span><span class="badge">monospace</span></div></div>
+</a></div>
+
+<div class="card"><a href="v12-mochi-pastel.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v12-mochi-pastel.html"></iframe></div>
+ <div class="meta"><div class="name">12 — Mochi Pastel</div><p class="desc">Soft pastels (blush/lavender/mint), Nunito rounded type, generous padding. Gentle vibe.</p><div class="badges"><span class="badge">soft</span><span class="badge">friendly</span></div></div>
+</a></div>
+
+<div class="card"><a href="v13-a11y-high-contrast.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v13-a11y-high-contrast.html"></iframe></div>
+ <div class="meta"><div class="name">13 — High-Contrast A11y</div><p class="desc">Atkinson Hyperlegible, 18px floor, thick black borders, ≥48px tap targets. WCAG-friendly.</p><div class="badges"><span class="badge">accessible</span><span class="badge">large-text</span></div></div>
+</a></div>
+
+<div class="card"><a href="v14-material.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v14-material.html"></iframe></div>
+ <div class="meta"><div class="name">14 — Material 3</div><p class="desc">Google M3 — rounded corners, purple primary, search chip header, FAB send button.</p><div class="badges"><span class="badge">android-vibe</span><span class="badge">m3</span></div></div>
+</a></div>
+
+<div class="card"><a href="v15-synthwave.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v15-synthwave.html"></iframe></div>
+ <div class="meta"><div class="name">15 — Synthwave Retro</div><p class="desc">Magenta + cyan on indigo. Retro-grid horizon. 80s neon. Doom-rave.</p><div class="badges"><span class="badge">retro-80s</span><span class="badge">neon</span></div></div>
+</a></div>
+
+<div class="card"><a href="v16-kanban-lanes.html" target="_blank">
+ <div class="frame-wrap"><iframe class="preview" src="v16-kanban-lanes.html"></iframe></div>
+ <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>
</body>
</html>
diff --git a/public/mockups/inbox/v10-glassmorphism.html b/public/mockups/inbox/v10-glassmorphism.html
new file mode 100644
index 0000000..2b7792d
--- /dev/null
+++ b/public/mockups/inbox/v10-glassmorphism.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v10 — Glassmorphism — Norma Inbox</title>
+<style>
+ :root { --fg:#fff; --muted:#c8c8ff; --line:rgba(255,255,255,0.15); --neon:#7df9ff; --pink:#ff6ec7; --gold:#ffd966; }
+ * { box-sizing:border-box; }
+ html,body { margin:0; height:100%; }
+ body { background:radial-gradient(ellipse at 30% 20%, #4a1f8a 0%, #1a0a3a 50%, #050020 100%), #050020; color:var(--fg); font:14px/1.5 -apple-system,BlinkMacSystemFont,system-ui,sans-serif; min-height:100vh; }
+ .glass { background:rgba(255,255,255,0.06); backdrop-filter:blur(20px) saturate(160%); -webkit-backdrop-filter:blur(20px) saturate(160%); border:1px solid var(--line); border-radius:16px; box-shadow:0 8px 32px rgba(0,0,0,0.25); }
+ .top { padding:14px 24px; display:flex; gap:14px; align-items:center; }
+ .top h1 { margin:0; font-size:22px; font-weight:700; flex:1; background:linear-gradient(90deg,var(--neon),var(--pink)); -webkit-background-clip:text; background-clip:text; color:transparent; }
+ .pill { font-size:12px; padding:6px 14px; border-radius:999px; background:rgba(255,255,255,0.08); border:1px solid var(--line); cursor:pointer; color:var(--fg); }
+ .pill.on { background:rgba(125,249,255,0.18); border-color:var(--neon); color:var(--neon); }
+ .stack { padding:18px 24px 40px; display:flex; flex-direction:column; gap:14px; }
+ .item { padding:14px 18px; cursor:pointer; transition:transform 0.18s, box-shadow 0.18s; }
+ .item:hover { transform:translateY(-2px); box-shadow:0 12px 36px rgba(125,249,255,0.18); }
+ .item.on { border-color:var(--neon); box-shadow:0 0 32px rgba(125,249,255,0.25); }
+ .row1 { display:flex; gap:10px; align-items:center; }
+ .ava { width:34px; height:34px; border-radius:50%; background:linear-gradient(135deg,var(--pink),var(--neon)); display:flex; align-items:center; justify-content:center; font-weight:700; font-size:13px; color:#150733; }
+ .from { font-weight:700; font-size:14px; flex:1; }
+ .when { font-size:11.5px; color:var(--muted); }
+ .subj { font-size:14.5px; margin:4px 0 2px; font-weight:600; }
+ .prev { font-size:12.5px; color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+ .chips { display:flex; gap:5px; margin-top:6px; flex-wrap:wrap; }
+ .chip { font-size:10px; padding:2px 9px; border-radius:999px; font-weight:700; }
+ .c-press { background:rgba(255,110,199,0.2); color:var(--pink); border:1px solid rgba(255,110,199,0.4); }
+ .c-policy { background:rgba(125,249,255,0.15); color:var(--neon); border:1px solid rgba(125,249,255,0.4); }
+ .c-assign { background:rgba(255,217,102,0.15); color:var(--gold); border:1px solid rgba(255,217,102,0.4); }
+ .c-seen { background:rgba(125,255,180,0.15); color:#7dffb4; border:1px solid rgba(125,255,180,0.4); }
+ /* Expanded */
+ .expand { padding:28px 30px; }
+ .exp-head h2 { margin:0; font-size:24px; font-weight:700; letter-spacing:-0.01em; }
+ .meta { display:grid; grid-template-columns:90px 1fr; gap:6px 14px; font-size:13px; margin:18px 0 22px; color:var(--muted); }
+ .meta strong { color:var(--fg); font-weight:600; }
+ select.assign { background:rgba(255,255,255,0.08); border:1px solid var(--line); color:var(--fg); font:13px inherit; padding:5px 12px; border-radius:999px; backdrop-filter:blur(10px); }
+ .seen-list { display:flex; gap:6px; flex-wrap:wrap; }
+ .seen-pill { font-size:11.5px; padding:3px 11px; border-radius:999px; background:rgba(125,255,180,0.12); color:#7dffb4; border:1px solid rgba(125,255,180,0.3); display:inline-flex; gap:5px; align-items:center; }
+ .body-card { background:rgba(0,0,0,0.18); border-radius:12px; padding:18px 20px; font-size:14.5px; line-height:1.7; }
+ .ai-card { margin-top:18px; padding:18px 20px; border-radius:12px; background:linear-gradient(180deg, rgba(255,110,199,0.05), rgba(125,249,255,0.05)); border:1px solid var(--line); }
+ .ai-card h4 { margin:0 0 10px; font-size:13px; font-weight:700; color:var(--neon); display:flex; align-items:center; gap:8px; }
+ textarea { width:100%; background:rgba(0,0,0,0.25); border:1px solid var(--line); color:var(--fg); border-radius:8px; padding:12px 14px; font:14px inherit; resize:vertical; min-height:100px; }
+ textarea:focus { outline:none; border-color:var(--neon); box-shadow:0 0 0 3px rgba(125,249,255,0.18); }
+ .act { display:flex; gap:8px; margin-top:12px; }
+ .btn { font:12.5px inherit; padding:7px 16px; border-radius:999px; border:1px solid var(--line); background:rgba(255,255,255,0.06); color:var(--fg); cursor:pointer; font-weight:600; }
+ .btn.pri { background:linear-gradient(90deg,var(--neon),var(--pink)); border:none; color:#150733; margin-left:auto; font-weight:800; }
+</style>
+</head><body>
+
+<div class="top glass" style="border-radius:0;border-left:none;border-right:none;border-top:none;backdrop-filter:none;background:rgba(255,255,255,0.04)">
+ <h1>◇ Inbox</h1>
+ <span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><button class="pill" style="background:linear-gradient(90deg,var(--neon),var(--pink));color:#150733;font-weight:700;border:none">↻ Sync</button>
+</div>
+
+<div class="stack">
+
+<div class="item glass">
+ <div class="row1"><div class="ava">BS</div><span class="from">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. Aide on this thread.</div>
+ <div class="chips"><span class="chip c-policy">POLICY</span><span class="chip c-assign">⌥ Natalia</span></div>
+</div>
+
+<div class="item glass on">
+ <div class="row1"><div class="ava" style="background:linear-gradient(135deg,var(--pink),#ff256e)">EW</div><span class="from">Erica Werner · Washington Post</span><span class="when">42m ago</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. 20 min by 4pm?</div>
+ <div class="chips"><span class="chip c-press">PRESS</span><span class="chip c-assign">⌥ Natalia</span><span class="chip c-seen">✓ 2 seen</span></div>
+
+ <div class="expand" style="margin:18px -18px -14px;background:rgba(0,0,0,0.18);border-radius:12px;padding-bottom:30px">
+ <div class="exp-head"><h2>Quote request — Dept of Ed PSLF guidance</h2></div>
+ <div class="meta">
+ <span>From</span><strong>Erica Werner <erica@washpost.com></strong>
+ <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option><option>— Unassigned —</option></select></span>
+ <span>Seen by</span><div class="seen-list"><span class="seen-pill">✓ Natalia · 3:21</span><span class="seen-pill">✓ Cody · 3:24</span></div>
+ </div>
+ <div class="body-card">
+ 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) Your read on whether borrowers between 100-120 of payment get a meaningful benefit.<br>
+ 2) Any data on how many borrowers are caught in this window?<br><br>
+ — Erica
+ </div>
+ <div class="ai-card">
+ <h4>✦ AI suggested reply</h4>
+ <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text you a number. Our cohort: ~12k PSLF borrowers, 23% in the 100-120 window. Buyback math wipes the gain above income cap — known 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>
+
+<div class="item glass">
+ <div class="row1"><div class="ava" style="background:linear-gradient(135deg,var(--gold),#d4a437)">AT</div><span class="from">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 the way we think it will.</div>
+</div>
+
+</div>
+</body></html>
diff --git a/public/mockups/inbox/v11-terminal.html b/public/mockups/inbox/v11-terminal.html
new file mode 100644
index 0000000..717f751
--- /dev/null
+++ b/public/mockups/inbox/v11-terminal.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v11 — Terminal — Norma Inbox</title>
+<style>
+ :root { --bg:#001100; --el:#002211; --fg:#33ff66; --dim:#1a7a33; --line:#1a4a26; --amber:#ffb86c; --red:#ff5577; }
+ * { box-sizing:border-box; }
+ body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.4 "Berkeley Mono", "JetBrains Mono", "SF Mono", ui-monospace, Menlo, monospace; text-shadow:0 0 3px rgba(51,255,102,0.4); }
+ body::before { content:""; position:fixed; inset:0; background:repeating-linear-gradient(0deg, rgba(0,0,0,0) 0px, rgba(0,0,0,0) 2px, rgba(0,0,0,0.18) 2px, rgba(0,0,0,0.18) 3px); pointer-events:none; z-index:1000; }
+ .top { padding:12px 24px; border-bottom:1px solid var(--line); display:flex; gap:18px; align-items:center; }
+ .top h1 { margin:0; font-size:14px; font-weight:700; color:var(--fg); flex:1; }
+ .top h1::before { content:"$ "; color:var(--amber); }
+ .pill { font-size:12px; padding:3px 10px; border:1px solid var(--line); background:transparent; color:var(--dim); cursor:pointer; }
+ .pill.on { background:var(--fg); color:var(--bg); border-color:var(--fg); }
+ .list { padding:8px 24px; }
+ .row { padding:5px 0; display:grid; grid-template-columns:40px 1fr 200px 100px 60px; gap:14px; cursor:pointer; border-bottom:1px dashed var(--line); align-items:center; }
+ .row:hover { background:var(--el); }
+ .row.on { background:rgba(51,255,102,0.08); }
+ .row .id { color:var(--dim); font-size:12px; }
+ .row .from { font-weight:700; }
+ .row .subj { color:var(--fg); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+ .row .subj::before { content:"│ "; color:var(--dim); }
+ .row .meta-r { color:var(--dim); font-size:12px; text-align:right; }
+ .row .when { color:var(--dim); font-size:12px; text-align:right; }
+ .row.hi .id, .row.hi .from { color:var(--red); }
+ .chips { display:inline-flex; gap:4px; }
+ .chip { font-size:10.5px; padding:1px 6px; border:1px solid var(--line); }
+ .chip.alert { color:var(--red); border-color:var(--red); }
+ .chip.assn { color:var(--amber); border-color:var(--amber); }
+ .chip.seen { color:var(--fg); border-color:var(--fg); }
+ /* expand */
+ .expand { padding:14px 24px 26px; background:var(--el); border-top:1px dashed var(--fg); border-bottom:1px dashed var(--fg); }
+ .expand h2 { margin:0 0 4px; font-size:18px; font-weight:700; }
+ .expand h2::before { content:"┌─ "; color:var(--amber); }
+ .meta-block { font-size:13px; line-height:1.7; margin:12px 0 14px; }
+ .meta-block .k { color:var(--dim); display:inline-block; min-width:110px; }
+ .meta-block select { background:var(--bg); border:1px solid var(--line); color:var(--fg); font:13px inherit; padding:2px 8px; }
+ .seen-pill { display:inline-block; padding:1px 8px; border:1px solid var(--fg); color:var(--fg); margin-right:4px; font-size:12px; }
+ .body { background:var(--bg); border:1px solid var(--line); padding:14px 16px; font-size:13.5px; line-height:1.65; white-space:pre-wrap; }
+ .body::before { content:"---- BEGIN MESSAGE BODY ----\A"; color:var(--dim); white-space:pre; }
+ .body::after { content:"\A---- END MESSAGE BODY ----"; color:var(--dim); white-space:pre; }
+ .reply { margin-top:16px; }
+ .reply label { color:var(--amber); font-weight:700; }
+ textarea { width:100%; background:var(--bg); border:1px solid var(--line); color:var(--fg); font:14px/1.55 inherit; padding:10px 12px; resize:vertical; min-height:100px; margin-top:6px; }
+ textarea:focus { outline:none; border-color:var(--fg); }
+ .act { display:flex; gap:10px; margin-top:10px; }
+ .btn { font:12.5px inherit; padding:4px 14px; border:1px solid var(--line); background:transparent; color:var(--fg); cursor:pointer; font-weight:700; }
+ .btn:hover { background:var(--fg); color:var(--bg); }
+ .btn.pri { border-color:var(--fg); color:var(--fg); margin-left:auto; }
+ .btn.pri:hover { background:var(--fg); color:var(--bg); }
+</style>
+</head><body>
+<div class="top"><h1>norma --inbox 2026-05-20 14:42 PT · uid:natalia</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="list">
+<div class="row hi"><span class="id">[001]</span><span class="from">sanders.senate.gov</span><span class="subj"><strong>RE: Markup tomorrow — borrower bill</strong></span><span class="meta-r"><span class="chip alert">HIGH</span> <span class="chip assn">@nat</span></span><span></span><span class="when">14m</span></div>
+<div class="row hi on"><span class="id">[002]</span><span class="from">erica@washpost.com</span><span class="subj"><strong>Quote request — Dept of Ed PSLF guidance</strong></span><span class="meta-r"><span class="chip alert">HIGH</span> <span class="chip assn">@nat</span></span><span class="chips"><span class="chip seen">✓2</span></span><span class="when">42m</span></div>
+
+<div class="expand">
+ <h2>Quote request — Dept of Ed PSLF guidance</h2>
+ <div style="color:var(--dim);font-size:12px">└─ Erica Werner <erica@washpost.com> → natalia@studentdebtcrisis.org · 2026-05-20T15:18-04:00 PT</div>
+ <div class="meta-block">
+ <div><span class="k">owner :</span> <select><option>natalia (admin)</option><option>cody (staff)</option><option>jess (intern)</option><option>— unassigned —</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">labels :</span> press, important</div>
+ <div><span class="k">priority :</span> <span style="color:var(--red)">HIGH</span></div>
+ </div>
+ <div class="body">Hi Natalia,
+
+Running a piece tomorrow on the new PSLF buyback guidance that came out
+this morning. Two questions if you have 20 min by 4pm ET:
+
+1) Your read on whether borrowers between months 100-120 of payment
+ actually get a meaningful benefit, or whether the buyback math
+ wipes it out.
+
+2) Any data points from SDCC on how many borrowers are caught in this
+ 100-120 window?
+
+Happy to do email if a call doesn't work. Thanks!
+— Erica</div>
+
+ <div class="reply">
+ <label>$ reply --tone professional</label>
+ <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text the number.
+Data: ~12k PSLF borrowers, 23% in the 100-120 window. Buyback math wipes
+the gain above income cap — known design flaw. — Natalia</textarea>
+ <div class="act"><button class="btn">copy</button><button class="btn">save</button><button class="btn pri">send</button></div>
+ </div>
+</div>
+
+<div class="row"><span class="id">[003]</span><span class="from">astra@debtcollective.org</span><span class="subj">Reading the new ED memo together?</span><span class="meta-r"><span class="chip assn">@cody</span></span><span></span><span class="when">2h</span></div>
+<div class="row"><span class="id">[004]</span><span class="from">marcus.huang@umich.edu</span><span class="subj">Borrower story — graduated 2018, default at 27</span><span class="meta-r">stories</span><span></span><span class="when">1d</span></div>
+<div class="row"><span class="id">[005]</span><span class="from">noreply@bls.gov</span><span class="subj">[Newsletter] BLS monthly employment data — Apr 2026</span><span class="meta-r">promo</span><span></span><span class="when">1d</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v12-mochi-pastel.html b/public/mockups/inbox/v12-mochi-pastel.html
new file mode 100644
index 0000000..7b0d6ec
--- /dev/null
+++ b/public/mockups/inbox/v12-mochi-pastel.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v12 — Mochi Pastel — Norma Inbox</title>
+<style>
+ :root { --bg:#fdf6f3; --panel:#fff; --el:#fef0eb; --fg:#3a2e2a; --muted:#9a8a82; --line:#f0e0d8; --blush:#f0a3a3; --lav:#c5b8e8; --mint:#a8d8b9; --sun:#f5d77c; }
+ * { box-sizing:border-box; }
+ body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.55 "Nunito", "Avenir Next", -apple-system, sans-serif; }
+ .top { padding:16px 28px; background:var(--panel); border-bottom:1px solid var(--line); display:flex; gap:12px; align-items:center; }
+ .top h1 { margin:0; font-size:22px; font-weight:800; flex:1; color:var(--fg); display:flex; align-items:center; gap:8px; }
+ .pill { font-size:12.5px; padding:6px 14px; border-radius:999px; background:var(--el); border:1px solid var(--line); color:var(--fg); font-weight:600; cursor:pointer; }
+ .pill.on { background:var(--blush); border-color:var(--blush); color:#fff; }
+ .pill.sync { background:var(--mint); border-color:var(--mint); color:#fff; font-weight:700; }
+ .grid { padding:20px 28px 60px; display:flex; flex-direction:column; gap:12px; max-width:920px; margin:0 auto; }
+ .card { background:var(--panel); border-radius:18px; padding:16px 20px; border:1.5px solid var(--line); cursor:pointer; transition:transform 0.15s, box-shadow 0.15s; }
+ .card:hover { transform:translateY(-2px); box-shadow:0 8px 20px rgba(58,46,42,0.08); }
+ .card.on { border-color:var(--blush); box-shadow:0 8px 32px rgba(240,163,163,0.2); }
+ .meta { display:flex; gap:10px; align-items:center; font-size:12.5px; color:var(--muted); margin-bottom:6px; }
+ .ava { width:30px; height:30px; border-radius:50%; background:var(--lav); color:#fff; display:flex; align-items:center; justify-content:center; font-weight:800; font-size:13px; }
+ .name { color:var(--fg); font-weight:800; font-size:14px; }
+ .when { margin-left:auto; }
+ .subj { font-size:15px; font-weight:700; margin:2px 0 2px; }
+ .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:3px 10px; border-radius:999px; font-weight:700; }
+ .c-press { background:rgba(240,163,163,0.25); color:#c45c5c; }
+ .c-policy { background:rgba(197,184,232,0.3); color:#7b6bb8; }
+ .c-partner { background:rgba(168,216,185,0.3); color:#4f8a64; }
+ .c-stories { background:rgba(245,215,124,0.3); color:#a67e1e; }
+ .c-assign { background:var(--el); color:var(--fg); display:inline-flex; gap:4px; align-items:center; padding-left:4px; }
+ .c-seen { background:rgba(168,216,185,0.3); color:#4f8a64; }
+ .mini-ava { width:18px; height:18px; border-radius:50%; background:var(--lav); color:#fff; font-size:9.5px; display:flex; align-items:center; justify-content:center; font-weight:800; }
+
+ /* Expanded */
+ .expand { padding:22px 26px 26px; }
+ .exp-head h2 { margin:0 0 4px; font-size:22px; font-weight:800; letter-spacing:-0.005em; }
+ .meta-grid { display:grid; grid-template-columns:80px 1fr; gap:6px 14px; font-size:13px; margin:14px 0 16px; color:var(--muted); }
+ .meta-grid strong { color:var(--fg); font-weight:700; }
+ select.assign { background:var(--bg); border:1.5px solid var(--line); color:var(--fg); font:13px inherit; padding:5px 11px; border-radius:999px; font-weight:600; }
+ .seen-pill { font-size:12px; padding:3px 11px; border-radius:999px; background:rgba(168,216,185,0.3); color:#4f8a64; display:inline-flex; gap:5px; align-items:center; font-weight:600; }
+ .body-card { background:var(--el); border-radius:14px; padding:16px 18px; font-size:14px; line-height:1.7; }
+ .ai-card { margin-top:14px; padding:16px 18px; border-radius:14px; background:linear-gradient(135deg, rgba(197,184,232,0.18), rgba(168,216,185,0.18)); border:1.5px solid var(--line); }
+ .ai-card h4 { margin:0 0 8px; font-size:13px; font-weight:800; color:var(--fg); display:flex; align-items:center; gap:6px; }
+ textarea { width:100%; background:var(--panel); border:1.5px solid var(--line); border-radius:12px; padding:11px 14px; font:13.5px/1.6 inherit; resize:vertical; min-height:90px; color:var(--fg); }
+ .act { display:flex; gap:8px; margin-top:12px; }
+ .btn { font:12.5px inherit; padding:7px 18px; border-radius:999px; border:1.5px solid var(--line); background:var(--panel); color:var(--fg); cursor:pointer; font-weight:700; }
+ .btn.pri { background:var(--blush); color:#fff; border-color:var(--blush); margin-left:auto; }
+</style>
+</head><body>
+
+<div class="top"><h1>🌸 Norma Mail</h1><span class="pill on">All</span><span class="pill">Unread</span><span class="pill">Mine</span><button class="pill sync">↻ Sync</button></div>
+
+<div class="grid">
+
+<div class="card">
+ <div class="meta"><div class="ava" style="background:var(--lav)">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">Natalia — Senator can do a quick call before 9am ET. Aide on this thread.</div>
+ <div class="chips"><span class="chip c-policy">policy</span><span class="chip c-assign"><span class="mini-ava">N</span> Natalia</span></div>
+</div>
+
+<div class="card on">
+ <div class="meta"><div class="ava" style="background:var(--blush)">EW</div><span class="name">Erica Werner · Washington Post</span><span class="when">42m ago</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. 20 min by 4pm?</div>
+ <div class="chips"><span class="chip c-press">press</span><span class="chip c-assign"><span class="mini-ava">N</span> Natalia</span><span class="chip c-seen">✿ Seen ×2</span></div>
+
+ <div class="expand">
+ <div class="exp-head"><h2>Quote request — Dept of Ed PSLF guidance</h2></div>
+ <div class="meta-grid">
+ <span>From</span><strong>Erica Werner <erica@washpost.com></strong>
+ <span>Owner</span><span><select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option><option>— Unassigned —</option></select></span>
+ <span>Seen by</span><span style="display:flex;gap:5px;flex-wrap:wrap"><span class="seen-pill">✿ Natalia · 3:21</span><span class="seen-pill">✿ Cody · 3:24</span></span>
+ </div>
+ <div class="body-card">
+ 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) Your read on whether borrowers between 100-120 of payment get a meaningful benefit.<br>
+ 2) Any data on how many borrowers are caught in this 100-120 window?<br><br>— Erica
+ </div>
+ <div class="ai-card">
+ <h4>✨ Sweet draft reply</h4>
+ <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 math wipes the gain above income cap — known 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>
+
+<div class="card">
+ <div class="meta"><div class="ava" style="background:var(--mint)">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 the way we think it will.</div>
+ <div class="chips"><span class="chip c-partner">partners</span><span class="chip c-assign"><span class="mini-ava" style="background:var(--sun)">C</span> Cody</span></div>
+</div>
+
+<div class="card">
+ <div class="meta"><div class="ava" style="background:var(--sun)">MH</div><span class="name">Marcus Huang</span><span class="when">Yesterday</span></div>
+ <div class="subj">Borrower story — graduated 2018, default at 27</div>
+ <div class="prev">Saw your work on PBS NewsHour. I'd like to share my story.</div>
+ <div class="chips"><span class="chip c-stories">stories</span></div>
+</div>
+
+</div></body></html>
diff --git a/public/mockups/inbox/v13-a11y-high-contrast.html b/public/mockups/inbox/v13-a11y-high-contrast.html
new file mode 100644
index 0000000..1b0da61
--- /dev/null
+++ b/public/mockups/inbox/v13-a11y-high-contrast.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v13 — High Contrast A11y — Norma Inbox</title>
+<style>
+ :root { --bg:#fff; --fg:#000; --muted:#000; --line:#000; --blue:#0030c8; --red:#c40000; --green:#00642e; }
+ * { box-sizing:border-box; }
+ body { margin:0; background:var(--bg); color:var(--fg); font:18px/1.6 "Atkinson Hyperlegible", "Helvetica Neue", Helvetica, Arial, sans-serif; }
+ a, button, select { font:18px/1.5 inherit; }
+ .top { padding:18px 28px; border-bottom:3px solid var(--fg); display:flex; gap:18px; align-items:center; flex-wrap:wrap; }
+ .top h1 { margin:0; font-size:32px; font-weight:900; flex:1; }
+ .btn { font-size:17px; padding:12px 22px; border:2px solid var(--fg); background:var(--bg); color:var(--fg); cursor:pointer; font-weight:700; min-height:48px; }
+ .btn.on, .btn:focus { background:var(--fg); color:var(--bg); outline:3px solid var(--blue); outline-offset:2px; }
+ .btn.sync { background:var(--green); color:var(--bg); border-color:var(--green); }
+ .list { padding:0; }
+ .row { padding:24px 28px; border-bottom:2px solid var(--fg); cursor:pointer; }
+ .row:hover, .row:focus-within { background:#fff5b3; outline:3px solid var(--fg); outline-offset:-3px; }
+ .row.on { background:#fffacc; border-left:8px solid var(--fg); padding-left:20px; }
+ .row.unread { border-left:8px solid var(--red); padding-left:20px; }
+ .meta-line { font-size:16px; margin-bottom:8px; }
+ .meta-line strong { font-weight:900; font-size:20px; }
+ .when { font-weight:700; margin-left:10px; }
+ .subj { font-size:22px; font-weight:900; line-height:1.3; margin:0 0 6px; }
+ .prev { font-size:17px; }
+ .chips { margin-top:12px; display:flex; gap:12px; flex-wrap:wrap; }
+ .chip { font-size:16px; font-weight:900; padding:6px 14px; border:2px solid var(--fg); text-transform:uppercase; letter-spacing:0.03em; }
+ .chip.urgent { background:var(--red); color:#fff; border-color:var(--red); }
+ .chip.assign { background:var(--blue); color:#fff; border-color:var(--blue); }
+ .chip.seen { background:var(--green); color:#fff; border-color:var(--green); }
+ /* expand */
+ .expand { padding:36px 28px; background:#fffacc; border-top:3px solid var(--fg); border-bottom:3px solid var(--fg); }
+ .expand h2 { margin:0 0 8px; font-size:32px; font-weight:900; }
+ .meta-block { font-size:18px; line-height:2; margin:24px 0 28px; padding:18px 22px; background:var(--bg); border:2px solid var(--fg); }
+ .meta-block .k { font-weight:900; min-width:130px; display:inline-block; }
+ select.assign { font:18px inherit; padding:10px 14px; border:2px solid var(--fg); background:var(--bg); min-height:48px; }
+ .seen-pill { display:inline-block; padding:8px 16px; background:var(--green); color:#fff; font-weight:900; font-size:16px; margin-right:8px; }
+ .body { font-size:20px; line-height:1.75; max-width:680px; }
+ .body p { margin:0 0 16px; }
+ textarea { width:100%; font:19px/1.65 inherit; padding:18px; border:3px solid var(--fg); background:var(--bg); resize:vertical; min-height:140px; color:var(--fg); }
+ .act { display:flex; gap:12px; margin-top:16px; flex-wrap:wrap; }
+ .btn.pri { background:var(--green); color:#fff; border-color:var(--green); font-weight:900; min-height:56px; padding:14px 30px; font-size:19px; margin-left:auto; }
+</style>
+</head><body>
+
+<div class="top">
+ <h1>Inbox · 12 messages</h1>
+ <button class="btn on">All</button>
+ <button class="btn">Unread (8)</button>
+ <button class="btn">Mine (3)</button>
+ <button class="btn sync">Sync now</button>
+</div>
+
+<div class="list">
+
+<div class="row unread">
+ <div class="meta-line"><strong>Sen. Bernie Sanders Office</strong> <span class="when">14 minutes ago</span></div>
+ <h3 class="subj">RE: Markup tomorrow — borrower bill</h3>
+ <p class="prev">Natalia — Senator can do a quick call before 9am ET. Aide on this thread.</p>
+ <div class="chips"><span class="chip">POLICY</span><span class="chip assign">Assigned: Natalia</span></div>
+</div>
+
+<div class="row unread on">
+ <div class="meta-line"><strong>Erica Werner · Washington Post</strong> <span class="when">42 minutes ago</span></div>
+ <h3 class="subj">Quote request — Dept of Ed PSLF guidance</h3>
+ <p class="prev">Hi Natalia — running a story for tomorrow on the new PSLF buyback option. 20 min by 4pm?</p>
+ <div class="chips"><span class="chip urgent">URGENT · PRESS</span><span class="chip assign">Assigned: Natalia</span><span class="chip seen">Seen by 2 people</span></div>
+</div>
+
+<div class="expand">
+ <h2>Quote request — Dept of Ed PSLF guidance</h2>
+ <div style="font-size:18px"><strong>From:</strong> Erica Werner <erica@washpost.com> · 3:18 PM today</div>
+
+ <div class="meta-block">
+ <div><span class="k">Owner:</span> <select class="assign"><option>Natalia Abrams (admin)</option><option>Cody Lin (staff)</option><option>Jess Park (intern)</option><option>— Unassigned —</option></select></div>
+ <div><span class="k">Seen by:</span> <span class="seen-pill">✓ Natalia · 3:21 PM</span> <span class="seen-pill">✓ Cody · 3:24 PM</span></div>
+ <div><span class="k">Priority:</span> <strong style="color:var(--red)">HIGH — same-day deadline</strong></div>
+ </div>
+
+ <div class="body">
+ <p>Hi Natalia,</p>
+ <p>Running a piece tomorrow on the new PSLF buyback guidance that came out this morning. Two questions if you have 20 min by 4pm ET:</p>
+ <p><strong>1.</strong> Your read on whether borrowers between months 100-120 of payment actually get a meaningful benefit, or whether the buyback math wipes it out.</p>
+ <p><strong>2.</strong> 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. Thanks!<br>— Erica</p>
+ </div>
+
+ <h3 style="margin-top:28px;font-size:22px;font-weight:900">Suggested reply</h3>
+ <textarea>Hi Erica — happy to help. I can do a quick call at 3:45pm ET; I'll text you a number. Our cohort of ~12k PSLF borrowers shows 23% are in the 100-120 window. Buyback math wipes the gain above the income cap — known design flaw. — Natalia</textarea>
+ <div class="act"><button class="btn">Copy text</button><button class="btn">Save as draft</button><button class="btn pri">Send reply now</button></div>
+</div>
+
+<div class="row">
+ <div class="meta-line"><strong>Astra Taylor · Debt Collective</strong> <span class="when">2 hours ago</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 it will.</p>
+ <div class="chips"><span class="chip">PARTNERS</span><span class="chip assign">Assigned: Cody</span></div>
+</div>
+
+</div></body></html>
diff --git a/public/mockups/inbox/v14-material.html b/public/mockups/inbox/v14-material.html
new file mode 100644
index 0000000..c9f3b62
--- /dev/null
+++ b/public/mockups/inbox/v14-material.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v14 — Material 3 — Norma Inbox</title>
+<style>
+ :root { --bg:#f8f6fd; --panel:#fff; --el:#ece7f4; --fg:#1c1b1f; --muted:#49454f; --line:#cac4d0; --m3:#6750a4; --m3-hi:#7c69b8; --m3-c:#eaddff; --rose:#ba1a1a; --green:#006e1c; }
+ * { box-sizing:border-box; }
+ body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.45 "Roboto", "Roboto Flex", -apple-system, sans-serif; }
+ .top { padding:8px 16px; background:var(--panel); display:flex; gap:14px; align-items:center; box-shadow:0 2px 4px rgba(0,0,0,0.06); }
+ .top .menu { width:40px; height:40px; border-radius:50%; background:transparent; border:none; color:var(--fg); font-size:22px; cursor:pointer; }
+ .top .search { flex:1; max-width:540px; background:var(--el); border-radius:28px; padding:10px 18px; display:flex; align-items:center; gap:10px; font-size:14px; color:var(--muted); }
+ .top .ava-r { width:36px; height:36px; border-radius:50%; background:var(--m3); color:#fff; display:flex; align-items:center; justify-content:center; font-weight:600; font-size:14px; }
+ .chips-toolbar { padding:12px 16px; display:flex; gap:8px; }
+ .chip-tb { padding:7px 16px; border:1px solid var(--line); border-radius:8px; background:var(--bg); cursor:pointer; font-size:13px; font-weight:500; color:var(--fg); }
+ .chip-tb.on { background:var(--m3-c); border-color:var(--m3-c); color:var(--m3); font-weight:600; }
+ .list { padding:0 8px 80px; }
+ .item { display:flex; gap:14px; padding:12px 16px; border-radius:24px; margin:4px 0; cursor:pointer; align-items:center; transition:background 0.2s; }
+ .item:hover { background:var(--el); }
+ .item.on { background:var(--m3-c); }
+ .ava { width:40px; height:40px; border-radius:50%; background:var(--m3); color:#fff; display:flex; align-items:center; justify-content:center; font-weight:600; font-size:14px; flex-shrink:0; }
+ .mid { flex:1; min-width:0; }
+ .from { font-size:14px; font-weight:500; }
+ .from-line { display:flex; align-items:center; gap:8px; }
+ .when { margin-left:auto; font-size:12px; color:var(--muted); }
+ .subj { font-size:13.5px; color:var(--muted); margin:2px 0 2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+ .item.unread .subj, .item.unread .from { font-weight:600; color:var(--fg); }
+ .chips { display:flex; gap:6px; margin-top:6px; flex-wrap:wrap; }
+ .ch-press { background:rgba(186,26,26,0.15); color:var(--rose); padding:2px 9px; border-radius:6px; font-size:11px; font-weight:500; }
+ .ch-policy { background:var(--m3-c); color:var(--m3); padding:2px 9px; border-radius:6px; font-size:11px; font-weight:500; }
+ .ch-assign { background:var(--bg); border:1px solid var(--line); color:var(--fg); padding:2px 9px 2px 4px; border-radius:6px; font-size:11px; display:inline-flex; align-items:center; gap:4px; }
+ .ch-seen { background:rgba(0,110,28,0.15); color:var(--green); padding:2px 9px; border-radius:6px; font-size:11px; font-weight:500; }
+ .mini { width:18px; height:18px; border-radius:50%; background:var(--m3); color:#fff; font-size:10px; display:flex; align-items:center; justify-content:center; font-weight:600; }
+
+ /* Expanded — looks like an opened conversation card */
+ .expand { margin:8px 0; padding:24px 28px 28px; background:var(--panel); border-radius:28px; box-shadow:0 4px 12px rgba(0,0,0,0.08); }
+ .expand h2 { margin:0; font-size:22px; font-weight:400; letter-spacing:0; }
+ .meta-grid { display:grid; grid-template-columns:80px 1fr; gap:6px 14px; font-size:13px; margin:18px 0 20px; color:var(--muted); }
+ .meta-grid strong { color:var(--fg); font-weight:500; }
+ select.assign { background:var(--bg); border:1px solid var(--line); color:var(--fg); font:13px inherit; padding:6px 12px; border-radius:8px; }
+ .seen-pill { font-size:12px; padding:4px 10px; border-radius:8px; background:rgba(0,110,28,0.12); color:var(--green); display:inline-flex; gap:5px; align-items:center; font-weight:500; }
+ .body-block { background:var(--el); border-radius:16px; padding:18px 20px; font-size:14.5px; line-height:1.7; }
+ .ai-block { margin-top:18px; padding:18px 20px; border-radius:16px; background:var(--m3-c); }
+ .ai-block h4 { margin:0 0 10px; font-size:13px; font-weight:600; color:var(--m3); display:flex; align-items:center; gap:6px; }
+ textarea { width:100%; background:var(--panel); border:1px solid var(--line); color:var(--fg); border-radius:12px; padding:12px 14px; font:14px inherit; resize:vertical; min-height:100px; }
+ .act { display:flex; gap:8px; margin-top:14px; align-items:center; }
+ .btn { font:13px inherit; padding:9px 22px; border-radius:999px; background:transparent; color:var(--m3); border:1px solid var(--line); cursor:pointer; font-weight:500; }
+ .btn.tonal { background:var(--m3-c); border:none; }
+ .fab { background:var(--m3); color:#fff; border:none; padding:14px 28px; font-weight:600; font-size:14px; border-radius:16px; cursor:pointer; box-shadow:0 4px 12px rgba(103,80,164,0.4); margin-left:auto; display:flex; align-items:center; gap:8px; }
+ .fab:hover { background:var(--m3-hi); }
+</style>
+</head><body>
+
+<div class="top">
+ <button class="menu">☰</button>
+ <div class="search">🔍 Search mail</div>
+ <button class="menu">⚙</button>
+ <div class="ava-r">N</div>
+</div>
+
+<div class="chips-toolbar">
+ <span class="chip-tb on">Inbox · 12</span>
+ <span class="chip-tb">Unread</span>
+ <span class="chip-tb">Mine</span>
+ <span class="chip-tb">Important</span>
+</div>
+
+<div class="list">
+
+<div class="item unread">
+ <div class="ava">BS</div>
+ <div class="mid">
+ <div class="from-line"><span class="from">Sen. Bernie Sanders Office</span><span class="when">14m</span></div>
+ <div class="subj">RE: Markup tomorrow — borrower bill</div>
+ <div class="chips"><span class="ch-policy">policy</span><span class="ch-assign"><span class="mini">N</span>Natalia</span></div>
+ </div>
+</div>
+
+<div class="item unread on">
+ <div class="ava" style="background:var(--rose)">EW</div>
+ <div class="mid">
+ <div class="from-line"><span class="from">Erica Werner · Washington Post</span><span class="when">42m</span></div>
+ <div class="subj">Quote request — Dept of Ed PSLF guidance</div>
+ <div class="chips"><span class="ch-press">press</span><span class="ch-assign"><span class="mini">N</span>Natalia</span><span class="ch-seen">✓ 2 seen</span></div>
+ </div>
+</div>
+
+<div class="expand">
+ <h2>Quote request — Dept of Ed PSLF guidance</h2>
+ <div style="font-size:13px;color:var(--muted);margin-top:4px">From <strong style="color:var(--fg)">Erica Werner</strong> · Washington Post · 3:18 PM today</div>
+
+ <div class="meta-grid">
+ <span>Owner</span><span><select class="assign"><option>Natalia Abrams (admin)</option><option>Cody Lin (staff)</option><option>Jess Park (intern)</option><option>— Unassigned —</option></select></span>
+ <span>Seen by</span><span style="display:flex;gap:5px;flex-wrap:wrap"><span class="seen-pill">✓ Natalia · 3:21</span><span class="seen-pill">✓ Cody · 3:24</span></span>
+ </div>
+
+ <div class="body-block">
+ 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) Your read on whether borrowers between 100-120 of payment get a meaningful benefit.<br>
+ 2) Any data on how many borrowers are caught in this 100-120 window?<br><br>
+ — Erica
+ </div>
+
+ <div class="ai-block">
+ <h4>✨ Smart Reply</h4>
+ <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text you a number. Our cohort: ~12k PSLF borrowers, 23% in the 100-120 window. Buyback math wipes the gain above income cap — known design flaw. — Natalia</textarea>
+ <div class="act">
+ <button class="btn">Copy</button>
+ <button class="btn tonal">Save Draft</button>
+ <button class="fab">▸ Send</button>
+ </div>
+ </div>
+</div>
+
+<div class="item">
+ <div class="ava" style="background:var(--green)">AT</div>
+ <div class="mid">
+ <div class="from-line"><span class="from">Astra Taylor · Debt Collective</span><span class="when">2h</span></div>
+ <div class="subj">Reading the new ED memo together?</div>
+ <div class="chips"><span class="ch-assign"><span class="mini" style="background:#a05b00">C</span>Cody</span></div>
+ </div>
+</div>
+
+<div class="item">
+ <div class="ava" style="background:#a05b00">MH</div>
+ <div class="mid">
+ <div class="from-line"><span class="from">Marcus Huang</span><span class="when">Yest.</span></div>
+ <div class="subj">Borrower story — graduated 2018, default at 27</div>
+ </div>
+</div>
+
+</div></body></html>
diff --git a/public/mockups/inbox/v15-synthwave.html b/public/mockups/inbox/v15-synthwave.html
new file mode 100644
index 0000000..99df33c
--- /dev/null
+++ b/public/mockups/inbox/v15-synthwave.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v15 — Synthwave — Norma Inbox</title>
+<style>
+ :root { --bg:#1a0033; --panel:#2a005a; --el:#3d0080; --fg:#ffd5ff; --muted:#aa8acc; --line:#5a0a8c; --magenta:#ff2bff; --cyan:#00ffe5; --sun:#ffae00; }
+ * { box-sizing:border-box; }
+ html, body { margin:0; height:100%; }
+ body { background:linear-gradient(180deg,#1a0033 0%,#3d0080 100%) fixed; color:var(--fg); font:14px/1.5 "Space Grotesk", "VT323", monospace, sans-serif; min-height:100vh; }
+ body::before { content:""; position:fixed; bottom:0; left:0; right:0; height:240px; background:linear-gradient(180deg, transparent, rgba(255,43,255,0.15)), repeating-linear-gradient(90deg, transparent 0, transparent 40px, rgba(255,43,255,0.3) 40px, rgba(255,43,255,0.3) 41px), repeating-linear-gradient(0deg, transparent 0, transparent 40px, rgba(0,255,229,0.2) 40px, rgba(0,255,229,0.2) 41px); transform:perspective(400px) rotateX(50deg); transform-origin:bottom; pointer-events:none; z-index:0; }
+ body > * { position:relative; z-index:1; }
+ .top { padding:18px 28px; display:flex; gap:14px; align-items:center; border-bottom:2px solid var(--magenta); box-shadow:0 0 20px rgba(255,43,255,0.4); }
+ .top h1 { margin:0; font-size:28px; font-weight:700; flex:1; letter-spacing:0.06em; text-transform:uppercase; background:linear-gradient(90deg,var(--magenta),var(--cyan)); -webkit-background-clip:text; background-clip:text; color:transparent; text-shadow:0 0 20px rgba(255,43,255,0.6); }
+ .pill { font-size:12px; padding:7px 16px; border:1px solid var(--cyan); background:transparent; color:var(--cyan); cursor:pointer; font-weight:600; text-transform:uppercase; letter-spacing:0.08em; }
+ .pill.on { background:var(--cyan); color:var(--bg); box-shadow:0 0 16px var(--cyan); }
+ .pill.sync { border-color:var(--magenta); color:var(--magenta); }
+ .list { padding:20px 28px 60px; display:flex; flex-direction:column; gap:8px; }
+ .row { display:grid; grid-template-columns:42px 1fr 130px 80px; gap:14px; padding:14px 18px; background:rgba(45,0,90,0.5); border:1px solid var(--line); cursor:pointer; align-items:center; transition:all 0.2s; }
+ .row:hover { border-color:var(--magenta); box-shadow:0 0 20px rgba(255,43,255,0.3); }
+ .row.on { border-color:var(--cyan); box-shadow:0 0 24px rgba(0,255,229,0.4); background:rgba(0,255,229,0.05); }
+ .ava { width:38px; height:38px; border-radius:0; background:linear-gradient(135deg,var(--magenta),var(--cyan)); color:var(--bg); display:flex; align-items:center; justify-content:center; font-weight:900; font-size:14px; transform:skewX(-8deg); }
+ .from { font-weight:700; font-size:14px; }
+ .subj { color:var(--muted); font-size:13px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+ .subj strong { color:var(--fg); font-weight:600; }
+ .meta-r { text-align:right; }
+ .chip { font-size:10px; padding:2px 9px; border:1px solid; font-weight:700; text-transform:uppercase; letter-spacing:0.06em; display:inline-block; }
+ .c-press { border-color:var(--magenta); color:var(--magenta); }
+ .c-assign { border-color:var(--sun); color:var(--sun); }
+ .c-seen { border-color:var(--cyan); color:var(--cyan); }
+ .when { font-size:11.5px; color:var(--muted); text-transform:uppercase; letter-spacing:0.06em; text-align:right; }
+
+ /* Expand */
+ .expand { padding:26px 30px 30px; background:rgba(26,0,51,0.85); border:2px solid var(--magenta); box-shadow:0 0 40px rgba(255,43,255,0.4); margin:6px 0; }
+ .expand h2 { margin:0 0 4px; font-size:24px; font-weight:700; letter-spacing:0.02em; color:var(--fg); text-shadow:0 0 16px var(--magenta); }
+ .meta-row { display:flex; gap:18px; flex-wrap:wrap; font-size:12px; color:var(--muted); padding:14px 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line); margin:14px 0 18px; text-transform:uppercase; letter-spacing:0.08em; }
+ .meta-row strong { color:var(--fg); font-weight:500; }
+ select.assign { background:transparent; border:1px solid var(--cyan); color:var(--cyan); font:12px inherit; padding:4px 10px; font-weight:600; letter-spacing:0.05em; }
+ .seen-pill { font-size:11px; padding:3px 10px; border:1px solid var(--cyan); color:var(--cyan); display:inline-flex; gap:5px; align-items:center; text-transform:uppercase; letter-spacing:0.05em; }
+ .body { font-size:15px; line-height:1.75; color:#e8d5ff; padding:14px 0; }
+ textarea { width:100%; background:rgba(0,0,0,0.4); border:1px solid var(--cyan); color:var(--fg); padding:14px 16px; font:14.5px/1.6 inherit; resize:vertical; min-height:110px; box-shadow:inset 0 0 12px rgba(0,255,229,0.1); }
+ textarea:focus { outline:none; border-color:var(--magenta); box-shadow:inset 0 0 16px rgba(255,43,255,0.2); }
+ .act { display:flex; gap:8px; margin-top:14px; }
+ .btn { font:12px inherit; padding:8px 22px; border:1px solid var(--line); background:transparent; color:var(--fg); cursor:pointer; font-weight:700; text-transform:uppercase; letter-spacing:0.08em; }
+ .btn.pri { background:linear-gradient(90deg,var(--magenta),var(--cyan)); color:var(--bg); border:none; font-weight:900; margin-left:auto; box-shadow:0 0 20px rgba(255,43,255,0.5); }
+</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 sync">⟳ Sync</button></div>
+
+<div class="list">
+
+<div class="row">
+ <div class="ava">BS</div>
+ <div><div class="from">Sen. Bernie Sanders Office</div><div class="subj"><strong>RE: Markup tomorrow — borrower bill</strong></div></div>
+ <div class="meta-r"><span class="chip c-press">POLICY</span> <span class="chip c-assign">⌬ NAT</span></div>
+ <div class="when">14m</div>
+</div>
+
+<div class="row on">
+ <div class="ava" style="background:linear-gradient(135deg,var(--magenta),var(--sun))">EW</div>
+ <div><div class="from">Erica Werner · Washington Post</div><div class="subj"><strong>Quote request — Dept of Ed PSLF guidance</strong></div></div>
+ <div class="meta-r"><span class="chip c-press">PRESS</span> <span class="chip c-seen">✓2</span></div>
+ <div class="when">42m</div>
+</div>
+
+<div class="expand">
+ <h2>// Quote request — Dept of Ed PSLF guidance</h2>
+ <div style="color:var(--cyan);font-size:12px;letter-spacing:0.06em;text-transform:uppercase">⟨ Erica Werner · Washington Post · erica@washpost.com · 3:18 PM ⟩</div>
+
+ <div class="meta-row">
+ <span>Owner · <select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option><option>— Unassigned —</option></select></span>
+ <span>Seen · <span class="seen-pill">✓ Natalia</span> <span class="seen-pill">✓ Cody</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) Your read on whether borrowers between 100-120 of payment get a meaningful benefit.<br>
+ 2) Any data on how many borrowers are in that 100-120 window?<br><br>
+ — Erica
+ </div>
+
+ <div style="margin-top:10px"><div style="color:var(--magenta);font-size:12px;letter-spacing:0.08em;text-transform:uppercase;font-weight:700;margin-bottom:6px">// AI Suggested Reply</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 math wipes the gain above income cap — known design flaw. — Natalia</textarea>
+ <div class="act"><button class="btn">⎘ Copy</button><button class="btn">⤓ Save</button><button class="btn pri">▶ Send</button></div></div>
+</div>
+
+<div class="row">
+ <div class="ava" style="background:linear-gradient(135deg,var(--sun),var(--magenta))">AT</div>
+ <div><div class="from">Astra Taylor · Debt Collective</div><div class="subj">Reading the new ED memo together?</div></div>
+ <div class="meta-r"><span class="chip c-assign">⌬ COD</span></div>
+ <div class="when">2h</div>
+</div>
+
+</div></body></html>
diff --git a/public/mockups/inbox/v16-kanban-lanes.html b/public/mockups/inbox/v16-kanban-lanes.html
new file mode 100644
index 0000000..f23ba2a
--- /dev/null
+++ b/public/mockups/inbox/v16-kanban-lanes.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v16 — Kanban Lanes — Norma Inbox</title>
+<style>
+ :root { --bg:#f4f5f7; --panel:#fff; --el:#ebecf0; --fg:#172b4d; --muted:#5e6c84; --line:#dfe1e6; --blue:#0052cc; --green:#36b37e; --rose:#de350b; --amber:#ff8b00; --purple:#6554c0; }
+ * { box-sizing:border-box; }
+ html, body { margin:0; height:100%; }
+ body { background:var(--bg); color:var(--fg); font:13.5px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif; height:100vh; overflow:hidden; display:flex; flex-direction:column; }
+ .top { padding:12px 20px; background:var(--panel); border-bottom:1px solid var(--line); display:flex; gap:12px; align-items:center; flex-shrink:0; }
+ .top h1 { margin:0; font-size:18px; font-weight:600; flex:1; }
+ .pill { font-size:13px; padding:6px 12px; border-radius:3px; background:var(--el); color:var(--fg); border:none; cursor:pointer; font-weight:500; }
+ .pill.on { background:var(--blue); color:#fff; }
+ .board { display:flex; gap:14px; padding:14px; overflow-x:auto; flex:1; min-height:0; }
+ .lane { width:300px; flex-shrink:0; background:var(--el); border-radius:5px; display:flex; flex-direction:column; max-height:100%; }
+ .lane-head { padding:10px 14px; display:flex; justify-content:space-between; align-items:center; border-bottom:1px solid var(--line); }
+ .lane-title { font-size:13px; font-weight:700; text-transform:uppercase; letter-spacing:0.04em; color:var(--muted); }
+ .lane-count { background:var(--panel); color:var(--muted); padding:1px 8px; border-radius:999px; font-size:11.5px; font-weight:600; }
+ .lane-body { padding:8px; overflow-y:auto; flex:1; display:flex; flex-direction:column; gap:8px; }
+ .card { background:var(--panel); border-radius:3px; padding:10px 12px; box-shadow:0 1px 2px rgba(9,30,66,0.18); cursor:grab; }
+ .card:hover { box-shadow:0 2px 6px rgba(9,30,66,0.25); }
+ .card.on { box-shadow:0 0 0 2px var(--blue); }
+ .card-label { display:inline-block; height:6px; width:42px; border-radius:3px; margin-bottom:6px; }
+ .lbl-press { background:var(--rose); }
+ .lbl-policy { background:var(--purple); }
+ .lbl-partners { background:var(--green); }
+ .lbl-stories { background:var(--amber); }
+ .card-subj { font-size:13.5px; font-weight:500; margin:0 0 4px; line-height:1.35; }
+ .card-prev { font-size:12px; color:var(--muted); overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
+ .card-foot { display:flex; gap:6px; align-items:center; margin-top:8px; font-size:11px; color:var(--muted); }
+ .ava { width:22px; height:22px; border-radius:50%; background:var(--purple); color:#fff; display:flex; align-items:center; justify-content:center; font-weight:700; font-size:10px; }
+ .seen-dot { display:inline-flex; gap:3px; align-items:center; padding:1px 7px; background:rgba(54,179,126,0.15); color:var(--green); border-radius:3px; font-weight:600; }
+ .pri-dot { display:inline-block; padding:1px 6px; border-radius:3px; font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:0.04em; }
+ .pri-h { background:rgba(222,53,11,0.15); color:var(--rose); }
+ .pri-m { background:rgba(255,139,0,0.18); color:var(--amber); }
+ .when { margin-left:auto; }
+
+ /* Expanded — when a card is in the "Doing" lane and selected, show below the board as a slide-up panel */
+ .detail { position:absolute; left:0; right:0; bottom:0; height:55%; background:var(--panel); border-top:2px solid var(--blue); box-shadow:0 -8px 24px rgba(9,30,66,0.18); padding:22px 28px; overflow-y:auto; }
+ .detail h2 { margin:0; font-size:20px; font-weight:600; }
+ .detail .ctx { font-size:13px; color:var(--muted); margin-top:4px; }
+ .meta-grid { display:grid; grid-template-columns:90px 1fr; gap:6px 14px; font-size:13px; margin:16px 0 18px; }
+ .meta-grid > span:nth-child(odd) { color:var(--muted); }
+ select.assign { background:var(--bg); border:1px solid var(--line); color:var(--fg); font:13px inherit; padding:4px 9px; border-radius:3px; }
+ .seen-pill { font-size:12px; padding:2px 9px; border-radius:3px; background:rgba(54,179,126,0.15); color:var(--green); display:inline-flex; gap:4px; align-items:center; font-weight:500; }
+ .body-card { background:var(--bg); border:1px solid var(--line); border-radius:5px; padding:14px 16px; font-size:13.5px; line-height:1.65; }
+ textarea { width:100%; background:var(--bg); border:1px solid var(--line); color:var(--fg); border-radius:5px; padding:10px 12px; font:13.5px inherit; resize:vertical; min-height:90px; }
+ .act { display:flex; gap:6px; margin-top:10px; }
+ .btn { font:12.5px inherit; padding:6px 16px; border:1px solid var(--line); background:var(--panel); color:var(--fg); cursor:pointer; border-radius:3px; font-weight:500; }
+ .btn.pri { background:var(--blue); color:#fff; border-color:var(--blue); margin-left:auto; }
+</style>
+</head><body>
+
+<div class="top"><h1>Inbox Board</h1><span class="pill on">All</span><span class="pill">Mine only</span><span class="pill">Search</span><button class="pill" style="background:var(--green);color:#fff;font-weight:600">↻ Sync</button></div>
+
+<div class="board" style="position:relative">
+
+ <!-- Unassigned -->
+ <div class="lane">
+ <div class="lane-head"><span class="lane-title">📥 Unassigned</span><span class="lane-count">3</span></div>
+ <div class="lane-body">
+ <div class="card"><span class="card-label lbl-stories"></span><h3 class="card-subj">Borrower story — graduated 2018, default at 27</h3><p class="card-prev">Saw your work on PBS NewsHour. I'd like to share my story...</p><div class="card-foot"><span>Marcus Huang</span><span class="when">1d</span></div></div>
+ <div class="card"><span class="card-label lbl-press"></span><h3 class="card-subj">Pitch — TIME magazine cover story</h3><p class="card-prev">Following up on our call last week. Editor green-lit the cover...</p><div class="card-foot"><span class="pri-dot pri-m">M</span><span>Sara Patel</span><span class="when">3d</span></div></div>
+ </div>
+ </div>
+
+ <!-- Triage / To-Do -->
+ <div class="lane">
+ <div class="lane-head"><span class="lane-title">⚠ Triage</span><span class="lane-count">2</span></div>
+ <div class="lane-body">
+ <div class="card"><span class="card-label lbl-policy"></span><h3 class="card-subj">RE: Markup tomorrow — borrower bill</h3><p class="card-prev">Natalia — Senator can do a quick call before 9am ET. Aide on this thread.</p><div class="card-foot"><span class="pri-dot pri-h">High</span><span class="ava">N</span><span class="when">14m</span></div></div>
+ </div>
+ </div>
+
+ <!-- Working (active card highlighted) -->
+ <div class="lane">
+ <div class="lane-head"><span class="lane-title">🔵 Working</span><span class="lane-count">3</span></div>
+ <div class="lane-body">
+ <div class="card on"><span class="card-label lbl-press"></span><h3 class="card-subj">Quote request — PSLF guidance</h3><p class="card-prev">Hi Natalia — running a story for tomorrow on the new PSLF buyback option. 20 min by 4pm?</p><div class="card-foot"><span class="pri-dot pri-h">High</span><span class="ava">N</span><span class="seen-dot">✓2</span><span class="when">42m</span></div></div>
+ <div class="card"><span class="card-label lbl-partners"></span><h3 class="card-subj">Reading the new ED memo together?</h3><p class="card-prev">Want to do a joint statement if it lands the way we think it will.</p><div class="card-foot"><span class="ava" style="background:var(--amber)">C</span><span class="when">2h</span></div></div>
+ </div>
+ </div>
+
+ <!-- Waiting on reply -->
+ <div class="lane">
+ <div class="lane-head"><span class="lane-title">⏳ Waiting</span><span class="lane-count">1</span></div>
+ <div class="lane-body">
+ <div class="card"><span class="card-label lbl-press"></span><h3 class="card-subj">RE: Briefing follow-up</h3><p class="card-prev">Sent yesterday — no reply yet. Will bump Friday.</p><div class="card-foot"><span class="ava">N</span><span class="when">1d</span></div></div>
+ </div>
+ </div>
+
+ <!-- Replied / Done -->
+ <div class="lane">
+ <div class="lane-head"><span class="lane-title">✅ Replied</span><span class="lane-count">12</span></div>
+ <div class="lane-body">
+ <div class="card" style="opacity:0.7"><span class="card-label lbl-stories"></span><h3 class="card-subj">Re: Welcome to SDCC newsletter</h3><div class="card-foot"><span class="ava" style="background:var(--green)">J</span><span class="when">3h</span></div></div>
+ </div>
+ </div>
+
+ <!-- Detail panel slides up when a card is open -->
+ <div class="detail">
+ <h2>Quote request — Dept of Ed PSLF guidance</h2>
+ <div class="ctx">Card in lane <strong>Working</strong> · From <strong>Erica Werner · Washington Post</strong> · 3:18 PM today</div>
+
+ <div class="meta-grid">
+ <span>Owner</span><span><select class="assign"><option>Natalia Abrams (admin)</option><option>Cody Lin (staff)</option><option>Jess Park (intern)</option><option>— Unassigned —</option></select></span>
+ <span>Seen by</span><span style="display:flex;gap:5px;flex-wrap:wrap"><span class="seen-pill">✓ Natalia · 3:21</span><span class="seen-pill">✓ Cody · 3:24</span></span>
+ <span>Lane</span><span><select class="assign"><option>Working</option><option>Triage</option><option>Waiting</option><option>Replied</option></select></span>
+ <span>Labels</span><span><span class="pri-dot pri-h">High · Press</span></span>
+ </div>
+
+ <div class="body-card">
+ 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) Your read on whether borrowers between 100-120 of payment get a meaningful benefit.<br>
+ 2) Any data on how many borrowers are in this 100-120 window?<br><br>
+ — Erica
+ </div>
+
+ <div style="margin-top:14px">
+ <div style="font-size:11px;text-transform:uppercase;letter-spacing:0.06em;color:var(--muted);font-weight:600;margin-bottom:6px">✨ Suggested reply</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 math wipes the gain above income cap — known design flaw. — Natalia</textarea>
+ <div class="act"><button class="btn">Copy</button><button class="btn">Save draft</button><button class="btn pri">Send & Move to Replied →</button></div>
+ </div>
+ </div>
+
+</div></body></html>
diff --git a/public/mockups/inbox/v7-spotify-dark.html b/public/mockups/inbox/v7-spotify-dark.html
new file mode 100644
index 0000000..20ae37d
--- /dev/null
+++ b/public/mockups/inbox/v7-spotify-dark.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v7 — Spotify Dark — Norma Inbox</title>
+<style>
+ :root { --bg:#121212; --panel:#181818; --el:#282828; --fg:#fff; --muted:#a7a7a7; --line:#2a2a2a; --green:#1db954; --hi:#1ed760; }
+ * { box-sizing:border-box; } body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.5 "Circular", -apple-system,BlinkMacSystemFont,sans-serif; }
+ .top { padding:16px 24px; display:flex; gap:14px; align-items:center; }
+ .top h1 { margin:0; font-size:24px; font-weight:900; letter-spacing:-0.02em; flex:1; }
+ .pill { background:var(--el); color:var(--fg); border:none; padding:7px 16px; border-radius:999px; font-weight:700; font-size:12.5px; cursor:pointer; }
+ .pill.on { background:var(--fg); color:var(--bg); }
+ .pill.green { background:var(--green); color:#000; }
+ .grid { padding:8px 24px 60px; }
+ .row { display:flex; gap:14px; align-items:center; padding:8px 12px; border-radius:6px; cursor:pointer; transition:background 0.18s; }
+ .row:hover { background:var(--el); }
+ .row.on { background:rgba(29,185,84,0.15); }
+ .row .n { color:var(--muted); font-size:13px; min-width:18px; }
+ .ava { width:44px; height:44px; border-radius:4px; flex-shrink:0; display:flex; align-items:center; justify-content:center; font-weight:900; font-size:15px; color:#000; background:linear-gradient(135deg,var(--green),#0a8a3d); }
+ .mid { flex:1; min-width:0; }
+ .from { font-weight:700; font-size:15px; }
+ .subj { color:var(--muted); font-size:13px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+ .right-meta { font-size:12px; color:var(--muted); text-align:right; min-width:120px; }
+ .chips { display:flex; gap:6px; margin-top:4px; }
+ .chip { font-size:10.5px; padding:2px 10px; border-radius:999px; font-weight:700; }
+ .c-press { background:#e22134; color:#fff; }
+ .c-assign { background:var(--el); color:var(--fg); }
+ .c-seen { background:rgba(29,185,84,0.2); color:var(--hi); }
+ /* Expanded */
+ .expand { margin:12px 0; padding:24px; background:linear-gradient(180deg,#222,var(--bg)); border-radius:10px; }
+ .exp-head { display:flex; gap:18px; align-items:flex-end; }
+ .big-ava { width:120px; height:120px; border-radius:8px; background:linear-gradient(135deg,var(--green),#0a8a3d); display:flex; align-items:center; justify-content:center; color:#000; font-weight:900; font-size:36px; flex-shrink:0; }
+ .exp-head h2 { margin:0; font-size:32px; font-weight:900; letter-spacing:-0.02em; line-height:1.1; }
+ .exp-head .label { color:var(--muted); font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:0.1em; }
+ .meta-row { display:flex; gap:18px; flex-wrap:wrap; margin:18px 0 16px; font-size:13px; color:var(--muted); }
+ .meta-row strong { color:var(--fg); font-weight:700; }
+ select.assign { background:var(--el); border:none; color:var(--fg); padding:6px 12px; border-radius:999px; font:13px inherit; font-weight:600; }
+ .seen-pill { font-size:12px; padding:3px 12px; border-radius:999px; background:rgba(29,185,84,0.2); color:var(--hi); display:inline-flex; gap:5px; align-items:center; font-weight:600; }
+ .body-block { font-size:15px; line-height:1.7; color:#d4d4d4; }
+ textarea { width:100%; background:var(--el); border:none; color:var(--fg); border-radius:6px; padding:12px 14px; font:14px/1.6 inherit; resize:vertical; min-height:100px; margin-top:14px; }
+ .act { display:flex; gap:8px; margin-top:14px; }
+ .btn { font:13px inherit; padding:8px 22px; border-radius:999px; border:1px solid var(--muted); background:transparent; color:var(--fg); cursor:pointer; font-weight:700; }
+ .btn.pri { background:var(--green); border-color:var(--green); color:#000; margin-left:auto; }
+</style>
+</head><body>
+<div class="top"><h1>Your 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="grid">
+<div class="row"><span class="n">1</span><div class="ava">BS</div><div class="mid"><div class="from">Sen. Bernie Sanders Office</div><div class="subj">RE: Markup tomorrow — borrower bill</div></div><div class="right-meta">14m · <span class="chip c-press" style="font-size:9.5px">POLICY</span></div></div>
+<div class="row on"><span class="n">2</span><div class="ava" style="background:linear-gradient(135deg,#e22134,#8a0e1f)">EW</div><div class="mid"><div class="from">Erica Werner · Washington Post</div><div class="subj">Quote request — Dept of Ed PSLF guidance</div><div class="chips"><span class="chip c-press">PRESS</span><span class="chip c-assign">Natalia</span><span class="chip c-seen">✓ 2</span></div></div><div class="right-meta">42m ago</div></div>
+
+<div class="expand">
+ <div class="exp-head">
+ <div class="big-ava" style="background:linear-gradient(135deg,#e22134,#8a0e1f)">EW</div>
+ <div>
+ <div class="label">PRESS · HIGH PRIORITY</div>
+ <h2>Quote request — Dept of Ed PSLF guidance</h2>
+ <div style="margin-top:8px;font-size:14px;color:var(--muted)">From <strong style="color:var(--fg)">Erica Werner</strong> · Washington Post · 3:18 PM</div>
+ </div>
+ </div>
+ <div class="meta-row">
+ <div>Owner · <select class="assign"><option>Natalia (admin)</option><option>Cody (staff)</option><option>Jess (intern)</option><option>— Unassigned —</option></select></div>
+ <div>Seen by · <span class="seen-pill">✓ Natalia</span> <span class="seen-pill">✓ Cody</span></div>
+ </div>
+ <div class="body-block">
+ Hi Natalia,<br><br>
+ Running a piece tomorrow on the new PSLF buyback guidance. Two questions if you have 20 min by 4pm ET:<br>
+ 1) Your read on whether borrowers between months 100-120 of payment actually get a meaningful benefit, or whether the buyback math wipes it out.<br>
+ 2) Any data points from SDCC on how many borrowers are caught in this 100-120 window?<br>
+ — Erica
+ </div>
+ <textarea>Hi Erica — happy to help. Quick call at 3:45pm ET; I'll text the number. Our cohort of ~12k PSLF borrowers: 23% in the 100-120 window. Buyback math wipes the gain above the 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 class="row"><span class="n">3</span><div class="ava" style="background:linear-gradient(135deg,#535353,#1a1a1a);color:#fff">AT</div><div class="mid"><div class="from">Astra Taylor · Debt Collective</div><div class="subj">Reading the new ED memo together?</div></div><div class="right-meta">2h</div></div>
+<div class="row"><span class="n">4</span><div class="ava" style="background:linear-gradient(135deg,#a05be8,#5a2da8);color:#fff">MH</div><div class="mid"><div class="from">Marcus Huang</div><div class="subj">Borrower story — graduated 2018, default at 27</div></div><div class="right-meta">Yesterday</div></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v8-minimal-mono.html b/public/mockups/inbox/v8-minimal-mono.html
new file mode 100644
index 0000000..76f40e6
--- /dev/null
+++ b/public/mockups/inbox/v8-minimal-mono.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v8 — Minimal Mono — Norma Inbox</title>
+<style>
+ :root { --bg:#fff; --el:#fafafa; --fg:#000; --muted:#666; --line:#000; }
+ * { box-sizing:border-box; }
+ body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif; }
+ .top { padding:20px 32px; display:flex; gap:24px; align-items:baseline; border-bottom:2px solid var(--fg); }
+ .top h1 { margin:0; font-size:30px; font-weight:300; letter-spacing:-0.02em; flex:1; }
+ .pill { font-size:11px; text-transform:uppercase; letter-spacing:0.15em; padding:6px 0; border-bottom:1px solid transparent; cursor:pointer; color:var(--muted); }
+ .pill.on { color:var(--fg); border-bottom-color:var(--fg); }
+ .list { padding:0 32px; }
+ .row { display:grid; grid-template-columns:24px 200px 1fr 120px; gap:24px; padding:18px 0; border-bottom:1px solid #e0e0e0; cursor:pointer; align-items:baseline; }
+ .row:hover { background:var(--el); margin:0 -32px; padding-left:32px; padding-right:32px; }
+ .row .n { font-size:11px; color:var(--muted); font-variant-numeric:tabular-nums; }
+ .from { font-weight:500; font-size:14px; }
+ .subj { font-weight:300; color:var(--muted); }
+ .subj strong { color:var(--fg); font-weight:500; }
+ .row.unread .from { font-weight:700; }
+ .row.unread .subj strong { font-weight:700; }
+ .row.selected { background:var(--fg); color:var(--bg); margin:0 -32px; padding-left:32px; padding-right:32px; }
+ .row.selected .subj, .row.selected .when, .row.selected .n { color:var(--bg); opacity:0.7; }
+ .row.selected .subj strong { color:var(--bg); }
+ .when { text-align:right; font-size:12px; color:var(--muted); font-variant-numeric:tabular-nums; }
+ .chips { font-size:10px; text-transform:uppercase; letter-spacing:0.1em; color:var(--muted); }
+ /* expand */
+ .expand { padding:36px 32px; background:var(--el); border-top:1px solid var(--fg); border-bottom:1px solid var(--fg); }
+ .expand h2 { margin:0; font-size:28px; font-weight:300; letter-spacing:-0.015em; max-width:640px; }
+ .meta { display:grid; grid-template-columns:120px 1fr; gap:8px 24px; margin:24px 0 28px; font-size:13px; max-width:680px; }
+ .meta > span:nth-child(odd) { font-size:10px; text-transform:uppercase; letter-spacing:0.15em; color:var(--muted); padding-top:4px; }
+ select.assign { background:transparent; border:none; border-bottom:1px solid var(--fg); color:var(--fg); font:14px inherit; padding:2px 0; cursor:pointer; }
+ .seen { display:flex; gap:18px; flex-wrap:wrap; font-size:13px; }
+ .seen span { padding:0 0 2px; border-bottom:1px dotted var(--fg); }
+ .body { max-width:680px; font-size:16px; line-height:1.7; }
+ .body p { margin:0 0 16px; }
+ textarea { width:100%; max-width:680px; background:transparent; border:1px solid var(--fg); padding:14px 16px; font:15px/1.65 inherit; resize:vertical; min-height:120px; color:var(--fg); }
+ .act { max-width:680px; margin-top:14px; display:flex; gap:20px; }
+ .btn { background:transparent; border:none; padding:8px 0; font:13px inherit; cursor:pointer; text-transform:uppercase; letter-spacing:0.12em; border-bottom:1px solid transparent; color:var(--fg); }
+ .btn:hover { border-bottom-color:var(--fg); }
+ .btn.pri { background:var(--fg); color:var(--bg); padding:10px 24px; border-bottom: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><span class="pill">↻ Sync</span></div>
+<div class="list">
+<div class="row unread">
+ <span class="n">01</span><span class="from">Sen. Bernie Sanders Office</span><span class="subj"><strong>RE: Markup tomorrow — borrower bill.</strong> Senator can do a quick call before 9am ET.</span><span class="when">14m</span>
+</div>
+<div class="row unread selected">
+ <span class="n">02</span><span class="from">Erica Werner</span><span class="subj"><strong>Quote request — Dept of Ed PSLF guidance.</strong> Running a story for tomorrow on the new PSLF buyback option.</span><span class="when">42m</span>
+</div>
+<div class="expand">
+ <h2>Quote request — Dept of Ed PSLF guidance.</h2>
+ <div class="meta">
+ <span>From</span><span>Erica Werner · Washington Post · erica@washpost.com</span>
+ <span>Date</span><span>20 May 2026, 3:18 PM PT</span>
+ <span>Owner</span><span><select class="assign"><option>Natalia Abrams (admin)</option><option>Cody Lin (staff)</option><option>Jess Park (intern)</option><option>— Unassigned —</option></select></span>
+ <span>Seen by</span><div class="seen"><span>Natalia · 3:21</span><span>Cody · 3:24</span></div>
+ <span>Labels</span><span>PRESS · IMPORTANT</span>
+ </div>
+ <div class="body">
+ <p>Hi Natalia,</p>
+ <p>Running a piece tomorrow on the new PSLF buyback guidance that came out this morning. Two questions if you have 20 min by 4pm ET:</p>
+ <p>1. Your read on whether borrowers between months 100-120 of payment actually get a meaningful benefit, or whether the buyback math wipes it out.<br>
+ 2. 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. Thanks!<br>—Erica</p>
+ </div>
+ <textarea>Hi Erica — happy to help. I can do a quick call at 3:45pm ET; I'll text you a number. Our cohort of ~12k PSLF borrowers shows 23% are in the 100-120 window. Buyback math wipes the gain above the income cap — known 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 class="row"><span class="n">03</span><span class="from">Astra Taylor</span><span class="subj"><strong>Reading the new ED memo together?</strong> Want to do a joint statement if it lands the way we think.</span><span class="when">2h</span></div>
+<div class="row"><span class="n">04</span><span class="from">Marcus Huang</span><span class="subj"><strong>Borrower story.</strong> Graduated 2018, default at 27. Saw your work on PBS NewsHour.</span><span class="when">Yest.</span></div>
+</div></body></html>
diff --git a/public/mockups/inbox/v9-newsprint.html b/public/mockups/inbox/v9-newsprint.html
new file mode 100644
index 0000000..9f02dc5
--- /dev/null
+++ b/public/mockups/inbox/v9-newsprint.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html lang="en"><head><meta charset="utf-8"><title>v9 — Newsprint — Norma Inbox</title>
+<style>
+ :root { --bg:#f1ebdc; --el:#ebe3cf; --fg:#1c1410; --muted:#6b5e4f; --line:#a89678; --red:#a8221c; }
+ * { box-sizing:border-box; }
+ body { margin:0; background:var(--bg); color:var(--fg); font:14px/1.55 "Adobe Caslon Pro", "Caslon", "Hoefler Text", Georgia, serif; }
+ .masthead { padding:24px 32px 14px; border-bottom:4px double var(--fg); text-align:center; }
+ .masthead h1 { margin:0; font-family:"Old English Text MT", "Cinzel", "Trajan Pro", serif; font-size:48px; font-weight:400; letter-spacing:0.04em; }
+ .masthead .sub { font-style:italic; color:var(--muted); font-size:12px; margin-top:4px; letter-spacing:0.1em; text-transform:uppercase; }
+ .toolbar { padding:8px 32px; display:flex; gap:24px; border-bottom:1px solid var(--line); font-size:12px; text-transform:uppercase; letter-spacing:0.12em; color:var(--muted); }
+ .toolbar span.on { color:var(--fg); font-weight:700; border-bottom:2px solid var(--fg); padding-bottom:6px; }
+ .grid { display:grid; grid-template-columns:1fr 2fr; gap:24px; padding:24px 32px; }
+ .list { border-right:1px solid var(--line); padding-right:24px; }
+ .item { padding:14px 0; border-bottom:1px dashed var(--line); cursor:pointer; }
+ .item:hover { background:rgba(168,150,120,0.1); margin:0 -8px; padding-left:8px; padding-right:8px; }
+ .item .head { font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:0.1em; margin-bottom:3px; display:flex; justify-content:space-between; }
+ .item h3 { margin:0 0 4px; font-size:18px; font-weight:700; line-height:1.25; }
+ .item .by { font-style:italic; color:var(--muted); font-size:12px; margin-bottom:4px; }
+ .item p { margin:0; font-size:13px; color:var(--fg); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
+ .item.lead { border-bottom:2px solid var(--fg); padding-bottom:18px; }
+ .item.lead h3 { font-size:22px; }
+ /* Featured article = expanded message */
+ .feature { padding:0 8px; }
+ .feature .label { font-size:11px; text-transform:uppercase; letter-spacing:0.15em; color:var(--red); font-weight:700; margin-bottom:6px; }
+ .feature h2 { margin:0 0 4px; font-size:32px; font-weight:700; line-height:1.15; letter-spacing:-0.005em; }
+ .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:80px 1fr; gap:5px 14px; font-size:12px; padding-bottom:18px; border-bottom:1px solid var(--line); margin-bottom:20px; }
+ .meta-strip > span:nth-child(odd) { color:var(--muted); text-transform:uppercase; letter-spacing:0.08em; }
+ select.assign { background:transparent; border:1px solid var(--line); color:var(--fg); font:13px inherit; padding:3px 8px; }
+ .seen-pill { font-size:11px; padding:1px 8px; border-radius:0; background:var(--el); color:var(--fg); border:1px solid var(--line); display:inline-flex; gap:5px; }
+ .body { font-size:15px; line-height:1.75; column-count:1; }
+ .body p::first-letter { font-size:200%; font-weight:700; }
+ .body p { margin:0 0 14px; text-indent:1.5em; }
+ .body p:first-child { text-indent:0; }
+ .reply { margin-top:24px; padding-top:18px; border-top:2px solid var(--fg); }
+ .reply label { font-size:11px; text-transform:uppercase; letter-spacing:0.15em; color:var(--red); font-weight:700; }
+ textarea { width:100%; background:var(--el); border:1px solid var(--line); padding:14px 16px; font:14.5px/1.6 inherit; resize:vertical; min-height:100px; margin-top:8px; color:var(--fg); }
+ .act { display:flex; gap:14px; margin-top:12px; }
+ .btn { font:12px inherit; padding:6px 14px; border:1px solid var(--fg); background:transparent; color:var(--fg); cursor:pointer; text-transform:uppercase; letter-spacing:0.1em; font-weight:600; }
+ .btn.pri { background:var(--fg); color:var(--bg); margin-left:auto; }
+</style>
+</head><body>
+<div class="masthead">
+ <h1>The Daily Norma</h1>
+ <div class="sub">Wednesday Edition · 20 May 2026 · No. 4128 · Three Cents</div>
+</div>
+<div class="toolbar"><span class="on">Inbox</span><span>Press</span><span>Policy</span><span>Partners</span><span>Stories</span><span style="margin-left:auto">↻ Run press</span></div>
+<div class="grid">
+ <div class="list">
+ <div class="item lead">
+ <div class="head"><span>Politics</span><span>14 min ago</span></div>
+ <h3>Sanders Office Pushes Markup Forward; Calls Imminent</h3>
+ <div class="by">By Sen. Bernie Sanders Office · to Natalia Abrams</div>
+ <p>Natalia — Senator can do a quick call before 9am ET. Aide on this thread.</p>
+ </div>
+ <div class="item">
+ <div class="head"><span>Press</span><span>2 hours ago</span></div>
+ <h3>Debt Collective Proposes Joint Statement</h3>
+ <div class="by">By Astra Taylor · to info@</div>
+ <p>Want to do a joint statement if the ED memo lands the way we think it will.</p>
+ </div>
+ <div class="item">
+ <div class="head"><span>Voices</span><span>Yesterday</span></div>
+ <h3>A 2018 Graduate's Story of Default at 27</h3>
+ <div class="by">By Marcus Huang · to info@</div>
+ <p>Saw your work on PBS NewsHour. I'd like to share my story...</p>
+ </div>
+ </div>
+
+ <div class="feature">
+ <div class="label">Press · Today's Lead Inquiry</div>
+ <h2>Quote Request — Dept of Ed PSLF Guidance Stirs Question of Real Benefit</h2>
+ <div class="byline">By <strong>Erica Werner</strong>, Washington Post · Filed 3:18 PM Eastern · To natalia@studentdebtcrisis.org</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><option>— Unassigned —</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 style="color:var(--red);font-weight:700;text-transform:uppercase;letter-spacing:0.08em">High — same-day deadline</span>
+ </div>
+
+ <div class="body">
+ <p>Hi Natalia — Running a piece tomorrow on the new PSLF buyback guidance that came out this morning. Two questions if you have 20 min by 4pm ET.</p>
+ <p>First, your read on whether borrowers between months 100-120 of payment actually get a 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>Happy to do email if a call doesn't work. Thanks! — Erica</p>
+ </div>
+
+ <div class="reply">
+ <label>↩ Reply — Suggested in your voice</label>
+ <textarea>Hi Erica — happy to help. I can do a quick call at 3:45pm ET; I'll text you a number. On the data: our cohort of ~12k PSLF borrowers shows 23% are in the 100-120 window. Buyback math wipes the gain for anyone above the income cap — known design flaw. — Natalia</textarea>
+ <div class="act"><button class="btn">Copy</button><button class="btn">Save Draft</button><button class="btn pri">Wire It →</button></div>
+ </div>
+ </div>
+</div></body></html>
← b163e4d session 2026-05-20: log roles/perms/modals + infra fires + 4
·
back to Norma
·
feat(inbox): +16 themes (v17-v32) — total 32 live + dropdown dfa8907 →