Template
Copperkey
A light, no-nonsense SaaS starter: a landing page with a typing terminal, a two-plan pricing page wired to hosted checkout, and a dashboard for team members, roles, security and an activity log. It gives builders auth, teams and billing so they can start on the actual product.
Team SaaS starter with terminal hero and role-based dashboard · App · Small tools and apps · full-stack app (auth + DB)
A mock-up of the homepage, drawn from this design’s layout, palette and typefaces. A build follows the full prompt below.
Add app screens
Pick up to 6 screens, such as a dashboard, settings or an empty state. Each is built in this design’s own palette and typefaces, with its states and guardrails.
Start from this templateRead the build prompt
Typefaces
Kumbh Sans is a tidy, friendly geometric grotesk for the warm-orange starter, and Fira Code gives the typed terminal its familiar developer look.
- Kumbh SansHeadings: headline 56px / 40px 700 at -0.02em, feature titles 18px 600
- Kumbh SansBody: body 16px/1.6 400/500
- Fira CodeFigures and code: terminal commands 14px
Patterns
- split hero with animated terminal card
- two-tone headline with accent second line
- outlined pill CTA with arrow
- three-column icon feature row with square accent tiles
- left sidebar settings shell
- activity log list
- members table with role select
States it is designed for
- terminal static under reduced motion
- sign-in error (wrong password) inline
- empty team with invite prompt
- pending invite row
- owner-only actions disabled for members with tooltip
- activity list empty and paginated
- checkout cancelled banner
- server action validation errors
Who it is for
- full-stack developers
- early-stage founders
- agencies bootstrapping client apps
Layout
- Header: circle logo mark + wordmark left; Pricing link and black 'Sign up' pill right
- Hero (light grey band): left 6 cols two-line headline (second line in orange), paragraph, outlined 'Deploy your own' pill; right 6 cols dark terminal card with traffic-light dots and copy icon; stacks under 1024px
- Features (white band): three columns with orange icon tile, title, two-line description; one column on mobile
- Secondary CTA band: heading + paragraph left, button right
- Pricing page: two plan cards with trial note and checkout button
- Dashboard: left sidebar (Team, General, Activity, Security) + main content; sidebar becomes a top menu on mobile
Palette
Friendly, practical, light. Warm orange on neutral greys keeps it approachable without looking toy-like.
- page background
#ffffff - hero band
#f9fafb - primary text
#111827 - secondary text
#4b5563 - orange accent (icons, headline line 2)
#ef6606 - orange text on light
#c2410c - primary button fill
#111827 - terminal card
#111827 - terminal text
#f9fafb - terminal prompt
#4ade80 - input / card border
#8b93a1
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 17.74:1 | 4.5:1 |
| Aa | body on hero band | 16.98:1 | 4.5:1 |
| Aa | muted text | 7.23:1 | 4.5:1 |
| Aa | button label | 17.74:1 | 4.5:1 |
| Aa | accent text / links | 5.18:1 | 4.5:1 |
| headline accent line (large) | 3.06:1 | 3:1 | |
| Aa | terminal text | 16.98:1 | 4.5:1 |
| Aa | terminal prompt | 10.18:1 | 4.5:1 |
| input border | 3.09:1 | 3:1 | |
| focus ring | 5.18:1 | 3:1 |
As vibld’s tokens
The palette on the fifteen colour tokens vibld styles a project with, each text colour on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.
- background
- card
- muted
- primary
- secondary
- accent
- destructive *
Type scale
- Display
- Kumbh Sans 700, 56px/1.1 desktop and 40px mobile, tracking -0.02em (similar to the observed geometric grotesk)
- Body
- Kumbh Sans 400/500, 16px/1.6
Fira Code 14px in the terminal; feature titles 18px 600.
Spacing and imagery
Comfortable; 1120px container; hero band 96px vertical padding; icon tiles 40px square, radius 8px; buttons full pill; cards radius 12px with 1px border and a small shadow in the app.
No photos. Square orange icon tiles with white line icons, a dark terminal mock with typed commands, simple avatars in the dashboard.
Components
- SiteHeader
- TerminalCard (typing, copy)
- FeatureTile
- PricingCard
- AuthForm
- DashboardSidebar
- MembersTable
- RoleSelect
- InviteMemberForm
- ActivityList
- PasswordForm
- DeleteAccountDialog
- Toast
Interactions
- Terminal types commands line by line, then shows a done mark; clicking copy copies all commands
- Hover darkens pills; focus ring orange
- Invite form validates email inline and adds a pending row optimistically
- Role change saves immediately with undo toast
- Remove member and delete account require confirmation
Data
User{id, email, name, password_hash, role (owner|member), created_at, deleted_at}Team{id, name, plan_name, subscription_status, provider_customer_id, provider_subscription_id}TeamMember{id, user_id, team_id, role (owner|member), joined_at}Invitation{id, team_id, email, role, invited_by, status (pending|accepted|revoked)}ActivityLog{id, team_id, user_id, action (SIGN_IN|SIGN_UP|UPDATE_PASSWORD|INVITE|REMOVE_MEMBER|...), ip_address, created_at}
Guardrails
Experience
- Headline second line is the only coloured text above the fold
- Make the terminal copyable and readable, not just decorative
- Owners see management controls; members see the same page read-only
- Log every security-relevant action in the activity list
- Keep pricing to two plans with a trial note
Accessibility
- Terminal has an accessible text alternative listing the commands
- Orange text on white uses the darker accent-text shade
- Members table uses real table semantics and labelled role selects
- Forms show errors next to fields and summarize on submit
- Traffic-light dots are decorative
- Sidebar is a nav with aria-current
Security
- RLS: teams, team_members, invitations and activity_logs readable only by members of that team (exists join on team_members where user_id = auth.uid())
- Only owners can insert/update/delete team_members and invitations (policy checks role = owner)
- Validate every server action with zod; rate-limit sign-in and invite
- Activity log is append-only; record IP only as needed and expire after 90 days
- Webhook signature verification for subscription updates
Build prompt
The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.
The baseline
### How to use these prompts Paste an entry's build prompt into your coding agent as the first message. Each prompt names its own stack, tokens and acceptance criteria; the rules below apply to all of them and can be prepended once per project. ### Engineering baseline - TypeScript strict mode, no `any`, small typed components, feature folders, and one source of truth for design tokens (CSS variables consumed by Tailwind). - Validate every input with a shared zod schema on the client and again on the server or edge function. Never trust client-side checks alone. - Show loading, empty and error states for every async view. Surface errors in plain language with a retry, and log details to the console in development only. - Keep secrets out of the bundle. Only publishable keys (for example a Supabase anon key) belong in client code; service-role keys, API keys and webhooks live in server or edge-function environment variables. ### Data and auth baseline (full-stack entries) - Enable Row Level Security on every table before inserting data. Default-deny, then add owner-scoped policies (`auth.uid() = user_id`) and explicit role checks for admin views. - Store roles in a separate table checked by a security-definer function, never in a user-editable profile field. - Upload files to private storage buckets with size and MIME limits, and serve them through signed URLs. - Rate-limit public endpoints (forms, auth, AI calls) and add a honeypot field or captcha to anonymous forms. - Take payments through a hosted checkout and verify webhooks by signature. Never handle raw card data. ### Accessibility and UX baseline - Target WCAG 2.2 AA: 4.5:1 contrast for normal text and 3:1 for large text, input borders, focus rings and meaningful icons or chart lines. Every palette in this catalog lists its verified pairs; re-check with a contrast tool after any colour change. - Keep body text at 16px or larger with 1.5 line height, nothing below 12px, no light weights under 24px, and uppercase only for short labels. - Give every interactive element a visible focus ring, full keyboard support, semantic landmarks, labelled form fields, and alt text on meaningful images. - Respect `prefers-reduced-motion` for every animation. Give drag-and-drop and carousels keyboard and button alternatives. - Build mobile-first and test at 375px, 768px and 1280px. ### Content guardrails - Use original copy, fictional sample data and placeholder or licensed imagery. Do not reuse another product's name, logo, screenshots or marketing text. - Label demo testimonials and metrics as samples. Collect the minimum personal data the feature needs. ### SaaS screen baseline - Design every screen for its full set of states: first-run empty, loading skeleton, partial data, error with retry, permission-denied, and success feedback. Each entry lists the states its screen needs. - Keep destructive actions (delete, revoke, downgrade, remove member) behind a confirmation that names the object, and prefer undo over a second dialog where the action is reversible. - Enforce authorisation on the server for every action a screen exposes. Hiding a button is not access control; check the role again in the API or RLS policy. - Never show secrets (API keys, tokens) in full after creation. Show them once, then mask them, and offer rotate and revoke. - Keep the app shell (navigation, workspace switcher, account menu) consistent across screens, and preserve filters, sort and scroll position when the user navigates back.
### Goal Build **Copperkey**, a starter for team-based SaaS. It ships a light landing page with a typing terminal, a two-plan pricing page tied to hosted checkout, email/password auth, and a dashboard where owners manage members and roles, change security settings and review an activity log. Builders should be able to clone it and start on their own features the same day. ### Stack Next.js (App Router), React, TypeScript, Tailwind CSS, shadcn/ui (Radix), lucide-react, react-hook-form + zod, TanStack Query, date-fns. Supabase Auth and Postgres (replace the original's custom JWT cookies with Supabase sessions). A hosted checkout provider with a customer portal and signed webhooks. ### Pages & layout 1. **/**: header (circle mark + wordmark, Pricing link, black Sign up pill). Hero on a light grey band: two-line headline with the second line in orange, paragraph, outlined "Deploy your own" pill with arrow; a dark terminal card on the right with three dots, copy icon and five typed commands. White band with three feature columns (orange icon tile, title, description). A closing CTA band. 2. **/pricing**: two plan cards (Base, Plus; invented prices) with a 14-day trial note and checkout buttons. 3. **/sign-in**, **/sign-up**: centered forms. 4. **/dashboard**: sidebar (Team, General, Activity, Security). Team: plan summary with "Manage subscription", members table with role select and remove, invite form. General: name/email form. Activity: chronological list with icons and relative times. Security: password change and delete account. Hero stacks under 1024px; sidebar becomes a top menu under 768px. ### Design system - Colors: `--bg: #ffffff` (page background), `--band: #f9fafb` (hero band), `--fg: #111827` (primary text), `--muted: #4b5563` (secondary text), `--accent: #ef6606` (orange accent (icons, headline line 2)), `--accent-text: #c2410c` (orange text on light), `--btn: #111827` (primary button fill), `--term-bg: #111827` (terminal card), `--term-fg: #f9fafb` (terminal text), `--term-prompt: #4ade80` (terminal prompt), `--border: #8b93a1` (input / card border). - Fonts: Kumbh Sans (Google Fonts) 700 headline 56px/1.1 (40px mobile), -0.02em; 400/500 body 16px/1.6; Fira Code 14px in the terminal. - Spacing: 4px base, 96px hero padding, 32px card padding, 24px grid gap. - Radius: full pills for buttons, 8px icon tiles, 12px cards and terminal. - Shadows: terminal `0 10px 30px rgb(0 0 0 / 0.15)`; app cards `0 1px 2px rgb(0 0 0 / 0.06)`. - Motion: terminal types at 40ms per character and 400ms between lines; disabled under reduced motion (show all lines). ### Components & interactions SiteHeader, TerminalCard (typing, copy-all, accessible command list), FeatureTile, PricingCard, AuthForm, DashboardSidebar, MembersTable, RoleSelect (owner only), InviteMemberForm (optimistic pending row), ActivityList, PasswordForm, DeleteAccountDialog (type email to confirm), Toast with undo for role changes. ### Data & state Tables: `teams`, `team_members(user_id, team_id, role)`, `invitations(team_id, email, role, status)`, `activity_logs(team_id, user_id, action, ip_address, created_at)`, plus provider ids and subscription status on `teams`. Server actions wrap every mutation with zod validation and write an activity row. Seed one team with an owner and two members (invented names). ### Accessibility Terminal exposes its commands as a visually hidden list. Orange body text uses `#c2410c`; bright `#ef6606` is for large headline text and icon tiles only. Tables have headers; role selects have labels naming the member. Errors appear next to fields. Focus ring 2px `#c2410c`. Verified contrast: body text: #111827 on #ffffff = 17.74:1; body on hero band: #111827 on #f9fafb = 16.98:1; muted text: #4b5563 on #f9fafb = 7.23:1; button label: #ffffff on #111827 = 17.74:1; accent text / links: #c2410c on #ffffff = 5.18:1; headline accent line (large): #ef6606 on #f9fafb = 3.06:1; terminal text: #f9fafb on #111827 = 16.98:1; terminal prompt: #4ade80 on #111827 = 10.18:1; input border: #8b93a1 on #ffffff = 3.09:1; focus ring: #c2410c on #ffffff = 5.18:1. ### Security - RLS on `teams`, `team_members`, `invitations`, `activity_logs`: select only when a `team_members` row links `auth.uid()` to that team; insert/update/delete on members and invitations only when the caller's role is owner. - `activity_logs` is insert-only via a security-definer function; no updates or deletes; purge IPs after 90 days. - Rate-limit sign-in, sign-up and invites; validate with zod. - Verify checkout webhooks and update team subscription fields idempotently. - Soft-delete accounts and anonymize email on deletion. ### Performance & SEO Static landing and pricing; dynamic dashboard with noindex. Preload Kumbh Sans 400/700 subsets. Keep the terminal pure CSS + small JS. Titles, descriptions and OG image on public pages. ### Guardrails - Invent product name, plans, members and log entries; no real brands. - Members never see owner-only controls as enabled. - Acceptance criteria: (1) sign-up creates a team with the user as owner; (2) invite, role change and removal work and are logged; (3) a member of team A cannot read team B; (4) checkout updates the plan summary; (5) terminal is readable with reduced motion and by screen readers.