Template
Stepstone
The last step of a guided tour in a workspace hub that groups the tools a team uses into sections of app tiles. It tells the user the tour is over, shows exactly where the help menu lives with a small preview, and hands control back with one button.
Tour-complete modal over an app launcher home · App screen: product tour · 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, 30px greeting; 22px modal title (600)
- InterBody: Inter 400 16px body, 15px modal paragraph at 1.55, 14px tile labels (500)
Patterns
- centered completion modal over dimmed page
- personal sender header (avatar + "from team")
- inline mini-screenshot preview of the help menu
- single black primary "Complete" button
- app-tile grid grouped by named sections
- time-of-day greeting heading
- compact icon top bar with Invite pill
- floating chat launcher
States it is designed for
- Final tour step (this screen)
- Tour skipped earlier (no modal, "Resume tour" in help menu)
- Empty section with "Add an app" dashed tile
- Preview image failed to load (show caption text only)
- Tour-state save failed (toast with retry; modal still closes)
- Many sections (lazy render below fold)
Who it is for
- New teammates onboarding to a shared workspace hub
- Operations and product teams organising their tool stack
- Admins who invited colleagues
Layout
- Top bar: menu toggle and workspace mark left; search, home, bell, black "Invite" pill and avatar right
- Main: greeting H1 with add (+) button right; section headings ("Product", "Operations") with overflow menu; rows of app tiles (icon + label)
- Scrim 50% grey over everything
- Centered modal (~280-320px wide): sender avatar with badge + name line, close x, preview image of the help menu, H2 "Tour complete!", paragraph, right-aligned "Complete" button
- Bottom-right round chat launcher
- Mobile: modal becomes full-width bottom sheet; tiles in 3-column grid
Palette
calm, personal, minimal, reassuring. A quiet sign-off from a real-feeling person on the team.
- page background
#ffffff - headings and body
#18181b - paragraph and captions
#5f6068 - Complete and Invite buttons
#111111 - label on black button
#ffffff - screenshot well inside modal
#f4f4f5 - overlay rgba(0,0,0,.5) (decorative)
#7f7f7f - tile hairlines (decorative)
#e7e7ea - focus ring
#2563eb - sample app icon tint
#0f766e
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 17.72:1 | 4.5:1 |
| Aa | muted paragraph | 6.25:1 | 4.5:1 |
| Aa | button label on black | 18.88:1 | 4.5:1 |
| Aa | muted caption on preview well | 5.69:1 | 4.5:1 |
| focus ring | 5.17:1 | 3:1 | |
| app icon tint on white | 5.47: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
- Inter 600, 30px greeting; 22px modal title (600)
- Body
- Inter 400 16px body, 15px modal paragraph at 1.55, 14px tile labels (500)
Similar to the observed clean grotesk. Sender line 14px with name in 600.
Spacing and imagery
Airy: 8px base, 32px page gutter, 48px between tile sections; modal padding 20px; radius 10px modal, 8px preview well, 6px buttons; modal shadow 0 20px 40px rgba(0,0,0,.2).
Small circular sender avatar; a simplified UI preview (not a photo); coloured square app icons on the grid, generic glyphs only.
Components
- Top bar with icon buttons and Invite pill
- Greeting heading
- Section header with overflow menu
- App tile (icon, name, hover actions)
- Modal with sender header
- Preview figure with caption
- Primary Complete button
- Close icon button
- Chat launcher
Interactions
- Modal scales from 0.96 and fades (200ms)
- Complete and x both mark the tour finished; Esc too
- After closing, the menu containing the help center briefly highlights (1 pulse)
- Tiles lift and show a pin action on hover
- Keyboard: Tab cycles within modal; Enter on Complete
Data
Profile{id, first_name, avatar_url, tour_completed_at}Section{id, workspace_id, name, position}AppTile{id, section_id, label, icon_key, url, position}TourStep{id, order, title, body, preview_key}
Guardrails
Experience
- End the tour with a clear summary of where help lives, not a new task
- One primary action; close does the same thing
- Show the tour step count on earlier steps but not on the completion step
- Never reopen the completed tour automatically
- Point at the real menu after closing so the preview maps to reality
Accessibility
- Radix Dialog with aria-labelledby title and aria-describedby paragraph
- Preview image has meaningful alt describing the help menu items
- Focus returns to the element that was focused before the tour
- Pulse highlight respects prefers-reduced-motion
- Icon-only top-bar buttons have aria-labels
Security
- Users can update only their own tour_completed_at (RLS)
- App tile URLs validated as https and opened with rel="noopener noreferrer"
- Section edits limited to workspace editors
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 **Stepstone**, the final step of a guided tour inside a workspace hub. The hub groups a team's tools into named sections of app tiles. At the end of the tour a centred modal, "sent" by a friendly teammate avatar, confirms the tour is complete, shows a small preview of the help menu and closes with a single "Complete" button.
### Stack
React + TypeScript + Vite, Tailwind CSS, shadcn/ui (Dialog, DropdownMenu, Tooltip) on Radix, lucide-react, Motion for the entrance and post-close highlight, TanStack Query, Supabase for auth, sections, tiles and tour state.
### Pages & layout
1. **Top bar** (56px): menu toggle and workspace mark left; search, home, notifications, a small black "Invite" pill and avatar on the right.
2. **Home**: greeting H1 ("Good afternoon, Priya") with a + button; sections ("Product", "Operations") each with an overflow menu and a row of large, airy app tiles (coloured square icon above a label).
3. **Tour modal**: 50% scrim; a 320px dialog with the sender avatar (small team badge), "Jonah from the team", a close icon, a preview well showing a simplified help menu (community, request a feature, shortcuts, quick guide, what's new), H2 "Tour complete!", a two-sentence paragraph, and a right-aligned black "Complete" button.
4. **Chat launcher** bottom-right.
5. Mobile: tiles in three columns; the modal becomes a bottom sheet with a full-width button.
### Design system
- Colors: `--bg: #ffffff` (page background), `--fg: #18181b` (headings and body), `--muted: #5f6068` (paragraph and captions), `--primary: #111111` (Complete and Invite buttons), `--on-primary: #ffffff` (label on black button), `--preview-bg: #f4f4f5` (screenshot well inside modal), `--scrim: #7f7f7f` (overlay rgba(0,0,0,.5) (decorative)), `--border: #e7e7ea` (tile hairlines (decorative)), `--focus: #2563eb` (focus ring), `--tile-teal: #0f766e` (sample app icon tint).
- Fonts: Inter (similar to the observed grotesk): greeting 30px/600, modal title 22px/600, body 16px/1.5, modal paragraph 15px/1.55, tile labels 14px/500.
- Spacing: 8px scale, 32px gutters, 48px between sections, 20px modal padding.
- Radius: modal 10px, preview 8px, buttons 6px, Invite pill full.
- Shadows: modal `0 20px 40px rgba(0,0,0,.2)`; tiles flat.
- Motion: modal 200ms scale/fade; after close, a 600ms ring pulse on the avatar menu that holds help; off under reduced motion.
### Components & interactions
TopBar, GreetingHeader, Section (with overflow menu: rename, reorder, delete), AppTile (hover lift and pin action; opens the app in a new tab), TourDialog (SenderHeader, PreviewFigure, Title, Body, CompleteButton), ChatLauncher. Complete, close and Esc all set `tour_completed_at` and then trigger the highlight. If saving fails, close anyway and show a toast with Retry.
### Data & state
Tables: `profiles(id, first_name, avatar_url, tour_completed_at)`, `sections(id, workspace_id, name, position)`, `app_tiles(id, section_id, label, icon_key, url, position)`, `tour_steps(id, order, title, body, preview_key)`. Seed two sections with six generic tiles ("Notes", "Tasks", "Roadmap", "Board", "Payroll", "Docs"). Handle states: final step, tour skipped (a "Resume tour" item in the help menu), empty section with a dashed "Add an app" tile, preview failed, save failed, long section lists.
### Accessibility
Use Radix Dialog: title and body wired to aria-labelledby and aria-describedby; focus starts on Complete and returns to the element focused before the tour. The preview has alt text listing the help menu items. Icon buttons carry aria-labels. The highlight pulse is skipped under reduced motion. Tiles are links with visible focus rings.
Verified contrast: body text: #18181b on #ffffff = 17.72:1; muted paragraph: #5f6068 on #ffffff = 6.25:1; button label on black: #ffffff on #111111 = 18.88:1; muted caption on preview well: #5f6068 on #f4f4f5 = 5.69:1; focus ring: #2563eb on #ffffff = 5.17:1; app icon tint on white: #0f766e on #ffffff = 5.47:1.
### Security
RLS: members read their workspace's sections and tiles; only editors insert, update or delete them; each user updates only their own profile's tour fields. Validate tile URLs as https with zod and open them with `rel="noopener noreferrer"`.
### Performance & SEO
Preload the preview image during the previous tour step. Render sections below the fold lazily. Keep the dialog bundle small. App routes are noindex.
### Guardrails
- Sender name, avatar and tiles are invented; use generic icons, never real app logos.
- The completion step introduces no new task.
- Acceptance criteria: (1) the modal appears only after the last step; (2) all three close paths persist completion; (3) the highlight points at the real help menu; (4) states render with mock data; (5) the dialog passes keyboard and screen-reader checks.