Template
Spreadwing
A share sheet in a crowdfunding dashboard that helps an organiser spread their fundraiser across messaging apps, social networks, email and offline materials. Copying the link is the first and most prominent action.
Fundraiser share sheet with channel grid · App screen: share · 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 700, 22px modal title
- InterBody: Inter 400 16px subline at 1.5; 15px channel labels (600); 13px URL preview
Patterns
- share modal with two-column channel grid
- circular icon + label channel buttons
- copy-link tile that flips to "Link copied" with check
- contextual tip strip with cluster of channel icons
- offline channels (QR code, print poster, website widget)
- dimmed dashboard with dark green primary CTA
- large close x
States it is designed for
- Default
- Link copied
- Clipboard blocked (show selectable URL)
- Popup blocked (fallback link opens in new tab)
- Fundraiser unpublished (share disabled with reason)
- Loading short link
Who it is for
- Individuals raising money for a cause
- Charities and community organisers
- Friends and family supporters who reshare
Layout
- Dashboard behind: top nav (search, audience menus, centered wordmark, your fundraisers, account), left nav (Dashboard, Donations, Transfers, Updates), main with "Share fundraiser" button
- Modal (~345-520px): close x; H2 + subline; two-column grid: Copy link tile (spans with URL preview), social network; tip strip with icon cluster; messaging apps, email, neighbourhood network, microblog, QR code, print poster, website widget
- Mobile: bottom sheet; native share as first option
Palette
warm, hopeful, simple, encouraging. Sharing feels like a small act of help.
- modal background
#ffffff - titles and labels
#232323 - subline, URL preview
#545454 - tip strip fill
#f3f3f3 - primary CTA
#0b5d3b - CTA label
#ffffff - copied state circle
#e6f5ec - copied check
#0b7a47 - neutral channel circle
#ececec - overlay (decorative)
#4c4c4c
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | title and labels | 15.72:1 | 4.5:1 |
| Aa | muted subline | 7.57:1 | 4.5:1 |
| Aa | tip strip text | 14.16:1 | 4.5:1 |
| Aa | CTA label | 7.95:1 | 4.5:1 |
| copied check icon | 4.79:1 | 3:1 | |
| Aa | copied label | 5.40:1 | 4.5:1 |
| focus ring | 7.95:1 | 3:1 | |
| neutral icon glyph | 13.30: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 700, 22px modal title
- Body
- Inter 400 16px subline at 1.5; 15px channel labels (600); 13px URL preview
Similar to the observed friendly grotesk; labels are sentence case.
Spacing and imagery
Roomy: 8px base; modal padding 24px; channel rows 48px with 12px icon gap; 16px column gap; radius 12px modal, 8px strip, full circles for icons; modal shadow 0 24px 60px rgba(0,0,0,.25).
Circular channel icons (use neutral generic glyphs: chat bubble, envelope, megaphone, house, QR, printer, code); a playful cluster of small circles in the tip strip; no photos in the modal.
Components
- Share modal
- Copy link tile with URL preview and copied state
- Channel button (circle icon + label)
- Tip strip
- QR code dialog with download
- Print poster generator
- Website widget embed dialog
- Native share button (mobile)
Interactions
- Copy link copies instantly and flips icon to check + "Link copied" for 3s
- Each network button opens a prefilled share URL in a popup; tracking parameter appended per channel
- QR code opens sub-dialog with PNG/SVG download
- Print poster opens a printable A4 page with QR and title
- Website widget shows embed code with copy
- Esc / x closes; focus returns to Share fundraiser
Data
Fundraiser{id, organiser_id, title, slug, status (draft|live|closed), goal_amount, raised_amount}ShareEvent{id, fundraiser_id, channel (copy|social|message|email|qr|poster|widget), created_at}ShortLink{fundraiser_id, code, utm_source}
Guardrails
Experience
- Put copy link first; it works everywhere
- Keep channel labels plain; icons are secondary
- Offer offline options (QR, poster) for local fundraising
- Use a bottom sheet with native share on mobile
- Show the actual URL so people trust what they share
Accessibility
- Channel buttons have text labels (icons aria-hidden); popups announced as "opens in new window"
- Copied state announced via role="status"
- Grid order reads left-to-right, top-to-bottom logically
- QR dialog includes the URL as text
- Modal traps focus and restores it
Security
- Share URLs built server-side from slug; never include personal data in query strings
- Widget embed is a sandboxed iframe with a fixed origin
- Share events stored without personal identifiers; rate-limit logging endpoint
- Unpublished fundraisers cannot be shared (server check)
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 **Spreadwing**, the share sheet of a crowdfunding dashboard. From "Share fundraiser", a modal titled "Help more people find this" lists ways to share in two columns: copy link first, then social, messaging, email, a neighbourhood network, a microblog, plus offline options (QR code, printable poster, website widget).
### Stack
Next.js (App Router) + TypeScript, Tailwind CSS, shadcn/ui (Dialog, Drawer, Toast) on Radix, lucide-react, TanStack Query. Supabase for auth, fundraisers, short links and share events. A small QR library generates the codes client-side.
### Pages & layout
1. **Dashboard behind**: top nav (search, "For individuals", "For charities", a centred invented wordmark, "Your fundraisers", account); left nav (Dashboard, Donations, Transfers with a dot, Updates); main with a dark green "Share fundraiser" button.
2. **Share modal** (520px): close x; H2 and a subline ("Sharing regularly is the best way to reach new supporters"); a two-column grid.
3. **Grid**: Copy link tile (circle icon, label, truncated URL preview); social network; a full-width tip strip ("Share your link anywhere online") with a cluster of small circles; messaging app; email; direct message; neighbourhood network; microblog; QR code; Print poster; Website widget.
4. Mobile: a bottom drawer with "Share via…" (native share) first, then the same list in one column.
### Design system
- Colors: `--bg: #ffffff` (modal background), `--fg: #232323` (titles and labels), `--muted: #545454` (subline, URL preview), `--strip: #f3f3f3` (tip strip fill), `--brand: #0b5d3b` (primary CTA), `--on-brand: #ffffff` (CTA label), `--copied-bg: #e6f5ec` (copied state circle), `--copied-fg: #0b7a47` (copied check), `--icon-neutral: #ececec` (neutral channel circle), `--scrim: #4c4c4c` (overlay (decorative)).
- Fonts: Inter (similar to the observed friendly grotesk): title 22px/700, subline 16px/1.5, labels 15px/600, URL preview 13px.
- Spacing: 8px scale; 24px modal padding; 48px rows; 16px column gap.
- Radius: modal 12px; strip 8px; icons fully round.
- Shadows: modal `0 24px 60px rgba(0,0,0,.25)`.
- Motion: 150ms icon flip on copy; dialog fade/scale; none under reduced motion.
### Components & interactions
ShareDialog (Drawer on mobile), CopyLinkTile (copies, shows check and "Link copied" for 3s, falls back to a selectable URL), ChannelButton (generic icon in a circle; opens a prefilled share URL in a popup, or a new tab if blocked), TipStrip, QrDialog (PNG/SVG download, URL shown as text), PosterPreview (printable page), WidgetDialog (embed code with copy), NativeShareButton. Each click logs a share event.
### Data & state
Tables: `fundraisers(id, organiser_id, title, slug, status, goal_amount, raised_amount)`, `short_links(fundraiser_id, code, utm_source)`, `share_events(id, fundraiser_id, channel, created_at)`. Mock "Rebuild the community library" as live. Handle states: default, copied, clipboard blocked, popup blocked, unpublished (disabled with reason), short link loading.
### Accessibility
Every channel is a button with a text label; icons are hidden. Popups say they open a new window. Copy feedback uses role="status". The QR dialog includes the URL as text. Focus is trapped and returns to the trigger. Focus ring: 2px dark green with offset.
Verified contrast: title and labels: #232323 on #ffffff = 15.72:1; muted subline: #545454 on #ffffff = 7.57:1; tip strip text: #232323 on #f3f3f3 = 14.16:1; CTA label: #ffffff on #0b5d3b = 7.95:1; copied check icon: #0b7a47 on #e6f5ec = 4.79:1; copied label: #0b7a47 on #ffffff = 5.40:1; focus ring: #0b5d3b on #ffffff = 7.95:1; neutral icon glyph: #232323 on #ececec = 13.30:1.
### Security
Build share URLs server-side from the slug with a per-channel source tag; include no personal data. The widget is a sandboxed iframe from a fixed origin. Share events store only channel and time and are rate-limited. The server refuses short links for unpublished fundraisers. RLS: organisers read their own share stats.
### Performance & SEO
Pre-generate the short link when the dashboard loads. Lazy-load the QR library and poster view. The public fundraiser page carries OG tags so shared links preview well; the dashboard is noindex.
### Guardrails
- Neutral channel icons and invented wordmark; no platform logos or names in labels (use "Social network", "Messaging app").
- Copy link is always first.
- Acceptance criteria: (1) copy works with fallback; (2) each channel opens correctly or falls back; (3) QR, poster and widget work; (4) mobile uses native share; (5) all states render; (6) keyboard and screen-reader flows pass.