diff --git a/DESIGN.md b/DESIGN.md deleted file mode 100644 index e71f88c77d..0000000000 --- a/DESIGN.md +++ /dev/null @@ -1,254 +0,0 @@ -# OmniRoute — Design System & Visual Identity - -> **Status:** analysis + standardization plan (no code applied yet — this doc is the spec to approve before implementation). -> **Date:** 2026-06-16 · **Scope:** unify the OmniRoute dashboard (`src/`) with the marketing site (`_mono_repo/omnirouteSite/`) into **one visual identity** — same graph-paper grid background, same color tokens, standardized components. - ---- - -## 1. Purpose - -The marketing site (`viral.omniroute.online`, `why.omniroute.online`, `omniroute.online`) and the product dashboard should look like **one product**. The site already borrowed its palette from the dashboard — its `css/tokens.css` even says _"Palette mirrors the OmniRoute dashboard (src/app/globals.css)"_. So the two are already ~80% aligned at the color level. What's missing on the dashboard: - -1. The **graph-paper grid wallpaper** the site uses on every page. -2. A handful of **shared design tokens** the site has but the dashboard lacks (radius scale, brand gradient, `surface-2`, mono font). -3. **Component-level consistency** — a number of dashboard components bypass the theme tokens with hardcoded hex/rgba. - -This document is the analysis and the plan. **Nothing is changed until approved.** - ---- - -## 2. Principles - -- **Single source of truth = `src/app/globals.css`.** The site mirrors the dashboard, never the other way around. New tokens land in `globals.css` first. -- **Tokens, never literals.** Components consume semantic tokens (`bg-surface`, `text-primary`, `border-border`), never raw `#hex`. -- **Subtle, not loud.** The grid is a faint wallpaper that sits behind content — it must never reduce text contrast or fight the UI. -- **Theme-aware.** Everything works in both `.dark` (default-ish, the product's signature look) and light. -- **Surgical rollout.** Ship the grid + tokens first (low risk, high visibility), then component cleanups in waves. - ---- - -## 3. Current state — what's already aligned vs. what's not - -### 3.1 Colors — already unified ✅ - -Every brand color and surface already matches the site **by value** (only the names differ — dashboard prefixes with `--color-`). Verified in `src/app/globals.css:30-128`: - -| Concept | Site token (`tokens.css`) | Dashboard token (`globals.css`) | Match | -| -------------------------- | ------------------------------------------- | ------------------------------- | ------------ | -| primary | `--primary #e54d5e` | `--color-primary #e54d5e` | ✅ | -| primary-hover | `--primary-hover #c93d4e` | `--color-primary-hover #c93d4e` | ✅ | -| accent | `--accent #6366f1` | `--color-accent #6366f1` | ✅ | -| accent-2 | `--accent-2 #8b5cf6` | `--color-accent-hover #8b5cf6` | ✅ (renamed) | -| accent-3 | `--accent-3 #a855f7` | `--color-accent-light #a855f7` | ✅ (renamed) | -| success / warning / error | `#22c55e / #f59e0b / #ef4444` | identical | ✅ | -| traffic lights | `#ff5f56 / #ffbd2e / #27c93f` | identical | ✅ | -| dark bg / surface / border | `#0b0e14 / #161b22 / rgba(255,255,255,.08)` | identical | ✅ | -| light bg / surface / text | `#f9f9fb / #fff / #1a1a2e` | identical | ✅ | - -**Conclusion:** there is no color migration to do. The identity is already shared; we are _finishing_ it, not rebuilding it. - -### 3.2 Gaps — what the dashboard is missing - -| Gap | Site has | Dashboard | Action | -| ----------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------- | ---------------------- | -| **Grid wallpaper** | `body::before` graph-paper, `--grid-line`, `--grid-size 46px`, `--section-alt` | none (flat `--color-bg`) | **Part A** | -| **Radius scale** | `--radius 14px`, `--radius-sm 9px` | none — primitives use ad-hoc `rounded-md/lg/xl` (6/8/12px) | **Part B** | -| **Brand gradient** | `--grad-brand 135deg primary→accent-3` | none — only a one-off `.bg-hero-gradient` | **Part B** | -| **Nested surface** | `--surface-2 #1c2230` | none | **Part B** | -| **Mono font** | `--font-mono` (ui-monospace stack) | none (code/terminal areas have no token) | **Part B** | -| **`text-muted` (dark)** | `#8b8b9e` | `#a1a1aa` (zinc-400) | reconcile — **Part B** | - -### 3.3 Theming mechanics (so we don't break anything) - -- **Tailwind v4, CSS-first** (no `tailwind.config.*`). Tokens are defined in `:root`/`.dark` and exposed to utilities via `@theme inline` (`globals.css:130-179`). -- **Dark via `.dark` class** on `` (`@custom-variant dark` at `globals.css:22`), toggled by a custom Zustand store (`src/store/themeStore.ts`), default theme = `system` (`src/shared/constants/appConfig.ts:11`). The site uses `html[data-theme="light"]` instead — **the mechanisms differ but never meet** (separate origins), so no conflict. We keep the dashboard's `.dark` mechanism. -- **Runtime primary override** exists (`themeStore.ts:85-97`, presets in `COLOR_THEMES`) — users can swap `--color-primary`. Any new token (gradient, etc.) that references `--color-primary` will inherit those overrides for free. ✅ - ---- - -## 4. Part A — The graph-paper grid background (headline ask) - -### 4.1 What it is - -The exact recipe from the site (`_mono_repo/omnirouteSite/css/base.css`): a **fixed, full-viewport pseudo-element** painting two 1px line gradients, sitting at `z-index:-1` behind all content. - -```css -body::before { - content: ""; - position: fixed; - inset: 0; - z-index: -1; - pointer-events: none; - background-image: - linear-gradient(to right, var(--grid-line) 1px, transparent 1px), - linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px); - background-size: var(--grid-size) var(--grid-size); -} -``` - -**Why this works even though `body` has an opaque `background-color`:** a `::before` with `z-index:-1` paints _above_ the element's own background but _below_ its in-flow content. So `--color-bg` is the base fill, the grid is layered on top of it, and the app renders above the grid. - -### 4.2 Precedent already in the codebase - -`src/app/landing/page.tsx:16-26` **already implements this same grid per-page** — but with **red** lines (`#E54D5E`, opacity `0.06`) at **50px**, plus animated orbs. So the pattern is proven in the product; we are promoting it to a **global, theme-aware** wallpaper and (optionally) retiring the duplicate. - -### 4.3 Tokens to add (in `globals.css`) - -```css -:root { - /* light */ - --grid-line: rgba(0, 0, 0, 0.045); - --grid-size: 46px; - --section-alt: rgba(0, 0, 0, 0.022); -} -.dark { - /* dark */ - --grid-line: rgba(255, 255, 255, 0.035); - --section-alt: rgba(255, 255, 255, 0.018); -} -``` - -### 4.4 The single blocker - -The grid is global by construction (it covers the panel, `auth`/`login`, error pages — every route — at once). Exactly **one** element hides it inside the panel: - -- `src/shared/components/layouts/DashboardLayout.tsx:62` — the outer wrapper paints an opaque `bg-bg`: - - ```jsx -