# Design brief — Ten31 CRM mobile-first redesign

*The input packet for a Claude Design (or equivalent) round-trip. Goal: make the phone a
first-class, **preferred** surface for the Ten31 CRM without losing the existing look. This
is a **layout / information-architecture / interaction** redesign — the visual language is
captured in `design/DESIGN.md` + `design/tokens.tokens.json` and is **preserved**. Posture:
**preserve-but-refine** — keep the brand DNA; small mobile-warranted tweaks (type scale,
density, touch sizing) are welcome, a visual reskin is not.*

---

## 0. The one instruction that matters most

**Preserve the visual language; redesign only layout, navigation, and touch interaction.**
The current app is already a coherent, deliberate dark venture-CRM look (see `DESIGN.md`).
Do **not** reinvent the palette, typography, or component styling. Where mobile genuinely
warrants it, you may refine — bump body type from 13px toward 15–16px, loosen touch density,
add bottom-sheet patterns — but the colors, the IBM Plex faces, the bordered-panel +
tinted-badge idiom, and the single `#3b82c4` accent stay.

## 1. Goal

The Ten31 CRM is the fund's system of record (~150 LPs, 250+ prospects, the capital-raise
pipeline), used by a ~5-person team. Today it's desktop-first; the team increasingly works
from phones — before/after investor meetings, on the move. Make **mobile the primary,
preferred surface**: every common on-the-go task is thumb-reachable and fast, and desktop
becomes the wide-screen enhancement rather than the baseline.

**Mobile is a focused subset, not the whole app** (decided 2026-06-18). Mobile carries only
the on-the-go core; everything else stays desktop-only.

- **Mobile surfaces — the only four:** **Fundraising Grid** (with fast switching between its
  saved *views*), **Pipeline**, **Reminders**, **Contacts**. Every other screen — Dashboard,
  Thesis, Thesis Workshop, Outreach, Communications, Email Capture, System Status, Feedback,
  Instructions, Settings — is **desktop-only and simply absent** from the mobile UI (keep only
  a minimal account/logout control).
- **Mobile editing — core records + quick capture (expanded 2026-06-18):** read everything;
  editable on mobile is **investor name**, **contacts (name + email)**, **notes / communication
  / outreach log** (logging activity, not composing/sending — see §3a Backend reality),
  **pipeline stage**, and **reminders** — *and* **creating a new investor**
  (name + one or more contacts; no type field — Existing-Investor is auto-derived, pipeline stage
  optional). Still **desktop-only**: commitments/amounts, the
  full 20+ column set, column structure, bulk ops, and CSV. So mobile is "create and manage the
  core investor record + log activity," not the full spreadsheet.
- **Create/edit investors go through the Grid — the canonical write path — never Contacts.**
  Per the app's model, the `fundraising_*` grid is the system of record (investor row → contact
  "pills" → commitments) and the **Contacts tab is a read-only directory auto-populated from
  it**. So the **"+ add investor"** entry point and all name/contact/email edits live on the
  **Grid** (its card list and detail); **Contacts stays read-only** on mobile — do not put an
  add/edit affordance there.
- **Guard against duplicate investors on create.** Adding an investor from a phone is a
  dupe-generation risk; the app already has entity resolution/merge. The mobile "+ add
  investor" flow should **check for an existing match first** (search-as-you-type on name)
  before creating a new row.
- **The Grid is card/detail on a phone, never a spreadsheet.** A row is one investor; mobile
  shows an investor card list → full-screen detail with the editable set above, plus a create flow.

## 2. Layout (global, mobile-first)

- **Base = mobile; enhance up.** Author layout for a 375px column first, then add `min-width`
  breakpoints for tablet/desktop. (Implementation note for later: the app's ~1300 inline
  `style={{}}` objects can't respond to media queries — responsive layout must live in the
  CSS `<style>` block / utility classes. The design tool doesn't need to solve this, but the
  brief should assume layout, not inline style, carries responsiveness.)
- **Navigation → a 4-tab bottom bar; everything else is desktop-only.** Replace the 250px
  sidebar with a **bottom tab bar of exactly four**: **Grid · Pipeline · Reminders ·
  Contacts**. The other ten destinations are **not** present on mobile — there is no "More"
  feature menu. Keep only a minimal **account control** (e.g. a top-bar avatar/menu) for
  profile + logout. The bar respects `env(safe-area-inset-bottom)`.
- **Grid views are a first-class mobile control (high priority — second only to the tabs).**
  The Grid's saved *views* (Main, Follow-up, All Investors, … and a growing set of
  filter-based cuts) are how the team reads the investor list different ways. Surface a **view
  picker at the top of the Grid screen** — a tappable current-view header that opens a
  **bottom-sheet list of views**. Use a sheet/dropdown, not a fixed segmented control, because
  the set of views grows over time. Switching a view re-filters the card list in place.
- **Overlays → bottom sheets.** Today's centered modal (500px) and right slide-over (400px,
  which overflows a phone) become **drag-to-dismiss bottom sheets** or full-screen detail
  views on mobile.
- **Touch + safe areas.** 44px minimum touch targets; sticky bottom nav respects
  `env(safe-area-inset-bottom)`; content gets bottom padding so the nav never overlaps it.

## 3. Per-screen briefs

Take the design tool through these **one screen at a time** (mobile re-layout is screen-by-
screen, not a global token swap). Ordered by value and difficulty.

### 3a. Fundraising Grid — the crux (do first)
The core feature and system of record: a 20+ column, ~3,000px-wide editable table. A row =
**one investor** (contact "pills" + per-fund commitments). On a phone it is a **card list**,
never a wide table.
- **View switching, up top (high priority):** a tappable current-view name → **bottom-sheet
  view picker** (Main / Follow-up / All Investors / … a growing set), plus search. Switching
  re-filters the card list in place.
- **Card:** at-a-glance — **name · committed amount · pipeline stage · last contact**, plus two
  derived indicators below. Tap → **full-screen investor detail** (today's slide-over, promoted).
  *(Card model is locked — see ROADMAP "Pipeline stages + investor flags/labels — LOCKED SPEC.")*
  - **Existing-Investor indicator** (auto-derived from any committed $): a quiet **star by the name
    or a thin left accent edge** — *not* a per-card banner. Existing LPs are special; unmistakable
    but restrained, in the blue accent.
  - **Priority** is the **only top-right corner badge** — a star/pill when flagged, empty otherwise.
    Graveyard is not a corner badge (those rows filter out / render muted). Priority + Graveyard are
    the only two disposition flags; there is **no investor "type"** — drop any INVESTOR/PROSPECT chip.
  - **Pipeline stage** chip shows **only when the row is in the pipeline** (`Lead → Engaged →
    Diligence → Commitment`); most rows have none.
  - **Last contact** carries staleness: grey when fresh → **amber → red** by age, appending "stale"
    past one global threshold (e.g. "35d stale"). Derived from one server value, so grid + mobile
    color-code identically.
- **Detail + edit:** the full field set is grouped into sections and **read-only**, *except*
  the editable set: **investor name**, **contacts (name + email — the contact "pills")**,
  **notes / communication / outreach** (a text area or "log a note" entry), **pipeline stage**
  (a picker / segmented control), and **set/update a reminder** (date + note). Each edit happens
  in a **bottom sheet**, one field at a time — no spreadsheet grid. Commitments/amounts and the
  rest of the columns stay read-only on mobile.
- **Add investor (`+` on the Grid):** a create flow capturing **investor name + one or more
  contacts (name, email)** — the minimum to start a record (no "type" to choose — Existing-Investor
  is auto-derived from committed $; pipeline stage is optional, set only if adding to the pipeline);
  the rest is filled later on desktop. **Search-as-you-type on name first** and offer existing matches before
  creating, so a phone-added investor doesn't duplicate one already in the grid.
- The full multi-column spreadsheet (commitments/amounts, column reorder, bulk/CSV) stays
  **desktop-only**.

> **Backend reality (read before designing the edit interactions — the write layer is not
> what "edit a field in a sheet" implies):**
> - **There is no field-level write. The grid is one JSON blob saved wholesale.**
>   `PUT /api/fundraising/state` takes the *entire* grid and rejects with **409** if the global
>   `version` moved under you (5 people edit live). So a naive "edit one field" = load the whole
>   grid → mutate one row → PUT it all back → race everyone else. **Mobile single-investor edits
>   (name, pills, add-investor, log-note) should instead go through the targeted, server-side,
>   one-row path** `POST /api/fundraising/log-communication` (it finds/creates a single row,
>   appends a note, and can create a new investor + first contact in one call via
>   `create_investor_if_missing`, with no whole-grid version race) — or a new narrow per-row
>   PATCH. Do **not** model these as whole-grid saves. The Matrix bot already uses this path.
> - **"Pipeline stage" is not a grid field** — it lives on the separate `opportunities` table and
>   editing it is a **two-call flow with a precondition**: the row must first be *linked* to a
>   pipeline opp (`POST /api/fundraising/pipeline/link`, which **requires ≥1 contact on the row**),
>   *then* `PATCH /api/opportunities/{id}/stage`. The grid only *displays* stage read-only. So the
>   detail-sheet "change stage" control needs a "not in pipeline yet → add to pipeline" state, and
>   it shares the *same* opportunities endpoint as the Pipeline tab (3c) — consistent with that, not
>   with the grid blob.
> - **Removing a contact pill has no tombstone/undo** — the `fundraising_*` tables are rebuilt on
>   every save; the JSON blob is canonical. Don't promise soft-delete/undo semantics for pill
>   removal (unlike comms/reminders, which *are* soft-deleted).
> - **Dedup typeahead is client-side** — filter the already-loaded rows; there is no investor-search
>   endpoint, and the app's `entity_merge` is an admin-only *after-the-fact* reconciliation, not a
>   create-time guard.
> - **"Notes / communication" = the `log-communication` path above (immediate write).** **Outreach
>   *composition*** is a different, **gated** feature (agent drafts → human edits → human sends; the
>   Outreach screen is desktop-only) — only the investor's outreach *log/notes* belong on mobile.
> - All of these are **plain-authenticated immediate writes** — a human **member** can do them on a
>   phone; there is no draft→approve gate on a *human's own* edit (that gate is for *agent*-originated
>   actions). "Agents draft, humans send" constrains the bot, not this UI.

