Template
Plainwrite
A lightweight collaborative document editor for small teams: rich text with a floating toolbar, live presence, inline comment threads, autosave, a month-grouped document library and simple writing analytics. It replaces heavier wiki or docs suites for teams of 2-20.
Lightweight collaborative docs editor · App · Small tools and apps · full-stack app (auth + DB)
Who it is for
- Small teams of 2-20
- Agencies and design studios
- Teams keeping meeting notes and roadmaps
- Managers tracking writing output
Layout
- White top bar: wordmark left, 'Sign in' and black pill 'Get started' right
- Centered hero: huge 70px product name, grey tagline, black pill CTA
- Greyscale logo strip
- Dark full-width band: pill tab switcher (Rich text editor / Live presence / Comments) with pause, section heading, and a browser-framed app mock (sidebar: New document, Overview, Documents, Analytics, Settings; doc breadcrumb, Saved ✓, word count)
- Auto-advancing demo progress pill
- Dark rounded CTA panel with white pill button
- Footer
- App: overview dashboard, documents library (list/grid, month groups), editor with cover image and emoji icon, comments sidebar, analytics charts, settings/invites
Palette
Minimal, monochrome, calm, confident, modern. Black-and-white restraint that keeps attention on writing.
- background
#ffffff - text
#0a0a0a - dark band
#1a1a1a - muted grey text
#666666 - surface
#f5f5f5 - border
#e5e5e5
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on background | 19.80:1 | 4.5:1 |
| Aa | muted grey text on background | 5.74:1 | 4.5:1 |
| Aa | muted grey text on muted surface | 5.27:1 | 4.5:1 |
| Aa | light text on black primary button | 18.97:1 | 4.5:1 |
| Aa | white text on dark band | 17.40:1 | 4.5:1 |
| Aa | secondary text on dark band | 6.90:1 | 4.5:1 |
| input border on background | 3.07: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
- Display
- Geist 600, 70px with -2.1px tracking; 32px section heads
- Body
- Geist 400 16px; 13px UI
Monochrome single-family system; the product's calm typography is the brand. Accessibility: body copy 16px or larger at 1.5+ line height with a ~70ch max measure; no text below 12px; weights under 400 only at 32px+; uppercase reserved for short labels with 0.05em+ tracking.
Spacing and imagery
Generous whitespace, ~900px mock inside 1200px container, pill buttons, 10px radius cards, 24px radius dark CTA panel.
Greyscale partner-style logo strip, browser-framed product UI mocks, cover image presets on documents, small avatars for presence.
Components
- Pill tab demo switcher
- Browser-framed product mock
- Logo strip
- Sidebar navigation
- Document library table grouped by month with mini previews
- List/grid toggle
- Search by title/content
- Multi-select batch delete
- Editor with cover image and emoji icon
- Floating bubble toolbar
- Presence avatars and cursors
- Inline comment threads
- Overview stat cards
- Analytics charts with date range filter
Interactions
- Auto-advancing demo tabs with pause
- Select text to format via bubble menu
- Real-time presence indicators
- Comment on selected text, reply, resolve
- Autosave with 'Saved' indicator and word count
- Search filters live
- Batch select and delete with confirm
- Date range filter on analytics
Data
Workspace{id, name}Member{workspace_id, user_id, role: owner|editor|viewer}Document{id, workspace_id, title, emoji, cover, ydoc_state, word_count, author_id, created_at, updated_at}CommentThread{id, document_id, anchor, resolved}Comment{thread_id, author_id, body, created_at}Invite{workspace_id, email, role, token}
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 a template'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 templates) - 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.
### Goal Build **Plainwrite**, a simple shared-docs tool for small teams (2-20 people) who find full wikis too heavy. Members write in a clean rich-text editor with cover images and emoji icons, see who else is in a document, discuss inline, and never think about saving. A library keeps docs findable and a small analytics view shows writing activity. ### Stack React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix), lucide-react. Tiptap with Collaboration/Cursor extensions over Yjs (provider on Supabase Realtime or a Hocuspocus server), dnd-kit for reordering pinned docs, TanStack Query + TanStack Table for the library, Recharts for analytics, Framer Motion for the landing demo, react-hook-form + zod for settings and invites. Supabase: Auth, Postgres, Realtime presence, Storage for custom covers, Edge Function for invites. ### Pages & layout 1. **Landing**: white nav; massive centered product name, grey tagline, black pill CTA; a greyscale strip of fictional partner wordmarks; a dark band with pill tabs (Editor, Presence, Comments) that auto-advance with a pause button above a browser-framed product mock; a dark rounded CTA panel; footer. 2. **Overview**: totals (documents, comments, words this week), three recent documents, activity list. 3. **Documents**: search (title and content), list/grid toggle, month-grouped table with mini thumbnail, title, author, word count, updated; checkbox multi-select with batch delete. 4. **Editor**: optional cover (six presets or upload) and emoji icon; title; body; breadcrumb, "Saved" state and word count in the header; presence avatars; comments sidebar. 5. **Analytics**: words and documents over time, top authors; range filter 7/30/90 days/all. 6. **Settings**: workspace name, members, roles, invites. ### Design system Monochrome. Tokens: `--background: #ffffff`, `--foreground: #0a0a0a`, `--muted: #f5f5f5`, `--muted-foreground: #666666`, `--border: #e5e5e5`, `--primary: #0a0a0a`, `--primary-foreground: #fafafa`, `--inverse: #1a1a1a`; presence colours from a set of eight. Font: Geist 400/500/600 (Google Fonts) with Geist Mono for counts; editor body 17px/1.7. Scale 13/16/20/32/70; headings at -0.03em. Radius 10px; pills for buttons; 24px on the CTA panel. Shadows barely there. Motion 200ms; tabs auto-advance every 6s. Add `--input-border: #939393` and dark-band secondary text `#a3a3a3`. ### Components & interactions Bubble toolbar (bold, italic, heading, code, quote, link) appears on selection. Comment flow: select text → "Comment" → thread with replies → resolve; resolved threads collapse. Presence: avatar stack and coloured cursor labels. Autosave states: saving, saved, offline. Batch delete: confirm dialog listing count. Empty library state with "New document". Errors show inline banners with retry. ### Data & state Workspace, Member(role), Document(title, emoji, cover, ydoc_state, word_count), CommentThread(anchor as Yjs relative position), Comment, Invite. Analytics computed from document update events or a daily snapshot table. Library filters in URL. Seed ~20 docs (roadmap, meeting notes, onboarding guide) with fictional authors. ### Accessibility Editor toolbar buttons labelled with `aria-pressed`; keyboard shortcuts documented. Auto-rotating demo pauses on hover/focus and reduced motion. Comments panel is a labelled `aside` with headings per thread. Grey text (#666666) passes 4.5:1 on white and on the muted surface at every size. Cover images marked decorative unless custom with alt. Type: body 16px+, line height 1.5+, max ~70ch, nothing under 12px. Verified contrast: body text #0a0a0a on #ffffff = 19.8:1; muted grey text #666666 on #ffffff = 5.74:1; muted grey text #666666 on #f5f5f5 = 5.27:1; light text #fafafa on #0a0a0a = 18.97:1. ### Security RLS by workspace membership: viewers read only; editors create and edit; owners manage members. Enforce read-only for viewers in the collaboration server as well as the UI. Sanitize pasted HTML and comment content with DOMPurify. Invites are expiring single-use tokens sent from an Edge Function. Cover uploads: images ≤5 MB. Batch delete is soft-delete with a 30-day restore window. ### Performance & SEO Lazy-load the editor and analytics; paginate library by month. Use small preview thumbnails. Landing meta/OG, semantic headings; app `noindex`. ### Guardrails - Original copy; fictional logos only -- never real company marks in a logo strip. - No invented customer quotes. - Typed components, no `any`, visible errors. - Done when: two users see each other's presence and edits live; comments anchor to text and resolve; the library groups by month and searches content; batch delete asks for confirmation; viewers cannot edit.