Skip to main content
vibld

Template

Nimova

A generated CRM app's home screen built in a no-code app builder. A photographic hero states total open pipeline, four stat cards summarise open deals, won revenue, follow-ups due and stale deals, and an exception list surfaces deals with no contact for a week or more.

CRM sales dashboard with photo hero and stale-deal list · App screen: dashboard · 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 - hero figure 40px, card figures 28px, -0.02em
  • InterBody: Inter 400 16px / 1.5

Patterns

  • photo hero banner with headline metric
  • stat cards row with icon per card
  • alert-coloured count for stale items
  • exception list with age badges
  • app-builder shell with tabs and publish pill
  • top tab bar inside the app (Dashboard, Deals, Contacts, Companies)

States it is designed for

  • loading skeletons for hero figure, cards and list
  • no deals yet (empty hero with 'Add your first deal')
  • no stale deals (positive empty message in the list area)
  • error loading with retry
  • very large numbers abbreviated with full value in tooltip
  • unpublished changes indicator on Publish

Who it is for

  • small sales teams
  • founders running their own pipeline
  • no-code builders generating internal tools

Layout

  1. Builder shell: left sidebar with workspace switcher, home/projects/app store, recent apps list, upgrade card; top bar with back/folder/chat icons, app tab, refresh, overflow, Edit and cyan Publish pill
  2. App header: app icon + name left, centred tabs (Dashboard active, Deals, Contacts, Companies)
  3. Hero banner (16:5) with office photo, dark gradient scrim bottom-left, uppercase eyebrow, large pipeline figure with suffix, one-line breakdown
  4. Stat cards row (4 columns): label + icon, big number (green for revenue, red for stale), sub-caption
  5. Stale deals section: alert icon heading, list rows (initials or logo tile, deal name, company, age badge in red tint, amount right)
  6. Tablet: stat cards 2x2; mobile: hero shorter with figure 32px, cards 1 column, list rows wrap amount under name

Palette

Warm, businesslike and optimistic; a real-office photo makes a generated app feel lived-in.

  • page#f6f6f5
  • surface#ffffff
  • text#1c1917
  • muted text#6b6560
  • revenue green#16a34a
  • stale red#d12222
  • stale badge bg#fde8e8
  • publish cyan#5ce1e6
  • on publish#0f172a
  • scrim over worst-case white photo#595959
  • on hero#ffffff
  • focus ring#2563eb

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text on white card17.49:14.5:1
Aamuted captions on card5.74:14.5:1
won revenue figure (large) on white3.30:13:1
stale count (large) on white5.30:13:1
Aastale badge text4.51:14.5:1
AaPublish label on cyan11.36:14.5:1
Aahero text over photo, white on 65% black scrim over a white patch7.00:14.5:1
focus ring on page4.78: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 scale

Display
Inter 700 - hero figure 40px, card figures 28px, -0.02em
Body
Inter 400 16px / 1.5

Similar to the observed neo-grotesk; eyebrow uppercase 12px 600 with 0.08em tracking; all figures tabular.

Spacing and imagery

Comfortable; 4px base, 16px gap between cards, 20px card padding; radius 12px hero and cards, 999px badges and Publish pill; cards use a 1px #e7e5e4 border, no shadow.

One licensed or generated office photo with a bottom-left dark gradient scrim (black 0% to 65%); small outline icons on cards; company logo tiles or initials in list rows.

Components

  • BuilderSidebar
  • BuilderTopBar with Edit and Publish
  • AppTabs
  • HeroMetricBanner
  • StatCard (label, icon, value, caption, tone)
  • StaleDealsList
  • AgeBadge
  • DealRow

Interactions

  • Stat cards are links that filter the Deals tab (e.g. Stale deals opens Deals filtered to stale)
  • Hovering a deal row highlights it and reveals a 'Log contact' quick action
  • Hero figure counts up once on first load (skipped under reduced motion)
  • Tabs are real routes with underline/pill active state
  • Publish opens a small popover with the share URL and visibility

