Files
ten31-database/design/DESIGN.md
T
Keysat 7b560c97b6 Distill mobile-first design round-trip into the contract
Phase C/D of the /design round-trip (Claude Design "Venture-CRM mobile
redesign", 2026-06-19). Captures the cloud output and folds it into the
durable design/ contract; no frontend reskin in this pass.

- _imports/2026-06-19/: provenance — GridApp.dc.html (byte-exact canonical
  surface) + a manifest README (project URL/inventory, data model, derived-
  field formulas, per-surface interaction model). DesignSync can't bulk-
  download, so screenshots/other sources stay recoverable from the cloud URL.
- DESIGN.md: §8 Responsive rewritten to the landed mobile-first system
  (4-tab bottom bar, card/detail, bottom sheets, swipe/snap, safe areas);
  §4 mobile component states; §3 15px mobile type scale; §2 stage/staleness
  + light-theme palette pointers.
- tokens.tokens.json: new `mobile` group (type scale, radii, touch sizing,
  safe-area) + `motion.sheet`; `color.light` palette — light theme adopted
  as a planned, toggle-gated feature (dark stays default).
- ROADMAP.md: mobile-first implementation backlog (contract-vs-code gap),
  gated on the inline-style->CSS migration and the locked pipeline spec.
2026-06-19 11:25:25 -05:00

193 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ten31 CRM — Design contract (DESIGN.md)
*The durable brand brief. Any agent (or person) building or changing user-facing UI reads
this file and `design/tokens.tokens.json` first and conforms to them. Extracted **as-built**
from `frontend/index.html` on 2026-06-18 (document-as-is); this is a faithful record of the
look that grew in the code, not an aspirational redesign. The mobile-first redesign in
`design/BRIEF.md` builds **on top of** this contract — it changes layout/navigation/touch,
not the visual language below.*
## 1. Visual theme
A dense, professional, **dark** venture-CRM workspace (a **light** theme is planned as an
optional toggle — see §8 — but dark is the default and the brand's primary identity) — calm,
data-forward, slightly
"terminal/financial." Cool blue-greys throughout, a single saturated blue as the only vivid
accent, and IBM Plex's engineered-but-humane character. Monospace (IBM Plex Mono) carries
all numbers, dates, and codes, reinforcing the data-tool feel. The mood is *trustworthy
instrument*, not consumer-app playful: restraint, legibility, and information density over
decoration. It is used by a ~5-person fund team handling sensitive LP data, so it should
read as serious and discreet.
## 2. Color palette
Canonical values live in `design/tokens.tokens.json`. Summary:
- **Backgrounds (darkest → lightest):** base `#0b1118` → panel `#111a27` → elevated
`#152233` → hover `#1b2a3a`. Recessed input/table-header surface: `#0d1622`.
- **Borders:** default `#263548` (the workhorse — borders, dividers, every table grid line),
strong `#35506a` (hover/emphasis).
- **Text:** primary `#e5edf5`, secondary `#c7d3e0`, muted `#8ea2b7` (most common),
subtle `#70859b`.
- **Accent (the one brand color):** `#3b82c4`. Hover/gradient-end `#2f6ea9`, tint
`#3b82c422`, on-tint text `#93c5fd`. Used for primary actions, active nav, links, focus.
- **Semantic:** success `#10b981`, warning `#f59e0b`/`#fcd34d`, due-soon `#e0b341`,
danger `#dc2626`/`#e06c6c`, error-text `#fca5a5`. Badges render semantic color at low
alpha for the fill with a lighter tint for the text.
White (`#ffffff`) appears only as text on accent fills and in the brand mark.
- **Pipeline-stage chips (redesign)** reuse existing semantic tints — no new hues: lead =
subtle grey, engaged = accent blue, diligence = due-soon `#e0b341`, commitment = success
`#10b981`/`#6ee7b7`. **Staleness** (last-contact age) overlays the same ramp: fresh grey →
due-soon amber `#e0b341` → danger-soft red `#e06c6c`/`#f87171`. Both are tinted-fill + tinted-
text badges, consistent with the badge rule above.
- **Light theme (planned)** mirrors every slot above in `tokens.tokens.json` `color.light` (e.g.
base `#eaeef3`, panel `#ffffff`, text-primary `#16202c`); accent `#3b82c4` is unchanged. Dark is
the default — see §8.
## 3. Typography
- **Families:** `IBM Plex Sans` (UI/body), `IBM Plex Mono` (numbers, dates, badges, logs,
nav icons). Loaded from Google Fonts; weights 400/500/600/700 sans, 500/600 mono.
- **Scale (as-built):** 11px micro/table-header/badge · 12px help/meta · **13px body / table
/ inputs (desktop base)** · 14px nav · 16px section title · 18px modal title · 20px page
title · 24px login title & KPI value.
- **Treatments:** global letter-spacing `0.01em`; table headers uppercase with `0.08em`
tracking; badges uppercase `0.5px`; numbers use `font-variant-numeric: tabular-nums`.
- **Mobile scale (redesign, sourced from the 2026-06-19 comps):** body/inputs/list rows
**15px** (up from desktop's 13px); card investor name 16/600; mono amounts 15/600; screen
title 21/600 (vs desktop 20); full-screen detail title 22/600; sheet title 18/600; section
labels mono-uppercase 11/600 `0.08em`; chips mono-uppercase 1011/600; meta/last-contact
mono 12; bottom-tab label mono 10. Inputs are 4446px tall for touch. The mono-for-numbers
and uppercase-tracked-badge rules are unchanged — only the base size grows.
## 4. Component styling
- **Buttons:** primary = top-to-bottom gradient `#3b82c4 → #2f6ea9`, white text, radius 6px,
padding 10×16, lift on hover (`translateY(-1px)` + soft blue shadow). Secondary = flat
`#1b2837`. Danger = `#dc2626`.
- **Cards / sections:** panel `#111a27`, 1px `#263548` border, radius 8px, padding 1620px,
composite drop shadow + inset top highlight. Hover lifts 1px and strengthens the border.
- **Tables:** recessed header `#0d1622`, uppercase muted 11px headers, sticky header +
sticky first column, 1px grid lines, row hover `#172435`, sticky aggregate footer.
- **Forms:** inputs on `#0d1622`, 1px border, radius 6px, accent focus ring; label 13/500,
help 12px muted, error 12px `#fca5a5`.
- **Badges:** radius 4px, 11px/600 uppercase, low-alpha semantic fill + tinted text.
- **Overlays:** modal (centered, radius 12, max-width 500, blurred backdrop) and slide-over
(right drawer, 400px) for detail/edit.
- **Other:** kanban cards (radius 6), toasts (bottom-right), accent spinner, shimmer
skeletons, left-marker timeline for activity feeds.
**Mobile component states (redesign, from the 2026-06-19 comps — see §8 and `_imports/`):**
- **Bottom tab bar:** exactly four tabs (Grid · Pipeline · Reminders · Contacts), 56px tall,
border-top, translucent panel bg + `backdrop-filter: blur(8px)`, `padding-bottom` for
`env(safe-area-inset-bottom)`. Active tab = accent (icon + 10px mono label); inactive =
subtle. 20px line-icons.
- **Bottom sheet** (replaces the centered modal + right slide-over on mobile): panel bg,
strong top border, **radius-20 top corners**, 38×4 grey drag handle, slide-up
(`translateY(100%)→0`, 280ms `cubic-bezier(.2,.8,.2,1)`), scrim `rgba(4,9,16,0.55)` fade-in,
max-height ~8890%, scroll-body; tap-scrim or × to dismiss. One field/action per sheet.
- **Mobile card** (the table→card transform): panel, 1px border, **radius-10**, card shadow,
1214px padding; name 16/600 + Priority corner badge (top-right); mono amount + stage chip +
staleness last-contact. Existing-LP = quiet accent **corner earmark** (star is the lighter
alternative; not a per-card banner).
- **Full-screen detail** (promotes the desktop slide-over): `screenIn` slide (translateX 14px,
200ms), " Grid" back affordance, grouped read-only sections with per-field edit entry points.
- **Swipe actions** (Reminders): pointer-drag a card to reveal complete (swipe-left) / snooze
(swipe-right) at a 70px threshold; the action color tints in under the card.
- **Snap-scroll stages** (Pipeline): full-width stage columns, `scroll-snap-type: x mandatory`,
a segmented stage control + page dots; per-card ` / ` stage move.
- **Account control:** a top-bar avatar opening a small popover (profile + logout) — the only
non-tab navigation on mobile.
- **Toast:** mobile position is bottom-center **above the tab bar** (not bottom-right).
## 5. Layout
Desktop shell = **fixed 250px left sidebar + flexible main content** with a top header bar
(page title + user). Content max-width 1400px, padding 20px. Primary content patterns:
wide data table (Fundraising Grid), KPI grid + timelines (Dashboard), kanban columns
(Pipeline), list + detail drawer (Contacts/Reminders), two-column (Thesis). Auto-fit grids
are used for KPI cards (`minmax(180px,1fr)`) and kanban columns (`minmax(300px,1fr)`).
## 6. Depth / elevation
Elevation is built from three stacked cues, not just one shadow: (a) a **layered radial-
gradient page background** (two soft blue glows top-left and top-right over `#0b1118`),
(b) panel-color steps (base → panel → elevated), and (c) composite drop shadows with a
1px inset white top-highlight (`inset 0 1px 0 #ffffff07-08`) that gives panels a faint lit
edge. Hover states lift elements 1px and deepen the shadow. Keep this restrained, cool, and
low-contrast — depth should be felt, not seen.
## 7. Do's and don'ts
- **Do** keep `#3b82c4` as the only vivid accent; everything else stays in the blue-grey
range. **Don't** introduce a second bright hue for emphasis — use weight, tint, or the
semantic colors.
- **Do** use IBM Plex Mono for every number/date/code. **Don't** set tabular data in the
sans face.
- **Do** reach for tinted-fill + tinted-text badges for status. **Don't** use solid
saturated fills for status chips.
- **Do** keep borders at `#263548` and lean on them for structure (this is a grid-lined,
bordered aesthetic). **Don't** switch to borderless/shadow-only cards.
- **Do** preserve the restrained 1px hover-lift motion. **Don't** add bouncy or long
animations (and honor `prefers-reduced-motion`, already wired).
## 8. Responsive behavior
**Current (as-built): desktop-first.** Breakpoints are `max-width` (900px, 768px); the
sidebar simply `display:none`s below 768px with no real mobile navigation; wide tables
overflow horizontally; the 400px slide-over overflows a 375px screen. A correct viewport
meta tag is present.
**Target: mobile-first, mobile-preferred.** The design landed via a Claude Design round-trip
(2026-06-19; source + per-surface interaction model in `design/_imports/2026-06-19/`, input
brief in `design/BRIEF.md`). The system:
- **Author base = a 375px column, enhance up** with `min-width` breakpoints for tablet/desktop
(inverting today's `max-width` rules). **Prerequisite:** responsive layout must live in the
CSS `<style>` block / utility classes — the ~1,300 inline `style={{}}` objects can't respond
to media queries, so an **inline-style→CSS migration** gates this work (tracked in `ROADMAP.md`).
- **Mobile is a focused subset, not the whole app:** only **four surfaces** ship on mobile —
**Fundraising Grid · Pipeline · Reminders · Contacts** — in a **bottom tab bar**; every other
screen (Dashboard, Thesis, Outreach, Settings, …) is desktop-only and absent, with just a
minimal top-bar account/logout control.
- **Navigation:** the 250px sidebar → a safe-area-aware **bottom tab bar of four**. No "More"
menu.
- **Transforms:** wide data table → **investor card list + full-screen detail**; Pipeline kanban
**swipe-between-stages** (snap-scroll, segmented control, per-card stage move); centered
modal + 400px slide-over → **drag-to-dismiss bottom sheets** / full-screen detail; Grid saved
*views* → a tappable view-name opening a **bottom-sheet view picker**.
- **Editing on mobile** is the on-the-go core only — investor name, contact pills, notes/comm
log, pipeline stage, reminders, and new-investor create (via the Grid, the canonical write
path). Commitments/amounts and the full column set stay **read-only / desktop-only**. (Write
paths use the targeted one-row `log-communication` endpoint + the pipeline link→stage flow,
**not** whole-grid saves — see `BRIEF.md` §3a "Backend reality.")
- **Touch + safe areas:** 44px minimum primary touch targets; body type bumped 13→15px (§3);
sticky bottom nav respects `env(safe-area-inset-bottom)` and content gets bottom padding so
the nav never overlaps it.
- **Light theme — planned (adopted 2026-06-19).** Ship the light palette (`tokens.tokens.json`
`color.light`) behind a `[data-theme]` switch + a top-bar toggle. **Dark stays the default and
the brand's primary identity;** light is the optional alternative. It co-lands with the
inline-style→CSS migration (theming needs CSS custom properties, not per-element inline values).
Full per-component light tints (stage/staleness/note badges) are in `_imports/2026-06-19/`.
The gap between this section and the current `index.html` is the implementation backlog in
`ROADMAP.md` (incl. the inline-style→CSS migration and the locked pipeline-stages/flags spec).
## 9. Agent prompt guide
When building or changing UI here:
- Pull every color, size, radius, and space value from `design/tokens.tokens.json` — do not
hand-pick new hexes. The app still inlines many values; prefer the `:root` CSS variables
(and grow that set) over fresh literals.
- Match the established components above; if you need a new one, compose it from existing
tokens and the bordered-panel + tinted-badge idiom rather than inventing a new visual style.
- Numbers/dates/codes → IBM Plex Mono + tabular-nums. Status → tinted badge. Primary action →
the blue gradient button. Destructive → `#dc2626` and a confirm step.
- **Building anything mobile/responsive?** Read `design/BRIEF.md` first — it holds the
mobile-first layout, navigation, and interaction decisions this section will eventually
absorb.
- Reminder: inline `style={{}}` objects cannot respond to media queries — put any
responsive layout in the CSS `<style>` block (or a utility class), not inline.