Files
fourge-portal/REDESIGN-LAYOUT2.md
T
Krao Hasanee c91e292066 redesign: Layout2 design-system + dashboard/tasks rework + perf
Design system (Layout2):
- Solid token-driven theme (no animated grid); single-source tokens for bg,
  cards (bg/border/radius), popups, fonts (Inter), and full semantic +
  data-viz color palette. Swept ~168 hardcoded colors to tokens.

Dashboard:
- Reflow: To Do + Calendar row (fixed right rail) over Activity / In-Progress /
  Team Performance; CSS height-match (To Do = Calendar); responsive stacking.
- 'Tasks Not Started' -> 'To Do' card with R#/Assigned columns; compact money fmt.

Tasks page:
- Combined tabs into Tasks + Completed with a Status column.
- Column-header sort + filter (Status, R#/new-vs-revision, Project, Task Type,
  Company) via portaled, scrollable FilterDropdown; removed toolbar filters and
  the projects side panel; headers stay visible when empty; renamed to 'Tasks'.

Perf:
- FK/filter index migration; removed redundant client/external scope waterfall
  (rely on RLS); parallel follow-up queries.

Mobile:
- Responsive grids; mobile topbar = hamburger only, blends with bg, proper offset.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 10:08:40 -04:00

194 lines
10 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.
# Layout2 — Redesign Tracker
> Visual redesign only. **Functions stay identical.** No data flow, query, route, or
> behavior changes. If a change touches logic, it does not belong in Layout2.
- **Branch:** `redesign`
- **Dev:** http://localhost:5173/ (Vite HMR, no rebuild)
- **Live:** untouched — nothing deploys until explicitly approved. No `vercel --prod` during Layout2.
- **Started:** 2026-06-23
---
## Rules
1. Redesign = layout, spacing, hierarchy, components' visual form. No prop/state/handler edits.
2. Keep every element that exists today (buttons, fields, badges) — reposition/restyle, don't remove function.
3. Preserve all routes, role gates (`team`/`external`/`client`), and conditional rendering as-is.
4. Reuse design tokens (below). Add new tokens rather than hard-coding values.
5. Commit per page/section with `redesign:` prefix so it's revertible.
---
## Direction
- **Background:** solid 95% black `#0d0d0d`, no gradient, no animation.
- **Cards:** solid gray `#1a1a1a` (5% lighter than bg); elevated/hover `#242424`.
- **Font:** **Inter** (Google Fonts, weights 300700) — modern, readable, app-wide. Brand `Fourge` font retired from UI text; logo is an image, unaffected.
---
## Control panel (single source of truth — `src/index.css :root`)
Change one line, every card/page across **all roles** updates.
| Knob | Token / line | Scope |
|---|---|---|
| Background | `--bg` | whole app |
| Card fill | `--card-bg` (+ `--card-bg-2` elevated/hover) | every card |
| Card border | `--card-border` (`1px solid transparent` = off) | every card |
| Card radius | `--card-radius` | every card |
| Font | body `font-family` (Inter) | whole app |
| Accent / gold | `--accent` (+ `--accent-hover`) | all gold UI |
| Status: error | `--danger` (+ `--danger-strong`) | all red |
| Status: success | `--success` (+ `--success-strong`) | success greens |
| Money/positive | `--positive` | dashboard/positive green |
| Info | `--info` | blue |
| Violet | `--violet` | purple |
| Warning | `--warning` | amber |
**Tints** pull from the same token: `color-mix(in srgb, var(--accent) 15%, transparent)`.
All semantic colors are theme-independent (badge light palette stays in `index.css`).
~168 hardcoded hex/rgba across 15 JSX files were swept to these tokens (zero visual change).
Cards = elements with `var(--card-bg)`; their frame uses `var(--card-border)`. The **menu/sidebar**
also uses `--card-border` + `--card-radius`. Inputs/tables/toolbar dividers keep their own `--border`
and are intentionally NOT card-controlled.
**Theming:** tokens live in `:root` (dark defaults); `[data-theme="light"]` overrides values.
Same token name site-wide, one value per theme. `--card-border` is set in both themes
(dark `#262626`, light `rgba(0,0,0,0.08)`); `--card-radius` is shared (color-free).
## Full token chart (canonical — `src/index.css`)
All in `:root` (dark); `[data-theme="light"]` overrides where noted. Same token name site-wide,
one value per theme. Solids = `var(--x)`; tints = `color-mix(in srgb, var(--x) N%, transparent)`.
### Surfaces
| Token | Dark | Light |
|---|---|---|
| `--bg` | `#1a1a1a` | `#ffffff` |
| `--card-bg` | `#1f1f1f` | `rgba(0,0,0,.02)` |
| `--card-bg-2` | `#262626` | `rgba(0,0,0,.08)` |
| `--surface-sunken` | `#141414` | `#f5f5f5` |
| `--popup-bg` | `var(--card-bg)` (= `#1f1f1f`) | `rgba(255,255,255,.92)` (opaque; light card-bg is translucent) |
### Borders
| Token | Dark | Light |
|---|---|---|
| `--border` | `rgba(245,165,35,.15)` | `rgba(0,0,0,.1)` |
| `--card-border` | `1px solid #262626` | `1px solid rgba(0,0,0,.08)` |
| `--card-radius` | `8px` | shared |
| `--interactive-hover-border` | `rgba(245,165,35,.3)` | `rgba(0,0,0,.2)` |
### Text
| Token | Dark | Light |
|---|---|---|
| `--text-primary` | `#ffffff` | `#0d0d0d` |
| `--text-secondary` | `#a8a8a8` | `rgba(0,0,0,.6)` |
| `--text-muted` | `#666666` | `rgba(0,0,0,.38)` |
| `--text-on-accent` | `#000000` | shared |
### Brand & status (theme-independent)
| Token | Value |
|---|---|
| `--accent` / `--accent-hover` | `#F5A523` / `#e09510` |
| `--danger` / `--danger-strong` | `#ef4444` / `#dc2626` |
| `--success` / `--success-strong` | `#22c55e` / `#16a34a` |
| `--positive` | `#4ade80` |
| `--info` | `#60a5fa` |
| `--violet` | `#a78bfa` |
| `--warning` | `#f59e0b` |
### Data / categorical (charts, file-type chips — by hue)
| Token | Value | Token | Value |
|---|---|---|---|
| `--data-blue` | `#3b82f6` | `--data-indigo` | `#2563eb` |
| `--data-purple` | `#8b5cf6` | `--data-purple-soft` | `#c084fc` |
| `--data-pink` | `#ec4899` | `--data-pink-soft` | `#f472b6` |
| `--data-orange` | `#f97316` | `--data-orange-soft` | `#fb923c` |
| `--data-emerald` | `#10b981` | `--data-emerald-soft` | `#34d399` |
| `--data-gray` | `#6b7280` | | |
### Utility / misc
| Token | Dark | Light |
|---|---|---|
| `--overlay-scrim` | `rgba(0,0,0,.58)` | `rgba(255,255,255,.72)` |
| `--popup-shadow` | `0 24px 64px rgba(0,0,0,.5)` | lighter |
| `--avatar-inner-ring` | `#111111` | `#ffffff` |
| `--sidebar-*` | bg `#0d0d0d`, text `#888`, active `#fff`/`#1a1a1a` | inverted |
| motion | `--motion-fast 160ms`, `--motion-base 220ms`, ease `cubic-bezier(0.22,1,0.36,1)` | |
| buttons | h `22px`, radius `8px`, font `11px/500`, tracking `0.8px` | |
**Intentionally NOT tokenized (must stay literal):**
- Canvas/PDF export colors (`BrandBook.jsx`, `Converters.jsx``ctx.fillStyle`), white logo backgrounds.
- `PayInvoice.jsx` — public printable invoice, standalone light styling, must not follow app theme.
**Established patterns (from memory):**
- Card label color `rgba(255,255,255,0.8)`.
- Filter/tab layout: dropdowns *outside* card, tab buttons *inside* card above table. Canonical: `Tasks.jsx` (Requests).
---
## Shared shell / components
| Item | File | Status |
|---|---|---|
| App shell / sidebar / nav | `src/components/Layout.jsx` | ⬜ |
| Global tokens & base CSS | `src/index.css` | ⬜ |
| StatusBadge | `src/components/StatusBadge.jsx` | ⬜ |
| FilterDropdown | `src/components/FilterDropdown.jsx` | ⬜ |
| SortTh (table headers) | `src/components/SortTh.jsx` | ⬜ |
| ProfileAvatar | `src/components/ProfileAvatar.jsx` | ⬜ |
| LoadingButton / PageLoader | `src/components/{LoadingButton,PageLoader}.jsx` | ⬜ |
| RequestForm | `src/components/RequestForm.jsx` | ⬜ |
| Invoice popups / tables | `InvoiceDetailPopup`, `InvoicePopupTable` | ⬜ |
| Subcontractor invoice form/view | `SubcontractorInvoice{Form,DetailView}.jsx` | ⬜ |
| FileAttachment | `src/components/FileAttachment.jsx` | ⬜ |
## Pages
| Route | Page | Roles | Status |
|---|---|---|---|
| `/` | Login | all | ⬜ |
| `/dashboard` | `team/TeamDashboard.jsx` | team/external/client | ⬜ |
| `/tasks` | `Tasks.jsx` (Requests) | team/external/client | ⬜ |
| `/tasks/:id` | `TaskDetail.jsx` | team/external/client | ⬜ |
| `/projects/:id` | `ProjectDetail.jsx` | team/external/client | ⬜ |
| `/company` | `Companies.jsx` | team/client | ⬜ |
| `/company/:id` | `CompanyDetail.jsx` | team/client | ⬜ |
| `/finances` | `team/TeamInvoices.jsx` | team | ⬜ |
| `/finances/:id` | `team/TeamInvoiceDetail.jsx` | team | ⬜ |
| `/subcontractor-pos/new` | `team/TeamCreateSubcontractorPO.jsx` | team | ⬜ |
| `/subcontractor-pos/:id` | `team/TeamSubcontractorPODetail.jsx` | team | ⬜ |
| `/sub-invoices/:id` | `team/TeamSubInvoiceDetail.jsx` | team | ⬜ |
| `/reports` | `team/TeamReports.jsx` | team | ⬜ |
| `/fourge-passwords` | `team/TeamFourgePasswords.jsx` | team | ⬜ |
| `/survey-maker` | `SurveyMaker.jsx` | team/external | ⬜ |
| `/brand-book` | `BrandBook.jsx` | team/external | ⬜ |
| `/converters` | `Converters.jsx` | team/external | ⬜ |
| `/my-purchase-orders` | `external/ExternalMyPurchaseOrders.jsx` | external | ⬜ |
| `/subs-invoices` | `external/ExternalMyInvoices.jsx` | external | ⬜ |
| `/subs-invoices/new` | `external/ExternalMyInvoiceCreate.jsx` | external | ⬜ |
| `/subs-invoices/:id` | `external/ExternalMyInvoiceDetail.jsx` | external | ⬜ |
| `/client-invoices` | `client/ClientMyInvoices.jsx` | client | ⬜ |
| `/profile`, `/profile/:id` | `Profile.jsx` | all | ⬜ |
| `/pay/:id` | `PayInvoice.jsx` | public | ⬜ |
Legend: ⬜ todo · 🔄 in progress · ✅ done
---
## Log
- 2026-06-23 — Doc created, `redesign` branch cut, dev on 5173.
- 2026-06-23 — Base tokens: solid `#0d0d0d` bg, killed animated grid; cards `#1a1a1a`/`#242424`. Font → Inter.
- 2026-06-23 — bg → `#1a1a1a` (90% K), cards `#1f1f1f`/`#262626` (88% K), solid/no transparency.
- 2026-06-23 — Tokenized cards: added `--card-border` (off) + `--card-radius`; swept 28 inline card frames + `.card` class to the tokens. All cards now controllable from one line.
- 2026-06-23 — Card border on at `#262626` (85% K); light-mode `--card-border` = `rgba(0,0,0,0.08)`; menu/sidebar routed to `--card-border`/`--card-radius`.
- 2026-06-23 — Color system: added `--positive/--info/--violet/--warning/--danger-strong/--success-strong`; swept 168 hardcoded colors across 15 JSX files to tokens + `color-mix` tints. Site/role/page colors now single-source.
- 2026-06-23 — Completed palette: added `--data-*` (hue-named) categorical set, `--surface-sunken`, `--text-on-accent`. Swept file-type chips + chart colors + surface neutrals to tokens. Remaining literals are canvas/PDF exports + PayInvoice (intentional). Full chart documented above.
- 2026-06-23 — Popups single-source: `--popup-bg` now = `var(--card-bg)` (dark); stripped 8 inline `background: var(--card-bg)` overrides on `popupSurfaceStyle` so loader/modals/menus all use the token. Light stays opaque white.
- 2026-06-23 — Dashboard reflow: row2 = To Do (fluid) + Calendar (280px); row3 = Activity / In-Progress / Team Perf. New `.dash-row-todo` / `.dash-row-trio` classes; responsive (trio 2-up ≤1200, all stack ≤768). Retired bottomCardsHeight viewport-fill hack. Mobile-friendly is now a standing requirement for Layout2.
- 2026-06-23 — Perf sweep: root cause = ~400770ms/query server cold-start (compute tier, infra). Code fixes: added FK/filter index migration (pushed to DB); removed redundant client/external scope waterfall in Tasks + Dashboard (rely on RLS, verified `has_company_access`/`project_members` parity); embedded submitter-profiles + deliveries into the Tasks submissions query (2 round trips all roles). Test client/external dashboards on 5173.