Data

  • Deal{id, name, company_id, amount, stage (lead|qualified|proposal|won|lost), last_contact_at, next_step?, close_date}
  • Company{id, name, logo_url?, industry}
  • Activity{id, deal_id, type (call|email|meeting|note), at}
  • Derived: pipeline_total, open_count, won_total, followups_today, stale_count (last_contact_at < now - 7d)

Guardrails

Experience

  • Lead with the single number that matters (open pipeline)
  • Use colour only on the figures that need attention
  • Make every card a door into a filtered list
  • Keep the stale list short (top 5) with a View all link
  • Show units and time windows in captions

Accessibility

  • Hero figure is real text over the image with a scrim; image alt is empty
  • Colour-coded figures also carry words (Won revenue, Stale deals) and icons with labels
  • Age badges read '82 days since last contact' to screen readers
  • Tab bar uses nav with aria-current
  • Stat cards as links have descriptive names

Security

  • RLS: deals, companies and activities scoped to the workspace
  • Validate amounts and dates server-side
  • Publishing respects visibility (private, workspace, public-link) and public views never expose notes
  • Escape user-entered names in all renders

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 **Nimova**, the dashboard tab of a small CRM app shown inside a no-code builder shell. Seed a dozen fictional deals and companies and implement the hero metric, stat cards, stale-deal list and all loading and empty states.

### Stack
Use React 18, TypeScript, Vite, Tailwind CSS, shadcn/ui, Radix, lucide-react, TanStack Query, react-hook-form, zod, Supabase, date-fns.  Use Supabase for Auth, Postgres (row-level security on every table) and Storage where noted; keep only the anon key in the browser and run privileged work in Edge Functions.

### Pages & layout
1. **Dashboard** (this screen).
2. **Deals**: table with stage filter, used by stat-card links.
3. **Contacts** and **Companies**: simple lists.
4. Builder chrome (sidebar and top bar) wraps all tabs.

Regions, in order:
- Builder shell: left sidebar with workspace switcher, home/projects/app store, recent apps list, upgrade card; top bar with back/folder/chat icons, app tab, refresh, overflow, Edit and cyan Publish pill
- App header: app icon + name left, centred tabs (Dashboard active, Deals, Contacts, Companies)
- Hero banner (16:5) with office photo, dark gradient scrim bottom-left, uppercase eyebrow, large pipeline figure with suffix, one-line breakdown
- Stat cards row (4 columns): label + icon, big number (green for revenue, red for stale), sub-caption
- Stale deals section: alert icon heading, list rows (initials or logo tile, deal name, company, age badge in red tint, amount right)
- Tablet: stat cards 2x2; mobile: hero shorter with figure 32px, cards 1 column, list rows wrap amount under name

### Design system
- Colors: `--page: #f6f6f5` (page), `--surface: #ffffff` (surface), `--text: #1c1917` (text), `--muted-text: #6b6560` (muted text), `--revenue-green: #16a34a` (revenue green), `--stale-red: #d12222` (stale red), `--stale-badge-bg: #fde8e8` (stale badge bg), `--publish-cyan: #5ce1e6` (publish cyan), `--on-publish: #0f172a` (on publish), `--scrim-over-worst-case-white-photo: #595959` (scrim over worst-case white photo), `--on-hero: #ffffff` (on hero), `--focus-ring: #2563eb` (focus ring).
- Fonts: Inter 700 - hero figure 40px, card figures 28px, -0.02em for headings; Inter 400 16px / 1.5 for body. Similar to the observed neo-grotesk; eyebrow uppercase 12px 600 with 0.08em tracking; all figures tabular.
- Spacing, radius and shadows: Comfortable; 4px base, 16px gap between cards, 20px card padding; radius 12px hero and cards, 999px badges and Publish pill; cards use a 1px #e7e5e4 border, no shadow.
- Motion: 150-200 ms ease-out for hover, focus and overlay transitions; overlays fade and scale from 98% to 100%; everything collapses to an instant change under prefers-reduced-motion.
- Mood: Warm, businesslike and optimistic; a real-office photo makes a generated app feel lived-in. Imagery: One licensed or generated office photo with a bottom-left dark gradient scrim (black 0% to 65%); small outline icons on cards; company logo tiles or initials in list rows.

