diff --git a/ROADMAP.md b/ROADMAP.md index bcdaab1..739e8ab 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -269,6 +269,53 @@ Items 3–6 are cheap (derived/read-time/frontend, reuse `last_activity_at`, no - **Last-contact recency** carries the staleness color (grey→amber→red, "Nd stale"). - This **replaces the design-mockup's INVESTOR/PROSPECT category chip** — we have no prospect/investor *type*; that two-value badge was the tool deriving committed-$>0, which is exactly our Existing-Investor flag. Feeds `design/BRIEF.md` §3a. +### Mobile-first implementation — backlog (design landed 2026-06-19) +*The `/design` round-trip is complete: the contract now describes the mobile-first system +(`design/DESIGN.md` §8 + the `mobile` token group), provenance + per-surface interaction model +are in `design/_imports/2026-06-19/`, and the input brief is `design/BRIEF.md`. This is the gap +between that contract and the current desktop-only `frontend/index.html` — the implementation +backlog. **Not yet started; scope/plan to be developed next (the user's stated next step).** +The comps are signed-off prototypes, **not drop-in** (Claude Design runtime, seed data) — each +surface is re-authored in the app's React idiom and wired to the **real API**.* + +**Hard prerequisite — inline-style→CSS migration.** Responsive layout cannot live in the +~1,300 inline `style={{}}` objects (they can't carry media queries). Mobile-first means +authoring a 375px base + `min-width` enhancements in the CSS ` + +
+ + +
+ 9:41 + 5G ▮▮▮▯ 84% +
+ + +
+ ·Ten31· +
+ + + +
+
+ + +
+ + +
+ +
+ {{ listCountLabel }} + +
+ +
+ + +
+ +
+ + + + + +
No investors match this view.
+
+
+
+
+ + +
+
{{ otherIcon }}
+
{{ otherTitle }}
+
This surface is part of the mobile set — designed next, after the Grid is signed off.
+ +
+
+ +
+ + +
+ + + +
+ + + +
+
+
+
Grant Gilliam
+
grant@ten31.xyz
+
+
+
Profile
+
Log out
+
+
+
+
+ + + +
+
+
+
Switch view
+
+ + + +
+
+
+
+ + + +
+
+
+ +
+
+
+
{{ inv.name }}
+ +
+
+ + Priority + + + Existing LP + + Last contact {{ inv.lastText }} +
+ +
+
Pipeline stage
+ +
+ +
+
+ Contacts + +
+
+ + + + +
No contacts yet — add one to enable pipeline linking.
+
+
+
+ +
+
+ Commitments + read-only +
+
+ +
+ {{ f.name }} + {{ f.amt }} +
+
+
+ Total invested + {{ inv.total }} +
+
+
+ +
+
Reminder
+ +
+ +
+
+ Notes / communication + +
+
+ +
+
+ + +
+
+
+ {{ n.type }} + {{ n.date }} +
+
{{ n.summary }}
+
+
+
+ +
No activity logged yet.
+
+
+
+
+
+
+ + + +
+
+
+
+ {{ sheetTitle }} + +
+
+ {{ sheetBody }} +
+
+
+
+ + + +
+ {{ toast }} +
+
+ +
+ + + + + diff --git a/design/_imports/2026-06-19/README.md b/design/_imports/2026-06-19/README.md new file mode 100644 index 0000000..e0cd2a9 --- /dev/null +++ b/design/_imports/2026-06-19/README.md @@ -0,0 +1,109 @@ +# Import bundle — mobile-first redesign round-trip (2026-06-19) + +Provenance for the `/design` round-trip that produced the mobile-first design. This folder is +**raw input / provenance** (per `~/Projects/standards/guides/design.md`); the durable contract +is `design/DESIGN.md` + `design/tokens.tokens.json`, which were distilled **from** this bundle. + +## Source + +- **Tool:** Claude Design (cloud, `claude.ai/design`), driven by Grant. +- **Project:** "Venture-CRM mobile redesign" — `91e62d47-4c4d-43fb-9135-edb05bc59970` +- **URL:** https://claude.ai/design/p/91e62d47-4c4d-43fb-9135-edb05bc59970 +- **Input packet:** `design/BRIEF.md` (the mobile-first brief) + uploaded `DESIGN.md`, + `tokens.tokens.json`, brand SVGs, and desktop screenshots. + +## What's in this folder vs. still in the cloud project + +The Claude Design MCP (`DesignSync`) streams file **content into context**; it has no +bulk-download / binary-export path. So: + +- **Byte-captured here:** `GridApp.dc.html` — the canonical surface, and the richest single + artifact: it embodies the shared **data model**, the **derived-field formulas**, the stage/ + staleness/note **color logic**, and the locked **card model**. The other surfaces reuse the + same patterns (verified by reading them). +- **Recoverable from the cloud project (not byte-copied):** the shell + the three other app + files, `store.js`, `support.js` (the DC runtime), the option-exploration files, and **all + screenshots**. The full inventory + the distilled logic below preserve the design intent in + text; re-pull any specific file from the project URL on request. + +> These are **Claude Design runtime prototypes** (`` / `` / `` + a +> `DCLogic` class + `support.js`, fed by a client-only seed `store.js`). They are **not +> drop-in** code for `frontend/index.html` (inline-Babel React, real API). They are the +> visual + interaction spec; implementation is a separate scoped build (see `ROADMAP.md`). + +## File inventory (cloud project) + +**The signed-off mobile set (what "Implement" refers to):** +- `Ten31 Mobile.dc.html` — shell: phone frame + 4-tab bottom bar over a shared + `window.T31Store` singleton, switching between the four surfaces (dark + light theme). +- `GridApp.dc.html` — Fundraising Grid (canonical). *[captured here]* +- `PipelineApp.dc.html` — Pipeline (swipe-between-stages + accordion variant). +- `RemindersApp.dc.html` — Reminders (urgency groups + swipe complete/snooze). +- `ContactsApp.dc.html` — Contacts (read-only A–Z directory + detail). +- `store.js` — shared client store (data model + derived helpers + mutations). +- `support.js` — the Claude Design runtime (generic; not design content). + +**Earlier explorations / option sheets (superseded by the App set):** +- `Fundraising Grid Mobile.dc.html`, `Contacts Mobile.dc.html`, `Pipeline Mobile.dc.html`, + `Reminders Mobile.dc.html` — static single-screen studies. +- `Existing-LP Flag Options.dc.html` — star vs. corner-earmark vs. top-banner trial (the App + set defaults to **earmark**; star is the lighter alternative). +- `Font Options.dc.html` — IBM Plex vs. Manrope vs. Hanken Grotesk trial (kept **Plex**). + +**`screenshots/`** (~25 PNGs, in-cloud) — per-state renders: grid cards/detail, sort, contact +detail, pipeline dots/log, swipe-reveal, sheets (name/note/view), reminders, LP-flag, fonts. + +**`uploads/`** (in-cloud) — the inputs we fed in (`BRIEF.md`, `DESIGN.md`, `tokens`, desktop +screenshots); originals already live in `design/`. + +## Data model (from `store.js`) + +Investor = `{ id, name, priority:bool, stage:'lead'|'engaged'|'diligence'|'commitment'|null, +daysAgo, contacts:[{name,email}], funds:[[fundName, amount], …], views:[…], notes:[[type, +summary, isoDate], …] }`. Reminder = `{ id, note, orgId, due:iso, done:bool }`. One canonical +copy in a `window` singleton so a stage move / logged comm / reminder edit on any tab reflects +on the others. Mirrors the server model (grid is system of record; `daysAgo` ← server +`last_activity_at`; commitments read-only on mobile). + +## Derived-field formulas (sourced — reuse verbatim in implementation) + +- **Committed $:** `sum(funds[].amount)`. **Existing-Investor** flag = `committed > 0` + (auto-derived; not a stored field). +- **Money format:** `≥1e6 → $N[.N]M` (drop `.0`); `≥1e3 → $NK`; `0 → $0`. +- **Staleness** (last-contact overlay, one global threshold — values **TBD with team**): + `AMBER=10`, `STALE=30` days. `<10` grey → `≥10` amber (`#e0b341` dark / `#a76a07` light) → + `≥30` red + "`Nd stale`" (`#f87171` / `#c0322f`). +- **Stage order:** `lead → engaged → diligence → commitment`. Stage chip shows **only when in + pipeline** (`stage != null`). +- **Reminder urgency buckets:** overdue (`<0d`) → today (`0`) → this-week (`1–7`) → later + (`>7`), colors red / due-soon / accent / subtle. + +## Color logic introduced by the comps (reconcile in the contract) + +- **Stage chips** use semantic tints (within the existing tinted-badge idiom, not new hues): + lead = subtle grey, engaged = accent blue, diligence = due-soon `#e0b341`, commitment = + success `#10b981`/`#6ee7b7`. +- **Light theme** — the comps add a full light palette + a theme toggle. **Adopted as a planned + feature** (owner decision 2026-06-19): dark stays the default, light ships behind a toggle. Core + palette is in `tokens.tokens.json` `color.light`; full per-component light tints live in + `GridApp.dc.html` here. See `DESIGN.md` §8 + the mobile backlog in `ROADMAP.md`. + +## Per-surface interaction model + +- **Grid:** card list (name · committed · stage chip · staleness last-contact) + Existing-LP + earmark + Priority corner badge; tappable view-name → bottom-sheet **view picker**; search + + `+` create (name typeahead → existing-match guard). Tap card → **full-screen detail** with + per-field **bottom-sheet** edits (name, contact pills, stage, reminder, log note); commitments + read-only. Graveyard view renders muted (opacity 0.55). +- **Pipeline:** segmented stage control + **snap-scroll** between full-width stage columns + (page dots), per-card `‹ back / fwd ›` stage move, tap → detail/log sheet. Accordion variant + included as the alternative. +- **Reminders:** urgency-grouped list; **pointer-drag** card to reveal complete (swipe-left, + threshold 70px) / snooze (swipe-right); `+` add; tap → edit sheet (note, investor, due chips). +- **Contacts:** read-only A–Z grouped directory (sticky letter headers) + search; tap → + full-screen read-only detail (email copy, linked investor, last note); pencil = quick-log. + +**Shared chrome:** 46px status bar (cosmetic), top bar (·Ten31· + theme toggle + account +avatar), 4-tab bottom bar (Grid·Pipeline·Reminders·Contacts; 56px tall; translucent + +backdrop-blur; `padding-bottom:18px` for safe-area), bottom sheets (radius-20 top, 38×4 drag +handle, `sheetUp` 280ms), toasts (above nav), account popover (profile + logout). diff --git a/design/tokens.tokens.json b/design/tokens.tokens.json index 9f0ba3a..39f1bec 100644 --- a/design/tokens.tokens.json +++ b/design/tokens.tokens.json @@ -36,6 +36,36 @@ }, "constant": { "white": { "$type": "color", "$value": "#ffffff", "$description": "Text on accent fills; brand mark." } + }, + "light": { + "$description": "Light-theme palette (planned; adopted 2026-06-19). The color.* values above are the DARK/default theme; these are the light-mode overrides for the same semantic slots, sourced from the comps' [data-theme=\"light\"] blocks. accent.default stays #3b82c4 in both themes. Full per-component light tints (stage/staleness/note badges) live in design/_imports/2026-06-19/GridApp.dc.html. Dark remains the default; light is a user toggle.", + "bg": { + "base": { "$type": "color", "$value": "#eaeef3" }, + "panel": { "$type": "color", "$value": "#ffffff" }, + "elevated": { "$type": "color", "$value": "#f4f7fb" }, + "input": { "$type": "color", "$value": "#eef2f7" }, + "hover": { "$type": "color", "$value": "#e6ecf4" } + }, + "border": { + "default": { "$type": "color", "$value": "#d6dde7" }, + "strong": { "$type": "color", "$value": "#b6c3d4" }, + "divider": { "$type": "color", "$value": "#e8edf3", "$description": "Dark-theme equivalent is #1c2735 (a distinct lighter-than-border divider the comps introduced)." } + }, + "text": { + "primary": { "$type": "color", "$value": "#16202c" }, + "secondary": { "$type": "color", "$value": "#33414f" }, + "muted": { "$type": "color", "$value": "#5a6b7d" }, + "subtle": { "$type": "color", "$value": "#84909e" } + }, + "accent": { + "light": { "$type": "color", "$value": "#1f6fb8", "$description": "On-light accent text (darker than the dark-theme #93c5fd)." } + }, + "semantic": { + "danger-soft": { "$type": "color", "$value": "#c0322f" }, + "success-text": { "$type": "color", "$value": "#057a55" } + }, + "nav-bg": { "$type": "color", "$value": "#ffffffd9", "$description": "Translucent bottom-nav background (light)." }, + "shadow-card": { "$type": "shadow", "$value": "0 8px 20px rgba(40,70,110,0.10), inset 0 1px 0 #ffffff" } } }, "font": { @@ -46,7 +76,7 @@ "size": { "xs": { "$type": "dimension", "$value": "11px", "$description": "Table headers, badges, micro-labels." }, "sm": { "$type": "dimension", "$value": "12px", "$description": "Help text, metadata." }, - "md": { "$type": "dimension", "$value": "13px", "$description": "Body / table cells / inputs (current desktop base). NOTE: bump toward 15–16px for mobile body — see BRIEF.md." }, + "md": { "$type": "dimension", "$value": "13px", "$description": "Body / table cells / inputs (desktop base). Mobile body base is 15px — see the `mobile` group + DESIGN.md §3/§8." }, "lg": { "$type": "dimension", "$value": "14px", "$description": "Nav items." }, "xl": { "$type": "dimension", "$value": "16px", "$description": "Section titles." }, "2xl": { "$type": "dimension", "$value": "18px", "$description": "Modal titles." }, @@ -88,7 +118,35 @@ "motion": { "fast": { "$type": "duration", "$value": "120ms", "$description": "Press/transform feedback." }, "base": { "$type": "duration", "$value": "150ms", "$description": "Hover color/shadow." }, - "panel": { "$type": "duration", "$value": "300ms", "$description": "Slide-over / toast entry." } + "panel": { "$type": "duration", "$value": "300ms", "$description": "Slide-over / toast entry." }, + "sheet": { "$type": "duration", "$value": "280ms", "$description": "Mobile bottom-sheet slide-up (cubic-bezier(.2,.8,.2,1))." } + }, + "mobile": { + "$description": "Mobile-first redesign deltas (2026-06-19 Claude Design round-trip; provenance in design/_imports/2026-06-19/, behavior in DESIGN.md §8). The values above are the desktop base; these override/extend for the <768px surface. Colors are unchanged — stage chips and staleness reuse the semantic tokens above (engaged→accent, diligence→due-soon, commitment→success, stale→danger-soft).", + "font-size": { + "body": { "$type": "dimension", "$value": "15px", "$description": "Body / list rows / inputs (up from desktop md 13px)." }, + "card-title": { "$type": "dimension", "$value": "16px", "$description": "Investor/card name." }, + "amount": { "$type": "dimension", "$value": "15px", "$description": "Mono money values." }, + "screen-title": { "$type": "dimension", "$value": "21px", "$description": "Tab screen title." }, + "detail-title": { "$type": "dimension", "$value": "22px", "$description": "Full-screen detail header." }, + "sheet-title": { "$type": "dimension", "$value": "18px", "$description": "Bottom-sheet title." }, + "tab-label": { "$type": "dimension", "$value": "10px", "$description": "Mono bottom-tab label." } + }, + "radius": { + "card": { "$type": "dimension", "$value": "10px", "$description": "Mobile cards (vs desktop lg 8px)." }, + "control": { "$type": "dimension", "$value": "8px", "$description": "Mobile inputs/buttons (vs desktop md 6px)." }, + "sheet": { "$type": "dimension", "$value": "20px", "$description": "Bottom-sheet top corners." } + }, + "size": { + "touch-target": { "$type": "dimension", "$value": "44px", "$description": "Minimum primary touch target." }, + "input": { "$type": "dimension", "$value": "46px", "$description": "Form input / sheet field height." }, + "tab-bar": { "$type": "dimension", "$value": "56px", "$description": "Bottom tab-bar item height." } + }, + "space": { + "screen-pad-x": { "$type": "dimension", "$value": "16px", "$description": "Screen horizontal padding (vs desktop xl 20px)." }, + "card-gap": { "$type": "dimension", "$value": "10px", "$description": "Gap between cards in a list." } + }, + "safe-area-bottom": { "$type": "dimension", "$value": "env(safe-area-inset-bottom)", "$description": "Not a static dimension — the sticky bottom nav and content bottom-padding must honor it. Kept as a CSS string." } }, "_unmappable": { "$description": "Documented-but-not-tokenized: the page background is a layered radial-gradient ('radial-gradient(1200px 600px at 15% -10%, #1a3c5e44, transparent 60%), radial-gradient(1000px 500px at 90% 0%, #27496b33, transparent 58%), #0b1118') — see DESIGN.md §Depth/elevation."