2 cases built from this template
Same prompt, different [VARIABLES]. Click one to preview it above.About this template
A single-page CRM app: an app shell with a left nav and a top bar; a pipeline kanban with five stages and drag-and-drop deal cards (company, value, owner, age) plus a keyboard move alternative; a contacts table with sortable columns, text search and owner/status filters; a deal detail drawer with an activity timeline and inline-editable fields; and an insights view with a revenue-by-month bar chart, stage distribution and top deals — every chart hand-rolled in SVG. About forty invented companies and deals are seeded deterministically on first load and persist to localStorage, with a Reset demo data button; every change — a stage move, a note, an edited value — survives reload. The look is dense productive SaaS: a near-white canvas, cool gray chrome, one deep indigo accent, 13px UI type with tabular numerals, subtle panel elevation. The build uses no drag library (pointer events) and no chart library — everything hand-rolled. To adapt it, swap the variables and rewrite the copy in one content file; stages, seed data, owners and chart labels all read from it.
The template prompt
The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].
# Sales CRM Dashboard
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
A single-page CRM app for [BRAND], the sales tool of [TEAM], a small team selling [FOCUS], denominated in [CURRENCY]. It must be a real app, not a mockup: five-stage pipeline kanban with pointer drag-and-drop and a keyboard alternative, a contacts table with sort/search/filters, a deal drawer with editable fields, notes and an activity timeline, an insights view with SVG charts, and ~40 seeded invented deals persisted in localStorage with reset. One page: index.html as a hash-routed app (#/pipeline, #/contacts, #/insights; #/deal/<id> opens the drawer). Everything runs in the browser; nothing is submitted anywhere.
- Audience: The sales-adjacent builder: indie founders and small-team operators evaluating what a CRM should feel like, plus developers who need an app-shell template with dense data UI done right.
- Goal: Feel like software, not a landing page. Within a minute a visitor drags a deal, opens a drawer, edits a value, reloads, and finds everything exactly where they left it.
- Tone: Terse product copy: button verbs, one-line empty states, no marketing voice anywhere in the app. Sample data carries believable B2B texture.
## Stack
- Framework: Vite 5 + React 18 + TypeScript
- Styling: Tailwind CSS 3.4
- Libraries: react (MIT), react-dom (MIT), motion (motion.dev, import from 'motion/react') (MIT), lucide-react (MIT), tailwindcss (MIT), postcss (MIT), autoprefixer (MIT), vite (MIT), @vitejs/plugin-react (MIT), typescript (Apache-2.0), @fontsource-variable/inter (OFL-1.1), @fontsource/jetbrains-mono (OFL-1.1)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
- Scaffold with npm create vite@latest using the react-ts template. One HTML page at the project root: index.html (entry src/main.tsx) — a hash-routed app (listen to hashchange; parse '#/pipeline', '#/contacts', '#/insights', '#/deal/<id>'; unknown routes land on #/pipeline, never an error).
- vite.config.ts: base './', plugins [react()], build { outDir 'dist', sourcemap false, assetsInlineLimit 0 }. Do not copy src/ into dist/.
- Tailwind 3.4 through PostCSS, content ['./index.html', './src/**/*.{ts,tsx}']. In tailwind.config.ts add every color under Design to theme.extend.colors with kebab-case keys (canvas, panel, chrome, hairline, ink, ink-soft, indigo, indigo-deep, indigo-mist, good, warn, danger) and fontFamily sans ['Inter Variable', 'system-ui', 'sans-serif'], mono ['JetBrains Mono', 'ui-monospace', 'monospace']. Set borderRadius DEFAULT to 8px.
- In src/fonts.ts import '@fontsource-variable/inter' and '@fontsource/jetbrains-mono/400.css', '@fontsource/jetbrains-mono/500.css'; import src/fonts.ts and src/index.css from the entry file.
- File layout: src/content.ts (stages, owners, seed companies/deals/activities with deterministic seeded generator, chart labels, all copy — typed), src/lib/brand.ts (brandSlug = [BRAND] lowercased with every run of non-alphanumeric characters replaced by '-'), src/lib/storage.ts (safe localStorage get/set, key brandSlug + ':crm'), src/lib/format.ts (money(cents, [CURRENCY]) with locale formatting; initials(name); ageInDays(fromSeed)); src/lib/router.ts (hash route parse/subscribe).
- State: src/store/crm.ts is a tiny external store (useSyncExternalStore) holding the whole dataset { deals, contacts, activities } loaded from localStorage or seeded on first run. Actions: moveDeal(id, stage, index), updateDeal(id, patch), addNote(id, text), toggleWon(id) (stage → Won), resetData(). Every action persists. The drawer route (#/deal/<id>) reads the current deal by id — a missing id closes the drawer back to the previous view, never an error.
- Drag-and-drop is hand-rolled: pointerdown on a card starts a drag (with a 6px threshold), pointermove lifts the card (a fixed-position clone, the origin a 40%-opacity ghost), hit-testing stage columns by bounding rect, pointerup drops; Escape cancels mid-drag. Keyboard: cards are buttons; Enter opens the drawer; Alt+ArrowLeft/Right moves the focused deal a stage (announced via an aria-live region). No dnd library.
- Charts are hand-rolled SVG: BarChart (revenue by month, 12 bars, axis ticks, hover tooltip), StageBar (horizontal stacked distribution), Sparkline (per-owner). No chart library.
- Components in src/components/: AppShell.tsx (Sidebar.tsx, TopBar.tsx with SearchInput, FilterMenu, NewDealButton), kanban/ (Pipeline.tsx, StageColumn.tsx, DealCard.tsx, DragLayer.tsx), contacts/ (ContactsTable.tsx, ContactRow.tsx, ContactCard.tsx mobile), drawer/ (DealDrawer.tsx, TimelineList.tsx, EditableValue.tsx, NoteBox.tsx), insights/ (Insights.tsx, BarChart.tsx, StageBar.tsx, TopDeals.tsx, Sparkline.tsx), common/ (Avatar.tsx initials, Badge.tsx, EmptyState.tsx, Toast.tsx). src/pages/App.tsx composes by route.
- public/favicon.svg as described under Assets. index.html: lang en, <meta name='theme-color' content='#F7F8FA'>, <link rel='icon' href='./favicon.svg' type='image/svg+xml'>, <title>[BRAND] — Sales CRM</title>.
- Write ASSETS.md at the project root as described under Assets.
- dist/ holds index.html, hashed JS/CSS, the woff2 fonts and favicon.svg. Keep it under 5 MB — no images.
## Variables
- [BRAND] — App name (default: "Pipestack"). Invented CRM name. Used in the title, top bar, footer colophon and localStorage keys. Never a real product.
- [TEAM] — Team name (default: "Northmill Supply"). The invented company using the CRM. Drives the top-bar team label, seeded deal companies' context (they sell to [TEAM]'s market) and the welcome line. Two common words.
- [FOCUS] — What they sell (default: "industrial sensor hardware"). The product being sold — drives seed company names and deal titles ('42-unit sensor rollout'). Keep it concrete B2B.
- [CURRENCY] — Currency (default: "USD"). Three-letter currency code for all money formatting (USD, EUR, GBP). Drives money() formatting of every value, total and chart tick.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/sales-crm-dashboard in the footer (default: yes; delete this line to remove it)
The copy under Pages & Sections is written for the default values. If your values differ, rewrite every headline, paragraph, label and image for them — same length, tone and structure. Layout, colors, type and motion stay as described.
Keep all copy, image paths and links in one content file (for example `src/content.ts`), keyed by section, so the content can be swapped later without touching components.Pro template. The design, sections, motion and assets parts of this prompt are for Pro members. The live demo and DESIGN.md stay free.
Join Pro early access →DESIGN.md
The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.
---
name: "Sales CRM Dashboard"
colors:
canvas: "#F7F8FA"
panel: "#FFFFFF"
chrome: "#EEF0F4"
hairline: "#E3E6EB"
ink: "#191D23"
ink_soft: "#5C6470"
indigo: "#3D56D6"
indigo_deep: "#3146B0"
indigo_mist: "#EDF0FC"
good: "#188652"
warn: "#B7791F"
danger: "#C0392B"
typography:
ui_text_nav_buttons_table_cells_deal_names_drawer_labels_empty_states_13_13_5px: { family: "Inter", weights: [400, 500, 600] }
numbers_deal_values_totals_chart_ticks_stage_counts_ages_tabular_nums: { family: "JetBrains Mono", weights: [400, 500] }
spacing: "4px base unit — dashboards are dense. App shell: sidebar 208px fixed, top bar 56px, content padding 20px. Kanban columns: 272px wide, 12px gaps, horizontal scroll of the whole board. Table rows 44px, cell padding 12px. Drawer 400px from the right, full-screen under 640px. Type scale: app title Inter 600 14px; nav items Inter 500 13.5px; deal value JetBrains Mono 500 13px tabular; deal company Inter 600 13.5px; metadata Inter 400 12.5px Ink Soft; table header Inter 600 11px uppercase letter-spacing 0.06em; empty state title Inter 600 14px with one 13px line under. Buttons: 32px high (primary Indigo fill, secondary Chrome fill with 1px Hairline border), 12.5px Inter 600. Inputs: 32px, Chrome fill, 1px Hairline border, focus 2px Indigo ring. Focus ring everywhere: 2px Indigo outline, 2px offset."
radius: "8px on cards, the drawer, inputs, buttons, avatars and tooltips. 999px only for badges, stage-count chips and avatars."
---
# Sales CRM Dashboard — Design System
Apply this design system to an existing project. It describes the look and feel only; for the full site, use prompt.md.
## Colors
- **Canvas** `#F7F8FA` — App background throughout.
- **Panel** `#FFFFFF` — Cards, columns, table rows, drawer, top bar surfaces.
- **Chrome** `#EEF0F4` — Sidebar background, table header, input fills, hover fills.
- **Hairline** `#E3E6EB` — 1px borders everywhere chrome meets panel.
- **Ink** `#191D23` — Primary text, deal names, chart labels.
- **Ink Soft** `#5C6470` — Secondary text, metadata, table headers, placeholder text.
- **Indigo** `#3D56D6` — The one accent: primary buttons, selected states, focus ring, chart bars, stage counts, link text.
- **Indigo Deep** `#3146B0` — Hover/pressed, drag-active column ring.
- **Indigo Mist** `#EDF0FC` — Selected row fill, Won stage tint, tooltip fill.
- **Good** `#188652` — Won badges, positive deltas, the toast success tick.
- **Warn** `#B7791F` — Aging badges (deal > 21 days), the stage-distribution 'Stalled' hint.
- **Danger** `#C0392B` — Lost badges and destructive button text only — never for errors that aren't real errors.
## Typography
- **UI text: nav, buttons, table cells, deal names, drawer labels, empty states (13–13.5px)** — Inter (OFL), weights 400/500/600. Self-host the font files.
- **Numbers: deal values, totals, chart ticks, stage counts, ages (tabular-nums)** — JetBrains Mono (OFL), weights 400/500. Self-host the font files.
## Spacing & shape
- Spacing: 4px base unit — dashboards are dense. App shell: sidebar 208px fixed, top bar 56px, content padding 20px. Kanban columns: 272px wide, 12px gaps, horizontal scroll of the whole board. Table rows 44px, cell padding 12px. Drawer 400px from the right, full-screen under 640px. Type scale: app title Inter 600 14px; nav items Inter 500 13.5px; deal value JetBrains Mono 500 13px tabular; deal company Inter 600 13.5px; metadata Inter 400 12.5px Ink Soft; table header Inter 600 11px uppercase letter-spacing 0.06em; empty state title Inter 600 14px with one 13px line under. Buttons: 32px high (primary Indigo fill, secondary Chrome fill with 1px Hairline border), 12.5px Inter 600. Inputs: 32px, Chrome fill, 1px Hairline border, focus 2px Indigo ring. Focus ring everywhere: 2px Indigo outline, 2px offset.
- Radius: 8px on cards, the drawer, inputs, buttons, avatars and tooltips. 999px only for badges, stage-count chips and avatars.
## Motion
- Easing: --ease-out cubic-bezier(0.22, 0.61, 0.36, 1) for drops and the drawer; --ease-io cubic-bezier(0.65, 0, 0.35, 1) for tooltips and route swaps. Product-speed: 150–260ms, nothing slower.
- Route swaps: views crossfade 160ms with an 8px rise (AnimatePresence).
- Drag: the lifted clone follows the pointer at 1.02 scale with a soft shadow; the target column ring pulses once; drop settles the card into its slot with a 180ms translate; the origin ghost collapses 140ms. Escape cancels — the clone flies home 200ms.
- Deal card hover: lifts 1px with a Hairline→Indigo/30% border; the drag handle appears.
- Drawer: slides from x 100% to 0 over 240ms --ease-out; backdrop fades 160ms; field edits crossfade the value; a note posts with a 160ms rise; the timeline's new entry draws its tick.
- Charts: bars grow from the baseline 320ms --ease-out staggered 30ms on view enter; hover tooltip fades 120ms; the stage distribution's segments settle width-first.
- Toasts: bottom-center, rise 8px + fade 200ms, auto-dismiss 2.4s with a thin progress rule; aria-live polite.
- Table sort: the header arrow flips 150ms; rows reorder instantly (no FLIP — tables read fine without it).
- prefers-reduced-motion: reduce — no bar growth (render at full height), no drawer slide (appear), no clone flight (cancel = instant), no staggers. Use CSS @media in index.css plus Motion's useReducedMotion in components.
## Imagery
No images at all. Avatars are initials circles (Chrome fill, Ink initials); charts are SVG; the favicon is SVG; deal 'logos' are two-letter monograms. Icons: lucide-react only, stroke width 2, 14–18px — small and crisp.
## Tone
Terse product copy: button verbs, one-line empty states, no marketing voice anywhere in the app. Sample data carries believable B2B texture.
---
— Prompt by VibeFather · https://vibefather.ai/t/sales-crm-dashboard · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown