Template
Coquill
A collaborative documents app starter: sign in, see your documents, create new ones, share them as viewer or editor, and edit together with live cursors, inline comments and notifications. It is a minimal but complete multi-user editor for teams building document features.
Collaborative rich-text documents editor starter · App · Small tools and apps · full-stack app (auth + DB)
A mock-up of the homepage, drawn from this design’s layout, palette and typefaces. A build follows the full prompt below.
Add app screens
Pick up to 6 screens, such as a dashboard, settings or an empty state. Each is built in this design’s own palette and typefaces, with its states and guardrails.
Start from this templateRead the build prompt
Typefaces
Sen is a friendly geometric sans for titles, Merriweather Sans gives the documents a papery, humane body, and Ubuntu Mono keeps code quiet.
- SenHeadings: page titles 24px 600, document H1 32px
- Merriweather SansBody: body 16px/1.6 400, list row names 14px 500, emails 14px
- Ubuntu MonoFigures and code: code 14px
Another design for the same product as Plainwrite, so the gallery lists it there. A collaborative documents editor with live cursors and inline comments.
Patterns
- demo-user picker list
- light/dark/system segmented toggle
- collapsible document sidebar
- centered page card on grey canvas
- presence avatars in top bar
- inline comments with sidebar
- live cursors
- share popover with viewer/editor roles
- notification inbox with count badge
States it is designed for
- no documents (create first document)
- document loading skeleton
- viewer mode (toolbar disabled, 'view only' badge)
- no access to document (request access)
- offline/reconnecting with queued edits
- comment resolved / reopened
- notification empty
Who it is for
- product engineers
- teams building knowledge or writing tools
- developers learning CRDT editors
Layout
- Sign-in: top-right theme segmented toggle; centered 336px column with product pill, title, two-line hint, list of user rows (initials avatar, name, email, 'Sign in' affordance)
- Editor shell: collapsible 260px sidebar (documents list, new document) + top bar (back, title, theme toggle, Share button, avatars, inbox count, notifications count)
- Canvas: grey background with a centered 720px page card holding the document
- Comments sidebar: slides in from the right, 320px
- Mobile: sidebar and comments become sheets; top bar hides avatars beyond two
Palette
Quiet, papery, friendly. Soft greys with colourful initials avatars and warm comment highlights.
- page background
#ffffff - editor canvas / row fill
#f5f5f5 - primary text
#0a0a0a - secondary text
#6b6b6b - row / input border
#8c8c8c - decorative dividers
#e0e0e0 - Share button fill
#0a0a0a - comment highlight
#ffe8a3 - status dot
#ffc31c - avatar fill A
#d93636 - avatar fill B
#0f7d78
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 19.80:1 | 4.5:1 |
| Aa | text on canvas | 18.16:1 | 4.5:1 |
| Aa | muted text on row | 4.89:1 | 4.5:1 |
| Aa | Share button label | 19.80:1 | 4.5:1 |
| Aa | avatar initials A | 4.63:1 | 4.5:1 |
| Aa | avatar initials B | 4.97:1 | 4.5:1 |
| row / input border | 3.36:1 | 3:1 | |
| focus ring | 18.16:1 | 3:1 | |
| Aa | comment highlight text | 16.33: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
- Sen 600, 24px/1.33 for page titles and document H1 (32px)
- Body
- Merriweather Sans 400, 16px/1.6 (observed a system sans; Merriweather Sans stands in for it)
Row names 14px 500 and emails 14px muted only within compact list rows; document body 16px; monospace code 14px Ubuntu Mono.
Spacing and imagery
Calm; 8px base; list rows 56px tall with 12px radius; page card 48px padding, radius 12px; buttons 8px radius; no shadows except popovers.
No photos; initials avatars on coloured circles, cursor flags in user colours, lucide icons in the toolbar.
Components
- ThemeToggle (segmented)
- DemoUserRow
- DocumentSidebar
- EditorTopBar
- PresenceAvatars
- ShareButton + SharePopover
- InboxBadge
- NotificationPanel
- RichTextEditor
- FloatingFormatToolbar
- CommentThread
- CommentsSidebar
- LiveCursor
- EmptyState
Interactions
- Selecting text shows a floating toolbar with bold, italic, heading, link and comment
- Comments highlight the anchored text; clicking opens the thread
- Live cursors show a name flag for 3s after movement
- Share popover: add teammate by email, choose viewer/editor, copy link
- Theme toggle switches instantly and persists
- Sidebar collapse with Ctrl+\
Data
User{id, name, email, color}Document{id, title, owner_id, created_at, updated_at, visibility (restricted|link)}DocumentMember{document_id, user_id, role (viewer|editor)}Comment{id, document_id, author_id, anchor, body, resolved, created_at}Notification{id, user_id, type (mention|reply|share), document_id, read_at}
Guardrails
Experience
- Viewers never see editing affordances as enabled
- Comments stay attached to their text as the document changes
- Show who has access before adding someone
- Notification counts clear when the panel is opened
- Keep the page card width fixed for comfortable reading
Accessibility
- Demo user rows are buttons with name and email in the accessible name
- Theme toggle is a radiogroup
- Live cursors are aria-hidden; presence list is available to screen readers
- Comment highlights also use an underline, not colour alone
- Initials on coloured avatars meet 4.5:1 (white on darkened fills)
- Formatting toolbar reachable by keyboard shortcut and arrow keys
Security
- RLS: documents readable by owner and document_members; updates only for editors; document_members managed by owner
- Realtime room access tokens minted server-side after membership check
- Sanitize pasted HTML in the editor
- Validate share emails and roles with zod; rate-limit share invites
- Demo sign-in only in development; production uses real auth
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 **Coquill**, a collaborative documents app: sign in, see your documents, create new ones, share them with teammates as viewer or editor, and write together with live cursors, inline comments and notifications. It should feel like a calm writing tool and demonstrate correct access control. ### Stack Next.js (App Router), React, TypeScript, Tailwind CSS, shadcn/ui (Radix), lucide-react, Tiptap with a CRDT collaboration extension, TanStack Query, react-hook-form + zod. Supabase Auth and Postgres for users, documents, membership, comments and notifications; a realtime presence service (or Supabase Realtime) for cursors and sync. ### Pages & layout 1. **/signin**: theme segmented control top-right. Centered 336px column: small product pill, title "Pick a demo user", two-line hint, six user rows (coloured initials avatar, name, email, "Sign in" with arrow). In production swap the list for email + OAuth. 2. **/docs**: sidebar with documents list and "New document"; main shows recent documents or an empty state. 3. **/docs/[id]**: top bar (back, editable title, theme toggle, Share, presence avatars, inbox and notifications counts). Grey canvas with a centered 720px page card; floating format toolbar on selection; comments sidebar on the right. Mobile: sidebar and comments become sheets, page card goes full width with 20px padding. ### Design system - Colors: `--bg: #ffffff` (page background), `--canvas: #f5f5f5` (editor canvas / row fill), `--fg: #0a0a0a` (primary text), `--muted: #6b6b6b` (secondary text), `--border: #8c8c8c` (row / input border), `--hairline: #e0e0e0` (decorative dividers), `--btn: #0a0a0a` (Share button fill), `--highlight: #ffe8a3` (comment highlight), `--amber: #ffc31c` (status dot), `--avatar-coral: #d93636` (avatar fill A), `--avatar-teal: #0f7d78` (avatar fill B). - Fonts: Sen (Google Fonts) 600 for titles (24px) and document H1 (32px); Merriweather Sans 400 body 16px/1.6; list row text 14px within compact rows; Ubuntu Mono 14px for code. - Spacing: 8px base; list rows 56px; page card padding 48px; 12px gaps. - Radius: 12px rows and page card, 8px buttons, full avatars. - Shadows: popovers `0 8px 24px rgb(0 0 0 / 0.12)`; none elsewhere. - Motion: 150ms; cursor flags fade after 3s; reduced motion removes slides. - Dark theme: invert surfaces (`#0a0a0a` bg, `#171717` canvas, `#f5f5f5` text) and re-check contrast. ### Components & interactions ThemeToggle, DemoUserRow, DocumentSidebar, EditorTopBar, PresenceAvatars, SharePopover (email + role select, member list, copy link), InboxBadge, NotificationPanel (mentions, replies, shares), RichTextEditor, FloatingFormatToolbar, CommentThread, CommentsSidebar, LiveCursor, EmptyState. ### Data & state Tables `documents(id, title, owner_id, visibility, updated_at)`, `document_members(document_id, user_id, role)`, `comments(document_id, author_id, anchor jsonb, body, resolved)`, `notifications(user_id, type, document_id, read_at)`. Document content is a CRDT persisted as snapshots in `document_snapshots`. Seed six invented users and five documents. ### Accessibility User rows are buttons whose names include name and email. Theme toggle is a radiogroup. Cursors are decorative; a presence list is exposed. Comment highlights add an underline. Avatar initials use white on darkened fills. Focus ring 2px `#0a0a0a`. Verified contrast: body text: #0a0a0a on #ffffff = 19.8:1; text on canvas: #0a0a0a on #f5f5f5 = 18.16:1; muted text on row: #6b6b6b on #f5f5f5 = 4.89:1; Share button label: #ffffff on #0a0a0a = 19.8:1; avatar initials A: #ffffff on #d93636 = 4.63:1; avatar initials B: #ffffff on #0f7d78 = 4.97:1; row / input border: #8c8c8c on #ffffff = 3.36:1; focus ring: #0a0a0a on #f5f5f5 = 18.16:1; comment highlight text: #0a0a0a on #ffe8a3 = 16.33:1. ### Security - RLS: `documents` select for owner or members; update for owner or members with role editor; `document_members` insert/update/delete by the owner only; `comments` select for members, insert for members, update/delete by author; `notifications` owner-only. - Mint realtime tokens server-side after checking membership and role (read-only tokens for viewers). - Sanitize pasted HTML; validate share input; rate-limit invites. Demo sign-in only when an env flag is set. ### Performance & SEO Lazy-load the editor bundle; debounce snapshot saves to 30s; throttle cursor updates to 20/s. App routes noindex. ### Guardrails - Invent all people, emails and document text. - Never let viewers write through the realtime channel. - Acceptance criteria: (1) two users edit the same document with live cursors; (2) a viewer cannot type or format; (3) comments stay anchored after edits; (4) sharing triggers a notification; (5) light and dark themes both pass contrast.