From 91c6ed94f15095d16985ff55f55feaefa085e10e Mon Sep 17 00:00:00 2001 From: Chris Anderson Date: Wed, 24 Jun 2026 10:36:40 +0200 Subject: [PATCH] Rebuild hatch.surf with Next.js - Recreated old website with Next.js 16 + Tailwind CSS - Hero section with terminal animation - Features section (Capture, Inspect, Mock) - Why section (Compliance, Cost, Speed) - CTA section - Header and Footer components - Dark theme with Inter + JetBrains Mono fonts - Static export for Docker deployment Co-Authored-By: Paperclip --- app/globals.css | 75 ++++++++++++++++++++++++++++++++--------- app/layout.tsx | 50 ++++++++++++++++++++------- app/page.tsx | 72 ++++++--------------------------------- components/CTA.tsx | 20 +++++++++++ components/Features.tsx | 61 +++++++++++++++++++++++++++++++++ components/Footer.tsx | 29 ++++++++++++++++ components/Header.tsx | 25 ++++++++++++++ components/Hero.tsx | 62 ++++++++++++++++++++++++++++++++++ components/Why.tsx | 55 ++++++++++++++++++++++++++++++ deploy.sh | 0 next.config.ts | 3 ++ 11 files changed, 363 insertions(+), 89 deletions(-) create mode 100644 components/CTA.tsx create mode 100644 components/Features.tsx create mode 100644 components/Footer.tsx create mode 100644 components/Header.tsx create mode 100644 components/Hero.tsx create mode 100644 components/Why.tsx mode change 100644 => 100755 deploy.sh diff --git a/app/globals.css b/app/globals.css index a2dc41ec..44371d21 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,26 +1,69 @@ -@import "tailwindcss"; +@tailwind base; +@tailwind components; +@tailwind utilities; :root { - --background: #ffffff; - --foreground: #171717; + --surface-0: #09090b; + --surface-1: #111114; + --surface-2: #1a1a1f; + --surface-3: #232328; + --brand: #3b82f6; + --brand-dim: #2563eb; + --text-primary: #fafafa; + --text-secondary: #a1a1aa; + --text-tertiary: #71717a; + --text-code: #e879f9; + --code-bg: #18181b; + --code-border: #27272a; } -@theme inline { - --color-background: var(--background); - --color-foreground: var(--foreground); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); +* { + margin: 0; + padding: 0; + box-sizing: border-box; } -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } +html { + font-size: 16px; + line-height: 1.6; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } body { - background: var(--background); - color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + font-family: var(--font-inter), -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + color: var(--text-primary); + background-color: var(--surface-0); + overflow-x: hidden; +} + +a { + color: var(--brand); + text-decoration: none; + transition: color 150ms cubic-bezier(0.16, 1, 0.3, 1); +} + +a:hover { + color: var(--text-primary); +} + +code { + font-family: var(--font-mono), 'SFMono-Regular', Consolas, monospace; + font-size: 0.875em; + background-color: var(--code-bg); + border: 1px solid var(--code-border); + padding: 0.15em 0.4em; + border-radius: 6px; + color: var(--text-code); +} + +/* Particle canvas */ +#particle-canvas { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 0; + pointer-events: none; } diff --git a/app/layout.tsx b/app/layout.tsx index 976eb90d..06214205 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,20 +1,45 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; +import { Inter, JetBrains_Mono } from "next/font/google"; import "./globals.css"; +import Header from "@/components/Header"; +import Footer from "@/components/Footer"; -const geistSans = Geist({ - variable: "--font-geist-sans", +const inter = Inter({ subsets: ["latin"], + variable: "--font-inter", }); -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", +const jetbrainsMono = JetBrains_Mono({ subsets: ["latin"], + variable: "--font-mono", }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Hatch — Self-hostable HTTP request inspector + mocker", + description: "Hatch is a self-hostable HTTP request inspector and mocker. One Go binary, SQLite, no SaaS, no per-request fee. Open source, MIT.", + openGraph: { + title: "Hatch — Self-hostable HTTP request inspector + mocker", + description: "Hatch is a self-hostable HTTP request inspector and mocker. One Go binary, SQLite, no SaaS, no per-request fee. Open source, MIT.", + url: "https://hatch.surf", + siteName: "Hatch", + images: [ + { + url: "/brand/og/default.png", + width: 1200, + height: 630, + }, + ], + type: "website", + }, + twitter: { + card: "summary_large_image", + title: "Hatch — Self-hostable HTTP request inspector + mocker", + description: "Hatch is a self-hostable HTTP request inspector and mocker. One Go binary, SQLite, no SaaS, no per-request fee. Open source, MIT.", + images: ["/brand/og/default.png"], + }, + icons: { + icon: "/brand/favicon/favicon-48.png", + }, }; export default function RootLayout({ @@ -23,11 +48,12 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - - {children} + + +
+ {children} +