diff --git a/apps/demo/slides/llmgateway/index.tsx b/apps/demo/slides/llmgateway/index.tsx
new file mode 100644
index 00000000..608e81be
--- /dev/null
+++ b/apps/demo/slides/llmgateway/index.tsx
@@ -0,0 +1,749 @@
+import type { DesignSystem, Page, SlideMeta } from '@open-slide/core';
+import type { ReactNode } from 'react';
+
+export const design: DesignSystem = {
+ palette: {
+ bg: '#0a0a12',
+ text: '#ededf4',
+ accent: '#a78bfa',
+ },
+ fonts: {
+ display: '"Inter", "SF Pro Display", system-ui, -apple-system, sans-serif',
+ body: '"Inter", "SF Pro Display", system-ui, -apple-system, sans-serif',
+ },
+ typeScale: {
+ hero: 168,
+ body: 36,
+ },
+ radius: 14,
+};
+
+const palette = {
+ surface: '#12121a',
+ surfaceHi: '#1a1a26',
+ border: 'rgba(255,255,255,0.08)',
+ borderBright: 'rgba(255,255,255,0.16)',
+ textSoft: '#cccddc',
+ muted: '#7d7e8f',
+ dim: '#42434f',
+ accentSoft: 'rgba(167,139,250,0.14)',
+ green: '#7ee787',
+ pink: '#ff9eb5',
+ amber: '#fbbf24',
+ blue: '#60a5fa',
+};
+
+const font = {
+ display: design.fonts.display,
+ body: design.fonts.body,
+ mono: '"JetBrains Mono", "SF Mono", ui-monospace, Menlo, monospace',
+};
+
+const fill = {
+ width: '100%',
+ height: '100%',
+ background: 'var(--osd-bg)',
+ color: 'var(--osd-text)',
+ fontFamily: 'var(--osd-font-body)',
+ letterSpacing: '-0.015em',
+ position: 'relative' as const,
+ overflow: 'hidden',
+} as const;
+
+const keyframes = `
+ @keyframes llg-fadeUp {
+ from { opacity: 0; transform: translateY(20px); }
+ to { opacity: 1; transform: translateY(0); }
+ }
+ @keyframes llg-fadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+ }
+ @keyframes llg-pulse {
+ 0%, 100% { opacity: 0.55; }
+ 50% { opacity: 1; }
+ }
+ @keyframes llg-drift {
+ 0% { transform: translateY(0px); }
+ 50% { transform: translateY(-12px); }
+ 100% { transform: translateY(0px); }
+ }
+`;
+
+const Style = () => ;
+
+const fadeUp = (delayMs: number) =>
+ ({
+ animation: `llg-fadeUp 700ms cubic-bezier(0.2, 0.7, 0.2, 1) ${delayMs}ms both`,
+ }) as const;
+
+const fadeIn = (delayMs: number) =>
+ ({
+ animation: `llg-fadeIn 800ms ease-out ${delayMs}ms both`,
+ }) as const;
+
+const GridBg = ({ opacity = 0.04 }: { opacity?: number }) => (
+
+);
+
+const GlowBlob = ({
+ top,
+ left,
+ size = 720,
+ color = 'var(--osd-accent)',
+ opacity = 0.18,
+}: {
+ top?: number | string;
+ left?: number | string;
+ size?: number;
+ color?: string;
+ opacity?: number;
+}) => (
+
+);
+
+const eyebrow = (n: string, label: string) => (
+
+ {n}
+ ·
+ {label}
+
+);
+
+// ─── 01 · Cover ───────────────────────────────────────────────────────────────
+const Cover: Page = () => (
+
+
+
+
+
+
+
+
+ Introducing
+
+
+
+ LLMGateway
+
+
+
+ Every model behind one key{' '}
+ — and one API surface.
+
+
+
+ llmgateway.io
+
+ AI SDK provider
+ ·
+ {new Date().getFullYear()}
+
+
+
+);
+
+// ─── 02 · The problem ─────────────────────────────────────────────────────────
+const ProviderChip = ({
+ name,
+ delay,
+ dim = false,
+}: {
+ name: string;
+ delay: number;
+ dim?: boolean;
+}) => (
+
+ {name}
+
+);
+
+const Problem: Page = () => (
+
+
+
+ {eyebrow('01', 'The problem')}
+
+
+ Five providers.{' '}
+ Five SDKs. Five keys. Five bills.
+
+
+
+ Want to A/B test Claude against GPT against Gemini? You're juggling separate accounts,
+ separate billing portals, and a different client per provider.
+
+
+
+
+
+ $ npm i {'@anthropic-ai/sdk openai @google/genai'}
+ …
+
+
+);
+
+// ─── 03 · The pitch ───────────────────────────────────────────────────────────
+const Pitch: Page = () => (
+
+
+
+
+ {eyebrow('02', 'The pitch')}
+
+
+ One gateway.
+
+ Every model.
+
+
+
+ LLMGateway proxies every major provider behind a single endpoint, a single API key, and a
+ single invoice. Drop in a Vercel AI SDK provider and you're routed to OpenAI, Anthropic,
+ Google, Groq — whichever you ask for.
+
+
+);
+
+// ─── 04 · Code ────────────────────────────────────────────────────────────────
+const tokens = {
+ k: 'var(--osd-accent)',
+ s: palette.green,
+ c: palette.muted,
+ fn: palette.amber,
+ txt: 'var(--osd-text)',
+ prop: palette.pink,
+ blue: palette.blue,
+};
+
+const codeLine = (i: number, kids: ReactNode) => (
+
+ {i + 1}
+ {kids}
+
+);
+
+const Code: Page = () => (
+
+
+
+ {eyebrow('03', 'Looks like this')}
+
+
+ Drop-in Vercel AI SDK provider.
+
+
+
+
+ {['#ff5f57', '#febc2e', '#28c840'].map((c) => (
+
+ ))}
+
+
+ app.ts
+
+
+
+ {codeLine(
+ 0,
+ <>
+ import
+ {'{ '}
+ llmgateway
+ {'} '}
+ from
+ "@llmgateway/ai-sdk-provider"
+ ;
+ >,
+ )}
+ {codeLine(
+ 1,
+ <>
+ import
+ {'{ '}
+ generateText
+ {'} '}
+ from
+ "ai"
+ ;
+ >,
+ )}
+ {codeLine(2, )}
+ {codeLine(
+ 3,
+ <>
+ const
+
+ {' '}
+ {'{ '}text{' }'}
+
+ =
+
+ await
+
+ generateText
+ {'({'}
+ >,
+ )}
+ {codeLine(
+ 4,
+ <>
+ {' '}
+ model
+ :
+ llmgateway
+ (
+ "gpt-4o"
+ ),
+ >,
+ )}
+ {codeLine(
+ 5,
+ <>
+ {' '}
+ prompt
+ :
+
+ "Write a vegetarian lasagna recipe for 4 people."
+
+ ,
+ >,
+ )}
+ {codeLine(6, {'});'})}
+
+
+
+
+ Swap "gpt-4o" for{' '}
+ "claude-sonnet-4.5"{' '}
+ and ship. Same shape. Same types.
+
+
+);
+
+// ─── 05 · Models ──────────────────────────────────────────────────────────────
+const ModelChip = ({ name, delay }: { name: string; delay: number }) => (
+
+ {name}
+
+);
+
+const Models: Page = () => (
+
+
+
+ {eyebrow('04', 'Models')}
+
+
+
+ Pick any of them.
+
+
+ 100+ available
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ →
+ llmgateway.io/models
+
+
+);
+
+// ─── 06 · Closing ─────────────────────────────────────────────────────────────
+const Closing: Page = () => (
+
+
+
+
+
+
+
+ 05
+ ·
+ Ship
+
+
+
+ One key.
+
+ Every model.
+
+
+
+ npm i{' '}
+
+ @llmgateway/ai-sdk-provider
+
+
+
+
+
+ llmgateway.io
+
+
+);
+
+export const meta: SlideMeta = { title: 'LLMGateway' };
+export default [Cover, Problem, Pitch, Code, Models, Closing] satisfies Page[];
diff --git a/apps/demo/slides/vercel-ai-sdk/index.tsx b/apps/demo/slides/vercel-ai-sdk/index.tsx
index 2d70e216..5d07d443 100644
--- a/apps/demo/slides/vercel-ai-sdk/index.tsx
+++ b/apps/demo/slides/vercel-ai-sdk/index.tsx
@@ -833,9 +833,9 @@ const providers = [
'Replicate',
'Ollama',
'OpenRouter',
+ 'LLMGateway',
'Cerebras',
'Hugging Face',
- '+ more',
];
const Providers: Page = () => (
@@ -907,7 +907,7 @@ const Providers: Page = () => (
background: palette.surface,
fontSize: 28,
fontWeight: 500,
- color: p === '+ more' ? 'var(--osd-accent)' : palette.textSoft,
+ color: palette.textSoft,
textAlign: 'center',
letterSpacing: '-0.01em',
}}