Template
Tamberly
The admin 'People & security' page of an AI assistant workspace. It groups domain verification (for SSO and auto-enrolment), an auto-join toggle, and the members list with invitations into one scrolling page so an admin can secure and populate a workspace in one place.
Workspace people and security admin page · 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 600, 26px H1; 20px section headings
- InterBody: Inter 400/500, 16px/1.5; table 15px; sidebar group labels 13px 600
Patterns
- admin sidebar with grouped sections
- top-level mode tabs (Chat / Spaces / Admin)
- stacked settings sections on one page
- dashed empty panel with centred CTA
- members table with tabs (Members / Invitations)
- role pill
- usage meter in sidebar footer
States it is designed for
- No domains (empty panel)
- Domain pending verification (polling, 'Check again')
- Domain verification failed with reason
- Auto-join disabled/enabled
- Single member (you)
- No pending invitations
- Invite errors (invalid email, already member, seat limit)
- Trial usage near limit (meter amber)
Who it is for
- Workspace admins rolling out an AI assistant to a company
- IT leads configuring domain verification and SSO
- Team leads inviting colleagues
Layout
- Sidebar (200px, light grey): mode tabs at top (Chat, Projects, Admin active with underline); groups Workspace (People & security active, Workspace settings, Analytics, Subscription), API & programmatic (API keys, Programmatic usage), Builder tools (Providers, Secrets); footer usage meter card and workspace/help switchers
- Main (max 760px): section icon + H1 + description
- Domain verification: heading with globe icon, description, grey panel with centred dark 'Add domain' button
- Auto-join workspace: heading, description, secondary 'Activate auto-join' button (disabled until a domain is verified)
- Members: heading, search field + dark 'Invite members' button, tabs Members / Invitations, table (Name, Email, Role pill), item count
- Mobile: sidebar behind a menu; table becomes cards
Palette
orderly, serious, administrative. Security and people management on one calm page.
- page
#ffffff - sidebar
#f7f7f7 - empty panel
#f3f3f4 - primary text
#111418 - muted text
#5b5f6b - border
#8a8e99 - dark button
#1e2230 - disabled button fill
#d4d4d8 - disabled label
#3a3a40 - admin pill fill
#fde4ec - admin pill text
#c0265f - focus ring
#2563eb
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on page | 18.47:1 | 4.5:1 |
| Aa | muted text on page | 6.38:1 | 4.5:1 |
| Aa | sidebar text | 5.95:1 | 4.5:1 |
| Aa | dark button label | 15.83:1 | 4.5:1 |
| Aa | disabled button label | 7.64:1 | 4.5:1 |
| Aa | admin pill text | 4.75:1 | 4.5:1 |
| dark button on empty panel | 14.27:1 | 3:1 | |
| input border | 3.28:1 | 3:1 | |
| focus ring | 5.17: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
- Inter 600, 26px H1; 20px section headings
- Body
- Inter 400/500, 16px/1.5; table 15px; sidebar group labels 13px 600
Neutral grotesk similar to observed; section headings carry a leading 20px icon.
Spacing and imagery
Settings scroll page: 32px between sections, 16px within; empty panel 160px tall radius 12px; table rows 48px; buttons 36px tall radius 8px; sidebar items 32px.
Monochrome line icons per section; no illustrations.
Components
- Mode tabs
- Grouped admin sidebar
- Usage meter card (messages used / limit)
- Section header with icon
- Empty panel with CTA
- Add domain dialog with DNS TXT instructions and copy
- Auto-join toggle button
- Member search
- Invite members dialog (emails, role)
- Members/Invitations tabs
- Members table with role pill
- Invitation row actions (resend, revoke)
Interactions
- Add domain opens a dialog showing a TXT record to copy and a Verify button with pending/verified/failed states
- Activate auto-join stays disabled with an explanation until a domain is verified
- Search filters members by email
- Tabs switch between members and pending invitations
- Role pill opens a menu to change role (admins only); you cannot demote the last admin
Data
Workspace{id, name, plan, trial_messages_used, trial_messages_limit, auto_join_enabled}Domain{id, workspace_id, domain, txt_token, status (pending|verified|failed), verified_at}Member{workspace_id, user_id, email, name, role (admin|builder|user)}Invitation{id, workspace_id, email, role, status (pending|accepted|revoked|expired), sent_at}
Guardrails
Experience
- Order sections by dependency: verify domain, then auto-join, then members
- Explain why a disabled action is disabled right beside it
- Show '(you)' next to the current user and block removing the last admin
- Make DNS records copyable with one click
- Keep member and invitation lists separate but one tab apart
Accessibility
- Disabled auto-join button still has 4.5:1 label contrast and aria-describedby pointing at the reason
- Tabs use Radix Tabs with correct roles
- Role pill text readable (4.5:1) and role also shown in text for screen readers
- Dialogs trap focus and return it
- Usage meter has text '3 of 100 messages used'
Security
- Domain verification via DNS TXT checked server-side; tokens random per domain
- RLS: members read workspace data; only admins manage domains, invitations and roles
- Invitations signed, single-use, expire in 7 days
- Rate-limit invitations per workspace
- Audit role changes and domain changes
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 **Tamberly**'s 'People & security' admin page for an AI assistant workspace. One scrolling page lets an admin verify company domains (for SSO and automatic enrolment), switch on auto-join, and manage members and invitations. ### 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. A scheduled Edge Function checks DNS TXT records for pending domains. ### Pages & layout 1. **Sidebar** (200px, `--sidebar`): mode tabs Chat / Projects / Admin (active underline); group 'Workspace' (People & security, Workspace settings, Analytics, Subscription), 'API & programmatic' (API keys, Programmatic usage), 'Builder tools' (Providers, Secrets). Footer: usage card 'Trial messages used 3 / 100' with a thin meter; workspace switcher and Help menu. 2. **/admin/people** main column (max 760px): icon, H1 'People & security', muted description. 3. **Domain verification** section: globe icon heading, description about SSO and auto-enrolment, `--panel` box with centred '+ Add domain'. When domains exist, list rows with domain, status chip, 'Check again', remove. 4. **Auto-join** section: heading, description, 'Activate auto-join' button (disabled until a verified domain exists, reason text beside it). 5. **Members** section: search + '+ Invite members'; tabs Members / Invitations; table Name (avatar, '(you)'), Email, Role pill; count '1 item'. 6. Mobile: sidebar in a sheet; tables to cards. ### Design system - Colors: `--bg: #ffffff` (page), `--sidebar: #f7f7f7` (sidebar), `--panel: #f3f3f4` (empty panel), `--fg: #111418` (primary text), `--muted: #5b5f6b` (muted text), `--border: #8a8e99` (border), `--primary: #1e2230` (dark button), `--disabled: #d4d4d8` (disabled button fill), `--disabled-fg: #3a3a40` (disabled label), `--role-bg: #fde4ec` (admin pill fill), `--role: #c0265f` (admin pill text), `--ring: #2563eb` (focus ring). - Fonts: Inter 400/500/600; H1 26px 600; section headings 20px 600; body 16px/1.5; table 15px. - Spacing: 4px base; 32px between sections. - Radius: panel 12px, buttons and inputs 8px, pills 9999px. - Shadows: none; dividers 1px `--border` at 30%. - Motion: 150ms tab underline slide; dialogs fade 150ms. ### Components & interactions `ModeTabs`, `AdminSidebar`, `UsageMeter`, `SectionHeader`, `EmptyPanel`, `AddDomainDialog` (domain input, TXT record with copy, Verify), `DomainRow` + `DomainStatusChip`, `AutoJoinButton` (disabled reason via aria-describedby), `MemberSearch`, `InviteDialog` (multi-email chips, role select, seat check), `MembersTabs`, `MembersTable`, `RolePill` (menu for admins), `InvitationRow` (resend, revoke). ### Data & state `workspaces(id, name, plan, trial_messages_used, trial_messages_limit, auto_join_enabled)`, `domains(id, workspace_id, domain unique, txt_token, status, verified_at)`, `members(workspace_id, user_id, email, name, role)`, `invitations(id, workspace_id, email, role, token_hash, status, sent_at, expires_at)`, `audit_events`. Mock states via seed: no domains, one pending, one verified. ### Accessibility Disabled button keeps readable contrast and explains itself. Tabs are Radix Tabs. Role pill includes visually hidden 'Role:' prefix. Copy buttons announce 'Copied'. Usage meter uses `role=meter` with text. Focus ring 2px `--ring`. Verified contrast: body text on page: #111418 on #ffffff = 18.47:1; muted text on page: #5b5f6b on #ffffff = 6.38:1; sidebar text: #5b5f6b on #f7f7f7 = 5.95:1; dark button label: #ffffff on #1e2230 = 15.83:1; disabled button label: #3a3a40 on #d4d4d8 = 7.64:1; admin pill text: #c0265f on #fde4ec = 4.75:1; dark button on empty panel: #1e2230 on #f3f3f4 = 14.27:1; input border: #8a8e99 on #ffffff = 3.28:1; focus ring: #2563eb on #ffffff = 5.17:1. ### Security RLS: `workspaces`, `members` select for members; `domains`, `invitations` select/insert/update only for `role = admin`; role updates via a security-definer function that refuses to remove the last admin. TXT tokens random 32 bytes; verification done server-side. Invitation tokens hashed, single use, 7-day expiry. Rate-limit invites (50/day per workspace). Audit domain, auto-join and role changes. ### Performance & SEO Section data loaded in parallel; tables paginated at 50. Admin routes `noindex`. ### Guardrails - Invent workspace names, members and domains (use example.com-style domains). - Name SSO providers generically. - Never let a non-admin see domain tokens. Acceptance criteria: - [ ] Add domain shows a copyable TXT record and verifies - [ ] Auto-join enables only after verification - [ ] Last admin cannot be demoted - [ ] Invitations can be resent and revoked - [ ] Contrast pairs pass