Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions apps/website/components.json
Original file line number Diff line number Diff line change
@@ -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"
}
6 changes: 5 additions & 1 deletion apps/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
34 changes: 34 additions & 0 deletions apps/website/src/app/global.css
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -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);
Expand All @@ -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;
}

* {
Expand Down
26 changes: 18 additions & 8 deletions apps/website/src/components/landing/FeatureStrip.tsx
Original file line number Diff line number Diff line change
@@ -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.' },
Expand All @@ -13,25 +14,34 @@ const FEATURES = [
export function FeatureStrip() {
return (
<section className="px-8 py-16 max-w-6xl mx-auto">
<h2 className="font-mono text-xs uppercase tracking-widest mb-12 text-center"
style={{ color: 'var(--color-accent)', fontWeight: 'normal' }}>Features</h2>
<h2
className="font-mono text-xs uppercase tracking-widest mb-12 text-center"
style={{ color: 'var(--color-accent)', fontWeight: 'normal' }}
>
Features
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{FEATURES.map((f, i) => (
<motion.div
key={f.title}
className="p-6 rounded-lg cursor-default"
style={{ border: '1px solid rgba(108,142,255,0.15)', background: 'rgba(108,142,255,0.02)' }}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ delay: i * 0.08, duration: 0.4 }}
whileHover={{
borderColor: 'rgba(108,142,255,0.4)',
boxShadow: '0 0 12px rgba(108,142,255,0.2)',
}}>
<div className="mb-3" style={{ fontSize: '1.5rem', color: '#6C8EFF' }} aria-hidden="true">{f.icon}</div>
<h3 style={{ fontFamily: 'var(--font-garamond)', fontWeight: 700, fontSize: '1.125rem', color: '#EEF1FF', marginBottom: 8 }}>{f.title}</h3>
<p style={{ fontSize: '0.875rem', color: '#8B96C8', lineHeight: 1.6 }}>{f.desc}</p>
}}
>
<Card className="p-6 h-full cursor-default transition-all">
<div className="mb-3 text-2xl" style={{ color: '#6C8EFF' }} aria-hidden="true">
{f.icon}
</div>
<CardTitle className="mb-2">{f.title}</CardTitle>
<CardContent className="p-0">
<p className="text-sm text-muted-foreground leading-relaxed">{f.desc}</p>
</CardContent>
</Card>
</motion.div>
))}
</div>
Expand Down
132 changes: 68 additions & 64 deletions apps/website/src/components/landing/HeroTwoCol.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<span style={{
display: 'inline-flex', alignItems: 'center', gap: 6,
background: 'rgba(108,142,255,0.08)',
border: '1px solid rgba(108,142,255,0.15)',
borderRadius: 20, padding: '4px 10px 4px 8px',
fontFamily: 'var(--font-mono)', fontSize: 11, color: '#EEF1FF',
}}>
<span style={{
width: 14, height: 14, borderRadius: 3,
background: 'rgba(127,200,255,0.2)',
border: '1px solid rgba(127,200,255,0.4)',
display: 'flex', alignItems: 'center', justifyContent: 'center',
fontSize: 7, fontWeight: 700, color: '#7FC8FF', lineHeight: 1,
}}>LC</span>
<Badge variant="default">
<span
style={{
width: 14,
height: 14,
borderRadius: 3,
background: 'rgba(127,200,255,0.2)',
border: '1px solid rgba(127,200,255,0.4)',
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 7,
fontWeight: 700,
color: '#7FC8FF',
lineHeight: 1,
flexShrink: 0,
}}
>
LC
</span>
LangChain
</span>
</Badge>
);
}

