Frontend Architecture
import { FileTree } from ‘@astrojs/starlight/components’;
Framework
Next.js 15 (App Router) deployed on Vercel Edge Network.
The frontend is a hybrid SSG/SSR application — static pages pre-rendered at build time, dynamic API routes running at the edge.
Directory Structure
Routing Model
| Route | Rendering | Notes |
|---|---|---|
/ | SSG | Hero + full marketing page |
/speaking | SSG | Services grid |
/consulting | SSG | Consulting detail |
/podcast | ISR (60s) | Fetches RSS feed at build + revalidates |
/media | SSG | Press grid, logo bar |
/contact | SSG | Static form shell; submission via Server Action |
/api/booking | Edge Function | Form handler |
/api/media-kit | Edge Function | Email gate + signed URL |
Design System
Typography
| Token | Font | Weight | Usage |
|---|---|---|---|
--font-display | Bebas Neue | 400 | Hero headlines, section labels |
--font-body | Inter | 400/500/600 | Body copy, UI text |
--font-mono | JetBrains Mono | 400 | Code blocks, case file labels |
Color Tokens
/* Terminal Layer (70% of UI) */--brand-black: #0A0A0A;--brand-charcoal: #1A1A1A;--brand-gray: #2D2D2D;--brand-muted: #4A4A4A;
/* Authority Layer (20% accent) */--brand-red: #CC0000;--brand-red-dim: #990000;--brand-red-glow: rgba(204,0,0,0.15);
/* Signal Layer (10% utility) */--brand-white: #F5F5F5;--brand-cream: #E8E0D0;--brand-green: #00FF41; /* terminal green — used sparingly */Animation Strategy
Framer Motion handles all page transitions and scroll-reveal animations.
Key patterns:
- Entry animations:
fadeInUpon section mount (stagger children) - Hero ticker: CSS
marqueeinfinite scroll for press logos - CTA hover: subtle
scale(1.02)+ red glow shadow - Form submit: spinner state, success/error feedback
Performance Targets
| Metric | Target | Gate |
|---|---|---|
| LCP | < 2.5s | Lighthouse CI |
| CLS | < 0.1 | Lighthouse CI |
| INP | < 200ms | Lighthouse CI |
| Lighthouse Score | ≥ 90 (all categories) | CI blocks merge on failure |
Component Conventions
- Components use named exports only (no default exports)
- Props interfaces defined inline above the component
- Tailwind only — no inline styles, no CSS modules
- Server Components by default;
"use client"only for interactive islands - All images via
next/imagewith explicitwidth/height
SEO & Metadata
Each page exports a generateMetadata() function returning:
title,description,openGraph,twittercards- Canonical URL
- Structured data injected via
<script type="application/ld+json">
Dynamic OG images generated via @vercel/og at /api/og?page=....