Files
fourge-portal/REDESIGN-LAYOUT2.md
T
Krao Hasanee 0d6ac3666e fix: revert leftover Project→Client mislabels, drop tracked .env.backfill
Rename in 91045a1 was only partially reverted by later commits, leaving
~20 UI spots calling the project entity "Client" while table headers
already said "Project". Reverted all of them plus the /clients/:id
route (now /projects/:id canonical again, nothing was live yet).

Also: stop tracking .env.backfill (had a live admin password/token
committed - rotate those credentials), remove stale pre-redesign
layout.md superseded by REDESIGN-LAYOUT2.md.
2026-07-15 15:14:57 -04:00

195 lines
11 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.
- 2026-07-15 — Naming cleanup: the 91045a1 Project→Client rename was only partially walked back by later commits, leaving the project entity mislabeled "Client" in ~20 spots (Add Project modal, filters, PO/report/dashboard columns, etc.) while table headers already said "Project". Confirmed with user: **Company** = the customer org (e.g. "Public Storage"), **Project** = a job within that company — "Client" was a leftover label, not a third entity. Reverted all mislabeled text to "Project"; reverted the `/clients/:id` route back to canonical `/projects/:id` (nothing deployed to prod yet, so no live URLs broke). Also: removed stale pre-redesign `layout.md` (superseded by this doc), stopped tracking `.env.backfill` (had a live admin password/token committed — rotate those credentials separately).