function AngularBadge() {
return (
<span style={{
display: 'inline-flex', alignItems: 'center', gap: 6,
background: 'rgba(108,142,255,0.08)',
border: '1px solid rgba(108,142,255,0.15)',
borderRadius: 20, padding: '4px 10px 4px 8px',
fontFamily: 'var(--font-mono)', fontSize: 11, color: '#EEF1FF',
}}>
<svg width="14" height="14" viewBox="0 0 250 250" aria-hidden={true}>
<path fill="#DD0031" d="M125 30L31.9 63.2l14.2 123.1L125 230l78.9-43.7 14.2-123.1z"/>
<path fill="#C3002F" d="M125 30v22.2l-61.7 162.4 37.8 15.4z"/>
<path fill="#fff" d="M125 52.1L66.8 182.6h21.7l11.7-29.2h49.4l11.7 29.2H183L125 52.1zm17 83.3h-34l17-40.9z"/>
<Badge variant="default">
<svg width="14" height="14" viewBox="0 0 250 250" aria-hidden={true} style={{ flexShrink: 0 }}>
<path fill="#DD0031" d="M125 30L31.9 63.2l14.2 123.1L125 230l78.9-43.7 14.2-123.1z" />
<path fill="#C3002F" d="M125 30v22.2l-61.7 162.4 37.8 15.4z" />
<path fill="#fff" d="M125 52.1L66.8 182.6h21.7l11.7-29.2h49.4l11.7 29.2H183L125 52.1zm17 83.3h-34l17-40.9z" />
</svg>
Angular
</span>
</Badge>
);
}

Expand All @@ -63,61 +64,64 @@ export async function HeroTwoCol() {
.hero-right { flex: none; max-width: 100%; width: 100%; max-height: 300px; overflow: hidden; }
}
`}</style>

{/* Left column — 55% */}
<div className="hero-left">
<div style={{ display: 'flex', gap: 8, marginBottom: 28, flexWrap: 'wrap' }}>
<LangChainBadge />
<AngularBadge />
</div>

<h1 id="hero-heading" style={{
fontFamily: 'var(--font-garamond)',
fontSize: 'clamp(36px, 4.5vw, 72px)',
fontWeight: 800,
lineHeight: 1.05,
color: '#EEF1FF',
margin: 0,
marginBottom: 20,
}}>
<h1
id="hero-heading"
style={{
fontFamily: 'var(--font-garamond)',
fontSize: 'clamp(36px, 4.5vw, 72px)',
fontWeight: 800,
lineHeight: 1.05,
color: '#EEF1FF',
margin: 0,
marginBottom: 20,
}}
>
The Enterprise Streaming Resource for LangChain and{' '}
<span style={{
color: '#DD0031',
textShadow: '0 0 30px rgba(221,0,49,0.5)',
}}>
<span style={{ color: '#DD0031', textShadow: '0 0 30px rgba(221,0,49,0.5)' }}>
Angular
</span>
</h1>

<p style={{
fontFamily: 'var(--font-garamond)',
fontStyle: 'italic',
fontSize: 'clamp(16px, 1.8vw, 20px)',
color: '#8B96C8',
maxWidth: '44ch',
lineHeight: 1.5,
margin: 0,
marginBottom: 32,
}}>
<p
style={{
fontFamily: 'var(--font-garamond)',
fontStyle: 'italic',
fontSize: 'clamp(16px, 1.8vw, 20px)',
color: '#8B96C8',
maxWidth: '44ch',
lineHeight: 1.5,
margin: 0,
marginBottom: 32,
}}
>
Full parity with React{' '}
<code style={{
fontStyle: 'normal',
fontFamily: 'var(--font-mono)',
fontSize: '0.8em',
background: 'rgba(108,142,255,0.08)',
color: '#6C8EFF',
padding: '2px 6px',
borderRadius: 4,
}}>useStream()</code>
<code
style={{
fontStyle: 'normal',
fontFamily: 'var(--font-mono)',
fontSize: '0.8em',
background: 'rgba(108,142,255,0.08)',
color: '#6C8EFF',
padding: '2px 6px',
borderRadius: 4,
}}
>
useStream()
</code>
{' '}— built natively for Angular 20+.
</p>

<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: 12 }}>
<CopyPromptButton prompt={prompt} variant="hero" />
<span style={{
fontFamily: 'var(--font-mono)',
fontSize: 12,
color: '#4A527A',
}}>
<span style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: '#4A527A' }}>
npm install @cacheplane/stream-resource
</span>
</div>
Expand Down
Loading