@yiaany/ghostapi 0.1.9 → 0.2.0

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 (292) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/CONTRIBUTING.md +132 -119
  3. package/LICENSE +21 -21
  4. package/PROVENANCE.md +13 -0
  5. package/README.md +78 -84
  6. package/SECURITY.md +56 -53
  7. package/dist/actions/gateway.js +320 -72
  8. package/dist/actions/gateway.js.map +1 -1
  9. package/dist/actions/index.d.ts +2 -2
  10. package/dist/actions/index.js +1 -1
  11. package/dist/actions/index.js.map +1 -1
  12. package/dist/agents/agentPrompt.js +7 -5
  13. package/dist/agents/agentPrompt.js.map +1 -1
  14. package/dist/ai/aiClient.js +5 -5
  15. package/dist/ai/aiClient.js.map +1 -1
  16. package/dist/ai/aiGenerator.js +66 -26
  17. package/dist/ai/aiGenerator.js.map +1 -1
  18. package/dist/ai/genericInference.js +151 -36
  19. package/dist/ai/genericInference.js.map +1 -1
  20. package/dist/ai/prompts.js +55 -49
  21. package/dist/ai/prompts.js.map +1 -1
  22. package/dist/approvals/approvalInbox.js +649 -133
  23. package/dist/approvals/approvalInbox.js.map +1 -1
  24. package/dist/approvals/index.d.ts +2 -2
  25. package/dist/approvals/index.js +1 -1
  26. package/dist/approvals/index.js.map +1 -1
  27. package/dist/behavior/behaviorStore.js +34 -14
  28. package/dist/behavior/behaviorStore.js.map +1 -1
  29. package/dist/cache/index.js +14 -5
  30. package/dist/cache/index.js.map +1 -1
  31. package/dist/cli/index.js +226 -93
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/cli/openUrl.js +17 -3
  34. package/dist/cli/openUrl.js.map +1 -1
  35. package/dist/cli/parser.js +79 -18
  36. package/dist/cli/parser.js.map +1 -1
  37. package/dist/config/dataPaths.js +4 -2
  38. package/dist/config/dataPaths.js.map +1 -1
  39. package/dist/config/localConfig.js +5 -2
  40. package/dist/config/localConfig.js.map +1 -1
  41. package/dist/config/serverConfig.js +11 -5
  42. package/dist/config/serverConfig.js.map +1 -1
  43. package/dist/contracts/contract.js +311 -83
  44. package/dist/contracts/contract.js.map +1 -1
  45. package/dist/contracts/index.d.ts +2 -2
  46. package/dist/contracts/index.js +1 -1
  47. package/dist/contracts/index.js.map +1 -1
  48. package/dist/credentials/credentialBroker.js +391 -79
  49. package/dist/credentials/credentialBroker.js.map +1 -1
  50. package/dist/credentials/index.d.ts +2 -2
  51. package/dist/credentials/index.js +1 -1
  52. package/dist/credentials/index.js.map +1 -1
  53. package/dist/dashboard/app.js +823 -685
  54. package/dist/dashboard/dashboard.js.map +1 -1
  55. package/dist/dashboard/index.html +704 -267
  56. package/dist/dashboard/styles.css +1040 -349
  57. package/dist/egress/capabilities.js +55 -25
  58. package/dist/egress/capabilities.js.map +1 -1
  59. package/dist/egress/linuxBootstrap.js +47 -11
  60. package/dist/egress/linuxBootstrap.js.map +1 -1
  61. package/dist/egress/run.js +170 -31
  62. package/dist/egress/run.js.map +1 -1
  63. package/dist/errors/errorEngine.js +15 -3
  64. package/dist/errors/errorEngine.js.map +1 -1
  65. package/dist/errors/providerErrors.js.map +1 -1
  66. package/dist/evals/evals.js +304 -78
  67. package/dist/evals/evals.js.map +1 -1
  68. package/dist/evals/index.d.ts +2 -2
  69. package/dist/evals/index.js +1 -1
  70. package/dist/evals/index.js.map +1 -1
  71. package/dist/evidence/index.d.ts +2 -2
  72. package/dist/evidence/index.js +1 -1
  73. package/dist/evidence/index.js.map +1 -1
  74. package/dist/evidence/report.d.ts +1 -1
  75. package/dist/evidence/report.js +263 -79
  76. package/dist/evidence/report.js.map +1 -1
  77. package/dist/fault/faultLab.js +24 -9
  78. package/dist/fault/faultLab.js.map +1 -1
  79. package/dist/index.d.ts +42 -42
  80. package/dist/index.js +21 -21
  81. package/dist/index.js.map +1 -1
  82. package/dist/inventory/analysis.d.ts +1 -1
  83. package/dist/inventory/analysis.js +174 -50
  84. package/dist/inventory/analysis.js.map +1 -1
  85. package/dist/inventory/index.d.ts +4 -4
  86. package/dist/inventory/index.js +3 -3
  87. package/dist/inventory/index.js.map +1 -1
  88. package/dist/inventory/inventoryController.js +362 -115
  89. package/dist/inventory/inventoryController.js.map +1 -1
  90. package/dist/inventory/types.js +680 -140
  91. package/dist/inventory/types.js.map +1 -1
  92. package/dist/ledger/actionLedger.js +355 -78
  93. package/dist/ledger/actionLedger.js.map +1 -1
  94. package/dist/ledger/index.d.ts +2 -2
  95. package/dist/ledger/index.js +1 -1
  96. package/dist/ledger/index.js.map +1 -1
  97. package/dist/mcp/server.js +26 -11
  98. package/dist/mcp/server.js.map +1 -1
  99. package/dist/policy/index.d.ts +2 -2
  100. package/dist/policy/index.js +1 -1
  101. package/dist/policy/index.js.map +1 -1
  102. package/dist/policy/policy.js +112 -32
  103. package/dist/policy/policy.js.map +1 -1
  104. package/dist/productTelemetry/index.js +71 -20
  105. package/dist/productTelemetry/index.js.map +1 -1
  106. package/dist/providers/conformance.js +10 -5
  107. package/dist/providers/conformance.js.map +1 -1
  108. package/dist/providers/discord.js +2 -2
  109. package/dist/providers/generic.js +3 -3
  110. package/dist/providers/github.js +2 -2
  111. package/dist/providers/index.d.ts +3 -3
  112. package/dist/providers/index.js +2 -2
  113. package/dist/providers/index.js.map +1 -1
  114. package/dist/providers/openai.js +3 -3
  115. package/dist/providers/packs/resendPack.js +51 -25
  116. package/dist/providers/packs/resendPack.js.map +1 -1
  117. package/dist/providers/packs/stripePack.js +590 -121
  118. package/dist/providers/packs/stripePack.js.map +1 -1
  119. package/dist/providers/registry.js +4 -4
  120. package/dist/providers/registry.js.map +1 -1
  121. package/dist/providers/runtime.js +7 -6
  122. package/dist/providers/runtime.js.map +1 -1
  123. package/dist/providers/stripeWebhook.js +39 -10
  124. package/dist/providers/stripeWebhook.js.map +1 -1
  125. package/dist/providers/twilio.js +2 -2
  126. package/dist/proxy/cacheKey.js +9 -2
  127. package/dist/proxy/cacheKey.js.map +1 -1
  128. package/dist/proxy/providerDetector.js +22 -9
  129. package/dist/proxy/providerDetector.js.map +1 -1
  130. package/dist/proxy/proxyHandler.js +57 -22
  131. package/dist/proxy/proxyHandler.js.map +1 -1
  132. package/dist/proxy/requestNormalizer.js +4 -2
  133. package/dist/proxy/requestNormalizer.js.map +1 -1
  134. package/dist/reliability/costGovernance.js +211 -49
  135. package/dist/reliability/costGovernance.js.map +1 -1
  136. package/dist/reliability/index.d.ts +8 -8
  137. package/dist/reliability/index.js +4 -4
  138. package/dist/reliability/index.js.map +1 -1
  139. package/dist/reliability/reconciliation.js +274 -65
  140. package/dist/reliability/reconciliation.js.map +1 -1
  141. package/dist/reliability/runtimeHealth.js +127 -35
  142. package/dist/reliability/runtimeHealth.js.map +1 -1
  143. package/dist/reliability/slo.js +257 -50
  144. package/dist/reliability/slo.js.map +1 -1
  145. package/dist/report/safetyReport.d.ts +6 -0
  146. package/dist/report/safetyReport.js +56 -12
  147. package/dist/report/safetyReport.js.map +1 -1
  148. package/dist/rules/aiRules.js +5 -5
  149. package/dist/rules/aiRules.js.map +1 -1
  150. package/dist/safety/index.d.ts +2 -2
  151. package/dist/safety/index.js +1 -1
  152. package/dist/safety/index.js.map +1 -1
  153. package/dist/safety/safetyController.js +675 -165
  154. package/dist/safety/safetyController.js.map +1 -1
  155. package/dist/scenarios/scenarioBundle.js +204 -71
  156. package/dist/scenarios/scenarioBundle.js.map +1 -1
  157. package/dist/scenarios/scenarioStore.js +88 -29
  158. package/dist/scenarios/scenarioStore.js.map +1 -1
  159. package/dist/security/headerSanitizer.js +52 -10
  160. package/dist/security/headerSanitizer.js.map +1 -1
  161. package/dist/security/secrets.js +10 -5
  162. package/dist/security/secrets.js.map +1 -1
  163. package/dist/server/accessControl.js +37 -10
  164. package/dist/server/accessControl.js.map +1 -1
  165. package/dist/server/createServer.js +1 -1
  166. package/dist/server/createServer.js.map +1 -1
  167. package/dist/server/eventsStore.js +15 -5
  168. package/dist/server/eventsStore.js.map +1 -1
  169. package/dist/server/routes.js +61 -19
  170. package/dist/server/routes.js.map +1 -1
  171. package/dist/server/sse.js +1 -1
  172. package/dist/server/sse.js.map +1 -1
  173. package/dist/setup/sdkDetector.js +7 -2
  174. package/dist/setup/sdkDetector.js.map +1 -1
  175. package/dist/setup/setupGenerator.js +136 -48
  176. package/dist/setup/setupGenerator.js.map +1 -1
  177. package/dist/state/stateExtractor.js +3 -1
  178. package/dist/state/stateExtractor.js.map +1 -1
  179. package/dist/state/stateResolver.js +10 -7
  180. package/dist/state/stateResolver.js.map +1 -1
  181. package/dist/state/stateStore.js +13 -4
  182. package/dist/state/stateStore.js.map +1 -1
  183. package/dist/storage/fileStore.js +12 -4
  184. package/dist/storage/fileStore.js.map +1 -1
  185. package/dist/teamControl/controlPlane.js +846 -174
  186. package/dist/teamControl/controlPlane.js.map +1 -1
  187. package/dist/teamControl/deployment.js +19 -5
  188. package/dist/teamControl/deployment.js.map +1 -1
  189. package/dist/teamControl/index.d.ts +4 -4
  190. package/dist/teamControl/index.js +2 -2
  191. package/dist/teamControl/index.js.map +1 -1
  192. package/dist/tests/testGenerator.js +15 -7
  193. package/dist/tests/testGenerator.js.map +1 -1
  194. package/dist/trust/index.d.ts +2 -2
  195. package/dist/trust/index.js +1 -1
  196. package/dist/trust/index.js.map +1 -1
  197. package/dist/trust/trustLadder.js +309 -63
  198. package/dist/trust/trustLadder.js.map +1 -1
  199. package/dist/worlds/index.d.ts +2 -2
  200. package/dist/worlds/index.js +1 -1
  201. package/dist/worlds/index.js.map +1 -1
  202. package/dist/worlds/worlds.js +364 -65
  203. package/dist/worlds/worlds.js.map +1 -1
  204. package/docs/assets/dashboard.png +0 -0
  205. package/docs/ci.md +49 -49
  206. package/docs/github-actions.md +84 -84
  207. package/docs/mcp.md +58 -52
  208. package/docs/policy.md +63 -61
  209. package/docs/providers/authoring-packs.md +180 -175
  210. package/docs/providers/stripe-core-pack.md +84 -82
  211. package/docs/releases/README.md +13 -0
  212. package/docs/security/action-gateway-threat-model.md +34 -34
  213. package/docs/security/action-ledger-incident-replay-threat-model.md +42 -42
  214. package/docs/security/approval-inbox-threat-model.md +35 -35
  215. package/docs/security/credential-broker-threat-model.md +52 -52
  216. package/docs/security/egress-threat-model.md +126 -126
  217. package/docs/security/inventory-threat-model.md +104 -104
  218. package/docs/security/kill-switch-budgets-threat-model.md +37 -37
  219. package/docs/security/reliability-threat-model.md +111 -111
  220. package/docs/security/trust-ladder-threat-model.md +33 -33
  221. package/docs/telemetry.md +14 -0
  222. package/docs/usage.md +680 -571
  223. package/examples/README.md +10 -10
  224. package/examples/agent-instructions/README.md +39 -39
  225. package/examples/ci-smoke/README.md +21 -21
  226. package/examples/ci-smoke/ghostapi.policy.yaml +22 -22
  227. package/examples/ci-smoke/package.json +9 -9
  228. package/examples/ci-smoke/production-egress.mjs +4 -2
  229. package/examples/ci-smoke/safe.mjs +21 -17
  230. package/examples/evals/README.md +24 -24
  231. package/examples/evals/retry-after.eval.json +71 -52
  232. package/examples/generic-rest/README.md +27 -27
  233. package/examples/github-fetch/README.md +38 -35
  234. package/examples/openai-streaming/README.md +16 -16
  235. package/examples/openai-streaming/streaming-tool-call.mjs +44 -31
  236. package/examples/policy/ghostapi.policy.yaml +27 -27
  237. package/examples/record-replay/README.md +19 -19
  238. package/examples/record-replay/replay-requests.json +22 -22
  239. package/examples/record-replay/stripe-checkout.har.json +30 -30
  240. package/examples/resend-node/README.md +22 -22
  241. package/examples/stripe-node/README.md +35 -35
  242. package/examples/stripe-node/checkout-flow.mjs +87 -61
  243. package/examples/twilio-node/README.md +21 -21
  244. package/examples/worlds/README.md +19 -19
  245. package/examples/worlds/subscription-recovery.mjs +21 -12
  246. package/package.json +28 -6
  247. package/dist/landing/assets/index-BXR41fAD.css +0 -1
  248. package/dist/landing/assets/index-CxWsopzP.css +0 -1
  249. package/dist/landing/assets/index-D8_ggMRE.js +0 -55
  250. package/dist/landing/assets/index-DZlpyhqd.js +0 -55
  251. package/dist/landing/assets/index-Dk-Xezs3.js +0 -55
  252. package/dist/landing/index.html +0 -15
  253. package/dist/landing/landing.d.ts +0 -3
  254. package/dist/landing/landing.js +0 -12
  255. package/dist/landing/landing.js.map +0 -1
  256. package/docs/commercial/README.md +0 -29
  257. package/docs/commercial/data-inventory.md +0 -36
  258. package/docs/commercial/manual-invoicing.md +0 -44
  259. package/docs/commercial/metrics.md +0 -51
  260. package/docs/commercial/pricing.md +0 -103
  261. package/docs/commercial/privacy-policy-draft.md +0 -41
  262. package/docs/commercial/terms-topics-for-counsel.md +0 -51
  263. package/docs/design-partners/README.md +0 -52
  264. package/docs/design-partners/demo-narratives.md +0 -33
  265. package/docs/design-partners/design-partner-offer.md +0 -39
  266. package/docs/design-partners/discovery-questions.md +0 -28
  267. package/docs/design-partners/feedback-capture-template.md +0 -48
  268. package/docs/design-partners/icp-one-pager.md +0 -43
  269. package/docs/design-partners/onboarding-checklist.md +0 -33
  270. package/docs/design-partners/pilot-success-criteria.md +0 -27
  271. package/docs/design-partners/pricing-interview-script.md +0 -18
  272. package/docs/design-partners/telemetry-plan.md +0 -48
  273. package/docs/development/baseline.md +0 -114
  274. package/docs/development/onboarding-smoke.md +0 -37
  275. package/docs/development/verification-0.1.8.md +0 -25
  276. package/docs/enterprise-product-roadmap-ru.md +0 -1879
  277. package/docs/fundraising/README.md +0 -87
  278. package/docs/fundraising/data-room-checklist.md +0 -72
  279. package/docs/fundraising/demo-script.md +0 -52
  280. package/docs/fundraising/design-partners-50.md +0 -74
  281. package/docs/fundraising/launch-posts.md +0 -37
  282. package/docs/fundraising/metrics-and-evidence.md +0 -30
  283. package/docs/fundraising/roadmap-12-month.md +0 -25
  284. package/docs/fundraising/technical-due-diligence-index.md +0 -37
  285. package/docs/fundraising/yc-application.md +0 -25
  286. package/docs/hosted-pilot.md +0 -111
  287. package/docs/operations/disaster-recovery-runbook.md +0 -81
  288. package/docs/operations/kill-switch-runbook.md +0 -32
  289. package/docs/release-checklist.md +0 -83
  290. package/docs/release-migration-and-rollback.md +0 -63
  291. package/docs/release-readiness.md +0 -39
  292. package/docs/team-control-plane.md +0 -72
