@bongos/core 1.19.726 → 1.19.728

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 (227) hide show
  1. package/.bongos-core.json +177 -492
  2. package/.devcontainer/Dockerfile +1 -1
  3. package/.devcontainer/devcontainer.json +2 -2
  4. package/.devcontainer/healthcheck.sh +1 -1
  5. package/.devcontainer/init-firewall.sh +1 -1
  6. package/.devcontainer/post-create.sh +2 -2
  7. package/.env.local.example +1 -1
  8. package/Dockerfile +1 -1
  9. package/docs/copy-inventory.md +1 -1
  10. package/docs/copy-registry.json +9 -9
  11. package/docs/module-api-changelog.md +4 -0
  12. package/docs/recipes/devbox-app-release.md +4 -4
  13. package/modules/dev-box/app/scripts/dmgbuild-settings.py +5 -5
  14. package/modules/dev-box/app/scripts/gen-brand.js +1 -1
  15. package/modules/dev-box/app/src/brand.js +1 -1
  16. package/modules/dev-box/app/test/unit.mjs +16 -16
  17. package/modules/dev-box/box-access.js +1 -1
  18. package/modules/dev-box/routes/box.js +1 -1
  19. package/modules/discord/discord-approvals.js +1 -1
  20. package/modules/grading/grader-model.js +1 -1
  21. package/modules/grading/grader-prompt.js +1 -1
  22. package/modules/grading/grader-workers/quality.js +1 -1
  23. package/modules/hall-ui/module.json +1 -1
  24. package/modules/hall-ui/public/brand-apply.js +1 -1
  25. package/modules/hall-ui/public/shell.js +1 -1
  26. package/modules/hall-ui/public/work.js +1 -1
  27. package/modules/lifecycle/conflict-resolve.js +1 -1
  28. package/modules/lifecycle/db-analytics.js +1 -1
  29. package/modules/lifecycle/routes/analytics.js +1 -1
  30. package/modules/onboarding/approval-broadcast.js +1 -1
  31. package/modules/onboarding/onboarding.js +1 -1
  32. package/modules/provisioning/tests/liveness.mjs +1 -1
  33. package/modules/public-landing/public/index.html +1 -1
  34. package/modules/public-landing/public/projects-floor.states.json +2 -2
  35. package/modules/public-landing/public/projects.probes.json +4 -4
  36. package/modules/public-landing/public/projects.states.json +2 -2
  37. package/modules/status-ui/module.json +1 -1
  38. package/modules/status-ui/public/status.js +4 -4
  39. package/modules/status-ui/public/style.css +1 -1
  40. package/modules/ui-design/kit/fixtures/cost-summary.json +1 -1
  41. package/modules/ui-design/kit/fixtures/featured-hub.json +1 -1
  42. package/modules/ui-design/kit/fixtures/featured.json +1 -1
  43. package/modules/ui-design/kit/fixtures/leaderboard.json +1 -1
  44. package/modules/ui-design/kit/fixtures/my-projects.json +1 -1
  45. package/modules/ui-design/kit/fixtures/progress.json +1 -1
  46. package/modules/ui-design/kit/fixtures/recent-shipped.json +1 -1
  47. package/package-lock.json +2 -2
  48. package/package.json +1 -1
  49. package/scripts/cron/style_guide_audit.sh +1 -1
  50. package/scripts/discord/lib.js +1 -1
  51. package/scripts/discord/post.js +1 -1
  52. package/scripts/gds/audit-authorship.sh +1 -1
  53. package/scripts/gds/audit-replay.sh +29 -2
  54. package/scripts/gds/audit-ships.js +1 -1
  55. package/scripts/gds/backfill-sessions.js +2 -2
  56. package/scripts/gds/cf-tunnel.js +4 -4
  57. package/scripts/gds/claude-materialize.js +2 -2
  58. package/scripts/gds/cli-lib.js +6 -6
  59. package/scripts/gds/cutover-codemod.js +1 -1
  60. package/scripts/gds/dev-lib.js +2 -2
  61. package/scripts/gds/diagnose-achievements.js +2 -2
  62. package/scripts/gds/fitness-checks-identity.js +6 -4
  63. package/scripts/gds/gen-diagrams.js +1 -1
  64. package/scripts/gds/leak-scan-allowlist.js +293 -0
  65. package/scripts/gds/learning-capture.js +1 -1
  66. package/scripts/gds/linkify-refs.js +2 -2
  67. package/scripts/gds/local-preview-lib.js +1 -1
  68. package/scripts/gds/mirror-lineage-check.js +1 -1
  69. package/scripts/gds/mirror-redact.js +17 -2
  70. package/scripts/gds/newcomer-floor.templates.json +1 -1
  71. package/scripts/gds/package-core.js +18 -1
  72. package/scripts/gds/paste-token.js +1 -1
  73. package/scripts/gds/provision-units.js +2 -2
  74. package/scripts/gds/publish-manifest.js +15 -0
  75. package/scripts/gds/repo-metrics.js +1 -1
  76. package/scripts/gds/sandbox-stage.js +1 -1
  77. package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +1 -1
  78. package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +1 -1
  79. package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +1 -1
  80. package/scripts/gds/seed-bongos-tasks.js +2 -2
  81. package/scripts/gds/seed-gds-v4-tasks.js +1 -1
  82. package/scripts/gds/seed-medusa-tasks.js +10 -10
  83. package/scripts/gds/seed-module-upstreaming.js +1 -1
  84. package/scripts/gds/seed-productization-tasks.js +6 -6
  85. package/scripts/gds/seed-provisioning-tasks.js +2 -2
  86. package/scripts/gds/seed-staging.sh +19 -6
  87. package/scripts/gds/ship-deploy-target.js +1 -1
  88. package/scripts/gds/ship-flow.js +1 -1
  89. package/scripts/gds/smoke-gds.js +1 -1
  90. package/scripts/status-probe.mjs +2 -2
  91. package/src/bongos/auth-discord.js +2 -2
  92. package/src/bongos/live-channel.js +1 -1
  93. package/src/bongos/pool.js +1 -1
  94. package/src/bongos/routes/auth.js +11 -11
  95. package/src/bongos/routes/security.js +1 -1
  96. package/src/bongos/routes.js +1 -1
  97. package/src/branding.js +1 -1
  98. package/src/devbox-downloads.js +1 -1
  99. package/src/instance-config.js +2 -2
  100. package/src/module-api.js +1 -1
  101. package/src/module-loader/provenance.js +2 -2
  102. package/tests/art_stage.mjs +2 -2
  103. package/tests/auth_anthropic_identity.mjs +1 -1
  104. package/tests/auth_duplicate_cookie.mjs +1 -1
  105. package/tests/auth_error_brand.mjs +1 -1
  106. package/tests/auth_inactive_builder.mjs +1 -1
  107. package/tests/backup_cli.mjs +4 -4
  108. package/tests/bongos_box_connect.mjs +2 -2
  109. package/tests/bongos_downloads.mjs +2 -2
  110. package/tests/bongos_login.mjs +5 -5
  111. package/tests/box_connect_e2e.mjs +2 -2
  112. package/tests/box_dns_repoint.mjs +10 -10
  113. package/tests/box_host_keys.mjs +1 -1
  114. package/tests/box_onboard.mjs +9 -9
  115. package/tests/box_scope_session.mjs +1 -1
  116. package/tests/box_terminal_ssrf.mjs +7 -7
  117. package/tests/boxes.mjs +9 -9
  118. package/tests/branding.mjs +2 -2
  119. package/tests/bump_version.mjs +2 -2
  120. package/tests/cf_tunnel.mjs +40 -40
  121. package/tests/cli_package.mjs +40 -1
  122. package/tests/cli_token_reissue.mjs +7 -7
  123. package/tests/cloud_bongos_pack.mjs +1 -1
  124. package/tests/currency_label.mjs +8 -8
  125. package/tests/dev_lib.mjs +4 -4
  126. package/tests/devbox_dmg_backdrop.mjs +1 -1
  127. package/tests/devbox_downloads.mjs +2 -2
  128. package/tests/devbox_icons.mjs +1 -1
  129. package/tests/discord_approvals.mjs +1 -1
  130. package/tests/discord_oauth.mjs +2 -2
  131. package/tests/executed_closure.mjs +6 -1
  132. package/tests/first_admin_bootstrap.mjs +1 -1
  133. package/tests/gate_approvals.mjs +5 -5
  134. package/tests/grade_aggregates_unavailable.mjs +1 -1
  135. package/tests/hook_user_agents.mjs +2 -2
  136. package/tests/init.mjs +6 -6
  137. package/tests/instance_config.mjs +1 -1
  138. package/tests/instance_manifest.mjs +5 -5
  139. package/tests/instance_mismatch_guard.mjs +13 -13
  140. package/tests/leak_scan_allowlist.mjs +94 -0
  141. package/tests/migrate_root_resolution.mjs +4 -4
  142. package/tests/mirror_redact.mjs +28 -4
  143. package/tests/module_catalog.mjs +5 -5
  144. package/tests/module_submissions.mjs +3 -3
  145. package/tests/package_core.mjs +1 -1
  146. package/tests/parallel-load.mjs +6 -6
  147. package/tests/projects_hub.mjs +2 -2
  148. package/tests/provision.mjs +50 -50
  149. package/tests/provisioning_github_app_routes.mjs +1 -1
  150. package/tests/provisioning_onboard_mode.mjs +2 -2
  151. package/tests/publish_reconciler.mjs +4 -4
  152. package/tests/sandbox_stage.mjs +1 -1
  153. package/tests/scrubber_corpus.mjs +3 -3
  154. package/tests/search_isolation.mjs +1 -1
  155. package/tests/session_records.mjs +1 -1
  156. package/tests/ship_card.mjs +6 -6
  157. package/tests/ship_ci_deploy.mjs +1 -1
  158. package/tests/single_host_hall.mjs +9 -9
  159. package/tests/smoke_preflight.mjs +1 -1
  160. package/tests/smoke_target.mjs +1 -1
  161. package/tests/status-probe.mjs +1 -1
  162. package/tests/status_mirror_sync.mjs +1 -1
  163. package/docs/adr/0004-amazonprimea-name-and-trademark-acceptance.md +0 -45
  164. package/docs/design/mocks/_schemes.css +0 -604
  165. package/docs/design/mocks/component-sheet.html +0 -428
  166. package/docs/design/mocks/hall/_tokens.css +0 -370
  167. package/docs/design/mocks/hall/board/v1.html +0 -846
  168. package/docs/design/mocks/hall/board/v2.html +0 -858
  169. package/docs/design/mocks/hall/board/v3.html +0 -884
  170. package/docs/design/mocks/hall/goals/v1.html +0 -1212
  171. package/docs/design/mocks/hall/goals/v2.html +0 -1192
  172. package/docs/design/mocks/hall/goals/v3.html +0 -1205
  173. package/docs/design/mocks/hall/hall-sheet.html +0 -244
  174. package/docs/design/mocks/hall/reading/v1.html +0 -1125
  175. package/docs/design/mocks/hall/reading/v2.html +0 -1177
  176. package/docs/design/mocks/hall/reading/v3.html +0 -1150
  177. package/docs/design/mocks/hall/settings/v1.html +0 -1238
  178. package/docs/design/mocks/hall/settings/v2.html +0 -1235
  179. package/docs/design/mocks/hall/settings/v3.html +0 -1299
  180. package/docs/design/mocks/hall/task/v1.html +0 -633
  181. package/docs/design/mocks/hall/task/v2.html +0 -646
  182. package/docs/design/mocks/hall/task/v3.html +0 -647
  183. package/docs/design/mocks/hub/assets/r3-space-deepfield-half.jpg +0 -0
  184. package/docs/design/mocks/hub/assets/r3-space-deepfield-half.jpg.json +0 -13
  185. package/docs/design/mocks/hub/assets/r3-space-dust-half.jpg +0 -0
  186. package/docs/design/mocks/hub/assets/r3-space-dust-half.jpg.json +0 -13
  187. package/docs/design/mocks/hub/assets/r3-space-nebula-half.jpg +0 -0
  188. package/docs/design/mocks/hub/assets/r3-space-nebula-half.jpg.json +0 -13
  189. package/docs/design/mocks/hub/assets/r3-space-starfield-half.jpg +0 -0
  190. package/docs/design/mocks/hub/assets/r3-space-starfield-half.jpg.json +0 -13
  191. package/docs/design/mocks/hub/hub-sheet.html +0 -192
  192. package/docs/design/mocks/hub/mine.html +0 -465
  193. package/docs/design/mocks/hub/picker.html +0 -421
  194. package/docs/design/mocks/hub/planets.html +0 -356
  195. package/docs/design/mocks/hub/v1.html +0 -1209
  196. package/docs/design/mocks/hub/v2.html +0 -1257
  197. package/docs/design/mocks/hub/v3.html +0 -1496
  198. package/docs/design/mocks/hub/wizard.html +0 -421
  199. package/docs/design/mocks/landing/landing-sheet.html +0 -131
  200. package/docs/design/mocks/landing/v1.html +0 -956
  201. package/docs/design/mocks/landing/v2.html +0 -708
  202. package/docs/design/mocks/landing/v3.html +0 -911
  203. package/docs/design/mocks/landing-page-mock.html +0 -687
  204. package/docs/design/mocks/landing-palettes.html +0 -103
  205. package/docs/design/mocks/projects-hub-mock.html +0 -991
  206. package/docs/design/mocks/projects-hub-variants.html +0 -146
  207. package/docs/design/mocks/projects-page-mock.html +0 -167
  208. package/docs/design/mocks/world/blue-hud/_tokens.css +0 -246
  209. package/docs/design/mocks/world/blue-hud/hall.html +0 -595
  210. package/docs/design/mocks/world/blue-hud/landing.html +0 -424
  211. package/docs/design/mocks/world/blue-hud/status.html +0 -410
  212. package/docs/design/mocks/world/chrome-blobs/_tokens.css +0 -479
  213. package/docs/design/mocks/world/chrome-blobs/hall.html +0 -553
  214. package/docs/design/mocks/world/chrome-blobs/landing-b.html +0 -581
  215. package/docs/design/mocks/world/chrome-blobs/landing.html +0 -328
  216. package/docs/design/mocks/world/chrome-blobs/status.html +0 -416
  217. package/docs/design/mocks/world/natgeo-editorial/_tokens.css +0 -377
  218. package/docs/design/mocks/world/natgeo-editorial/hall.html +0 -649
  219. package/docs/design/mocks/world/natgeo-editorial/landing-b.html +0 -743
  220. package/docs/design/mocks/world/natgeo-editorial/landing.html +0 -475
  221. package/docs/design/mocks/world/natgeo-editorial/status.html +0 -437
  222. package/docs/design/mocks/world/organic-cards/_tokens.css +0 -462
  223. package/docs/design/mocks/world/organic-cards/hall.html +0 -625
  224. package/docs/design/mocks/world/organic-cards/landing-b.html +0 -736
  225. package/docs/design/mocks/world/organic-cards/landing.html +0 -420
  226. package/docs/design/mocks/world/organic-cards/status.html +0 -458
  227. package/docs/design/mocks/world/world-sheet.html +0 -156
