feat: landing page mvp

This commit is contained in:
Nik L
2026-03-09 13:39:15 -04:00
commit 4a1d666ee2
28 changed files with 3441 additions and 0 deletions

183
app/globals.css Normal file
View File

@@ -0,0 +1,183 @@
@import 'tailwindcss';
@import 'tw-animate-css';
@custom-variant dark (&:is(.dark *));
:root {
--background: 240 240 236;
--foreground: 22 22 20;
--card: 249 249 247;
--card-foreground: 22 22 20;
--popover: 249 249 247;
--popover-foreground: 22 22 20;
--primary: 217 94 42;
--primary-foreground: 249 249 247;
--secondary: 240 240 236;
--secondary-foreground: 47 47 44;
--muted: 240 240 236;
--muted-foreground: 87 87 83;
--accent: 221 221 215;
--accent-foreground: 22 22 20;
--destructive: 180 50 50;
--destructive-foreground: 249 249 247;
--border: 196 196 189;
--input: 196 196 189;
--ring: 217 94 42;
--radius: 0.375rem;
}
.dark {
--background: 22 22 20;
--foreground: 249 249 247;
--card: 47 47 44;
--card-foreground: 249 249 247;
--popover: 47 47 44;
--popover-foreground: 249 249 247;
--primary: 217 94 42;
--primary-foreground: 249 249 247;
--secondary: 87 87 83;
--secondary-foreground: 249 249 247;
--muted: 87 87 83;
--muted-foreground: 196 196 189;
--accent: 87 87 83;
--accent-foreground: 249 249 247;
--destructive: 180 50 50;
--destructive-foreground: 249 249 247;
--border: 87 87 83;
--input: 87 87 83;
--ring: 217 94 42;
}
@theme inline {
--font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif;
--font-serif: 'Source Serif 4', 'Source Serif Pro', Georgia, serif;
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
--color-background: rgb(var(--background));
--color-foreground: rgb(var(--foreground));
--color-card: rgb(var(--card));
--color-card-foreground: rgb(var(--card-foreground));
--color-popover: rgb(var(--popover));
--color-popover-foreground: rgb(var(--popover-foreground));
--color-primary: rgb(var(--primary));
--color-primary-foreground: rgb(var(--primary-foreground));
--color-secondary: rgb(var(--secondary));
--color-secondary-foreground: rgb(var(--secondary-foreground));
--color-muted: rgb(var(--muted));
--color-muted-foreground: rgb(var(--muted-foreground));
--color-accent: rgb(var(--accent));
--color-accent-foreground: rgb(var(--accent-foreground));
--color-destructive: rgb(var(--destructive));
--color-destructive-foreground: rgb(var(--destructive-foreground));
--color-border: rgb(var(--border));
--color-input: rgb(var(--input));
--color-ring: rgb(var(--ring));
--radius-sm: calc(var(--radius) - 2px);
--radius-md: var(--radius);
--radius-lg: calc(var(--radius) + 2px);
--radius-xl: calc(var(--radius) + 4px);
--color-greyhaven-orange: #D95E2A;
--color-greyhaven-offblack: #161614;
--color-greyhaven-offwhite: #F9F9F7;
--color-greyhaven-grey1: #F0F0EC;
--color-greyhaven-grey2: #DDDDD7;
--color-greyhaven-grey3: #C4C4BD;
--color-greyhaven-grey4: #A6A69F;
--color-greyhaven-grey5: #7F7F79;
--color-greyhaven-grey7: #575753;
--color-greyhaven-grey8: #2F2F2C;
}
@layer base {
* {
@apply border-border outline-ring/50;
}
html {
scroll-behavior: smooth;
}
body {
@apply bg-background text-foreground;
}
}
/* Code block styling */
.code-block {
background: rgb(30 30 27);
border: 1px solid rgb(var(--border));
border-radius: var(--radius-lg);
}
/* Subtle glow effect for primary elements */
.glow-orange {
box-shadow: 0 0 40px rgba(217, 94, 42, 0.08);
}
/* Terminal prompt styling */
.terminal-line::before {
content: '$ ';
color: rgb(var(--muted-foreground));
}
/* Smooth section transitions */
section {
scroll-margin-top: 5rem;
}
/* Custom scrollbar for dark theme */
.dark ::-webkit-scrollbar {
width: 8px;
}
.dark ::-webkit-scrollbar-track {
background: rgb(22 22 20);
}
.dark ::-webkit-scrollbar-thumb {
background: rgb(87 87 83);
border-radius: 4px;
}
/* Animated gradient border */
@keyframes border-glow {
0%, 100% { opacity: 0.3; }
50% { opacity: 0.6; }
}
.border-glow {
animation: border-glow 3s ease-in-out infinite;
}
/* Layer card hover effect */
.layer-card {
transition: all 0.3s ease;
}
.layer-card:hover {
transform: translateY(-2px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
}
/* Fade in animation for sections */
@keyframes fade-up {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fade-up {
animation: fade-up 0.6s ease-out forwards;
}
/* Stagger children */
.stagger-children > * {
opacity: 0;
animation: fade-up 0.5s ease-out forwards;
}
.stagger-children > *:nth-child(1) { animation-delay: 0.1s; }
.stagger-children > *:nth-child(2) { animation-delay: 0.2s; }
.stagger-children > *:nth-child(3) { animation-delay: 0.3s; }
.stagger-children > *:nth-child(4) { animation-delay: 0.4s; }
.stagger-children > *:nth-child(5) { animation-delay: 0.5s; }

38
app/layout.tsx Normal file
View File

@@ -0,0 +1,38 @@
import type { Metadata } from 'next'
import './globals.css'
export const metadata: Metadata = {
title: 'Greywall — Sandbox for AI Agents',
description:
'Container-free, default-deny sandboxing with real-time observability for AI coding agents. Five defense layers. One command.',
icons: {
icon: [
{ url: '/icon.svg', type: 'image/svg+xml' },
{ url: '/icon-dark-32x32.png', sizes: '32x32', type: 'image/png', media: '(prefers-color-scheme: dark)' },
{ url: '/icon-light-32x32.png', sizes: '32x32', type: 'image/png', media: '(prefers-color-scheme: light)' },
],
apple: '/apple-icon.png',
},
}
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en" className="dark">
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Source+Serif+4:ital,opsz,wght@0,8..60,400;0,8..60,500;0,8..60,600;0,8..60,700;1,8..60,400&display=swap"
rel="stylesheet"
/>
</head>
<body className="font-sans antialiased bg-background text-foreground">
{children}
</body>
</html>
)
}

30
app/page.tsx Normal file
View File

@@ -0,0 +1,30 @@
'use client'
import { PlatformProvider } from '@/components/platform-toggle'
import { Nav } from '@/components/nav'
import { Hero } from '@/components/hero'
import { Agents } from '@/components/agents'
import { Problem } from '@/components/problem'
import { Layers } from '@/components/layers'
import { Observability } from '@/components/observability'
import { Control } from '@/components/control'
import { Comparison } from '@/components/comparison'
import { Footer } from '@/components/footer'
export default function Home() {
return (
<PlatformProvider>
<main className="min-h-screen">
<Nav />
<Hero />
<Agents />
<Problem />
<Layers />
<Observability />
<Control />
<Comparison />
<Footer />
</main>
</PlatformProvider>
)
}