DEV Community

Dev Maya
Dev Maya

Posted on

Building an AI tool landing page with Next.js 14 — chat mockup, FAQ accordion, and zero dependencies

Building an AI tool landing page with Next.js 14

Every AI tool launching right now needs a landing page. Most of them look identical — dark mode, purple gradients, floating blobs. I wanted to build something different.

This is what I learned building Forge, an AI tool landing page template in Next.js 14.

🔗 Live demo: https://forge-ai-template.vercel.app/

Design decisions

I deliberately went against the grain:

  • Light mode with clean whites and indigo accents (#4f46e5)
  • Space Grotesk — geometric but warm, not cold like Inter
  • Grid background in the hero with CSS mask-image (no canvas, no JS)
  • Chat interface as the hero mockup instead of a generic screenshot

The goal was to feel like a well-funded AI startup, not another side project.


The hero grid background

One of my favorite CSS tricks in this project:

.grid {
  background-image:
    linear-gradient(var(--border) 1px, transparent 1px),
    linear-gradient(90deg, var(--border) 1px, transparent 1px);
  background-size: 40px 40px;
  mask-image: radial-gradient(
    ellipse 70% 50% at 50% 0%,
    black,
    transparent 70%
  );
  opacity: 0.4;
}
Enter fullscreen mode Exit fullscreen mode

The mask-image fades the grid out toward the bottom — no JavaScript, no SVG, no library. Just CSS.


The AI chat mockup

The entire chat window is pure HTML/CSS. No canvas, no external library:

.window {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  box-shadow:
    0 4px 6px rgba(0,0,0,0.05),
    0 20px 60px rgba(0,0,0,0.08);
}
Enter fullscreen mode Exit fullscreen mode

The "thinking" animation on the AI response uses staggered delays:

@keyframes thinking {
  0%, 100% { transform: translateY(0); opacity: 0.4; }
  50%       { transform: translateY(-4px); opacity: 1; }
}

.thinkDot:nth-child(2) { animation-delay: 0.2s; }
.thinkDot:nth-child(3) { animation-delay: 0.4s; }
Enter fullscreen mode Exit fullscreen mode

Three dots, staggered delays, zero JavaScript. Clean.


The FAQ accordion

This is the only component that needs 'use client' in the entire project. Everything else is server components.

'use client'
import { useState } from 'react'

export default function FAQ() {
  const [open, setOpen] = useState<number | null>(0)

  return (
    <div>
      {siteConfig.faq.map((item, i) => (
        <div key={i}>
          <button onClick={() => setOpen(open === i ? null : i)}>
            {item.question}
          </button>
          {open === i && <div>{item.answer}</div>}
        </div>
      ))}
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Simple, accessible, no animation library needed.


Single config file pattern

Everything the buyer needs to edit lives in src/lib/config.ts:

export const siteConfig = {
  name: 'YourAI',
  tagline: 'The AI that actually understands your code',
  steps: [
    { number: '01', title: 'Connect your repo', description: '...' },
    { number: '02', title: 'Ask in plain English', description: '...' },
    { number: '03', title: 'Ship production code', description: '...' },
  ],
  features: [...],
  pricing: [...],
  faq: [...],
}
Enter fullscreen mode Exit fullscreen mode

Brand name, steps, features, pricing, FAQ — all in one place. Change the file, the whole site updates. No hunting through components.


Architecture overview

src/
├── app/
│   ├── globals.css      # CSS variables & base styles
│   ├── layout.tsx       # Root layout + metadata
│   └── page.tsx         # Assembles all sections
├── components/
│   ├── sections/        # Navbar, Hero, Features, Pricing, FAQ...
│   └── ui/              # ChatMockup
└── lib/
    └── config.ts        # ← Edit this to customize everything
Enter fullscreen mode Exit fullscreen mode

The only 'use client' boundary is FAQ.tsx. Every other section is a server component — better performance, simpler mental model.


Sections included

  • Sticky navbar with blur on scroll
  • Hero with animated chat mockup + grid background
  • Social proof bar (stats)
  • How it works (3 steps with dashed connector)
  • Features grid (dark background section)
  • Pricing table (3 tiers, featured plan)
  • FAQ accordion (interactive)
  • CTA banner
  • Footer

Lessons learned

Keep 'use client' boundaries minimal. The FAQ is the only interactive element that truly needs client-side state. Everything else benefits from being a server component.

CSS variables pay for themselves. Having all colors in :root meant changing the entire indigo palette took 2 lines.

The config file is the product. Buyers don't care about the components — they care about how fast they can make it theirs. A single file with clear comments is worth more than any design decision.


🔗 Live demo: https://forge-ai-template.vercel.app
🛒 Available on Gumroad: https://devmaya.gumroad.com/l/njzbkz

If you have questions about any implementation detail, drop them in the comments — happy to go deeper.

Top comments (0)