feat: add shared design tokens, JetBrains Mono font, and fix cn() utility

- Add CSS custom properties for surfaces, text, borders, accent, radius, font stacks
- Add JetBrains Mono via next/font/google alongside Inter (both as CSS variables)
- Upgrade cn() from naive filter/join to twMerge(clsx()) for proper Tailwind class merging
- Standardize marketing section containers from max-w-7xl to max-w-6xl
- Install tailwind-merge and clsx dependencies
This commit is contained in:
Vectry
2026-02-10 17:22:45 +00:00
parent cccb3123ed
commit f9e7956e6f
6 changed files with 75 additions and 11 deletions

View File

@@ -1 +1,38 @@
@import "tailwindcss";
@layer base {
:root {
/* Surfaces */
--surface-page: #0a0a0a;
--surface-card: rgb(23 23 23); /* neutral-900 */
--surface-card-hover: rgb(38 38 38 / 0.5); /* neutral-800/50 */
--surface-elevated: rgb(23 23 23); /* neutral-900 */
--surface-input: rgb(10 10 10); /* neutral-950 */
/* Text */
--text-primary: rgb(245 245 245); /* neutral-100 */
--text-secondary: rgb(163 163 163); /* neutral-400 */
--text-muted: rgb(115 115 115); /* neutral-500 */
/* Borders */
--border-default: rgb(38 38 38); /* neutral-800 */
--border-subtle: rgb(38 38 38 / 0.5); /* neutral-800/50 */
--border-strong: rgb(64 64 64); /* neutral-700 */
/* Accent (AgentLens emerald) */
--accent: #10b981;
--accent-hover: #34d399;
--accent-muted: rgba(16, 185, 129, 0.15);
--accent-foreground: #0a0a0a;
/* Radius */
--radius-card: 1rem;
--radius-button: 0.5rem;
--radius-icon: 0.75rem;
--radius-badge: 9999px;
/* Fonts */
--font-sans: var(--font-inter), system-ui, sans-serif;
--font-mono: var(--font-jetbrains), 'JetBrains Mono', 'Fira Code', monospace;
}
}

View File

@@ -1,9 +1,10 @@
import { Inter } from "next/font/google";
import { Inter, JetBrains_Mono } from "next/font/google";
import type { Metadata } from "next";
import { SessionProvider } from "next-auth/react";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
const inter = Inter({ subsets: ["latin"], variable: "--font-inter", display: "swap" });
const jetbrainsMono = JetBrains_Mono({ subsets: ["latin"], variable: "--font-jetbrains", display: "swap" });
export const metadata: Metadata = {
metadataBase: new URL("https://agentlens.vectry.tech"),
@@ -72,7 +73,7 @@ export default function RootLayout({
}>) {
return (
<html lang="en" className="dark">
<body className={`${inter.className} bg-neutral-950 text-neutral-100 antialiased`}>
<body className={`${inter.variable} ${jetbrainsMono.variable} bg-neutral-950 text-neutral-100 antialiased`}>
<SessionProvider>{children}</SessionProvider>
</body>
</html>

View File

@@ -95,7 +95,7 @@ export default function HomePage() {
{/* Subtle grid pattern for depth */}
<div className="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.012)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.012)_1px,transparent_1px)] bg-[size:64px_64px]" />
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-20 pb-24">
<div className="relative max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 pt-20 pb-24">
<div className="text-center">
{/* Top badges row */}
<div className="flex flex-wrap items-center justify-center gap-3 mb-8">
@@ -160,7 +160,7 @@ export default function HomePage() {
{/* Features Section */}
<section className="py-24 border-b border-neutral-800/50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<h2 className="text-3xl sm:text-4xl font-bold mb-4">
Everything you need to understand your agents
@@ -210,7 +210,7 @@ export default function HomePage() {
{/* How it Works Section */}
<section className="py-24 border-b border-neutral-800/50 relative">
<div className="absolute inset-0 bg-[radial-gradient(ellipse_60%_40%_at_50%_50%,rgba(16,185,129,0.04),transparent)]" />
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="relative max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-neutral-700 bg-neutral-800/30 text-neutral-400 text-sm mb-6">
<Zap className="w-4 h-4" />
@@ -300,7 +300,7 @@ export default function HomePage() {
{/* Code Example Section */}
<section className="py-24 border-b border-neutral-800/50">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="grid lg:grid-cols-2 gap-12 items-start">
<div className="lg:sticky lg:top-8">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-neutral-700 bg-neutral-800/30 text-neutral-400 text-sm mb-6">
@@ -487,7 +487,7 @@ export default function HomePage() {
{/* Integrations Section */}
<section className="py-24 border-b border-neutral-800/50 relative">
<div className="absolute inset-0 bg-[radial-gradient(ellipse_50%_50%_at_50%_50%,rgba(16,185,129,0.03),transparent)]" />
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="relative max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-neutral-700 bg-neutral-800/30 text-neutral-400 text-sm mb-6">
<Link2 className="w-4 h-4" />
@@ -544,7 +544,7 @@ export default function HomePage() {
{/* Pricing Section */}
<section className="py-24 border-b border-neutral-800/50 relative">
<div className="absolute inset-0 bg-[radial-gradient(ellipse_70%_50%_at_50%_50%,rgba(16,185,129,0.04),transparent)]" />
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="relative max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full border border-neutral-700 bg-neutral-800/30 text-neutral-400 text-sm mb-6">
<Shield className="w-4 h-4" />

View File

@@ -19,6 +19,9 @@ export function formatRelativeTime(date: string | Date): string {
return `${diffDay}d ago`;
}
export function cn(...classes: (string | boolean | undefined | null)[]): string {
return classes.filter(Boolean).join(" ");
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}