Skip to content

Commit 9707538

Browse files
committed
docs: create landing animation (#256)
1 parent 2170a2e commit 9707538

File tree

10 files changed

+1023
-93
lines changed

10 files changed

+1023
-93
lines changed

PLAN_animation.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Hero Section Animation Plan
2+
3+
## Overview
4+
5+
An animated DAG visualization showcasing pgflow's core capabilities: parallel execution and automatic retry handling. The animation displays a content generation workflow executing in real-time with visual feedback for all state transitions.
6+
7+
## What We're Building
8+
9+
### Animation Description
10+
11+
A horizontal DAG flow visualization with 5 nodes arranged left-to-right:
12+
13+
```
14+
[fetchArticle] → [summarize] → [publish]
15+
[extractKeywords]
16+
[generateImage]
17+
```
18+
19+
**Visual Style:**
20+
- React Flow aesthetic: rectangular nodes with rounded corners (8px border radius)
21+
- Orthogonal connections with smooth curved corners (90-degree routing)
22+
- Clean, professional design using site color palette
23+
- Subtle pulse animation on active nodes
24+
- Node dimensions: 140×50px
25+
26+
**Animation Sequence (~8 seconds, loops):**
27+
28+
1. **fetchArticle** starts → fails (red flash) → retries with badge "1/3" → succeeds
29+
2. All three parallel steps start simultaneously (visual parallelism demonstration)
30+
3. Steps complete at staggered intervals showing independence:
31+
- extractKeywords completes first
32+
- summarize completes second
33+
- generateImage completes last
34+
4. **publish** waits for all three, then starts and completes
35+
5. Hold final state, fade, restart loop
36+
37+
**Color States:**
38+
- **Pending**: Gray (#2a3d39) - not yet started
39+
- **Running**: Blue (#3B82F6) with pulse effect
40+
- **Failed**: Red (#DC2626) - brief failure state
41+
- **Retrying**: Orange (#F59E0B) with retry counter badge
42+
- **Success**: pgflow accent green (#007b6e)
43+
44+
## Why We're Building This
45+
46+
### Problem Statement
47+
48+
The current hero section uses a static logo. This doesn't communicate pgflow's key differentiators:
49+
1. Workflows handle failures gracefully with automatic retries
50+
2. Independent tasks run in parallel without manual coordination
51+
3. The system provides clear visual feedback on execution state
52+
53+
### Value Proposition
54+
55+
The animation instantly demonstrates these capabilities without requiring users to read documentation or imagine how the system works. It answers the implicit question: "How is this different from writing my own job queue?"
56+
57+
## Where It Will Be Used
58+
59+
**Primary Location:** Landing page hero section (index.mdx)
60+
61+
Currently, the hero displays:
62+
- Title: "Dead-simple workflow orchestration for Supabase"
63+
- Tagline: "AI workflows you can actually debug"
64+
- Static pgflow logo
65+
66+
**Replacement Strategy:**
67+
Replace the static logo with the animated DAG to show, not tell, what pgflow does.
68+
69+
**Current Development Location:** `/animation.mdx` for isolated development and iteration
70+
71+
## Target Audience
72+
73+
### Primary Personas
74+
75+
**1. Backend Developers Building AI Workflows**
76+
- Pain: Complex orchestration logic for multi-step AI processes
77+
- Need: Reliable execution with failure handling
78+
- Takeaway: "This handles retries automatically so I don't have to"
79+
80+
**2. Supabase Users Scaling Beyond Simple Functions**
81+
- Pain: Manual coordination between Edge Functions, queues, and cron jobs
82+
- Need: Workflow orchestration that fits their existing stack
83+
- Takeaway: "This replaces all the manual plumbing I'm doing now"
84+
85+
**3. Engineers Evaluating Workflow Engines**
86+
- Pain: Comparing pgflow to Temporal, Inngest, DBOS, etc.
87+
- Need: Quick understanding of core capabilities
88+
- Takeaway: "I can see exactly what this does - parallel execution + retries"
89+
90+
### What They Should Understand in 10 Seconds
91+
92+
1. **Visual Parallelism**: Three tasks run simultaneously without coordination code
93+
2. **Automatic Retries**: Failed steps retry automatically with visible feedback
94+
3. **Dependency Management**: Final step waits for all dependencies before executing
95+
4. **Real-time Observability**: Every state change is visible
96+
97+
## Technical Implementation
98+
99+
**Technology Stack:**
100+
- Vanilla JavaScript (no dependencies)
101+
- SVG for rendering
102+
- CSS animations for state transitions
103+
- Inline script in MDX for simplicity
104+
105+
**Performance:**
106+
- Lightweight (~100 lines of code)
107+
- No external libraries
108+
- Smooth 60fps animations
109+
- Works on all modern browsers
110+
111+
**Future Considerations:**
112+
- Pause/resume on hover (for users who want to study the flow)
113+
- Adjustable animation speed
114+
- Integration with actual pgflow execution data (advanced feature)
115+
116+
## Success Metrics
117+
118+
**Qualitative Goals:**
119+
- Users immediately understand parallel execution capability
120+
- Retry behavior is clear and reassuring (not alarming)
121+
- Visual style matches professional standards (React Flow reference)
122+
123+
**Future Quantitative Metrics:**
124+
- Increased conversion from landing page to installation
125+
- Reduced "what does this do?" questions in Discord
126+
- Higher engagement time on landing page
127+
128+
## Next Steps
129+
130+
1. ✅ Create DAG structure and animation sequence
131+
2. ✅ Implement React Flow visual style
132+
3. ✅ Fix orthogonal routing corner smoothness
133+
4. ⏳ Fine-tune timing and polish animations
134+
5. ⏳ Test responsiveness on mobile/tablet
135+
6. ⏳ Replace hero logo with animation
136+
7. ⏳ Gather feedback from early users

pkgs/website/astro.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ export default defineConfig({
395395
label: 'Architecture',
396396
items: [
397397
{ label: 'How pgflow works', link: '/concepts/how-pgflow-works/' },
398+
{ label: 'Architecture', link: '/concepts/architecture/' },
398399
{ label: 'Data model', link: '/concepts/data-model/' },
399400
],
400401
},
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
stateDiagram-v2
2+
created --> started: dependencies met
3+
started --> completed: success
4+
started --> failed: error

pkgs/website/src/components/ConditionalHero.astro

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,27 @@ import Default from '@astrojs/starlight/components/Hero.astro';
44
import HeroWithSlot from './HeroWithSlot.astro';
55
import LandingPageCodeExamples from './LandingPageCodeExamples.mdx';
66
import PgflowLandingPageCodeExamples from './PgflowLandingPageCodeExamples.mdx';
7+
import SVGDAGAnimation from './SVGDAGAnimation.astro';
78
8-
const isHomepage = Astro.props.id === '';
9-
const isPgflowLanding = Astro.props.id === 'pgflow/new-landing';
9+
// Component overrides receive props via Astro.locals.starlightRoute
10+
const route = Astro.locals.starlightRoute;
11+
const isHomepage = !route.id || route.id === '';
12+
const isPgflowLanding = route.id === 'pgflow/new-landing';
1013
---
1114

1215
{
1316
isHomepage ? (
14-
<HeroWithSlot {...Astro.props}>
15-
<div class="glow-box">
16-
<LandingPageCodeExamples/>
17-
</div>
17+
<HeroWithSlot>
18+
<SVGDAGAnimation />
1819
</HeroWithSlot>
1920
) : isPgflowLanding ? (
20-
<HeroWithSlot {...Astro.props}>
21+
<HeroWithSlot>
2122
<div class="">
2223
<PgflowLandingPageCodeExamples/>
2324
</div>
2425
</HeroWithSlot>
2526
) : (
26-
<Default {...Astro.props}/>
27+
<Default />
2728
)
2829
}
2930

pkgs/website/src/components/HeroWithSlot.astro

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
---
22
// import { PAGE_TITLE_ID } from '../constants';
33
const PAGE_TITLE_ID = '_top';
4-
import type { Props } from '@astrojs/starlight/props';
54
import { LinkButton } from '@astrojs/starlight/components';
65
7-
// Get hero data from Starlight props
8-
const { title, tagline, actions = [] } = (Astro.props as Props).entry?.data?.hero || {};
9-
// Fallback to page title if hero title is not set
10-
const heroTitle = title || (Astro.props as Props).entry?.data?.title;
6+
// Access page data the same way Starlight's default Hero does
7+
const { data } = Astro.locals.starlightRoute.entry;
8+
const { title = data.title, tagline, actions = [] } = data.hero || {};
119
---
1210

1311
<div class="hero">
@@ -42,12 +40,13 @@ const heroTitle = title || (Astro.props as Props).entry?.data?.title;
4240
align-items: center;
4341
gap: 1rem;
4442
padding-bottom: 1rem;
43+
padding-top: 0.5rem;
4544
}
4645

4746
.hero > img,
4847
.hero > .hero-html {
4948
object-fit: contain;
50-
width: min(70%, 20rem);
49+
width: min(85.5%, 33.25rem);
5150
height: auto;
5251
margin-inline: auto;
5352
order: 2;
@@ -94,11 +93,12 @@ const heroTitle = title || (Astro.props as Props).entry?.data?.title;
9493
.hero {
9594
grid-template-columns: 4fr 5fr;
9695
gap: 3%;
97-
padding-block: clamp(2.5rem, calc(1rem + 10vmin), 10rem);
96+
padding-block: clamp(1.5rem, calc(0.5rem + 8vmin), 8rem);
9897
}
9998

10099
.hero > .hero-html {
101-
width: min(100%, 25rem);
100+
width: 95%;
101+
max-width: 42.75rem;
102102
}
103103

104104
.stack {

0 commit comments

Comments
 (0)