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.
Files changed (190) hide show
  1. package/README.md +54 -3
  2. package/bin/cross-publish.mjs +344 -0
  3. package/bin/forgedock.mjs +2205 -541
  4. package/bin/github-app-manifest.json.license +2 -0
  5. package/bin/hooks/session-start.mjs +4 -5
  6. package/bin/registry.mjs +20 -0
  7. package/bin/tui.mjs +172 -96
  8. package/commands/adopt.md +433 -0
  9. package/commands/analytics.md +2 -0
  10. package/commands/audit-agents.md +2 -0
  11. package/commands/audit.md +2 -0
  12. package/commands/autopilot.md +77 -0
  13. package/commands/changelog.md +354 -0
  14. package/commands/cleanup.md +2 -0
  15. package/commands/compat-audit.md +330 -0
  16. package/commands/deploy-info.md +6 -5
  17. package/commands/design-bench.md +176 -0
  18. package/commands/design-render-critique-loop.md +103 -0
  19. package/commands/design.md +259 -0
  20. package/commands/diagnose.md +483 -0
  21. package/commands/explain.md +349 -0
  22. package/commands/forge-stats.md +2 -0
  23. package/commands/forgedock-init.md +2 -0
  24. package/commands/geo-audit.md +2 -0
  25. package/commands/incident-response.md +2 -0
  26. package/commands/issue.md +9 -3
  27. package/commands/milestone.md +2 -0
  28. package/commands/optimize.md +411 -0
  29. package/commands/orchestrate.md +239 -0
  30. package/commands/pipeline-health.md +60 -1
  31. package/commands/qa-sweep.md +39 -2
  32. package/commands/quality-gate.md +67 -0
  33. package/commands/replay.md +263 -0
  34. package/commands/resume.md +264 -0
  35. package/commands/review-pr-agents.md +5 -1
  36. package/commands/review-pr-staging.md +160 -2
  37. package/commands/review-pr.md +85 -3
  38. package/commands/rollback.md +2 -0
  39. package/commands/scope.md +280 -0
  40. package/commands/security-audit.md +2 -0
  41. package/commands/status.md +262 -0
  42. package/commands/sync-ecosystem.md +2 -0
  43. package/commands/test-gate.md +929 -0
  44. package/commands/validate.md +2 -0
  45. package/commands/work-on/build/architect.md +128 -18
  46. package/commands/work-on/build/context.md +130 -17
  47. package/commands/work-on/build/implement.md +7 -3
  48. package/commands/work-on/build/validate.md +2 -0
  49. package/commands/work-on/build.md +32 -7
  50. package/commands/work-on/close.md +85 -0
  51. package/commands/work-on/decompose.md +2 -0
  52. package/commands/work-on/investigate.md +30 -3
  53. package/commands/work-on/review.md +13 -1
  54. package/commands/work-on-monolithic.md +2 -0
  55. package/commands/work-on.md +676 -38
  56. package/docs/BRAND.md +51 -0
  57. package/docs/CI.md +177 -0
  58. package/docs/CONFIG.md +94 -0
  59. package/docs/FORGE-PROTOCOL.md +324 -0
  60. package/docs/articles/b-vs-c-baseline.md +210 -0
  61. package/docs/articles/full-abc-benchmark.md +205 -0
  62. package/docs/articles/per-repo-adaptive-scripts-token-savings.md +174 -0
  63. package/docs/articles/selective-spec-loading-token-savings.md +140 -0
  64. package/docs/claude-breakpoints.json +47 -0
  65. package/docs/design/abc-benchmark.md +195 -0
  66. package/docs/design/design-architect-rationale.md +123 -0
  67. package/docs/design/design-memory.md +61 -0
  68. package/docs/design/design-spec-schema.md +248 -0
  69. package/docs/design/design-system-lint.md +150 -0
  70. package/docs/design/divergent-generation.md +106 -0
  71. package/docs/design/effects-appropriateness.md +133 -0
  72. package/docs/design/fixtures/briefs/README.md +47 -0
  73. package/docs/design/fixtures/briefs/cadence.md +39 -0
  74. package/docs/design/fixtures/briefs/plume.md +39 -0
  75. package/docs/design/fixtures/briefs/slipstream.md +39 -0
  76. package/docs/design/fixtures/briefs/tender.md +39 -0
  77. package/docs/design/fixtures/briefs/voltage.md +39 -0
  78. package/docs/design/fixtures/runs/b-vs-c-baseline/cadence/arm-b/run-1.html +364 -0
  79. package/docs/design/fixtures/runs/b-vs-c-baseline/cadence/arm-b/run-2.html +420 -0
  80. package/docs/design/fixtures/runs/b-vs-c-baseline/cadence/arm-b/run-3.html +506 -0
  81. package/docs/design/fixtures/runs/b-vs-c-baseline/plume/arm-b/run-1.html +611 -0
  82. package/docs/design/fixtures/runs/b-vs-c-baseline/plume/arm-b/run-2.html +594 -0
  83. package/docs/design/fixtures/runs/b-vs-c-baseline/plume/arm-b/run-3.html +817 -0
  84. package/docs/design/fixtures/runs/b-vs-c-baseline/runs.json +175 -0
  85. package/docs/design/fixtures/runs/b-vs-c-baseline/scorecard.json +138 -0
  86. package/docs/design/fixtures/runs/b-vs-c-baseline/slipstream/arm-b/run-1.html +373 -0
  87. package/docs/design/fixtures/runs/b-vs-c-baseline/slipstream/arm-b/run-2.html +398 -0
  88. package/docs/design/fixtures/runs/b-vs-c-baseline/slipstream/arm-b/run-3.html +595 -0
  89. package/docs/design/fixtures/runs/b-vs-c-baseline/tender/arm-b/run-1.html +531 -0
  90. package/docs/design/fixtures/runs/b-vs-c-baseline/tender/arm-b/run-2.html +565 -0
  91. package/docs/design/fixtures/runs/b-vs-c-baseline/tender/arm-b/run-3.html +674 -0
  92. package/docs/design/fixtures/runs/b-vs-c-baseline/voltage/arm-b/run-1.html +388 -0
  93. package/docs/design/fixtures/runs/b-vs-c-baseline/voltage/arm-b/run-2.html +463 -0
  94. package/docs/design/fixtures/runs/b-vs-c-baseline/voltage/arm-b/run-3.html +568 -0
  95. package/docs/design/fixtures/runs/full-abc/cadence/arm-a/run-1.html +562 -0
  96. package/docs/design/fixtures/runs/full-abc/cadence/arm-a/run-2.html +618 -0
  97. package/docs/design/fixtures/runs/full-abc/cadence/arm-a/run-3.html +618 -0
  98. package/docs/design/fixtures/runs/full-abc/cadence/arm-b/run-1.html +364 -0
  99. package/docs/design/fixtures/runs/full-abc/cadence/arm-b/run-2.html +420 -0
  100. package/docs/design/fixtures/runs/full-abc/cadence/arm-b/run-3.html +506 -0
  101. package/docs/design/fixtures/runs/full-abc/plume/arm-a/run-1.html +527 -0
  102. package/docs/design/fixtures/runs/full-abc/plume/arm-a/run-2.html +445 -0
  103. package/docs/design/fixtures/runs/full-abc/plume/arm-a/run-3.html +483 -0
  104. package/docs/design/fixtures/runs/full-abc/plume/arm-b/run-1.html +611 -0
  105. package/docs/design/fixtures/runs/full-abc/plume/arm-b/run-2.html +594 -0
  106. package/docs/design/fixtures/runs/full-abc/plume/arm-b/run-3.html +817 -0
  107. package/docs/design/fixtures/runs/full-abc/runs.json +190 -0
  108. package/docs/design/fixtures/runs/full-abc/scorecard.json +144 -0
  109. package/docs/design/fixtures/runs/full-abc/slipstream/arm-a/run-1.html +496 -0
  110. package/docs/design/fixtures/runs/full-abc/slipstream/arm-a/run-2.html +447 -0
  111. package/docs/design/fixtures/runs/full-abc/slipstream/arm-a/run-3.html +564 -0
  112. package/docs/design/fixtures/runs/full-abc/slipstream/arm-b/run-1.html +373 -0
  113. package/docs/design/fixtures/runs/full-abc/slipstream/arm-b/run-2.html +398 -0
  114. package/docs/design/fixtures/runs/full-abc/slipstream/arm-b/run-3.html +595 -0
  115. package/docs/design/fixtures/runs/full-abc/tender/arm-a/run-1.html +622 -0
  116. package/docs/design/fixtures/runs/full-abc/tender/arm-a/run-2.html +475 -0
  117. package/docs/design/fixtures/runs/full-abc/tender/arm-a/run-3.html +660 -0
  118. package/docs/design/fixtures/runs/full-abc/tender/arm-b/run-1.html +531 -0
  119. package/docs/design/fixtures/runs/full-abc/tender/arm-b/run-2.html +565 -0
  120. package/docs/design/fixtures/runs/full-abc/tender/arm-b/run-3.html +674 -0
  121. package/docs/design/fixtures/runs/full-abc/voltage/arm-a/run-1.html +525 -0
  122. package/docs/design/fixtures/runs/full-abc/voltage/arm-a/run-2.html +446 -0
  123. package/docs/design/fixtures/runs/full-abc/voltage/arm-a/run-3.html +463 -0
  124. package/docs/design/fixtures/runs/full-abc/voltage/arm-b/run-1.html +388 -0
  125. package/docs/design/fixtures/runs/full-abc/voltage/arm-b/run-2.html +463 -0
  126. package/docs/design/fixtures/runs/full-abc/voltage/arm-b/run-3.html +568 -0
  127. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-a/run-1.html +1068 -0
  128. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-a/run-2.html +1423 -0
  129. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-a/run-3.html +1245 -0
  130. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-b/run-1.html +305 -0
  131. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-b/run-2.html +327 -0
  132. package/docs/design/fixtures/runs/full-abc-opus/cadence/arm-b/run-3.html +428 -0
  133. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-a/run-1.html +1270 -0
  134. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-a/run-2.html +1172 -0
  135. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-a/run-3.html +1532 -0
  136. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-b/run-1.html +315 -0
  137. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-b/run-2.html +342 -0
  138. package/docs/design/fixtures/runs/full-abc-opus/plume/arm-b/run-3.html +353 -0
  139. package/docs/design/fixtures/runs/full-abc-opus/runs.json +190 -0
  140. package/docs/design/fixtures/runs/full-abc-opus/scorecard.json +144 -0
  141. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-a/run-1.html +345 -0
  142. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-a/run-2.html +396 -0
  143. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-a/run-3.html +502 -0
  144. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-b/run-1.html +408 -0
  145. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-b/run-2.html +446 -0
  146. package/docs/design/fixtures/runs/full-abc-opus/slipstream/arm-b/run-3.html +496 -0
  147. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-a/run-1.html +813 -0
  148. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-a/run-2.html +711 -0
  149. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-a/run-3.html +721 -0
  150. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-b/run-1.html +280 -0
  151. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-b/run-2.html +291 -0
  152. package/docs/design/fixtures/runs/full-abc-opus/tender/arm-b/run-3.html +366 -0
  153. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-a/run-1.html +1010 -0
  154. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-a/run-2.html +836 -0
  155. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-a/run-3.html +930 -0
  156. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-b/run-1.html +407 -0
  157. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-b/run-2.html +396 -0
  158. package/docs/design/fixtures/runs/full-abc-opus/voltage/arm-b/run-3.html +529 -0
  159. package/docs/design/foundations/brutalist.css +294 -0
  160. package/docs/design/foundations/editorial.css +300 -0
  161. package/docs/design/foundations/minimal-luxury.css +295 -0
  162. package/docs/design/foundations/technical.css +293 -0
  163. package/docs/design/foundations/warm-photo.css +299 -0
  164. package/docs/design/reference-corpus.md +1726 -0
  165. package/docs/design/render-critique-loop.md +57 -0
  166. package/docs/site/getting-started.md +21 -0
  167. package/docs/spec-graph-schema.md +397 -0
  168. package/package.json +3 -3
  169. package/scripts/bench-scorecard.mjs +239 -0
  170. package/scripts/build-spec-graph.mjs +509 -0
  171. package/scripts/classify-lane.sh +138 -0
  172. package/scripts/design-system-lint.mjs +993 -0
  173. package/scripts/graph-query.sh +486 -0
  174. package/scripts/transition-label.sh +169 -0
  175. package/scripts/validate-pr-target.sh +30 -0
  176. package/scripts/validate-spec-graph.sh +423 -0
  177. package/templates/devdocs/README.md +72 -0
  178. package/templates/devdocs/agent/using-forgedock.md +3 -0
  179. package/templates/devdocs/agent/using-github.md +3 -0
  180. package/templates/devdocs/index.yaml +162 -0
  181. package/templates/devdocs/project/architecture.md +3 -0
  182. package/templates/devdocs/project/conventions.md +3 -0
  183. package/templates/devdocs/project/custom-instructions.md +3 -0
  184. package/templates/devdocs/project/glossary.md +3 -0
  185. package/templates/devdocs/project/stack.md +3 -0
  186. package/templates/devdocs/templates/commit-convention.md +3 -0
  187. package/templates/devdocs/templates/issue.md +3 -0
  188. package/templates/devdocs/templates/pull-request.md +3 -0
  189. package/templates/devdocs/templates/review-finding.md +3 -0
  190. package/templates/workflows/forgedock-review.yml +96 -0
