On Client 360 → Modules, a client with many modules was one long flat stack of service
cards + checklists — hard to scroll and find, say, RTGS. Now each module is its own
collapsible section with a coloured accent header (module name + status + kind); all of
that module's data lives inside it. Click a header to collapse/expand. Headings stand
out so you can jump straight to the module you want.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Table pagers (Modules roster, Client 360 tickets) used an unstyled .wf-pager so the
summary text and Prev/Next butted together. Add .wf-pager flex styling: summary on the
left, Prev/page/Next pushed to the right end.
- Module Details: 'Billing kinds' label + checkboxes now on one line (was stacked).
- Module Fields: add a plain-language explainer — what the fields are (with an SMS
example) and WHERE they show up (each client's Modules tab + Catalog → Module data).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Home hub (/home) now shows only the day-to-day sections — Dashboard,
Clients, Documents, Reminders, Renewals, Pipeline, Tickets, SMS credits,
Modules — as a flat card grid; everything else stays in the sidebar.
- Sidebar section count badges (Layout.tsx): Reminders, Pipeline, Tickets,
Renewals and SMS now show a live count, fetched best-effort. Badges are
neutral by default, amber for SMS low balance, red for failed sends; the
reminder-queue badge moves from Dashboard to Reminders. Hidden when the
rail is collapsed.
- Neutral count-badge base + hub spacing (app.css).
Typecheck clean; web build + 410 tests green. The server.ts prod DB
password is intentionally left uncommitted.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two 'easily get to it' access screens:
- Portals (Catalog): every subscription with a stored login/URL across all modules,
Open ↗ links, 🔑 = password on file (reveal stays on Client 360). listPortals().
- Global search: the Ctrl-K palette now spans clients + issued documents + tickets in
one /search call (repos-search.globalSearch), each hit routing to its record; per-type
top-N with an honest 'capped' flag (no silent truncation).
Full suite 410 green; all three endpoints smoke-tested on live data (portals 78,
search capped, RTGS directory 13 fields).
Note: includes pages/Home.tsx (the concurrent dashboard-redesign session's Home hub)
so main.tsx's existing /home route resolves and the tree stays buildable; that session
owns its further iteration.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add a `data-palette` theme axis (neutral ground) alongside mode + accent:
Warm (default), Slate, Graphite, Zinc — selectable in Settings > Appearance,
persisted per browser. Backward-compatible: `warm` needs no attribute so the
existing look is unchanged; accent (7 hues) and light/dark stay orthogonal.
Swap the UI font Inter -> Geist Variable + Geist Mono Variable (bundled offline).
Add the `.dash-*` cockpit styles finishing the redesigned Dashboard markup
already in tree (flat Today hero, KPI row, reminder queue, bento sections;
low-colour, red reserved for real failures).
packages/ui theme.ts/tokens.css/ThemeSwitcher.tsx are shared — restyles every
page. Typecheck clean; 410 tests pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- The 7-swatch accent selector is removed from the top bar (it now lives only
in Settings > Appearance); the bar keeps a single compact light/dark ModeToggle.
This declutters the header and fixes most of the mobile congestion.
- Mobile pass (<=640px): search takes the bar, Ctrl-K hint + Gmail pill hidden,
avatar-only user chip; pages get real padding + bottom room; toolbars/chips
wrap with air; inputs full-width & 42px tall; stats 2-up; tables padded.
- Billing composer: client search + line-item cards go full-width and stack on
phones (composer-search / composer-line classes) so no container is undersized.
typecheck + web build clean, web tests 4/4.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Web manifest (standalone, id/scope/start_url=/, teal theme) + icon set
generated from the HQ mark: pwa-192, pwa-512, maskable-512 (full-bleed
safe-zone), apple-touch-icon 180, icon.svg. sharp added as a devDep for
generation.
- Service worker (public/sw.js): installable + fast repeat loads without
faking offline. NEVER touches /api or /share (always live); navigations
network-first with an app-shell fallback; hashed assets cache-first. Registered
from main.tsx in production builds only (skips Vite dev/HMR).
- index.html: manifest link, apple-touch-icon, apple/mobile-web-app meta,
viewport-fit=cover; vite-env.d.ts adds vite/client types.
- Phone polish (app.css): safe-area insets, 16px inputs (kills iOS focus-zoom),
40px tap targets, bottom-sheet dialogs, 2-up stat cards — on top of the existing
<900px drawer + scrolling tables.
typecheck + web build clean, web tests 4/4.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Red-team frontend clusters (a11y + UX + code quality), three coordinated passes:
Accessibility:
- DataTable clickable rows keyboard-operable (role=button, tabindex, Enter/Space).
- <main> landmark + skip link; icon-only buttons get aria-labels; inputs relying
on placeholder alone get aria-labels; AWS-ranking link is a real <button>;
Login fields wrapped in a <form> so Enter submits from either field; toasts
role=alert for errors (urgency not by color alone).
UX safety:
- 'Notify all' and reminder 'Send' now behind ConfirmDialogs naming the count/
client; document action bar disables while an action is in flight (no
double-submit dupes); SendDialog surfaces why a send is blocked instead of
failing silently; client search + ticket search debounced (~300ms); inline
Client-360 edit failures surface via toast, not an off-screen banner; LivePreview
gets a real Retry; destructive client-status transitions confirm first.
Code quality:
- ErrorBoundary wraps the app (a render throw no longer white-screens).
- useData clears stale data on dep change (no record flashing under a new id).
- Shared ErrorBoundary/SecretField/Pager components extracted; Pager adopted in
Documents; write-call api types tightened off Record<string,unknown>.
typecheck clean (root + both workspaces), web build clean, web tests 4/4, full
suite 388 green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
27 adversarially-confirmed findings from the multi-agent whole-branch review (2 deferred).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- sidebar collapses to an icon rail (footer toggle, localStorage-persisted;
nav tooltips via title; <900px hamburger untouched)
- dashboardView gains mine-scoping: staff are ALWAYS scoped to their book
(clients they own, docs/payments they created, their follow-ups, their queue);
owner/manager get a Mine/Everyone toggle (?mine=1)
- 1 test; suite green
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- QUOTATION renders one titled section per line: module name, its what's-
included block, SAC + qty × rate + amount; sections never split mid-page and
each module after the first opens a fresh page in print
- summary line up top ('This proposal covers: …'); totals/terms/signature
unchanged; INVOICE/PROFORMA/CN/RECEIPT keep the compact grid (regression-
asserted); preview-fidelity golden test untouched and green
- 3 tests; suite green
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chip was a bare link to /profile with a separate logout icon; the spec
(§5) calls for a small menu. Chip is now a button toggling a two-item menu
(Profile / Logout) that closes on outside click, Escape, and route change.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>