Skip to main content
vibld

Template

Revoza

A playground for generating expressive speech from text. Users write or pick an example script, choose a voice and model in the right panel, then generate and listen, with credit usage always visible.

Text-to-speech playground with voice and model panel · App screen: playground · 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, 16px section titles; 22px voice name
  • InterBody: Inter 400, 16px editor text, line-height 1.6

Patterns

  • nested sidebar with expandable groups
  • script editor with speaker chip and character counter
  • add speaker divider
  • example prompt chips grid
  • keyboard-shortcut buttons (Enhance, Generate)
  • right inspector: promo card, voice card, model select, advanced disclosure
  • plan chip and credit balance in top bar
  • usage ring for characters

States it is designed for

  • empty editor (Generate disabled)
  • over character limit: counter turns danger with message
  • generating with cancel
  • generated (player)
  • insufficient credits: Generate disabled with upgrade link
  • voice removed: prompt to choose a voice
  • API error with retry
  • free plan limits note

Who it is for

  • developers evaluating a voice AI API
  • podcasters and content creators prototyping voices

Layout

  1. top bar: collapse toggle, logo, plan chip, credits, balance, bell, user menu
  2. sidebar (~155px): Home, Voices, Text to speech (expanded: Playground, Voice conversion, Projects), Speech to speech, Expression; Platform group; Resources group
  3. header strip: page title, 'View documentation' link
  4. main editor: speaker chip, large textarea, counter 0/1,500, 'Add speaker' divider; examples section with emotion chips; footer with usage ring, Enhance and Generate
  5. right inspector (~230px): promo card, Voice card (play, name, Change, Remove), Model select with helper box, Advanced disclosure
  6. below 1100px inspector becomes a drawer opened by a 'Voice & model' button; below 768px sidebar collapses

Palette

Expressive yet professional; soft lavender accents hint at emotion without noise.

  • bg#ffffff
  • canvas#f7f7f8
  • text#18181b
  • muted#5f5f6a
  • chip#f1f1f3
  • generate#4a4a52
  • helper#ece7fb
  • helper-text#3b2f7a
  • border#8b8b96
  • focus#6d4fe0

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text17.72:14.5:1
Aaplaceholder / meta6.30:14.5:1
Aachip label15.71:14.5:1
AaGenerate label8.78:14.5:1
Aahelper text9.28:14.5:1
input border3.37:13:1
focus ring5.46:13:1
Aamuted on sidebar5.89: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, 16px section titles; 22px voice name
Body
Inter 400, 16px editor text, line-height 1.6

Shortcut buttons use 13px uppercase labels with 0.08em tracking plus kbd hints in JetBrains Mono.

Spacing and imagery

Density: Medium. Grid: 8px; editor padding 16px; chip gaps 8px. Container: fluid; inspector fixed 260px. Radius: 8px cards, chips and buttons. Shadows: Cards flat with borders; promo card soft shadow.

Small colour thumbnail on the promo card; voice avatars as small circles; example chips use simple icons (no emoji required).

Components

  • TopBar with PlanChip and CreditBalance
  • NestedSidebar
  • SpeakerChip
  • ScriptEditor with CharCounter
  • AddSpeakerDivider
  • ExampleChips
  • UsageRing
  • EnhanceButton (⌘E)
  • GenerateButton (⌘Enter)
  • VoiceCard with preview play
  • ModelSelect with helper
  • AdvancedSettings (speed, stability)
  • AudioPlayer

Interactions

  • Clicking an example chip fills the editor with a matching invented script
  • ⌘E enhances the script with delivery cues; ⌘Enter generates
  • Add speaker inserts a new speaker block for dialogue
  • Voice play previews a 5s sample; Change opens a voice library dialog
  • Generated audio plays in a footer player with download and regenerate

Data

  • Generation{id, user_id, text, voice_id, model (auto|v1|v2), speakers jsonb, chars, audio_url, created_at}
  • Voice{id, owner_id, name, preview_url, is_library}
  • CreditLedger{user_id, delta, reason, created_at}

Guardrails

Experience

  • Keep the character counter visible and near the limit warn early
  • Show cost in credits before generating
  • Make shortcut hints visible on buttons
  • Examples must replace text only after confirmation if the editor isn't empty
  • Keep voice and model choice visible while writing

Accessibility

  • Editor has a label naming the current speaker
  • Counter uses aria-live when within 10% of the limit
  • Chips are buttons in a group with a heading
  • Audio player has labelled controls and transcript (the script)
  • Shortcuts are also clickable buttons

