Template
Mapleshore
The appearance section of a scheduling tool's settings. It controls how the user's public booking pages look: theme (follow system, light or dark), which calendar layouts bookers can switch between and which is the default, and brand colours for each theme.
Booking-page appearance settings with theme and layout thumbnails · 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.
- ManropeHeadings: Manrope 700, 20px for page title; 16px 600 for card titles
- InterBody: Inter 400, 16px/1.5; sidebar 15px 500; captions 14px
Patterns
- settings sidebar with account-grouped sub-navigation
- sectioned settings cards with footer action bar
- thumbnail radio cards (system / light / dark)
- multi-select layout thumbnails with default choice
- per-section update button enabled when dirty
- brand colour pair for light and dark
States it is designed for
- loading skeleton thumbnails
- pristine (Update disabled)
- dirty (Update enabled)
- saving
- saved inline tick
- save failed inline error with retry
- attempt to deselect last layout (blocked with message)
- brand colour fails contrast (warning)
- team-managed setting locked (lock icon, tooltip)
Who it is for
- freelancers and consultants who take bookings
- sales and support teams
- team admins standardising booking pages
Layout
- Settings sidebar (~140px on light grey): Back link, user group (Profile, General, Calendars, Conferencing, Appearance active), Security group, Billing group, Developer group, Teams group with team item and 'Add a team'
- Main column (~550px): page title and description
- Card: Theme - header (title, description), three thumbnail radio cards with captions, footer bar with right-aligned Update button
- Card: Booking layout - header, three layout thumbnails with checkboxes, default-view radio row, footer Update
- Card: Brand colours - light and dark swatch inputs with contrast hint, footer Update
- Below 900px sidebar becomes a top select; thumbnails wrap 2 then 1 per row
Palette
Neutral, crisp, product-grade. Greys let the thumbnails carry the meaning.
- canvas
#ffffff - sidebar
#f9fafb - text
#111827 - muted
#5f6167 - border
#e5e7eb - control-border
#8b8e94 - selected
#111827 - primary
#111827 - on-primary
#ffffff - thumb-bg
#e8e9eb - focus
#3b5bdb
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on white | 17.74:1 | 4.5:1 |
| Aa | muted description on white | 6.19:1 | 4.5:1 |
| Aa | sidebar text on grey | 16.98:1 | 4.5:1 |
| Aa | update button label | 17.74:1 | 4.5:1 |
| selected thumbnail outline on white | 17.74:1 | 3:1 | |
| checkbox border on white | 3.28:1 | 3:1 | |
| focus ring on white | 5.67:1 | 3: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
- Manrope 700, 20px for page title; 16px 600 for card titles
- Body
- Inter 400, 16px/1.5; sidebar 15px 500; captions 14px
Similar to the observed display grotesk for headings; Inter for UI.
Spacing and imagery
Comfortable; 8px base; cards 24px padding with a grey footer bar (12px 24px); thumbnails 170x96 with 12px gap; radius 8px cards and thumbnails, 6px buttons; no shadows; selected thumbnail gets a 2px near-black outline.
Schematic thumbnails of booking pages drawn with CSS blocks (light, dark and split for system); no photos.
Components
- settings sidebar
- section card with footer
- thumbnail radio card
- thumbnail checkbox card
- default view radio group
- colour swatch input
- update button
- unsaved-changes indicator
Interactions
- Selecting a theme thumbnail updates the preview state and enables Update
- Layout thumbnails toggle; at least one must remain selected
- Default-view options only list selected layouts
- Update saves just that card and shows an inline 'Saved' tick for 2s
- Thumbnails respond to arrow keys within their group
Data
User{id, name, username}AppearanceSettings{user_id, theme (system|light|dark), layouts (month|week|column)[], default_layout, brand_light_hex, brand_dark_hex, updated_at}
Guardrails
Experience
- Each card saves independently with its own Update button
- Explain that settings affect public booking pages only
- Never allow zero layouts
- Show what 'system' means (follows the booker's device)
- Offer a contrast hint for each brand colour against its theme
- Lock and explain settings enforced by a team
Accessibility
- Theme thumbnails are a radio group with visible captions as labels
- Layout thumbnails are checkboxes; the default is a separate radio group
- Selected state uses outline plus a check badge, not colour alone
- Update buttons state which section they save via aria-label
- Inline saved/error messages use role=status
- Sidebar groups are nav landmarks with headings
Security
- RLS: appearance_settings readable and writable only by the owner (and team admins for team-locked fields)
- Validate enum values and hex format server-side
- Public booking pages read settings through a view exposing only presentation fields
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 **Mapleshore**, the Appearance page in a scheduling tool's settings. It controls how the user's public booking pages look: theme, which calendar layouts bookers can switch between (and the default), and brand colours for light and dark themes. Each section saves on its own. ### Stack React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (RadioGroup, Checkbox, Button, Tooltip, Popover), lucide-react, react-hook-form + zod (one form per card), TanStack Query. Supabase Auth and Postgres. ### Pages & layout 1. **Settings shell**: sidebar with Back, the user's name as a group (Profile, General, Calendars, Conferencing, Appearance), Security (Password, Impersonation, Two-factor), Billing (Manage billing), Developer (Webhooks, API keys), Teams (a team, Add a team). 2. **/settings/appearance** (this screen): title 'Appearance', description 'Control how your booking pages look to visitors.'; Theme card (System default, Light, Dark thumbnails); Booking layout card (Month, Weekly, Column thumbnails + 'Default view' radios); Brand colours card (light and dark swatches with hex inputs). 3. **Public booking page stub** to prove settings apply. 4. Responsive: sidebar becomes a Select; thumbnails wrap. ### Design system - Colors: `--canvas: #ffffff`, `--sidebar: #f9fafb`, `--text: #111827`, `--muted: #5f6167`, `--border: #e5e7eb`, `--control-border: #8b8e94`, `--selected: #111827`, `--primary: #111827`, `--on-primary: #ffffff`, `--thumb-bg: #e8e9eb`, `--focus: #3b5bdb`. - Fonts: Manrope 700 for headings (similar to the observed display grotesk), Inter for UI. Title 20px; card titles 16px/600; body 16px/1.5; captions 14px. - Spacing: 8px base; card padding 24px; footer bar 12px 24px on `--sidebar` grey. - Radius: 8px cards and thumbnails; 6px buttons. - Shadows: none. - Motion: 120ms outline and background transitions; reduced motion respected. ### Components & interactions `SettingsNav`, `SettingsCard` (header, body, footer with UpdateButton and inline status), `ThemeThumb` (CSS-drawn page, system variant split diagonally), `LayoutThumb` (checkbox + drawing), `DefaultLayoutRadio`, `BrandColorInput` (swatch, hex input, contrast hint), `LockedField` (lock icon, tooltip naming the team). Update is disabled until its card is dirty. ### Data & state `appearance_settings(user_id pk, theme, layouts text[] check (cardinality(layouts) >= 1), default_layout, brand_light_hex, brand_dark_hex, updated_at)` plus `team_locks(team_id, field)`. Each card has its own form and mutation; optimistic update with rollback on error. Mock user 'Jonah Reyes'. ### Accessibility Radio and checkbox semantics on thumbnails with captions as labels. Check badge on selected. Status messages via role=status. Default-view radios list only enabled layouts and announce when the list changes. Focus ring 2px blue offset 2px. Verified contrast: body text on white: #111827 on #ffffff = 17.74:1; muted description on white: #5f6167 on #ffffff = 6.19:1; sidebar text on grey: #111827 on #f9fafb = 16.98:1; update button label: #ffffff on #111827 = 17.74:1; selected thumbnail outline on white: #111827 on #ffffff = 17.74:1; checkbox border on white: #8b8e94 on #ffffff = 3.28:1; focus ring on white: #3b5bdb on #ffffff = 5.67:1. ### Security RLS: `appearance_settings` select/update where `user_id = auth.uid()`; team-locked fields enforced in an update trigger that rejects changes. Public pages read a `public_appearance` view with only presentation columns. Validate enums and hex server-side. ### Performance & SEO Thumbnails are CSS, no images. Settings routes code-split. Noindex. ### Guardrails - Invented names only - Do not merge the cards into one giant Save - Never leave bookers without a layout - Typed code, visible errors - Acceptance criteria: (1) each card saves independently and shows inline status; (2) deselecting the last layout is blocked; (3) default view options follow selected layouts; (4) locked fields cannot be changed (UI and DB); (5) works at 390px.