Template
Voltessa
The workspace members page of a collaborative presentation tool. Owners invite people by typing an email, choosing a role and pressing one button, then see members in a tabbed list. The sidebar promotes the paid team library feature.
Workspace members with inline invite bar · App screen: team members · Small tools and apps · full-stack app (auth + DB)
A mock-up of the screen, drawn from its layout, palette and typefaces. A build follows the full prompt below.
Start from this screenRead the build prompt
Typefaces
The catalog's own faces. A screen composed into a template is drawn in that template's typefaces.
- InterHeadings: Inter 700, 26px H1
- InterBody: Inter 400/500, 16px/1.5; row name 16px 600; email 14px muted
Patterns
- inline invite bar (email + role + button)
- tabbed members list with count
- sidebar upsell card with illustration
- workspace switcher at top of sidebar
- upgrade link in accent colour
- centred content column
States it is designed for
- Only owner
- Pending invitations tab appears when invites exist
- Invalid email chip (red outline + message)
- Already a member
- Seat limit reached: inline upgrade prompt
- Promo dismissed
- Viewer: invite bar replaced with 'Ask an admin to invite people'
Who it is for
- Founders and team leads sharing a presentation workspace
- Marketing teams onboarding collaborators
- Freelancers inviting clients
Layout
- Sidebar (240px): user/workspace switcher with bell, accent 'Upgrade this workspace' link, search & commands field, Recents, Manage library, Links overview, collapsible Team and Private folders with 'Create folder' ghosts; promo card near bottom; Invite members (active), Recently deleted, Install app
- Main (max 640px, centred): H1 'Workspace members'
- Invite card: label left, help text with accent links right; row with email input containing an inline role dropdown, violet 'Invite member' button
- Members card: tab 'Members (1)' underlined in violet; row with photo avatar, name, email, role text right
- Help button bottom-right
- Mobile: sidebar becomes a drawer; invite row stacks (input full width, button below)
Palette
friendly, creative, confident. Inviting people feels as light as sharing a link.
- page
#ffffff - sidebar active fill
#f1f1f3 - primary text
#1b1b1f - muted text
#5e5e6a - border
#8b8b96 - accent violet
#6b46c1 - accent tint
#f1ebfd - promo illustration orange
#f25c19 - focus ring
#6b46c1 - error
#b42318
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 17.17:1 | 4.5:1 |
| Aa | muted text | 6.39:1 | 4.5:1 |
| Aa | violet button label | 6.42:1 | 4.5:1 |
| Aa | accent link on page | 6.42:1 | 4.5:1 |
| Aa | accent text on tint | 5.52:1 | 4.5:1 |
| Aa | sidebar active text | 15.22:1 | 4.5:1 |
| input border | 3.37:1 | 3:1 | |
| focus ring violet | 6.42: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.
- background
- card
- muted
- primary
- secondary
- accent
- destructive
Type scale
- Display
- Inter 700, 26px H1
- Body
- Inter 400/500, 16px/1.5; row name 16px 600; email 14px muted
Friendly grotesk similar to the observed face (Plus Jakarta Sans is an alternative).
Spacing and imagery
Centred column with 24px card padding; 16px gap between cards; input + button 40px tall radius 8px; cards radius 12px with 1px border; sidebar items 32px.
Photo avatars (use illustrated in mocks); a playful original 3D-style illustration in the promo card; line icons elsewhere.
Components
- Workspace switcher
- Upgrade link
- Search & commands
- Folder tree with create ghosts
- Promo card with CTA
- Invite bar (email input with embedded role select + button)
- Help links
- Members tabs with count
- Member row
- Role change menu
- Remove member dialog
- Pending invites tab
Interactions
- Typing comma or Enter in the email field turns entries into chips; paste of multiple emails supported
- Role dropdown inside the input (Admin, Editor, Viewer) with descriptions
- Invite button shows spinner then success toast; new invite appears under a 'Pending (n)' tab
- Role text becomes a menu on hover for admins
- Promo card dismissible
Data
Workspace{id, name, plan (free|pro|business), seat_limit}Member{workspace_id, user_id, name, email, avatar_url, role (owner|admin|editor|viewer)}Invite{id, workspace_id, email, role, status, invited_by, sent_at}
Guardrails
Experience
- Put invite first; the list is secondary
- Default role to the least privileged sensible one (Editor or Viewer), not Admin
- Link to role explanations next to the invite bar
- Show pending invites separately with resend/revoke
- Tell users before they hit the seat limit
Accessibility
- Email input has a visible label; chips are removable buttons with labels
- Role select inside the input is a separate focusable control with its own label
- Tabs show count in text
- Upgrade link is not colour-only: it has an icon and is underlined on hover/focus
- Promo illustration aria-hidden
Security
- RLS: members and invites visible to members; invites and role changes only by owner/admin
- Server validates emails and seat limits
- Invitation links single-use with expiry
- Rate-limit invites per workspace per day
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 **Voltessa**'s workspace members page for a collaborative presentation tool. An inline invite bar (email, role, button) sits on top, members are listed below in tabs, and the sidebar gently promotes the paid team library. ### Stack React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix primitives) and lucide-react icons. TanStack Query for server state, react-hook-form + zod for forms, date-fns for dates. Supabase for Auth, Postgres and Row Level Security. Invitation emails go through a transactional email service called from an Edge Function. ### Pages & layout 1. **Sidebar** (240px): avatar + workspace name switcher and bell; accent link 'Upgrade this workspace' with rocket icon; 'Search & commands'; Recents, Manage library, Links overview; collapsible Team and Private sections with ghost 'Create folder'; promo card 'Team library' (short copy, violet Set up button, original illustration); bottom: Invite members (active), Recently deleted, Install app. 2. **/workspace/members** (centred 640px): H1 'Workspace members'. 3. **Invite card**: 'Invite members' label; right text 'Learn about workspace roles and pricing' with accent links; row: email input with embedded role select (default Editor) and violet 'Invite member'. 4. **Members card**: tabs 'Members (1)' and 'Pending (n)'; rows with avatar, name, email, role. 5. Floating help button bottom-right. 6. Mobile: drawer sidebar; invite row stacks. ### Design system - Colors: `--bg: #ffffff` (page), `--active: #f1f1f3` (sidebar active fill), `--fg: #1b1b1f` (primary text), `--muted: #5e5e6a` (muted text), `--border: #8b8b96` (border), `--accent: #6b46c1` (accent violet), `--accent-bg: #f1ebfd` (accent tint), `--promo: #f25c19` (promo illustration orange), `--ring: #6b46c1` (focus ring), `--danger: #b42318` (error). - Fonts: Inter 400/500/600/700; H1 26px 700; body 16px/1.5; names 16px 600; emails 14px. - Spacing: 4px base; 24px card padding; 16px between cards. - Radius: cards 12px, inputs/buttons 8px, avatars full. - Shadows: none; 1px `--border` at 35% on cards; inputs full `--border`. - Motion: chip add 120ms scale; toast 200ms; tab underline 150ms. ### Components & interactions `WorkspaceSwitcher`, `UpgradeLink`, `CommandTrigger`, `FolderTree`, `PromoCard` (dismissible, remembered per user), `InviteBar` (`EmailChipsInput` + `RoleSelect` + button), `RoleHelpLinks`, `MembersTabs`, `MemberRow`, `RoleMenu`, `RemoveMemberDialog`, `PendingInviteRow` (resend, revoke), `SeatLimitNotice`. ### Data & state `workspaces(id, name, plan, seat_limit)`, `members(workspace_id, user_id, name, email, avatar_url, role)`, `invites(id, workspace_id, email, role, token_hash, status, invited_by, sent_at, expires_at)`, `promo_dismissals(user_id, promo_key)`. Seat usage = members + pending invites. Mock: one owner; toggle seeds three pending invites and a near-limit plan. ### Accessibility Email input labelled; chips are buttons 'Remove name@example.com'. Role select separate tab stop with its own label. Tabs contain counts in text. Upgrade link has icon + underline on focus. Focus ring 2px violet, offset 2px. Verified contrast: body text: #1b1b1f on #ffffff = 17.17:1; muted text: #5e5e6a on #ffffff = 6.39:1; violet button label: #ffffff on #6b46c1 = 6.42:1; accent link on page: #6b46c1 on #ffffff = 6.42:1; accent text on tint: #6b46c1 on #f1ebfd = 5.52:1; sidebar active text: #1b1b1f on #f1f1f3 = 15.22:1; input border: #8b8b96 on #ffffff = 3.37:1; focus ring violet: #6b46c1 on #ffffff = 6.42:1. ### Security RLS: `members`, `invites` select for workspace members; insert/update/delete only for owner/admin via policies checking `members.role`; owner cannot be removed except by transfer. Edge Function validates emails, dedupes against members, enforces seat limit, rate-limits (100/day). Invite tokens hashed, 14-day expiry, single use. `promo_dismissals` owner-only. ### Performance & SEO Lazy-load the promo illustration (SVG under 15KB). Members list paginated at 100. App routes `noindex`. ### Guardrails - Draw an original promo illustration; invent all people. - Default invite role is Editor, never Admin. - Keep upsell to one card and one link; no modal nags. Acceptance criteria: - [ ] Multiple emails become chips and invite in one go - [ ] Pending tab shows invites with resend/revoke - [ ] Seat limit blocks invites server-side with a clear message - [ ] Viewers see no invite bar - [ ] Contrast pairs pass