---
name: landing-page-builder
description: Build SEO-optimized one-page landing pages using product brand guidelines. Deploys to *.landing.symph.co.
---

# Landing Page Builder

Create beautiful, SEO-optimized one-page landing pages for Symph Agency products.

## ⛔ MANDATORY: Gather Context First — NO EXCEPTIONS

**Before spawning ANY landing page build:**

```bash
# Step 1: Run gatherer
bash ~/.openclaw/workspace/skills/build-context-gatherer/scripts/gather-context.sh <slug> landing

# Step 2: Read the bundle
CONTEXT=$(cat /tmp/build-context-<slug>.md)

# Step 3: Embed in spawn task (NOT just file paths!)
sessions_spawn({
  task: "Build/redesign landing page for <product>.\n\n## CONTEXT BUNDLE\n${CONTEXT}\n\n## YOUR TASK\n...",
  label: "landing-<slug>"
})
```

### ❌ NEVER DO THIS
```bash
# WRONG: Telling subagent to read files
sessions_spawn({
  task: "Redesign the page. Read design-system-prompt.md at /path/to/file"
})
# Subagents skip files, partially read them, or misinterpret them!
```

### ✅ ALWAYS DO THIS
```bash
# CORRECT: Embed the actual content
CONTEXT=$(cat /tmp/build-context-<slug>.md)
sessions_spawn({
  task: "Redesign the page.\n\n## CONTEXT BUNDLE\n${CONTEXT}\n\n..."
})
# Content is IN the prompt — can't be skipped
```

**Policy set by Ed (Design) — 2026-02-18. Violations = build rejected.**

## ⚠️ Asset Storage Policy (MANDATORY)

**NEVER save generated assets in workspace root.**

| Asset Type | Save To |
|------------|---------|
| Landing page source code | `/home/aria/projects/<slug>-landing/` |
| Generated images (hero, etc.) | `/home/aria/products/<slug>/marketing/images/` |
| Design assets copied from product | Reference from `/home/aria/products/<slug>/design/assets/` |

This policy is enforced by Raven (CTO).

## Prerequisites

**Read `frontend-design/SKILL.md` first.** This skill extends those principles for landing page-specific patterns. All rules from frontend-design apply here, especially:

- **Color Consistency (MANDATORY)** — Use only your defined palette throughout; no random colors for "visual interest"
- **Icons: Lucide React ONLY** — Never emoji, never other icon libraries
- **Copy with Personality** — Headlines with voice, not corporate-speak
- **Social Proof patterns** — Specific metrics > vague claims
- **Typography System** — Distinctive fonts, proper scale
- **Anti-Patterns** — All forbidden patterns from frontend-design apply

When in doubt, defer to frontend-design rules.

## Domain Setup

- **Pattern:** `{slug}.landing.symph.co`
- **Port range:** 3100-3199 (separate from dev apps)
- **Managed by:** Caddy reverse proxy

## Input Requirements

