| name | seo-page-ui |
| description | UI blueprint for building rich SEO landing pages with Next.js/TSX. Defines the exact section order, animated SVG patterns, comparison tables, FAQ accordions, CTA blocks, JSON-LD structured data, and color palette. Use when building any /use-case/ or landing page that needs to rank in search. |
| user_invocable | true |
SEO Page UI
A reusable UI blueprint for building rich, SEO-optimized landing pages in Next.js (TSX). This skill defines the visual component patterns, section order, animated SVG templates, comparison tables, and structured data that every SEO landing page should have.
This is the UI layer only. It does not handle keyword discovery, state files, or pipeline orchestration. It tells you what to build visually.
When to Use
- Building a
/use-case/ page targeting a keyword
- Creating any SEO landing page that needs rich media
- When a pipeline skill (like
gsc-seo-page or underserved-seo-page) needs to know the page structure
File Structure
Each page is a single TSX file at src/app/{route}/{slug}/page.tsx:
import { Metadata } from "next";
import Link from "next/link";
import { Navbar } from "@/components/navbar";
import { Footer } from "@/components/footer";
export const metadata: Metadata = { };
export default function PageName() {
const jsonLd = [ ];
return (
<main className="noise-overlay">
<Navbar />
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
<div className="max-w-4xl mx-auto px-6 py-24">
{/* All 11 sections here */}
</div>
<Footer />
</main>
);
}
Color Palette
All SEO pages use these colors exclusively:
| Token | Hex | Usage |
|---|
| Box fill | #1e293b | SVG rectangles, diagram backgrounds |
| Dark background | #0f172a | Optional deeper background fills |
| Primary stroke | #14b8a6 | Borders, lines, non-agent boxes |
| Agent highlight | #2dd4bf | Fazm agent box, animated dots, bold text |
| Dark accent | #0d9488 | Arrow labels, connection lines |
| Text primary | #e2e8f0 | Headings, labels inside SVG |
| Text secondary | #94a3b8 | Sub-labels, captions |
| Warning | #f59e0b | Warning callouts |
| Error | #ef4444 | Error callouts |
Never use: indigo (#6366f1), purple (#818cf8, #8b5cf6), or blue (#3b82f6).
CSS classes for the page body use the site's design tokens: text-white, text-muted, text-accent, bg-surface-light/50, border-white/5, border-accent/20.
Required Metadata
export const metadata: Metadata = {
title: "AI {Topic} Automation for Mac - {Subtitle} | Fazm",
description: "155-160 char meta description with primary keyword naturally included.",
keywords: [
"primary keyword",
"primary keyword mac",
"variation 1",
"variation 2",
"variation 3",
"variation 4",
],
alternates: { canonical: "https://fazm.ai/{route}/{slug}" },
openGraph: {
title: "AI {Topic} Automation for Mac - Fazm",
description: "Short OG description under 200 chars.",
type: "website",
url: "https://fazm.ai/{route}/{slug}",
siteName: "Fazm",
},
twitter: {
card: "summary_large_image",
title: "AI {Topic} Automation for Mac - Fazm",
description: "Short Twitter description.",
},
};
Required JSON-LD (4 blocks)
Every page must include these 4 structured data blocks in a jsonLd array:
1. WebPage
{
"@context": "https://schema.org",
"@type": "WebPage",
name: "AI {Topic} Automation for Mac",
description: "Same as meta description.",
url: "https://fazm.ai/{route}/{slug}",
}
2. BreadcrumbList
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: [
{ "@type": "ListItem", position: 1, name: "Home", item: "https://fazm.ai" },
{ "@type": "ListItem", position: 2, name: "{Section}", item: "https://fazm.ai/{route}" },
{ "@type": "ListItem", position: 3, name: "AI {Topic} Automation", item: "https://fazm.ai/{route}/{slug}" },
],
}
3. HowTo
4 steps. Always follows this pattern:
{
"@context": "https://schema.org",
"@type": "HowTo",
name: "How to Automate {Topic} with Fazm",
description: "Step-by-step guide to automating {topic} on macOS.",
step: [
{ "@type": "HowToStep", position: 1, name: "Download Fazm", text: "Download and install Fazm on your Mac from fazm.ai/download." },
{ "@type": "HowToStep", position: 2, name: "Open {relevant app}", text: "Open {app} on your Mac..." },
{ "@type": "HowToStep", position: 3, name: "Describe the task", text: "Tell Fazm what to do..." },
{ "@type": "HowToStep", position: 4, name: "Fazm handles it", text: "Fazm navigates your app..." },
],
}
4. FAQPage
4 Q&A pairs. First FAQ differentiates Fazm from cloud competitors. Must match the FAQ section content exactly.
{
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: [
{
"@type": "Question",
name: "How is Fazm different from {competitor}?",
acceptedAnswer: { "@type": "Answer", text: "..." },
},
],
}
The 11 Required Sections
Every SEO page must have all 11 sections in this exact order.
Section 1: Breadcrumbs
<nav aria-label="Breadcrumb" className="mb-8">
<ol className="flex items-center gap-2 text-sm text-muted">
<li><Link href="/" className="hover:text-white transition-colors">Home</Link></li>
<li>/</li>
<li><Link href="/{route}" className="hover:text-white transition-colors">{Section}</Link></li>
<li>/</li>
<li className="text-white">AI {Topic} Automation</li>
</ol>
</nav>
Section 2: H1 + Lede
<h1 className="text-4xl sm:text-5xl font-bold text-white mb-6">
AI {Topic} Automation for macOS
</h1>
<p className="text-lg text-muted max-w-3xl mb-8">
{2-4 sentences. Lead with a concrete stat or pain point. Explain why every
existing tool is cloud/SaaS. Position Fazm as the desktop agent alternative.
No filler, no marketing fluff.}
</p>
Section 3: Hero Animated SVG
A flow diagram showing data moving through Fazm to target apps. Must include SMIL <animate> elements for moving dots.
Layout: Source (left) -> Fazm Agent (center) -> Target Apps (right, stacked 2-3)
<div className="my-8 max-w-lg mx-auto">
<svg viewBox="0 0 400 120" className="w-full" xmlns="http://www.w3.org/2000/svg">
{/* Source box */}
<rect x="10" y="35" width="90" height="50" rx="10"
fill="#1e293b" stroke="#14b8a6" strokeWidth="2" />
<text x="55" y="58" textAnchor="middle" fill="#e2e8f0"
fontSize="11" fontFamily="sans-serif">{Source}</text>
<text x="55" y="73" textAnchor="middle" fill="#94a3b8"
fontSize="9" fontFamily="sans-serif">{Subtitle}</text>
{/* Fazm agent box - slightly larger, brighter stroke */}
<rect x="155" y="30" width="90" height="60" rx="10"
fill="#1e293b" stroke="#2dd4bf" strokeWidth="2.5" />
<text x="200" y="57" textAnchor="middle" fill="#2dd4bf"
fontSize="12" fontWeight="bold" fontFamily="sans-serif">Fazm</text>
<text x="200" y="73" textAnchor="middle" fill="#94a3b8"
fontSize="9" fontFamily="sans-serif">AI Agent</text>
{/* Target boxes - 3 stacked on right */}
<rect x="300" y="10" width="90" height="30" rx="6"
fill="#1e293b" stroke="#14b8a6" strokeWidth="1.5" />
<text x="345" y="30" textAnchor="middle" fill="#e2e8f0"
fontSize="10" fontFamily="sans-serif">{App1}</text>
<rect x="300" y="48" width="90" height="30" rx="6"
fill="#1e293b" stroke="#14b8a6" strokeWidth="1.5" />
<text x="345" y="68" textAnchor="middle" fill="#e2e8f0"
fontSize="10" fontFamily="sans-serif">{App2}</text>
<rect x="300" y="86" width="90" height="30" rx="6"
fill="#1e293b" stroke="#14b8a6" strokeWidth="1.5" />
<text x="345" y="106" textAnchor="middle" fill="#e2e8f0"
fontSize="10" fontFamily="sans-serif">{App3}</text>
{/* Dashed connection lines */}
<line x1="100" y1="60" x2="155" y2="60"
stroke="#0d9488" strokeWidth="1.5" strokeDasharray="4 3" opacity="0.5" />
<line x1="245" y1="50" x2="300" y2="25"
stroke="#0d9488" strokeWidth="1.5" strokeDasharray="4 3" opacity="0.5" />
<line x1="245" y1="60" x2="300" y2="63"
stroke="#0d9488" strokeWidth="1.5" strokeDasharray="4 3" opacity="0.5" />
<line x1="245" y1="70" x2="300" y2="101"
stroke="#0d9488" strokeWidth="1.5" strokeDasharray="4 3" opacity="0.5" />
{/* Animated dots - 2 dots with staggered timing */}
<circle r="4" fill="#2dd4bf">
<animate attributeName="cx" values="100;155;245;300" dur="2.5s" repeatCount="indefinite" />
<animate attributeName="cy" values="60;60;50;25" dur="2.5s" repeatCount="indefinite" />
<animate attributeName="opacity" values="1;0.8;0.6;1" dur="2.5s" repeatCount="indefinite" />
</circle>
<circle r="4" fill="#14b8a6">
<animate attributeName="cx" values="100;155;245;300" dur="2.5s" repeatCount="indefinite" begin="0.8s" />
<animate attributeName="cy" values="60;60;60;63" dur="2.5s" repeatCount="indefinite" begin="0.8s" />
<animate attributeName="opacity" values="1;0.8;0.6;1" dur="2.5s" repeatCount="indefinite" begin="0.8s" />
</circle>
</svg>
</div>