Skip to main content
vibld

Template

Rostane

An admin invites several people at once to an AI workspace by pasting emails and choosing a role. The drawer keeps the people-and-security settings visible behind it so admins stay oriented.

Invite-users drawer over team security settings · App screen: invite team · 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, 20px drawer title, 28px page title
  • InterBody: Inter 400, 16px, line-height 1.5

Patterns

  • right drawer form over settings page
  • large multi-email textarea
  • role pill select with helper line
  • sticky drawer footer with Cancel and Send
  • trial banner at top
  • admin sidebar with grouped sections
  • members/invitations tabs

States it is designed for

  • empty: Send disabled
  • validation: invalid emails listed with reasons
  • sending
  • partial success: some addresses already members, listed
  • seat limit: warning with Subscription link
  • permission-denied for non-admins: drawer never opens, button hidden
  • server error with Retry

Who it is for

  • workspace admins
  • IT managers onboarding a department

Layout

  1. sidebar: tabs Chat / Spaces / Admin; groups Workspace (People & security, Settings, Analytics, Subscription), API (Keys, Programmatic usage), Builder tools (Providers, Secrets); footer trial meter
  2. main (dimmed): trial banner, People & security title, Domain verification card, Auto-join card, Members with search and Members/Invitations tabs and table
  3. right drawer (~40% width): title and close button, label, tall textarea, Role row with pill select and chevron, helper sentence, sticky footer with Cancel and Send invite
  4. below 768px the drawer is full-screen

Palette

Practical and plain; one big field, one choice, one button.

  • bg#ffffff
  • canvas#f5f6f8
  • text#161a22
  • muted#5d6472
  • border#8d94a1
  • role#e3f7c9
  • role-text#2f5a0c
  • primary#1e5bd8
  • disabled#c7ccd4
  • banner#fff4d6

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text17.43:14.5:1
Aahelper text5.95:14.5:1
Aarole pill text7.11:14.5:1
AaSend button label5.93:14.5:1
textarea border3.05:13:1
focus ring5.93:13:1
Aatrial banner text15.90:14.5: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, 20px drawer title, 28px page title
Body
Inter 400, 16px, line-height 1.5

Field labels 16px 600; helper text 15px; table headers 13px 600.

Spacing and imagery

Density: Medium. Grid: 8px; drawer padding 16-24px. Container: drawer 40vw clamped 400-520px. Radius: 6px textarea and buttons, full pill for role. Shadows: Drawer left shadow; footer has a top border instead of a shadow.

Line icons only (people, globe, lock, key).

Components

  • TrialBanner
  • AdminSidebar
  • MembersTable with tabs
  • InviteDrawer
  • EmailTextarea
  • RoleSelect pill
  • RoleHelperText
  • DrawerFooter

Interactions

  • Emails parsed live; count shown under the field ('3 valid, 1 invalid')
  • Role select changes the helper sentence describing permissions
  • Send disabled until ≥1 valid email; shows spinner while sending
  • On success the drawer closes and the Invitations tab gains a count badge
  • Esc or Cancel closes; unsaved text triggers a discard confirm

Data

  • Membership{workspace_id, user_id, role (admin|builder|member)}
  • Invitation{id, workspace_id, email, role, status (pending|accepted|revoked|expired), sent_at}
  • Workspace{id, name, seats, trial_ends_at}

Guardrails

Experience

  • Accept comma and newline separators and trim whitespace
  • Explain the selected role in one plain sentence
  • Show a per-address result after sending
  • Keep Cancel as a secondary text button left of Send
  • Keep the trial banner dismissible per session

Accessibility

  • Drawer is a dialog with labelled title and focus trap
  • Textarea has a visible label and describes its separator rules
  • Role select is keyboard operable and its helper text is aria-describedby
  • Result list announced via aria-live=polite
  • Disabled Send has aria-disabled and an explanation

Security

  • Only admins can invite (RLS on invitations: insert where caller is admin)
  • Server re-validates emails and dedupes against memberships
  • Rate-limit to 100 invites/hour per workspace
  • Log invitations to an audit table
  • Invite tokens are single-use and expire

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 **Rostane**, the invite-users drawer on a workspace's people-and-security settings page. Admins paste many emails, pick a role and send; results show per address. Build the admin sidebar shell, the settings page behind a scrim and the drawer.

### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui on Radix primitives and lucide-react icons. TanStack Query for server state, react-hook-form + zod for every form, date-fns for relative times. Supabase for Auth, Postgres with row-level security and Edge Functions for anything that needs a secret. Invite emails go out through a transactional email service from an Edge Function.

