Skip to main content
vibld

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

  1. White top bar: wordmark left, 'Sign in' and black pill 'Get started' right
  2. Centered hero: huge 70px product name, grey tagline, black pill CTA
  3. Greyscale logo strip
  4. 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)
  5. Auto-advancing demo progress pill
  6. Dark rounded CTA panel with white pill button
  7. Footer
  8. 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

SampleWhereRatioNeeds
Aabody text on background19.80:14.5:1
Aamuted grey text on background5.74:14.5:1
Aamuted grey text on muted surface5.27:14.5:1
Aalight text on black primary button18.97:14.5:1
Aawhite text on dark band17.40:14.5:1
Aasecondary text on dark band6.90:14.5:1
input border on background3.07:13: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.

Open the builderAll templatesThis palette on its own