Template
Emberlens
A dark, gallery-forward marketing site for a text-to-image and image-to-image generator. It sells creators and small studios on speed and prompt tooling, shows real-looking outputs up front, and routes them to a three-tier subscription or an API trial.
AI image-generation 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
League Spartan is a sturdy geometric grotesk whose 700 keeps its shape at 72px on the near-black canvas and stays plain at 16px, so the generated images keep all the colour.
- League SpartanHeadings: H1 72px / 44px mobile 700, -0.01em; H2 48px 700; pricing figures 44px 700
- League SpartanBody: body 16px/1.5, lede 20px 400/500, card titles 20px 600
Patterns
- split hero with staggered image mosaic
- gradient pill CTA
- logo strip
- three-up mock-UI feature cards
- numbered vertical stepper beside image collage
- masonry prompt gallery
- segmented control text/image mode switch
- pricing toggle monthly/yearly with savings badge
- highlighted middle pricing card
- FAQ accordion
- testimonial cards
States it is designed for
- image tiles show a shimmer skeleton on the surface colour until loaded
- broken image falls back to a gradient placeholder with alt text caption
- gallery 'load more' button with loading spinner and 'no more images' end state
- copy-prompt success toast ('Prompt copied')
- contact/demo form: inline validation, disabled submit while sending, success and retryable error messages
- reduced-motion: mosaic drift and scroll reveals disabled
- long prompts truncated to three lines with full text in the overlay
Who it is for
- independent creators and illustrators
- social media and content marketers
- small product studios needing mockups
- developers evaluating an image API
Layout
- sticky transparent top bar: wordmark left, centred links with a Pages dropdown, gradient pill 'Request demo' right; collapses to a hamburger sheet under 768px
- hero: left column H1, one-line lede, gradient primary pill + outlined secondary pill, small 'no card needed' note; right column two staggered rows of portrait tiles bleeding off the right edge (stacks below text on mobile, horizontally scrollable)
- 'featured in' heading with five greyscale partner logos (wraps to 2-3 per row on mobile)
- feature intro: centred H2 + lede, three cards each holding a mini product UI (prompt box, recent prompts, keyword chips) with a title and two-line caption
- how-it-works: rounded dark panel with a 4-step numbered vertical stepper (violet circles joined by a line) left and an overlapping image collage right; stacks on mobile
- gallery: centred heading, masonry grid of generated images that reveal their prompt on hover/focus, single gradient CTA below
- mode explainer: segmented control 'Text to image / Image to image' switching a portrait-plus-floating-panel illustration and a two-paragraph description
- pricing: heading, monthly/yearly toggle with 'save 25%' badge, three cards (middle card filled with violet gradient), check-list rows, full-width CTA
- FAQ accordion, then testimonial card grid
- footer CTA band and compact footer with links
Palette
Nocturnal, vivid, gallery-like: a near-black violet canvas lets saturated generated images and one indigo-to-violet gradient do all the talking.
- canvas
#0f0b18 - surface
#1d1926 - raised card
#2a292d - text
#ffffff - muted text
#d6d6d6 - indigo accent / gradient start
#5563ff - violet gradient end
#9f40ff - light violet link text
#8b93ff - input border
#67666a
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text | 19.42:1 | 4.5:1 |
| Aa | muted text on surface | 11.85:1 | 4.5:1 |
| Aa | primary pill label (gradient start) | 4.55:1 | 4.5:1 |
| Aa | primary pill label (gradient end) | 4.51:1 | 4.5:1 |
| link / focus ring | 7.13:1 | 3:1 | |
| input border | 3.41:1 | 3:1 | |
| input border on surface | 3.02: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
- League Spartan 700, 72px desktop / 44px mobile, line-height 1.1, tracking -0.01em (similar to the observed geometric grotesk)
- Body
- League Spartan 400/500, 18-20px lede, 16px body, line-height 1.5
Section H2 48px/700; card titles 20px/600; pricing figures 44px/700 with 16px '/mo' suffix; nothing below 12px.
Spacing and imagery
Density: airy marketing rhythm, 120px section padding desktop, 72px mobile Grid: 12-column, 24px gutter Container: 1200px max, 40px side padding (16px mobile) Radius: cards 24px, image tiles 16px, buttons fully rounded Shadows: none on dark; depth from surface steps and a soft violet glow behind the featured pricing card
Full-bleed generated portraits and scenes in 16px-rounded tiles; mini product UI cards rendered as live HTML (not screenshots); dotted grid ornaments on pricing cards; outline icons at 20px.
Components
- top bar with Pages dropdown and mobile sheet
- gradient pill button
- outlined pill button
- staggered image mosaic
- partner logo strip
- mock prompt-box card
- keyword chip group
- numbered vertical stepper
- image collage
- masonry gallery tile with prompt reveal
- segmented control
- billing toggle with savings badge
- pricing card (default / featured)
- FAQ accordion
- testimonial card
- footer CTA band
Interactions
- image tiles fade and rise 16px on scroll into view (60ms stagger)
- gallery tile hover/focus shows prompt overlay with 'copy prompt' button
- segmented control slides its pill indicator (200ms) and cross-fades the illustration
- billing toggle animates price numbers and updates '/mo' vs '/yr' text
- accordion rows expand with height animation and rotate a plus icon
- buttons brighten gradient on hover and show a 2px light-violet focus ring
- hero mosaic columns drift slowly vertically; paused on hover and under reduced motion
Data
Plan{id, name, monthlyPrice, yearlyPrice, features[], highlighted (bool), ctaLabel}GalleryItem{id, imageUrl, alt, prompt, mode (text|image), aspect (portrait|square|landscape)}Step{order, title, body}Faq{question, answer}Testimonial{quote, name, role, avatarUrl}DemoRequest{name, email, company, useCase, createdAt}
Guardrails
Experience
- Show real output images above the fold so the product's value is visible before any copy.
- Keep one gradient style for primary actions only; secondary actions are outlined pills.
- The billing toggle must change every price and the billing note at once, with the saving stated in words.
- Gallery overlays show the prompt text and a copy button; never hide the prompt behind hover only.
- On mobile the hero mosaic becomes a horizontal snap-scroll strip below the CTAs, not a squeezed grid.
- Limit the featured pricing card to one; label it 'Most popular' in text, not just colour.
Accessibility
- Every generated image has descriptive alt text derived from its prompt.
- Segmented control uses role=tablist semantics with arrow-key navigation.
- Billing toggle is a real switch (role=switch, aria-checked) with a visible text label.
- Focus ring: 2px #8b93ff outline with 2px offset on every interactive element.
- Respect prefers-reduced-motion by stopping mosaic drift and scroll reveals.
- White labels sit on the gradient only where both ends pass 4.5:1 (#5563ff and #9f40ff).
Security
- Demo-request form validated with zod client- and server-side; reject unknown fields.
- Rate-limit the form endpoint per IP and add a honeypot field.
- Store demo requests in a Supabase table with RLS: insert-only for anon, select for staff role only.
- Never expose API keys for the image model on the marketing site; the 'try API' link goes to the authenticated app.
- Serve gallery images from a public bucket with no user-uploaded content on this site.
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 **Emberlens**, a dark marketing site for an AI image generator that turns short prompts or a reference photo into finished visuals. The page must make visitors *see* output quality in the first screen, explain the four-step flow, show a browsable gallery of sample images with their prompts, and convert to one of three monthly plans or an API trial. All copy and sample images are original; people in images are generated or stock with permission. ### Stack Astro + TypeScript with React islands for interactive parts, Tailwind CSS, shadcn/ui (Radix) primitives for Tabs, Switch, Accordion, Dialog and Sheet, lucide-react icons, Motion for reveals and the mosaic drift. zod validates the demo-request form; a Supabase table stores requests. Images are optimised with Astro's image pipeline (AVIF/WebP, responsive srcset). ### Pages & layout 1. **Home** (single long page): top bar → split hero (copy left, two staggered rows of portrait tiles right that bleed off-canvas) → 'featured in' logo strip → three mock-UI feature cards → how-it-works panel (4-step numbered stepper + image collage) → masonry gallery with prompt overlays and a 'Generate your own' CTA → text/image mode explainer with a segmented control → pricing (toggle + 3 cards, middle featured) → FAQ accordion → testimonial grid → footer CTA band → footer. 2. **About** and **Contact / Request demo** (form: name, work email, company, use case select, message). 3. Breakpoints: ≥1024px two-column hero and 3-up cards; 768-1023px 2-up cards and hero stacked; <768px everything single column, mosaic turns into a snap-scrolling strip, top links move into a Sheet. ### Design system - Colors: `--canvas: #0f0b18`, `--surface: #1d1926`, `--raised: #2a292d`, `--text: #ffffff`, `--muted: #d6d6d6`, `--accent: #5563ff`, `--accent-2: #9f40ff`, `--link: #8b93ff`, `--border: #67666a`. - Gradient: `linear-gradient(90deg, var(--accent), var(--accent-2))` for primary pills and the featured pricing card only. - Fonts: League Spartan (similar to the observed geometric grotesk) 700 for H1 72/44px and H2 48/32px, 600 for card titles 20px; body 16px/1.5, lede 20px/1.5; smallest label 12px. - Spacing: 4px base; section padding 120px (72px mobile); card padding 24px; grid gutter 24px. - Radius: 24px cards and panels, 16px image tiles, 9999px buttons and toggles. - Shadows: none; featured pricing card gets `0 0 60px rgba(159,64,255,.35)` glow. - Motion: 250ms ease-out reveals with 60ms stagger; 200ms indicator slides; mosaic drift 40s linear loop. ### Components & interactions TopBar (Pages dropdown via Radix DropdownMenu; Sheet on mobile), GradientButton / OutlineButton, HeroMosaic (two offset columns, lazy images, pause on hover), LogoStrip (greyscale SVG placeholders, 60% opacity), FeatureCard with embedded MiniPromptBox / RecentPrompts / KeywordChips rendered in HTML, Stepper (ordered list with numbered circles and connecting line), Collage, GalleryMasonry (CSS columns; each tile a button that opens a Dialog with the full image, prompt text and 'Copy prompt'), ModeSwitch (Tabs styled as a segmented control, cross-fading illustration), BillingToggle (Switch + 'Save 25%' badge), PricingCard (default and featured variants, check rows with lucide Check icons), FaqAccordion, TestimonialCard, CtaBand, Footer. Hover states brighten backgrounds by one step; all focus states use the light-violet ring. ### Data & state Content lives in typed collections: `plans`, `galleryItems`, `steps`, `faqs`, `testimonials` (Astro content collections validated by zod). Billing period is local island state and mirrored to `?billing=yearly` so shared links keep the choice. Gallery paginates 12 items at a time from the collection. Demo requests POST to a server endpoint that validates with zod and inserts into `demo_requests`. ### Accessibility Use one H1; sections are landmarks with headings. Gallery tiles are buttons with alt text and an accessible name that includes the prompt's first words. The mode switch is a tablist; the billing control is a labelled switch and prices announce via aria-live=polite when they change. All images of people have neutral descriptive alt text. Honour reduced motion. Minimum text size 12px; body 16px at line-height 1.5. Verified contrast: body text: #ffffff on #0f0b18 = 19.42:1; muted text on surface: #d6d6d6 on #1d1926 = 11.85:1; primary pill label (gradient start): #ffffff on #5563ff = 4.55:1; primary pill label (gradient end): #ffffff on #9f40ff = 4.51:1; link / focus ring: #8b93ff on #0f0b18 = 7.13:1; input border: #67666a on #0f0b18 = 3.41:1; input border on surface: #67666a on #1d1926 = 3.02:1. ### Security Enable RLS on `demo_requests`: anon may insert only; select/update/delete limited to a `staff` role. Validate and length-limit every field server-side, strip HTML, add a honeypot and per-IP rate limit (5/min). No model or storage secrets reach the browser; only the anon key is public. Serve a strict CSP (self + image CDN). ### Performance & SEO Preload the first two hero images only; lazy-load the rest with fixed aspect ratios to avoid layout shift. Ship React only for interactive islands. Title, meta description, Open Graph image and SoftwareApplication + FAQPage structured data. Target LCP < 2.5s on 4G and Lighthouse 90+. ### Guardrails - Write fresh headlines and generic partner logos; never reuse another product's name, images or copy. - Do not show images of real, identifiable people without rights; prefer generated or licensed stock. - Pricing figures are placeholders and clearly editable in one data file. - Keep the gradient for primary actions and the featured plan only. **Acceptance criteria** - [ ] Hero shows sample outputs within the first viewport at 390px and 1440px - [ ] Gallery tiles open a dialog with prompt text and a working copy button - [ ] Billing toggle updates all three prices and announces the change - [ ] Demo form validates, rate-limits and stores a row visible only to staff - [ ] Lighthouse accessibility score ≥ 95 and no contrast failures