@@ -0,0 +1,618 @@
1
+ <!--
2
+ CADENCE — ARM A, RUN 2
3
+ ======================
4
+
5
+ ARCHETYPE: editorial-typographic
6
+ Rationale: Email is a content medium — using an editorial archetype creates
7
+ a productive irony: the infrastructure product is sold using the same visual
8
+ language as the publications that rely on it. Serif headlines signal considered
9
+ opinion and craft; the tight mono code accents prove engineering depth. This
10
+ directly targets content-forward teams who are choosing an email tool because
11
+ they care about words, not just packets. Think: Stripe Docs meets The Ringer.
12
+
13
+ SIGNATURE MOVE: "Running marginalia" — the page uses a narrow left-margin
14
+ column (like editorial footnotes) that annotates each major section with small
15
+ pull-quote labels, percentages, or dates. This gives the page a newspaper
16
+ production quality that no template provides. The margin text is secondary
17
+ information that rewards careful reading without cluttering the main content.
18
+
19
+ EFFECTS PLAN:
20
+ - EARN: Thin horizontal rule slides in from left on section enter (1px, 280ms).
21
+ Justified: mimics a magazine rule drop; marks editorial section breaks.
22
+ - EARN: Headline text counter for the stats row (scrolled into view trigger).
23
+ Justified: makes the numbers land with weight, not just sit there.
24
+ - EARN: Code block line-by-line reveal (each line fades in with 60ms stagger).
25
+ Justified: demonstrates the brevity of the API by making each line meaningful.
26
+ - NEVER: Any gradient whatsoever, hover-scale animations, glassmorphism,
27
+ parallax, blob shapes, carousel, or sticky header color transitions.
28
+
29
+ ANTI-SLOP CHECKS (all must be false to ship):
30
+ N1 Purple/blue gradient hero → NO (cream + ink-black, NO gradient)
31
+ N2 Inter at default weights everywhere → NO (Playfair Display + DM Sans + DM Mono)
32
+ N3 Everything centered, no asymmetry → NO (left-anchored, marginalia column)
33
+ N4 Three identical feature icon cards → NO (editorial text-grid, no icon cards)
34
+ N5 One radius applied to everything → NO (code: 2px; tags: 2px; CTA btn: 3px)
35
+ N6 Default Tailwind palette as brand → NO (brand: #1B4332 forest green)
36
+ N7 Boilerplate hero→3cards→test→CTA → NO (magazine-style layout, running text)
37
+ N8 Stock illustration / 3D blobs → NO (typographic treatments only)
38
+ N9 Glassmorphism overuse → NO (zero glassmorphism)
39
+ N10 Equal visual weight / no hierarchy → NO (serif display vs. body vs. mono = 4 levels)
40
+ N11 Abstract promises, no product shown → NO (code shown in first viewport, real data)
41
+ N12 Decorative effects serving nothing → NO (rule animation signals section entry)
42
+
43
+ SELF-CRITIQUE: The marginalia device is unusual in SaaS — which is the point.
44
+ The risk is it reads "academic" rather than "editorial." The fix is to keep the
45
+ margin text warm/factual (stats, attributions, short labels) rather than
46
+ abstract commentary. The Playfair + DM Sans combination avoids the "startup serif
47
+ overconfidence" trap by pairing the editorial headline font with a grounded workhorse.
48
+ -->
49
+ <!DOCTYPE html>
50
+ <html lang="en">
51
+ <head>
52
+ <meta charset="UTF-8" />
53
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
54
+ <title>Cadence — Email sending API for product teams</title>
55
+ <script src="https://cdn.tailwindcss.com"></script>
56
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
57
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
58
+ <link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,600;0,700;1,400;1,600&family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;1,9..40,300&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet" />
59
+ <script>
60
+ tailwind.config = {
61
+ theme: {
62
+ extend: {
63
+ fontFamily: {
64
+ serif: ['Playfair Display', 'Georgia', 'serif'],
65
+ sans: ['DM Sans', 'sans-serif'],
66
+ mono: ['DM Mono', 'monospace'],
67
+ },
68
+ colors: {
69
+ brand: {
70
+ 50: '#f0faf4',
71
+ 100: '#d1f0dd',
72
+ 200: '#a3e0bb',
73
+ 300: '#6dcb95',
74
+ 400: '#3db070',
75
+ 500: '#1B4332',
76
+ 600: '#163829',
77
+ 700: '#112c1f',
78
+ 800: '#0c2117',
79
+ 900: '#07150e',
80
+ },
81
+ accent: '#2D6A4F',
82
+ parchment: '#F6F2EB',
83
+ rule: '#D6D0C6',
84
+ ink: {
85
+ 900: '#1A1714',
86
+ 800: '#262220',
87
+ 700: '#33302D',
88
+ 600: '#4D4946',
89
+ 500: '#6B6763',
90
+ 400: '#8F8B88',
91
+ 300: '#B5B1AE',
92
+ 200: '#D4D1CE',
93
+ 100: '#EDEAE7',
94
+ 50: '#F6F4F1',
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ </script>
101
+ <style>
102
+ * { box-sizing: border-box; }
103
+ body { background-color: #F6F2EB; color: #1A1714; }
104
+
105
+ /* Running rule animation */
106
+ .section-rule {
107
+ height: 1px;
108
+ background: #1B4332;
109
+ width: 0;
110
+ transition: width 0.45s cubic-bezier(0.4, 0, 0.2, 1);
111
+ margin-bottom: 2rem;
112
+ }
113
+ .section-rule.active { width: 100%; }
114
+
115
+ /* Code reveal animation */
116
+ .code-line {
117
+ opacity: 0;
118
+ transform: translateX(-6px);
119
+ transition: opacity 0.25s ease, transform 0.25s ease;
120
+ }
121
+ .code-line.visible { opacity: 1; transform: translateX(0); }
122
+
123
+ /* Marginalia column */
124
+ .marginalia {
125
+ font-family: 'DM Mono', monospace;
126
+ font-size: 0.65rem;
127
+ line-height: 1.4;
128
+ letter-spacing: 0.05em;
129
+ color: #8F8B88;
130
+ writing-mode: vertical-rl;
131
+ text-orientation: mixed;
132
+ transform: rotate(180deg);
133
+ }
134
+
135
+ /* Inline marginalia (horizontal, smaller screens) */
136
+ .margin-label {
137
+ font-family: 'DM Mono', monospace;
138
+ font-size: 0.6rem;
139
+ letter-spacing: 0.12em;
140
+ text-transform: uppercase;
141
+ color: #8F8B88;
142
+ }
143
+
144
+ /* Drop cap */
145
+ .drop-cap::first-letter {
146
+ font-family: 'Playfair Display', Georgia, serif;
147
+ font-size: 3.5rem;
148
+ line-height: 0.85;
149
+ float: left;
150
+ margin-right: 0.1em;
151
+ margin-top: 0.05em;
152
+ color: #1B4332;
153
+ font-weight: 700;
154
+ }
155
+
156
+ /* Syntax */
157
+ .tok-kw { color: #2D6A4F; font-weight: 500; }
158
+ .tok-str { color: #7C6F3E; }
159
+ .tok-fn { color: #5B4F9E; }
160
+ .tok-cmt { color: #8F8B88; font-style: italic; }
161
+ .tok-var { color: #1A1714; }
162
+ .tok-num { color: #A0522D; }
163
+
164
+ /* Nav */
165
+ .nav-item {
166
+ font-size: 0.8125rem;
167
+ letter-spacing: 0.04em;
168
+ color: #4D4946;
169
+ font-weight: 400;
170
+ transition: color 0.15s ease;
171
+ }
172
+ .nav-item:hover { color: #1B4332; }
173
+
174
+ /* Feature text list */
175
+ .feature-row {
176
+ border-top: 1px solid #D6D0C6;
177
+ transition: border-color 0.15s ease;
178
+ }
179
+ .feature-row:hover { border-top-color: #2D6A4F; }
180
+
181
+ /* Pull quote */
182
+ .pull-quote {
183
+ border-left: 2px solid #1B4332;
184
+ padding-left: 1.25rem;
185
+ }
186
+
187
+ /* Fade up */
188
+ .fade-up {
189
+ opacity: 0;
190
+ transform: translateY(14px);
191
+ transition: opacity 0.4s ease, transform 0.4s ease;
192
+ }
193
+ .fade-up.in { opacity: 1; transform: translateY(0); }
194
+
195
+ /* Stat counter */
196
+ .stat-n { font-variant-numeric: tabular-nums; }
197
+
198
+ /* Green tag */
199
+ .green-tag {
200
+ display: inline-flex;
201
+ align-items: center;
202
+ gap: 0.35rem;
203
+ font-family: 'DM Mono', monospace;
204
+ font-size: 0.65rem;
205
+ letter-spacing: 0.08em;
206
+ color: #2D6A4F;
207
+ background: #d1f0dd;
208
+ border: 1px solid #a3e0bb;
209
+ border-radius: 2px;
210
+ padding: 2px 8px;
211
+ }
212
+
213
+ /* Button */
214
+ .btn-primary {
215
+ display: inline-flex;
216
+ align-items: center;
217
+ gap: 0.5rem;
218
+ background: #1B4332;
219
+ color: #F6F2EB;
220
+ font-family: 'DM Sans', sans-serif;
221
+ font-size: 0.875rem;
222
+ font-weight: 500;
223
+ border-radius: 3px;
224
+ padding: 0.65rem 1.4rem;
225
+ transition: background 0.15s ease;
226
+ letter-spacing: 0.01em;
227
+ }
228
+ .btn-primary:hover { background: #2D6A4F; }
229
+
230
+ .btn-ghost {
231
+ display: inline-flex;
232
+ align-items: center;
233
+ gap: 0.5rem;
234
+ border: 1px solid #D6D0C6;
235
+ color: #4D4946;
236
+ font-family: 'DM Sans', sans-serif;
237
+ font-size: 0.875rem;
238
+ font-weight: 400;
239
+ border-radius: 3px;
240
+ padding: 0.65rem 1.4rem;
241
+ transition: border-color 0.15s ease, color 0.15s ease;
242
+ }
243
+ .btn-ghost:hover { border-color: #1B4332; color: #1B4332; }
244
+
245
+ /* Volume rule */
246
+ .vol-rule { height: 1px; background: #D6D0C6; }
247
+ </style>
248
+ </head>
249
+ <body class="font-sans antialiased">
250
+
251
+ <!-- MASTHEAD / NAV -->
252
+ <header class="border-b border-rule">
253
+ <!-- Top bar: date-like publication metadata -->
254
+ <div class="bg-brand-500 px-6 py-1.5 flex items-center justify-between">
255
+ <div class="font-mono text-[10px] tracking-widest text-brand-200 uppercase">Cadence</div>
256
+ <div class="font-mono text-[10px] tracking-wider text-brand-300">Email API · Established 2022</div>
257
+ <div class="font-mono text-[10px] tracking-wider text-brand-300 hidden sm:block">99.4% inbox rate</div>
258
+ </div>
259
+ <!-- Main nav -->
260
+ <div class="max-w-6xl mx-auto px-6 h-14 flex items-center justify-between">
261
+ <a href="#" class="font-serif text-[1.35rem] font-bold tracking-tight text-ink-900">Cadence</a>
262
+ <nav class="hidden md:flex items-center gap-7">
263
+ <a href="#" class="nav-item">Documentation</a>
264
+ <a href="#" class="nav-item">Pricing</a>
265
+ <a href="#" class="nav-item">Changelog</a>
266
+ <a href="#" class="nav-item">Blog</a>
267
+ <a href="#" class="nav-item">Status</a>
268
+ </nav>
269
+ <div class="flex items-center gap-3">
270
+ <a href="#" class="nav-item hidden sm:inline">Log in</a>
271
+ <a href="#" class="btn-primary text-[13px] py-1.5 px-4">Get API key</a>
272
+ </div>
273
+ </div>
274
+ </header>
275
+
276
+ <!-- HERO — editorial layout with marginalia -->
277
+ <section class="max-w-6xl mx-auto px-6 pt-16 pb-20">
278
+ <div class="grid grid-cols-1 lg:grid-cols-[3rem_1fr_1fr] gap-8 items-start">
279
+
280
+ <!-- Marginalia column (hidden on mobile) -->
281
+ <div class="hidden lg:flex flex-col items-center pt-4">
282
+ <div class="marginalia">EMAIL INFRASTRUCTURE · SINCE 2022</div>
283
+ </div>
284
+
285
+ <!-- Left: Display type -->
286
+ <div class="fade-up">
287
+ <div class="vol-rule mb-6 w-full section-rule" id="hero-rule"></div>
288
+ <div class="margin-label mb-4 block">Vol. I — Sending</div>
289
+ <h1 class="font-serif text-[3.6rem] leading-[1.08] font-bold tracking-[-0.02em] text-ink-900 mb-6">
290
+ Email that<br/>
291
+ <em class="not-italic text-brand-500">delivers</em>,<br/>
292
+ at last.
293
+ </h1>
294
+ <p class="text-[1rem] text-ink-600 leading-[1.75] max-w-[360px] mb-8 drop-cap">
295
+ transactional and marketing email from a single REST API. Engineers write four lines of TypeScript. Content teams manage templates without a pull request.
296
+ </p>
297
+ <div class="flex flex-wrap gap-3 mb-8">
298
+ <a href="#" class="btn-primary">Get your API key</a>
299
+ <a href="#" class="btn-ghost">Read the docs</a>
300
+ </div>
301
+ <div class="flex flex-wrap items-center gap-3">
302
+ <span class="green-tag">
303
+ <svg width="7" height="7" viewBox="0 0 7 7" fill="none"><circle cx="3.5" cy="3.5" r="3.5" fill="#2D6A4F"/></svg>
304
+ LIVE
305
+ </span>
306
+ <span class="font-mono text-[11px] text-ink-400">4,200+ teams · 4.2B emails/mo · 99.99% uptime</span>
307
+ </div>
308
+ </div>
309
+
310
+ <!-- Right: Code -->
311
+ <div class="fade-up" style="transition-delay:0.12s" id="code-block-wrap">
312
+ <div class="bg-ink-900 border border-ink-700 rounded-[2px] overflow-hidden">
313
+ <div class="flex items-center justify-between px-4 py-2.5 border-b border-white/5">
314
+ <span class="font-mono text-[10px] tracking-wider text-ink-400 uppercase">welcome.ts</span>
315
+ <span class="green-tag" style="font-size:0.55rem">SDK v3.2</span>
316
+ </div>
317
+ <div class="p-5 font-mono text-[12.5px] leading-[1.85]" id="code-lines">
318
+ <div class="code-line"><span class="tok-kw">import</span> <span class="tok-var">Cadence</span> <span class="tok-kw">from</span> <span class="tok-str">'@cadence/sdk'</span><span class="text-ink-500">;</span></div>
319
+ <div class="code-line">&nbsp;</div>
320
+ <div class="code-line"><span class="tok-kw">const</span> <span class="tok-var">client</span> <span class="text-ink-500">=</span> <span class="tok-kw">new</span> <span class="tok-fn">Cadence</span><span class="text-ink-500">(</span><span class="tok-str">'ck_live_...'</span><span class="text-ink-500">);</span></div>
321
+ <div class="code-line">&nbsp;</div>
322
+ <div class="code-line"><span class="tok-kw">await</span> <span class="tok-var">client</span><span class="text-ink-500">.</span><span class="tok-var">emails</span><span class="text-ink-500">.</span><span class="tok-fn">send</span><span class="text-ink-500">({'{'}</span></div>
323
+ <div class="code-line pl-5"><span class="tok-var">from</span><span class="text-ink-500">:</span> <span class="tok-str">'hello@acme.com'</span><span class="text-ink-500">,</span></div>
324
+ <div class="code-line pl-5"><span class="tok-var">to</span><span class="text-ink-500">:</span> <span class="tok-str">'user@example.com'</span><span class="text-ink-500">,</span></div>
325
+ <div class="code-line pl-5"><span class="tok-var">template</span><span class="text-ink-500">:</span> <span class="tok-str">'welcome-v2'</span><span class="text-ink-500">,</span></div>
326
+ <div class="code-line pl-5"><span class="tok-var">data</span><span class="text-ink-500">:</span> <span class="text-ink-500">{'{'}</span> <span class="tok-var">name</span><span class="text-ink-500">:</span> <span class="tok-str">'Jordan'</span> <span class="text-ink-500">{'}'}</span></div>
327
+ <div class="code-line"><span class="text-ink-500">});</span></div>
328
+ <div class="code-line">&nbsp;</div>
329
+ <div class="code-line"><span class="tok-cmt">// 200 · delivered · 87ms · inbox</span></div>
330
+ </div>
331
+ </div>
332
+ <!-- Inline editorial note below code -->
333
+ <div class="mt-3 pl-1 border-l border-rule">
334
+ <p class="font-mono text-[10.5px] text-ink-400 leading-relaxed">
335
+ TypeScript · Python · Go · Ruby · PHP · REST<br/>
336
+ Works with any stack. No vendor lock-in.
337
+ </p>
338
+ </div>
339
+ </div>
340
+ </div>
341
+ </section>
342
+
343
+ <!-- VOL RULE + STATS -->
344
+ <section class="border-t border-b border-rule py-10">
345
+ <div class="max-w-6xl mx-auto px-6">
346
+ <div class="grid grid-cols-2 md:grid-cols-4 gap-0 divide-x divide-rule">
347
+ <div class="px-6 first:pl-0 fade-up">
348
+ <div class="stat-n font-serif text-[2.5rem] font-bold text-ink-900 leading-none mb-1">99.4<span class="text-brand-500 text-[1.4rem]">%</span></div>
349
+ <div class="margin-label">Avg. inbox rate</div>
350
+ </div>
351
+ <div class="px-6 fade-up" style="transition-delay:0.06s">
352
+ <div class="stat-n font-serif text-[2.5rem] font-bold text-ink-900 leading-none mb-1">4.2<span class="text-brand-500 text-[1.4rem]">B</span></div>
353
+ <div class="margin-label">Emails per month</div>
354
+ </div>
355
+ <div class="px-6 fade-up" style="transition-delay:0.12s">
356
+ <div class="stat-n font-serif text-[2.5rem] font-bold text-ink-900 leading-none mb-1">&lt;80<span class="text-brand-500 text-[1.4rem]">ms</span></div>
357
+ <div class="margin-label">Median send latency</div>
358
+ </div>
359
+ <div class="px-6 fade-up" style="transition-delay:0.18s">
360
+ <div class="stat-n font-serif text-[2.5rem] font-bold text-ink-900 leading-none mb-1">99.99<span class="text-brand-500 text-[1.4rem]">%</span></div>
361
+ <div class="margin-label">API uptime SLA</div>
362
+ </div>
363
+ </div>
364
+ </div>
365
+ </section>
366
+
367
+ <!-- FEATURES — editorial text list, marginalia-annotated -->
368
+ <section class="py-20 px-6">
369
+ <div class="max-w-6xl mx-auto">
370
+ <div class="grid grid-cols-1 lg:grid-cols-[3rem_1fr] gap-8">
371
+ <!-- Marginalia -->
372
+ <div class="hidden lg:flex flex-col items-center pt-8">
373
+ <div class="marginalia">CAPABILITIES · v3</div>
374
+ </div>
375
+
376
+ <div>
377
+ <div class="section-rule fade-up" id="feat-rule"></div>
378
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-0 mb-0 fade-up">
379
+ <div class="md:pr-16">
380
+ <h2 class="font-serif text-[2rem] font-bold tracking-[-0.02em] text-ink-900 mb-3 leading-snug">
381
+ Everything email.<br/>Nothing else.
382
+ </h2>
383
+ <p class="text-[14px] text-ink-500 leading-relaxed">
384
+ Cadence does one thing and does it completely. Transactional sends,
385
+ marketing broadcasts, template management, deliverability monitoring —
386
+ all in one API surface, not a patchwork of tools.
387
+ </p>
388
+ </div>
389
+ <div class="mt-8 md:mt-0 pl-0 md:pl-8 md:border-l border-rule">
390
+ <div class="pull-quote">
391
+ <p class="font-serif italic text-[1.05rem] text-ink-700 leading-relaxed">
392
+ "The SDK is the best-designed piece of developer tooling
393
+ we've integrated this year. Type errors at the call site,
394
+ not in production."
395
+ </p>
396
+ <div class="mt-3 flex items-center gap-2">
397
+ <div class="w-6 h-6 rounded-full bg-brand-100 flex items-center justify-center text-[9px] font-semibold text-brand-700">MP</div>
398
+ <span class="font-mono text-[10px] text-ink-400">Marcus P. · Head of Eng, Vercel customer</span>
399
+ </div>
400
+ </div>
401
+ </div>
402
+ </div>
403
+
404
+ <!-- Feature rows (editorial list style) -->
405
+ <div class="mt-14 space-y-0">
406
+
407
+ <div class="feature-row py-6 grid grid-cols-1 md:grid-cols-[160px_1fr_1fr] gap-4 fade-up">
408
+ <div>
409
+ <div class="margin-label mb-1">API Layer</div>
410
+ </div>
411
+ <div>
412
+ <h3 class="font-serif text-[1.1rem] font-semibold text-ink-900 mb-2 leading-snug">REST API + typed SDKs</h3>
413
+ <p class="text-[13px] text-ink-500 leading-relaxed">One endpoint, five official SDKs. Idempotency keys built in. OpenAPI spec always current.</p>
414
+ </div>
415
+ <div class="font-mono text-[11px] text-ink-400 leading-relaxed pt-1">
416
+ POST /v1/emails<br/>
417
+ GET /v1/emails/:id<br/>
418
+ GET /v1/analytics/templates
419
+ </div>
420
+ </div>
421
+
422
+ <div class="feature-row py-6 grid grid-cols-1 md:grid-cols-[160px_1fr_1fr] gap-4 fade-up">
423
+ <div>
424
+ <div class="margin-label mb-1">Templates</div>
425
+ </div>
426
+ <div>
427
+ <h3 class="font-serif text-[1.1rem] font-semibold text-ink-900 mb-2 leading-snug">React Email components</h3>
428
+ <p class="text-[13px] text-ink-500 leading-relaxed">Version-controlled templates as React components. Non-engineers edit copy in the dashboard without touching git.</p>
429
+ </div>
430
+ <div class="bg-ink-50 border border-ink-100 rounded-[2px] p-3 font-mono text-[10.5px] text-ink-500 leading-relaxed">
431
+ <span class="text-brand-500">&lt;Email&gt;</span><br/>
432
+ &nbsp;&nbsp;<span class="text-ink-700">&lt;Heading&gt;</span>Welcome, {'{{name}}'}<span class="text-ink-700">&lt;/Heading&gt;</span><br/>
433
+ &nbsp;&nbsp;<span class="text-ink-700">&lt;Button</span> <span class="text-brand-500">href</span>=<span class="tok-str">{'{{ctaUrl}}'}</span><span class="text-ink-700">&gt;</span>Get started<span class="text-ink-700">&lt;/Button&gt;</span><br/>
434
+ <span class="text-brand-500">&lt;/Email&gt;</span>
435
+ </div>
436
+ </div>
437
+
438
+ <div class="feature-row py-6 grid grid-cols-1 md:grid-cols-[160px_1fr_1fr] gap-4 fade-up">
439
+ <div>
440
+ <div class="margin-label mb-1">Deliverability</div>
441
+ </div>
442
+ <div>
443
+ <h3 class="font-serif text-[1.1rem] font-semibold text-ink-900 mb-2 leading-snug">Inbox placement, not just delivery</h3>
444
+ <p class="text-[13px] text-ink-500 leading-relaxed">SPF, DKIM, DMARC configured automatically. Reputation monitoring across Gmail, Outlook, Yahoo — alerting before a problem becomes a block.</p>
445
+ </div>
446
+ <div class="space-y-2 pt-1">
447
+ <div class="flex items-center gap-2">
448
+ <div class="flex-1 bg-ink-100 rounded-full h-1">
449
+ <div class="bg-brand-400 h-1 rounded-full" style="width:97%"></div>
450
+ </div>
451
+ <span class="font-mono text-[10px] text-ink-400 w-20">Gmail 97%</span>
452
+ </div>
453
+ <div class="flex items-center gap-2">
454
+ <div class="flex-1 bg-ink-100 rounded-full h-1">
455
+ <div class="bg-brand-400 h-1 rounded-full" style="width:94%"></div>
456
+ </div>
457
+ <span class="font-mono text-[10px] text-ink-400 w-20">Outlook 94%</span>
458
+ </div>
459
+ <div class="flex items-center gap-2">
460
+ <div class="flex-1 bg-ink-100 rounded-full h-1">
461
+ <div class="bg-brand-400 h-1 rounded-full" style="width:98%"></div>
462
+ </div>
463
+ <span class="font-mono text-[10px] text-ink-400 w-20">Yahoo 98%</span>
464
+ </div>
465
+ </div>
466
+ </div>
467
+
468
+ <div class="feature-row py-6 grid grid-cols-1 md:grid-cols-[160px_1fr_1fr] gap-4 fade-up">
469
+ <div>
470
+ <div class="margin-label mb-1">Analytics</div>
471
+ </div>
472
+ <div>
473
+ <h3 class="font-serif text-[1.1rem] font-semibold text-ink-900 mb-2 leading-snug">Per-template performance</h3>
474
+ <p class="text-[13px] text-ink-500 leading-relaxed">Open rates, click-through, unsubscribes, and bounce classification — per template, per variant, per send. Export to your warehouse via webhook or CSV.</p>
475
+ </div>
476
+ <div class="bg-ink-50 border border-ink-100 rounded-[2px] divide-y divide-ink-100 font-mono text-[10.5px] text-ink-500">
477
+ <div class="px-3 py-2 flex justify-between"><span>welcome-v2</span><span class="text-ink-700">61% open</span></div>
478
+ <div class="px-3 py-2 flex justify-between"><span>pw-reset</span><span class="text-ink-700">88% open</span></div>
479
+ <div class="px-3 py-2 flex justify-between"><span>digest-aug</span><span class="text-ink-700">44% open</span></div>
480
+ </div>
481
+ </div>
482
+
483
+ <div class="feature-row py-6 grid grid-cols-1 md:grid-cols-[160px_1fr_1fr] gap-4 fade-up">
484
+ <div>
485
+ <div class="margin-label mb-1">Testing</div>
486
+ </div>
487
+ <div>
488
+ <h3 class="font-serif text-[1.1rem] font-semibold text-ink-900 mb-2 leading-snug">Test mode catches errors before users do</h3>
489
+ <p class="text-[13px] text-ink-500 leading-relaxed">Swap your live key for a test key. Emails render and validate — missing variables surface as type errors — but nothing sends.</p>
490
+ </div>
491
+ <div class="font-mono text-[11px] text-ink-400 pt-1 leading-relaxed">
492
+ <span class="text-amber-600">WARN</span> missing variable: firstName<br/>
493
+ <span class="text-amber-600">WARN</span> template: welcome-v2<br/>
494
+ <span class="text-green-600">PASS</span> html renders 14.2kb<br/>
495
+ <span class="text-green-600">PASS</span> text fallback present
496
+ </div>
497
+ </div>
498
+
499
+ </div>
500
+ </div>
501
+ </div>
502
+ </div>
503
+ </section>
504
+
505
+ <!-- TESTIMONIAL — large editorial quote -->
506
+ <section class="border-t border-rule py-20 px-6 bg-brand-500">
507
+ <div class="max-w-4xl mx-auto fade-up">
508
+ <div class="margin-label mb-6" style="color:#a3e0bb">From the field</div>
509
+ <blockquote class="font-serif text-[2rem] font-normal italic leading-[1.4] text-white mb-8 tracking-[-0.01em]">
510
+ "We moved off a major ESP in two days. Cadence's API is half the surface area with twice the reliability. Our growth team now deploys email copy without opening a ticket."
511
+ </blockquote>
512
+ <div class="flex items-center gap-4 not-italic">
513
+ <div class="w-10 h-10 rounded-full bg-brand-300 flex items-center justify-center font-mono text-[12px] font-bold text-brand-900">TW</div>
514
+ <div>
515
+ <div class="font-sans font-medium text-[14px] text-white">Tara Wu</div>
516
+ <div class="font-mono text-[11px] text-brand-300">VP Engineering · Framer</div>
517
+ </div>
518
+ </div>
519
+ </div>
520
+ </section>
521
+
522
+ <!-- CTA -->
523
+ <section class="py-24 px-6 bg-parchment border-t border-rule">
524
+ <div class="max-w-6xl mx-auto grid grid-cols-1 lg:grid-cols-[3rem_1fr] gap-8">
525
+ <div class="hidden lg:flex flex-col items-center pt-2">
526
+ <div class="marginalia">GET STARTED</div>
527
+ </div>
528
+ <div>
529
+ <div class="section-rule fade-up" id="cta-rule" style="max-width:240px"></div>
530
+ <div class="fade-up">
531
+ <div class="margin-label mb-4">No credit card required</div>
532
+ <h2 class="font-serif text-[3rem] font-bold tracking-[-0.03em] text-ink-900 mb-4 leading-tight">
533
+ Your first 10,000<br/>emails are free.
534
+ </h2>
535
+ <p class="text-[15px] text-ink-500 mb-8 max-w-md leading-relaxed">
536
+ Generate an API key, install the SDK, and send your first email in under ten minutes.
537
+ Honest pricing after that — no seat limits, no egress fees.
538
+ </p>
539
+ <div class="flex flex-wrap gap-3 mb-8">
540
+ <a href="#" class="btn-primary">Get your API key →</a>
541
+ <a href="#" class="btn-ghost">View documentation</a>
542
+ </div>
543
+ <div class="font-mono text-[12px] text-ink-400">
544
+ npm install @cadence/sdk &nbsp;·&nbsp; pip install cadence &nbsp;·&nbsp; go get cadence.dev/sdk
545
+ </div>
546
+ </div>
547
+ </div>
548
+ </div>
549
+ </section>
550
+
551
+ <!-- FOOTER -->
552
+ <footer class="border-t border-rule px-6 py-8">
553
+ <div class="max-w-6xl mx-auto flex flex-col sm:flex-row items-center justify-between gap-4">
554
+ <a href="#" class="font-serif font-bold text-[1.1rem] text-ink-900">Cadence</a>
555
+ <div class="flex flex-wrap items-center gap-5 font-mono text-[11px] text-ink-400">
556
+ <a href="#" class="hover:text-ink-700 transition-colors">Docs</a>
557
+ <a href="#" class="hover:text-ink-700 transition-colors">Status</a>
558
+ <a href="#" class="hover:text-ink-700 transition-colors">Changelog</a>
559
+ <a href="#" class="hover:text-ink-700 transition-colors">Privacy</a>
560
+ <a href="#" class="hover:text-ink-700 transition-colors">Terms</a>
561
+ <span class="text-ink-200">© 2024 Cadence</span>
562
+ </div>
563
+ </div>
564
+ </footer>
565
+
566
+ <script>
567
+ // Fade-up observer
568
+ const fadeObs = new IntersectionObserver((entries) => {
569
+ entries.forEach(e => {
570
+ if (e.isIntersecting) {
571
+ e.target.classList.add('in');
572
+ fadeObs.unobserve(e.target);
573
+ }
574
+ });
575
+ }, { threshold: 0.08, rootMargin: '0px 0px -30px 0px' });
576
+
577
+ document.querySelectorAll('.fade-up').forEach(el => fadeObs.observe(el));
578
+
579
+ // Trigger above-fold immediately
580
+ document.querySelectorAll('.fade-up').forEach(el => {
581
+ if (el.getBoundingClientRect().top < window.innerHeight) el.classList.add('in');
582
+ });
583
+
584
+ // Section rules
585
+ const ruleObs = new IntersectionObserver((entries) => {
586
+ entries.forEach(e => {
587
+ if (e.isIntersecting) {
588
+ e.target.classList.add('active');
589
+ ruleObs.unobserve(e.target);
590
+ }
591
+ });
592
+ }, { threshold: 0.5 });
593
+ document.querySelectorAll('.section-rule').forEach(el => ruleObs.observe(el));
594
+
595
+ // Code line reveal
596
+ const codeLines = document.querySelectorAll('#code-lines .code-line');
597
+ const codeObs = new IntersectionObserver((entries) => {
598
+ entries.forEach(e => {
599
+ if (e.isIntersecting) {
600
+ codeLines.forEach((line, i) => {
601
+ setTimeout(() => line.classList.add('visible'), i * 55);
602
+ });
603
+ codeObs.unobserve(e.target);
604
+ }
605
+ });
606
+ }, { threshold: 0.3 });
607
+ const codeWrap = document.getElementById('code-lines');
608
+ if (codeWrap) codeObs.observe(codeWrap);
609
+
610
+ // Trigger code if in view
611
+ if (codeWrap && codeWrap.getBoundingClientRect().top < window.innerHeight) {
612
+ codeLines.forEach((line, i) => {
613
+ setTimeout(() => line.classList.add('visible'), i * 55);
614
+ });
615
+ }
616
+ </script>
617
+ </body>
618
+ </html>