forgedock 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -3
- package/bin/cross-publish.mjs +344 -0
- package/bin/forgedock.mjs +2205 -541
- package/bin/github-app-manifest.json.license +2 -0
- package/bin/hooks/session-start.mjs +4 -5
- package/bin/registry.mjs +20 -0
- package/bin/tui.mjs +172 -96
- package/commands/adopt.md +433 -0
- package/commands/analytics.md +2 -0
- package/commands/audit-agents.md +2 -0
- package/commands/audit.md +2 -0
- package/commands/autopilot.md +77 -0
- package/commands/changelog.md +354 -0
- package/commands/cleanup.md +2 -0
- package/commands/compat-audit.md +330 -0
- package/commands/deploy-info.md +6 -5
- package/commands/design-bench.md +176 -0
- package/commands/design-render-critique-loop.md +103 -0
- package/commands/design.md +259 -0
- package/commands/diagnose.md +483 -0
- package/commands/explain.md +349 -0
- package/commands/forge-stats.md +2 -0
- package/commands/forgedock-init.md +2 -0
- package/commands/geo-audit.md +2 -0
- package/commands/incident-response.md +2 -0
- package/commands/issue.md +9 -3
- package/commands/milestone.md +2 -0
- package/commands/optimize.md +411 -0
- package/commands/orchestrate.md +239 -0
- package/commands/pipeline-health.md +60 -1
- package/commands/qa-sweep.md +39 -2
- package/commands/quality-gate.md +67 -0
- package/commands/replay.md +263 -0
- package/commands/resume.md +264 -0
- package/commands/review-pr-agents.md +5 -1
- package/commands/review-pr-staging.md +160 -2
- package/commands/review-pr.md +85 -3
- package/commands/rollback.md +2 -0
- package/commands/scope.md +280 -0
- package/commands/security-audit.md +2 -0
- package/commands/status.md +262 -0
- package/commands/sync-ecosystem.md +2 -0
- package/commands/test-gate.md +929 -0
- package/commands/validate.md +2 -0
- package/commands/work-on/build/architect.md +128 -18
- package/commands/work-on/build/context.md +130 -17
- package/commands/work-on/build/implement.md +7 -3
- package/commands/work-on/build/validate.md +2 -0
- package/commands/work-on/build.md +32 -7
- package/commands/work-on/close.md +85 -0
- package/commands/work-on/decompose.md +2 -0
- package/commands/work-on/investigate.md +30 -3
- package/commands/work-on/review.md +13 -1
- package/commands/work-on-monolithic.md +2 -0
- package/commands/work-on.md +676 -38
- package/docs/BRAND.md +51 -0
- package/docs/CI.md +177 -0
- package/docs/CONFIG.md +94 -0
- package/docs/FORGE-PROTOCOL.md +324 -0
- package/docs/articles/b-vs-c-baseline.md +210 -0
- package/docs/articles/full-abc-benchmark.md +205 -0
- package/docs/articles/per-repo-adaptive-scripts-token-savings.md +174 -0
- package/docs/articles/selective-spec-loading-token-savings.md +140 -0
- package/docs/claude-breakpoints.json +47 -0
- package/docs/design/abc-benchmark.md +195 -0
- package/docs/design/design-architect-rationale.md +123 -0
- package/docs/design/design-memory.md +61 -0
- package/docs/design/design-spec-schema.md +248 -0
- package/docs/design/design-system-lint.md +150 -0
- package/docs/design/divergent-generation.md +106 -0
- package/docs/design/effects-appropriateness.md +133 -0
- package/docs/design/fixtures/briefs/README.md +47 -0
- package/docs/design/fixtures/briefs/cadence.md +39 -0
- package/docs/design/fixtures/briefs/plume.md +39 -0
- package/docs/design/fixtures/briefs/slipstream.md +39 -0
- package/docs/design/fixtures/briefs/tender.md +39 -0
- package/docs/design/fixtures/briefs/voltage.md +39 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/cadence/arm-b/run-1.html +364 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/cadence/arm-b/run-2.html +420 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/cadence/arm-b/run-3.html +506 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/plume/arm-b/run-1.html +611 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/plume/arm-b/run-2.html +594 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/plume/arm-b/run-3.html +817 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/runs.json +175 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/scorecard.json +138 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/slipstream/arm-b/run-1.html +373 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/slipstream/arm-b/run-2.html +398 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/slipstream/arm-b/run-3.html +595 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/tender/arm-b/run-1.html +531 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/tender/arm-b/run-2.html +565 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/tender/arm-b/run-3.html +674 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/voltage/arm-b/run-1.html +388 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/voltage/arm-b/run-2.html +463 -0
- package/docs/design/fixtures/runs/b-vs-c-baseline/voltage/arm-b/run-3.html +568 -0
- package/docs/design/fixtures/runs/full-abc/cadence/arm-a/run-1.html +562 -0
- package/docs/design/fixtures/runs/full-abc/cadence/arm-a/run-2.html +618 -0
- package/docs/design/fixtures/runs/full-abc/cadence/arm-a/run-3.html +618 -0
- package/docs/design/fixtures/runs/full-abc/cadence/arm-b/run-1.html +364 -0
- package/docs/design/fixtures/runs/full-abc/cadence/arm-b/run-2.html +420 -0
- package/docs/design/fixtures/runs/full-abc/cadence/arm-b/run-3.html +506 -0
- package/docs/design/fixtures/runs/full-abc/plume/arm-a/run-1.html +527 -0
- package/docs/design/fixtures/runs/full-abc/plume/arm-a/run-2.html +445 -0
- package/docs/design/fixtures/runs/full-abc/plume/arm-a/run-3.html +483 -0
- package/docs/design/fixtures/runs/full-abc/plume/arm-b/run-1.html +611 -0
- package/docs/design/fixtures/runs/full-abc/plume/arm-b/run-2.html +594 -0
- package/docs/design/fixtures/runs/full-abc/plume/arm-b/run-3.html +817 -0
- package/docs/design/fixtures/runs/full-abc/runs.json +190 -0
- package/docs/design/fixtures/runs/full-abc/scorecard.json +144 -0
- package/docs/design/fixtures/runs/full-abc/slipstream/arm-a/run-1.html +496 -0
- package/docs/design/fixtures/runs/full-abc/slipstream/arm-a/run-2.html +447 -0
- package/docs/design/fixtures/runs/full-abc/slipstream/arm-a/run-3.html +564 -0
- package/docs/design/fixtures/runs/full-abc/slipstream/arm-b/run-1.html +373 -0
- package/docs/design/fixtures/runs/full-abc/slipstream/arm-b/run-2.html +398 -0
- package/docs/design/fixtures/runs/full-abc/slipstream/arm-b/run-3.html +595 -0
- package/docs/design/fixtures/runs/full-abc/tender/arm-a/run-1.html +622 -0
- package/docs/design/fixtures/runs/full-abc/tender/arm-a/run-2.html +475 -0
- package/docs/design/fixtures/runs/full-abc/tender/arm-a/run-3.html +660 -0
- package/docs/design/fixtures/runs/full-abc/tender/arm-b/run-1.html +531 -0
- package/docs/design/fixtures/runs/full-abc/tender/arm-b/run-2.html +565 -0
- package/docs/design/fixtures/runs/full-abc/tender/arm-b/run-3.html +674 -0
- package/docs/design/fixtures/runs/full-abc/voltage/arm-a/run-1.html +525 -0
- package/docs/design/fixtures/runs/full-abc/voltage/arm-a/run-2.html +446 -0
- package/docs/design/fixtures/runs/full-abc/voltage/arm-a/run-3.html +463 -0
- package/docs/design/fixtures/runs/full-abc/voltage/arm-b/run-1.html +388 -0
- package/docs/design/fixtures/runs/full-abc/voltage/arm-b/run-2.html +463 -0
- package/docs/design/fixtures/runs/full-abc/voltage/arm-b/run-3.html +568 -0
- package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-a/run-1.html +1068 -0
- package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-a/run-2.html +1423 -0
- package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-a/run-3.html +1245 -0
- package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-b/run-1.html +305 -0
- package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-b/run-2.html +327 -0
- package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-b/run-3.html +428 -0
- package/docs/design/fixtures/runs/full-abc-opus/plume/arm-a/run-1.html +1270 -0
- package/docs/design/fixtures/runs/full-abc-opus/plume/arm-a/run-2.html +1172 -0
- package/docs/design/fixtures/runs/full-abc-opus/plume/arm-a/run-3.html +1532 -0
- package/docs/design/fixtures/runs/full-abc-opus/plume/arm-b/run-1.html +315 -0
- package/docs/design/fixtures/runs/full-abc-opus/plume/arm-b/run-2.html +342 -0
- package/docs/design/fixtures/runs/full-abc-opus/plume/arm-b/run-3.html +353 -0
- package/docs/design/fixtures/runs/full-abc-opus/runs.json +190 -0
- package/docs/design/fixtures/runs/full-abc-opus/scorecard.json +144 -0
- package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-a/run-1.html +345 -0
- package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-a/run-2.html +396 -0
- package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-a/run-3.html +502 -0
- package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-b/run-1.html +408 -0
- package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-b/run-2.html +446 -0
- package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-b/run-3.html +496 -0
- package/docs/design/fixtures/runs/full-abc-opus/tender/arm-a/run-1.html +813 -0
- package/docs/design/fixtures/runs/full-abc-opus/tender/arm-a/run-2.html +711 -0
- package/docs/design/fixtures/runs/full-abc-opus/tender/arm-a/run-3.html +721 -0
- package/docs/design/fixtures/runs/full-abc-opus/tender/arm-b/run-1.html +280 -0
- package/docs/design/fixtures/runs/full-abc-opus/tender/arm-b/run-2.html +291 -0
- package/docs/design/fixtures/runs/full-abc-opus/tender/arm-b/run-3.html +366 -0
- package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-a/run-1.html +1010 -0
- package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-a/run-2.html +836 -0
- package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-a/run-3.html +930 -0
- package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-b/run-1.html +407 -0
- package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-b/run-2.html +396 -0
- package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-b/run-3.html +529 -0
- package/docs/design/foundations/brutalist.css +294 -0
- package/docs/design/foundations/editorial.css +300 -0
- package/docs/design/foundations/minimal-luxury.css +295 -0
- package/docs/design/foundations/technical.css +293 -0
- package/docs/design/foundations/warm-photo.css +299 -0
- package/docs/design/reference-corpus.md +1726 -0
- package/docs/design/render-critique-loop.md +57 -0
- package/docs/site/getting-started.md +21 -0
- package/docs/spec-graph-schema.md +397 -0
- package/package.json +3 -3
- package/scripts/bench-scorecard.mjs +239 -0
- package/scripts/build-spec-graph.mjs +509 -0
- package/scripts/classify-lane.sh +138 -0
- package/scripts/design-system-lint.mjs +993 -0
- package/scripts/graph-query.sh +486 -0
- package/scripts/transition-label.sh +169 -0
- package/scripts/validate-pr-target.sh +30 -0
- package/scripts/validate-spec-graph.sh +423 -0
- package/templates/devdocs/README.md +72 -0
- package/templates/devdocs/agent/using-forgedock.md +3 -0
- package/templates/devdocs/agent/using-github.md +3 -0
- package/templates/devdocs/index.yaml +162 -0
- package/templates/devdocs/project/architecture.md +3 -0
- package/templates/devdocs/project/conventions.md +3 -0
- package/templates/devdocs/project/custom-instructions.md +3 -0
- package/templates/devdocs/project/glossary.md +3 -0
- package/templates/devdocs/project/stack.md +3 -0
- package/templates/devdocs/templates/commit-convention.md +3 -0
- package/templates/devdocs/templates/issue.md +3 -0
- package/templates/devdocs/templates/pull-request.md +3 -0
- package/templates/devdocs/templates/review-finding.md +3 -0
- package/templates/workflows/forgedock-review.yml +96 -0
|
@@ -0,0 +1,930 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Voltage</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
|
+
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&family=Fira+Code:wght@400;500&display=swap" rel="stylesheet">
|
|
9
|
+
<style>
|
|
10
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
11
|
+
|
|
12
|
+
:root {
|
|
13
|
+
--bg: #fafaf8;
|
|
14
|
+
--bg-code: #18181b;
|
|
15
|
+
--surface: #ffffff;
|
|
16
|
+
--border: #e8e8e4;
|
|
17
|
+
--border-dark: #d0d0cc;
|
|
18
|
+
--text: #1a1a1a;
|
|
19
|
+
--text-secondary: #6b6b6b;
|
|
20
|
+
--text-tertiary: #999999;
|
|
21
|
+
--accent: #0f5fff;
|
|
22
|
+
--accent-light: #e8f0ff;
|
|
23
|
+
--code-bg: #18181b;
|
|
24
|
+
--code-green: #4ade80;
|
|
25
|
+
--code-blue: #60a5fa;
|
|
26
|
+
--code-yellow: #fbbf24;
|
|
27
|
+
--code-orange: #fb923c;
|
|
28
|
+
--code-gray: #71717a;
|
|
29
|
+
--code-white: #e4e4e7;
|
|
30
|
+
--sans: 'Plus Jakarta Sans', sans-serif;
|
|
31
|
+
--mono: 'Fira Code', monospace;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
body {
|
|
35
|
+
background: var(--bg);
|
|
36
|
+
color: var(--text);
|
|
37
|
+
font-family: var(--sans);
|
|
38
|
+
-webkit-font-smoothing: antialiased;
|
|
39
|
+
line-height: 1.6;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ── NAV ── */
|
|
43
|
+
.nav {
|
|
44
|
+
max-width: 1120px;
|
|
45
|
+
margin: 0 auto;
|
|
46
|
+
padding: 24px 40px;
|
|
47
|
+
display: flex;
|
|
48
|
+
justify-content: space-between;
|
|
49
|
+
align-items: center;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.nav-logo {
|
|
53
|
+
font-weight: 700;
|
|
54
|
+
font-size: 19px;
|
|
55
|
+
letter-spacing: -0.5px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.nav-logo .dot { color: var(--accent); }
|
|
59
|
+
|
|
60
|
+
.nav-right { display: flex; gap: 32px; align-items: center; }
|
|
61
|
+
.nav-right a {
|
|
62
|
+
font-size: 14px;
|
|
63
|
+
color: var(--text-secondary);
|
|
64
|
+
text-decoration: none;
|
|
65
|
+
font-weight: 500;
|
|
66
|
+
}
|
|
67
|
+
.nav-right a:hover { color: var(--text); }
|
|
68
|
+
|
|
69
|
+
.btn-start {
|
|
70
|
+
background: var(--text);
|
|
71
|
+
color: var(--bg);
|
|
72
|
+
padding: 10px 24px;
|
|
73
|
+
font-size: 14px;
|
|
74
|
+
font-weight: 600;
|
|
75
|
+
border: none;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
text-decoration: none;
|
|
78
|
+
transition: opacity 0.15s;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.btn-start:hover { opacity: 0.85; }
|
|
82
|
+
|
|
83
|
+
/* ── HERO ── */
|
|
84
|
+
.hero {
|
|
85
|
+
max-width: 1120px;
|
|
86
|
+
margin: 0 auto;
|
|
87
|
+
padding: 100px 40px 80px;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.hero-overline {
|
|
91
|
+
font-family: var(--mono);
|
|
92
|
+
font-size: 12px;
|
|
93
|
+
color: var(--accent);
|
|
94
|
+
letter-spacing: 0.5px;
|
|
95
|
+
margin-bottom: 20px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.hero-title {
|
|
99
|
+
font-size: clamp(40px, 5.5vw, 64px);
|
|
100
|
+
font-weight: 700;
|
|
101
|
+
line-height: 1.08;
|
|
102
|
+
letter-spacing: -2px;
|
|
103
|
+
max-width: 720px;
|
|
104
|
+
margin-bottom: 24px;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.hero-desc {
|
|
108
|
+
font-size: 18px;
|
|
109
|
+
color: var(--text-secondary);
|
|
110
|
+
max-width: 520px;
|
|
111
|
+
line-height: 1.7;
|
|
112
|
+
font-weight: 400;
|
|
113
|
+
margin-bottom: 40px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.hero-actions {
|
|
117
|
+
display: flex;
|
|
118
|
+
gap: 16px;
|
|
119
|
+
align-items: center;
|
|
120
|
+
margin-bottom: 16px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.btn-outline {
|
|
124
|
+
background: transparent;
|
|
125
|
+
color: var(--text);
|
|
126
|
+
padding: 10px 24px;
|
|
127
|
+
font-size: 14px;
|
|
128
|
+
font-weight: 600;
|
|
129
|
+
border: 1.5px solid var(--border-dark);
|
|
130
|
+
cursor: pointer;
|
|
131
|
+
text-decoration: none;
|
|
132
|
+
transition: border-color 0.15s;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.btn-outline:hover { border-color: var(--text); }
|
|
136
|
+
|
|
137
|
+
.hero-install {
|
|
138
|
+
font-family: var(--mono);
|
|
139
|
+
font-size: 13px;
|
|
140
|
+
color: var(--text-tertiary);
|
|
141
|
+
margin-top: 12px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.hero-install code {
|
|
145
|
+
background: var(--surface);
|
|
146
|
+
border: 1px solid var(--border);
|
|
147
|
+
padding: 4px 12px;
|
|
148
|
+
color: var(--text);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* ── CODE SHOWCASE ── */
|
|
152
|
+
.showcase {
|
|
153
|
+
max-width: 1120px;
|
|
154
|
+
margin: 0 auto;
|
|
155
|
+
padding: 0 40px 100px;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.showcase-window {
|
|
159
|
+
background: var(--code-bg);
|
|
160
|
+
overflow: hidden;
|
|
161
|
+
box-shadow: 0 24px 80px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.06);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.showcase-chrome {
|
|
165
|
+
display: flex;
|
|
166
|
+
align-items: center;
|
|
167
|
+
justify-content: space-between;
|
|
168
|
+
padding: 14px 20px;
|
|
169
|
+
background: #111113;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.showcase-dots { display: flex; gap: 6px; }
|
|
173
|
+
.showcase-dots span {
|
|
174
|
+
width: 10px;
|
|
175
|
+
height: 10px;
|
|
176
|
+
border-radius: 50%;
|
|
177
|
+
background: #333;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.showcase-filename {
|
|
181
|
+
font-family: var(--mono);
|
|
182
|
+
font-size: 12px;
|
|
183
|
+
color: var(--code-gray);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.showcase-tabs {
|
|
187
|
+
display: flex;
|
|
188
|
+
background: #111113;
|
|
189
|
+
border-bottom: 1px solid #27272a;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.showcase-tab {
|
|
193
|
+
padding: 10px 24px;
|
|
194
|
+
font-family: var(--mono);
|
|
195
|
+
font-size: 12px;
|
|
196
|
+
color: var(--code-gray);
|
|
197
|
+
border-right: 1px solid #27272a;
|
|
198
|
+
cursor: pointer;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.showcase-tab.active {
|
|
202
|
+
color: var(--code-white);
|
|
203
|
+
background: var(--code-bg);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.showcase-grid {
|
|
207
|
+
display: grid;
|
|
208
|
+
grid-template-columns: 40px 1fr;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.showcase-lines {
|
|
212
|
+
padding: 24px 0;
|
|
213
|
+
background: #111113;
|
|
214
|
+
text-align: right;
|
|
215
|
+
font-family: var(--mono);
|
|
216
|
+
font-size: 13px;
|
|
217
|
+
line-height: 1.85;
|
|
218
|
+
color: #3f3f46;
|
|
219
|
+
user-select: none;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.showcase-lines span {
|
|
223
|
+
display: block;
|
|
224
|
+
padding-right: 12px;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.showcase-code {
|
|
228
|
+
padding: 24px 24px 24px 16px;
|
|
229
|
+
font-family: var(--mono);
|
|
230
|
+
font-size: 13px;
|
|
231
|
+
line-height: 1.85;
|
|
232
|
+
color: var(--code-white);
|
|
233
|
+
overflow-x: auto;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.s-kw { color: var(--code-blue); }
|
|
237
|
+
.s-fn { color: var(--code-white); }
|
|
238
|
+
.s-str { color: var(--code-green); }
|
|
239
|
+
.s-dec { color: var(--code-yellow); }
|
|
240
|
+
.s-num { color: var(--code-orange); }
|
|
241
|
+
.s-cmt { color: var(--code-gray); }
|
|
242
|
+
.s-param { color: var(--code-orange); }
|
|
243
|
+
.s-dim { color: #52525b; }
|
|
244
|
+
|
|
245
|
+
/* ── METRICS BAR ── */
|
|
246
|
+
.metrics-bar {
|
|
247
|
+
max-width: 1120px;
|
|
248
|
+
margin: 0 auto;
|
|
249
|
+
padding: 0 40px 100px;
|
|
250
|
+
display: grid;
|
|
251
|
+
grid-template-columns: repeat(4, 1fr);
|
|
252
|
+
gap: 1px;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.metric-card {
|
|
256
|
+
background: var(--surface);
|
|
257
|
+
border: 1px solid var(--border);
|
|
258
|
+
padding: 32px 28px;
|
|
259
|
+
border-right: none;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.metric-card:last-child { border-right: 1px solid var(--border); }
|
|
263
|
+
|
|
264
|
+
.metric-value {
|
|
265
|
+
font-size: 32px;
|
|
266
|
+
font-weight: 700;
|
|
267
|
+
letter-spacing: -1px;
|
|
268
|
+
margin-bottom: 4px;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.metric-label {
|
|
272
|
+
font-size: 13px;
|
|
273
|
+
color: var(--text-tertiary);
|
|
274
|
+
font-weight: 500;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/* ── HOW IT WORKS ── */
|
|
278
|
+
.how-section {
|
|
279
|
+
max-width: 1120px;
|
|
280
|
+
margin: 0 auto;
|
|
281
|
+
padding: 0 40px 100px;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.section-label {
|
|
285
|
+
font-family: var(--mono);
|
|
286
|
+
font-size: 12px;
|
|
287
|
+
color: var(--accent);
|
|
288
|
+
margin-bottom: 12px;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.section-title {
|
|
292
|
+
font-size: 36px;
|
|
293
|
+
font-weight: 700;
|
|
294
|
+
letter-spacing: -1px;
|
|
295
|
+
margin-bottom: 48px;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.how-steps {
|
|
299
|
+
display: grid;
|
|
300
|
+
grid-template-columns: 1fr 1fr 1fr;
|
|
301
|
+
gap: 48px;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.how-step-num {
|
|
305
|
+
font-family: var(--mono);
|
|
306
|
+
font-size: 11px;
|
|
307
|
+
color: var(--text-tertiary);
|
|
308
|
+
margin-bottom: 16px;
|
|
309
|
+
padding-bottom: 16px;
|
|
310
|
+
border-bottom: 1px solid var(--border);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
.how-step-title {
|
|
314
|
+
font-size: 18px;
|
|
315
|
+
font-weight: 600;
|
|
316
|
+
margin-bottom: 10px;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.how-step-desc {
|
|
320
|
+
font-size: 14px;
|
|
321
|
+
color: var(--text-secondary);
|
|
322
|
+
line-height: 1.7;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.how-step-code {
|
|
326
|
+
font-family: var(--mono);
|
|
327
|
+
font-size: 12px;
|
|
328
|
+
background: var(--code-bg);
|
|
329
|
+
color: var(--code-green);
|
|
330
|
+
padding: 12px 16px;
|
|
331
|
+
margin-top: 16px;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/* ── GPU SECTION ── */
|
|
335
|
+
.gpu-section {
|
|
336
|
+
max-width: 1120px;
|
|
337
|
+
margin: 0 auto;
|
|
338
|
+
padding: 0 40px 100px;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.gpu-table-wrap {
|
|
342
|
+
background: var(--surface);
|
|
343
|
+
border: 1px solid var(--border);
|
|
344
|
+
overflow-x: auto;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.gpu-table {
|
|
348
|
+
width: 100%;
|
|
349
|
+
border-collapse: collapse;
|
|
350
|
+
font-size: 14px;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.gpu-table th {
|
|
354
|
+
text-align: left;
|
|
355
|
+
padding: 14px 20px;
|
|
356
|
+
font-size: 11px;
|
|
357
|
+
font-family: var(--mono);
|
|
358
|
+
text-transform: uppercase;
|
|
359
|
+
letter-spacing: 1px;
|
|
360
|
+
color: var(--text-tertiary);
|
|
361
|
+
font-weight: 500;
|
|
362
|
+
border-bottom: 1px solid var(--border);
|
|
363
|
+
background: var(--bg);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.gpu-table td {
|
|
367
|
+
padding: 14px 20px;
|
|
368
|
+
border-bottom: 1px solid var(--border);
|
|
369
|
+
color: var(--text-secondary);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.gpu-table tr:last-child td { border-bottom: none; }
|
|
373
|
+
|
|
374
|
+
.gpu-table tr:hover td { background: var(--accent-light); }
|
|
375
|
+
|
|
376
|
+
.gpu-name { color: var(--text); font-weight: 600; }
|
|
377
|
+
.gpu-price { color: var(--accent); font-weight: 600; font-family: var(--mono); }
|
|
378
|
+
|
|
379
|
+
/* ── USE CASES ── */
|
|
380
|
+
.cases-section {
|
|
381
|
+
max-width: 1120px;
|
|
382
|
+
margin: 0 auto;
|
|
383
|
+
padding: 0 40px 100px;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.cases-grid {
|
|
387
|
+
display: grid;
|
|
388
|
+
grid-template-columns: 1fr 1fr;
|
|
389
|
+
gap: 24px;
|
|
390
|
+
margin-top: 48px;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
.case-card {
|
|
394
|
+
background: var(--surface);
|
|
395
|
+
border: 1px solid var(--border);
|
|
396
|
+
overflow: hidden;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.case-header {
|
|
400
|
+
padding: 24px 28px 0;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.case-label {
|
|
404
|
+
font-family: var(--mono);
|
|
405
|
+
font-size: 11px;
|
|
406
|
+
color: var(--text-tertiary);
|
|
407
|
+
text-transform: uppercase;
|
|
408
|
+
letter-spacing: 1px;
|
|
409
|
+
margin-bottom: 8px;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.case-title {
|
|
413
|
+
font-size: 20px;
|
|
414
|
+
font-weight: 600;
|
|
415
|
+
margin-bottom: 8px;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.case-desc {
|
|
419
|
+
font-size: 14px;
|
|
420
|
+
color: var(--text-secondary);
|
|
421
|
+
line-height: 1.6;
|
|
422
|
+
padding: 0 28px 20px;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.case-code {
|
|
426
|
+
background: var(--code-bg);
|
|
427
|
+
padding: 20px 24px;
|
|
428
|
+
font-family: var(--mono);
|
|
429
|
+
font-size: 12px;
|
|
430
|
+
line-height: 1.8;
|
|
431
|
+
color: var(--code-white);
|
|
432
|
+
border-top: 1px solid var(--border);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* ── PRICING ── */
|
|
436
|
+
.pricing-section {
|
|
437
|
+
max-width: 1120px;
|
|
438
|
+
margin: 0 auto;
|
|
439
|
+
padding: 0 40px 100px;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.pricing-grid {
|
|
443
|
+
display: grid;
|
|
444
|
+
grid-template-columns: repeat(3, 1fr);
|
|
445
|
+
gap: 24px;
|
|
446
|
+
margin-top: 48px;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
.pricing-card {
|
|
450
|
+
background: var(--surface);
|
|
451
|
+
border: 1px solid var(--border);
|
|
452
|
+
padding: 36px 32px;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.pricing-card.featured {
|
|
456
|
+
background: var(--text);
|
|
457
|
+
color: var(--bg);
|
|
458
|
+
border-color: var(--text);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
.pricing-card.featured .pricing-card-label { color: var(--code-green); }
|
|
462
|
+
.pricing-card.featured .pricing-card-price { color: var(--bg); }
|
|
463
|
+
.pricing-card.featured .pricing-card-features li { color: #a1a1aa; border-color: #333; }
|
|
464
|
+
.pricing-card.featured .pricing-card-features li::before { color: var(--code-green); }
|
|
465
|
+
|
|
466
|
+
.pricing-card-label {
|
|
467
|
+
font-family: var(--mono);
|
|
468
|
+
font-size: 11px;
|
|
469
|
+
color: var(--accent);
|
|
470
|
+
text-transform: uppercase;
|
|
471
|
+
letter-spacing: 1px;
|
|
472
|
+
margin-bottom: 16px;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.pricing-card-price {
|
|
476
|
+
font-size: 40px;
|
|
477
|
+
font-weight: 700;
|
|
478
|
+
letter-spacing: -2px;
|
|
479
|
+
margin-bottom: 4px;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
.pricing-card-unit {
|
|
483
|
+
font-size: 13px;
|
|
484
|
+
color: var(--text-tertiary);
|
|
485
|
+
margin-bottom: 28px;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.pricing-card-features {
|
|
489
|
+
list-style: none;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.pricing-card-features li {
|
|
493
|
+
font-size: 13px;
|
|
494
|
+
color: var(--text-secondary);
|
|
495
|
+
padding: 8px 0;
|
|
496
|
+
border-bottom: 1px solid var(--border);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
.pricing-card-features li::before {
|
|
500
|
+
content: "+";
|
|
501
|
+
font-family: var(--mono);
|
|
502
|
+
color: var(--accent);
|
|
503
|
+
margin-right: 10px;
|
|
504
|
+
font-weight: 600;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/* ── BOTTOM CTA ── */
|
|
508
|
+
.bottom-cta {
|
|
509
|
+
max-width: 1120px;
|
|
510
|
+
margin: 0 auto;
|
|
511
|
+
padding: 0 40px 120px;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
.bottom-cta-inner {
|
|
515
|
+
background: var(--text);
|
|
516
|
+
padding: 80px 64px;
|
|
517
|
+
display: flex;
|
|
518
|
+
justify-content: space-between;
|
|
519
|
+
align-items: center;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.bottom-cta-title {
|
|
523
|
+
font-size: 36px;
|
|
524
|
+
font-weight: 700;
|
|
525
|
+
color: var(--bg);
|
|
526
|
+
letter-spacing: -1px;
|
|
527
|
+
max-width: 480px;
|
|
528
|
+
line-height: 1.15;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
.bottom-cta-right { display: flex; flex-direction: column; gap: 12px; align-items: flex-end; }
|
|
532
|
+
|
|
533
|
+
.btn-volt {
|
|
534
|
+
background: var(--code-green);
|
|
535
|
+
color: var(--text);
|
|
536
|
+
padding: 14px 32px;
|
|
537
|
+
font-size: 15px;
|
|
538
|
+
font-weight: 700;
|
|
539
|
+
border: none;
|
|
540
|
+
cursor: pointer;
|
|
541
|
+
text-decoration: none;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.btn-volt:hover { opacity: 0.9; }
|
|
545
|
+
|
|
546
|
+
.bottom-cta-hint {
|
|
547
|
+
font-family: var(--mono);
|
|
548
|
+
font-size: 12px;
|
|
549
|
+
color: #71717a;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/* ── FOOTER ── */
|
|
553
|
+
.footer {
|
|
554
|
+
max-width: 1120px;
|
|
555
|
+
margin: 0 auto;
|
|
556
|
+
padding: 24px 40px 40px;
|
|
557
|
+
display: flex;
|
|
558
|
+
justify-content: space-between;
|
|
559
|
+
font-size: 12px;
|
|
560
|
+
color: var(--text-tertiary);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
.footer a { color: var(--text-tertiary); text-decoration: none; }
|
|
564
|
+
.footer a:hover { color: var(--text); }
|
|
565
|
+
|
|
566
|
+
/* ── MOBILE ── */
|
|
567
|
+
@media (max-width: 900px) {
|
|
568
|
+
.hero { padding: 60px 24px 48px; }
|
|
569
|
+
.hero-title { font-size: 36px; letter-spacing: -1px; }
|
|
570
|
+
.showcase { padding: 0 24px 64px; }
|
|
571
|
+
.metrics-bar { grid-template-columns: 1fr 1fr; padding: 0 24px 64px; }
|
|
572
|
+
.metric-card { border-right: 1px solid var(--border); border-bottom: none; }
|
|
573
|
+
.how-steps { grid-template-columns: 1fr; gap: 32px; }
|
|
574
|
+
.cases-grid { grid-template-columns: 1fr; }
|
|
575
|
+
.pricing-grid { grid-template-columns: 1fr; }
|
|
576
|
+
.bottom-cta-inner { flex-direction: column; gap: 32px; padding: 48px 32px; text-align: center; }
|
|
577
|
+
.bottom-cta-right { align-items: center; }
|
|
578
|
+
.nav-right a:not(:last-child) { display: none; }
|
|
579
|
+
.how-section, .gpu-section, .cases-section, .pricing-section { padding-left: 24px; padding-right: 24px; }
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
@media (max-width: 600px) {
|
|
583
|
+
.metrics-bar { grid-template-columns: 1fr; }
|
|
584
|
+
.hero-actions { flex-direction: column; align-items: flex-start; }
|
|
585
|
+
.showcase-grid { grid-template-columns: 1fr; }
|
|
586
|
+
.showcase-lines { display: none; }
|
|
587
|
+
}
|
|
588
|
+
</style>
|
|
589
|
+
</head>
|
|
590
|
+
<body>
|
|
591
|
+
|
|
592
|
+
<!-- NAV -->
|
|
593
|
+
<nav class="nav">
|
|
594
|
+
<div class="nav-logo">voltage<span class="dot">.</span></div>
|
|
595
|
+
<div class="nav-right">
|
|
596
|
+
<a href="#">Documentation</a>
|
|
597
|
+
<a href="#">Pricing</a>
|
|
598
|
+
<a href="#">Changelog</a>
|
|
599
|
+
<a href="#" class="btn-start">Get started</a>
|
|
600
|
+
</div>
|
|
601
|
+
</nav>
|
|
602
|
+
|
|
603
|
+
<!-- HERO -->
|
|
604
|
+
<section class="hero">
|
|
605
|
+
<div class="hero-overline">Serverless compute for AI workloads</div>
|
|
606
|
+
<h1 class="hero-title">Run GPU workloads<br>without the infrastructure.</h1>
|
|
607
|
+
<p class="hero-desc">Write ordinary Python. Attach the resources you need. Voltage runs it in the cloud, scaling from zero to thousands of containers.</p>
|
|
608
|
+
<div class="hero-actions">
|
|
609
|
+
<a href="#" class="btn-start">Run your first function</a>
|
|
610
|
+
<a href="#" class="btn-outline">View documentation</a>
|
|
611
|
+
</div>
|
|
612
|
+
<div class="hero-install">
|
|
613
|
+
<code>pip install voltage</code>
|
|
614
|
+
</div>
|
|
615
|
+
</section>
|
|
616
|
+
|
|
617
|
+
<!-- CODE SHOWCASE -->
|
|
618
|
+
<div class="showcase">
|
|
619
|
+
<div class="showcase-window">
|
|
620
|
+
<div class="showcase-chrome">
|
|
621
|
+
<div class="showcase-dots"><span></span><span></span><span></span></div>
|
|
622
|
+
<div class="showcase-filename">3 files changed</div>
|
|
623
|
+
</div>
|
|
624
|
+
<div class="showcase-tabs">
|
|
625
|
+
<div class="showcase-tab active">serve.py</div>
|
|
626
|
+
<div class="showcase-tab">image.py</div>
|
|
627
|
+
<div class="showcase-tab">deploy.sh</div>
|
|
628
|
+
</div>
|
|
629
|
+
<div class="showcase-grid">
|
|
630
|
+
<div class="showcase-lines">
|
|
631
|
+
<span>1</span><span>2</span><span>3</span><span>4</span><span>5</span>
|
|
632
|
+
<span>6</span><span>7</span><span>8</span><span>9</span><span>10</span>
|
|
633
|
+
<span>11</span><span>12</span><span>13</span><span>14</span><span>15</span>
|
|
634
|
+
<span>16</span><span>17</span><span>18</span><span>19</span><span>20</span>
|
|
635
|
+
<span>21</span><span>22</span><span>23</span><span>24</span><span>25</span>
|
|
636
|
+
<span>26</span><span>27</span>
|
|
637
|
+
</div>
|
|
638
|
+
<div class="showcase-code">
|
|
639
|
+
<span class="s-kw">import</span> voltage
|
|
640
|
+
|
|
641
|
+
app = voltage.App(<span class="s-str">"text-to-image"</span>)
|
|
642
|
+
|
|
643
|
+
<span class="s-cmt"># Build container image with ML dependencies</span>
|
|
644
|
+
image = (
|
|
645
|
+
voltage.Image.debian_slim(python=<span class="s-str">"3.11"</span>)
|
|
646
|
+
.pip_install(<span class="s-str">"torch"</span>, <span class="s-str">"diffusers"</span>, <span class="s-str">"accelerate"</span>)
|
|
647
|
+
)
|
|
648
|
+
|
|
649
|
+
<span class="s-dec">@app.cls</span>(gpu=<span class="s-str">"A100-80GB"</span>, image=image, container_idle_timeout=<span class="s-num">120</span>)
|
|
650
|
+
<span class="s-kw">class</span> TextToImage:
|
|
651
|
+
<span class="s-dec">@voltage.enter</span>()
|
|
652
|
+
<span class="s-kw">def</span> setup(self):
|
|
653
|
+
<span class="s-kw">from</span> diffusers <span class="s-kw">import</span> StableDiffusionXLPipeline
|
|
654
|
+
self.pipe = StableDiffusionXLPipeline.from_pretrained(
|
|
655
|
+
<span class="s-str">"stabilityai/stable-diffusion-xl-base-1.0"</span>,
|
|
656
|
+
torch_dtype=torch.float16,
|
|
657
|
+
).to(<span class="s-str">"cuda"</span>)
|
|
658
|
+
|
|
659
|
+
<span class="s-dec">@voltage.method</span>()
|
|
660
|
+
<span class="s-kw">def</span> generate(self, prompt: <span class="s-param">str</span>, steps: <span class="s-param">int</span> = <span class="s-num">30</span>) -> bytes:
|
|
661
|
+
image = self.pipe(prompt, num_inference_steps=steps).images[<span class="s-num">0</span>]
|
|
662
|
+
buf = io.BytesIO()
|
|
663
|
+
image.save(buf, format=<span class="s-str">"PNG"</span>)
|
|
664
|
+
<span class="s-kw">return</span> buf.getvalue()
|
|
665
|
+
</div>
|
|
666
|
+
</div>
|
|
667
|
+
</div>
|
|
668
|
+
</div>
|
|
669
|
+
|
|
670
|
+
<!-- METRICS -->
|
|
671
|
+
<div class="metrics-bar">
|
|
672
|
+
<div class="metric-card">
|
|
673
|
+
<div class="metric-value"><300ms</div>
|
|
674
|
+
<div class="metric-label">Cold start latency</div>
|
|
675
|
+
</div>
|
|
676
|
+
<div class="metric-card">
|
|
677
|
+
<div class="metric-value">10,000+</div>
|
|
678
|
+
<div class="metric-label">Concurrent containers</div>
|
|
679
|
+
</div>
|
|
680
|
+
<div class="metric-card">
|
|
681
|
+
<div class="metric-value">$0.00</div>
|
|
682
|
+
<div class="metric-label">Cost when idle</div>
|
|
683
|
+
</div>
|
|
684
|
+
<div class="metric-card">
|
|
685
|
+
<div class="metric-value">6</div>
|
|
686
|
+
<div class="metric-label">GPU types available</div>
|
|
687
|
+
</div>
|
|
688
|
+
</div>
|
|
689
|
+
|
|
690
|
+
<!-- HOW IT WORKS -->
|
|
691
|
+
<section class="how-section">
|
|
692
|
+
<div class="section-label">How it works</div>
|
|
693
|
+
<h2 class="section-title">Three steps. No infrastructure.</h2>
|
|
694
|
+
|
|
695
|
+
<div class="how-steps">
|
|
696
|
+
<div class="how-step">
|
|
697
|
+
<div class="how-step-num">01 / Define</div>
|
|
698
|
+
<h3 class="how-step-title">Write a Python function</h3>
|
|
699
|
+
<p class="how-step-desc">Use the @app.function decorator to specify GPU type, memory, timeout, and dependencies. Your function is the deployment artifact.</p>
|
|
700
|
+
<div class="how-step-code">@app.function(gpu="A100")</div>
|
|
701
|
+
</div>
|
|
702
|
+
<div class="how-step">
|
|
703
|
+
<div class="how-step-num">02 / Deploy</div>
|
|
704
|
+
<h3 class="how-step-title">One command to ship</h3>
|
|
705
|
+
<p class="how-step-desc">Voltage builds a container with your dependencies, pushes it to our global fleet, and creates an HTTPS endpoint automatically.</p>
|
|
706
|
+
<div class="how-step-code">$ voltage deploy</div>
|
|
707
|
+
</div>
|
|
708
|
+
<div class="how-step">
|
|
709
|
+
<div class="how-step-num">03 / Scale</div>
|
|
710
|
+
<h3 class="how-step-title">Automatic scaling</h3>
|
|
711
|
+
<p class="how-step-desc">From zero to thousands of GPU containers based on demand. Scale back to zero between bursts. Per-second billing only.</p>
|
|
712
|
+
<div class="how-step-code">generate.remote(prompt)</div>
|
|
713
|
+
</div>
|
|
714
|
+
</div>
|
|
715
|
+
</section>
|
|
716
|
+
|
|
717
|
+
<!-- GPU CATALOG -->
|
|
718
|
+
<section class="gpu-section">
|
|
719
|
+
<div class="section-label">Hardware</div>
|
|
720
|
+
<h2 class="section-title">GPU catalog</h2>
|
|
721
|
+
|
|
722
|
+
<div class="gpu-table-wrap">
|
|
723
|
+
<table class="gpu-table">
|
|
724
|
+
<thead>
|
|
725
|
+
<tr>
|
|
726
|
+
<th>GPU</th>
|
|
727
|
+
<th>VRAM</th>
|
|
728
|
+
<th>FP16 TFLOPS</th>
|
|
729
|
+
<th>Ideal for</th>
|
|
730
|
+
<th>Price</th>
|
|
731
|
+
<th>Cold start</th>
|
|
732
|
+
</tr>
|
|
733
|
+
</thead>
|
|
734
|
+
<tbody>
|
|
735
|
+
<tr>
|
|
736
|
+
<td class="gpu-name">NVIDIA T4</td>
|
|
737
|
+
<td>16 GB</td>
|
|
738
|
+
<td>65</td>
|
|
739
|
+
<td>Inference, embeddings</td>
|
|
740
|
+
<td class="gpu-price">$0.59/hr</td>
|
|
741
|
+
<td>~200ms</td>
|
|
742
|
+
</tr>
|
|
743
|
+
<tr>
|
|
744
|
+
<td class="gpu-name">NVIDIA L4</td>
|
|
745
|
+
<td>24 GB</td>
|
|
746
|
+
<td>121</td>
|
|
747
|
+
<td>Inference, encoding</td>
|
|
748
|
+
<td class="gpu-price">$0.73/hr</td>
|
|
749
|
+
<td>~220ms</td>
|
|
750
|
+
</tr>
|
|
751
|
+
<tr>
|
|
752
|
+
<td class="gpu-name">NVIDIA A10G</td>
|
|
753
|
+
<td>24 GB</td>
|
|
754
|
+
<td>125</td>
|
|
755
|
+
<td>Training & inference</td>
|
|
756
|
+
<td class="gpu-price">$1.10/hr</td>
|
|
757
|
+
<td>~250ms</td>
|
|
758
|
+
</tr>
|
|
759
|
+
<tr>
|
|
760
|
+
<td class="gpu-name">NVIDIA A100 40GB</td>
|
|
761
|
+
<td>40 GB</td>
|
|
762
|
+
<td>312</td>
|
|
763
|
+
<td>Large model training</td>
|
|
764
|
+
<td class="gpu-price">$2.78/hr</td>
|
|
765
|
+
<td>~280ms</td>
|
|
766
|
+
</tr>
|
|
767
|
+
<tr>
|
|
768
|
+
<td class="gpu-name">NVIDIA A100 80GB</td>
|
|
769
|
+
<td>80 GB</td>
|
|
770
|
+
<td>312</td>
|
|
771
|
+
<td>70B+ parameter models</td>
|
|
772
|
+
<td class="gpu-price">$3.64/hr</td>
|
|
773
|
+
<td>~280ms</td>
|
|
774
|
+
</tr>
|
|
775
|
+
<tr>
|
|
776
|
+
<td class="gpu-name">NVIDIA H100</td>
|
|
777
|
+
<td>80 GB</td>
|
|
778
|
+
<td>989</td>
|
|
779
|
+
<td>Frontier training</td>
|
|
780
|
+
<td class="gpu-price">$4.25/hr</td>
|
|
781
|
+
<td>~90s</td>
|
|
782
|
+
</tr>
|
|
783
|
+
</tbody>
|
|
784
|
+
</table>
|
|
785
|
+
</div>
|
|
786
|
+
</section>
|
|
787
|
+
|
|
788
|
+
<!-- USE CASES -->
|
|
789
|
+
<section class="cases-section">
|
|
790
|
+
<div class="section-label">Patterns</div>
|
|
791
|
+
<h2 class="section-title">What people build</h2>
|
|
792
|
+
|
|
793
|
+
<div class="cases-grid">
|
|
794
|
+
<div class="case-card">
|
|
795
|
+
<div class="case-header">
|
|
796
|
+
<div class="case-label">Batch processing</div>
|
|
797
|
+
<h3 class="case-title">Parallel GPU inference at scale</h3>
|
|
798
|
+
</div>
|
|
799
|
+
<p class="case-desc">Fan out across hundreds of GPU containers with .map(). Process millions of items in minutes instead of hours.</p>
|
|
800
|
+
<div class="case-code">
|
|
801
|
+
<span class="s-dec">@app.function</span>(gpu=<span class="s-str">"T4"</span>, concurrency=<span class="s-num">200</span>)
|
|
802
|
+
<span class="s-kw">def</span> embed(batch: list[<span class="s-param">str</span>]):
|
|
803
|
+
model = SentenceTransformer(<span class="s-str">"all-MiniLM-L6-v2"</span>)
|
|
804
|
+
<span class="s-kw">return</span> model.encode(batch)
|
|
805
|
+
|
|
806
|
+
<span class="s-cmt"># 5M docs across 200 containers</span>
|
|
807
|
+
results = list(embed.map(chunks))
|
|
808
|
+
</div>
|
|
809
|
+
</div>
|
|
810
|
+
<div class="case-card">
|
|
811
|
+
<div class="case-header">
|
|
812
|
+
<div class="case-label">Scheduled jobs</div>
|
|
813
|
+
<h3 class="case-title">Nightly training with GPU on demand</h3>
|
|
814
|
+
</div>
|
|
815
|
+
<p class="case-desc">Schedule training runs or batch jobs. GPU allocated only during execution, released immediately after.</p>
|
|
816
|
+
<div class="case-code">
|
|
817
|
+
<span class="s-dec">@app.function</span>(
|
|
818
|
+
gpu=<span class="s-str">"A100-80GB"</span>,
|
|
819
|
+
schedule=voltage.Cron(<span class="s-str">"0 2 * * *"</span>),
|
|
820
|
+
timeout=<span class="s-num">7200</span>,
|
|
821
|
+
)
|
|
822
|
+
<span class="s-kw">def</span> nightly_train():
|
|
823
|
+
dataset = load_latest_data()
|
|
824
|
+
model = finetune(dataset, epochs=<span class="s-num">5</span>)
|
|
825
|
+
push_to_registry(model)
|
|
826
|
+
</div>
|
|
827
|
+
</div>
|
|
828
|
+
<div class="case-card">
|
|
829
|
+
<div class="case-header">
|
|
830
|
+
<div class="case-label">Web endpoints</div>
|
|
831
|
+
<h3 class="case-title">Model serving with auto-scaling</h3>
|
|
832
|
+
</div>
|
|
833
|
+
<p class="case-desc">Turn any model into an HTTP API with automatic scaling, request batching, and GPU warm pools.</p>
|
|
834
|
+
<div class="case-code">
|
|
835
|
+
<span class="s-dec">@app.endpoint</span>(method=<span class="s-str">"POST"</span>)
|
|
836
|
+
<span class="s-kw">def</span> generate(prompt: <span class="s-param">str</span>):
|
|
837
|
+
<span class="s-kw">return</span> TextToImage().generate.remote(
|
|
838
|
+
prompt
|
|
839
|
+
)
|
|
840
|
+
|
|
841
|
+
<span class="s-cmt"># https://your-app.voltage.run/generate</span>
|
|
842
|
+
</div>
|
|
843
|
+
</div>
|
|
844
|
+
<div class="case-card">
|
|
845
|
+
<div class="case-header">
|
|
846
|
+
<div class="case-label">Data pipelines</div>
|
|
847
|
+
<h3 class="case-title">Chain functions into workflows</h3>
|
|
848
|
+
</div>
|
|
849
|
+
<p class="case-desc">Build DAG pipelines that mix CPU and GPU stages. Each stage scales independently. Shared volumes pass data between steps.</p>
|
|
850
|
+
<div class="case-code">
|
|
851
|
+
<span class="s-dec">@app.function</span>(cpu=<span class="s-num">8</span>)
|
|
852
|
+
<span class="s-kw">def</span> preprocess(raw_path: <span class="s-param">str</span>):
|
|
853
|
+
data = clean(load(raw_path))
|
|
854
|
+
<span class="s-kw">return</span> save(data, <span class="s-str">"/vol/clean"</span>)
|
|
855
|
+
|
|
856
|
+
<span class="s-dec">@app.function</span>(gpu=<span class="s-str">"A100"</span>)
|
|
857
|
+
<span class="s-kw">def</span> train(data_path: <span class="s-param">str</span>):
|
|
858
|
+
model = fit(load(data_path))
|
|
859
|
+
<span class="s-kw">return</span> save(model, <span class="s-str">"/vol/models"</span>)
|
|
860
|
+
</div>
|
|
861
|
+
</div>
|
|
862
|
+
</div>
|
|
863
|
+
</section>
|
|
864
|
+
|
|
865
|
+
<!-- PRICING -->
|
|
866
|
+
<section class="pricing-section">
|
|
867
|
+
<div class="section-label">Pricing</div>
|
|
868
|
+
<h2 class="section-title">Pay for seconds. Idle is free.</h2>
|
|
869
|
+
|
|
870
|
+
<div class="pricing-grid">
|
|
871
|
+
<div class="pricing-card">
|
|
872
|
+
<div class="pricing-card-label">CPU</div>
|
|
873
|
+
<div class="pricing-card-price">$0.024</div>
|
|
874
|
+
<div class="pricing-card-unit">per vCPU / hour</div>
|
|
875
|
+
<ul class="pricing-card-features">
|
|
876
|
+
<li>Up to 64 vCPUs per container</li>
|
|
877
|
+
<li>Up to 256 GB RAM</li>
|
|
878
|
+
<li>Per-second billing</li>
|
|
879
|
+
<li>NVMe scratch included</li>
|
|
880
|
+
</ul>
|
|
881
|
+
</div>
|
|
882
|
+
<div class="pricing-card featured">
|
|
883
|
+
<div class="pricing-card-label">GPU</div>
|
|
884
|
+
<div class="pricing-card-price">$0.59</div>
|
|
885
|
+
<div class="pricing-card-unit">per GPU / hour (from T4)</div>
|
|
886
|
+
<ul class="pricing-card-features">
|
|
887
|
+
<li>T4, L4, A10G, A100, H100</li>
|
|
888
|
+
<li>Multi-GPU configurations</li>
|
|
889
|
+
<li>Per-second billing</li>
|
|
890
|
+
<li>Preemptible: up to 60% off</li>
|
|
891
|
+
</ul>
|
|
892
|
+
</div>
|
|
893
|
+
<div class="pricing-card">
|
|
894
|
+
<div class="pricing-card-label">Storage + Network</div>
|
|
895
|
+
<div class="pricing-card-price">$0.10</div>
|
|
896
|
+
<div class="pricing-card-unit">per GB / month (storage)</div>
|
|
897
|
+
<ul class="pricing-card-features">
|
|
898
|
+
<li>Persistent shared volumes</li>
|
|
899
|
+
<li>Free ingress</li>
|
|
900
|
+
<li>$0.05/GB egress</li>
|
|
901
|
+
<li>Global edge routing</li>
|
|
902
|
+
</ul>
|
|
903
|
+
</div>
|
|
904
|
+
</div>
|
|
905
|
+
</section>
|
|
906
|
+
|
|
907
|
+
<!-- BOTTOM CTA -->
|
|
908
|
+
<section class="bottom-cta">
|
|
909
|
+
<div class="bottom-cta-inner">
|
|
910
|
+
<h2 class="bottom-cta-title">Run your first GPU function in under five minutes.</h2>
|
|
911
|
+
<div class="bottom-cta-right">
|
|
912
|
+
<a href="#" class="btn-volt">Get started free</a>
|
|
913
|
+
<div class="bottom-cta-hint">pip install voltage</div>
|
|
914
|
+
</div>
|
|
915
|
+
</div>
|
|
916
|
+
</section>
|
|
917
|
+
|
|
918
|
+
<!-- FOOTER -->
|
|
919
|
+
<footer class="footer">
|
|
920
|
+
<span>Voltage 2026</span>
|
|
921
|
+
<div>
|
|
922
|
+
<a href="#">Docs</a> ·
|
|
923
|
+
<a href="#">Pricing</a> ·
|
|
924
|
+
<a href="#">Status</a> ·
|
|
925
|
+
<a href="#">GitHub</a>
|
|
926
|
+
</div>
|
|
927
|
+
</footer>
|
|
928
|
+
|
|
929
|
+
</body>
|
|
930
|
+
</html>
|