Template
Loomgraph
A marketing site for an AI data platform that connects a company's scattered tools into one knowledge graph and lets teams ask questions in plain language. It targets data-curious operators and technical buyers with a moody, precise aesthetic and product-module storytelling.
Dark AI data-intelligence (knowledge graph) landing site · Website · SaaS landing page · static site
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
Mozilla Headline and Mozilla Text are a paired grotesk for display and reading sizes, precise and quiet on black, and Reddit Mono gives the counts and ticks an engineered, lab-like voice.
- Mozilla HeadlineHeadings: H1 72px 700, -0.03em, line-height 1.0
- Mozilla TextBody: H2 32px 600, body 16px/1.6 400-500
- Reddit MonoFigures and code: entity counts, step numbers and axis ticks 13px
Patterns
- warm near-black canvas with framed column rules
- announcement row under nav with 'New' chip
- split hero: headline left, WebGL particle ribbon right
- light solid + dark outlined button pair
- numbered three-step strip (connect, map, ask)
- wordmark marquee with trust caption
- two-tone statement heading (muted then bright)
- natural-language query box with results card
- product module rows: title, paragraph, three icon bullets, 'explore more' link, visual right
- source list cards with live/syncing/pending status dots
- big-number stats
- FAQ
- closing CTA with newsletter
States it is designed for
- WebGL unsupported or reduced motion: static rendered image of the ribbon
- Query demo: typing, loading shimmer, results, zero results message
- Status dots: live, syncing, pending, error (red with label)
- Subscribe: invalid, submitting, success, error
- Blog/changelog: empty filter state
- Long entity names truncate with ellipsis and full name in a tooltip
Who it is for
- RevOps and business operations leads
- Data and analytics engineers
- Founders at data-heavy SaaS companies
- Customer success leaders tracking churn signals
Layout
- Nav: logo left, Features and Resources dropdowns, Pricing, About; light 'Get started' button right; thin rule under nav; hamburger on mobile
- Announcement row: 'New' chip, separator dots, one-line feature announcement, bounded by a rule on the left half
- Hero split: 72px bold two-line headline, muted paragraph, light 'Connect a source' + dark outlined 'Book a demo'; right a WebGL/particle ribbon drifting slowly
- Steps strip: '1. Connect / 2. Map / 3. Ask' each with a short line and a progress sweep underline
- Trust caption + grayscale wordmark marquee
- Statement: two-tone heading (problem in muted gray, answer in white)
- Query demo: input-like card with a question and result count, results list with risk tags, export/share chips; particle mesh behind
- Module rows (graph, ask, monitoring): title, paragraph, three icon bullets, 'Explore more' link; right visual (source cards with status dots, chat answer, alert feed)
- Integrations: 'connect your stack' grid of source tiles
- Outcome stats row (big numbers), FAQ accordion, closing CTA 'data connected' with subscribe form, footer
- Framed layout: vertical rules at container edges and some horizontal half-width rules; mobile hides rules and stacks the ribbon above the headline
Palette
moody, technical, precise, quiet, intelligent. A dark lab where scattered threads of data knot into one glowing line.
- canvas (warm black)
#110f0d - card surface
#1c1917 - raised surface / rules (decorative)
#292524 - primary text
#fafaf9 - muted text
#a6a09b - dim text (accessible fix)
#89807a - light button fill
#f5f5f4 - input border / outlined button
#6a655f - live status green
#10ec90 - syncing status blue
#38bdf8 - pending status amber
#f59e0b
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | primary text on canvas | 18.31:1 | 4.5:1 |
| Aa | muted text on card | 6.76:1 | 4.5:1 |
| Aa | dim text on canvas | 4.95:1 | 4.5:1 |
| Aa | dim text on card | 4.52:1 | 4.5:1 |
| Aa | label on light button | 16.03:1 | 4.5:1 |
| live status dot on card | 11.18:1 | 3:1 | |
| syncing status dot on card | 8.16:1 | 3:1 | |
| pending status dot on card | 8.14:1 | 3:1 | |
| input border on canvas | 3.31:1 | 3:1 | |
| focus ring (light) on canvas | 17.53: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 scale
- Display
- Mozilla Headline 700 (similar to the observed bold grotesk), 72px hero with -0.03em tracking, 1.0 line-height
- Body
- Mozilla Text 400-500, 16px / 1.6 (observed 12-14px raised); section headings Mozilla Text 600 32px with -0.01em
Reddit Mono 13px for entity counts, step numbers and axis ticks. Two-tone headings: first clause #a6a09b, second #fafaf9.
Spacing and imagery
Structured and spacious: 1120px framed container with 1px vertical rules; section padding 120-160px; cards 12px radius; buttons 8px radius; chips 999px. No shadows; depth via particle fields and slightly lighter surfaces.
Generative white particle ribbons and point-cloud meshes on black; UI fragments (query box, result rows with risk tags, source cards with status dots); small line icons; grayscale wordmarks.
Components
- Dropdown nav
- Announcement row
- Particle ribbon canvas
- Button pair (light solid, dark outlined)
- Numbered step strip with sweep underline
- Wordmark marquee
- Two-tone statement heading
- Query box with results card and export chips
- Module row with icon bullets and explore link
- Source card with status dot and entity count
- Integration tile grid
- Stat figure
- FAQ accordion
- Subscribe form
Interactions
- Particle ribbon rotates slowly and reacts subtly to pointer; pauses when off-screen
- Step strip underline sweeps across each step in sequence
- Query box types out a sample question, then results fade in row by row
- Source cards gently blink their status dot every few seconds
- Dropdown menus open on click/Enter with arrow-key navigation
- Buttons: light button dims slightly; outlined button fills with the surface colour on hover
Data
Source{id, name, kind (crm|billing|warehouse|support|analytics), entity_count, status (live|syncing|pending|error)}QueryExample{question, results[{account, risk (high|medium|low), signal}]}Module{slug, title, body, bullets[{icon, text}], visual}Stat{value, label}Post{slug, title, excerpt, published_at}ChangelogEntry{date, title, body}Job{title, team, location}Subscriber{email, created_at}
Guardrails
Experience
- The hero visual is atmosphere; keep the headline and CTAs readable at every width
- Use invented source names and entity counts; never real tool brands
- Every module row pairs claims with a concrete UI fragment
- Status is always text + dot, never dot alone
- Keep one light primary button per view
Accessibility
- Body copy 16px minimum; mono labels 13px minimum
- Dim text uses #89807a; #a6a09b for secondary copy
- Particle canvas is aria-hidden with a pause toggle and a static fallback
- Typed-out query demo is also present as static text for screen readers
- Dropdown menus follow the Radix NavigationMenu keyboard pattern
Security
- Subscribe and demo forms post to an Edge Function with zod validation, honeypot and rate limit
- RLS on subscribers and demo_requests: no anon read
- Query demo is canned data; no live queries against any source from the marketing site
- Content Security Policy allows only self-hosted WebGL assets and scripts
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 the marketing site for **Loomgraph**, an AI data platform that links a company's tools (CRM, billing, support, warehouse) into a living knowledge graph and answers plain-language questions across them. The site should feel like a dark, precise lab: generative particle ribbons, framed columns and sharp UI fragments that show a question turning into an answer.
### Stack
Next.js (App Router) with React and TypeScript, Tailwind CSS, shadcn/ui on Radix (NavigationMenu, Accordion), lucide-react, Motion for sequence animations, a small WebGL/Canvas particle component (hand-written with plain WebGL or a lightweight open-source 3D library) and react-hook-form + zod. Supabase Edge Function for subscribe/demo requests.
### Pages & layout
1. **Home**: nav with dropdowns; announcement row; hero split (72px headline, paragraph, "Connect a source" + "Book a demo"; particle ribbon right); three-step strip; trust caption + wordmark marquee; two-tone statement; query demo card with results and export chips; three module rows (graph, ask, monitoring) each with bullets and a visual; integrations grid; stats; FAQ; closing CTA with subscribe; footer.
2. **Feature pages** (one per module), **Pricing**, **About**, **Blog**, **Changelog**, **Careers**, **Integrations**, **Contact / demo**.
Desktop frames content with 1px vertical rules at the container edges; mobile removes rules, puts the ribbon above a centered headline and stacks module visuals under text.
### Design system
- Colors: `--canvas: #110f0d`, `--card: #1c1917`, `--raised: #292524` (rules, decorative), `--fg: #fafaf9`, `--muted: #a6a09b`, `--dim: #89807a`, `--btn-light: #f5f5f4`, `--on-light: #1c1917`, `--input-border: #6a655f`, `--live: #10ec90`, `--syncing: #38bdf8`, `--pending: #f59e0b`, `--ring: #f5f5f4`.
- Fonts: Mozilla Headline 700 for H1 (72px/1.0, -0.03em); Mozilla Text 600 for H2 (32px); Mozilla Text 400-500 body 16px/1.6; Reddit Mono 13px for counts and step numbers.
- Spacing: 8px base; sections 128px / 80px mobile; container 1120px.
- Radius: cards 12px, buttons 8px, chips 999px.
- Shadows: none.
- Motion: ribbon rotation 0.02 rad/s; typed query 40ms per character; result rows stagger 80ms; step sweep 2.4s per step.
### Components & interactions
NavDropdown, AnnouncementRow, ParticleRibbon (IntersectionObserver pauses off-screen; pause button; static PNG fallback), ButtonPair, StepStrip, WordmarkMarquee, TwoToneHeading, QueryDemo (typed question, result rows with risk tag, export/share chips), ModuleRow (reversible), SourceCard (name, mono entity count, status dot + label), IntegrationGrid, StatFigure, FaqAccordion, SubscribeForm.
### Data & state
Static JSON: sources with invented names ("Harborline CRM", "Quillbooks"), query examples, modules, stats (labelled as sample), FAQ. Query demo state machine: idle → typing → loading → results | empty. Subscribe states: idle, invalid, submitting, success, error.
### Accessibility
Body 16px+, mono 13px+. Canvas `aria-hidden`, with a visible pause toggle; reduced motion swaps to the static image and disables typing and sweeps. Two-tone headings are one heading element. Status uses dot + text. Focus ring 2px `--ring` with 2px offset.
Verified contrast: primary text on canvas: #fafaf9 on #110f0d = 18.31:1; muted text on card: #a6a09b on #1c1917 = 6.76:1; dim text on canvas: #89807a on #110f0d = 4.95:1; dim text on card: #89807a on #1c1917 = 4.52:1; label on light button: #1c1917 on #f5f5f4 = 16.03:1; live status dot on card: #10ec90 on #1c1917 = 11.18:1; syncing status dot on card: #38bdf8 on #1c1917 = 8.16:1; pending status dot on card: #f59e0b on #1c1917 = 8.14:1; input border on canvas: #6a655f on #110f0d = 3.31:1; focus ring (light) on canvas: #f5f5f4 on #110f0d = 17.53:1.
### Security
Forms post to an Edge Function (zod, honeypot, per-IP rate limit, service-role insert); `subscribers` and `demo_requests` have RLS with no anon select/update/delete. Query demo is canned; no connectors run from the marketing site. Strict CSP; WebGL shaders bundled locally.
### Performance & SEO
Load the particle component after first paint with `requestIdleCallback`; cap particles by device memory; render at devicePixelRatio ≤ 1.5. Static pages with unique meta and OG images; RSS for blog and changelog. Target LCP under 2s with the headline as LCP element.
### Guardrails
- No real company wordmarks or tool logos; invent them.
- Don't claim specific model vendors or accuracy numbers.
- Keep the particle effect subtle; never behind body text.
- Acceptance criteria:
- [ ] Hero readable and interactive before WebGL loads
- [ ] Query demo and step strip work with reduced motion (static)
- [ ] Dropdowns and FAQ are keyboard operable
- [ ] Contrast pairs pass