### 3b. Contacts — lowest-risk transform (good pattern validator)
A **read-only** per-person directory (auto-populated from the Grid — no create/edit here),
today a table + tabs (All / Investors / Prospects) + a detail slide-over.
- **Mobile pattern:** a **list of contact rows** (initial/avatar · name · organization · type
  badge · last contact) with the tabs as a top segmented control and search pinned → tap →
  **full-screen read-only detail** (contact info, linked investor, communication history).
- Pure browse→detail, no edit — validate the list+detail+sheet pattern here before the Grid.

### 3c. Pipeline (Kanban) — re-think the horizontal board
Today: horizontal kanban columns, one per stage (count + total per column), tap card → edit.
Horizontal columns don't work on a phone.
- **Mobile pattern (lead option):** **swipe between stage columns** — one full-width stage at
  a time, snap-scrolling, a stage indicator/segmented control at top, vertical list of
  investor cards within each stage. (Alternative to weigh: a vertical accordion of collapsible
  stages.) Tap a card → the same investor detail sheet as the Grid. **Editing pipeline stage**
  is one of the mobile-editable fields, so make stage changeable here too (a stage picker on the
  card, or drag/swipe a card to the next stage).

### 3d. Reminders — a primary tab + an edit surface
A follow-up/tickler list tied to investors (one of the mobile-editable areas).
- **Mobile pattern:** a **list grouped by urgency** (overdue → due-soon → later), each row
  showing title, investor, due date (urgency-colored: overdue `#e06c6c`, due-soon `#e0b341`),
  and assignee. **Quick actions** (done / snooze / edit) via swipe or a row menu; a **`+`**
  creates one. Tap → a **bottom-sheet edit** (title, investor, due date, note, assignee). This
  is also the editor reached from an investor detail's "set a reminder" action.

## 4. Brand description (~120 words)

Ten31's CRM is a *trustworthy instrument* — a dense, dark, data-forward venture-fund
workspace for a small team handling sensitive LP relationships. The voice is serious,
discreet, and precise: cool blue-greys, a single confident blue accent, IBM Plex's
engineered-but-humane type, monospace for every number and date. It feels like a well-made
financial terminal, not a consumer app — restraint and legibility over decoration. The
mobile version should feel like the *same instrument in your pocket*: calmer and roomier for
touch, but unmistakably the same tool. It is **not** playful, colorful, skeuomorphic, or
trend-chasing; **not** a second bright color or a borderless/flat reskin. Quiet confidence,
information density made thumb-friendly.

## 5. Inputs to bring to the cloud tool

- **Point at:** `frontend/` (the single `index.html` holds the whole UI — point at the
  directory, not the repo root).
