diff --git a/apps/website/components.json b/apps/website/components.json new file mode 100644 index 000000000..93b584cf6 --- /dev/null +++ b/apps/website/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/app/global.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} diff --git a/apps/website/package.json b/apps/website/package.json index cc69ee2c1..432100f25 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -3,9 +3,13 @@ "version": "0.0.1", "private": true, "dependencies": { + "@radix-ui/react-slot": "^1.1.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", "next": "~16.1.6", "react": "^19.0.0", "react-dom": "^19.0.0", - "shiki": "*" + "shiki": "*", + "tailwind-merge": "^2.5.0" } } diff --git a/apps/website/src/app/global.css b/apps/website/src/app/global.css index 2b83225be..bfdf8fb5e 100644 --- a/apps/website/src/app/global.css +++ b/apps/website/src/app/global.css @@ -1,6 +1,7 @@ @import "tailwindcss"; @theme { + /* Existing design tokens — preserved for backward compat */ --color-bg: #080B14; --color-accent: #6C8EFF; --color-accent-glow: rgba(108, 142, 255, 0.35); @@ -18,7 +19,25 @@ --font-mono: "JetBrains Mono", monospace; } +/* shadcn CSS variable tokens — new, non-conflicting names */ +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); +} + :root { + /* Existing legacy vars */ --color-bg: #080B14; --color-accent: #6C8EFF; --color-accent-glow: rgba(108, 142, 255, 0.35); @@ -30,6 +49,21 @@ --color-text-muted: #4A527A; --color-sidebar-bg: #0A0D18; --color-angular-red: #DD0031; + + /* shadcn semantic vars — maps to same palette */ + --background: #080B14; + --foreground: #EEF1FF; + --primary: #6C8EFF; + --primary-foreground: #ffffff; + --card: #0A0D18; + --card-foreground: #EEF1FF; + --muted: #0D1020; + --muted-foreground: #8B96C8; + --border: #1a2040; + --input: #1a2040; + --ring: #6C8EFF; + --destructive: #FF6B6B; + --destructive-foreground: #ffffff; } * { diff --git a/apps/website/src/components/landing/FeatureStrip.tsx b/apps/website/src/components/landing/FeatureStrip.tsx index 133e5f09b..7d3f61a0e 100644 --- a/apps/website/src/components/landing/FeatureStrip.tsx +++ b/apps/website/src/components/landing/FeatureStrip.tsx @@ -1,5 +1,6 @@ 'use client'; import { motion } from 'framer-motion'; +import { Card, CardContent, CardTitle } from '@/components/ui/card'; const FEATURES = [ { icon: '⚡', title: 'Token-by-token streaming', desc: 'Real-time SSE streaming via FetchStreamTransport. Messages update as each token arrives.' }, @@ -13,14 +14,16 @@ const FEATURES = [ export function FeatureStrip() { return (
-

Features

+

+ Features +

{FEATURES.map((f, i) => ( - -

{f.title}

-

{f.desc}

+ }} + > + + + {f.title} + +

{f.desc}

+
+
))}
diff --git a/apps/website/src/components/landing/HeroTwoCol.tsx b/apps/website/src/components/landing/HeroTwoCol.tsx index b1364cecb..a801db800 100644 --- a/apps/website/src/components/landing/HeroTwoCol.tsx +++ b/apps/website/src/components/landing/HeroTwoCol.tsx @@ -1,44 +1,45 @@ import { GenerativeUIFrame } from './GenerativeUIFrame'; import { CopyPromptButton } from '../docs/CopyPromptButton'; import { getPromptBySlug } from '../../lib/docs'; +import { Badge } from '@/components/ui/badge'; function LangChainBadge() { return ( - - LC + + + LC + LangChain - + ); } function AngularBadge() { return ( - - - - - + + + + + Angular - + ); } @@ -63,6 +64,7 @@ export async function HeroTwoCol() { .hero-right { flex: none; max-width: 100%; width: 100%; max-height: 300px; overflow: hidden; } } `} + {/* Left column — 55% */}
@@ -70,54 +72,56 @@ export async function HeroTwoCol() {
-

+

The Enterprise Streaming Resource for LangChain and{' '} - + Angular

-

+

Full parity with React{' '} - useStream() + + useStream() + {' '}— built natively for Angular 20+.

- + npm install @cacheplane/stream-resource
diff --git a/apps/website/src/components/pricing/LeadForm.tsx b/apps/website/src/components/pricing/LeadForm.tsx index 063f8743c..f63020277 100644 --- a/apps/website/src/components/pricing/LeadForm.tsx +++ b/apps/website/src/components/pricing/LeadForm.tsx @@ -1,5 +1,9 @@ 'use client'; import { useState } from 'react'; +import { Input } from '@/components/ui/input'; +import { Textarea } from '@/components/ui/textarea'; +import { Label } from '@/components/ui/label'; +import { Button } from '@/components/ui/button'; export function LeadForm() { const [status, setStatus] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle'); @@ -21,21 +25,14 @@ export function LeadForm() { } }; - const inputStyle: React.CSSProperties = { - background: 'rgba(108,142,255,0.04)', - border: '1px solid rgba(108,142,255,0.15)', - color: '#EEF1FF', - borderRadius: '6px', - padding: '10px 14px', - width: '100%', - fontFamily: 'var(--font-sans)', - fontSize: '14px', - outline: 'none', - }; - return (
-

Enterprise

+

+ Enterprise +

+ }} + > Need volume seats or a custom contract?

+ {status === 'sent' ? ( -

Thanks — we'll be in touch within one business day.

+

+ Thanks — we'll be in touch within one business day. +

) : (
- { e.target.style.borderColor = '#6C8EFF'; e.target.style.outline = '2px solid rgba(108,142,255,0.4)'; e.target.style.outlineOffset = '2px'; }} - onBlur={(e) => { e.target.style.borderColor = 'rgba(108,142,255,0.15)'; e.target.style.outline = 'none'; }} - /> - { e.target.style.borderColor = '#6C8EFF'; e.target.style.outline = '2px solid rgba(108,142,255,0.4)'; e.target.style.outlineOffset = '2px'; }} - onBlur={(e) => { e.target.style.borderColor = 'rgba(108,142,255,0.15)'; e.target.style.outline = 'none'; }} - /> - { e.target.style.borderColor = '#6C8EFF'; e.target.style.outline = '2px solid rgba(108,142,255,0.4)'; e.target.style.outlineOffset = '2px'; }} - onBlur={(e) => { e.target.style.borderColor = 'rgba(108,142,255,0.15)'; e.target.style.outline = 'none'; }} - /> -