Template
Oxmere
A transactional email sent when a workspace is deleted. It confirms the deletion in the headline, states the retention window before permanent removal and gives a support address to request immediate erasure.
Workspace-deleted confirmation email · App screen: delete account · 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: Arial/Helvetica 400 32px headline for email safety, with Inter as web-font preference
- InterBody: Arial/Helvetica 400 16px / 1.6
Patterns
- transactional email with logo, headline and single paragraph
- support mailto link for immediate purge
- grey outer frame with white content block
- large headline quoting the workspace name
States it is designed for
- standard deletion with 30-day retention
- immediate purge already requested (alternate copy)
- workspace with paid plan (adds note about final invoice)
- dark-mode client rendering
- plain-text version
Who it is for
- workspace owners who just deleted a workspace
- compliance-minded admins
Layout
- Outer grey band (preheader area)
- White content block, max 600px: wordmark top-left
- Large headline with the workspace name in quotes
- Body paragraph: retention window, how to request immediate removal with an underlined mailto link
- Collapsed quoted content indicator (email client)
- Footer: company address, reason you received this, no marketing links
- Mobile: 16px side padding, headline 26px
Palette
Plain, factual and reassuring; it closes the loop without upsell.
- outer band
#f4f4f4 - content
#ffffff - text
#111111 - muted text
#5f6368 - link
#1155cc - brand dark
#1e1e1e - divider
#dfe0e3 - footer text
#666666
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | headline and body on white | 18.88:1 | 4.5:1 |
| Aa | link on white | 6.57:1 | 4.5:1 |
| Aa | muted text on white | 6.05:1 | 4.5:1 |
| Aa | footer text on outer band | 5.22:1 | 4.5:1 |
| wordmark on white (graphic) | 16.67:1 | 3:1 | |
| Aa | body text on outer band | 17.17:1 | 4.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
- Arial/Helvetica 400 32px headline for email safety, with Inter as web-font preference (Arial is not on Google Fonts; a vibld project loads Inter)
- Body
- Arial/Helvetica 400 16px / 1.6 (Arial is not on Google Fonts; a vibld project loads Inter)
Email clients need system-font fallbacks; keep Inter only where supported.
Spacing and imagery
Email-safe table layout; 32px content padding, 24px between blocks, 600px max; no radius needed except 4px on buttons; no shadows.
Wordmark only, as a hosted PNG with alt text and fixed width.
Components
- EmailLayout (outer band, content block)
- LogoHeader
- Headline with workspace name
- BodyParagraph with mailto link
- FooterNotice
- Plain-text alternative
Interactions
- Mailto link opens with a prefilled subject 'Erase workspace <id> now'
- No tracking pixels or click-tracking redirects on this email
- Preview route in the app renders the email with sample data and a dark-mode toggle
Data
Workspace{id, name, owner_email, deleted_at, purge_after}EmailLog{id, to, template (workspace_deleted), sent_at, provider_message_id}PurgeRequest{workspace_id, requested_by, requested_at, completed_at?}
Guardrails
Experience
- Say what happened in the headline
- State the retention period in days and the exact date
- Give one clear way to request immediate removal
- No marketing content in this email
Accessibility
- Use semantic headings and real text, not images of text
- Set lang and role=presentation on layout tables
- Link text is the email address itself and is underlined
- Provide a plain-text part
- Check colours in dark-mode clients (no pure-white images without padding)
Security
- Escape the workspace name (user-generated) before inserting into HTML
- Send only to the verified owner address
- No tracking pixels on deletion emails
- Verify purge requests from the support address against the owner before acting
- Keep email service keys in function secrets
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 **Oxmere**, the workspace-deleted confirmation email and the pipeline that sends it: soft-delete trigger, Edge Function render and send, plus an in-app preview route. Use an invented workspace name.
### Stack
Use React 18, TypeScript, Tailwind CSS, Supabase, date-fns, zod. Render the email with React components to static HTML with inline styles; send through a transactional email service from an Edge Function triggered when a workspace row is soft-deleted. Use Supabase for Auth, Postgres (row-level security on every table) and Storage where noted; keep only the anon key in the browser and run privileged work in Edge Functions.
### Pages & layout
1. **Email template** (HTML + plain text).
2. **/dev/emails/workspace-deleted** preview route with sample data and a light/dark toggle.
3. **Edge Function** `send-workspace-deleted`.
Regions, in order:
- Outer grey band (preheader area)
- White content block, max 600px: wordmark top-left
- Large headline with the workspace name in quotes
- Body paragraph: retention window, how to request immediate removal with an underlined mailto link
- Collapsed quoted content indicator (email client)
- Footer: company address, reason you received this, no marketing links
- Mobile: 16px side padding, headline 26px
### Design system
- Colors: `--outer-band: #f4f4f4` (outer band), `--content: #ffffff` (content), `--text: #111111` (text), `--muted-text: #5f6368` (muted text), `--link: #1155cc` (link), `--brand-dark: #1e1e1e` (brand dark), `--divider: #dfe0e3` (divider), `--footer-text: #666666` (footer text).
- Fonts: Arial/Helvetica 400 32px headline for email safety, with Inter as web-font preference for headings; Arial/Helvetica 400 16px / 1.6 for body. Email clients need system-font fallbacks; keep Inter only where supported.
- Spacing, radius and shadows: Email-safe table layout; 32px content padding, 24px between blocks, 600px max; no radius needed except 4px on buttons; no shadows.
- Motion: 150-200 ms ease-out for hover, focus and overlay transitions; overlays fade and scale from 98% to 100%; everything collapses to an instant change under prefers-reduced-motion.
- Mood: Plain, factual and reassuring; it closes the loop without upsell. Imagery: Wordmark only, as a hosted PNG with alt text and fixed width.
### Components & interactions
Build these components: EmailLayout (outer band, content block); LogoHeader; Headline with workspace name; BodyParagraph with mailto link; FooterNotice; Plain-text alternative.
- Mailto link opens with a prefilled subject 'Erase workspace <id> now'
- No tracking pixels or click-tracking redirects on this email
- Preview route in the app renders the email with sample data and a dark-mode toggle
### Data & state
Model: `Workspace{id, name, owner_email, deleted_at, purge_after}`; `EmailLog{id, to, template (workspace_deleted), sent_at, provider_message_id}`; `PurgeRequest{workspace_id, requested_by, requested_at, completed_at?}`.
A database trigger on `workspaces.deleted_at` enqueues a job; the function renders with the workspace name and purge date (formatted with date-fns in the owner's locale) and logs the send.
States to implement and demo:
- standard deletion with 30-day retention
- immediate purge already requested (alternate copy)
- workspace with paid plan (adds note about final invoice)
- dark-mode client rendering
- plain-text version
### Accessibility
- Use semantic headings and real text, not images of text
- Set lang and role=presentation on layout tables
- Link text is the email address itself and is underlined
- Provide a plain-text part
- Check colours in dark-mode clients (no pure-white images without padding)
- Body text is 16px with line-height 1.5 (15px only inside dense tables), nothing renders below 12px, weights of 300 or lighter appear only at 24px and above, and uppercase is limited to short labels with at least 0.05em tracking.
Verified contrast: headline and body on white: #111111 on #ffffff = 18.88:1; link on white: #1155cc on #ffffff = 6.57:1; muted text on white: #5f6368 on #ffffff = 6.05:1; footer text on outer band: #666666 on #f4f4f4 = 5.22:1; wordmark on white (graphic): #1e1e1e on #ffffff = 16.67:1; body text on outer band: #111111 on #f4f4f4 = 17.17:1.
### Security
- Escape the workspace name (user-generated) before inserting into HTML
- Send only to the verified owner address
- No tracking pixels on deletion emails
- Verify purge requests from the support address against the owner before acting
- Keep email service keys in function secrets
RLS: `workspaces` - owner select/update (soft delete); `email_logs` and `purge_requests` - no client access except owner select of own purge request; the function uses the service role.
### Performance & SEO
Keep HTML under 100KB, inline critical styles, host the logo on a CDN with fixed dimensions. Preview route is noindex.
### Guardrails
- Say what happened in the headline
- State the retention period in days and the exact date
- Give one clear way to request immediate removal
- No marketing content in this email
- Use the product name Oxmere and fresh, generic copy throughout; all people, companies, amounts and IDs are invented, and no third-party brand, logo or wordmark appears.
- Keep components small and typed (no `any`), and surface every failure visibly instead of swallowing it.
Acceptance criteria:
- [ ] Email renders in light and dark previews
- [ ] Workspace name is escaped
- [ ] Trigger sends exactly once per deletion
- [ ] Plain-text part present
- [ ] Contrast pairs pass