index.html
228 lines1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
{{template "main.html" .}}
{{define "title"}}Congo — Go Framework{{end}}
{{define "content"}}
<style>
.cloud-wrap {
position: relative;
overflow: hidden;
}
.cloud-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
overflow: hidden;
z-index: 0;
}
.cloud-layer ~ section { position: relative; z-index: 1; }
.cloud {
position: absolute;
will-change: transform;
filter: drop-shadow(0 4px 12px rgba(79,142,247,0.18)) drop-shadow(0 1px 2px rgba(79,142,247,0.12));
}
@keyframes drift {
from { transform: translateX(-120%); }
to { transform: translateX(calc(100vw + 120%)); }
}
/* Feature cards: floating bob + pulsing blue underglow */
.feature-float {
animation: float-bob 5s ease-in-out infinite;
box-shadow: 0 8px 32px rgba(79,142,247,0.12), 0 2px 8px rgba(79,142,247,0.08);
}
.feature-float:hover {
animation-play-state: paused;
}
@keyframes float-bob {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
@keyframes pulse-glow {
0%, 100% { box-shadow: 0 8px 32px rgba(79,142,247,0.12), 0 2px 8px rgba(79,142,247,0.08); }
50% { box-shadow: 0 12px 40px rgba(79,142,247,0.25), 0 4px 16px rgba(79,142,247,0.15); }
}
</style>
<div class="cloud-wrap">
<div class="cloud-layer" id="clouds-behind"></div>
<div class="cloud-layer" id="clouds-front"></div>
<!-- Hero -->
<section class="relative min-h-[70vh] flex items-center justify-center px-6">
<div class="hero-glow"></div>
<div class="relative text-center max-w-xl mx-auto">
<h1 class="text-5xl md:text-6xl font-bold tracking-tight leading-[1.1] mb-5">
Build fast.<br><span class="shimmer text-accent">Ship faster.</span>
</h1>
<p class="text-body text-base leading-relaxed mb-8 max-w-md mx-auto">
One binary. Routing, database, templates, deployment — all included.
Source code vendored into your project. Read it, modify it, own it.
</p>
<div class="flex gap-3 justify-center mb-6" hx-boost="true">
<a href="/source" class="btn-glow"><span class="font-mono text-xs mr-1"></></span> View Source</a>
<a href="/tutorial" class="btn-glow btn-glow-primary">Get Started</a>
</div>
</div>
</section>
<!-- Three Steps -->
<section class="py-20 px-6">
<div class="max-w-3xl mx-auto">
<h2 class="text-2xl font-bold text-center mb-3 tracking-tight">Three commands, running app</h2>
<p class="text-muted text-sm text-center mb-14">Requires <a href="https://go.dev/dl/" class="text-accent hover:text-bright transition-colors" target="_blank" rel="noopener">Go 1.25+</a></p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div class="text-center">
<div class="text-accent text-xs font-mono mb-3">01</div>
<div class="code-block mb-3">
<pre><code class="language-bash">congo init myapp</code></pre>
</div>
<p class="text-body text-sm leading-relaxed">Scaffolds a project with the full framework vendored inside.</p>
</div>
<div class="text-center">
<div class="text-accent text-xs font-mono mb-3">02</div>
<div class="code-block mb-3">
<pre><code class="language-bash">congo dev</code></pre>
</div>
<p class="text-body text-sm leading-relaxed">Starts the dev server at <code class="text-accent">localhost:5000</code>. Open your browser, start building.</p>
</div>
<div class="text-center">
<div class="text-accent text-xs font-mono mb-3">03</div>
<div class="code-block mb-3">
<pre><code class="language-bash">congo launch</code></pre>
</div>
<p class="text-body text-sm leading-relaxed">Builds, ships, and deploys with health checks and rollback.</p>
</div>
</div>
</div>
</section>
<!-- Features -->
<section class="py-20 px-6">
<div class="max-w-3xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="glow-card feature-float p-6" style="animation: float-bob 5s ease-in-out -0.5s infinite, pulse-glow 3s ease-in-out -0.5s infinite;">
<h3 class="text-bright font-semibold text-sm mb-2">Vendored Source</h3>
<p class="text-body text-sm leading-relaxed">The full framework is copied into your project as regular Go files. Read every line, modify anything, no hidden magic.</p>
</div>
<div class="glow-card feature-float p-6" style="animation: float-bob 5.5s ease-in-out -2s infinite, pulse-glow 3.5s ease-in-out -1s infinite;">
<h3 class="text-bright font-semibold text-sm mb-2">HTMX + DaisyUI</h3>
<p class="text-body text-sm leading-relaxed">Server-rendered HTML with HTMX interactivity and DaisyUI components. Most pages need zero JavaScript.</p>
</div>
<div class="glow-card feature-float p-6" style="animation: float-bob 4.8s ease-in-out -3.5s infinite, pulse-glow 3.2s ease-in-out -2s infinite;">
<h3 class="text-bright font-semibold text-sm mb-2">SQLite ORM</h3>
<p class="text-body text-sm leading-relaxed">Auto-migrating database with type-safe collections. Define a struct, get CRUD. <a href="https://turso.tech/libsql" class="text-accent hover:text-bright transition-colors" target="_blank" rel="noopener">LibSQL</a> for production replicas.</p>
</div>
<div class="glow-card feature-float p-6" style="animation: float-bob 5.2s ease-in-out -1s infinite, pulse-glow 3.8s ease-in-out -2.5s infinite;">
<h3 class="text-bright font-semibold text-sm mb-2">React Islands</h3>
<p class="text-body text-sm leading-relaxed">Optional React components for complex UI. Auto-mounted on page load and HTMX swaps. HMR in development.</p>
</div>
<div class="glow-card feature-float p-6" style="animation: float-bob 5.8s ease-in-out -4s infinite, pulse-glow 3s ease-in-out -1.5s infinite;">
<h3 class="text-bright font-semibold text-sm mb-2">AI-Ready</h3>
<p class="text-body text-sm leading-relaxed"><code class="text-accent">congo claude</code> launches Claude Code with full framework context. AI knows your patterns.</p>
</div>
<div class="glow-card feature-float p-6" style="animation: float-bob 4.5s ease-in-out -2.5s infinite, pulse-glow 3.4s ease-in-out -0.8s infinite;">
<h3 class="text-bright font-semibold text-sm mb-2">One Binary</h3>
<p class="text-body text-sm leading-relaxed">Web server, CLI, database, and deployment tooling compile into a single executable. No runtime dependencies.</p>
</div>
</div>
</section>
<!-- Dogfooding -->
<section class="section-divide py-20 px-6">
<div class="max-w-3xl mx-auto text-center">
<p class="text-body text-sm leading-relaxed mb-6">
This website is a Congo app. Five controllers, two models, thirteen templates.
<a href="/source/web" class="text-accent hover:text-bright transition-colors" hx-boost="true">Browse its source</a> to see how it's built.
</p>
<div class="flex gap-3 justify-center" hx-boost="true">
<a href="/philosophy" class="btn-glow">Why These Choices</a>
<a href="/tutorial" class="btn-glow btn-glow-primary">Start the Tutorial</a>
</div>
</div>
</section>
<!-- Mailing List -->
<section class="py-12 px-6">
<div class="max-w-md mx-auto">
{{template "mailing-list.html" .}}
</div>
</section>
</div><!-- /cloud-wrap -->
<script nonce="{{nonce}}">
(function() {
// Storybook cloud: puffy bumps on top/sides, smooth arch on bottom
function makeCloud(w) {
var bumps = Math.floor(4 + (w / 80));
if (bumps > 7) bumps = 7;
var h = w * 0.55;
var cx = w / 2, cy = h * 0.45;
var pad = w * 0.2;
// Place bumps only on top half (–π to 0), keeping bottom smooth
var circles = [];
for (var i = 0; i < bumps; i++) {
var angle = -Math.PI + (Math.PI * ((i + 0.5) / bumps)) + (Math.random() - 0.5) * 0.25;
var r = (w * 0.18) * (0.8 + Math.random() * 0.4);
var distX = w * 0.3 * (0.85 + Math.random() * 0.3);
var distY = h * 0.25 * (0.85 + Math.random() * 0.3);
var bx = cx + Math.cos(angle) * distX;
var by = cy + Math.sin(angle) * distY;
circles.push({ cx: bx, cy: by, r: r });
}
// Bottom arch: wide flat ellipse spanning the base
var archCy = h * 0.55;
var archRx = w * 0.42;
var archRy = h * 0.22;
var svg = '<svg viewBox="' + (-pad) + ' ' + (-pad) + ' ' + (w + pad*2) + ' ' + (h + pad*2) + '" xmlns="http://www.w3.org/2000/svg">';
// Bottom arch ellipse — smooth curved base
svg += '<ellipse cx="' + cx + '" cy="' + archCy.toFixed(1) +
'" rx="' + archRx.toFixed(1) + '" ry="' + archRy.toFixed(1) + '" fill="white"/>';
// Core body
svg += '<ellipse cx="' + cx + '" cy="' + cy + '" rx="' + (w * 0.3).toFixed(1) +
'" ry="' + (h * 0.25).toFixed(1) + '" fill="white"/>';
// Bumps on top and sides
for (var j = 0; j < circles.length; j++) {
var c = circles[j];
svg += '<circle cx="' + c.cx.toFixed(1) + '" cy="' + c.cy.toFixed(1) +
'" r="' + c.r.toFixed(1) + '" fill="white"/>';
}
svg += '</svg>';
return { svg: svg, h: h };
}
var layers = [
{ id: 'clouds-behind', count: 10, minW: 200, maxW: 380, minDur: 35, maxDur: 120, minOp: 0.75, maxOp: 0.95 },
{ id: 'clouds-front', count: 8, minW: 130, maxW: 280, minDur: 18, maxDur: 70, minOp: 0.85, maxOp: 1.0 }
];
layers.forEach(function(layer) {
var container = document.getElementById(layer.id);
if (!container) return;
for (var i = 0; i < layer.count; i++) {
var el = document.createElement('div');
el.className = 'cloud';
var w = layer.minW + Math.random() * (layer.maxW - layer.minW);
var cloud = makeCloud(Math.round(w));
var top = Math.random() * 85;
var dur = layer.minDur + Math.random() * (layer.maxDur - layer.minDur);
var delay = -(Math.random() * dur);
var op = layer.minOp + Math.random() * (layer.maxOp - layer.minOp);
el.style.width = w + 'px';
el.style.top = top + '%';
el.style.opacity = op.toFixed(2);
el.style.animation = 'drift ' + dur.toFixed(1) + 's linear ' + delay.toFixed(1) + 's infinite';
el.innerHTML = cloud.svg;
container.appendChild(el);
}
});
})();
</script>
{{end}}