Skip to content

Commit 7b0b5a0

Browse files
committed
web: retina-quality assets, blog headers, fix all broken images
Resolution fixes: - Feature videos re-rendered at 1600x1000 (was 800x500) for retina - Hero screenshot at 2540x1520 (2x display size) - All MP4s re-encoded with CRF 26 + faststart + slow preset Blog headers (new): - 15 unique 1200x630 images via Remotion BlogHeaders composition - Each blog post gets a themed header with icon, title, gradient - Converted PNG → WebP (9.8MB → 164KB total, 98% reduction) - All 15 MDX frontmatter updated from /dashboard.png to per-article WebP Broken image fixes: - Created /dashboard.png (was missing — referenced by solution.tsx, how-it-works.tsx, og/route.tsx, and all blog posts) - solution.tsx: 4x Safari src updated to /assets/hero-screenshot.png - how-it-works.tsx: 3x image updated to /assets/hero-screenshot.png Copy fixes: - "27 MCP tools" → "43 MCP tools" across 7 files (features, solution, how-it-works, use-cases, compare, testimonials, quant-intelligence, onboarding) Asset budget: - Hero: 152KB PNG (+ 41KB WebP) - Demo video: 656KB MP4 - 4 feature clips: 211KB total MP4 - 15 blog headers: 164KB total WebP - Grand total: ~1.2MB for the entire site
1 parent 0a79094 commit 7b0b5a0

47 files changed

Lines changed: 239 additions & 79 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/marketing-assets/src/Root.tsx

Lines changed: 16 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,29 @@ import { GifEventExplorer } from "./compositions/GifEventExplorer";
55
import { GifLiveStream } from "./compositions/GifLiveStream";
66
import { GifApiKeyCreation } from "./compositions/GifApiKeyCreation";
77
import { GifOnboarding } from "./compositions/GifOnboarding";
8+
import { blogHeaders, makeBlogHeader } from "./compositions/BlogHeaders";
9+
10+
// Resolutions sized for retina displays. Feature videos display at
11+
// ~600-900px wide in the browser, so 1600x1000 gives crisp 2x on
12+
// most screens. Hero is 2540x1520 (2x of 1270x760 display size).
13+
// Blog headers are 1200x630 (OG image standard).
814

915
export const RemotionRoot: React.FC = () => {
1016
return (
1117
<>
12-
<Still
13-
id="hero-screenshot"
14-
component={HeroScreenshot}
15-
width={1270}
16-
height={760}
17-
/>
18-
19-
<Composition
20-
id="demo-video"
21-
component={DemoVideo}
22-
durationInFrames={1800}
23-
fps={30}
24-
width={1920}
25-
height={1080}
26-
/>
27-
28-
<Composition
29-
id="gif-event-explorer"
30-
component={GifEventExplorer}
31-
durationInFrames={150}
32-
fps={30}
33-
width={800}
34-
height={500}
35-
/>
18+
<Still id="hero-screenshot" component={HeroScreenshot} width={2540} height={1520} />
3619

37-
<Composition
38-
id="gif-live-stream"
39-
component={GifLiveStream}
40-
durationInFrames={150}
41-
fps={30}
42-
width={800}
43-
height={500}
44-
/>
20+
<Composition id="demo-video" component={DemoVideo} durationInFrames={1800} fps={30} width={1920} height={1080} />
4521

46-
<Composition
47-
id="gif-api-key"
48-
component={GifApiKeyCreation}
49-
durationInFrames={120}
50-
fps={30}
51-
width={800}
52-
height={500}
53-
/>
22+
<Composition id="gif-event-explorer" component={GifEventExplorer} durationInFrames={150} fps={30} width={1600} height={1000} />
23+
<Composition id="gif-live-stream" component={GifLiveStream} durationInFrames={150} fps={30} width={1600} height={1000} />
24+
<Composition id="gif-api-key" component={GifApiKeyCreation} durationInFrames={120} fps={30} width={1600} height={1000} />
25+
<Composition id="gif-onboarding" component={GifOnboarding} durationInFrames={150} fps={30} width={1600} height={1000} />
5426

55-
<Composition
56-
id="gif-onboarding"
57-
component={GifOnboarding}
58-
durationInFrames={150}
59-
fps={30}
60-
width={800}
61-
height={500}
62-
/>
27+
{/* Blog header images — 1200x630 (OG standard) */}
28+
{Object.keys(blogHeaders).map((slug) => (
29+
<Still key={slug} id={`blog-${slug}`} component={makeBlogHeader(slug)} width={1200} height={630} />
30+
))}
6331
</>
6432
);
6533
};
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import type React from "react";
2+
import { colors, fonts } from "../components/styles";
3+
4+
interface BlogHeaderProps {
5+
title: string;
6+
icon: string;
7+
gradient: string;
8+
accentColor: string;
9+
}
10+
11+
const BlogHeader: React.FC<BlogHeaderProps> = ({ title, icon, gradient, accentColor }) => (
12+
<div
13+
style={{
14+
width: "100%",
15+
height: "100%",
16+
background: `linear-gradient(135deg, ${colors.bg} 0%, #0d0d18 100%)`,
17+
display: "flex",
18+
flexDirection: "column",
19+
alignItems: "center",
20+
justifyContent: "center",
21+
fontFamily: fonts.sans,
22+
padding: 80,
23+
position: "relative",
24+
overflow: "hidden",
25+
}}
26+
>
27+
{/* Background pattern */}
28+
<div style={{
29+
position: "absolute",
30+
inset: 0,
31+
backgroundImage: `radial-gradient(circle at 25% 25%, ${accentColor}15 0%, transparent 50%), radial-gradient(circle at 75% 75%, ${accentColor}10 0%, transparent 50%)`,
32+
}} />
33+
34+
{/* Grid lines */}
35+
<div style={{
36+
position: "absolute",
37+
inset: 0,
38+
backgroundImage: `linear-gradient(${colors.border}30 1px, transparent 1px), linear-gradient(90deg, ${colors.border}30 1px, transparent 1px)`,
39+
backgroundSize: "60px 60px",
40+
opacity: 0.3,
41+
}} />
42+
43+
{/* Icon */}
44+
<div style={{
45+
fontSize: 64,
46+
marginBottom: 32,
47+
filter: "drop-shadow(0 0 40px " + accentColor + "60)",
48+
position: "relative",
49+
}}>
50+
{icon}
51+
</div>
52+
53+
{/* Title */}
54+
<h1 style={{
55+
fontSize: 48,
56+
fontWeight: 800,
57+
color: colors.text,
58+
textAlign: "center",
59+
lineHeight: 1.2,
60+
maxWidth: 900,
61+
margin: 0,
62+
position: "relative",
63+
letterSpacing: -1,
64+
}}>
65+
{title}
66+
</h1>
67+
68+
{/* AllSource branding */}
69+
<div style={{
70+
position: "absolute",
71+
bottom: 40,
72+
display: "flex",
73+
alignItems: "center",
74+
gap: 10,
75+
}}>
76+
<div style={{
77+
width: 24,
78+
height: 24,
79+
borderRadius: 7,
80+
background: `linear-gradient(135deg, ${colors.primary}, ${colors.cyan})`,
81+
display: "flex",
82+
alignItems: "center",
83+
justifyContent: "center",
84+
fontSize: 12,
85+
fontWeight: 800,
86+
color: "white",
87+
}}>A</div>
88+
<span style={{ fontSize: 14, fontWeight: 600, color: colors.textDim }}>AllSource Blog</span>
89+
</div>
90+
</div>
91+
);
92+
93+
// Each blog post gets a themed header
94+
export const blogHeaders: Record<string, BlogHeaderProps> = {
95+
"introducing-allsource": {
96+
title: "Introducing AllSource",
97+
icon: "🚀",
98+
gradient: "from-indigo-500 to-purple-500",
99+
accentColor: "#6366f1",
100+
},
101+
"time-travel-queries": {
102+
title: "Time-Travel Queries",
103+
icon: "⏳",
104+
gradient: "from-blue-500 to-cyan-500",
105+
accentColor: "#3b82f6",
106+
},
107+
"ai-agents-need-memory": {
108+
title: "AI Agents Need Memory",
109+
icon: "🧠",
110+
gradient: "from-purple-500 to-pink-500",
111+
accentColor: "#a855f7",
112+
},
113+
"event-store-vs-database": {
114+
title: "Event Store vs Database",
115+
icon: "⚡",
116+
gradient: "from-orange-500 to-red-500",
117+
accentColor: "#f97316",
118+
},
119+
"mcp-tools-claude-integration": {
120+
title: "43 MCP Tools for Claude",
121+
icon: "🔧",
122+
gradient: "from-cyan-500 to-blue-500",
123+
accentColor: "#06b6d4",
124+
},
125+
"building-agent-memory-in-rust": {
126+
title: "Building Agent Memory in Rust",
127+
icon: "🦀",
128+
gradient: "from-orange-500 to-amber-500",
129+
accentColor: "#f97316",
130+
},
131+
"12-microsecond-agent-memory": {
132+
title: "12-Microsecond Agent Memory",
133+
icon: "⚡",
134+
gradient: "from-yellow-500 to-orange-500",
135+
accentColor: "#eab308",
136+
},
137+
"temporal-ai-future-of-rag": {
138+
title: "Temporal AI: The Future of RAG",
139+
icon: "🔮",
140+
gradient: "from-violet-500 to-purple-500",
141+
accentColor: "#8b5cf6",
142+
},
143+
"why-event-sourcing-2026": {
144+
title: "Why Event Sourcing in 2026",
145+
icon: "📐",
146+
gradient: "from-green-500 to-emerald-500",
147+
accentColor: "#22c55e",
148+
},
149+
"compressed-index-doubles-cross-domain-recall": {
150+
title: "Compressed Index Doubles Recall",
151+
icon: "📊",
152+
gradient: "from-teal-500 to-cyan-500",
153+
accentColor: "#14b8a6",
154+
},
155+
"from-zerodex-to-allsource": {
156+
title: "From Zer0dex to AllSource",
157+
icon: "🔄",
158+
gradient: "from-blue-500 to-indigo-500",
159+
accentColor: "#3b82f6",
160+
},
161+
"zer0dex-vs-allsource-recall": {
162+
title: "Zer0dex vs AllSource Recall",
163+
icon: "⚖️",
164+
gradient: "from-slate-500 to-zinc-500",
165+
accentColor: "#64748b",
166+
},
167+
"tiered-context-loading-for-agent-loops": {
168+
title: "Tiered Context Loading",
169+
icon: "🔄",
170+
gradient: "from-amber-500 to-orange-500",
171+
accentColor: "#f59e0b",
172+
},
173+
"connecting-without-an-sdk": {
174+
title: "Connecting Without an SDK",
175+
icon: "🔌",
176+
gradient: "from-green-500 to-teal-500",
177+
accentColor: "#22c55e",
178+
},
179+
"connection-path": {
180+
title: "The Connection Path",
181+
icon: "🛤️",
182+
gradient: "from-indigo-500 to-blue-500",
183+
accentColor: "#6366f1",
184+
},
185+
};
186+
187+
// Factory: create a component for a specific blog slug
188+
export const makeBlogHeader = (slug: string): React.FC => {
189+
const props = blogHeaders[slug];
190+
if (!props) return () => <BlogHeader title={slug} icon="📝" gradient="from-gray-500 to-gray-600" accentColor="#64748b" />;
191+
return () => <BlogHeader {...props} />;
192+
};

apps/web/content/12-microsecond-agent-memory.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "12μs Agent Memory: How We Got There"
33
publishedAt: "2026-03-21"
44
summary: "From event store to agent memory engine in microseconds. DashMap projections, HNSW vector index, and why the storage layer matters more than the query layer."
55
author: "all.source team"
6-
image: "/dashboard.png"
6+
image: "/assets/blog/12-microsecond-agent-memory.webp"
77
---
88

99
AllSource Prime queries agent memory in **12 microseconds**. Not milliseconds. Microseconds.

apps/web/content/ai-agents-need-memory.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "Your AI Agents Need Memory, Not Just Storage"
33
publishedAt: "2026-02-12"
44
summary: AI agents are getting smarter, but they still can't remember yesterday. Here's why temporal context is the missing piece in agentic AI.
55
author: "all.source team"
6-
image: "/dashboard.png"
6+
image: "/assets/blog/ai-agents-need-memory.webp"
77
---
88

99
AI agents in 2026 are impressive. They can write code, analyze documents, manage workflows, and hold conversations that feel genuinely intelligent.

apps/web/content/building-agent-memory-in-rust.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "Building Agent Memory in Rust: From Event Store to Knowledge Graph"
33
publishedAt: "2026-03-21"
44
summary: "How we built a unified agent memory engine — vectors + graph + compressed index — on top of an event store. Architecture decisions, SOLID refactoring, and why Rust was the right choice."
55
author: "all.source team"
6-
image: "/dashboard.png"
6+
image: "/assets/blog/building-agent-memory-in-rust.webp"
77
---
88