@@ -1,12 +1,21 @@
1
- import { runSubscriptionFailureWorkflow } from "../../dist/index.js";
2
-
3
- const worldId = process.env.GHOSTAPI_WORLD_ID ?? "subscription-recovery";
4
- const receipt = await runSubscriptionFailureWorkflow(worldId, "subscription-payment-failed");
5
-
6
- console.log(JSON.stringify({
7
- customerId: receipt.customerId,
8
- subscriptionId: receipt.subscriptionId,
9
- emailId: receipt.emailId,
10
- githubIssue: receipt.issueNumber,
11
- genericRestFailureId: receipt.genericFailureId
12
- }, null, 2));
1
+ import { runSubscriptionFailureWorkflow } from "../../dist/index.js";
2
+
3
+ const worldId = process.env.GHOSTAPI_WORLD_ID ?? "subscription-recovery";
4
+ const receipt = await runSubscriptionFailureWorkflow(
5
+ worldId,
6
+ "subscription-payment-failed",
7
+ );
8
+
9
+ console.log(
10
+ JSON.stringify(
11
+ {
12
+ customerId: receipt.customerId,
13
+ subscriptionId: receipt.subscriptionId,
14
+ emailId: receipt.emailId,
15
+ githubIssue: receipt.issueNumber,
16
+ genericRestFailureId: receipt.genericFailureId,
17
+ },
18
+ null,
19
+ 2,
20
+ ),
21
+ );
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yiaany/ghostapi",
3
- "version": "0.1.9",
4
- "description": "The local internet for AI coding agents.",
3
+ "version": "0.2.0",
4
+ "description": "Local API simulation and test evidence for AI-assisted development.",
5
5
  "type": "module",