### Pages & layout
1. **Sidebar** with three top tabs and grouped admin links; trial usage meter in the footer.
2. **People & security page**: dismissible trial banner, title and description, domain verification card, auto-join card, members section with search and Members / Invitations tabs.
3. **Invite drawer**: title 'Invite people' with close X; label 'Email addresses (comma or new line)'; tall textarea; 'Role:' with a green pill select; helper sentence; sticky footer with Cancel and Send invite.
Responsive: full-screen drawer under 768px.

### Design system
- Colors: `--bg: #ffffff` (drawer), `--canvas: #f5f6f8` (page and sidebar), `--text: #161a22` (primary text), `--muted: #5d6472` (helper text), `--border: #8d94a1` (textarea border), `--role: #e3f7c9` (role pill fill), `--role-text: #2f5a0c` (role pill text), `--primary: #1e5bd8` (Send button), `--disabled: #c7ccd4` (disabled button fill), `--banner: #fff4d6` (trial banner).
- Fonts: Inter 600, 20px drawer title, 28px page title for headings; Inter 400, 16px, line-height 1.5 for body. Field labels 16px 600; helper text 15px; table headers 13px 600.
- Spacing: Medium. 8px; drawer padding 16-24px. Container: drawer 40vw clamped 400-520px.
- Radius: 6px textarea and buttons, full pill for role.
- Shadows: Drawer left shadow; footer has a top border instead of a shadow.
- Motion: Drawer slides 200ms; role pill opens a Radix Select; success collapses the drawer and flashes the Invitations tab count.

### Components & interactions
RoleSelect is a soft green pill with a chevron trigger. The drawer footer is sticky with a top border so buttons are always visible above long textarea content.

- Emails parsed live; count shown under the field ('3 valid, 1 invalid')
- Role select changes the helper sentence describing permissions
- Send disabled until ≥1 valid email; shows spinner while sending
- On success the drawer closes and the Invitations tab gains a count badge
- Esc or Cancel closes; unsaved text triggers a discard confirm

### Data & state
Seed one admin and two pending invitations. Parsing is a pure function unit-tested for separators and duplicates. Invitations list refetches after send.

Entities: `Membership{workspace_id, user_id, role (admin|builder|member)}`; `Invitation{id, workspace_id, email, role, status (pending|accepted|revoked|expired), sent_at}`; `Workspace{id, name, seats, trial_ends_at}`.

States to build and show in a dev-only state switcher:
- empty: Send disabled
- validation: invalid emails listed with reasons
- sending
- partial success: some addresses already members, listed
- seat limit: warning with Subscription link
- permission-denied for non-admins: drawer never opens, button hidden
- server error with Retry

### Accessibility
- Drawer is a dialog with labelled title and focus trap
- Textarea has a visible label and describes its separator rules
- Role select is keyboard operable and its helper text is aria-describedby
- Result list announced via aria-live=polite
- Disabled Send has aria-disabled and an explanation
Verified contrast: body text: #161a22 on #ffffff = 17.43:1; helper text: #5d6472 on #ffffff = 5.95:1; role pill text: #2f5a0c on #e3f7c9 = 7.11:1; Send button label: #ffffff on #1e5bd8 = 5.93:1; textarea border: #8d94a1 on #ffffff = 3.05:1; focus ring: #1e5bd8 on #ffffff = 5.93:1; trial banner text: #161a22 on #fff4d6 = 15.9:1.

### Security
- Only admins can invite (RLS on invitations: insert where caller is admin)
- Server re-validates emails and dedupes against memberships
- Rate-limit to 100 invites/hour per workspace
- Log invitations to an audit table
- Invite tokens are single-use and expire
RLS detail: `memberships` select for members of the same workspace, write for admins; `invitations` select/insert/update for admins; `audit_log` insert-only.

### Performance & SEO
Split the drawer into its own chunk; debounce parsing at 150ms for large pastes (500+ addresses).

### Guardrails
- Accept comma and newline separators and trim whitespace
- Explain the selected role in one plain sentence
- Show a per-address result after sending
- Keep Cancel as a secondary text button left of Send
- Keep the trial banner dismissible per session
- Write fresh, generic copy and invented sample data; no real brands, logos, product names or people.
- Keep components small and typed (no `any`); surface every error visibly with a way to recover.

Acceptance criteria:
- Pasting mixed separators yields correct valid/invalid counts
- Send creates invitations with the chosen role
- Duplicates and existing members are reported
- Non-admins cannot invite (RLS verified)
- Drawer is fully keyboard-operable

Open the builderAll templatesThis palette on its own