2 cases built from this template
Same prompt, different [VARIABLES]. Click one to preview it above.About this template
This is a dark, cinematic landing page for an AI image generator, built with React, Tailwind CSS and Motion. The first screen does the selling: a glass prompt box types an example prompt letter by letter, a Generate button fills a progress bar, and the large image beside it dissolves into a matching picture through a small hand-written WebGL shader. Five prompt and image pairs loop, and visitors can jump between them with the thumbnail strip. Below the hero, the page follows the order people expect from a generative product: a strip of product facts, three how-it-works cards with small interface mocks, a feature bento, a before and after slider with three finishing modes, a masonry gallery, credit-based pricing, an FAQ and a sign-up band over a blurred collage of results.
It suits founders and indie developers launching an image, avatar, upscaling or concept art tool, and anyone who wants a polished page for a credit-based creative app. The palette is near-black with soft off-white text and one violet-to-coral gradient kept for buttons, focus rings, the caret and the highlighted plan. Gallery tiles dim on hover to reveal the exact prompt, a style tag and a copy button, and style chips reflow the masonry with smooth layout motion. The comparison slider works with pointer and keyboard. Reduced-motion users get full prompts, static images and a manual next button.
To adapt it, change the brand, the product description, the audience and the name of the usage unit; the prompt asks the builder to rewrite every headline, plan and answer to fit. Pricing math is spelled out (cost per draft, standard and HD image), so swapping in your own numbers is quick. The six images share one dusk-lit look, and four gallery tiles are abstract art drawn in canvas.
The template prompt
The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].
# AI Image Generator Landing Page
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
A one-page, dark, cinematic landing page for [BRAND], [PRODUCT]. The first screen is a working-looking product moment: a glass prompt box types example prompts letter by letter while the large image beside it dissolves into a matching picture through a hand-written WebGL noise-displacement shader. The page then proves the product with a stats strip, a three-step how-it-works with small UI mocks, a feature bento, a draggable before/after slider, a filterable masonry gallery that reveals the prompt behind each image, credit-based pricing, an FAQ and a sign-up band over a blurred collage of results.
- Audience: [AUDIENCE] who want finished images from a sentence without learning a complex tool, and founders or indie developers launching a generative product (image, video, avatar or upscaler apps) who need a believable landing page.
- Goal: Show the product working within two seconds, make the credit pricing easy to understand, and turn visitors into sign-ups through the 'Start free' buttons and the email field in the final CTA band.
- Tone: Calm, confident and concrete. Short sentences, plain verbs, real numbers (render times, pixel sizes, credit costs). No hype words like 'revolutionary', 'unleash' or 'magic'; let the images and the live prompt do the selling.
## 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 (ISC), tailwindcss (MIT), postcss (MIT), autoprefixer (MIT), vite (MIT), @vitejs/plugin-react (MIT), typescript (Apache-2.0), @fontsource-variable/bricolage-grotesque (OFL-1.1), @fontsource-variable/dm-sans (OFL-1.1), @fontsource-variable/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 page: index.html at the project root with entry src/main.tsx. package.json scripts: dev 'vite', build 'tsc -b && vite build', preview 'vite preview'.
- vite.config.ts: base './', plugins [react()], build { outDir 'dist', sourcemap false, assetsInlineLimit 0 }. Images live in public/images/ and are referenced as './images/<file>' so they work under any sub-path. Do not copy src/ into dist/.
- Tailwind 3.4 through PostCSS (tailwindcss + postcss + autoprefixer), content ['./index.html', './src/**/*.{ts,tsx}']. In tailwind.config.ts add every Design color to theme.extend.colors with kebab-case keys (void, panel, raised, lifted, line, line-strong, text, muted, faint, violet, orchid, coral, mint) and fontFamily display ['Bricolage Grotesque Variable', 'system-ui', 'sans-serif'], sans ['DM Sans Variable', 'system-ui', 'sans-serif'], mono ['JetBrains Mono Variable', 'ui-monospace', 'monospace']; maxWidth { container: '1200px' }; borderRadius { tile: '24px', card: '20px', thumb: '16px' }; backgroundImage { accent: 'linear-gradient(100deg, #8E6CFF 0%, #C86BD8 50%, #FF7A59 100%)' }.
- src/fonts.ts imports the three Fontsource packages; src/main.tsx imports src/fonts.ts and src/index.css. index.css holds the Tailwind layers, body background #0B0B10 and color #F2F0EC, the .glass recipe, the .text-gradient and .border-gradient utilities, the caret 'blink' and 'shimmer' keyframes, and a @media (prefers-reduced-motion: reduce) block that disables CSS animations and transitions longer than 0.01ms.
- File layout: src/content.ts (all copy and data, typed), src/lib/brand.ts (brandSlug, emailDomain, companyName, creditSingular), src/lib/useReducedMotion.ts (matchMedia hook), src/lib/random.ts (mulberry32), src/lib/clipboard.ts, src/hero/morphShader.ts (WebGL setup and GLSL strings), src/hero/useHeroLoop.ts (state machine), src/hero/Hero.tsx, src/hero/PromptBox.tsx, src/hero/ImagePanel.tsx, src/art/drawTiles.ts (the four code-drawn canvases), src/components/ (Header.tsx, MobileMenu.tsx, StatsStrip.tsx, HowItWorks.tsx, Bento.tsx, CompareSlider.tsx, Gallery.tsx, GalleryTile.tsx, Pricing.tsx, BillingToggle.tsx, Faq.tsx, CtaBand.tsx, Footer.tsx, SectionHeader.tsx, Button.tsx, Reveal.tsx), src/App.tsx composing them in page order.
- Morph shader (src/hero/morphShader.ts), plain WebGL1, no libraries: a full-screen quad; uniforms uFrom, uTo (sampler2D), uProgress (0..1), uZoom (1.00..1.04), uRes (canvas px), uFromSize, uToSize (image natural px). Compute cover-fit UVs per texture (scale so the image fills the canvas aspect, centered) and apply uZoom around the center. Noise: 2D value noise with 4-octave fbm. In the fragment shader: n = fbm(uv * 3.0); t = n * 0.75 + (1.0 - uv.y) * 0.25; m = smoothstep(uProgress - 0.1, uProgress + 0.1, t) (1 = still showing uFrom); displace the from-UV by (n - 0.5) * 0.10 * uProgress and the to-UV by (n - 0.5) * 0.10 * (1.0 - uProgress); color = mix(texture(uTo), texture(uFrom), m); add an edge glow where the dissolve front is: glow = (1.0 - smoothstep(0.0, 0.05, abs(t - uProgress))) * step(0.001, uProgress) * step(uProgress, 0.999); color += glow * 0.55 * mix(vec3(0.557, 0.424, 1.0), vec3(1.0, 0.478, 0.349), uv.x). Load the five hero images as textures (UNPACK_FLIP_Y_WEBGL true, CLAMP_TO_EDGE, LINEAR) after all have decoded; size the canvas with a ResizeObserver at devicePixelRatio capped at 2; render only while a transition or the zoom hold is running and the hero is visible. If WebGL is unavailable or a context is lost, fall back to two stacked <img> elements crossfading opacity over 700ms.
- Reveal.tsx wraps sections in Motion whileInView fade-up (opacity 0 -> 1, y 24 -> 0, duration 0.6, ease [0.22, 1, 0.36, 1], viewport once with amount 0.2) and renders children unanimated when reduced motion is on. Wrap the app in MotionConfig reducedMotion='user'.
- index.html: lang en, <meta name='theme-color' content='#0B0B10'>, <link rel='icon' href='./favicon.svg' type='image/svg+xml'>, <title>[BRAND] — Type a sentence, get the picture</title>. public/favicon.svg is the logo mark (gradient rounded square with the tilted off-white frame).
- Download the six images with the curl commands under Assets into public/images/ before building, and write ASSETS.md at the project root as described under Assets.
- dist/ holds index.html, hashed JS/CSS, the woff2 files, favicon.svg and the six images; it should stay under 5 MB.
## Variables
- [BRAND] — Brand name (default: "Driftframe"). Invented product name. Used in the wordmark, page title, hero subhead, gallery heading, FAQ, footer and the email domain. Never a real AI product, model family or company.
- [PRODUCT] — What the product is (default: "an AI image generator that turns one sentence into a print-ready picture"). One lowercase phrase that completes '[BRAND] is ...'. Drives the hero subhead, step copy, features and FAQ. Any generative visual product fits: avatars, upscaling, concept art, product shots.
- [AUDIENCE] — Who it is for (default: "designers, marketers and indie creators"). Plural noun phrase. Used in the hero subhead and footer line; feature and FAQ examples adapt to it.
- [CREDIT_NAME] — Usage unit (plural) (default: "credits"). The plural word for what users spend per render, e.g. credits, sparks, tokens. Used on the Generate button, pricing headlines, the credit explainer, the CTA and FAQ; the singular drops the trailing s.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/ai-image-generator-landing-page 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.
## Design
### Colors
- void `#0B0B10` — Page background, text on gradient buttons
- panel `#12121A` — Cards, tiles, prompt box base, chips
- raised `#1A1A25` — Inputs, hover fills, checkerboard dark squares
- lifted `#15141F` — Highlighted Creator plan background
- line `#FFFFFF14` — Hairline borders and dividers (white at 8%)
- line-strong `#FFFFFF26` — Glass panel borders, image frames, ghost buttons (white at 15%)
- text `#F2F0EC` — Primary text, light buttons, handle line
- muted `#A3A1AD` — Body copy, nav links, labels
- faint `#6B6977` — Captions, footnotes, mono labels
- violet `#8E6CFF` — Gradient start, glows, cursor light
- orchid `#C86BD8` — Gradient midpoint
- coral `#FF7A59` — Gradient end, section labels, errors, 'Rendering' state
- mint `#5BD6A0` — Success states and paid-plan check icons only
- accent gradient `linear-gradient(100deg, #8E6CFF 0%, #C86BD8 50%, #FF7A59 100%)` — Used sparingly: primary buttons, focus rings, caret, highlighted plan border, gradient text in H1/H2 phrases and key numbers
### Typography
- Display: H1 clamp(40px, 5.4vw, 76px) line-height 1.02 letter-spacing -0.035em weight 650; H2 clamp(34px, 4vw, 54px) line-height 1.06 letter-spacing -0.03em weight 600; card titles 22px weight 600; big numbers: Bricolage Grotesque Variable (OFL), weights 500/600/650/700
- Text: body 16px/1.6, subheads 17-18px, nav 14px, buttons 14-15px weight 600: DM Sans Variable (OFL), weights 400/500/600
- Mono: prompt text, seeds, section labels (12px, letter-spacing 0.14em, uppercase), credit numbers, chips: JetBrains Mono Variable (OFL), weights 400/500/600
### Layout & motion
- Spacing: 8px base. Container max-width 1200px with 24px side padding (20px below 640px). Sections 112px vertical padding on desktop, 80px on mobile. 12-column grid with 20-48px gaps. Section header blocks have 56px space below them. Cards pad 24-32px.
- Radius: Bento tiles, image panel, slider frame and plan cards 24px; step cards and FAQ card 20px; prompt box 20px; gallery tiles 16px; small thumbnails 10px; inputs inside panels 14px; every button, chip, tab and toggle is a full pill (999px).
- Motion: Hero loop: type 30ms/char, hold 450ms, generate 1400ms progress with shimmer, WebGL noise-dissolve morph 1200ms easeInOutCubic, show 2600ms with 1.00 -> 1.04 zoom, erase 12ms/char; pauses off screen and in hidden tabs.
- Motion: Blinking gradient caret (1s steps) in the prompt box.
- Motion: Cursor-following violet glow and gradient border ring on the prompt box; soft white pointer spotlight on bento tiles (hover devices only).
- Motion: Scroll reveals: fade up 24px, 0.6s, ease [0.22, 1, 0.36, 1], once, stagger 0.05-0.1s.
- Motion: Gallery: tiles lift 4px and zoom image to 1.04 on hover, prompt overlay fades in; filter changes reflow with Motion layout springs.
- Motion: Before/after: one-time hint sweep of the handle when first in view; drag with pointer or keyboard.
- Motion: Pricing numbers slide on billing toggle; FAQ answers animate height; CTA collage drifts slowly.
- Motion: prefers-reduced-motion: no typing, shader zoom, shimmer, glow, hint sweep, layout animation or drift; hero shows full prompts with a manual 'Next prompt' button and instant image swaps.
- Imagery: Six generated images in one consistent look: cinematic digital renders with photographic realism, dusk light with deep violet shadows and warm coral highlights, soft haze and glowing practical lights, no people and no text. They appear as hero morph targets, step and bento visuals, the before/after subject, gallery tiles and the blurred CTA collage. Four extra gallery tiles are abstract art drawn in canvas with the same violet/orchid/coral palette. All UI mocks (prompt fields, chips, toggles, export panel, batch table) are built in HTML/CSS. No stock photos, no faces, no logos.
## Pages & Sections
### Home (`index.html`)
1. **Content file and copy rules** — All copy in this prompt is written for the default values ([BRAND] = Driftframe, [PRODUCT] = an AI image generator that turns one sentence into a print-ready picture, [AUDIENCE] = designers, marketers and indie creators, [CREDIT_NAME] = credits). Put every string, number, prompt, gallery item, stat, feature, plan, FAQ answer and footer link in src/content.ts and render from it; components contain no copy. If any variable value differs, rewrite every headline, subhead, step, feature, stat label, plan bullet, FAQ answer and CTA so it is specific and believable for the new product and audience, keeping the same structure, item counts and approximate lengths. The six images never change, so when you rewrite the hero and gallery prompts, each prompt must still describe what its image actually shows (only the framing and vocabulary change). [CREDIT_NAME] is the plural usage unit; use it everywhere the word credits appears (pricing headline numbers, the Generate button cost, the credit explainer, FAQ) and derive the singular by dropping a trailing 's'. Derived values in src/lib/brand.ts: brandSlug = [BRAND] lowercased with every run of non-alphanumeric characters replaced by '-'; emailDomain = brandSlug without hyphens + '.com' (driftframe.com); companyName = [BRAND] + ' Labs, Inc.'. Company facts used in the footer and FAQ: 418 Halden Street, Studio 3, Portland, OR 97209; hello@ + emailDomain; support@ + emailDomain. Every number on the page is an invented product fact for the invented brand; there are no user counts, customer logos or testimonials.
Layout: No visual output. content.ts exports typed objects: brand, nav, hero (pairs), stats, steps, features, compare (tabs), gallery (filters, items), pricing (plans, creditCosts), faq, cta, footer. Section order on the page: Header, Hero, Stats strip, How it works, Feature bento, Before/after, Gallery, Pricing, FAQ, CTA band, Footer.
2. **Header (shared, sticky)** — Left: logo mark + wordmark '[BRAND]' (Bricolage Grotesque 650, 20px, letter-spacing -0.02em). Logo mark: 26px inline SVG, a rounded square (rx 8) filled with the accent gradient (100deg #8E6CFF -> #C86BD8 -> #FF7A59), inside it an off-white (#F2F0EC) 12px-wide rounded rectangle outline (stroke 2) rotated -8deg with a 3px off-white dot at its top-right corner, like a tilted photo frame. Center nav links (DM Sans 500, 14px, #A3A1AD, hover #F2F0EC): How it works (#how), Features (#features), Gallery (#gallery), Pricing (#pricing), FAQ (#faq). Right: text link 'Log in' (href #cta, #A3A1AD) and a gradient pill button 'Start free' (href #cta).
Layout: Fixed top, height 68px, full width; inner container max-width 1200px, padding-x 24px, flex justify-between items-center. Transparent at scroll 0; after 12px of scroll it gets background rgba(11,11,16,0.72), backdrop-filter blur(14px) saturate(140%) and a 1px bottom border #FFFFFF14 (transition 200ms). Below 900px: nav and Log in hide; show 'Start free' (small, height 36px) and a 40px icon button with Lucide Menu that opens a full-width sheet sliding down from under the header (background #12121A, border-bottom #FFFFFF14) listing the five nav links at 18px with 56px row height plus a full-width 'Start free' button; X icon closes it, Escape closes it, tapping a link closes it. All anchors scroll smoothly with a 72px top offset (scroll-margin-top on sections).
Motion: Sheet: Motion height/opacity 220ms ease-out. Header background change is a CSS transition. No motion under prefers-reduced-motion except instant state changes.
3. **Hero: typing prompt box + morphing image** — Eyebrow pill: Lucide Sparkles 14px in coral + 'New: Style lock keeps one look across 40 images' (DM Sans 500, 13px, #F2F0EC on #FFFFFF0D, border #FFFFFF1A, pill, padding 6px 12px). H1 (two lines on desktop): 'Type a sentence.' / 'Get the picture you meant.' where 'the picture you meant' uses gradient text (background-clip text, accent gradient). Subhead (18px, #A3A1AD, max-width 520px): '[BRAND] is an AI image generator that turns one sentence into a print-ready picture, built for designers, marketers and indie creators who need visuals today, not next sprint.' Then the PROMPT BOX (see layout). Under it a row of two buttons: primary gradient pill 'Start free with 50 credits' (Lucide ArrowRight 16px trailing, href #cta) and ghost pill 'Browse the gallery' (Lucide ArrowDown, href #gallery, border #FFFFFF26, text #F2F0EC). Under the buttons, one muted line (13px, #6B6977) with three items separated by middots: 'No card required' · 'Commercial use on paid plans' · 'Exports up to 4096 px'. Prompt/image pairs, in loop order (file | style tag | seed | prompt text): 1) hero-greenhouse.webp | style 'Cinematic' | seed 48213 | prompt "A glass greenhouse on a sea cliff at dusk, fog rolling in, warm lamps glowing inside, wide cinematic shot"; 2) hero-camper.webp | style 'Cinematic' | seed 90577 | prompt "A vintage camper van alone on a salt flat at twilight, string lights, coral horizon, faint star trails"; 3) hero-perfume.webp | style 'Product' | seed 31146 | prompt "Unlabeled ribbed ceramic perfume bottle on wet black stone, coral rim light, low violet mist, studio product shot"; 4) hero-nook.webp | style '3D render' | seed 77402 | prompt "A cozy reading nook with a round window over a rainy neon city at night, soft lamp light, 3D render"; 5) hero-jellyfish.webp | style 'Fantasy' | seed 15889 | prompt "A giant glowing jellyfish drifting above a pine forest at night, bioluminescent trails, dreamy matte painting". Each pair also has a fixed render time label: 6.2s, 5.8s, 4.9s, 7.1s, 6.6s.
Layout: Section min-height 100vh (min 760px), padding-top 132px, padding-bottom 96px. Background: #0B0B10 plus two absolutely positioned blurred glows (a 620px violet #8E6CFF circle at left 8% top 4% and a 520px coral #FF7A59 circle at right 4% bottom 0, both filter blur(140px), opacity 0.18) and a full-section SVG feTurbulence grain overlay at opacity 0.04, pointer-events none. Container 1200px, 12-column grid, gap 48px, items-center: text column col-span-6, image column col-span-6. PROMPT BOX (margin-top 32px, max-width 560px): relative glass panel, background rgba(18,18,26,0.72), backdrop-filter blur(16px), 1px border #FFFFFF26, radius 20px, padding 18px 18px 14px, box-shadow 0 24px 60px -24px rgba(0,0,0,0.7). Top row (flex, gap 8px): mono label 'PROMPT' (JetBrains Mono 500, 11px, letter-spacing 0.12em, #6B6977), then on the right two small chips (mono 11px, #A3A1AD, background #FFFFFF0D, radius 999px, padding 3px 9px): the current style tag and '4:5'. Text area: min-height 84px (3 lines), margin 10px 0 14px, JetBrains Mono 400, 16px, line-height 1.55, color #F2F0EC; the typed text is followed by a caret span 2px wide, 1.15em tall, background accent gradient, blinking with steps(1) at 1s. The text is an aria-live='polite' region that announces each full prompt once it finishes typing (not every letter). Bottom row (flex justify-between, border-top 1px #FFFFFF14, padding-top 12px): left three 32px icon buttons with tooltips (Lucide ImagePlus 'Add reference', RectangleVertical 'Aspect 4:5', Wand2 'Enhance prompt'; #A3A1AD, hover background #FFFFFF0D, radius 10px; they are decorative and do nothing on click); right the Generate button: gradient pill, height 40px, padding 0 16px, Lucide Sparkles 16px + 'Generate' (DM Sans 600, 14px, #0B0B10 text on the gradient) + a mono '4 [CREDIT_NAME]' label at 12px in rgba(11,11,16,0.7). During the generating phase its label becomes 'Generating…' and the Sparkles icon spins. Along the very bottom edge inside the box (left 18px, right 18px, bottom 0) sits a 2px progress track (#FFFFFF14) whose fill is the accent gradient with a moving white shimmer highlight. Clicking Generate restarts the current pair's generate phase. IMAGE PANEL (image column): relative wrapper with a decorative glow behind it (inset -24px, accent gradient at 100deg, filter blur(72px), opacity 0.32, radius 32px). The panel itself: aspect-ratio 4/5, width 100%, max-width 520px, margin-left auto, radius 24px, overflow hidden, 1px border #FFFFFF26, background #12121A. Inside: a full-size <canvas> running the morph shader (see Stack setup) with a plain <img> of the first image underneath until all textures load. Overlays: top-left glass chip (rgba(11,11,16,0.55), blur 10px, radius 999px, padding 6px 12px, DM Sans 500 13px) showing the current style tag with a 6px gradient dot; bottom-left glass caption (radius 12px, padding 8px 12px, JetBrains Mono 12px #F2F0EC) reading 'seed 48213 · 4:5 · 6.2s' for the current pair; right edge inside (right 14px, vertically centered) a vertical stack of five 46px square thumbnails (radius 10px, gap 8px, object-fit cover, opacity 0.6, 1px border #FFFFFF26) of the five hero images; the active one has opacity 1 and a 2px accent-gradient ring (outline via a padded gradient wrapper). Clicking a thumbnail jumps to that pair: its prompt is set instantly (no typing), the morph runs, then the loop continues from there. During the generating phase a diagonal shimmer band (linear-gradient 115deg, transparent -> rgba(255,255,255,0.08) -> transparent, 40% wide) sweeps across the panel once per 1.1s. Mobile (<900px): single column, text centered-left; order is eyebrow, H1 (40px), subhead (16px), image panel (aspect 1/1, full width, max-width none), then the prompt box overlapping the bottom of the image panel by 56px (relative z-index 2, margin-top -56px, margin-x 12px), then buttons stacked full width, then the muted line. On mobile the thumbnail stack becomes a horizontal row of five 8px dots at the panel's top-right (active dot is a 20px gradient pill).
Motion: Loop state machine (one requestAnimationFrame/timeout driver, starts 600ms after load): TYPE the prompt at 30ms per character -> HOLD 450ms -> GENERATE: Generate button pressed (scale 0.97 for 120ms), progress fills 0 to 100% over 1400ms (ease-in-out), panel shimmer runs -> MORPH: shader progress tweens 0 to 1 over 1200ms (easeInOutCubic) from the previous image to this pair's image; style chip, caption and active thumbnail update when progress passes 0.5 -> SHOW for 2600ms (shader applies a slow 1.00 to 1.04 zoom over the hold) -> ERASE the prompt backwards at 12ms per character -> next pair (wraps to 1). The very first pair skips the morph (image already shown) but still runs type and generate. Pause the whole loop (and the render loop) when the hero is less than 20% visible (IntersectionObserver) or document.hidden; resume where it stopped. Cursor glow: pointermove on the prompt box sets CSS variables --mx/--my; a ::before layer paints radial-gradient(260px circle at var(--mx) var(--my), rgba(142,108,255,0.20), transparent 65%) and a ::after layer paints the same circle in the accent gradient but masked to a 1px border ring (mask with content-box/xor technique), fading in on pointerenter and out on pointerleave over 200ms. Only when (hover: hover) and motion is allowed. Entry: text column children fade up (y 24 -> 0, opacity 0 -> 1, 0.6s, stagger 0.08s); image panel fades in and scales 0.96 -> 1 over 0.8s. REDUCED MOTION: no typing, no erase, no shimmer, no shader zoom, no cursor glow; the prompt text shows in full, the image swaps with a 200ms opacity crossfade (or instantly), and a small ghost button 'Next prompt' with Lucide ArrowRight appears under the prompt box (right-aligned) to step through the five pairs manually; thumbnails still work.
4. **Stats strip (logo-free trust)** — Four product facts, each a big number and a label: '6.2 s' / 'median render time for a 1024 px image'; '48' / 'curated styles, from film still to clay'; '4096 px' / 'maximum export, ready for print'; '1 credit' / 'per draft preview, so exploring stays cheap' (render the word credit from [CREDIT_NAME] singular). No logos, no user counts.
Layout: Container 1200px, margin-top -24px. One row of four equal cells inside a panel with 1px border #FFFFFF14 top and bottom only (no box), padding 28px 0; cells separated by 1px vertical #FFFFFF14 lines; each cell padding-x 28px. Number: Bricolage Grotesque 600, 40px, letter-spacing -0.03em, #F2F0EC with the unit ('s', 'px', 'credit') at 18px #A3A1AD. Label: DM Sans 400, 14px, #A3A1AD, max-width 220px, margin-top 6px. Mobile: 2x2 grid, horizontal divider between rows, numbers 32px.
Motion: Cells fade up with 0.08s stagger when 30% in view (once). Numbers do not count up.
5. **How it works (#how): three steps with small UI mocks** — Section label (mono 12px, letter-spacing 0.14em, coral #FF7A59): 'HOW IT WORKS'. H2: 'Three steps from idea to file.' Sub (17px, #A3A1AD): 'No node graphs, no settings maze. Describe it, pick a direction, export.' Step 01 'Describe it' — 'Write what you see in plain words. [BRAND] suggests lighting, lens and mood as chips you can tap in.' Mock: a mini prompt field (mono 13px text 'a lighthouse made of frosted glass, stormy sea…' with a static gradient caret) and below it four suggestion chips: '+ golden hour', '+ 35 mm', '+ volumetric fog', '+ 4:5' (the first two shown as selected with gradient border). Step 02 'Pick a direction' — 'Every run gives you four drafts at 1 [CREDIT_NAME singular] each. Keep the one that feels right.' Mock: a 2x2 grid of four square thumbnails, all cropped from public/images/hero-greenhouse.webp with object-position 20% 30%, 80% 30%, 30% 80%, 70% 70% and CSS filters hue-rotate(0deg), hue-rotate(18deg), hue-rotate(-16deg) saturate(1.2), hue-rotate(36deg); the second one is selected (2px gradient ring + a 20px circular Lucide Check badge on #F2F0EC). Step 03 'Refine and export' — 'Upscale, remove the background or fix one detail with a brush, then download.' Mock: an export panel with three rows: 'Upscale 4x' with an on toggle (gradient track), 'Remove background' with an off toggle, 'Format' with a segmented control PNG / WEBP / JPG (PNG active); then a full-width small gradient button 'Export 4096 x 5120'.
Layout: Section padding 112px 0 (80px mobile). Header block left-aligned, max-width 640px, margin-bottom 56px. Three cards in a 3-column grid (gap 24px; single column below 900px). Card: background #12121A, 1px border #FFFFFF14, radius 20px, padding 24px; top: the mock area (height 220px, background #0B0B10, radius 14px, 1px border #FFFFFF0D, padding 16px, contents vertically centered), then step number '01' (JetBrains Mono 500, 13px, gradient text), title (Bricolage Grotesque 600, 22px, margin-top 20px), body (15px, #A3A1AD, line-height 1.6). Mocks are built in HTML/CSS (not images) except the step 02 thumbnails.
Motion: Cards fade up with 0.1s stagger (once). In step 01 the two selected chips pop in (scale 0.9 -> 1) 300ms after the card appears. Static under reduced motion.
6. **Feature bento (#features)** — Section label 'FEATURES'. H2: 'Control without the learning curve.' Six tiles: T1 (large) 'Style lock' — 'Save a look once (palette, light, lens, grain) and apply it to every image in a campaign. Up to 40 images stay visually related.' Visual: three overlapping image cards fanned like photos (public/images/hero-greenhouse.webp, hero-jellyfish.webp, hero-camper.webp; 3:4, radius 14px, 1px border #FFFFFF26, rotated -8deg, 0deg, 8deg, offset 70px apart), each with a small glass chip 'Look: Dusk Glass' and a Lucide Lock 12px icon. T2 'Brush to fix' — 'Paint over one detail and say what should be there instead. The rest of the image stays untouched.' Visual: public/images/hero-perfume.webp (cover, height 180px, radius 12px) with an SVG dashed brush loop (stroke #F2F0EC, 2px, dash 6 5) drawn around the upper right of the bottle and a glass speech chip 'add a sprig of lavender'. T3 'Upscale to 4096 px' — 'Turn any 1024 px result into a sharp print file in about ten seconds.' Visual: JetBrains Mono numbers '1024' -> '4096' (Lucide ArrowRight between) at 34px with the second in gradient text, and a 6px bar below that fills to 100%. T4 'Clean cutouts' — 'Remove the background in one click and export a transparent PNG.' Visual: a CSS checkerboard (12px squares, #1A1A25 / #12121A) with a code-drawn glossy orb (radial gradient #F2F0EC -> #C86BD8 -> #8E6CFF -> #2A1E4A) and a soft contact shadow. T5 'Brand palettes' — 'Pin your brand colors so every render leans toward them.' Visual: five 40px circular swatches #8E6CFF, #C86BD8, #FF7A59, #F2C27B, #1A1A25 in a row, the first three with a small Lucide Pin badge. T6 'Batch from a sheet' — 'Upload a CSV of prompts and get a folder of images back. Up to 500 rows per batch on Studio.' Visual: a mini table of three rows (mono 12px): 'hero banner, spring sale' — chip 'Done' (#5BD6A0 on #5BD6A01A); 'product card, mint tin' — 'Done'; 'story frame 03' — 'Rendering' (coral on #FF7A591A with a pulsing dot).
Layout: Section padding 112px 0. Grid of 12 columns, gap 20px, auto rows. Row 1-2: T1 col-span-7 row-span-2 (min-height 520px); T2 col-span-5; T3 col-span-5. Row 3: T4, T5, T6 col-span-4 each (min-height 260px). Tile: background #12121A, 1px border #FFFFFF14, radius 24px, padding 28px, overflow hidden, flex column with the text block (title Bricolage Grotesque 600 22px; body 15px #A3A1AD, max-width 380px) at the top and the visual filling the rest. Below 900px every tile is full width in source order and T1 min-height 440px.
Motion: Tiles fade up with stagger (once). Each tile has a pointer spotlight: a ::before radial-gradient(360px circle at var(--mx) var(--my), rgba(255,255,255,0.06), transparent 60%) that appears on hover (hover devices only). T1 cards fan slightly further apart on tile hover (rotation x1.25, 300ms). T2 brush path draws in via stroke-dashoffset over 900ms when in view. T3 bar fills 0 -> 100% over 1.2s when in view. T6 'Rendering' dot pulses (opacity 1 -> 0.3, 1.2s loop). All static under reduced motion.
7. **Before / after slider** — Section label 'BEFORE / AFTER'. H2: 'From rough draft to print-ready in one click.' Sub: 'Drag the handle. Same seed, same prompt; only the finishing pass changes.' Three tabs above the slider: 'Upscale 8x' (default), 'Relight', 'Denoise'. Corner labels per tab (left = before, right = after): Upscale: 'Draft · 512 px' / 'Upscaled · 4096 px'; Relight: 'Flat light' / 'Relit · golden hour'; Denoise: 'Noisy draft' / 'Cleaned'. Under the slider, the prompt in mono 13px #6B6977: 'A floating island with a tiny observatory above a sea of clouds at sunrise, waterfalls spilling into the clouds'.
Layout: Section padding 112px 0. Header centered, max-width 680px, margin 0 auto 32px. Tabs: centered segmented control (background #12121A, 1px border #FFFFFF14, radius 999px, padding 4px; active tab background #FFFFFF14 with #F2F0EC text, others #A3A1AD; DM Sans 500 14px; role tablist). Slider frame: margin-top 28px, width 100%, aspect-ratio 16/9, radius 24px, overflow hidden, 1px border #FFFFFF26, position relative, touch-action pan-y, cursor ew-resize. AFTER layer: public/images/compare-island.webp, object-fit cover. BEFORE layer: a <canvas> on top, same size, clipped with clip-path inset(0 calc(100% - var(--pos)) 0 0). Before images are derived at runtime from the same file (no extra assets): Upscale = draw the image into an offscreen canvas 1/10 of the display width, then draw it back at full size with imageSmoothingEnabled = false (visible pixelation) and apply filter 'saturate(0.85) contrast(0.92)'; Relight = draw with ctx.filter 'saturate(0.35) brightness(0.82) contrast(0.82)' then fill #5D6B8C at globalAlpha 0.28 with globalCompositeOperation 'multiply'; Denoise = draw the image, then add monochrome noise (each pixel offset by a seeded random -38..38, mulberry32 seed 7) and a light 'blur(0.6px)'. Re-render the before canvas on resize (debounced 150ms) and on tab change. Handle: a 2px vertical line (#F2F0EC, box-shadow 0 0 12px rgba(0,0,0,0.5)) at var(--pos) full height, with a 48px circular glass knob centered on it (rgba(11,11,16,0.6), blur 10px, 1.5px border #F2F0EC) holding Lucide ChevronsLeftRight 20px. Corner labels: glass chips at top-left and top-right (16px inset), JetBrains Mono 12px. Accessibility: the knob is role='slider', tabindex 0, aria-label 'Compare before and after', aria-valuemin 0, aria-valuemax 100, aria-valuenow = pos; ArrowLeft/ArrowRight move 5, Shift+Arrow 10, Home 0, End 100; visible focus ring (2px accent gradient outline offset 3px). Pointer: pointerdown anywhere on the frame jumps the handle there and setPointerCapture drags it; position clamps to 0..100. Default pos 50. Mobile: aspect-ratio 4/3, tabs scroll horizontally if needed.
Motion: When the frame is first 50% in view, a one-time hint animates pos 50 -> 62 -> 40 -> 50 over 1.6s (easeInOut) unless the user already interacted or reduced motion is on. Tab switch crossfades the before canvas (opacity 0 -> 1, 200ms).
8. **Gallery (#gallery): masonry with hover prompts and style filters** — Section label 'GALLERY'. H2: 'Made with [BRAND]. Prompts included.' Sub: 'Hover any image to see exactly what was typed. Copy it, change two words, make it yours.' Filter chips: All, Cinematic, Product, 3D, Fantasy, Abstract (each chip shows its count in mono at 11px: All 10, Cinematic 2, Product 1, 3D 2, Fantasy 2, Abstract 3). Ten tiles in this order (source | aspect | style | credit line | prompt): 1) public/images/hero-greenhouse.webp | 3:4 | style 'Cinematic' | by @mira.okafor · 4 [CREDIT_NAME] | prompt "A glass greenhouse on a sea cliff at dusk, fog rolling in, warm lamps glowing inside, wide cinematic shot"; 2) canvas:liquid-chrome | 1:1 | style 'Abstract' | by @tvale · 4 [CREDIT_NAME] | prompt "Liquid chrome ribbons folding through violet and coral light, macro, ultra smooth gradients"; 3) public/images/hero-perfume.webp | 3:4 | style 'Product' | by @juno.studio · 8 [CREDIT_NAME] | prompt "Unlabeled ribbed ceramic perfume bottle on wet black stone, coral rim light, low violet mist, studio product shot"; 4) public/images/compare-island.webp | 16:9 | style 'Fantasy' | by @kasper.lind · 8 [CREDIT_NAME] | prompt "A floating island with a tiny observatory above a sea of clouds at sunrise, waterfalls spilling into the clouds"; 5) public/images/hero-nook.webp | 1:1 | style '3D' | by @noor.makes · 4 [CREDIT_NAME] | prompt "A cozy reading nook with a round window over a rainy neon city at night, soft lamp light, 3D render"; 6) canvas:glass-orbs | 4:5 | style '3D' | by @ellis.park · 4 [CREDIT_NAME] | prompt "Seven glossy glass orbs floating in a dark void, soft studio reflections, violet and coral glow"; 7) public/images/hero-jellyfish.webp | 3:4 | style 'Fantasy' | by @rhea.prakash · 8 [CREDIT_NAME] | prompt "A giant glowing jellyfish drifting above a pine forest at night, bioluminescent trails, dreamy matte painting"; 8) canvas:topographic-dusk | 4:3 | style 'Abstract' | by @dmitri.k · 4 [CREDIT_NAME] | prompt "Topographic contour lines glowing coral on a deep violet field, minimal, map-like"; 9) public/images/hero-camper.webp | 3:4 | style 'Cinematic' | by @saoirse.frames · 8 [CREDIT_NAME] | prompt "A vintage camper van alone on a salt flat at twilight, string lights, coral horizon, faint star trails"; 10) canvas:aurora-ribbons | 3:4 | style 'Abstract' | by @lowtide.co · 4 [CREDIT_NAME] | prompt "Soft aurora ribbons in violet, orchid and coral over a quiet starfield, long exposure feel". Code-drawn tiles (canvas, rendered once at devicePixelRatio capped at 2, seeded with mulberry32 so every build looks identical): liquid-chrome (seed 11) = background linear gradient #1B1030 -> #0B0B10, then 70 horizontal sine ribbons (y offset = i*height/70 plus 0.18*height*sin(x*0.006 + i*0.21)), each stroked with a #8E6CFF -> #FF7A59 horizontal gradient, lineWidth 1.2, globalAlpha 0.45, globalCompositeOperation 'lighter'; glass-orbs (seed 7) = background #0E0B16, seven orbs at seeded positions and radii 8%-22% of width, each a radial gradient (highlight #F2F0EC at 30%/28% of the orb, body alternating #8E6CFF and #FF7A59, rim #1A1230), with a soft blurred shadow under each; topographic-dusk (seed 23) = background #120E1C, 26 concentric closed contours around a seeded center, radius r_i = 12 + i*14 px plus a wobble 6*sin(3a + i*0.4) + 4*sin(5a - i*0.7), stroke #FF7A59 with globalAlpha falling from 0.9 to 0.15 outward, lineWidth 1.2; aurora-ribbons (seed 31) = background #07070C, 140 star dots (radius 0.4-1.2 px, #F2F0EC at alpha 0.2-0.8), then five wide curved bands (lineWidth 40-90 px, lineCap round) in #8E6CFF, #C86BD8, #FF7A59, #8E6CFF, #C86BD8 at globalAlpha 0.35 with ctx.filter 'blur(28px)' and 'lighter' compositing. Each tile: role figure, the image or canvas has alt / aria-label 'Generated image: ' + prompt.
Layout: Section padding 112px 0. Header left-aligned; filter chips in a row under it (margin 28px 0 32px), chip = DM Sans 500 14px, height 36px, padding 0 14px, radius 999px, background #12121A, 1px border #FFFFFF14, #A3A1AD; active chip background #F2F0EC, text #0B0B10; chips are a role='radiogroup'; they scroll horizontally on mobile without a visible scrollbar. Masonry is computed in JS, not CSS columns: column count 3 at >= 1024px, 2 below (including 390px mobile); for the current filter, place each visible item in order into the currently shortest column (column height = sum of 1/aspect for its items); render columns as flex columns with gap 16px (12px mobile) inside a flex row with the same gap. Tile: relative, width 100%, aspect-ratio from data, radius 16px, overflow hidden, background #12121A, 1px border #FFFFFF14; images object-fit cover, loading lazy except the first three. Hover overlay (hidden until hover/focus-within): a layer with background rgba(11,11,16,0.45) plus a bottom gradient (transparent 35% -> rgba(11,11,16,0.92) 100%); at the bottom (padding 16px): the style tag chip (glass, mono 11px), the prompt (JetBrains Mono 13px, line-height 1.5, #F2F0EC, 3-line clamp, 4 lines on tiles wider than 360px), and a row with the credit line ('by @mira.okafor · 4 credits', DM Sans 12px #A3A1AD) on the left and a 'Copy prompt' button on the right (height 32px, padding 0 12px, radius 999px, background #F2F0EC, text #0B0B10, DM Sans 600 12px, Lucide Copy 14px). Copy uses navigator.clipboard.writeText inside try/catch with a hidden-textarea execCommand('copy') fallback; on success the button shows Lucide Check + 'Copied' for 1600ms. Each tile is keyboard focusable (tabindex 0) so the overlay also shows on focus. On touch devices (hover: none) the first tap on a tile toggles the overlay; tapping another tile moves it.
Motion: Hover (hover devices): tile translateY(-4px) and box-shadow 0 24px 48px -20px rgba(0,0,0,0.8); image scale 1 -> 1.04 (400ms ease-out); overlay opacity 0 -> 1 and prompt block y 8 -> 0 (220ms). Filtering: each tile is a Motion element with layout and layoutId so tiles glide to their new columns (spring stiffness 260, damping 30); leaving tiles fade and scale to 0.96 via AnimatePresence (180ms), entering tiles fade in. Tiles fade up on first scroll into view with stagger 0.05s. Under reduced motion: no lift, zoom or layout animation; overlay still appears on hover/focus instantly.
9. **Pricing (#pricing): credit-based plans** — Section label 'PRICING'. H2: 'Pay for what you make.' Sub: 'Every plan runs on [CREDIT_NAME]. A standard 1024 px image costs 4.' Billing toggle: 'Monthly' / 'Yearly' with a small badge 'Save 20%' next to Yearly. Plan 1 'Free' — price '$0' with caption 'forever'; headline number '50' + '[CREDIT_NAME], once'; explainer line 'About 12 standard images'; bullets: 'Up to 1024 px exports', '8 starter styles', 'Personal use only', 'Small corner watermark'; button 'Start free' (ghost). Plan 2 'Creator' (highlighted, badge 'Most popular') — Monthly '$12' / Yearly '$9.60' with caption '/month' and, in yearly mode, a second caption 'billed $115 yearly'; headline '1,200' + '[CREDIT_NAME] / month'; explainer 'About 300 standard images'; bullets: 'All 48 styles', 'Upscale to 4096 px', 'Style lock: 3 saved looks', 'Brush to fix and clean cutouts', 'Commercial license', 'Private gallery'; button 'Choose Creator' (gradient). Plan 3 'Studio' — Monthly '$36' / Yearly '$28.80', yearly caption 'billed $346 yearly'; headline '4,800' + '[CREDIT_NAME] / month'; explainer 'About 1,200 standard images'; bullets: 'Everything in Creator', '5 seats sharing one pool', 'Batch from CSV, 500 rows', 'Unlimited style locks', 'Brand palettes', 'Priority render queue'; button 'Choose Studio' (ghost). All buttons link to #cta. Credit explainer row under the cards, titled 'How [CREDIT_NAME] work', four cells: '1' + 'draft preview, 512 px'; '4' + 'standard image, 1024 px'; '8' + 'HD image, 2048 px'; '+6' + 'upscale to 4096 px'. Footnote (13px #6B6977): 'Unused [CREDIT_NAME] roll over for one month on paid plans. Failed renders are refunded automatically. Prices in USD.'
Layout: Section padding 112px 0. Header centered, max-width 640px. Toggle centered below it (margin 28px auto 48px): segmented pill like the compare tabs, role radiogroup, the badge 'Save 20%' is a tiny gradient-bordered pill in coral text. Cards: 3-column grid, gap 20px, items-stretch; single column below 900px with Creator first. Card: background #12121A, 1px border #FFFFFF14, radius 24px, padding 32px, flex column. Creator card: 1px gradient border (gradient wrapper with 1px padding and inner #12121A, or border-image via mask), background slightly lifted #15141F, a soft accent glow behind it (box-shadow 0 30px 80px -30px rgba(142,108,255,0.45)), and the 'Most popular' badge (gradient fill, #0B0B10 text, DM Sans 600 12px, pill) at the top-right. Inside each card in order: plan name (DM Sans 600, 15px, #A3A1AD, uppercase, letter-spacing 0.08em); price row (Bricolage Grotesque 600, 48px, letter-spacing -0.03em) + caption (15px #A3A1AD) and the yearly billed caption beneath (13px #6B6977, reserved height so cards do not jump); a divider; the credits headline number (Bricolage Grotesque 600, 36px, gradient text on Creator, #F2F0EC on others) with its unit text (15px #A3A1AD) on the same line; explainer (14px #6B6977); bullets (15px #F2F0EC, 12px gap, Lucide Check 16px in #5BD6A0 on the paid plans and #A3A1AD on Free); button pinned to the bottom (margin-top auto, full width, height 48px, radius 999px). Credit explainer row: margin-top 40px, panel with 1px border #FFFFFF14 radius 20px, a title cell on the left and four cells (JetBrains Mono 600 28px number in gradient text + 13px label) separated by vertical lines; 2x2 under the title on mobile.
Motion: Price change on toggle: the number slides (Motion AnimatePresence, old y 0 -> -12 and fade out, new y 12 -> 0 and fade in, 220ms); the toggle thumb moves with a Motion layout spring. Cards fade up with stagger. Reduced motion: values swap instantly.
10. **FAQ (#faq)** — Section label 'FAQ'. H2: 'Questions, answered.' Eight items: 1) 'What is a credit?' — 'It is how [BRAND] measures work. A 512 px draft costs 1, a standard 1024 px image costs 4, an HD 2048 px image costs 8 and upscaling to 4096 px adds 6. You see the cost on the Generate button before you press it.' 2) 'Can I use the images commercially?' — 'Yes on Creator and Studio. You can use what you make in client work, ads, packaging, merch and print. Images made on the Free plan are for personal use.' 3) 'Do unused credits roll over?' — 'On paid plans, unused credits carry over for one month, up to one month of your plan's allowance. Free credits do not expire.' 4) 'What if a result is not what I wanted?' — 'Start with 1-credit drafts to explore, then spend more only on the direction you like. If a render fails on our side, the credits go back to your balance automatically.' 5) 'Can I keep one style across a whole campaign?' — 'Style lock saves the palette, light, lens and grain of an image you like and applies it to new prompts. Creator keeps 3 saved looks; Studio keeps as many as you need.' 6) 'Are my prompts and images private?' — 'Paid plan galleries are private by default and are never used to train models. Free plan images can appear in the public gallery unless you delete them.' 7) 'What can't I generate?' — 'Prompts that name living artists or real people, copyrighted characters, or explicit content are blocked. You will see a short note explaining why, and no credits are spent.' 8) 'Can I cancel anytime?' — 'Yes. Your plan stays active until the end of the billing period. Yearly plans can be refunded in full within 14 days of purchase; write to support@' + emailDomain + '.' In all answers, use [CREDIT_NAME] for the unit word.
Layout: Section padding 112px 0. Two columns on desktop: left col-span-4 holds the label, H2 and a small card 'Still stuck?' with text 'Write to us and a human replies within one business day.' and the email support@ + emailDomain as a link (mailto); right col-span-8 holds the accordion. Accordion: items separated by 1px #FFFFFF14 lines; question row is a full-width button (DM Sans 500, 18px, #F2F0EC, padding 22px 0, aria-expanded, aria-controls) with a 28px circular icon on the right (Lucide Plus that rotates 45deg when open, background #FFFFFF0D); answer 16px #A3A1AD line-height 1.65, max-width 640px, padding-bottom 22px. Only one item open at a time; item 1 open by default. Mobile: single column, the 'Still stuck?' card moves below the accordion.
Motion: Answer height animates with Motion (auto height, 240ms ease-out) and opacity; icon rotates 200ms. Instant under reduced motion.
11. **Sign-up CTA band (#cta) over a blurred collage** — H2 (centered, two lines): 'Your first 50 [CREDIT_NAME]' / 'are on us.' Sub: 'Enough for a dozen finished images. No card, no trial clock.' Form: email input (placeholder '[email protected]', aria-label 'Email address') + gradient button 'Get my [CREDIT_NAME]'. Small line under it (13px #6B6977): 'We send one sign-in link. No newsletter unless you ask.' Success state (replaces the form in place): a 40px circle with Lucide Check on #5BD6A01A in #5BD6A0, heading 'Check your inbox' and text 'Your sign-in link is on its way to {email}.' plus a text button 'Use a different email' that restores the form. Invalid email: inline error 'Enter a valid email address' in #FF7A59 under the field, aria-invalid on the input.
Layout: Full-bleed section, margin 48px 0 0, min-height 560px, position relative, overflow hidden, border-top and border-bottom 1px #FFFFFF14. Background collage (aria-hidden): an absolutely positioned 5-column grid, width 130%, left -15%, top -20%, rotated -6deg, gap 16px, made of the six images and the four gallery canvases (re-drawn small, or use toDataURL from the gallery renders) in aspect 3:4 tiles, radius 16px, filter blur(18px) saturate(1.25), opacity 0.5. Over it: radial-gradient(ellipse at center, rgba(11,11,16,0.55) 0%, rgba(11,11,16,0.92) 70%, #0B0B10 100%). Content centered, max-width 640px, padding 120px 24px. H2 Bricolage Grotesque 600, 56px (36px mobile), letter-spacing -0.035em, with '50 [CREDIT_NAME]' in gradient text. Form: margin-top 32px, a single glass pill (background rgba(18,18,26,0.75), blur 14px, 1px border #FFFFFF26, radius 999px, padding 6px, max-width 480px, margin auto) containing the input (transparent, 16px, padding 0 18px, flex 1) and the button (height 48px, radius 999px). Focus within the pill: 2px accent-gradient ring. Mobile: input and button stack inside a radius-20px panel, button full width.
Motion: Collage drifts very slowly (translateX 0 -> -40px, 30s linear alternate infinite; off under reduced motion). Content fades up on view. Success state: Motion fade/scale 0.96 -> 1 (220ms). The form calls preventDefault and only changes local state; nothing is sent.
12. **Footer** — Left: logo mark + '[BRAND]', one line 'An AI image generator for designers, marketers and indie creators.' (rewrite from the variables), and the address '418 Halden Street, Studio 3, Portland, OR 97209' with hello@ + emailDomain. Three link columns: Product (Features #features, Gallery #gallery, Pricing #pricing, How it works #how); Resources (Prompt guide, Style library, Help center, Status) linking to #top; Company (About, Careers, Press kit, Contact) linking to #top, Contact as mailto hello@. Bottom row: '© ' + companyName on the left; on the right text links Terms, Privacy, Acceptable use (#top) and three 36px icon buttons with generic Lucide icons Mail (mailto), Rss and MessageCircle (#top). Then the optional [CREDIT] link if provided.
Layout: Padding 72px 0 40px, border-top 1px #FFFFFF14 (omit if directly after the CTA border). Container 1200px; grid 12 columns: brand block col-span-5, link columns col-span-2 each with a column heading (DM Sans 600, 13px, #F2F0EC, uppercase, letter-spacing 0.08em) and links (15px #A3A1AD, hover #F2F0EC, 12px gap). Bottom row margin-top 56px, padding-top 24px, border-top 1px #FFFFFF14, 13px #6B6977, flex justify-between. Mobile: brand block full width, link columns in a 2-column grid, bottom row stacks.
Motion: None beyond link color transitions.
## Assets
- image: Six template images generated for this design (Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template). Download each with curl -L -o into public/images/ and reference them as ./images/<file>: https://media.vibefather.ai/assets/5bb65dea-af92-461c-9e11-5240dcf552c8/hero-greenhouse.webp -> public/images/hero-greenhouse.webp (hero pair 1, step 02 thumbnails, bento T1, gallery tile 1, CTA collage; alt 'A glass greenhouse glowing on a foggy sea cliff at dusk'); https://media.vibefather.ai/assets/5bb65dea-af92-461c-9e11-5240dcf552c8/hero-camper.webp -> public/images/hero-camper.webp (hero pair 2, bento T1, gallery tile 9, CTA collage; alt 'A vintage camper van with string lights on a salt flat at twilight'); https://media.vibefather.ai/assets/5bb65dea-af92-461c-9e11-5240dcf552c8/hero-perfume.webp -> public/images/hero-perfume.webp (hero pair 3, bento T2, gallery tile 3, CTA collage; alt 'An unlabeled ceramic perfume bottle on wet black stone with coral backlight'); https://media.vibefather.ai/assets/5bb65dea-af92-461c-9e11-5240dcf552c8/hero-nook.webp -> public/images/hero-nook.webp (hero pair 4, gallery tile 5, CTA collage; alt 'A reading nook with a round window over a rainy city at night'); https://media.vibefather.ai/assets/5bb65dea-af92-461c-9e11-5240dcf552c8/hero-jellyfish.webp -> public/images/hero-jellyfish.webp (hero pair 5, bento T1, gallery tile 7, CTA collage; alt 'A glowing jellyfish drifting above a pine forest at night'); https://media.vibefather.ai/assets/5bb65dea-af92-461c-9e11-5240dcf552c8/compare-island.webp -> public/images/compare-island.webp (before/after slider, gallery tile 4, CTA collage; alt 'A floating island with a small observatory above clouds at sunrise'). Six files in total; do not substitute other images.
- image: Drawn in code, no bitmaps: the logo mark and public/favicon.svg, hero glows and SVG grain, the four abstract gallery canvases (liquid-chrome, glass-orbs, topographic-dusk, aurora-ribbons, algorithms given in the Gallery section), the before images of the slider (derived at runtime from compare-island.webp), the step and bento UI mocks, the checkerboard and orb in bento T4, the color swatches and the brush path.
- icon: lucide-react (ISC), imported per icon: Sparkles, ArrowRight, ArrowDown, ImagePlus, RectangleVertical, Wand2, Check, Copy, Lock, Pin, ChevronsLeftRight, Plus, Menu, X, Mail, Rss, MessageCircle. No brand logos, no Simple Icons, no Lucide brand-shaped icons.
- font: Install @fontsource-variable/bricolage-grotesque, @fontsource-variable/dm-sans and @fontsource-variable/jetbrains-mono (all OFL-1.1) and import them in src/fonts.ts. Vite bundles the woff2 files into dist/.
- image: Write ASSETS.md at the project root with a table (path, source URL, author, license): one row per image in public/images/ with its media.vibefather.ai URL, author 'VibeFather', license 'Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template'; rows for the three Fontsource packages (OFL-1.1, https://fontsource.org) and lucide-react (Lucide contributors, ISC, https://lucide.dev); and a line stating that the logo, favicon, abstract gallery art and UI mocks are drawn in code for this project.
## Don'ts
- No backend of any kind: no server code, API routes, databases, auth, email services, payment providers, image-generation APIs, analytics or third-party APIs. The Generate button only replays the scripted demo; the CTA form calls preventDefault and only changes local UI state; nothing is submitted or sent.
- Do not load fonts from fonts.googleapis.com, fonts.gstatic.com, Adobe Fonts or any CDN. Self-host through the three Fontsource packages only. No commercial or custom fonts.
- No CDN <script>, <link> or import maps. Every script, style, font, icon and image is installed or downloaded into the project and bundled into dist/. Never hotlink the media.vibefather.ai URLs at runtime; download them first.
- No source maps in the production build (build.sourcemap false), and src/ is not copied into dist/.
- Relative asset paths (Vite base './', images as ./images/<file>). Internal links are hash anchors (#how, #features, #gallery, #pricing, #faq, #cta, #top) or ./index.html, never a bare directory or a leading slash.
- No names, logos, UI chrome, wordmarks or model names of real AI image products, model families or AI companies anywhere in copy, labels, sample data, alt text or code comments. The product is the invented [BRAND]; refer to the engine generically ('our image model').
- No prompts that name living artists, studios or photographers ('in the style of ...'), real people, celebrities, or copyrighted characters, mascots and game or anime IP. Describe looks with generic terms (film still, matte painting, clay, 3D render).
- No images scraped from AI image communities or showcase feeds, no Unsplash, Pexels, Pixabay or other restricted stock, no watermarked images, no placeholder-image services. Use only the six listed files and the code-drawn art.
- No real usage numbers, user counts, model benchmarks, funding, customer logos or testimonials. Stats are invented product facts for the invented brand.
- Do not use code or components from Aceternity UI, Tailwind Plus / Tailwind UI or any purchased template for the compare slider, spotlight, glow border, masonry or any other effect. Re-implement everything as described here.
- No real payment processor names, logos, card icons or checkout flows on the pricing cards; plan buttons only scroll to #cta.
- No three.js or other 3D/WebGL libraries: the hero morph is the small hand-written WebGL1 shader described in Stack setup, with an <img> crossfade fallback.
- Animate only transform, opacity, clip-path and CSS variables on HTML elements; never animate width, height, top or left directly (Motion auto-height in the FAQ is the one exception). Pause the hero loop and its render loop when off screen or in a hidden tab.
- Respect prefers-reduced-motion: no typing, shader zoom, shimmer, cursor glow, hint sweep, layout animation or collage drift; the hero shows full prompts with a manual 'Next prompt' button.
- Must work at 1440x900 and 390x844 with zero console errors and no horizontal scroll; the first screen on mobile must show the image panel.
- Do not mention VibeFather anywhere in the site except the optional [CREDIT] footer link.
---
— Prompt by VibeFather · https://vibefather.ai/t/ai-image-generator-landing-page · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown
Free for personal projects under CC BY-NC 4.0. Commercial use comes with Pro.
DESIGN.md
The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.
---
name: "AI Image Generator Landing Page"
colors:
void: "#0B0B10"
panel: "#12121A"
raised: "#1A1A25"
lifted: "#15141F"
line: "#FFFFFF14"
line_strong: "#FFFFFF26"
text: "#F2F0EC"
muted: "#A3A1AD"
faint: "#6B6977"
violet: "#8E6CFF"
orchid: "#C86BD8"
coral: "#FF7A59"
mint: "#5BD6A0"
accent_gradient: "linear-gradient(100deg, #8E6CFF 0%, #C86BD8 50%, #FF7A59 100%)"
typography:
display_h1_clamp_40px_5_4vw_76px_line_height_1_02_letter_spacing_0_035em_weight_650_h2_clamp_34px_4vw_54px_line_height_1_06_letter_spacing_0_03em_weight_600_card_titles_22px_weight_600_big_numbers: { family: "Bricolage Grotesque Variable", weights: [500, 600, 650, 700] }
text_body_16px_1_6_subheads_17_18px_nav_14px_buttons_14_15px_weight_600: { family: "DM Sans Variable", weights: [400, 500, 600] }
mono_prompt_text_seeds_section_labels_12px_letter_spacing_0_14em_uppercase_credit_numbers_chips: { family: "JetBrains Mono Variable", weights: [400, 500, 600] }
spacing: "8px base. Container max-width 1200px with 24px side padding (20px below 640px). Sections 112px vertical padding on desktop, 80px on mobile. 12-column grid with 20-48px gaps. Section header blocks have 56px space below them. Cards pad 24-32px."
radius: "Bento tiles, image panel, slider frame and plan cards 24px; step cards and FAQ card 20px; prompt box 20px; gallery tiles 16px; small thumbnails 10px; inputs inside panels 14px; every button, chip, tab and toggle is a full pill (999px)."
---
# AI Image Generator Landing Page — 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
- **void** `#0B0B10` — Page background, text on gradient buttons
- **panel** `#12121A` — Cards, tiles, prompt box base, chips
- **raised** `#1A1A25` — Inputs, hover fills, checkerboard dark squares
- **lifted** `#15141F` — Highlighted Creator plan background
- **line** `#FFFFFF14` — Hairline borders and dividers (white at 8%)
- **line-strong** `#FFFFFF26` — Glass panel borders, image frames, ghost buttons (white at 15%)
- **text** `#F2F0EC` — Primary text, light buttons, handle line
- **muted** `#A3A1AD` — Body copy, nav links, labels
- **faint** `#6B6977` — Captions, footnotes, mono labels
- **violet** `#8E6CFF` — Gradient start, glows, cursor light
- **orchid** `#C86BD8` — Gradient midpoint
- **coral** `#FF7A59` — Gradient end, section labels, errors, 'Rendering' state
- **mint** `#5BD6A0` — Success states and paid-plan check icons only
- **accent gradient** `linear-gradient(100deg, #8E6CFF 0%, #C86BD8 50%, #FF7A59 100%)` — Used sparingly: primary buttons, focus rings, caret, highlighted plan border, gradient text in H1/H2 phrases and key numbers
## Typography
- **Display: H1 clamp(40px, 5.4vw, 76px) line-height 1.02 letter-spacing -0.035em weight 650; H2 clamp(34px, 4vw, 54px) line-height 1.06 letter-spacing -0.03em weight 600; card titles 22px weight 600; big numbers** — Bricolage Grotesque Variable (OFL), weights 500/600/650/700. Self-host the font files.
- **Text: body 16px/1.6, subheads 17-18px, nav 14px, buttons 14-15px weight 600** — DM Sans Variable (OFL), weights 400/500/600. Self-host the font files.
- **Mono: prompt text, seeds, section labels (12px, letter-spacing 0.14em, uppercase), credit numbers, chips** — JetBrains Mono Variable (OFL), weights 400/500/600. Self-host the font files.
## Spacing & shape
- Spacing: 8px base. Container max-width 1200px with 24px side padding (20px below 640px). Sections 112px vertical padding on desktop, 80px on mobile. 12-column grid with 20-48px gaps. Section header blocks have 56px space below them. Cards pad 24-32px.
- Radius: Bento tiles, image panel, slider frame and plan cards 24px; step cards and FAQ card 20px; prompt box 20px; gallery tiles 16px; small thumbnails 10px; inputs inside panels 14px; every button, chip, tab and toggle is a full pill (999px).
## Motion
- Hero loop: type 30ms/char, hold 450ms, generate 1400ms progress with shimmer, WebGL noise-dissolve morph 1200ms easeInOutCubic, show 2600ms with 1.00 -> 1.04 zoom, erase 12ms/char; pauses off screen and in hidden tabs.
- Blinking gradient caret (1s steps) in the prompt box.
- Cursor-following violet glow and gradient border ring on the prompt box; soft white pointer spotlight on bento tiles (hover devices only).
- Scroll reveals: fade up 24px, 0.6s, ease [0.22, 1, 0.36, 1], once, stagger 0.05-0.1s.
- Gallery: tiles lift 4px and zoom image to 1.04 on hover, prompt overlay fades in; filter changes reflow with Motion layout springs.
- Before/after: one-time hint sweep of the handle when first in view; drag with pointer or keyboard.
- Pricing numbers slide on billing toggle; FAQ answers animate height; CTA collage drifts slowly.
- prefers-reduced-motion: no typing, shader zoom, shimmer, glow, hint sweep, layout animation or drift; hero shows full prompts with a manual 'Next prompt' button and instant image swaps.
## Imagery
Six generated images in one consistent look: cinematic digital renders with photographic realism, dusk light with deep violet shadows and warm coral highlights, soft haze and glowing practical lights, no people and no text. They appear as hero morph targets, step and bento visuals, the before/after subject, gallery tiles and the blurred CTA collage. Four extra gallery tiles are abstract art drawn in canvas with the same violet/orchid/coral palette. All UI mocks (prompt fields, chips, toggles, export panel, batch table) are built in HTML/CSS. No stock photos, no faces, no logos.
## Tone
Calm, confident and concrete. Short sentences, plain verbs, real numbers (render times, pixel sizes, credit costs). No hype words like 'revolutionary', 'unleash' or 'magic'; let the images and the live prompt do the selling.
---
— Prompt by VibeFather · https://vibefather.ai/t/ai-image-generator-landing-page · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown