Template
Slotfield
The entry editor of a headless CMS for editing one page section (a full-bleed hero) across locales. Editors pick a field in the left tree, fill in each language in the centre, and check the result in a live preview before publishing.
Headless CMS component editor with localized fields and live preview · App screen: settings · 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 entry title; 14px field labels (600)
- InterBody: Inter 400 16px inputs at 1.5; 14px tree items; 12px locale tags (600)
Patterns
- environment banner in top bar (tinted)
- vertical rotated layout label strip
- component field tree on left with type icons
- localized field stacks (en / de / fr) with locale tags
- split Save / Publish buttons with dropdown carets
- collapsible preview pane with device toggles
- field type pills (Title, Localized)
- success toast after saving a field
States it is designed for
- Clean (Save disabled)
- Dirty (Save enabled, dot on tab)
- Saving / saved toast / save failed with retry
- Validation error (required en title missing, max length)
- Missing translation indicators per locale
- Another editor is viewing (avatar) / editing lock
- Preview loading / preview failed
- Published vs draft badge
Who it is for
- Content editors and localisation managers
- Marketing teams running multi-language sites
- Developers configuring content models
Layout
- Top bar: project chip and name, environment indicator (tinted green band), global search with icons, AI assist button, help/comments/bell/avatar
- Icon rail far left (home, schema, content, assets, playground)
- Rotated breadcrumb strip ("LAYOUT: PAGE HOME")
- Editor header: close, section chip, entry title, more menu, collaborator avatar, Save (disabled until dirty) and Publish split buttons
- Field tree (~150px): Title, Description, Asset, Buttons (expandable), Page, Show advanced fields, Content position, Opaque, Text colour
- Form (~240-480px): each field with label, type pills, stacked locale inputs
- Preview pane (fluid): title with open-in-new icon, device toggles, comments, close
- Mobile: preview hidden behind a toggle; tree becomes a select
Palette
structured, efficient, calm, multilingual. A tool that makes translation feel like filling a grid.
- form and page background
#ffffff - environment band
#e8f5ee - environment text
#1b6b3a - labels and input text
#0f172a - helper text, tree items
#475569 - input outlines
#8a94a6 - locale tag fill
#f1f5f9 - Publish button
#1f7a4d - Publish label
#ffffff - selected tree item
#eef2ff - focus ring
#4f46e5
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | input text | 17.85:1 | 4.5:1 |
| Aa | muted helper | 7.58:1 | 4.5:1 |
| Aa | environment text on band | 5.83:1 | 4.5:1 |
| Aa | Publish label | 5.32:1 | 4.5:1 |
| Aa | locale tag text | 6.92:1 | 4.5:1 |
| input border | 3.06:1 | 3:1 | |
| focus ring | 6.29:1 | 3:1 | |
| Aa | selected tree item text | 15.97: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
- Inter 600, 16px entry title; 14px field labels (600)
- Body
- Inter 400 16px inputs at 1.5; 14px tree items; 12px locale tags (600)
Similar to the observed neutral grotesk. The rotated strip uses 12px uppercase 600 with 0.08em tracking.
Spacing and imagery
Dense editorial: 4px base; 16px between locale inputs, 24px between fields; inputs 40px; radius 6px inputs and buttons, full pills for type and locale tags; panels divided by 1px borders, no shadows.
None in the editor; preview shows the actual rendered section. Outline field-type icons in the tree.
Components
- Environment indicator
- Global search
- AI assist button
- Field tree with type icons and expanders
- Field block (label, type pills, locale inputs)
- Locale tag
- Save split button
- Publish split button (publish / schedule)
- Preview pane with device toggles
- Collaborator avatar
- Toast
- Unsaved-changes guard
Interactions
- Clicking a tree item scrolls the form to that field and highlights it
- Editing enables Save; Cmd/Ctrl+S saves; Publish runs validation first
- Preview updates live (debounced 300ms) and supports desktop/tablet/mobile widths
- Collapse button hides the tree for a wider form
- Publish caret offers "Schedule…" and "Publish with references"
- Toast "Field saved" appears bottom-center after save
Data
Environment{id, name (master|staging), project_id}Model{id, api_id, fields[]}Field{id, model_id, api_id, type (text|rich_text|asset|reference|enum|bool|color), localized bool, required bool}Entry{id, model_id, stage (draft|published), updated_by, updated_at}FieldValue{entry_id, field_id, locale (en|de|fr), value jsonb}Locale{code, name, is_default}
Guardrails
Experience
- Always show which environment is being edited, in colour and words
- Group locale inputs under one field label with clear locale tags
- Keep Save and Publish separate; Publish validates required locales
- Show missing translations without blocking drafts
- Preview must reflect unsaved edits
Accessibility
- Each locale input labelled "Title (German)" via aria-label or visually hidden text
- Field tree is a tree/list with aria-current on the selected field
- Rotated strip duplicated as normal text for screen readers
- Validation errors linked with aria-describedby and summarised at top on Publish
- Device toggles are a radio group
Security
- RLS by project and environment role (editor can edit drafts; publisher can publish)
- Validate values against the content model server-side
- Preview served from a sandboxed origin with a short-lived preview token
- Audit log entries for publish and schedule
- Sanitise rich text before rendering
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 **Slotfield**, the entry editor of a headless CMS for one page section (a full-bleed hero). Editors choose a field from a tree, fill in English, German and French values in stacked inputs, watch a live preview, save drafts and publish. A tinted environment band always shows which environment is being edited.
### Stack
React + TypeScript + Vite, Tailwind CSS, shadcn/ui (Resizable, DropdownMenu, ToggleGroup, Toast, Tooltip) on Radix, lucide-react, TanStack Query, react-hook-form + zod (schemas generated from the content model). Supabase for auth, models, entries and localised values; the preview renders in a sandboxed iframe.
### Pages & layout
1. **Top bar**: project chip and name ("Trailwind Bikes"); a light-green band showing the environment name with a branch icon; search with history and recent icons; an "AI assist" button; help, comments, bell and avatar.
2. **Icon rail** and a rotated strip reading "LAYOUT: PAGE HOME".
3. **Editor header**: close; section chip "Section: Hero full bleed"; the entry title (truncated); a more menu; a collaborator avatar; Save split button (disabled until dirty); green Publish split button.
4. **Field tree**: Title, Description, Asset, Buttons (expandable), Page, Show advanced fields, Content position, Opaque, Text colour, each with a type icon.
5. **Form**: for each field a label with type pills (Title, Localized) and stacked inputs tagged en, de, fr; textareas for Description.
6. **Preview pane**: "Preview" with open-in-new, desktop/tablet/mobile toggles, comments, close.
7. Mobile: the tree becomes a Select and the preview opens as a sheet.
### Design system
- Colors: `--bg: #ffffff` (form and page background), `--env: #e8f5ee` (environment band), `--env-fg: #1b6b3a` (environment text), `--fg: #0f172a` (labels and input text), `--muted: #475569` (helper text, tree items), `--input-border: #8a94a6` (input outlines), `--locale: #f1f5f9` (locale tag fill), `--publish: #1f7a4d` (Publish button), `--on-publish: #ffffff` (Publish label), `--selected: #eef2ff` (selected tree item), `--focus: #4f46e5` (focus ring).
- Fonts: Inter (similar to the observed grotesk): entry title 16px/600, labels 14px/600, inputs 16px/1.5, tree 14px, locale tags 12px/600, rotated strip 12px uppercase with 0.08em tracking.
- Spacing: 4px base; 16px between locales, 24px between fields; 40px inputs.
- Radius: 6px inputs and buttons; full pills for tags.
- Shadows: none; 1px panel borders.
- Motion: 150ms highlight on the scrolled-to field; toast slides up.
### Components & interactions
TopBar with EnvironmentBadge, IconRail, RotatedCrumb, EditorHeader, SplitButton (Save; Publish with Schedule and Publish with references), FieldTree (collapse toggle), FieldBlock, LocaleInput (missing-translation dot), PreviewPane (debounced live updates and device widths), PresenceAvatar, UnsavedGuard, Toast ("Field saved"). Cmd/Ctrl+S saves. Publish validates and shows an error summary.
### Data & state
Tables: `environments`, `models`, `fields(id, model_id, api_id, type, localized, required, max_length)`, `entries(id, model_id, environment_id, stage, updated_by, updated_at)`, `field_values(entry_id, field_id, locale, value jsonb)`, `locales(code, name, is_default)`. Mock an English title ("Ride further, stress less") with empty de/fr. Handle states: clean, dirty, saving/saved/failed, validation errors, missing translations, editing lock, preview loading/failed, draft vs published.
### Accessibility
Each locale input has an accessible name such as "Title, German". The tree marks the current field with aria-current. The rotated strip has a normal-text equivalent. Publish errors are summarised and linked to fields. Device toggles are a radio group. Focus ring: 2px indigo.
Verified contrast: input text: #0f172a on #ffffff = 17.85:1; muted helper: #475569 on #ffffff = 7.58:1; environment text on band: #1b6b3a on #e8f5ee = 5.83:1; Publish label: #ffffff on #1f7a4d = 5.32:1; locale tag text: #475569 on #f1f5f9 = 6.92:1; input border: #8a94a6 on #ffffff = 3.06:1; focus ring: #4f46e5 on #ffffff = 6.29:1; selected tree item text: #0f172a on #eef2ff = 15.97:1.
### Security
RLS per project and environment role: editors write drafts, publishers publish, viewers read. Validate values against the model on the server. Serve previews from a sandboxed origin with a short-lived token. Sanitise rich text. Log publishes and schedules.
### Performance & SEO
Load field values per entry with one query. Debounce preview messages via postMessage. Virtualise long field trees. The editor is noindex.
### Guardrails
- Invented project and copy; no real brand names.
- Environment must be visible on every editor screen.
- Acceptance criteria: (1) the tree scrolls to fields; (2) three locales edit independently and show missing markers; (3) Save and Publish follow their rules; (4) preview reflects unsaved edits; (5) every state renders; (6) keyboard and screen-reader checks pass.