Template
Mothwing
The customisation step of a builder for interactive challenges and quizzes that marketers embed or share. The creator sets a small set of colour tokens (page and frame background, accent, text, button and input colours) that style the public challenge, then saves and publishes.
Dark colour-token customiser for an interactive quiz builder · App screen: appearance · 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, 18px for card titles; 16px 600 sidebar title
- InterBody: Inter 400, 16px/1.5; token labels 14px muted; hex values 15px 600 (JetBrains Mono optional)
Patterns
- icon rail plus secondary section sidebar
- grouped token cards (page, button, inputs)
- swatch + label + hex token field
- neon accent primary actions
- publish button in top bar
- publication status chip
- destructive delete button docked at sidebar bottom
- 'soon' badge on disabled nav item
States it is designed for
- pristine
- dirty (save enabled, unsaved dot on nav item)
- saving / saved toast
- invalid hex
- low contrast between text and page background (warning with suggested fix)
- unpublished vs published status chip
- publish in progress / failed
- delete confirmation
- feature coming soon (disabled nav item)
Who it is for
- growth marketers
- community and event organisers
- educators running interactive challenges
Layout
- Icon rail (56px, near-black): logo mark, accent '+' create button, app icons, avatar at bottom
- Section sidebar (~170px): 'Challenge setup' title, nav (Main page, Challenge blocks, Question sets [soon], Customisation active, Integrations, Share and settings), status chip and full-width delete button at bottom
- Top bar: breadcrumb with grid icon and challenge name, accent Publish button right
- Main: card 'Page and frame' with four token fields in a row; second row with 'Button' (two fields) and 'Inputs' (one field) cards side by side; accent 'Save colours' button
- Below 1024px section sidebar becomes a top select; token fields wrap to 2 per row, then 1
Palette
Bold, nocturnal, energetic. A single neon accent against layered near-blacks makes actions unmistakable.
- page-bg
#0e0f0f - frame
#171818 - card
#202222 - field
#262828 - text
#ffffff - muted
#a3a6a6 - field-border
#6e7272 - accent
#d5fe52 - on-accent
#0e0f0f - danger
#f26d6d - on-danger
#1a0a0a - focus
#d5fe52
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | text on page background | 19.20:1 | 4.5:1 |
| Aa | muted label on card | 6.52:1 | 4.5:1 |
| Aa | accent button label | 16.57:1 | 4.5:1 |
| Aa | delete button label | 6.58:1 | 4.5:1 |
| field border on card | 3.28:1 | 3:1 | |
| focus ring on card | 13.80:1 | 3:1 | |
| Aa | hex value on field | 14.82: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.
- background
- card
- muted
- primary
- secondary
- accent
- destructive
Type scale
- Display
- Inter 600, 18px for card titles; 16px 600 sidebar title
- Body
- Inter 400, 16px/1.5; token labels 14px muted; hex values 15px 600 (JetBrains Mono optional)
Similar to the observed neo-grotesk; 'soon' badge 12px 500 lowercase.
Spacing and imagery
Medium density; 8px base; cards 16px padding with 18px radius; token fields 56px tall, 10px radius, 40px swatch; 12px gaps; no shadows; 1px subtle borders on fields.
No imagery; square colour swatches are the visual content.
Components
- icon rail
- section sidebar
- soon badge
- status chip
- delete button
- breadcrumb
- publish button
- token card
- colour token field with picker
- save button
- live preview drawer
Interactions
- Clicking a token field opens a picker popover with hex input and recent colours
- Changes reflect instantly in an optional preview drawer (toggle 'Preview')
- Save colours enables when dirty; Publish warns if there are unsaved changes
- Delete opens a confirmation requiring the challenge name
- Hex typing auto-formats and validates on blur
Data
Challenge{id, owner_id, name, status (draft|published), published_at}Theme{challenge_id, page_bg, frame_bg, accent, text, button_bg, button_text, input_bg, updated_at}
Guardrails
Experience
- Group tokens by where they appear (page, buttons, inputs)
- Show the hex beside every swatch
- Warn when text/background or button text/button colour pairs fall below 4.5:1
- Keep Save and Publish distinct and explain the difference
- Guard delete with typed confirmation
- Mark unfinished features as 'soon' and make them non-interactive
Accessibility
- Each token field is a button whose name includes the label and current hex
- Picker popover traps focus and closes with Escape
- Contrast warnings are text with icon
- Disabled 'soon' item has aria-disabled and explanatory tooltip
- Focus ring in accent colour, 2px, visible on all dark surfaces
- Status chip text is not colour-only
Security
- RLS: challenges and themes editable only by the owner or workspace editors
- Validate all hex values server-side
- Publishing copies the theme to a public read-only view; drafts are never public
- Delete is soft-delete with 30-day restore and an audit entry
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 **Mothwing**, the Customisation step of a builder for interactive marketing challenges. The creator sets seven colour tokens that style the public challenge (page background, frame background, accent, text, button background, button text, input background), saves, and publishes.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS (dark theme only for the builder), shadcn/ui (Popover, AlertDialog, Tooltip, Toast), lucide-react, react-hook-form + zod, TanStack Query. Supabase Auth and Postgres.
### Pages & layout
1. **Builder shell**: 56px icon rail (logo, accent create button, Challenges, Analytics, Settings, Feedback, avatar). Section sidebar 'Challenge setup' with nav items and bottom status chip ('Draft') and red Delete. Top bar breadcrumb (grid icon > 'Spring product quiz') and accent Publish.
2. **/challenges/:id/customise** (this screen): 'Page and frame' card (Page background #0E0F0F, Frame background #171818, Accent #D5FE52, Text #FFFFFF); 'Button' card (Button background, Button text); 'Inputs' card (Input background); 'Save colours'. A 'Preview' toggle opens a right drawer showing a sample question screen using the tokens.
3. Responsive: section nav as Select under 1024px; fields 2 per row, then 1.
### Design system
- Colors: `--page-bg: #0e0f0f`, `--frame: #171818`, `--card: #202222`, `--field: #262828`, `--text: #ffffff`, `--muted: #a3a6a6`, `--field-border: #6e7272`, `--accent: #d5fe52`, `--on-accent: #0e0f0f`, `--danger: #f26d6d`, `--on-danger: #1a0a0a`, `--focus: #d5fe52`.
- Fonts: Inter (similar to observed). Card titles 18px/600; body 16px/1.5; labels 14px; hex 15px/600.
- Spacing: 8px base; cards 16px padding; 12px gaps; 24px page padding.
- Radius: cards 18px, fields 10px, buttons 10px, swatches 6px.
- Shadows: none; depth by tone steps (page > frame > card > field).
- Motion: 150ms; drawer slide 220ms; reduced motion respected.
### Components & interactions
`IconRail`, `SectionNav` (item, SoonBadge, unsaved dot), `StatusChip`, `DeleteChallengeButton` (AlertDialog with typed name), `Breadcrumb`, `PublishButton`, `TokenCard`, `ColorTokenField` (swatch with 1px border so dark colours stay visible, label, hex; Popover picker), `ContrastWarning`, `SaveButton`, `PreviewDrawer`.
### Data & state
`challenges(id, owner_id, name, status, published_at, deleted_at)` and `challenge_themes(challenge_id pk, page_bg, frame_bg, accent, text, button_bg, button_text, input_bg, updated_at)` with hex check constraints. Form state in react-hook-form; preview reads live values. Publishing snapshots the theme into `published_themes`.
### Accessibility
Builder UI itself meets AA in dark mode. Token fields announce label and hex. Contrast warnings computed with the WCAG formula for text/page, text/frame and button_text/button_bg. Delete dialog is focus-trapped and names the challenge.
Verified contrast: text on page background: #ffffff on #0e0f0f = 19.2:1; muted label on card: #a3a6a6 on #202222 = 6.52:1; accent button label: #0e0f0f on #d5fe52 = 16.57:1; delete button label: #1a0a0a on #f26d6d = 6.58:1; field border on card: #6e7272 on #202222 = 3.28:1; focus ring on card: #d5fe52 on #202222 = 13.8:1; hex value on field: #ffffff on #262828 = 14.82:1.
### Security
RLS on `challenges`, `challenge_themes`: owner or workspace editor for select/update; public visitors read only `published_themes` via a view. Hex validated with a regex constraint. Delete is a soft delete RPC with typed-name confirmation and an audit row.
### Performance & SEO
Preview drawer lazy-loaded. Debounce live preview updates. Builder routes noindex; public challenge pages get their own meta.
### Guardrails
- Invented challenge names and copy
- Never publish unsaved changes silently
- Always show contrast warnings for text pairs
- Typed code, clear errors
- Acceptance criteria: (1) editing a token updates the preview instantly; (2) Save and Publish behave distinctly with warnings; (3) delete requires typed confirmation and is restorable; (4) RLS blocks other users; (5) works at 390px.