← RequestWave — White-label Client Portal project

Product design system

RequestWave, broken down.

A white-label client portal means one component system, re-skinned per agency tenant. This page takes it apart: the palette observed from the live product, the type, and the defining move rebuilt live — the same portal re-themed per tenant. Exact tokens (Tailwind + shadcn) land from the repo (manifest).

In my words

What I built

RequestWave is my own product — I designed the brand, the UI, and built the full stack solo: React front end, a multi-tenant Postgres backend with row-level security, Stripe Connect payments, transactional email. No handoff, brand to backend.

The design problem that shaped everything: white-label. Every agency runs the portal under its own name and colors, so the system had to separate what's constant (layout, components, flows) from what's the tenant's (brand). The toggle below is that separation, made literal.

Role
Founder — brand → backend
Since
2025
Stack
React · Supabase · Stripe
Model
Multi-tenant · RLS

The originals

The finished outputs, first

The live marketing site (requestwave.com).

requestwave.com
requestwave.com
Marketing hero

Color

Constants, and what varies

Observed from the live product (dark navy ground, a product blue). Exact tokens are confirmed from the repo's Tailwind config + shadcn theme.

Constants

App ground
#0a0e1a
Product blue
#2563eb
Panel
#0f172a
Paper
#f8fafc
Success
#22c55e
Review
#f59e0b

The tenant brand — the variable

Each agency's accent replaces the product blue across the whole portal. Four sample tenants below; try the live toggle.

Northwind
#6366f1
Nova
#059669
Bright
#e11d48
Atlas
#0891b2

Type

Typefaces + specimens

Requests
Display / product — Grotesque black.
Active · Review · Done
UI / labels — Grotesque sans.

Closest-match stand-ins; the production type comes from the repo tokens.

White-label

The same portal, any agency — live

The defining move: pick a tenant and the portal re-skins (accent + name) while the layout stays fixed. A real rebuild of the multi-tenant theming.

N
Northwind Studio
Requests
+ New request
12
Active
5
Review
28
Done
Brand refreshIn review
Landing pageActive
Q3 campaignDone

One component tree, one database — the tenant's brand (name + accent) is a prop. Row-level security keeps each agency's data walled off underneath.

The chrome

Repeating components, named

The component system the white-label runs on.

Tenant brand slot
Name + accent as props — the only thing that changes per agency.
4 tenants
Request pipeline
Intake → requests → approvals → billing, one flow.
activereviewdone
Stat header
Active / Review / Done counts — the dashboard's pulse.
Row-level security
Enforced in Postgres, not the UI — no tenant can read another's rows.

The asset set

The vocabulary the system draws on

Flows
IntakeRequestsApprovalsBilling
Tenant accents
Stack
ReactViteTypeScriptTailwindshadcn/uiSupabaseStripe Connect

What it took

Built with

The full stack, brand to backend — one person, no handoff.

FigmaReactTypeScriptViteTailwindshadcn/uiNodeSupabaseStripe ConnectPostgres + RLSNetlifyBrevo

Product lexicon

The stack, in its own words

Multi-tenant
One app + one database serving many agencies, isolated per tenant.
RLS
Row-level security — Postgres enforces isolation at the row, not the UI.
White-label
Each agency runs the portal under its own brand; the brand is a prop.
Design tokens
The palette / type / spacing variables the whole UI reads from.
Stripe Connect
Marketplace payments — each tenant gets paid through the platform.
Transactional email
System-triggered mail (approvals, receipts) vs. marketing sends.

RequestWave brand, product UI, and full-stack build by Leonel Gomez. Palette is observed from the live marketing site; the portal above is a React reconstruction of the white-label theming, not the production app.