### Components & interactions
Build these components: BuilderSidebar; BuilderTopBar with Edit and Publish; AppTabs; HeroMetricBanner; StatCard (label, icon, value, caption, tone); StaleDealsList; AgeBadge; DealRow.

- Stat cards are links that filter the Deals tab (e.g. Stale deals opens Deals filtered to stale)
- Hovering a deal row highlights it and reveals a 'Log contact' quick action
- Hero figure counts up once on first load (skipped under reduced motion)
- Tabs are real routes with underline/pill active state
- Publish opens a small popover with the share URL and visibility

### Data & state
Model: `Deal{id, name, company_id, amount, stage (lead|qualified|proposal|won|lost), last_contact_at, next_step?, close_date}`; `Company{id, name, logo_url?, industry}`; `Activity{id, deal_id, type (call|email|meeting|note), at}`; `Derived: pipeline_total, open_count, won_total, followups_today, stale_count (last_contact_at < now - 7d)`.

Compute derived metrics in SQL views (or a pure TS module over fetched rows). Staleness threshold is a setting (default 7 days).

States to implement and demo:
- loading skeletons for hero figure, cards and list
- no deals yet (empty hero with 'Add your first deal')
- no stale deals (positive empty message in the list area)
- error loading with retry
- very large numbers abbreviated with full value in tooltip
- unpublished changes indicator on Publish

### Accessibility
- Hero figure is real text over the image with a scrim; image alt is empty
- Colour-coded figures also carry words (Won revenue, Stale deals) and icons with labels
- Age badges read '82 days since last contact' to screen readers
- Tab bar uses nav with aria-current
- Stat cards as links have descriptive names
- Body text is 16px with line-height 1.5 (15px only inside dense tables), nothing renders below 12px, weights of 300 or lighter appear only at 24px and above, and uppercase is limited to short labels with at least 0.05em tracking.
Verified contrast: body text on white card: #1c1917 on #ffffff = 17.49:1; muted captions on card: #6b6560 on #ffffff = 5.74:1; won revenue figure (large) on white: #16a34a on #ffffff = 3.30:1; stale count (large) on white: #d12222 on #ffffff = 5.30:1; stale badge text: #d12222 on #fde8e8 = 4.51:1; Publish label on cyan: #0f172a on #5ce1e6 = 11.36:1; hero text over photo, white on 65% black scrim over a white patch: #ffffff on #595959 = 7.00:1; focus ring on page: #2563eb on #f6f6f5 = 4.78:1.

### Security
- RLS: deals, companies and activities scoped to the workspace
- Validate amounts and dates server-side
- Publishing respects visibility (private, workspace, public-link) and public views never expose notes
- Escape user-entered names in all renders

RLS: `deals`, `companies`, `activities` - select/insert/update/delete where the user is a member of `workspace_id`; views inherit via security_invoker.

### Performance & SEO
Serve the hero image as responsive AVIF/WebP with width descriptors and lazy-load list logos. Cache metrics queries for 30s. App routes are noindex unless published publicly.

### Guardrails
- Lead with the single number that matters (open pipeline)
- Use colour only on the figures that need attention
- Make every card a door into a filtered list
- Keep the stale list short (top 5) with a View all link
- Show units and time windows in captions
- Use the product name Nimova and fresh, generic copy throughout; all people, companies, amounts and IDs are invented, and no third-party brand, logo or wordmark appears.
- Keep components small and typed (no `any`), and surface every failure visibly instead of swallowing it.

Acceptance criteria:
- [ ] Metrics match seeded data
- [ ] Stat cards link to filtered deals
- [ ] Empty and loading states render
- [ ] Text over photo passes with scrim
- [ ] 390px layout works

Open the builderAll templatesThis palette on its own