- **Upload:** `design/DESIGN.md`, `design/tokens.tokens.json`, `design/brand/ten31-logo-white.svg`,
  `design/brand/ten31-favicon.svg`, and **screenshots of each screen** below at desktop width
  (Fundraising Grid, Contacts, Pipeline, Dashboard, a modal, the slide-over) so the tool sees
  the as-built look it must preserve.
- **Web-capture:** the running app URL if convenient (it's behind auth on the Start9 box; a
  set of screenshots is the reliable path).

## 6. Prompt blocks (paste into the design tool, one per screen)

**Global frame (paste first):**
> Redesign this dark venture-CRM web app to be mobile-first and mobile-preferred. **Preserve
> the existing visual language exactly** (see the uploaded DESIGN.md + tokens: dark blue-grey
> palette, single `#3b82c4` accent, IBM Plex Sans/Mono, bordered panels, tinted badges) —
> change only **layout, navigation, and touch interaction**. Small mobile-warranted refinements
> (body type 13→15–16px, looser touch density, bottom sheets) are welcome; no visual reskin.
> Mobile carries only **four surfaces in a bottom tab bar — Grid, Pipeline, Reminders,
> Contacts**; every other screen is desktop-only and absent here (keep just a minimal top-bar
> account/logout menu). Convert centered modals and the right slide-over into **drag-to-dismiss
> bottom sheets / full-screen detail views**. 44px touch targets, safe-area-aware sticky bottom
> nav. Design for a 375px phone first.

**Fundraising Grid:**
> This is a 20+ column editable data table; each row is one investor (contact pills + per-fund
> commitments) — unusable as a wide table on a phone. Design a mobile **investor card list**:
> card shows name, committed amount, pipeline stage (only if in the pipeline), and last contact
> (which color-shifts grey→amber→red as it goes stale); plus an auto-derived Existing-Investor star
> and a Priority corner badge — there is **no** investor/prospect type chip. At the top, a
> **tappable current-view name that opens a bottom-sheet list of saved views** (Main, Follow-up,
> All Investors, and a growing set of filtered cuts) plus search; switching a view re-filters
> the list. Tapping a card opens a **full-screen detail**: most fields read-only **except** the
> editable set — **investor name**, **contacts (name + email)**, **notes/communication/outreach**,
> **pipeline stage**, and **set a reminder** — each edited in a bottom sheet. Add a **`+` to
> create a new investor** (name + one or more contacts with name/email; no type, pipeline stage
> optional), with
> search-as-you-type on name to surface existing matches before creating (avoid duplicates).
> Commitments/amounts and the full column set stay read-only / desktop-only.

**Contacts:**
> A read-only people directory (no create/edit here). Today it's a table with All/Investors/
> Prospects tabs and a detail panel. Design a mobile **contact list** (initial, name,
> organization, type badge, last contact), tabs as a top segmented control, search pinned;
> tapping a row opens a **full-screen read-only detail** with contact info, linked investor,
> and communication history.

**Pipeline (Kanban):**
> A kanban board of pipeline stages (one column per stage, each showing count + total),
> cards are investors. Horizontal columns don't fit a phone. Design a **swipe-between-stages**
> mobile view: one full-width stage at a time with snap-scrolling and a stage segmented
> control at top, a vertical list of investor cards within each stage; tapping a card opens
> the investor detail sheet. Stage is editable here (a stage picker on the card, or drag a card
> to the next stage). Also sketch a vertical-accordion alternative for comparison.

**Reminders:**
> A follow-up/tickler list tied to investors. Design a mobile **reminders list grouped by
> urgency** (overdue, due-soon, later); each row shows title, investor, due date (urgency-
> colored), assignee, with quick actions (done / snooze / edit) via swipe or a row menu and a
> `+` to create. Tapping a row opens a **bottom-sheet edit** (title, investor, due date, note,
> assignee).

---

## 7. After the round-trip (Phase C reminder)

Export the **"Handoff to Claude Code" bundle** + screenshots, drop them in
`design/_imports/<date>/`, then distill back into the contract: update `DESIGN.md` §8
(Responsive behavior) with the real mobile-first system, add mobile component states (bottom
nav, sheets, card list) to §4, and bump the mobile type scale in `tokens.tokens.json` if it
changed. The gap between the new contract and the current `index.html` is the implementation
backlog → capture it to `ROADMAP.md` (incl. the inline-style→CSS migration that makes
responsive layout possible at all). Do not silently reskin existing code in the same pass.