Security

  • Speech API key only in the Edge Function
  • Server-side character and rate limits per plan
  • RLS on generations and voices (owner only; library voices public read)
  • Store audio in a private bucket with signed URLs
  • Ledger credits server-side only

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 **Revoza**, a text-to-speech playground: script editor with speakers and examples in the centre, voice and model inspector on the right, generate and listen with credits visible. Build the app shell and playground with mocked synthesis.

### 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. Call the speech API from an Edge Function (key server-side) and store audio in private storage.

### Pages & layout
1. **Top bar** with plan chip, credits and balance.
2. **Sidebar** with nested Text to speech group.
3. **Playground**: title strip; editor with speaker chip, textarea, counter, Add speaker; examples chips; footer with usage ring, Enhance and Generate.
4. **Inspector**: promo card, Voice card, Model select with helper, Advanced.

### Design system
- Colors: `--bg: #ffffff` (page), `--canvas: #f7f7f8` (sidebar), `--text: #18181b` (primary text), `--muted: #5f5f6a` (placeholders and meta), `--chip: #f1f1f3` (example chips), `--generate: #4a4a52` (Generate button), `--helper: #ece7fb` (model helper box), `--helper-text: #3b2f7a` (model helper text), `--border: #8b8b96` (inputs and outlined buttons), `--focus: #6d4fe0` (focus ring and selected select border).
- Fonts: Inter 600, 16px section titles; 22px voice name for headings; Inter 400, 16px editor text, line-height 1.6 for body. Shortcut buttons use 13px uppercase labels with 0.08em tracking plus kbd hints in JetBrains Mono.
- Spacing: Medium. 8px; editor padding 16px; chip gaps 8px. Container: fluid; inspector fixed 260px.
- Radius: 8px cards, chips and buttons.
- Shadows: Cards flat with borders; promo card soft shadow.
- Motion: Generate shows a waveform shimmer while synthesising; audio player slides up from the footer; chips press scale 0.97.

### Components & interactions
ExampleChips is a wrap grid of 14 small outlined chips with an icon and emotion word; selecting one fills an invented line. ModelSelect shows a lavender helper box explaining automatic routing.

- Clicking an example chip fills the editor with a matching invented script
- ⌘E enhances the script with delivery cues; ⌘Enter generates
- Add speaker inserts a new speaker block for dialogue
- Voice play previews a 5s sample; Change opens a voice library dialog
- Generated audio plays in a footer player with download and regenerate

### Data & state
Mock synthesis returns a sample tone after 2s. Seed three invented voices. Credits decremented via ledger rows.

Entities: `Generation{id, user_id, text, voice_id, model (auto|v1|v2), speakers jsonb, chars, audio_url, created_at}`; `Voice{id, owner_id, name, preview_url, is_library}`; `CreditLedger{user_id, delta, reason, created_at}`.

States to build and show in a dev-only state switcher:
- empty editor (Generate disabled)
- over character limit: counter turns danger with message
- generating with cancel
- generated (player)
- insufficient credits: Generate disabled with upgrade link
- voice removed: prompt to choose a voice
- API error with retry
- free plan limits note

### Accessibility
- Editor has a label naming the current speaker
- Counter uses aria-live when within 10% of the limit
- Chips are buttons in a group with a heading
- Audio player has labelled controls and transcript (the script)
- Shortcuts are also clickable buttons
Verified contrast: body text: #18181b on #ffffff = 17.72:1; placeholder / meta: #5f5f6a on #ffffff = 6.3:1; chip label: #18181b on #f1f1f3 = 15.71:1; Generate label: #ffffff on #4a4a52 = 8.78:1; helper text: #3b2f7a on #ece7fb = 9.28:1; input border: #8b8b96 on #ffffff = 3.37:1; focus ring: #6d4fe0 on #ffffff = 5.46:1; muted on sidebar: #5f5f6a on #f7f7f8 = 5.89:1.

### Security
- Speech API key only in the Edge Function
- Server-side character and rate limits per plan
- RLS on generations and voices (owner only; library voices public read)
- Store audio in a private bucket with signed URLs
- Ledger credits server-side only
RLS detail: `generations` select/insert/delete where user_id = auth.uid(); `voices` select where is_library or owner_id = auth.uid(), write by owner; `credit_ledger` owner select, service-role insert.

### Performance & SEO
Lazy-load the audio player and voice library; stream audio when possible; private route noindex.

### Guardrails
- Keep the character counter visible and near the limit warn early
- Show cost in credits before generating
- Make shortcut hints visible on buttons
- Examples must replace text only after confirmation if the editor isn't empty
- Keep voice and model choice visible while writing
- 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:
- Generate produces playable audio and deducts credits
- Limit and credit states block generation clearly
- Shortcuts work
- Voice change persists
- API key never reaches the client

Open the builderAll templatesThis palette on its own