99
We set out to build an agent memory system that beats [zer0dex](https://github.com/roli-lpci/zer0dex) on cross-domain recall while adding what it can't do: temporal reasoning, full provenance, and auto-generated indexes.

apps/web/content/compressed-index-doubles-cross-domain-recall.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "How a Compressed Index Doubles Cross-Domain Recall"
33
publishedAt: "2026-03-21"
44
summary: "Vector similarity finds X or Y — rarely both. A 500-token markdown index bridges the gap. Here's why, with benchmark data."
55
author: "all.source team"
6-
image: "/dashboard.png"
6+
image: "/assets/blog/compressed-index-doubles-cross-domain-recall.webp"
77
---
88

99
When you ask an AI agent "How does our pricing relate to the Q3 churn spike?", vector similarity search faces a fundamental problem: it finds pricing docs OR churn docs, but rarely both in the same result set.

apps/web/content/connecting-without-an-sdk.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "Connecting to AllSource without an SDK"
33
publishedAt: "2026-04-17"
44
summary: How to ingest, query, stream, and build projections against AllSource using only HTTP and WebSockets — no SDK required. For teams on unsupported languages or anyone who wants to understand the wire protocol.
55
author: "all.source team"
6-
image: "/dashboard.png"
6+
image: "/assets/blog/connecting-without-an-sdk.webp"
77
---
88

99
The AllSource ecosystem ships first-party SDKs for Rust, Go, Python, and TypeScript. But not every team is on one of those runtimes, and even the ones that are sometimes need to understand what's happening underneath. This post walks through the full wire protocol: how to connect, authenticate, ingest events, run queries, subscribe to the live stream, and drive projections using only HTTP and WebSockets.

apps/web/content/connection-path.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "Direct to Core, or through the gateway? Choosing your connection path"
33
publishedAt: "2026-04-17"
44
summary: AllSource has one public front door (api.all-source.xyz) and one internal fast path (Core, reachable only inside your network). Picking the right one cuts your p99 in half — picking the wrong one either reimplements rate limits or exposes your event store to the internet.
55
author: "all.source team"
6-
image: "/dashboard.png"
6+
image: "/assets/blog/connection-path.webp"
77
---
88

99
AllSource runs two services, but they're **not two public front doors**. They're a public gateway and a private fast path.

apps/web/content/event-store-vs-database.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "Event Store vs Database: Choosing the Right Foundation"
33
publishedAt: "2026-02-12"
44
summary: Databases store state. Event stores store history. Here's how to decide which foundation your application actually needs.
55
author: "all.source team"
6-
image: "/dashboard.png"
6+
image: "/assets/blog/event-store-vs-database.webp"
77
---
88

99
Every few months, a new database launches claiming to be "the future of data." Edge databases, serverless SQL, multi-model stores—the options are endless.

apps/web/content/from-zerodex-to-allsource.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "From zer0dex to AllSource: What We Learned"
33
publishedAt: "2026-03-21"
44
summary: "We analyzed zer0dex's dual-layer memory system, found the insight that matters, and built on it. Here's what we kept, what we changed, and why."
55
author: "all.source team"
6-
image: "/dashboard.png"
6+
image: "/assets/blog/from-zerodex-to-allsource.webp"
77
---
88

99
When [zer0dex](https://github.com/roli-lpci/zer0dex) dropped from Hermes Labs' LPCI research, we did what any self-respecting engineering team would do: we took it apart.

0 commit comments

Comments
 (0)