Before building, gather from Design phase:
- ⭐ `design/design-system-prompt.md` - PRIMARY reference (distilled design system with brand personality, visual identity, component rules, layout patterns, anti-patterns)
- `brand-guidelines.md` - Colors, typography, logo (fallback if design-system-prompt.md doesn't exist)
- `design/assets/` - Logo, images, visual pegs
- Product name and tagline
- Key features (from PRD)
- Target audience (from target-market.md)

## Page Structure (Opinionated — NOT Generic)

⚠️ **DO NOT just stack sections vertically with centered text. Every section must have a DISTINCT layout.**

Study these reference sites for inspiration on how to break the generic SaaS pattern:
- https://www.jarvisa.com/ — Interactive hero with form, clean card-based features
- https://www.humanlike.bot/ — Bold typography, section labels as chips/badges, real testimonials with company names
- https://www.gcg.locker/ — Creative typography, images woven into layout

### Section Blueprint (Vary layouts — NEVER repeat the same pattern)

```
1. HERO (First impression — make it count)
   Layout: Asymmetric split (60/40) or full-bleed with product screenshot
   - Headline: Short, punchy, benefit-focused (NOT "Transform your X")
     Use the product's actual value prop from brief.md
     Try conversational tone: "Yo, going somewhere?" > "Streamline your workflow"
   - Subheadline: 1 sentence max, plain language
   - CTA: One primary button (high contrast), optionally one ghost/link
   - Visual: Product screenshot in device frame, OR interactive element (form, demo)
     Generate hero image with Nano Banana Pro if no screenshot exists
   - Optional: Small trust signal below CTA (star rating, user count, badge)

2. SOCIAL PROOF BAR (immediately after hero — builds trust)
   Layout: Horizontal logo strip, grayscale, no "Trusted by" text
   - If no logos available: Skip, or use a single stat ("500+ users" or "4.9★ rating")
   - Keep it subtle — single row, small logos

3. FEATURES (The meat — show what it does)
   Layout: ALTERNATE between these patterns (never use the same twice):
   a) Left image + right text (or vice versa)
   b) Large screenshot with overlaid feature callouts
   c) Interactive tabs or accordion revealing different features
   d) Bento grid (mixed card sizes) with icons and short descriptions
   
   For each feature:
   - Lucide icon (NOT emoji)
   - Short title (3-5 words)
   - 1-2 sentence description
   - Screenshot or generated illustration if possible
   
   Section label: Use a small chip/badge above the heading (e.g., "⚡ Features" or "🔧 How It Works")

4. HOW IT WORKS (Optional but recommended for complex products)
   Layout: Numbered steps with connecting line/arrows, or timeline
   - 3-4 steps max
   - Each step: number + title + short description
   - Visual progression (1 → 2 → 3)

5. TESTIMONIALS / SOCIAL PROOF (if available)
   Layout: ONE of these (not a 3-card grid):
   a) Single large quote with name, role, company (most impactful)
   b) Two-column with quote + company result metric
   c) Scrolling ticker of short quotes
   
   Include: Real name, real company, specific result ("3x increase in deals")
   If no real testimonials: Skip this section entirely. Never fake it.

6. PRICING (if applicable)
   Layout: Side-by-side cards (2-3 tiers max)
   - Highlight recommended tier
   - Keep it simple — bullet features, not comparison tables
   - Show actual prices (not "Contact us")

7. FAQ (helps SEO + reduces objections)
   Layout: Accordion or clean list
   - 4-6 questions max
   - Write from user's perspective, not marketing speak

8. FINAL CTA (Close the deal)
   Layout: Full-width section with contrasting background color
   - Repeat the core value prop (different wording from hero)
   - Single CTA button
   - Optional: email input for waitlist/newsletter

9. FOOTER
   Layout: Simple, dark background
   - Logo + tagline
   - 2-3 link columns max
   - Copyright
   - Social links (if applicable)
```

### AI Image Generation for Landing Pages

Use **Nano Banana Pro** (Gemini) to generate custom images when product screenshots aren't available.

⚠️ **CRITICAL: Background Images ONLY — Never Mock UI**

**DO:**
- ✅ Use AI-generated images for **backgrounds** and **abstract visuals**
- ✅ Generate geometric patterns, abstract compositions, brand-forward art

**DON'T:**
- ❌ **NEVER generate mock UI screenshots** — they always look fake
- ❌ **NEVER generate fake app interfaces, dashboards, or product mockups**
- ❌ Don't try to illustrate "what the app looks like"

**If you need to show the product UI:**
- Use actual screenshots from the built app
- Or leave the section as text-only with icons
- Or use a simple placeholder with "Screenshot coming soon"

Unless the user explicitly requests AI-generated UI mockups, **always default to backgrounds only**.

**Why geometric/abstract works for backgrounds:**
- Shapes/patterns can't look "wrong" the way realistic images can
- More timeless and brand-forward
- Still conveys the concept without the uncanny valley
- AI generates clean geometric art much better than realistic scenes

**Prompt pattern:**
```
"Abstract geometric composition representing [concept]. 
Shapes: [circles/lines/grids/waves/nodes]. 
Colors: [brand primary] and [brand secondary] on [background]. 
Style: minimal, modern, NOT realistic, NOT illustrative, NOT stock photo."
```

**When to use AI images vs real screenshots:**

| Section | AI-Generated (Backgrounds) | Real Screenshots |
|---------|---------------------------|------------------|
| Hero background | ✅ Abstract geometric composition | — |
| Feature sections | ✅ Abstract patterns as accents | ✅ Actual app screenshots (preferred) |
| Behind testimonials | ✅ Subtle geometric texture | — |
| CTA section | ✅ Brand-colored abstract shapes | — |

**If no real screenshots exist:** Use text + icons only for feature sections. Don't fake it.

**Abstract background examples (OK to generate):**

| Concept | ✅ Generate |
|---------|-------------|
| Analytics vibe | Flowing lines, bar shapes, gradient grids |
| Scheduling vibe | Circular time patterns, connected nodes, rhythm grids |
| Community vibe | Network nodes, connected circles, abstract shapes |
| Hero | Dynamic geometric composition with brand colors |
| History vibe | Layered shapes, stacked elements, time-flow pattern |

**Example commands:**

```bash
# Hero — abstract brand composition
uv run /path/to/nano-banana-pro/scripts/generate_image.py \
  --prompt "Abstract geometric composition with dynamic flowing shapes. Colors: cyan (#00ade5) and white on dark navy (#080c0f). Style: minimal, modern, tech-forward. Overlapping translucent circles and lines creating depth. NOT realistic, NOT illustrative." \
  --filename "hero-geometric.png" \
  --resolution 2K

# Feature — data/analytics concept
uv run /path/to/nano-banana-pro/scripts/generate_image.py \
  --prompt "Abstract data visualization art. Vertical bars of varying heights, flowing connection lines, grid pattern background. Colors: cyan (#00ade5) accents on dark background. Minimal, geometric, NOT a real dashboard screenshot." \
  --filename "feature-analytics.png" \
  --resolution 2K
```

Save generated images to `public/images/` in the landing page project.

## Design Rules (MANDATORY)

### Icons
- **ALWAYS use `lucide-react`** — never emoji, never Heroicons
- Import specific icons: `import { Rocket, Shield, Zap } from "lucide-react"`
- Size: `className="h-5 w-5"` for inline, `className="h-8 w-8"` for feature sections

### Anti-Patterns (NEVER DO)
- ❌ Emoji as icons (🚀 ➡️ `<Rocket />`)
- ❌ Purple/indigo gradient hero backgrounds
- ❌ 3-column feature grid with icon-title-description (vary layouts!)
- ❌ "Transform/Revolutionize/Supercharge your X" headlines
- ❌ Fake testimonial cards with stock avatars
- ❌ Perfectly centered symmetrical everything
- ❌ Generic abstract blob illustrations
- ❌ Pure white (#FFFFFF) backgrounds — use off-white from brand palette

### Layout Variety (REQUIRED)
Each section MUST use a different layout pattern:
- Hero: Asymmetric split (60/40) or full-bleed with overlay
- Features: Alternating left-right with screenshots, NOT a grid
- Social proof: Logo bar or single large quote, NOT cards
- CTA: Asymmetric with background accent, NOT centered box
- Use `framer-motion` for subtle scroll animations (fade-in-up, 0.4s)

### Typography
- Use `next/font` for loading (not Google Fonts CDN)
- Hero headline: Display/serif font at 3-5rem with tight letter-spacing
- Body: Clean sans-serif at 1rem/1.6 line-height
- One "typographic moment" per page (oversized text, gradient text, or rotated label)

## Tech Stack

```bash
npx create-next-app@latest {slug}-landing --typescript --tailwind --eslint --app --src-dir --use-npm
```

- Next.js (App Router)
- Tailwind CSS
- TypeScript
- lucide-react (REQUIRED — install immediately)
- framer-motion (for scroll animations)
- @studio-freight/lenis (for smooth scrolling)
- Single page (src/app/page.tsx)

### Lenis Smooth Scrolling Setup

Install and configure Lenis for buttery-smooth scroll experience:

```bash
npm install @studio-freight/lenis
```

Create a provider component (`src/components/SmoothScroll.tsx`):

```tsx
"use client";

import { useEffect } from "react";
import Lenis from "@studio-freight/lenis";

export default function SmoothScroll({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    const lenis = new Lenis({
      duration: 0.8,  // Keep snappy, not sluggish
      easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
      smoothWheel: true,
      wheelMultiplier: 1.2,  // Responsive wheel scrolling
    });

    function raf(time: number) {
      lenis.raf(time);
      requestAnimationFrame(raf);
    }

    requestAnimationFrame(raf);

    return () => lenis.destroy();
  }, []);

  return <>{children}</>;
}
```

Wrap your layout (`src/app/layout.tsx`):

```tsx
import SmoothScroll from "@/components/SmoothScroll";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <SmoothScroll>{children}</SmoothScroll>
      </body>
    </html>
  );
}
```

## SEO Requirements

In `src/app/layout.tsx`:

```typescript
export const metadata: Metadata = {
  title: "{Product Name} - {Benefit}",
  description: "{Compelling 150-160 char description}",
  keywords: ["{keyword1}", "{keyword2}", ...],
  openGraph: {
    title: "{Product Name}",
    description: "{Description}",
    images: ["/og-image.png"],
  },
  twitter: {
    card: "summary_large_image",
    title: "{Product Name}",
    description: "{Description}",
  },
};
```

Also add:
- Semantic HTML (h1, h2, sections)
- Alt text on all images
- Fast loading (optimize images)
- Mobile responsive

### Schema Markup (REQUIRED)

Add JSON-LD schema to `layout.tsx` or in a `<script>` tag:

**For SaaS Products:**
```typescript
// In layout.tsx or as script tag
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify({
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "{Product Name}",
  "applicationCategory": "BusinessApplication",
  "operatingSystem": "Web",
  "description": "{Full description}",
  "url": "https://{slug}.landing.symph.co",
  "offers": {
    "@type": "Offer",
    "price": "{price or 0}",
    "priceCurrency": "USD"
  },
  "creator": {
    "@type": "Organization",
    "name": "Symph",
    "url": "https://symph.co"
  }
})}} />
```

**Organization Schema (ALWAYS include):**
```typescript
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify({
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "{Product} by Symph",
  "url": "https://{slug}.landing.symph.co",
  "logo": "https://{slug}.landing.symph.co/logo.svg",
  "parentOrganization": {
    "@type": "Organization",
    "name": "Symph",
    "url": "https://symph.co"
  }
})}} />
```

**FAQ Schema (if FAQ section exists):**
```typescript
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify({
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": faqs.map(faq => ({
    "@type": "Question",
    "name": faq.question,
    "acceptedAnswer": {
      "@type": "Answer",
      "text": faq.answer
    }
  }))
})}} />
```

### Static SEO Files (REQUIRED)

Create these in `public/`:

**robots.txt:**
```
User-agent: *
Allow: /

Sitemap: https://{slug}.landing.symph.co/sitemap.xml
```

**sitemap.xml:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://{slug}.landing.symph.co/</loc>
    <lastmod>{YYYY-MM-DD}</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
</urlset>
```

### SEO Checklist (Must complete before deploy)

- [ ] Title tag: 50-60 chars, keyword + brand
- [ ] Meta description: 150-160 chars, value prop
- [ ] Canonical URL: `<link rel="canonical" href="...">`
- [ ] Single H1 tag (main headline)
- [ ] Proper heading hierarchy (H1 → H2 → H3)
- [ ] All images have alt text
- [ ] Open Graph tags complete (title, description, image, url, type)
- [ ] Twitter Card tags complete
- [ ] Schema markup: Organization + SoftwareApplication/Service
- [ ] FAQ schema (if FAQ section exists)
- [ ] `public/robots.txt` created
- [ ] `public/sitemap.xml` created
- [ ] OG image exists (`public/og-image.png`, 1200x630)
- [ ] Favicon + apple-touch-icon

**Full SEO reference:** `agency/docs/landing-page-seo-checklist.md`

## Brand Application

**Colors:** Extract from design-system-prompt.md (or brand-guidelines.md fallback)
```typescript
// tailwind.config.ts — extend with brand colors
colors: {
  primary: '{from brand}',
  secondary: '{from brand}',
  accent: '{from brand}',
  background: '{from brand}',  // NOT pure white
  surface: '{from brand}',
  foreground: '{from brand}',  // NOT pure black
}
```

**Typography:** Use `next/font` (NOT Google Fonts CDN — better performance + no layout shift)
```typescript
// src/app/layout.tsx
import { Inter, Playfair_Display } from 'next/font/google'

const heading = Playfair_Display({ subsets: ['latin'], variable: '--font-heading' })
const body = Inter({ subsets: ['latin'], variable: '--font-body' })
```

**Logo:** Copy from design/assets/ to public/

## Deployment

1. **Build the landing page:**
```bash
cd /home/aria/projects/{slug}-landing
npm run build
```

2. **Allocate port (3100-3199 range):**
```bash
# Check .caddy-ports.json for next available in 3100-3199
```

3. **Add to Caddy:**
Create site config for `{slug}.landing.symph.co` pointing to the port.

4. **Start the app:**
```bash
/home/aria/bin/app-manager start {slug}
```
`app-manager` handles port assignment, PM2 supervision, and Caddy config automatically.

5. **Trigger Approval Card (Auto):**

After deploy, trigger before/after capture for visual comparison:
```bash
~/.openclaw/workspace/scripts/post-deploy-hook.sh "{slug}" landing "Updated hero section" "New features block"
```

This runs async (~15s) and creates an approval card in the product's build phase chat.

## Healthcheck

Add healthcheck endpoint:
```typescript
// src/app/api/healthcheck/route.ts
import { NextResponse } from "next/server";

export async function GET() {
  return NextResponse.json({
    status: "ok",
    timestamp: new Date().toISOString(),
    app: "{slug}-landing",
  });
}
```

## Output

After building:

1. **landing-page.md** - Documentation of the landing page
   - URL
   - Sections included
   - SEO metadata
   - Screenshot

2. **landing-page.html** - Card for Agency UI
   - Preview/thumbnail
   - "View Landing Page" button
   - Lighthouse scores (if available)

## Example HTML Card

```html
<div class="card">
  <h2>Landing Page</h2>
  <div class="preview">
    <img src="/api/products/{slug}/market/assets/landing-preview.png" />
  </div>
  <div class="stats">
    <span>SEO Score: 95</span>
    <span>Mobile: ✓</span>
  </div>
  <a href="https://{slug}.landing.symph.co" target="_blank" class="cta-button">
    View Landing Page
  </a>
</div>
```

## Checklist

- [ ] `design-system-prompt.md` loaded as primary design reference
- [ ] Brand colors applied (NOT default purple/indigo)
- [ ] Typography: `next/font` (NOT CDN), display font for headings, sans for body
- [ ] Icons: Lucide React ONLY (zero emoji anywhere on page)
- [ ] Layout variety: No two sections share the same layout pattern
- [ ] Hero: Asymmetric or interactive (NOT centered text + stock image)
- [ ] Features: Alternating layouts (NOT 3-column icon grid)
- [ ] AI-generated images where product screenshots unavailable
- [ ] Logo in header
- [ ] Mobile responsive (mobile-first)
- [ ] SEO metadata complete (title, description, OG, Twitter, canonical)
- [ ] Schema markup (Organization + Product/Service type)
- [ ] FAQ section with FAQPage schema (recommended for rich snippets)
- [ ] `public/robots.txt` created
- [ ] `public/sitemap.xml` created
- [ ] OG image set (1200x630)
- [ ] Animations: framer-motion fade-in on scroll
- [ ] No fake testimonials, no mock data
- [ ] Healthcheck endpoint
- [ ] Deployed to Caddy
- [ ] Fast load time (<3s)
- [ ] **⛔ Approval card triggered** (`post-deploy-hook.sh` — REQUIRED)
