Add mobile-first design contract and redesign brief

Scaffold design/ for the frontend's first design contract, extracted
as-built from index.html (document-as-is):
- DESIGN.md: 9-section brand brief (dark venture-CRM look, IBM Plex,
  single #3b82c4 accent) + tokens.tokens.json (DTCG, from :root + an
  inline-style census).
- BRIEF.md: the mobile-first redesign packet. Mobile = 4 surfaces
  (Grid, Pipeline, Reminders, Contacts) in a bottom tab bar; the rest
  desktop-only. Grid view-switching first-class; narrow on-the-go edit
  set (name, contacts, notes/comms/outreach log, stage, reminders) +
  create-investor, all via the canonical grid path (Contacts stays
  read-only). Includes a backend-reality callout: no field-level write
  (whole-grid versioned PUT vs the targeted log-communication path),
  stage is a separate two-call opportunities flow, pill removal has no
  undo, dedup typeahead is client-side.
- brand/ assets, inspiration/ provenance.

Wire the AGENTS.md Design line so any agent reads the contract before
UI work.
This commit is contained in:
Keysat
2026-06-18 21:50:34 -05:00
parent ab0d82ff00
commit 99404db48b
8 changed files with 538 additions and 4 deletions
+125
View File
@@ -0,0 +1,125 @@
# 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 — 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.
## 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 note:** 13px body is comfortable for desktop and tight on a phone — the redesign
bumps the mobile base toward 1516px. See `BRIEF.md`.
## 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.
## 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 — active redesign.** The team increasingly works
from phones, so mobile is becoming the primary surface. The full plan (navigation
re-architecture to a bottom tab bar, table→card transforms, bottom sheets, touch sizing,
type bump) lives in **`design/BRIEF.md`**. Update this section to describe the new
mobile-first system once that redesign lands.
## 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.