6
6
  "repository": {
7
7
  "type": "git",
@@ -27,23 +27,39 @@
27
27
  "files": [
28
28
  "dist",
29
29
  "examples",
30
- "docs",
30
+ "docs/usage.md",
31
+ "docs/mcp.md",
32
+ "docs/policy.md",
33
+ "docs/telemetry.md",
34
+ "docs/ci.md",
35
+ "docs/github-actions.md",
36
+ "docs/providers",
37
+ "docs/security",
38
+ "docs/releases",
39
+ "docs/assets",
31
40
  "README.md",
32
41
  "CHANGELOG.md",
33
42
  "SECURITY.md",
34
43
  "CONTRIBUTING.md",
44
+ "PROVENANCE.md",
35
45
  "LICENSE"
36
46
  ],
37
47
  "scripts": {
38
48
  "dev": "tsx src/cli/index.ts start",
49
+ "clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
39
50
  "build": "tsc -p tsconfig.json && npm run build:static",
40
51
  "build:static": "node -e \"const {cpSync, mkdirSync} = require('fs'); mkdirSync('dist/dashboard', {recursive:true}); cpSync('src/dashboard/index.html', 'dist/dashboard/index.html'); cpSync('src/dashboard/styles.css', 'dist/dashboard/styles.css'); cpSync('src/dashboard/app.js', 'dist/dashboard/app.js');\"",
41
52
  "start": "node dist/cli/index.js start",
42
53
  "typecheck": "tsc -p tsconfig.json --noEmit",
43
54
  "test": "vitest run",
55
+ "test:sdk-compat": "npm run build && npm ci --prefix compat/sdk && npm test --prefix compat/sdk",
56
+ "test:coverage": "vitest run --coverage",
44
57
  "smoke:package": "node scripts/package-smoke.mjs",
45
- "lint": "npm run format:check",
46
- "format:check": "prettier --check package.json tsconfig.json vitest.config.ts scripts/package-smoke.mjs test/dashboardAssets.test.ts"
58
+ "prepack": "npm run clean && npm run build",
59
+ "lint": "npm run format:check && npm run lint:code",
60
+ "lint:code": "eslint .",
61
+ "format": "prettier --write .",
62
+ "format:check": "prettier --check ."
47
63
  },
48
64
  "keywords": [
49
65
  "mcp",
@@ -58,7 +74,9 @@
58
74
  "api-testing",
59
75
  "mock-api",
60
76
  "developer-tools",
61
- "typescript"
77
+ "typescript",
78
+ "api-simulation",
79
+ "egress-testing"
62
80
  ],
63
81
  "license": "MIT",
64
82
  "dependencies": {
@@ -77,9 +95,13 @@
77
95
  "devDependencies": {
78
96
  "@types/express": "^4.17.21",
79
97
  "@types/node": "^20.14.10",
98
+ "@vitest/coverage-v8": "^4.1.11",
99
+ "eslint": "^10.9.1",
100
+ "globals": "^17.11.0",
80
101
  "prettier": "^3.9.6",
81
102
  "tsx": "^4.16.2",
82
103
  "typescript": "^5.5.3",
104
+ "typescript-eslint": "^8.68.0",
83
105
  "vitest": "^4.1.11"
84
106
  },
85
107
  "engines": {
@@ -1 +0,0 @@
1
- @import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500&family=Source+Code+Pro:wght@400&display=swap";:root{--color-phosphor-green: #3ecf8e;--color-mint-pulse: #00c573;--color-forest-depth: #1f4b37;--color-midnight-emerald: #006239;--color-snow: #fafafa;--color-silver-mist: #b4b4b4;--color-smoke: #898989;--color-graphite: #4d4d4d;--color-slate: #393939;--color-charcoal: #2e2e2e;--color-ash: #242424;--color-obsidian: #121212;--font-circular: "Circular", Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--font-source-code-pro: "Source Code Pro", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;--text-caption: 12px;--leading-caption: 1.5;--tracking-caption: -.084px;--text-body-sm: 14px;--leading-body-sm: 1.43;--tracking-body-sm: -.098px;--text-body: 16px;--leading-body: 1.5;--tracking-body: -.112px;--text-subheading: 18px;--leading-subheading: 1.38;--tracking-subheading: -.126px;--text-heading-sm: 24px;--leading-heading-sm: 1.33;--tracking-heading-sm: -.168px;--text-heading: 36px;--leading-heading: 1.2;--tracking-heading: -.252px;--text-display: 72px;--leading-display: 1;--tracking-display: -.504px;--font-weight-regular: 400;--font-weight-medium: 500;--spacing-unit: 8px;--spacing-8: 8px;--spacing-16: 16px;--spacing-24: 24px;--spacing-32: 32px;--spacing-40: 40px;--spacing-48: 48px;--spacing-64: 64px;--spacing-80: 80px;--spacing-96: 96px;--spacing-112: 112px;--spacing-128: 128px;--spacing-224: 224px;--page-max-width: 1200px;--section-gap: 64px;--card-padding: 24px;--element-gap: 16px;--radius-lg: 8px;--radius-lg-2: 11px;--radius-2xl: 16px;--radius-full: 9999px;--radius-tags: 9999px;--radius-cards: 16px;--radius-inputs: 8px;--radius-buttons: 9999px;--shadow-sm: rgba(0, 0, 0, .1) 0px 4px 6px -1px, rgba(0, 0, 0, .1) 0px 2px 4px -2px;--surface-obsidian-canvas: #121212;--surface-ash-card: #242424;--surface-charcoal-border: #2e2e2e}@theme{ --color-phosphor-green: #3ecf8e; --color-mint-pulse: #00c573; --color-forest-depth: #1f4b37; --color-midnight-emerald: #006239; --color-snow: #fafafa; --color-silver-mist: #b4b4b4; --color-smoke: #898989; --color-graphite: #4d4d4d; --color-slate: #393939; --color-charcoal: #2e2e2e; --color-ash: #242424; --color-obsidian: #121212; --font-circular: "Circular", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --font-source-code-pro: "Source Code Pro", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; --text-caption: 12px; --leading-caption: 1.5; --tracking-caption: -.084px; --text-body-sm: 14px; --leading-body-sm: 1.43; --tracking-body-sm: -.098px; --text-body: 16px; --leading-body: 1.5; --tracking-body: -.112px; --text-subheading: 18px; --leading-subheading: 1.38; --tracking-subheading: -.126px; --text-heading-sm: 24px; --leading-heading-sm: 1.33; --tracking-heading-sm: -.168px; --text-heading: 36px; --leading-heading: 1.2; --tracking-heading: -.252px; --text-display: 72px; --leading-display: 1; --tracking-display: -.504px; --spacing-8: 8px; --spacing-16: 16px; --spacing-24: 24px; --spacing-32: 32px; --spacing-40: 40px; --spacing-48: 48px; --spacing-64: 64px; --spacing-80: 80px; --spacing-96: 96px; --spacing-112: 112px; --spacing-128: 128px; --spacing-224: 224px; --radius-lg: 8px; --radius-lg-2: 11px; --radius-2xl: 16px; --radius-full: 9999px; --shadow-sm: rgba(0, 0, 0, .1) 0px 4px 6px -1px, rgba(0, 0, 0, .1) 0px 2px 4px -2px; }*{box-sizing:border-box}html{background:var(--color-obsidian);color:var(--color-snow);scroll-behavior:smooth}body{margin:0;background:var(--color-obsidian);color:var(--color-snow);font-family:var(--font-circular);font-size:var(--text-body);font-weight:var(--font-weight-regular);letter-spacing:var(--tracking-body);line-height:var(--leading-body);-webkit-font-smoothing:antialiased}a{color:inherit;text-decoration:none}button,a{-webkit-tap-highlight-color:transparent}:focus-visible{outline:1px solid var(--color-phosphor-green);outline-offset:4px}.site-shell{min-height:100vh;overflow:hidden;background:linear-gradient(var(--color-charcoal) 1px,transparent 1px),linear-gradient(90deg,var(--color-charcoal) 1px,transparent 1px),var(--color-obsidian);background-size:96px 96px;background-position:center top}.site-shell:before{content:"";position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;background:radial-gradient(circle at 50% 0%,rgba(62,207,142,.1),transparent 28%);opacity:.8}.nav{position:fixed;top:0;left:0;right:0;z-index:20;display:flex;align-items:center;justify-content:space-between;height:64px;padding:0 max(24px,calc((100vw - var(--page-max-width)) / 2));background:#121212e0;border-bottom:1px solid var(--color-charcoal);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.brand,.nav-links,.nav-actions,.hero-actions,.visual-topline,.control-row,.footer{display:flex;align-items:center}.brand{gap:10px;font-size:var(--text-body-sm);font-weight:var(--font-weight-medium);letter-spacing:var(--tracking-body-sm)}.logo-mark{width:24px;height:24px;color:var(--color-phosphor-green);fill:currentColor}.logo-mark circle{fill:var(--color-obsidian)}.nav-links{gap:24px;color:var(--color-silver-mist);font-size:var(--text-body-sm);line-height:var(--leading-body-sm)}.nav-links a:hover{color:var(--color-snow)}.nav-actions{gap:8px}.stars-pill,.announcement{border:1px solid var(--color-charcoal);border-radius:var(--radius-full);background:var(--color-ash);color:var(--color-snow)}.stars-pill{padding:6px 10px;font-size:var(--text-caption);line-height:var(--leading-caption)}.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;min-height:38px;padding:8px 16px;border:1px solid var(--color-slate);border-radius:var(--radius-buttons);font-size:var(--text-body-sm);font-weight:var(--font-weight-medium);line-height:var(--leading-body-sm);letter-spacing:var(--tracking-body-sm);transition:border-color .18s ease,background-color .18s ease,transform .18s ease}.btn:hover{transform:translateY(-1px)}.btn-primary{border-color:var(--color-phosphor-green);background:var(--color-phosphor-green);color:var(--color-snow)}.btn-primary:hover{border-color:var(--color-forest-depth)}.btn-ghost{background:transparent;color:var(--color-snow)}.btn-ghost:hover{border-color:var(--color-graphite);background:#ffffff0a}.section{position:relative;z-index:1;width:min(var(--page-max-width),calc(100vw - 48px));margin:0 auto;padding:96px 0}.hero{min-height:100vh;padding-top:160px;text-align:center}.announcement{display:inline-flex;align-items:center;gap:8px;padding:6px 16px;color:var(--color-silver-mist);font-size:var(--text-caption);line-height:var(--leading-caption);animation:fade-up .5s ease both}.announcement span{color:var(--color-silver-mist)}.hero h1{max-width:970px;margin:28px auto 0;color:var(--color-snow);font-size:clamp(48px,7vw,var(--text-display));font-weight:var(--font-weight-regular);letter-spacing:var(--tracking-display);line-height:var(--leading-display);animation:fade-up .62s 80ms ease both}.hero h1 span{display:block;color:var(--color-phosphor-green)}.hero-subline{max-width:760px;margin:24px auto 0;color:var(--color-silver-mist);font-size:var(--text-body);line-height:var(--leading-body);animation:fade-up .62s .16s ease both}.hero-actions{justify-content:center;gap:12px;margin-top:32px;animation:fade-up .62s .24s ease both}.hero-command{width:min(460px,100%);margin:24px auto 0;animation:fade-up .62s .32s ease both}.code{margin:0;overflow:auto;border:1px solid var(--color-charcoal);border-radius:var(--radius-inputs);background:#0d0d0d;color:var(--color-snow);padding:12px 14px;text-align:left;font-family:var(--font-source-code-pro);font-size:var(--text-caption);font-weight:var(--font-weight-regular);letter-spacing:.1em;line-height:1.33}.product-visual{position:relative;max-width:1060px;margin:56px auto 0;padding:24px;border:1px solid var(--color-charcoal);border-radius:var(--radius-cards);background:var(--color-obsidian);text-align:left;animation:fade-up .62s .4s ease both}.product-visual:before,.product-visual:after{content:"";position:absolute;width:8px;height:8px;border-radius:9999px;background:var(--color-phosphor-green);box-shadow:0 0 24px #3ecf8e80}.product-visual:before{top:18px;right:24px}.product-visual:after{right:17%;bottom:28%;animation:pulse-dot 1.6s ease-in-out infinite}.visual-topline{justify-content:space-between;padding-bottom:16px;color:var(--color-smoke);font-family:var(--font-source-code-pro);font-size:var(--text-caption);letter-spacing:.1em}.live-dot{color:var(--color-phosphor-green)}.visual-grid{display:grid;grid-template-columns:1.1fr 1fr;grid-template-rows:auto auto;gap:16px}.panel{min-height:214px;border:1px solid var(--color-charcoal);border-radius:var(--radius-cards);background:linear-gradient(var(--color-charcoal) 1px,transparent 1px),linear-gradient(90deg,var(--color-charcoal) 1px,transparent 1px),#0d0d0d;background-size:32px 32px;padding:20px}.traffic-panel{grid-row:span 2}.panel-label,.eyebrow{display:inline-flex;margin-bottom:16px;color:var(--color-phosphor-green);font-size:var(--text-caption);font-weight:var(--font-weight-medium);letter-spacing:var(--tracking-caption);line-height:var(--leading-caption)}.request{display:grid;grid-template-columns:58px minmax(0,1fr) 72px;align-items:center;gap:12px;margin-top:10px;padding:12px;border:1px solid var(--color-charcoal);border-radius:var(--radius-inputs);color:var(--color-silver-mist);animation:scan-row 4.8s linear infinite}.request.active{border-color:var(--color-phosphor-green)}.request span,.request em,.control-row b{font-family:var(--font-source-code-pro);font-size:var(--text-caption);font-style:normal;letter-spacing:.1em}.request strong{overflow:hidden;color:var(--color-snow);font-size:var(--text-body-sm);font-weight:var(--font-weight-medium);text-overflow:ellipsis;white-space:nowrap}.failure-panel .code{height:148px;border-color:var(--color-slate);color:var(--color-silver-mist)}.control-panel{min-height:180px}.control-row{justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--color-charcoal);color:var(--color-silver-mist);font-size:var(--text-body-sm)}.control-row:last-child{border-bottom:0}.control-row b{color:var(--color-phosphor-green);font-weight:var(--font-weight-regular)}.product-visual p,.killer-use-case,.section-copy p,.feature-card p,.step-card p,.audience-grid p,.faq-grid p,.install-note,.footer p{color:var(--color-silver-mist)}.product-visual p{margin:18px 0 0;text-align:center;font-size:var(--text-body-sm)}.killer-use-case{max-width:760px;margin:24px auto 0;font-size:var(--text-body-sm);line-height:var(--leading-body-sm)}.section-copy{max-width:760px}.section-copy.centered{margin:0 auto 48px;text-align:center}.section-copy h2,.proof-card h2{margin:0;color:var(--color-snow);font-size:clamp(30px,4vw,var(--text-heading));font-weight:var(--font-weight-regular);letter-spacing:var(--tracking-heading);line-height:var(--leading-heading)}.section-copy p{margin:16px 0 0}.problem{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:start}.problem-grid,.audience-grid,.faq-grid{display:grid;gap:16px}.problem-grid article,.audience-grid article,.faq-grid article,.step-card,.feature-card,.install-card,.proof-card{border:1px solid var(--color-charcoal);border-radius:var(--radius-cards);background:var(--color-obsidian);padding:var(--card-padding)}.problem-grid article{color:var(--color-silver-mist)}.steps-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}.step-number{color:var(--color-smoke);font-family:var(--font-source-code-pro);font-size:var(--text-caption);letter-spacing:.1em}.step-card h3,.feature-card h3,.audience-grid h3,.install-card h3,.faq-grid h3{margin:14px 0 8px;color:var(--color-snow);font-size:var(--text-subheading);font-weight:var(--font-weight-medium);letter-spacing:var(--tracking-subheading);line-height:var(--leading-subheading)}.step-card .code{margin:18px 0}.feature-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}.feature-card{display:flex;min-height:356px;flex-direction:column}.feature-icon .logo-mark{width:26px;height:26px}.line-art{position:relative;display:grid;grid-template-columns:repeat(3,1fr);gap:10px;min-height:116px;margin-top:auto;overflow:hidden;border:1px solid var(--color-charcoal);border-radius:var(--radius-inputs);background:#0d0d0d;padding:18px}.line-art span{border:1px solid var(--color-graphite);border-radius:var(--radius-inputs);transform:skewY(-8deg)}.line-art span:nth-child(2){border-color:var(--color-phosphor-green);animation:pulse-border 1.8s ease-in-out infinite}.feature-card .code{margin-top:16px}.audience-section{display:grid;grid-template-columns:.9fr 1.1fr;gap:48px;align-items:start}.install-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}.install-card h3{margin-top:0}.install-card .code{min-height:74px}.install-note{margin:16px 0 0;text-align:center;font-size:var(--text-body-sm)}.proof-card{display:grid;grid-template-columns:.9fr 1.1fr;gap:48px;align-items:center;padding:40px}.storyboard{display:grid;gap:10px}.storyboard span{position:relative;display:block;padding:12px 14px 12px 36px;border:1px solid var(--color-charcoal);border-radius:var(--radius-inputs);color:var(--color-silver-mist);font-size:var(--text-body-sm)}.storyboard span:before{content:"";position:absolute;top:17px;left:14px;width:8px;height:8px;border-radius:9999px;background:var(--color-phosphor-green)}.faq-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.footer{position:relative;z-index:1;justify-content:space-between;width:min(var(--page-max-width),calc(100vw - 48px));margin:0 auto;padding:48px 0 64px;border-top:1px solid var(--color-charcoal)}.footer p{margin:0;font-size:var(--text-body-sm)}@keyframes fade-up{0%{opacity:0;transform:translateY(18px)}to{opacity:1;transform:translateY(0)}}@keyframes pulse-dot{0%,to{opacity:.45;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}@keyframes pulse-border{0%,to{opacity:.4}50%{opacity:1}}@keyframes scan-row{0%,38%,to{background:transparent}42%,50%{background:#3ecf8e0a}}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:1ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:1ms!important}}@media (max-width: 1060px){.nav-links,.stars-pill{display:none}.feature-grid,.steps-grid,.install-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.problem,.audience-section,.proof-card{grid-template-columns:1fr}}@media (max-width: 760px){.nav{height:auto;min-height:64px;padding:10px 16px}.nav-actions .btn-ghost{display:none}.section{width:min(100% - 32px,var(--page-max-width));padding:72px 0}.hero{padding-top:128px}.hero-actions{flex-direction:column}.hero-actions .btn{width:100%}.visual-grid,.feature-grid,.steps-grid,.install-grid,.faq-grid{grid-template-columns:1fr}.request{grid-template-columns:54px minmax(0,1fr)}.request em{display:none}.product-visual,.proof-card{padding:16px}.footer{align-items:flex-start;flex-direction:column;gap:18px;width:min(100% - 32px,var(--page-max-width))}}@media (max-width: 440px){.brand span{display:none}.nav-actions .btn{min-height:34px;padding:7px 12px}.hero h1{font-size:44px}}
@@ -1 +0,0 @@
1
- @import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500&family=Source+Code+Pro:wght@400&display=swap";:root{--color-phosphor-green: #3ecf8e;--color-mint-pulse: #00c573;--color-forest-depth: #1f4b37;--color-midnight-emerald: #006239;--color-snow: #fafafa;--color-silver-mist: #b4b4b4;--color-smoke: #898989;--color-graphite: #4d4d4d;--color-slate: #393939;--color-charcoal: #2e2e2e;--color-ash: #242424;--color-obsidian: #121212;--font-circular: "Circular", Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--font-source-code-pro: "Source Code Pro", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;--text-caption: 12px;--leading-caption: 1.5;--tracking-caption: -.084px;--text-body-sm: 14px;--leading-body-sm: 1.43;--tracking-body-sm: -.098px;--text-body: 16px;--leading-body: 1.5;--tracking-body: -.112px;--text-subheading: 18px;--leading-subheading: 1.38;--tracking-subheading: -.126px;--text-heading-sm: 24px;--leading-heading-sm: 1.33;--tracking-heading-sm: -.168px;--text-heading: 36px;--leading-heading: 1.2;--tracking-heading: -.252px;--text-display: 72px;--leading-display: 1;--tracking-display: -.504px;--font-weight-regular: 400;--font-weight-medium: 500;--spacing-unit: 8px;--spacing-8: 8px;--spacing-16: 16px;--spacing-24: 24px;--spacing-32: 32px;--spacing-40: 40px;--spacing-48: 48px;--spacing-64: 64px;--spacing-80: 80px;--spacing-96: 96px;--spacing-112: 112px;--spacing-128: 128px;--spacing-224: 224px;--page-max-width: 1200px;--section-gap: 64px;--card-padding: 24px;--element-gap: 16px;--radius-lg: 8px;--radius-lg-2: 11px;--radius-2xl: 16px;--radius-full: 9999px;--radius-tags: 9999px;--radius-cards: 16px;--radius-inputs: 8px;--radius-buttons: 9999px;--shadow-sm: rgba(0, 0, 0, .1) 0px 4px 6px -1px, rgba(0, 0, 0, .1) 0px 2px 4px -2px;--surface-obsidian-canvas: #121212;--surface-ash-card: #242424;--surface-charcoal-border: #2e2e2e}@theme{ --color-phosphor-green: #3ecf8e; --color-mint-pulse: #00c573; --color-forest-depth: #1f4b37; --color-midnight-emerald: #006239; --color-snow: #fafafa; --color-silver-mist: #b4b4b4; --color-smoke: #898989; --color-graphite: #4d4d4d; --color-slate: #393939; --color-charcoal: #2e2e2e; --color-ash: #242424; --color-obsidian: #121212; --font-circular: "Circular", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --font-source-code-pro: "Source Code Pro", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; --text-caption: 12px; --leading-caption: 1.5; --tracking-caption: -.084px; --text-body-sm: 14px; --leading-body-sm: 1.43; --tracking-body-sm: -.098px; --text-body: 16px; --leading-body: 1.5; --tracking-body: -.112px; --text-subheading: 18px; --leading-subheading: 1.38; --tracking-subheading: -.126px; --text-heading-sm: 24px; --leading-heading-sm: 1.33; --tracking-heading-sm: -.168px; --text-heading: 36px; --leading-heading: 1.2; --tracking-heading: -.252px; --text-display: 72px; --leading-display: 1; --tracking-display: -.504px; --spacing-8: 8px; --spacing-16: 16px; --spacing-24: 24px; --spacing-32: 32px; --spacing-40: 40px; --spacing-48: 48px; --spacing-64: 64px; --spacing-80: 80px; --spacing-96: 96px; --spacing-112: 112px; --spacing-128: 128px; --spacing-224: 224px; --radius-lg: 8px; --radius-lg-2: 11px; --radius-2xl: 16px; --radius-full: 9999px; --shadow-sm: rgba(0, 0, 0, .1) 0px 4px 6px -1px, rgba(0, 0, 0, .1) 0px 2px 4px -2px; }*{box-sizing:border-box}html{background:var(--color-obsidian);color:var(--color-snow);scroll-behavior:smooth}body{margin:0;background:var(--color-obsidian);color:var(--color-snow);font-family:var(--font-circular);font-size:var(--text-body);font-weight:var(--font-weight-regular);letter-spacing:var(--tracking-body);line-height:var(--leading-body);-webkit-font-smoothing:antialiased}a{color:inherit;text-decoration:none}button,a{-webkit-tap-highlight-color:transparent}:focus-visible{outline:1px solid var(--color-phosphor-green);outline-offset:4px}.site-shell{min-height:100vh;overflow:hidden;background:linear-gradient(var(--color-charcoal) 1px,transparent 1px),linear-gradient(90deg,var(--color-charcoal) 1px,transparent 1px),var(--color-obsidian);background-size:96px 96px;background-position:center top}.site-shell:before{content:"";position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;background:radial-gradient(circle at 50% 0%,rgba(62,207,142,.1),transparent 28%);opacity:.8}.nav{position:fixed;top:0;left:0;right:0;z-index:20;display:flex;align-items:center;justify-content:space-between;height:64px;padding:0 max(24px,calc((100vw - var(--page-max-width)) / 2));background:#121212e0;border-bottom:1px solid var(--color-charcoal);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}.brand,.nav-links,.nav-actions,.hero-actions,.visual-topline,.control-row,.footer{display:flex;align-items:center}.brand{gap:10px;font-size:var(--text-body-sm);font-weight:var(--font-weight-medium);letter-spacing:var(--tracking-body-sm)}.logo-mark{width:24px;height:24px;color:var(--color-phosphor-green);fill:currentColor}.logo-mark circle{fill:var(--color-obsidian)}.nav-links{gap:24px;color:var(--color-silver-mist);font-size:var(--text-body-sm);line-height:var(--leading-body-sm)}.nav-links a:hover{color:var(--color-snow)}.nav-actions{gap:8px}.stars-pill,.announcement{border:1px solid var(--color-charcoal);border-radius:var(--radius-full);background:var(--color-ash);color:var(--color-snow)}.stars-pill{padding:6px 10px;font-size:var(--text-caption);line-height:var(--leading-caption)}.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;min-height:38px;padding:8px 16px;border:1px solid var(--color-slate);border-radius:var(--radius-buttons);font-size:var(--text-body-sm);font-weight:var(--font-weight-medium);line-height:var(--leading-body-sm);letter-spacing:var(--tracking-body-sm);transition:border-color .18s ease,background-color .18s ease,transform .18s ease}.btn:hover{transform:translateY(-1px)}.btn-primary{border-color:var(--color-phosphor-green);background:var(--color-phosphor-green);color:var(--color-snow)}.btn-primary:hover{border-color:var(--color-forest-depth)}.btn-ghost{background:transparent;color:var(--color-snow)}.btn-ghost:hover{border-color:var(--color-graphite);background:#ffffff0a}.section{position:relative;z-index:1;width:min(var(--page-max-width),calc(100vw - 48px));margin:0 auto;padding:96px 0}.hero{min-height:100vh;padding-top:160px;text-align:center}.announcement{display:inline-flex;align-items:center;gap:8px;padding:6px 16px;color:var(--color-silver-mist);font-size:var(--text-caption);line-height:var(--leading-caption);animation:fade-up .5s ease both}.announcement span{color:var(--color-silver-mist)}.hero h1{max-width:970px;margin:28px auto 0;color:var(--color-snow);font-size:clamp(48px,7vw,var(--text-display));font-weight:var(--font-weight-regular);letter-spacing:var(--tracking-display);line-height:var(--leading-display);animation:fade-up .62s 80ms ease both}.hero h1 span{display:block;color:var(--color-phosphor-green)}.hero-subline{max-width:760px;margin:24px auto 0;color:var(--color-silver-mist);font-size:var(--text-body);line-height:var(--leading-body);animation:fade-up .62s .16s ease both}.hero-actions{justify-content:center;gap:12px;margin-top:32px;animation:fade-up .62s .24s ease both}.hero-command{width:min(460px,100%);margin:24px auto 0;animation:fade-up .62s .32s ease both}.code{margin:0;overflow:auto;border:1px solid var(--color-charcoal);border-radius:var(--radius-inputs);background:#0d0d0d;color:var(--color-snow);padding:12px 14px;text-align:left;font-family:var(--font-source-code-pro);font-size:var(--text-caption);font-weight:var(--font-weight-regular);letter-spacing:.1em;line-height:1.33}.product-visual{position:relative;max-width:1060px;margin:56px auto 0;padding:24px;border:1px solid var(--color-charcoal);border-radius:var(--radius-cards);background:var(--color-obsidian);text-align:left;animation:fade-up .62s .4s ease both}.product-visual:before,.product-visual:after{content:"";position:absolute;width:8px;height:8px;border-radius:9999px;background:var(--color-phosphor-green);box-shadow:0 0 24px #3ecf8e80}.product-visual:before{top:18px;right:24px}.product-visual:after{right:17%;bottom:28%;animation:pulse-dot 1.6s ease-in-out infinite}.visual-topline{justify-content:space-between;padding-bottom:16px;color:var(--color-smoke);font-family:var(--font-source-code-pro);font-size:var(--text-caption);letter-spacing:.1em}.live-dot{color:var(--color-phosphor-green)}.visual-grid{display:grid;grid-template-columns:1.1fr 1fr;grid-template-rows:auto auto;gap:16px}.panel{min-height:214px;border:1px solid var(--color-charcoal);border-radius:var(--radius-cards);background:linear-gradient(var(--color-charcoal) 1px,transparent 1px),linear-gradient(90deg,var(--color-charcoal) 1px,transparent 1px),#0d0d0d;background-size:32px 32px;padding:20px}.traffic-panel{grid-row:span 2}.panel-label,.eyebrow{display:inline-flex;margin-bottom:16px;color:var(--color-phosphor-green);font-size:var(--text-caption);font-weight:var(--font-weight-medium);letter-spacing:var(--tracking-caption);line-height:var(--leading-caption)}.request{display:grid;grid-template-columns:58px minmax(0,1fr) 72px;align-items:center;gap:12px;margin-top:10px;padding:12px;border:1px solid var(--color-charcoal);border-radius:var(--radius-inputs);color:var(--color-silver-mist);animation:scan-row 4.8s linear infinite}.request.active{border-color:var(--color-phosphor-green)}.request span,.request em,.control-row b{font-family:var(--font-source-code-pro);font-size:var(--text-caption);font-style:normal;letter-spacing:.1em}.request strong{overflow:hidden;color:var(--color-snow);font-size:var(--text-body-sm);font-weight:var(--font-weight-medium);text-overflow:ellipsis;white-space:nowrap}.failure-panel .code{height:148px;border-color:var(--color-slate);color:var(--color-silver-mist)}.control-panel{min-height:180px}.control-row{justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--color-charcoal);color:var(--color-silver-mist);font-size:var(--text-body-sm)}.control-row:last-child{border-bottom:0}.control-row b{color:var(--color-phosphor-green);font-weight:var(--font-weight-regular)}.product-visual p,.killer-use-case,.section-copy p,.feature-card p,.step-card p,.audience-grid p,.faq-grid p,.install-note,.footer p{color:var(--color-silver-mist)}.product-visual p{margin:18px 0 0;text-align:center;font-size:var(--text-body-sm)}.killer-use-case{max-width:760px;margin:24px auto 0;font-size:var(--text-body-sm);line-height:var(--leading-body-sm)}.section-copy{max-width:760px}.section-copy.centered{margin:0 auto 48px;text-align:center}.section-copy h2,.proof-card h2{margin:0;color:var(--color-snow);font-size:clamp(30px,4vw,var(--text-heading));font-weight:var(--font-weight-regular);letter-spacing:var(--tracking-heading);line-height:var(--leading-heading)}.section-copy p{margin:16px 0 0}.problem{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:start}.problem-grid,.audience-grid,.faq-grid{display:grid;gap:16px}.problem-grid article,.audience-grid article,.faq-grid article,.step-card,.feature-card,.install-card,.proof-card{border:1px solid var(--color-charcoal);border-radius:var(--radius-cards);background:var(--color-obsidian);padding:var(--card-padding)}.problem-grid article{color:var(--color-silver-mist)}.steps-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}.step-number{color:var(--color-smoke);font-family:var(--font-source-code-pro);font-size:var(--text-caption);letter-spacing:.1em}.step-card h3,.feature-card h3,.audience-grid h3,.install-card h3,.faq-grid h3{margin:14px 0 8px;color:var(--color-snow);font-size:var(--text-subheading);font-weight:var(--font-weight-medium);letter-spacing:var(--tracking-subheading);line-height:var(--leading-subheading)}.step-card .code{margin:18px 0}.feature-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}.feature-card{display:flex;min-height:356px;flex-direction:column}.feature-icon .logo-mark{width:26px;height:26px}.line-art{position:relative;display:grid;grid-template-columns:repeat(3,1fr);gap:10px;min-height:116px;margin-top:auto;overflow:hidden;border:1px solid var(--color-charcoal);border-radius:var(--radius-inputs);background:#0d0d0d;padding:18px}.line-art span{border:1px solid var(--color-graphite);border-radius:var(--radius-inputs);transform:skewY(-8deg)}.line-art span:nth-child(2){border-color:var(--color-phosphor-green);animation:pulse-border 1.8s ease-in-out infinite}.feature-card .code{margin-top:16px}.audience-section{display:grid;grid-template-columns:.9fr 1.1fr;gap:48px;align-items:start}.install-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:16px}.install-card h3{margin-top:0}.install-card .code{min-height:74px}.install-note{margin:16px 0 0;text-align:center;font-size:var(--text-body-sm)}.proof-card{display:grid;grid-template-columns:.9fr 1.1fr;gap:48px;align-items:center;padding:40px}.storyboard{display:grid;gap:10px}.storyboard span{position:relative;display:block;padding:12px 14px 12px 36px;border:1px solid var(--color-charcoal);border-radius:var(--radius-inputs);color:var(--color-silver-mist);font-size:var(--text-body-sm)}.storyboard span:before{content:"";position:absolute;top:17px;left:14px;width:8px;height:8px;border-radius:9999px;background:var(--color-phosphor-green)}.faq-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.footer{position:relative;z-index:1;justify-content:space-between;width:min(var(--page-max-width),calc(100vw - 48px));margin:0 auto;padding:48px 0 64px;border-top:1px solid var(--color-charcoal)}.footer p{margin:0;font-size:var(--text-body-sm)}@keyframes fade-up{0%{opacity:0;transform:translateY(18px)}to{opacity:1;transform:translateY(0)}}@keyframes pulse-dot{0%,to{opacity:.45;transform:scale(1)}50%{opacity:1;transform:scale(1.6)}}@keyframes pulse-border{0%,to{opacity:.4}50%{opacity:1}}@keyframes scan-row{0%,38%,to{background:transparent}42%,50%{background:#3ecf8e0a}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:1ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important;transition-duration:1ms!important}}@media(max-width:1060px){.nav-links,.stars-pill{display:none}.feature-grid,.steps-grid,.install-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.problem,.audience-section,.proof-card{grid-template-columns:1fr}}@media(max-width:760px){.nav{height:auto;min-height:64px;padding:10px 16px}.nav-actions .btn-ghost{display:none}.section{width:min(100% - 32px,var(--page-max-width));padding:72px 0}.hero{padding-top:128px}.hero-actions{flex-direction:column}.hero-actions .btn{width:100%}.visual-grid,.feature-grid,.steps-grid,.install-grid,.faq-grid{grid-template-columns:1fr}.request{grid-template-columns:54px minmax(0,1fr)}.request em{display:none}.product-visual,.proof-card{padding:16px}.footer{align-items:flex-start;flex-direction:column;gap:18px;width:min(100% - 32px,var(--page-max-width))}}@media(max-width:440px){.brand span{display:none}.nav-actions .btn{min-height:34px;padding:7px 12px}.hero h1{font-size:44px}}