@@ -1,687 +0,0 @@
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">
6
- <title>The front door — cloudbongos.com/ (task 1002747)</title>
7
- <!-- ── S0 · HEAD METADATA ──────────────────────────────────────────────────
8
- These are the tags whose absence made task 1002746 urgent. They CANNOT be
9
- filled by the client branding script — social tags are read before JS runs
10
- (C8) — and they cannot be hardcoded, because public-landing/ ships wholesale
11
- to every instance (C1).
12
-
13
- DECIDED (owner, 2026-08-13): landingPage() (src/platform-server.js:64-73)
14
- is extended to stamp these server-side from the full branding(), in THIS
15
- pass. It already does a per-file injectBrandingGlobal pass, so this is the
16
- same seam. That closes idea 1000715 and cures the broken hall link (C9) by
17
- the same mechanism. Shown below as the {{placeholders}} it will fill.
18
-
19
- <meta name="description" content="{{tagline}} — {{productName}} is an open, AI-first build platform.">
20
- <link rel="canonical" href="{{publicOrigin}}/">
21
- <meta property="og:type" content="website">
22
- <meta property="og:site_name" content="{{productName}}">
23
- <meta property="og:url" content="{{publicOrigin}}/">
24
- <meta property="og:title" content="{{productName}} — {{tagline}}">
25
- <meta property="og:description" content="…">
26
- <meta property="og:image" content="{{publicOrigin}}/buddha.png">
27
- <meta name="twitter:card" content="summary_large_image">
28
- ───────────────────────────────────────────────────────────────────────── -->
29
- <meta name="description" content="Building software is laying down a beat. An open, AI-first build platform.">
30
- <link rel="preconnect" href="https://fonts.googleapis.com">
31
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
32
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Baloo+2:wght@500;600;700&family=Quicksand:wght@400;500;600;700&family=Fira+Code:wght@400;500&display=swap">
33
- <!-- Same convention as projects-page-mock.html: this links the REAL token layer
34
- the live pages use, so what you review is what ships. Toggle ☾/☀ in the header. -->
35
- <link rel="stylesheet" href="../../../modules/public-landing/public/assets/cosmos.css">
36
- <!-- Candidate palettes. MOCK-ONLY: on a real instance exactly one of these
37
- exists and arrives via config/branding.json → themeMarkup(). See the file
38
- header for the contrast audit. -->
39
- <link rel="stylesheet" href="_schemes.css">
40
- <script>
41
- /* ?scheme= / ?mascot= / ?mode= / ?rail=0 let the contact sheet drive this page
42
- in an iframe; otherwise the last choice is remembered. Mock-only. */
43
- (function(){
44
- var q=new URLSearchParams(location.search), r=document.documentElement;
45
- try{
46
- var m=q.get('mode')||localStorage.getItem('cb-color-mode');
47
- if(m==='light'||m==='dark') r.setAttribute('data-mode',m);
48
- /* ember marigold is the CHOSEN palette (owner, 2026-08-13). The switcher
49
- stays as the record of what was considered; this is the default. */
50
- var s=q.has('scheme')?q.get('scheme'):(localStorage.getItem('cb-mock-scheme')||'ember-marigold');
51
- if(s) r.setAttribute('data-scheme',s);
52
- }catch(e){}
53
- })();
54
- </script>
55
- <style>
56
- /* ── MOCK-LOCAL ONLY ─────────────────────────────────────────────────────
57
- Components cosmos.css does NOT have, because it was built for /create and
58
- /projects and never for a marketing page: a page container, a type scale
59
- below h1, a spacing scale, grid primitives, and a mid breakpoint. If this
60
- direction is approved these graduate INTO cosmos.css, so the landing page
61
- and the hub stay one system instead of two.
62
-
63
- NOTE: there is deliberately NO :root block here. injectBrandingGlobal
64
- splices the pack's theme <style> at the end of <head>, and a page-local
65
- :root would silently outrank it and defeat re-branding (constraint C4).
66
- Page-local custom properties are therefore scoped to their component, and
67
- dark-mode overrides are written TWICE to match cosmos.css's own pattern (C7).
68
- ──────────────────────────────────────────────────────────────────────── */
69
- .wrap{position:relative;z-index:1;max-width:1060px;margin:0 auto;padding:0 clamp(16px,4vw,40px);}
70
- .sec{margin-bottom:clamp(38px,6vw,78px);}
71
- /* Both modes take their ink from the SAME token (--accent-deep), which every
72
- palette defines and which cosmos.css flips per mode. An earlier version used
73
- --gold in dark only; --gold is real (cosmos.css's locked space palette) but
74
- it is platform-fixed, so it would NOT follow a re-theme while the light half
75
- did — the two halves would drift apart under any pack but the default. */
76
- .mockNote{background:rgba(255,255,255,.72);border:1.5px solid var(--rule);border-radius:16px;padding:14px 20px;font-size:13px;font-weight:600;color:var(--accent-deep);line-height:1.6;margin:0 0 34px;backdrop-filter:blur(6px);}
77
- :root[data-mode="dark"] .mockNote{background:rgba(13,15,40,.55);border-color:var(--rule);color:var(--accent-deep);}
78
- @media(prefers-color-scheme:dark){:root:not([data-mode="light"]) .mockNote{background:rgba(13,15,40,.55);border-color:var(--rule);color:var(--accent-deep);}}
79
- .mockNote code{font-family:var(--font-mono);font-size:12px;}
80
- .mockNote kbd{font-family:var(--font-mono);font-size:11.5px;border:1px solid currentColor;border-radius:4px;padding:0 5px;opacity:.85;}
81
-
82
- /* type scale below h1 — cosmos.css stops at h1 */
83
- h2.sec-h{font-family:var(--font-display);font-weight:700;font-size:clamp(22px,3vw,29px);letter-spacing:-.6px;line-height:1.15;margin-bottom:10px;}
84
- p.sec-p{font-size:15.5px;font-weight:500;color:var(--ink-soft);line-height:1.6;max-width:60ch;}
85
-
86
- /* ── S2 hero ── */
87
- .lead{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(18px,4vw,52px);align-items:center;padding:clamp(8px,2.5vw,26px) 0 clamp(30px,5vw,60px);}
88
- .eyebrow{font-family:var(--font-mono);font-size:13.5px;font-weight:500;color:var(--chrome-ink-dim);margin-bottom:18px;text-shadow:var(--chrome-glow);}
89
- .eyebrow .typed{color:var(--chrome-accent);font-weight:600;}
90
- .eyebrow .caret{display:inline-block;width:8px;color:var(--chrome-accent);animation:blink 1.05s step-end infinite;}
91
- @keyframes blink{50%{opacity:0;}}
92
- h1.big{font-family:var(--font-display);font-weight:700;font-size:clamp(33px,5.4vw,58px);line-height:1.05;letter-spacing:-1.3px;color:var(--chrome-ink);margin-bottom:18px;text-shadow:var(--chrome-glow);}
93
- .lead .lede{font-size:clamp(15.5px,1.85vw,18px);color:var(--hero-lede);max-width:50ch;margin-bottom:26px;line-height:1.58;text-shadow:var(--chrome-glow);font-weight:500;}
94
- .cta-row{display:flex;gap:12px;flex-wrap:wrap;align-items:center;}
95
- .btn.lg{font-size:16.5px;padding:14px 28px;}
96
-
97
- /* ── MASCOT OPTION A · the buddha ──
98
- The 44-frame idle loop that already exists on disk and has only ever been
99
- visible behind a 401. buddha.png is the poster + reduced-motion still. */
100
- .mascot{position:relative;}
101
- .mascot img{display:block;width:100%;height:auto;}
102
- body[data-mascot="bongos"] .mascot-buddha{display:none;}
103
- body:not([data-mascot="bongos"]) .mascot-bongos{display:none;}
104
-
105
- /* ── MASCOT OPTION B · the bongo pair ──
106
- The brand's OWN mark — the favicon is already two circles, big + small, with
107
- light heads (config/branding.neutral.json theme.ui.favicon) — made
108
- dimensional and given a beat. Every fill is a token, so unlike buddha.png it
109
- RE-THEMES with the palette instead of being a baked illustration. It is also
110
- ~3KB of inline SVG against 1.3MB of webp frames.
111
- The head is SKIN: it takes its own tokens and must never inherit --bg-card,
112
- or it turns black in dark mode. */
113
- :root{--skin-hi:#fffdf8;--skin-mid:#fff6e9;--skin-lo:#e8d3b6;}
114
- :root[data-mode="dark"]{--skin-hi:#fdf7ea;--skin-mid:#efe1c8;--skin-lo:#c3ae90;}
115
- @media(prefers-color-scheme:dark){:root:not([data-mode="light"]){--skin-hi:#fdf7ea;--skin-mid:#efe1c8;--skin-lo:#c3ae90;}}
116
- .bongos{display:block;width:100%;height:auto;overflow:visible;}
117
- .bongos .glow {transform-box:fill-box;transform-origin:center;animation:glowPulse 1.6s ease-out infinite;}
118
- .bongos .bshadow{transform-box:fill-box;transform-origin:center;animation:shadowPulse 1.6s ease-out infinite;}
119
- .bongos .drumBig{transform-origin:150px 270px;animation:bobBig 1.6s ease-out infinite;}
120
- .bongos .drumSml{transform-origin:296px 270px;animation:bobSml 1.6s ease-out infinite;}
121
- .bongos .headBig{transform-origin:150px 118px;animation:hitBig 1.6s ease-out infinite;}
122
- .bongos .headSml{transform-origin:296px 134px;animation:hitSml 1.6s ease-out infinite;}
123
- .bongos .ring {transform-box:fill-box;transform-origin:center;opacity:0;animation:burst 1.6s ease-out infinite;}
124
- /* the beat — BIG on 0.0 and 0.8 · SMALL on 0.4, 1.0, 1.25 of a 1.6s loop */
125
- @keyframes hitBig{
126
- 0%{transform:translateY(5px) scaleY(.88);} 9%{transform:translateY(0) scaleY(1);}
127
- 50%{transform:translateY(0) scaleY(1);} 51%{transform:translateY(5px) scaleY(.88);}
128
- 60%,100%{transform:translateY(0) scaleY(1);}
129
- }
130
- @keyframes hitSml{
131
- 0%,24%{transform:translateY(0) scaleY(1);} 25.5%{transform:translateY(3.5px) scaleY(.88);}
132
- 34%,62%{transform:translateY(0) scaleY(1);} 63.5%{transform:translateY(3.5px) scaleY(.88);}
133
- 71%,77%{transform:translateY(0) scaleY(1);} 78.5%{transform:translateY(2.5px) scaleY(.91);}
134
- 87%,100%{transform:translateY(0) scaleY(1);}
135
- }
136
- @keyframes bobBig{
137
- 0%{transform:translateY(2px);} 11%,50%{transform:translateY(0);}
138
- 52%{transform:translateY(2px);} 63%,100%{transform:translateY(0);}
139
- }
140
- @keyframes bobSml{
141
- 0%,24%{transform:translateY(0);} 26%{transform:translateY(1.5px);}
142
- 36%,64%{transform:translateY(0);} 65%{transform:translateY(1.5px);}
143
- 74%,79%{transform:translateY(0);} 80%{transform:translateY(1.2px);}
144
- 89%,100%{transform:translateY(0);}
145
- }
146
- @keyframes burst{0%{transform:scale(.3);opacity:.85;}26%{opacity:0;}100%{transform:scale(1.18);opacity:0;}}
147
- @keyframes glowPulse{
148
- 0%{opacity:.85;transform:scale(1.035);} 16%{opacity:.42;transform:scale(1);}
149
- 50%{opacity:.72;transform:scale(1.025);} 66%,100%{opacity:.42;transform:scale(1);}
150
- }
151
- @keyframes shadowPulse{
152
- 0%{transform:scaleX(1.06);opacity:1;} 11%,50%{transform:scaleX(1);opacity:.78;}
153
- 53%{transform:scaleX(1.05);opacity:.95;} 64%,100%{transform:scaleX(1);opacity:.78;}
154
- }
155
- @media(prefers-reduced-motion:reduce){.bongos *{animation:none !important;}.bongos .ring{display:none;}}
156
-
157
- /* ── mock-only control rail ── */
158
- .rail{position:fixed;left:50%;transform:translateX(-50%);bottom:16px;z-index:40;
159
- display:flex;align-items:center;gap:14px;flex-wrap:wrap;justify-content:center;
160
- background:rgba(18,16,30,.86);backdrop-filter:blur(10px);
161
- border:1.5px solid rgba(255,255,255,.16);border-radius:999px;padding:9px 16px;
162
- box-shadow:0 18px 40px -16px rgba(0,0,0,.6);max-width:min(96vw,980px);}
163
- .rail b{font-family:var(--font-mono);font-size:10.5px;font-weight:500;letter-spacing:.6px;
164
- text-transform:uppercase;color:rgba(255,255,255,.5);}
165
- .rail .grp{display:flex;gap:6px;align-items:center;flex-wrap:wrap;}
166
- .sw{display:flex;align-items:center;gap:7px;cursor:pointer;border-radius:999px;
167
- border:1.5px solid transparent;background:rgba(255,255,255,.07);color:#fff;
168
- font-family:var(--font-body);font-weight:700;font-size:12px;padding:5px 11px 5px 6px;}
169
- .sw:hover{background:rgba(255,255,255,.14);}
170
- .sw[aria-pressed="true"]{border-color:#fff;background:rgba(255,255,255,.2);}
171
- .sw i{width:15px;height:15px;border-radius:50%;display:block;
172
- box-shadow:0 0 0 1.5px rgba(255,255,255,.3) inset;}
173
- .rail .divider{width:1px;height:22px;background:rgba(255,255,255,.18);}
174
- .mascot::before{content:"";position:absolute;inset:-8% -12%;z-index:-1;border-radius:50%;
175
- background:radial-gradient(ellipse at center,rgba(255,255,255,.95) 0%,rgba(255,255,255,.7) 45%,rgba(255,255,255,0) 72%);}
176
- :root[data-mode="dark"] .mascot::before{background:radial-gradient(ellipse at center,rgba(255,217,138,.22) 0%,rgba(251,146,60,.10) 46%,rgba(255,255,255,0) 72%);}
177
- @media(prefers-color-scheme:dark){:root:not([data-mode="light"]) .mascot::before{background:radial-gradient(ellipse at center,rgba(255,217,138,.22) 0%,rgba(251,146,60,.10) 46%,rgba(255,255,255,0) 72%);}}
178
-
179
- /* ── S3 the mechanism ── */
180
- .beats{display:grid;grid-template-columns:repeat(auto-fit,minmax(238px,1fr));gap:clamp(15px,2.2vw,22px);}
181
- .beat{background:var(--card);border-radius:22px;box-shadow:var(--shadow-card);padding:clamp(19px,2.5vw,26px);}
182
- .beatNum{font-family:var(--font-mono);font-size:12px;font-weight:500;color:var(--accent);letter-spacing:1.3px;text-transform:uppercase;margin-bottom:11px;}
183
- .beat h3{font-family:var(--font-display);font-weight:700;font-size:17.5px;letter-spacing:-.3px;margin-bottom:8px;line-height:1.25;}
184
- .beat p{font-size:14.5px;font-weight:500;color:var(--ink-soft);line-height:1.58;}
185
-
186
- /* ── S4 lifecycle: this is cosmos.css's .strip, unmodified, doing marketing
187
- work. The point is that the landing page and the working page share a
188
- component rather than resembling each other. ── */
189
- .railWrap{background:var(--card);border-radius:24px;box-shadow:var(--shadow-card);padding:clamp(20px,3vw,30px) clamp(18px,3vw,30px) clamp(14px,2vw,20px);}
190
- .railWrap .strip{margin-top:18px;}
191
-
192
- /* ── S5 proof: the sky appears exactly ONCE in the warm page, as a full-bleed
193
- band. Real catalog names, and the same verification chips the hub uses. ── */
194
- .band{position:relative;z-index:1;background:linear-gradient(180deg,#080a1c 0%,#0d0f28 52%,#0a0c20 100%);
195
- padding:clamp(34px,5vw,58px) 0;margin-bottom:clamp(38px,6vw,78px);overflow:hidden;}
196
- .band::before{content:"";position:absolute;inset:0;pointer-events:none;
197
- background:radial-gradient(60% 90% at 22% 12%,rgba(43,36,86,.75) 0%,rgba(43,36,86,0) 62%),
198
- radial-gradient(50% 80% at 82% 88%,rgba(251,146,60,.16) 0%,rgba(251,146,60,0) 60%);}
199
- .band .wrap{position:relative;z-index:1;}
200
- .band h2.sec-h,.bandSub{color:#fff6e6;}
201
- .bandSub{font-size:14.5px;font-weight:600;color:rgba(255,246,230,.62);margin-bottom:22px;}
202
- .bandHead{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;flex-wrap:wrap;}
203
- .bandHead .linklike{color:var(--gold);}
204
- .conGrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));gap:13px;}
205
- .conItem{display:flex;gap:13px;align-items:center;text-decoration:none;color:inherit;
206
- border:1.5px solid rgba(255,217,138,.22);border-radius:16px;padding:13px 15px;
207
- background:rgba(13,15,40,.55);backdrop-filter:blur(6px);transition:transform .14s ease,border-color .14s ease;}
208
- .conItem:hover{transform:translateY(-2px);border-color:rgba(255,217,138,.5);}
209
- .conItem .orb{flex:0 0 38px;width:38px;height:38px;cursor:inherit;}
210
- .conName{font-family:var(--font-display);font-weight:700;font-size:15.5px;letter-spacing:-.2px;line-height:1.2;color:#fff6e6;display:block;}
211
- .conTag{font-size:12.5px;font-weight:600;color:rgba(255,246,230,.58);margin-top:3px;line-height:1.35;display:block;}
212
- .conItem .chip{margin-top:8px;white-space:nowrap;}
213
-
214
- /* ── S6/S7 ── */
215
- .own{background:var(--card);border-radius:24px;box-shadow:var(--shadow-card);padding:clamp(22px,3.2vw,34px);}
216
- .doors{display:grid;grid-template-columns:1fr 1fr;gap:clamp(15px,2.2vw,22px);}
217
- .door{background:var(--card);border-radius:22px;box-shadow:var(--shadow-card);padding:clamp(20px,2.8vw,28px);display:flex;flex-direction:column;gap:10px;align-items:flex-start;}
218
- .door h3{font-family:var(--font-display);font-weight:700;font-size:18px;letter-spacing:-.3px;}
219
- .door p{font-size:14.5px;font-weight:500;color:var(--ink-soft);line-height:1.55;flex:1;}
220
-
221
- /* mock affordance: outline the blocks that are NOT true on a child instance */
222
- .showScope [data-apex-only]{outline:2px dashed color-mix(in srgb,var(--sea) 65%,transparent);outline-offset:9px;}
223
- .showScope [data-apex-only]{position:relative;}
224
- .showScope [data-apex-only]::after{content:"apex-only";position:absolute;top:-11px;left:16px;
225
- font-family:var(--font-mono);font-size:10.5px;font-weight:500;letter-spacing:.5px;
226
- color:var(--sea);background:var(--page-bg);padding:0 7px;border-radius:4px;z-index:3;}
227
- .showScope .band[data-apex-only]::after{background:#080a1c;}
228
-
229
- /* mock affordance: preview the CHILD-INSTANCE shape — what a project like
230
- spike-harbor.cloudbongos.com renders from this same file once the server
231
- conditional is in (owner decision, 2026-08-13). */
232
- .childView [data-apex-only]{display:none;}
233
- .childBanner{display:none;position:sticky;top:0;z-index:5;text-align:center;
234
- font-family:var(--font-mono);font-size:12px;font-weight:500;letter-spacing:.3px;
235
- color:#fff;background:var(--sea);padding:7px 14px;}
236
- .childView .childBanner{display:block;}
237
-
238
- @media(max-width:900px){
239
- .lead{grid-template-columns:1fr;text-align:center;}
240
- .lead .lede{margin-left:auto;margin-right:auto;}
241
- .cta-row{justify-content:center;}
242
- .mascot{max-width:330px;margin:0 auto;order:-1;}
243
- .doors{grid-template-columns:1fr;}
244
- }
245
- @media(prefers-reduced-motion:reduce){.eyebrow .caret{animation:none;}}
246
- </style>
247
- </head>
248
- <body>
249
-
250
- <div class="childBanner">child-instance shape — what spike-harbor.cloudbongos.com renders from this same file · press C to return to the apex</div>
251
-
252
- <!-- ══ MOCK-ONLY CONTROL RAIL — not part of the design ══════════════════════
253
- Each palette is what a branding pack does to the cosmos.css contract tier.
254
- On a real instance exactly ONE exists, injected by themeMarkup().
255
- ═══════════════════════════════════════════════════════════════════════ -->
256
- <div class="rail" id="rail">
257
- <div class="grp"><b>palette</b><span id="schemeBtns" class="grp"></span></div>
258
- <span class="divider"></span>
259
- <div class="grp"><b>hero</b>
260
- <button class="sw" data-mascot-btn="buddha" aria-pressed="true">buddha</button>
261
- <button class="sw" data-mascot-btn="bongos" aria-pressed="false">bongos</button>
262
- </div>
263
- </div>
264
-
265
- <div class="sky" aria-hidden="true">
266
- <span class="star" style="top:3%;left:11%;width:2px;height:2px;"></span>
267
- <span class="star" style="top:6%;left:27%;width:1.5px;height:1.5px;animation-delay:.7s;"></span>
268
- <span class="star" style="top:4%;left:44%;width:2px;height:2px;animation-delay:1.4s;"></span>
269
- <span class="star" style="top:9%;left:61%;width:1.5px;height:1.5px;animation-delay:.3s;"></span>
270
- <span class="star" style="top:5%;left:79%;width:2.5px;height:2.5px;animation-delay:2s;"></span>
271
- <span class="star" style="top:12%;left:90%;width:1.5px;height:1.5px;animation-delay:1s;"></span>
272
- <span class="star" style="top:16%;left:19%;width:1.5px;height:1.5px;animation-delay:1.8s;"></span>
273
- <span class="star" style="top:24%;left:54%;width:2px;height:2px;animation-delay:.5s;"></span>
274
- <span class="star" style="top:31%;left:35%;width:1.5px;height:1.5px;animation-delay:2.4s;"></span>
275
- <span class="star" style="top:28%;left:77%;width:1.5px;height:1.5px;animation-delay:1.2s;"></span>
276
- <span class="star" style="top:46%;left:7%;width:2px;height:2px;animation-delay:.9s;"></span>
277
- <span class="star" style="top:53%;left:92%;width:1.5px;height:1.5px;animation-delay:1.6s;"></span>
278
- <span class="star" style="top:66%;left:23%;width:1.5px;height:1.5px;animation-delay:2.1s;"></span>
279
- <span class="star" style="top:74%;left:66%;width:2px;height:2px;animation-delay:.4s;"></span>
280
- <span class="star" style="top:86%;left:41%;width:1.5px;height:1.5px;animation-delay:1.9s;"></span>
281
- <span class="star" style="top:93%;left:81%;width:2px;height:2px;animation-delay:.8s;"></span>
282
- </div>
283
-
284
- <!-- ══ S1 · HEADER ══════════════════════════════════════════════════════════
285
- THE DOOR. Its absence is what blocks the apex flip (task 1002743 part 3):
286
- today the shared index.html links only to the Hall. #who is not optional —
287
- tests/platform_boot.mjs:120 asserts /id="who"/ on the apex landing, and that
288
- test must be unparked in the same change that makes it pass (C28).
289
- ═══════════════════════════════════════════════════════════════════════ -->
290
- <header class="top">
291
- <a class="mark" href="/">cloud <span>bongos</span></a>
292
- <div class="top-right">
293
- <a class="btn-space" href="/projects">Projects</a>
294
- <!-- ⚠ C9 — a live bug this page inherits: [data-link-hall] never re-points,
295
- because clientBranding() does not project domains (src/branding.js:172-201).
296
- Every child instance currently sends its visitors to builders.cloudbongos.com.
297
- FIXED BY THE SAME DECISION as the social tags: landingPage() stamps the hall
298
- href server-side, where the origins already live. The branding contract keeps
299
- origins server-side deliberately, so this is the fix that respects it. -->
300
- <a class="btn-space" data-link-hall href="https://builders.cloudbongos.com">Hall</a>
301
- <button class="mode-toggle" id="mode" type="button" aria-label="Toggle light or dark">☾</button>
302
- <div class="who" id="who"></div>
303
- </div>
304
- </header>
305
-
306
- <div class="wrap">
307
- <div class="mockNote">
308
- <b>MOCK — task 1002747, goal 1000061 (apex UI pass).</b>
309
- The page that would answer <code>cloudbongos.com/</code> instead of today's 302 into the orb gate.
310
- Structure is fixed by <code>front-door-and-hub-direction.md</code>; this proposes the
311
- <b>look and the content spine</b>. Every word is live markup, not JS-built, so it survives a
312
- crawler and JS-off.
313
- <br><br>
314
- <b>Decided 2026-08-13:</b> the <b>bongo pair</b> is the hero (not the buddha) ·
315
- the palette is <b>ember marigold</b> · ONE file with a server-side apex conditional ·
316
- <code>landingPage()</code> stamps the social tags server-side.
317
- <br>
318
- Toggle <b>☾/☀</b> — both modes are real ·
319
- <kbd>S</kbd> outlines the apex-only blocks ·
320
- <kbd>C</kbd> previews <b>exactly what a child instance renders</b> (the portable half) ·
321
- the palette rail is the record of what was considered.
322
- </div>
323
- </div>
324
-
325
- <!-- ══ S2 · HERO ═══════════════════════════════════════════════════════════ -->
326
- <div class="wrap">
327
- <section class="lead">
328
- <div>
329
- <p class="eyebrow">type <span class="typed" id="typed">bongos</span><span class="caret">▌</span> in any AI</p>
330
- <h1 class="big" data-brand-tagline>Building software is laying&nbsp;down a beat.</h1>
331
- <!-- verbatim from space.js:34 — already public-facing copy, not newly invented -->
332
- <p class="lede">AI agents claim tasks and ship the code; you set the direction and the gates.</p>
333
- <div class="cta-row">
334
- <a class="btn lg" href="/projects?view=new">Start a project</a>
335
- <!-- apex-only: on a child instance there is no catalog to look at, and
336
- /projects there means "this instance's own provisioning rows". The
337
- child shape keeps the single primary CTA. -->
338
- <a class="btn ghost lg" href="/projects" data-apex-only>See what's building</a>
339
- </div>
340
- </div>
341
- <div class="mascot">
342
- <img class="mascot-buddha" id="buddha" src="../../../modules/public-landing/public/buddha.png"
343
- alt="A laughing Cloud Bongos buddha playing the bongos on a cloud">
344
-
345
- <svg class="mascot-bongos bongos" viewBox="0 0 440 320" role="img"
346
- aria-label="A pair of bongo drums being played">
347
- <defs>
348
- <linearGradient id="shellBig" x1="0" y1="0" x2="1" y2="0.35">
349
- <stop offset="0%" stop-color="var(--accent-deep)"/><stop offset="16%" stop-color="var(--accent)"/>
350
- <stop offset="48%" stop-color="var(--accent)"/><stop offset="86%" stop-color="var(--accent-deep)"/>
351
- <stop offset="100%" stop-color="var(--accent-deep)"/>
352
- </linearGradient>
353
- <linearGradient id="shellSml" x1="0" y1="0" x2="1" y2="0.35">
354
- <stop offset="0%" stop-color="var(--accent-deep)"/><stop offset="18%" stop-color="var(--terracotta)"/>
355
- <stop offset="55%" stop-color="var(--terracotta)"/><stop offset="100%" stop-color="var(--accent-deep)"/>
356
- </linearGradient>
357
- <radialGradient id="skin" cx="0.36" cy="0.26" r="0.9">
358
- <stop offset="0%" stop-color="var(--skin-hi)"/><stop offset="58%" stop-color="var(--skin-mid)"/>
359
- <stop offset="100%" stop-color="var(--skin-lo)"/>
360
- </radialGradient>
361
- <radialGradient id="halo" cx="0.5" cy="0.5" r="0.5">
362
- <stop offset="0%" stop-color="var(--accent)" stop-opacity="0.30"/>
363
- <stop offset="48%" stop-color="var(--accent)" stop-opacity="0.13"/>
364
- <stop offset="100%" stop-color="var(--accent)" stop-opacity="0"/>
365
- </radialGradient>
366
- <filter id="soft" x="-60%" y="-160%" width="220%" height="420%">
367
- <feGaussianBlur stdDeviation="9"/>
368
- </filter>
369
- </defs>
370
-
371
- <ellipse class="glow" cx="222" cy="170" rx="215" ry="140" fill="url(#halo)"/>
372
- <ellipse class="bshadow" cx="220" cy="286" rx="142" ry="14"
373
- fill="var(--ink)" opacity=".22" filter="url(#soft)"/>
374
-
375
- <!-- the joining block, behind both shells -->
376
- <path d="M 214,196 C 232,188 250,188 264,196 L 258,232 C 244,225 230,225 219,232 Z" fill="var(--accent-deep)"/>
377
- <path d="M 214,196 C 232,188 250,188 264,196 L 262,205 C 247,197 231,197 216,205 Z" fill="var(--ink)" opacity=".22"/>
378
-
379
- <g class="drumBig">
380
- <path d="M 74,118 C 76,166 90,228 98,266 A 52,17 0 0 0 202,266 C 210,228 224,166 226,118 Z" fill="url(#shellBig)"/>
381
- <path d="M 172,124 C 174,176 186,232 192,268 A 52,17 0 0 0 202,266 C 210,228 224,166 226,118 Z" fill="var(--ink)" opacity=".17"/>
382
- <path d="M 92,126 C 94,174 104,230 110,266 A 52,17 0 0 1 100,267 C 92,230 78,172 76,124 Z" fill="#fff" opacity=".20"/>
383
- <ellipse cx="150" cy="121" rx="80" ry="29" fill="var(--accent-deep)"/>
384
- <ellipse cx="150" cy="117" rx="80" ry="29" fill="var(--accent)"/>
385
- <ellipse cx="150" cy="117" rx="80" ry="29" fill="#fff" opacity=".13"/>
386
- <g class="headBig">
387
- <ellipse cx="150" cy="118" rx="70" ry="24" fill="url(#skin)"/>
388
- <ellipse cx="150" cy="118" rx="70" ry="24" fill="none" stroke="var(--ink)" stroke-opacity=".09" stroke-width="1.4"/>
389
- <ellipse cx="150" cy="118" rx="55" ry="18" fill="none" stroke="var(--ink)" stroke-opacity=".045" stroke-width="1"/>
390
- <ellipse class="ring" cx="150" cy="118" rx="56" ry="19" fill="none" stroke="var(--accent-deep)" stroke-width="2.6" style="animation-delay:0s"/>
391
- <ellipse class="ring" cx="150" cy="118" rx="56" ry="19" fill="none" stroke="var(--accent-deep)" stroke-width="2.6" style="animation-delay:.8s"/>
392
- </g>
393
- <g fill="var(--accent-deep)">
394
- <path d="M 78,138 l 9,0 -1.5,20 -6,0 z"/><path d="M 120,148 l 9,0 -1,21 -7,0 z"/>
395
- <path d="M 172,148 l 9,0 -1,21 -7,0 z"/><path d="M 214,138 l 9,0 -1.5,20 -6,0 z"/>
396
- </g>
397
- </g>
398
-
399
- <g class="drumSml">
400
- <path d="M 240,134 C 242,178 252,230 258,266 A 40,13 0 0 0 338,266 C 344,230 354,178 356,134 Z" fill="url(#shellSml)"/>
401
- <path d="M 314,140 C 316,186 324,234 328,268 A 40,13 0 0 0 338,266 C 344,230 354,178 356,134 Z" fill="var(--ink)" opacity=".19"/>
402
- <path d="M 254,140 C 256,182 264,232 268,266 A 40,13 0 0 1 260,267 C 254,232 244,182 242,138 Z" fill="#fff" opacity=".17"/>
403
- <ellipse cx="296" cy="137" rx="60" ry="22" fill="var(--accent-deep)"/>
404
- <ellipse cx="296" cy="133" rx="60" ry="22" fill="var(--terracotta)"/>
405
- <ellipse cx="296" cy="133" rx="60" ry="22" fill="#fff" opacity=".13"/>
406
- <g class="headSml">
407
- <ellipse cx="296" cy="134" rx="51" ry="18" fill="url(#skin)"/>
408
- <ellipse cx="296" cy="134" rx="51" ry="18" fill="none" stroke="var(--ink)" stroke-opacity=".09" stroke-width="1.4"/>
409
- <ellipse cx="296" cy="134" rx="39" ry="13" fill="none" stroke="var(--ink)" stroke-opacity=".045" stroke-width="1"/>
410
- <ellipse class="ring" cx="296" cy="134" rx="41" ry="14" fill="none" stroke="var(--accent-deep)" stroke-width="2.3" style="animation-delay:.4s"/>
411
- <ellipse class="ring" cx="296" cy="134" rx="41" ry="14" fill="none" stroke="var(--accent-deep)" stroke-width="2.3" style="animation-delay:1s"/>
412
- <ellipse class="ring" cx="296" cy="134" rx="41" ry="14" fill="none" stroke="var(--accent-deep)" stroke-width="2.3" style="animation-delay:1.25s"/>
413
- </g>
414
- <g fill="var(--accent-deep)">
415
- <path d="M 243,152 l 8,0 -1,17 -6,0 z"/><path d="M 276,160 l 8,0 -1,18 -6,0 z"/>
416
- <path d="M 312,160 l 8,0 -1,18 -6,0 z"/><path d="M 345,152 l 8,0 -1,17 -6,0 z"/>
417
- </g>
418
- </g>
419
- </svg>
420
- </div>
421
- </section>
422
- </div>
423
-
424
- <!-- ══ S3 · THE MECHANISM ══════════════════════════════════════════════════
425
- "AI writes code" is a crowded claim and not the differentiator. What is
426
- actually enforced — a ledger, a server-checked ladder, an adversarial
427
- grade — is. All three are portable: a child instance inherits them.
428
- ═══════════════════════════════════════════════════════════════════════ -->
429
- <div class="wrap">
430
- <section class="sec beats">
431
- <div class="beat">
432
- <div class="beatNum">the ledger</div>
433
- <h3>Every change is a claimed task</h3>
434
- <p>No admin loophole, no tiny-fix loophole. If work happened, there is a row that says who did
435
- it, what it cost, and why. The ledger is complete or it lies.</p>
436
- </div>
437
- <div class="beat">
438
- <div class="beatNum">the gates</div>
439
- <h3>A rank ladder the server enforces</h3>
440
- <p>Authority lives in the database, checked per request, never cached. An agent editing its own
441
- instructions grants itself nothing.</p>
442
- </div>
443
- <div class="beat">
444
- <div class="beatNum">the grade</div>
445
- <h3>Nothing ships ungraded</h3>
446
- <p>An adversarial panel reads the real committed diff before work lands — not the summary the
447
- agent wrote about itself.</p>
448
- </div>
449
- </section>
450
- </div>
451
-
452
- <!-- ══ S4 · THE LIFECYCLE ══════════════════════════════════════════════════
453
- cosmos.css's .strip, unmodified. Marketing page and working page share the
454
- component instead of merely resembling each other.
455
- ═══════════════════════════════════════════════════════════════════════ -->
456
- <div class="wrap">
457
- <section class="sec railWrap">
458
- <h2 class="sec-h">How a change reaches your project</h2>
459
- <p class="sec-p">The same five beats every task moves through — the ones you'll watch on your own
460
- projects page.</p>
461
- <div class="strip isLive" role="img" aria-label="claim, build, grade, ship, credit">
462
- <ul class="stages">
463
- <li class="done"><span class="sdot"></span><span class="slbl">claim</span></li>
464
- <li class="done"><span class="sdot"></span><span class="slbl">build</span></li>
465
- <li class="done"><span class="sdot"></span><span class="slbl">grade</span></li>
466
- <li class="done"><span class="sdot"></span><span class="slbl">ship</span></li>
467
- <li class="now"><span class="sdot"></span><span class="slbl">credit</span></li>
468
- </ul>
469
- <div class="pnote">Locked to one agent · built in its own worktree · read by a panel · merged and
470
- verified live · paid only once it lands.</div>
471
- </div>
472
- </section>
473
- </div>
474
-
475
- <!-- ══ S5 · LIVING PROOF ═══════════════════════════════════════════════════
476
- The sky appears exactly ONCE in the warm page, as a band — so the catalog
477
- reads as a window into the hub rather than as wallpaper.
478
- Names come from GET /api/bongos/projects/featured (four columns, public,
479
- cannot vary by viewer — C26). The chips are the SAME verification vocabulary
480
- the hub uses (C25), which is itself part of the argument.
481
- THE WHOLE BAND SELF-HIDES on a non-200 or empty feed — that self-hiding is
482
- what makes an apex-only block safe in a file every instance ships.
483
- ═══════════════════════════════════════════════════════════════════════ -->
484
- <section class="band" data-apex-only>
485
- <div class="wrap">
486
- <div class="bandHead">
487
- <div>
488
- <h2 class="sec-h">Built on Cloud Bongos</h2>
489
- <p class="bandSub">Real projects, standing up right now.</p>
490
- </div>
491
- <a class="linklike" href="/projects">Open the map →</a>
492
- </div>
493
- <div class="conGrid">
494
- <a class="conItem" href="#">
495
- <span class="orb" style="--acc:#f97316;--glow:rgba(249,115,22,.5);"></span>
496
- <span>
497
- <span class="conName">Cloud Bongos</span>
498
- <span class="conTag">The platform, building itself.</span>
499
- <span class="chip live"><span class="cdot"></span>live<span class="rec">· checked 2m ago</span></span>
500
- </span>
501
- </a>
502
- <a class="conItem" href="#">
503
- <span class="orb" style="--acc:#38bdf8;--glow:rgba(56,189,248,.5);"></span>
504
- <span>
505
- <span class="conName">Emersonian Circles</span>
506
- <span class="conTag">Reading circles that convene themselves.</span>
507
- <span class="chip live"><span class="cdot"></span>live<span class="rec">· checked 4m ago</span></span>
508
- </span>
509
- </a>
510
- <a class="conItem" href="#">
511
- <span class="orb dim" style="--acc:#fb7185;"></span>
512
- <span>
513
- <span class="conName">Off the Boats</span>
514
- <span class="conTag">An island the settlers build.</span>
515
- <span class="chip maybe"><span class="cdot"></span>live?<span class="rec">· last seen 3h ago</span></span>
516
- </span>
517
- </a>
518
- </div>
519
- </div>
520
- </section>
521
-
522
- <!-- ══ S6 · WHAT YOU OWN ═══════════════════════════════════════════════════
523
- Copy verbatim from create.html:391 — already owner-approved and already
524
- public-facing. "Capture-resistant" is the product's own load-bearing word.
525
- ═══════════════════════════════════════════════════════════════════════ -->
526
- <div class="wrap">
527
- <section class="sec own" data-apex-only>
528
- <h2 class="sec-h">What you own</h2>
529
- <p class="sec-p" style="margin-bottom:18px;">Free while we find our feet. Your project's repo and
530
- server are yours — Cloud Bongos is
531
- <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank" rel="noopener">open source
532
- (AGPL-3.0)</a> and capture-resistant by design. Run the whole thing on your own box and owe us
533
- nothing; the hosted version is a convenience, not a lock.</p>
534
- <a class="btn ghost" href="https://github.com/lars589/cloud-bongos" target="_blank" rel="noopener">Read the source →</a>
535
- </section>
536
- </div>
537
-
538
- <!-- ══ S7 · TWO DOORS ══════════════════════════════════════════════════════
539
- The hero can only lead one of the two arrivals. This is the second chance
540
- for whichever one it didn't serve.
541
- ═══════════════════════════════════════════════════════════════════════ -->
542
- <div class="wrap">
543
- <section class="sec doors">
544
- <div class="door">
545
- <h3>Build a project</h3>
546
- <p>Say what you want to exist. Agents take it from there, and you hold every gate that matters.</p>
547
- <a class="btn" href="/projects?view=new">Start a project</a>
548
- </div>
549
- <div class="door">
550
- <h3>Join as a builder</h3>
551
- <p>Claim tasks, ship code, earn credits. The hall is where the work is, and newcomers start
552
- with a real task on day one.</p>
553
- <a class="btn ghost" data-link-hall href="https://builders.cloudbongos.com">Enter the Hall →</a>
554
- </div>
555
- </section>
556
- </div>
557
-
558
- <!-- The footer line splits. "A non-profit, capture-resistant commons" is a claim
559
- about Cloud Bongos the platform and is FALSE on a child instance — today's
560
- index.html:104 ships it to every instance regardless. The attribution half is
561
- portable and is the half a child should carry. -->
562
- <div class="foot"><span data-apex-only>A non-profit, capture-resistant commons. </span>Built by agents, on Cloud&nbsp;Bongos.</div>
563
-
564
- <script>
565
- /* Mock-only chrome. The real page keeps the existing data-brand-* fill
566
- (index.html:106-120) — nothing here replaces it. */
567
- (function(){
568
- var root=document.documentElement, btn=document.getElementById('mode');
569
- function isDark(){
570
- return root.getAttribute('data-mode')==='dark' ||
571
- (!root.getAttribute('data-mode') && matchMedia('(prefers-color-scheme:dark)').matches);
572
- }
573
- function paint(){ btn.textContent = isDark() ? '☀' : '☾'; }
574
- btn.addEventListener('click',function(){
575
- var next = isDark() ? 'light' : 'dark';
576
- root.setAttribute('data-mode',next);
577
- try{localStorage.setItem('cb-color-mode',next);}catch(e){}
578
- paint();
579
- });
580
- paint();
581
-
582
- /* Mock only: a stand-in for the signed-in identity chip, so #who is visible
583
- in review. The real page fills it from /api/bongos/me exactly as
584
- projects.html:57 does — and the hero CTA resolves off the same call
585
- (signed out → Start a project; ≥1 instance → Your projects). */
586
- document.getElementById('who').innerHTML =
587
- '<img src="https://avatars.githubusercontent.com/u/64553469?v=4" alt="" width="26" height="26" style="border-radius:50%;box-shadow:var(--ava-shadow)"> jaxri';
588
-
589
- /* The self-typing metaphor — the idea space.js:1477 already carries, moved to
590
- the front door. DECORATION over real text: the markup says "bongos" and
591
- stays correct with scripting off or motion reduced. */
592
- var reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
593
- if(!reduce){
594
- var el=document.getElementById('typed'), words=['claude','gemini','chatgpt','bongos'], w=0;
595
- (function cycle(){
596
- var word=words[w++%words.length], i=0;
597
- el.textContent='';
598
- (function type(){
599
- if(i<=word.length){ el.textContent=word.slice(0,i++); setTimeout(type,72); }
600
- else setTimeout(function erase(){
601
- if(el.textContent.length){ el.textContent=el.textContent.slice(0,-1); setTimeout(erase,38); }
602
- else cycle();
603
- }, word==='bongos' ? 2100 : 900);
604
- })();
605
- })();
606
- }
607
-
608
- /* The 44-frame idle loop — public-landing/assets/anim/idle/frame_00-43.webp.
609
- Same 12fps rAF shape as mountBuddha() at space.js:1441-1470, which holds
610
- frame 0 under reduced motion. This asset is finished and tested and has
611
- only ever been visible behind a 401. buddha.png stays the poster so the
612
- hero is never blank while frames load. */
613
- if(!reduce){
614
- var img=document.getElementById('buddha'), FR=44, base='../../../modules/public-landing/public/assets/anim/idle/frame_';
615
- var srcs=[], loaded=0;
616
- for(var i=0;i<FR;i++){
617
- var p=new Image();
618
- p.onload=function(){ if(++loaded===FR) run(); };
619
- p.onerror=function(){ loaded=-999; }; /* missing frames → keep the still */
620
- p.src = base + String(i).padStart(2,'0') + '.webp';
621
- srcs.push(p.src);
622
- }
623
- function run(){
624
- var f=0, last=0;
625
- (function tick(t){
626
- if(t-last>83){ img.src=srcs[f=(f+1)%FR]; last=t; }
627
- requestAnimationFrame(tick);
628
- })(0);
629
- }
630
- }
631
-
632
- /* ── mock-only: palette + hero switcher ── */
633
- var SCHEMES=[
634
- {key:'', name:'shipped', sw:'#f97316'},
635
- {key:'ember-marigold', name:'marigold',sw:'#ce4806'},
636
- {key:'adobe-clay', name:'clay', sw:'#b8492c'},
637
- {key:'letterpress', name:'press', sw:'#C22A12'},
638
- {key:'deep-water', name:'water', sw:'#0d7f97'},
639
- {key:'sapwood', name:'sapwood', sw:'#3d7a33'},
640
- {key:'plumfield', name:'plum', sw:'#932bcf'}
641
- ];
642
- var host=document.getElementById('schemeBtns');
643
- var cur=root.getAttribute('data-scheme')||'';
644
- SCHEMES.forEach(function(s){
645
- var b=document.createElement('button');
646
- b.className='sw'; b.type='button';
647
- b.setAttribute('aria-pressed', String(s.key===cur));
648
- b.innerHTML='<i style="background:'+s.sw+'"></i>'+s.name;
649
- b.addEventListener('click',function(){
650
- if(s.key) root.setAttribute('data-scheme',s.key); else root.removeAttribute('data-scheme');
651
- try{localStorage.setItem('cb-mock-scheme',s.key);}catch(e){}
652
- host.querySelectorAll('.sw').forEach(function(x){x.setAttribute('aria-pressed','false');});
653
- b.setAttribute('aria-pressed','true');
654
- });
655
- host.appendChild(b);
656
- });
657
-
658
- var Q=new URLSearchParams(location.search);
659
- if(Q.get('rail')==='0'){
660
- document.getElementById('rail').style.display='none';
661
- document.querySelectorAll('.mockNote').forEach(function(n){n.style.display='none';});
662
- }
663
- var savedMascot='buddha';
664
- try{savedMascot=Q.get('mascot')||localStorage.getItem('cb-mock-mascot')||'buddha';}catch(e){savedMascot=Q.get('mascot')||'buddha';}
665
- function setMascot(m){
666
- document.body.setAttribute('data-mascot',m);
667
- try{localStorage.setItem('cb-mock-mascot',m);}catch(e){}
668
- document.querySelectorAll('[data-mascot-btn]').forEach(function(x){
669
- x.setAttribute('aria-pressed', String(x.getAttribute('data-mascot-btn')===m));
670
- });
671
- }
672
- document.querySelectorAll('[data-mascot-btn]').forEach(function(x){
673
- x.addEventListener('click',function(){ setMascot(x.getAttribute('data-mascot-btn')); });
674
- });
675
- setMascot(savedMascot);
676
-
677
- /* S outlines the apex-only blocks; C previews the child-instance shape.
678
- Mock affordances only — on the real page the server decides, not a keypress. */
679
- addEventListener('keydown',function(e){
680
- if(/^(INPUT|TEXTAREA)$/.test(document.activeElement.tagName)) return;
681
- if(e.key==='s'||e.key==='S') document.body.classList.toggle('showScope');
682
- if(e.key==='c'||e.key==='C') document.body.classList.toggle('childView');
683
- });
684
- })();
685
- </script>
686
- </body>
687
- </html>