@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,1177 +0,0 @@
1
- <!doctype html>
2
- <html lang="en" data-mode="dark" data-theme="dark">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width,initial-scale=1">
6
- <title>Reading room, the hall in the world: v2 "the sheet" (task 1003302)</title>
7
- <link rel="icon" href="data:,">
8
- <link rel="preconnect" href="https://fonts.googleapis.com">
9
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400&family=Manrope:wght@300;400;500;600&display=swap">
11
- <link rel="stylesheet" href="../_tokens.css">
12
- <style>
13
- /* ---------------------------------------------------------------------------
14
- READING ROOM, v2 "the sheet". The article is a document: a --bg-card sheet
15
- with a --rule-soft hairline edge and --radius-sm corners, set on the --bg
16
- ground, with the table of contents and the acknowledge gate as two more
17
- sheets beside and below it. No shadow anywhere: a sheet is separated from the
18
- ground by tone and a hairline, never by lift. Sections are divided by air and
19
- a mono number rather than by a rule, because on a sheet the edge is already
20
- doing the dividing. Composition tokens live on body; colours come from
21
- ../_tokens.css.
22
- --------------------------------------------------------------------------- */
23
-
24
- *, *::before, *::after { box-sizing: border-box; }
25
- html { -webkit-text-size-adjust: 100%; }
26
-
27
- body {
28
- /* ---- the composition tokens for v2 ---- */
29
- --gutter: 30px;
30
- --shell-pad: 20px;
31
- --toc-w: 250px;
32
- --col-gap: 26px;
33
- /* the measure is set in ch, but a `ch` is Manrope's ZERO, which is much wider
34
- than its average lowercase: 58ch measured 72 rendered characters. These are
35
- tuned against the rendered count, which is what the world's 56 to 62 means. */
36
- --measure: 48ch; /* the prose column: 59 rendered characters */
37
- --sheet-pad: clamp(22px, 3vw, 52px);
38
- --body-size: 17px;
39
- --body-lead: 1.7;
40
- --h1-size: clamp(32px, 4vw, 48px);
41
- --h2-size: clamp(24px, 2.3vw, 30px);
42
- --h3-size: 19px;
43
- /* the sheet declares its surfaces: this is the version that does */
44
- --art-bg: var(--bg-card);
45
- --art-edge: var(--rule-soft);
46
- --art-radius: var(--radius-sm);
47
- --well-bg: var(--bg);
48
- --well-edge: var(--rule-soft);
49
- --sidebar-bg: var(--bg-frame);
50
- --topbar-bg: var(--bg);
51
-
52
- margin: 0;
53
- min-height: 100dvh;
54
- display: grid;
55
- grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
56
- grid-template-rows: auto minmax(0, 1fr);
57
- background: var(--bg);
58
- color: var(--ink);
59
- font-family: var(--font-body);
60
- font-size: var(--body-size);
61
- line-height: var(--body-lead);
62
- -webkit-font-smoothing: antialiased;
63
- }
64
-
65
- /* ---------- shared atoms ---------- */
66
-
67
- .u-sr {
68
- position: absolute; width: 1px; height: 1px; margin: -1px;
69
- padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
70
- }
71
- .num { font-variant-numeric: tabular-nums; }
72
- .label {
73
- font: 400 var(--label-size)/1.25 var(--label-face);
74
- letter-spacing: var(--label-space);
75
- text-transform: var(--label-case);
76
- color: var(--ink-faint);
77
- }
78
- .nav-icon, .topbar-icon, .foot-icon {
79
- width: 16px; height: 16px; flex: none;
80
- fill: none; stroke: currentColor; stroke-width: 1.4;
81
- stroke-linecap: round; stroke-linejoin: round;
82
- }
83
-
84
- .skip {
85
- position: absolute; left: var(--sp-sm); top: -60px; z-index: 200;
86
- display: inline-flex; align-items: center; min-height: 34px;
87
- padding: 6px 18px; border-radius: var(--radius-pill);
88
- background: var(--bg-card); color: var(--ink);
89
- border: var(--line) solid var(--rule); text-decoration: none; font-size: 14px;
90
- transition: top 200ms cubic-bezier(.2, .7, .3, 1);
91
- }
92
- .skip:focus { top: var(--sp-xs); }
93
-
94
- /* ---------- the focus treatment ---------- */
95
-
96
- :focus-visible,
97
- body[data-state="focus"] .is-focus {
98
- outline: 2px solid var(--focus);
99
- outline-offset: 3px;
100
- box-shadow: 0 0 0 8px var(--bg);
101
- border-radius: 3px;
102
- }
103
-
104
- /* ---------- the sidebar: hall-1's grouped mono headings, and its pinned
105
- identity card at the foot ---------- */
106
-
107
- .app-sidebar {
108
- grid-column: 1; grid-row: 1 / 3;
109
- position: sticky; top: 0; height: 100dvh;
110
- display: flex; flex-direction: column; min-height: 0;
111
- overflow: hidden; /* the sidebar never scrolls: its nav does */
112
- background: var(--sidebar-bg);
113
- border-right: var(--line) solid var(--rule-soft);
114
- z-index: var(--z-sidebar);
115
- }
116
- .app-sidebar__brand {
117
- flex: none; height: var(--topbar-h);
118
- display: flex; align-items: center;
119
- padding: 0 var(--shell-pad);
120
- }
121
- .brand-mark {
122
- flex: 1 1 auto; min-width: 24px;
123
- display: flex; align-items: center; gap: 10px;
124
- min-height: 30px; padding: 3px 0;
125
- color: var(--ink); text-decoration: none;
126
- font-weight: 500; font-size: 15.5px; letter-spacing: -.015em;
127
- }
128
- .brand-mark__dot {
129
- width: 11px; height: 11px; flex: none;
130
- border: 2px solid var(--ink); border-radius: var(--radius-pill);
131
- }
132
- .brand-mark__name { white-space: nowrap; }
133
-
134
- .app-sidebar__nav {
135
- flex: 1 1 auto; min-height: 0; overflow-y: auto;
136
- padding: var(--sp-xs) 0 var(--sp-md);
137
- }
138
- .nav-group { padding: 0 var(--sp-xs) var(--sp-sm); }
139
- .nav-group__head {
140
- display: flex; align-items: center; justify-content: space-between;
141
- width: 100%; min-height: 28px; padding: 8px var(--sp-xs) 6px; margin: 0;
142
- background: none; border: 0; cursor: pointer;
143
- font: 400 var(--label-size)/1.25 var(--label-face);
144
- letter-spacing: var(--label-space); text-transform: var(--label-case);
145
- color: var(--ink-faint);
146
- }
147
- .nav-group__chevron {
148
- width: 10px; height: 6px; flex: none;
149
- fill: none; stroke: currentColor; stroke-width: 1.4;
150
- stroke-linecap: round; stroke-linejoin: round;
151
- }
152
- .nav-item {
153
- text-transform: lowercase;
154
- display: flex; align-items: center; gap: 11px;
155
- min-height: 34px; padding: 5px var(--sp-xs);
156
- border-radius: var(--radius-sm);
157
- border-left: 2px solid transparent;
158
- color: var(--ink-soft); text-decoration: none; font-size: 14.5px;
159
- transition: color 200ms cubic-bezier(.2, .7, .3, 1);
160
- }
161
- .nav-item:hover { color: var(--ink); }
162
- .nav-item__label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
163
- /* the current page is a sheet of its own inside the sidebar, lit on its left
164
- edge. The only accent in the sidebar. */
165
- .nav-item--active {
166
- color: var(--ink);
167
- background: var(--bg-card);
168
- border-left-color: var(--accent);
169
- border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
170
- }
171
-
172
- /* hall-1's pinned identity card */
173
- .app-sidebar__foot {
174
- flex: none; display: flex; align-items: center; gap: 4px;
175
- margin: var(--sp-xs) 8px var(--sp-sm);
176
- padding: 8px;
177
- background: var(--bg-card);
178
- border: var(--line) solid var(--rule-soft);
179
- border-radius: var(--radius-sm);
180
- }
181
- .shell-user {
182
- flex: 1 1 auto; min-width: 0;
183
- display: flex; align-items: center; gap: 10px;
184
- min-height: 36px; padding: 2px 0;
185
- color: var(--ink); text-decoration: none;
186
- }
187
- .shell-user__avatar {
188
- width: 30px; height: 30px; flex: none; border-radius: var(--radius-pill);
189
- background: color-mix(in srgb, var(--ink) 13%, var(--bg-card));
190
- border: var(--line) solid var(--rule-soft);
191
- }
192
- .shell-user__meta { display: flex; flex-direction: column; min-width: 0; }
193
- .shell-user__name {
194
- font-size: 13.5px; font-weight: 500;
195
- white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
196
- }
197
- .shell-user__rank {
198
- font: 400 var(--label-size)/1.35 var(--label-face);
199
- letter-spacing: var(--label-space); text-transform: var(--label-case);
200
- color: var(--ink-faint);
201
- }
202
- .shell-home, .shell-signout {
203
- flex: none; width: 26px; height: 26px;
204
- display: inline-flex; align-items: center; justify-content: center;
205
- color: var(--ink-faint); text-decoration: none;
206
- transition: color 200ms cubic-bezier(.2, .7, .3, 1);
207
- }
208
- .shell-home:hover, .shell-signout:hover { color: var(--ink); }
209
-
210
- .app-scrim { display: none; }
211
-
212
- /* ---------- the topbar ---------- */
213
-
214
- .app-topbar {
215
- grid-column: 2; grid-row: 1;
216
- position: sticky; top: 0; z-index: var(--z-topbar);
217
- height: var(--topbar-h);
218
- display: flex; align-items: center; gap: var(--sp-sm);
219
- padding: 0 var(--gutter);
220
- background: var(--topbar-bg);
221
- border-bottom: var(--line) solid var(--rule-soft);
222
- }
223
- .topbar-menu {
224
- display: none; width: 32px; height: 32px; margin-left: -6px;
225
- align-items: center; justify-content: center;
226
- background: none; border: 0; color: var(--ink-soft); cursor: pointer;
227
- }
228
- .topbar-title {
229
- margin: 0;
230
- font-family: var(--font-display); font-weight: 300;
231
- font-size: 20px; letter-spacing: -.03em; color: var(--ink);
232
- }
233
- .topbar-side { margin-left: auto; display: flex; align-items: center; gap: var(--sp-xs); }
234
- .topbar-note {
235
- font: 400 var(--label-size)/1.25 var(--label-face);
236
- letter-spacing: var(--label-space); text-transform: var(--label-case);
237
- color: var(--ink-faint); white-space: nowrap;
238
- }
239
- .topbar-jump {
240
- display: inline-flex; align-items: center; gap: 9px;
241
- min-height: 32px; padding: 0 12px;
242
- background: var(--bg-card); border: var(--line) solid var(--rule-soft);
243
- border-radius: var(--radius-pill);
244
- color: var(--ink-soft); font-family: var(--font-body); font-size: 13px;
245
- cursor: pointer;
246
- transition: color 200ms cubic-bezier(.2, .7, .3, 1);
247
- }
248
- .topbar-jump:hover { color: var(--ink); }
249
- .topbar-jump__kbd { font: 400 11px var(--font-mono); color: var(--ink-faint); }
250
- .zoom-toggle, .theme-toggle {
251
- width: 32px; height: 32px;
252
- display: inline-flex; align-items: center; justify-content: center;
253
- background: none; border: 0; color: var(--ink-soft); cursor: pointer;
254
- transition: color 200ms cubic-bezier(.2, .7, .3, 1);
255
- }
256
- .zoom-toggle:hover, .theme-toggle:hover { color: var(--ink); }
257
-
258
- /* ---------- the content column ---------- */
259
-
260
- .app-content {
261
- grid-column: 2; grid-row: 2;
262
- min-width: 0; padding: 0 var(--gutter) var(--sp-xl);
263
- }
264
- .app-content:focus { outline: none; }
265
-
266
- /* ---------- 1. the reading progress bar ---------- */
267
-
268
- .primer-progress {
269
- position: sticky; top: var(--topbar-h); z-index: 25;
270
- height: 3px; margin: 0 calc(var(--gutter) * -1);
271
- background: color-mix(in srgb, var(--accent) 14%, transparent);
272
- }
273
- .primer-progress__bar {
274
- height: 100%; width: 46%;
275
- background: var(--accent);
276
- transition: width 200ms cubic-bezier(.2, .7, .3, 1);
277
- }
278
- body[data-state="loading"] .primer-progress__bar,
279
- body[data-state="empty"] .primer-progress__bar,
280
- body[data-state="error"] .primer-progress__bar { width: 0; }
281
-
282
- /* ---------- the page head, with hall-1's tile rhythm ---------- */
283
-
284
- .page-head { padding: var(--sp-lg) 0 var(--sp-md); }
285
- .page-head__eyebrow { margin: 0 0 12px; }
286
- .page-head__h {
287
- margin: 0;
288
- font-family: var(--font-display); font-weight: 300;
289
- font-size: var(--h1-size); line-height: 1.02; letter-spacing: -.042em;
290
- text-transform: lowercase; color: var(--ink);
291
- }
292
- .page-head__sub {
293
- margin: var(--sp-sm) 0 0; max-width: var(--measure);
294
- color: var(--ink-soft); font-size: 15.5px;
295
- }
296
- /* mono uppercase labels over big tabular figures: hall-1's rhythm, on the one
297
- set of numbers a reading page actually owns. */
298
- .read-facts {
299
- display: flex; flex-wrap: wrap; gap: var(--sp-sm);
300
- margin: var(--sp-md) 0 0; padding: 0; list-style: none;
301
- }
302
- .read-facts li {
303
- flex: 1 1 150px; min-width: 0;
304
- padding: var(--sp-sm) var(--sp-md);
305
- background: var(--bg-card);
306
- border: var(--line) solid var(--rule-soft);
307
- border-radius: var(--radius-sm);
308
- }
309
- .read-facts__k { display: block; margin-bottom: 8px; }
310
- .read-facts__v {
311
- display: block;
312
- font-family: var(--font-display); font-weight: 300;
313
- font-size: clamp(24px, 2.2vw, 32px); line-height: 1; letter-spacing: -.035em;
314
- font-variant-numeric: tabular-nums; color: var(--ink);
315
- }
316
- .read-facts__u { font-size: .5em; color: var(--ink-faint); letter-spacing: 0; }
317
-
318
- /* ---------- 2. the table of contents, as a sheet ---------- */
319
-
320
- .primer-layout {
321
- display: grid;
322
- grid-template-columns: var(--toc-w) minmax(0, 1fr);
323
- gap: var(--col-gap);
324
- align-items: start;
325
- margin-top: var(--sp-md);
326
- }
327
- .primer-toc {
328
- position: sticky; top: calc(var(--topbar-h) + var(--sp-sm));
329
- align-self: start;
330
- }
331
- .primer-toc__toggle {
332
- display: none; width: 100%;
333
- align-items: center; justify-content: space-between;
334
- min-height: 42px; padding: 8px 14px;
335
- background: var(--bg-card); border: var(--line) solid var(--rule-soft);
336
- border-radius: var(--radius-sm);
337
- color: var(--ink); font-family: var(--font-body); font-size: 14px;
338
- cursor: pointer;
339
- }
340
- .primer-toc__chevron {
341
- width: 10px; height: 6px; flex: none;
342
- fill: none; stroke: currentColor; stroke-width: 1.4;
343
- stroke-linecap: round; stroke-linejoin: round;
344
- transition: transform 200ms cubic-bezier(.2, .7, .3, 1);
345
- }
346
- .primer-toc__toggle[aria-expanded="true"] .primer-toc__chevron { transform: rotate(180deg); }
347
- .primer-toc__inner {
348
- background: var(--bg-card);
349
- border: var(--line) solid var(--rule-soft);
350
- border-radius: var(--radius-sm);
351
- padding: var(--sp-md) var(--sp-sm) var(--sp-sm);
352
- }
353
- .primer-toc__heading { margin: 0 0 var(--sp-xs); padding: 0 var(--sp-xs); }
354
- .primer-toc__list { list-style: none; margin: 0; padding: 0; counter-reset: toc; }
355
- .primer-toc__list a {
356
- display: flex; align-items: baseline; gap: 10px;
357
- min-height: 32px; padding: 7px var(--sp-xs);
358
- border-radius: var(--radius-sm);
359
- border-left: 2px solid transparent;
360
- color: var(--ink-soft); text-decoration: none;
361
- font-size: 14px; line-height: 1.35;
362
- transition: color 200ms cubic-bezier(.2, .7, .3, 1);
363
- }
364
- .primer-toc__list a::before {
365
- counter-increment: toc;
366
- content: counter(toc, decimal-leading-zero);
367
- flex: none;
368
- font: 400 11px/1 var(--font-mono); font-variant-numeric: tabular-nums;
369
- color: var(--ink-faint);
370
- }
371
- .primer-toc__list a:hover { color: var(--ink); }
372
- /* the scrollspy's lit row: the reader's place in the document */
373
- .primer-toc__list a.is-active {
374
- color: var(--ink);
375
- background: var(--bg);
376
- border-left-color: var(--accent);
377
- border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
378
- }
379
- .primer-toc__placeholder {
380
- padding: 8px var(--sp-xs); color: var(--ink-faint); font-size: 14px;
381
- }
382
-
383
- /* ---------- 3. the article, on the sheet ---------- */
384
-
385
- .primer-article {
386
- padding: var(--sheet-pad);
387
- background: var(--art-bg);
388
- border: var(--line) solid var(--art-edge);
389
- border-radius: var(--art-radius);
390
- counter-reset: sec;
391
- color: var(--ink);
392
- }
393
- /* prose is measured inside the sheet; a table, a figure and a code block may
394
- run the whole sheet, which is what makes the sheet worth having. */
395
- .primer-article > p,
396
- .primer-article > ul,
397
- .primer-article > ol,
398
- .primer-article > blockquote,
399
- .primer-article > h2,
400
- .primer-article > h3 { max-width: var(--measure); }
401
-
402
- .primer-article h2 {
403
- margin: var(--sp-xl) 0 var(--sp-sm);
404
- scroll-margin-top: calc(var(--topbar-h) + 28px);
405
- font-family: var(--font-display); font-weight: 300;
406
- font-size: var(--h2-size); line-height: 1.1; letter-spacing: -.035em;
407
- color: var(--ink);
408
- }
409
- /* the mono number is the section break: on a sheet, air and a kicker divide,
410
- because the sheet's own edge is already the page's structure. */
411
- .primer-article h2::before {
412
- counter-increment: sec;
413
- content: counter(sec, decimal-leading-zero);
414
- display: block; margin-bottom: 10px;
415
- font: 400 var(--label-size)/1.25 var(--label-face);
416
- letter-spacing: var(--label-space); font-variant-numeric: tabular-nums;
417
- color: var(--accent-ink);
418
- }
419
- .primer-article > h2:first-child { margin-top: 0; }
420
- .primer-article h3 {
421
- margin: var(--sp-lg) 0 var(--sp-xs);
422
- font-family: var(--font-display); font-weight: 400;
423
- font-size: var(--h3-size); letter-spacing: -.02em; color: var(--ink);
424
- }
425
- .primer-article p { margin: 0 0 var(--sp-sm); }
426
- .primer-article ul, .primer-article ol { margin: 0 0 var(--sp-md); padding-left: 1.4em; }
427
- .primer-article li { margin-bottom: 10px; }
428
- .primer-article li::marker { color: var(--ink-faint); }
429
- .primer-article a {
430
- color: var(--accent-ink);
431
- /* 1px of vertical padding takes the inline hit area past the 24px floor */
432
- padding: 1px 0;
433
- text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px;
434
- }
435
- .primer-article strong { font-weight: 600; color: var(--ink); }
436
- .primer-article em { font-style: italic; }
437
- .primer-article code {
438
- font: 400 .86em/1.4 var(--font-mono);
439
- background: var(--well-bg);
440
- border: var(--line) solid var(--well-edge);
441
- padding: 1px 5px; border-radius: 4px;
442
- }
443
- /* a well: the sheet's own ground, set back into the sheet */
444
- .primer-article pre {
445
- margin: 0 0 var(--sp-md);
446
- padding: var(--sp-sm) var(--sp-md);
447
- overflow-x: auto;
448
- background: var(--well-bg);
449
- border: var(--line) solid var(--well-edge);
450
- border-radius: var(--radius-sm);
451
- }
452
- .primer-article pre code {
453
- background: none; border: 0; padding: 0; border-radius: 0;
454
- font-size: 13.5px; line-height: 1.72; color: var(--ink-soft);
455
- }
456
- .primer-article blockquote {
457
- margin: var(--sp-md) 0; padding: var(--sp-sm) var(--sp-md);
458
- background: var(--well-bg);
459
- border: var(--line) solid var(--well-edge);
460
- border-left: 2px solid var(--rule);
461
- border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
462
- color: var(--ink-soft);
463
- }
464
- .primer-article blockquote p { margin: 0; max-width: var(--measure); }
465
- .primer-article table {
466
- width: 100%;
467
- border-collapse: collapse; margin: 0 0 var(--sp-md);
468
- font-size: 14.5px; font-variant-numeric: tabular-nums;
469
- }
470
- .primer-article th, .primer-article td {
471
- text-align: left; vertical-align: top;
472
- padding: 11px 14px 11px 0;
473
- border-bottom: var(--line) solid var(--rule-soft);
474
- }
475
- .primer-article th {
476
- font: 400 var(--label-size)/1.25 var(--label-face);
477
- letter-spacing: var(--label-space); text-transform: var(--label-case);
478
- color: var(--ink-faint);
479
- padding-bottom: 12px;
480
- }
481
- .primer-article td.t-id { font: 400 13px var(--font-mono); color: var(--ink-faint); }
482
- .primer-article td.t-n, .primer-article th.t-n { text-align: right; padding-right: 0; }
483
- .primer-article tr:last-child td { border-bottom: 0; }
484
-
485
- /* ---------- 4. the inline diagram ---------- */
486
-
487
- .primer-figure { margin: var(--sp-lg) 0; }
488
- .primer-figure__frame {
489
- position: relative;
490
- padding: var(--sp-md);
491
- background: var(--well-bg);
492
- border: var(--line) solid var(--well-edge);
493
- border-radius: var(--radius-sm);
494
- }
495
- .primer-figure__art { display: block; width: 100%; height: auto; }
496
- .primer-figure__zoom {
497
- position: absolute; top: 10px; right: 10px;
498
- display: inline-flex; align-items: center; gap: 8px;
499
- min-height: 30px; padding: 0 13px;
500
- background: var(--bg-card); border: var(--line) solid var(--rule-soft);
501
- border-radius: var(--radius-pill);
502
- color: var(--ink-soft); font-family: var(--font-body); font-size: 12.5px;
503
- cursor: pointer;
504
- transition: color 200ms cubic-bezier(.2, .7, .3, 1);
505
- }
506
- .primer-figure__zoom:hover { color: var(--ink); }
507
- .primer-figure figcaption {
508
- margin-top: 12px; max-width: var(--measure);
509
- font-size: 13px; line-height: 1.5; color: var(--ink-faint);
510
- }
511
- .dgm-rule { stroke: var(--rule); stroke-width: 1; }
512
- .dgm-dot { fill: none; stroke: var(--ink-faint); stroke-width: 1.4; }
513
- .dgm-dot--lit { fill: var(--accent); stroke: var(--accent); }
514
- .dgm-step {
515
- font: 400 11px var(--label-face); letter-spacing: var(--label-space);
516
- fill: var(--ink-faint);
517
- }
518
- .dgm-step--lit { fill: var(--ink); }
519
- .dgm-clause { font: 400 11.5px var(--font-body); fill: var(--ink-faint); }
520
-
521
- /* ---------- the loading skeleton, in the shape of the article ---------- */
522
-
523
- .sk {
524
- display: block; height: 10px; border-radius: 3px;
525
- background: color-mix(in srgb, var(--ink) 9%, transparent);
526
- }
527
- .primer-toc__list--sk li { padding: 10px var(--sp-xs); }
528
- .primer-skeleton {
529
- padding: var(--sheet-pad);
530
- background: var(--art-bg);
531
- border: var(--line) solid var(--art-edge);
532
- border-radius: var(--art-radius);
533
- }
534
- .primer-skeleton__h { height: 26px; width: 58%; margin-bottom: var(--sp-md); }
535
- .primer-skeleton__p { margin-bottom: var(--sp-md); max-width: var(--measure); }
536
- .primer-skeleton__p .sk { margin-bottom: 13px; }
537
- .primer-skeleton__rule { height: var(--line); margin: var(--sp-lg) 0 var(--sp-md); background: var(--rule-soft); }
538
- .sk-w1 { width: 100%; } .sk-w2 { width: 96%; } .sk-w3 { width: 99%; }
539
- .sk-w4 { width: 91%; } .sk-w5 { width: 74%; } .sk-w6 { width: 46%; }
540
- .sk-w7 { width: 84%; } .sk-w8 { width: 63%; }
541
-
542
- /* ---------- the empty and error notes, each on its own sheet ---------- */
543
-
544
- .primer-note {
545
- padding: var(--sheet-pad);
546
- background: var(--art-bg);
547
- border: var(--line) solid var(--art-edge);
548
- border-radius: var(--art-radius);
549
- }
550
- .primer-note__label { margin: 0 0 12px; }
551
- .primer-note--error .primer-note__label { color: var(--danger); }
552
- .primer-note__body { margin: 0 0 var(--sp-md); max-width: var(--measure); color: var(--ink-soft); }
553
- .primer-note__acts { display: flex; flex-wrap: wrap; gap: var(--sp-xs); margin: 0; }
554
- .primer-note__act {
555
- display: inline-flex; align-items: center; min-height: 36px; padding: 0 18px;
556
- border: var(--line) solid var(--rule); border-radius: var(--radius-pill);
557
- background: none; color: var(--ink); text-decoration: none;
558
- font-family: var(--font-body); font-size: 14px; cursor: pointer;
559
- }
560
- .primer-note__act:hover { border-color: var(--ink-faint); }
561
-
562
- /* ---------- 5. the acknowledge gate, its own sheet under the article ---------- */
563
-
564
- .primer-ack {
565
- margin-top: var(--sp-sm);
566
- padding: var(--sheet-pad);
567
- background: var(--art-bg);
568
- border: var(--line) solid var(--art-edge);
569
- border-radius: var(--art-radius);
570
- }
571
- .primer-ack__h {
572
- margin: 0 0 12px;
573
- font-family: var(--font-display); font-weight: 300;
574
- font-size: 26px; letter-spacing: -.03em; color: var(--ink);
575
- }
576
- .primer-ack__lede { margin: 0 0 var(--sp-sm); max-width: var(--measure); color: var(--ink-soft); }
577
- .primer-ack__meter { margin: 0 0 var(--sp-md); }
578
- .primer-ack__meter .num { color: var(--ink); }
579
- .primer-ack__btn {
580
- display: inline-flex; align-items: center;
581
- min-height: 46px; padding: 0 28px;
582
- background: var(--well-bg); border: var(--line) solid var(--rule);
583
- border-radius: var(--radius-pill);
584
- color: var(--ink-faint); font-family: var(--font-body); font-size: 15px;
585
- cursor: not-allowed;
586
- transition: color 200ms cubic-bezier(.2, .7, .3, 1);
587
- }
588
- .primer-ack__btn[aria-disabled="false"] {
589
- background: var(--accent); border-color: var(--accent);
590
- color: var(--accent-on); cursor: pointer;
591
- }
592
- .primer-ack__note { margin: var(--sp-xs) 0 0; font-size: 13.5px; color: var(--ink-faint); }
593
-
594
- /* ---------- the state contract: real markup, shown and hidden by CSS ---------- */
595
-
596
- .p-populated, .p-loading, .p-empty, .p-error { display: none; }
597
- body[data-state="populated"] .p-populated,
598
- body[data-state="rail"] .p-populated,
599
- body[data-state="drawer"] .p-populated,
600
- body[data-state="focus"] .p-populated { display: block; }
601
- /* the tile strip is a flex row, so it restates its own display when shown */
602
- body[data-state="populated"] .read-facts.p-populated,
603
- body[data-state="rail"] .read-facts.p-populated,
604
- body[data-state="drawer"] .read-facts.p-populated,
605
- body[data-state="focus"] .read-facts.p-populated { display: flex; }
606
- body[data-state="loading"] .p-loading { display: block; }
607
- body[data-state="empty"] .p-empty { display: block; }
608
- body[data-state="error"] .p-error { display: block; }
609
-
610
- body[data-state="focus"] .primer-toc__toggle { display: flex; margin-bottom: var(--sp-sm); }
611
-
612
- /* ---------- the rail: the sidebar collapsed to 64px ---------- */
613
-
614
- body[data-state="rail"] { --sidebar-w: var(--sidebar-w-rail); }
615
- body[data-state="rail"] .brand-mark__name,
616
- body[data-state="rail"] .nav-item__label,
617
- body[data-state="rail"] .nav-group__head-label,
618
- body[data-state="rail"] .nav-group__chevron,
619
- body[data-state="rail"] .shell-user__meta { display: none; }
620
- body[data-state="rail"] .app-sidebar__brand { padding-inline: 0; }
621
- body[data-state="rail"] .nav-group { padding-inline: 6px; }
622
- body[data-state="rail"] .brand-mark,
623
- body[data-state="rail"] .nav-item,
624
- body[data-state="rail"] .nav-group__head,
625
- body[data-state="rail"] .shell-user { justify-content: center; padding-inline: 0; }
626
- body[data-state="rail"] .nav-item { border-left: 0; border-right: 2px solid transparent; }
627
- body[data-state="rail"] .nav-item--active {
628
- border-right-color: var(--accent);
629
- border-radius: var(--radius-sm) 0 0 var(--radius-sm);
630
- }
631
- body[data-state="rail"] .nav-group__head { padding-bottom: 4px; }
632
- body[data-state="rail"] .app-sidebar__foot {
633
- flex-direction: column; gap: 6px; margin-inline: 6px; padding: 8px 0;
634
- }
635
-
636
- @media (max-width: 1024px) {
637
- .brand-mark__name, .nav-item__label, .nav-group__head-label,
638
- .nav-group__chevron, .shell-user__meta { display: none; }
639
- .app-sidebar__brand { padding-inline: 0; }
640
- .nav-group { padding-inline: 6px; }
641
- .brand-mark, .nav-item, .nav-group__head, .shell-user {
642
- justify-content: center; padding-inline: 0;
643
- }
644
- .nav-item { border-left: 0; border-right: 2px solid transparent; }
645
- .nav-item--active {
646
- border-right-color: var(--accent);
647
- border-radius: var(--radius-sm) 0 0 var(--radius-sm);
648
- }
649
- .nav-group__head { padding-bottom: 4px; }
650
- .app-sidebar__foot { flex-direction: column; gap: 6px; margin-inline: 6px; padding: 8px 0; }
651
- .topbar-note { display: none; }
652
- }
653
-
654
- /* ---------- the drawer ---------- */
655
-
656
- body[data-state="drawer"] { grid-template-columns: minmax(0, 1fr); }
657
- body[data-state="drawer"] .app-topbar,
658
- body[data-state="drawer"] .app-content { grid-column: 1; }
659
- body[data-state="drawer"] .topbar-menu { display: inline-flex; }
660
- body[data-state="drawer"] .app-sidebar {
661
- position: fixed; inset: 0 auto 0 0; width: 264px; height: 100dvh;
662
- transform: none; /* beats the narrow-width off-canvas rule */
663
- z-index: var(--z-drawer);
664
- }
665
- body[data-state="drawer"] .brand-mark__name,
666
- body[data-state="drawer"] .nav-item__label,
667
- body[data-state="drawer"] .nav-group__head-label,
668
- body[data-state="drawer"] .nav-group__chevron,
669
- body[data-state="drawer"] .shell-user__meta { display: block; }
670
- body[data-state="drawer"] .app-sidebar__brand { padding-inline: var(--shell-pad); }
671
- body[data-state="drawer"] .nav-group { padding-inline: var(--sp-xs); }
672
- body[data-state="drawer"] .brand-mark,
673
- body[data-state="drawer"] .shell-user { justify-content: flex-start; }
674
- body[data-state="drawer"] .nav-group__head { justify-content: space-between; }
675
- body[data-state="drawer"] .nav-group__head { padding-inline: var(--sp-xs); }
676
- body[data-state="drawer"] .nav-item {
677
- justify-content: flex-start; padding-inline: var(--sp-xs);
678
- border-right: 0; border-left: 2px solid transparent;
679
- }
680
- body[data-state="drawer"] .nav-item--active {
681
- border-left-color: var(--accent);
682
- border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
683
- }
684
- body[data-state="drawer"] .app-sidebar__foot {
685
- flex-direction: row; gap: 4px;
686
- margin: var(--sp-xs) 8px var(--sp-sm); padding: 8px;
687
- }
688
- body[data-state="drawer"] .app-scrim {
689
- display: block; position: fixed; inset: 0; z-index: var(--z-scrim);
690
- background: rgba(0, 0, 0, .55);
691
- }
692
-
693
- /* ---------- 760px: the page's one breakpoint ----------
694
- the same one primer.js's matchMedia mirrors and tests/hall_audit.mjs pins. */
695
-
696
- @media (max-width: 760px) {
697
- body {
698
- --gutter: 16px;
699
- --col-gap: 0px;
700
- --sheet-pad: 20px;
701
- --body-size: 16px;
702
- --measure: 100%;
703
- grid-template-columns: minmax(0, 1fr);
704
- }
705
- .app-topbar, .app-content { grid-column: 1; }
706
- .topbar-menu { display: inline-flex; }
707
- .app-sidebar {
708
- position: fixed; inset: 0 auto 0 0; width: 264px;
709
- transform: translateX(-100%); z-index: var(--z-drawer);
710
- }
711
- .primer-layout { grid-template-columns: minmax(0, 1fr); }
712
- .primer-toc { position: static; margin-bottom: var(--sp-sm); }
713
- .primer-toc__toggle { display: flex; }
714
- .primer-toc__inner { display: none; margin-top: 8px; }
715
- .primer-toc__toggle[aria-expanded="true"] + .primer-toc__inner { display: block; }
716
- .primer-article h2 { font-size: 23px; }
717
- .page-head__h { font-size: 32px; }
718
- .read-facts li { flex: 1 1 100%; }
719
- /* a markdown table's column count is fixed by its source, so its min-content
720
- width outruns a phone. Give the table its own scrollport rather than let it
721
- drag the page sideways. This is primer.css's shipped rule, unchanged. */
722
- .primer-article table {
723
- display: block; width: max-content; max-width: 100%; overflow-x: auto;
724
- }
725
- .primer-figure__zoom { position: static; margin-top: var(--sp-xs); }
726
- }
727
- </style>
728
- <script>
729
- (function(){try{var q=new URLSearchParams(location.search||location.hash.slice(1)||'').get('mode');
730
- var m=(q==='light'||q==='dark')?q:'dark';
731
- document.documentElement.setAttribute('data-mode',m);
732
- document.documentElement.setAttribute('data-theme',m);}catch(e){}})();
733
- </script>
734
- </head>
735
- <body class="mock" data-state="populated">
736
- <!--
737
- Reading room in the chrome world, v2 "the sheet" (task 1003302, goal 1000081).
738
- THESIS A twenty page document wants to be a document, so the article gets a --bg-card sheet
739
- with a hairline edge and no lift at all, and the reader gets an edge to rest against.
740
- COMPOSITION First viewport at 1440: a --bg-frame sidebar with grouped mono headings and hall-1's
741
- pinned identity card, a 56px topbar, the progress hairline, then the lowercase h1 over
742
- three mono-label tiles carrying the document's own figures, and below that a 250px
743
- table-of-contents sheet beside the article sheet, prose measured to 60ch inside it,
744
- with the code block, the table and the diagram set into wells of the page ground.
745
- LIGHT Light is where this version is at home: the sheet reads as paper on a slightly darker
746
- paper, exactly the owner's light reference, and the tonal step does the separating that
747
- a shadow would have done. In dark the same step is card over pure black.
748
- RISK The sheet costs a reader edge weight: at 60ch inside 52px of padding there is a lot of
749
- container around not much line, the tile strip spends the first screen on metadata
750
- rather than on the first paragraph, and every well inside the sheet is one more box to
751
- read past.
752
- ?state=populated the page with real data
753
- ?state=loading skeletons in the SHAPE of the final content
754
- ?state=empty nothing to show yet
755
- ?state=error the feed failed
756
- ?state=rail the sidebar collapsed to its 64px rail
757
- ?state=drawer the mobile drawer open
758
- ?state=focus keyboard focus rings on the page's real controls
759
- -->
760
-
761
- <a class="skip" href="#main">Skip to content</a>
762
-
763
- <div class="app-sidebar" id="app-sidebar">
764
- <div class="app-sidebar__brand">
765
- <a class="brand-mark" href="/" id="brand-mark">
766
- <span class="brand-mark__dot"></span><span class="brand-mark__name">Cloud Bongos</span></a>
767
- </div>
768
- <nav class="app-sidebar__nav" aria-label="Primary">
769
- <div class="nav-group">
770
- <a class="nav-item" id="nav-home" href="/" data-gate="always">
771
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.5 7.2 8 2.5l5.5 4.7V13a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5z"/></svg>
772
- <span class="nav-item__label">Home</span></a>
773
- <a class="nav-item" id="nav-roadmap" href="/roadmap" data-gate="always">
774
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.5 4h11M2.5 8h7.5M2.5 12h4.5"/></svg>
775
- <span class="nav-item__label">Roadmap</span></a>
776
- <a class="nav-item" id="nav-goals" href="/goals" data-gate="always">
777
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="5.5"/><circle cx="8" cy="8" r="1.6"/></svg>
778
- <span class="nav-item__label">Goals</span></a>
779
- <a class="nav-item" id="nav-work" href="/work" data-gate="always">
780
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.5 4.5h11v9h-11zM2.5 7.5h11M6 7.5v6"/></svg>
781
- <span class="nav-item__label">Tasks</span></a>
782
- <a class="nav-item" id="nav-ideas" href="/ideas" data-gate="always">
783
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 2.5a3.6 3.6 0 0 0-2.2 6.4v1.3h4.4V8.9A3.6 3.6 0 0 0 8 2.5zM6.4 12.6h3.2"/></svg>
784
- <span class="nav-item__label">Ideas</span></a>
785
- <a class="nav-item" id="nav-copy-desk" href="/copy-desk" data-gate="always">
786
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M4 2.5h5l3 3v8H4zM9 2.5v3h3"/></svg>
787
- <span class="nav-item__label">Copy desk</span></a>
788
- </div>
789
- <div class="nav-group nav-group--collapsible" id="nav-items-you" data-group="you">
790
- <button class="nav-group__head" data-gate="signed" data-group="you" aria-controls="nav-items-you" aria-expanded="true">
791
- <span class="nav-group__head-label">You</span>
792
- <svg class="nav-group__chevron" viewBox="0 0 10 6" aria-hidden="true"><path d="M1 1.2 5 4.8 9 1.2"/></svg></button>
793
- <a class="nav-item" id="nav-standing" href="/#standing" data-gate="signed">
794
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M3 13.5V9M8 13.5V4.5M13 13.5v-3"/></svg>
795
- <span class="nav-item__label">Standing</span></a>
796
- <a class="nav-item" id="nav-profile" href="/profile" data-gate="signed">
797
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="5.6" r="2.6"/><path d="M3.2 13.5a4.8 4.8 0 0 1 9.6 0"/></svg>
798
- <span class="nav-item__label">Profile</span></a>
799
- </div>
800
- <div class="nav-group nav-group--collapsible" id="nav-items-community" data-group="community">
801
- <button class="nav-group__head" data-gate="signed" data-group="community" aria-controls="nav-items-community" aria-expanded="true">
802
- <span class="nav-group__head-label">Community</span>
803
- <svg class="nav-group__chevron" viewBox="0 0 10 6" aria-hidden="true"><path d="M1 1.2 5 4.8 9 1.2"/></svg></button>
804
- <a class="nav-item" id="nav-collab" href="/collab" data-gate="signed">
805
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><circle cx="5.6" cy="5.6" r="2.1"/><circle cx="10.6" cy="10.4" r="2.1"/><path d="M7.2 7.2 9 8.9"/></svg>
806
- <span class="nav-item__label">Collab</span></a>
807
- <a class="nav-item" id="nav-leaderboard" href="/#leaderboard" data-gate="signed">
808
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.5 13.5h11M5 13.5V8.2h2.2v5.3M8.8 13.5V4.5H11v9"/></svg>
809
- <span class="nav-item__label">Leaderboard</span></a>
810
- <a class="nav-item" id="nav-people" href="/people" data-gate="signed">
811
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><circle cx="6" cy="5.6" r="2.2"/><path d="M2.2 13.2a3.9 3.9 0 0 1 7.6 0M10.6 4.1a2.2 2.2 0 0 1 0 4.3M11.6 9.7a3.9 3.9 0 0 1 2.2 3.5"/></svg>
812
- <span class="nav-item__label">People</span></a>
813
- </div>
814
- <div class="nav-group nav-group--collapsible" id="nav-items-docs" data-group="docs">
815
- <button class="nav-group__head" data-gate="always" data-group="docs" aria-controls="nav-items-docs" aria-expanded="true">
816
- <span class="nav-group__head-label">Docs</span>
817
- <svg class="nav-group__chevron" viewBox="0 0 10 6" aria-hidden="true"><path d="M1 1.2 5 4.8 9 1.2"/></svg></button>
818
- <a class="nav-item nav-item--active is-focus" id="nav-primer" href="/primer" data-gate="always" aria-current="page">
819
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 4.4v9M8 4.4A3.4 3.4 0 0 0 5 2.9H2.6v8.6H5a3.4 3.4 0 0 1 3 1.9M8 4.4A3.4 3.4 0 0 1 11 2.9h2.4v8.6H11a3.4 3.4 0 0 0-3 1.9"/></svg>
820
- <span class="nav-item__label">Primer</span></a>
821
- <a class="nav-item" id="nav-ranks" href="/ranks" data-gate="always">
822
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M3 11.5l5-4 5 4M3 7.5l5-4 5 4"/></svg>
823
- <span class="nav-item__label">Ranks</span></a>
824
- <a class="nav-item" id="nav-economy" href="/drachmae" data-gate="always">
825
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="5.5"/><path d="M6 6.4h4M6 9.6h4M8 4.6v6.8"/></svg>
826
- <span class="nav-item__label">Economy</span></a>
827
- <a class="nav-item" id="nav-diagrams" href="/diagrams" data-gate="always">
828
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.5 2.8h4.2v3.4H2.5zM9.3 9.8h4.2v3.4H9.3zM4.6 6.2v3.6h6.8"/></svg>
829
- <span class="nav-item__label">Diagrams</span></a>
830
- <a class="nav-item" id="nav-atlas" href="/atlas" data-gate="always">
831
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.5 12.8V4.2h4l1.2 1.6h5.8v7z"/></svg>
832
- <span class="nav-item__label">Repo Atlas</span></a>
833
- <a class="nav-item" id="nav-modules" href="/modules" data-gate="always">
834
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.8 2.8h4.2v4.2H2.8zM9 2.8h4.2v4.2H9zM2.8 9h4.2v4.2H2.8zM9 9h4.2v4.2H9z"/></svg>
835
- <span class="nav-item__label">Modules</span></a>
836
- <a class="nav-item" id="nav-apidocs" href="/docs" data-gate="always">
837
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M6 3.6 2.6 8 6 12.4M10 3.6 13.4 8 10 12.4"/></svg>
838
- <span class="nav-item__label">API docs</span></a>
839
- </div>
840
- <div class="nav-group nav-group--collapsible" id="nav-items-government" data-group="government">
841
- <button class="nav-group__head" data-gate="signed" data-group="government" aria-controls="nav-items-government" aria-expanded="true">
842
- <span class="nav-group__head-label">Government</span>
843
- <svg class="nav-group__chevron" viewBox="0 0 10 6" aria-hidden="true"><path d="M1 1.2 5 4.8 9 1.2"/></svg></button>
844
- <a class="nav-item" id="nav-watch" href="/watch" data-gate="signed">
845
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M1.6 8s2.4-4.2 6.4-4.2S14.4 8 14.4 8s-2.4 4.2-6.4 4.2S1.6 8 1.6 8z"/><circle cx="8" cy="8" r="1.8"/></svg>
846
- <span class="nav-item__label">Watch</span></a>
847
- <a class="nav-item" id="nav-harbor" href="/harbor" data-gate="signed">
848
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="3.4" r="1.4"/><path d="M8 4.9v8.6M4.6 7.1h6.8M2.9 9.4a5.1 5.1 0 0 0 10.2 0"/></svg>
849
- <span class="nav-item__label">Harbor</span></a>
850
- <a class="nav-item" id="nav-gate" href="/gate" data-gate="signed">
851
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.8 13.5V6L8 2.8 13.2 6v7.5M6.2 13.5V9h3.6v4.5"/></svg>
852
- <span class="nav-item__label">Gate</span></a>
853
- <a class="nav-item" id="nav-sessions" href="/sessions" data-gate="signed">
854
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="5.5"/><path d="M8 4.8V8l2.4 1.4"/></svg>
855
- <span class="nav-item__label">Sessions</span></a>
856
- <a class="nav-item" id="nav-government" href="/government" data-gate="signed">
857
- <svg class="nav-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 2.4l4.8 1.8v4c0 3-2.1 4.6-4.8 5.4-2.7-.8-4.8-2.4-4.8-5.4v-4z"/></svg>
858
- <span class="nav-item__label">Permissions</span></a>
859
- </div>
860
- </nav>
861
- <div class="app-sidebar__foot">
862
- <a class="shell-user" id="shell-user" href="/settings" title="Settings">
863
- <span class="shell-user__avatar"></span>
864
- <span class="shell-user__meta">
865
- <span class="shell-user__name">Percy Jackson</span>
866
- <span class="shell-user__rank">Owner</span></span></a>
867
- <a class="shell-home" href="/" title="Back to Cloud Bongos">
868
- <svg class="foot-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.5 7.2 8 2.5l5.5 4.7V13a.5.5 0 0 1-.5.5H3a.5.5 0 0 1-.5-.5z"/></svg>
869
- <span class="u-sr">Back to Cloud Bongos</span></a>
870
- <a class="shell-signout" href="/api/bongos/auth/logout" title="Sign out">
871
- <svg class="foot-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M6.4 2.8H3.2v10.4h3.2M9.4 5.4 12 8l-2.6 2.6M12 8H6.2"/></svg>
872
- <span class="u-sr">Sign out</span></a>
873
- </div>
874
- </div>
875
- <div class="app-scrim" id="app-scrim" aria-hidden="true"></div>
876
-
877
- <header class="app-topbar" id="app-topbar">
878
- <button class="topbar-menu" id="topbar-menu" aria-label="Open navigation" aria-expanded="false">
879
- <svg class="topbar-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M2.5 4.5h11M2.5 8h11M2.5 11.5h11"/></svg></button>
880
- <h2 class="topbar-title">Primer</h2>
881
- <div class="topbar-side">
882
- <span class="topbar-note">Docs, a ten minute read</span>
883
- <button class="topbar-jump" id="topbar-jump" aria-label="Jump to a page or record">
884
- <span class="topbar-jump__label">Jump to</span><kbd class="topbar-jump__kbd">Ctrl K</kbd></button>
885
- <button class="zoom-toggle" aria-label="Text size">
886
- <svg class="topbar-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M1.8 12.4 5 4.6l3.2 7.8M2.9 10.2h4.2M9.6 12.4 12 7l2.4 5.4M10.4 10.6h3.2"/></svg></button>
887
- <button class="theme-toggle" aria-label="Switch theme">
888
- <svg class="topbar-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M13.2 9.4A5.6 5.6 0 0 1 6.6 2.8a5.6 5.6 0 1 0 6.6 6.6z"/></svg></button>
889
- </div>
890
- </header>
891
-
892
- <main class="app-content" id="main" tabindex="-1">
893
-
894
- <!-- 1. the reading progress bar -->
895
- <div class="primer-progress" aria-hidden="true"><div class="primer-progress__bar"></div></div>
896
-
897
- <div class="page-head">
898
- <p class="page-head__eyebrow label">Docs</p>
899
- <h1 class="page-head__h">the primer</h1>
900
- <p class="page-head__sub">Everything a new builder needs before claiming a first task: what this
901
- platform is, how work moves from claim to credit, and what each rank opens.</p>
902
- <ul class="read-facts p-populated">
903
- <li><span class="read-facts__k label">Sections</span><span class="read-facts__v num">6</span></li>
904
- <li><span class="read-facts__k label">Reading time</span><span class="read-facts__v num">10<span class="read-facts__u"> min</span></span></li>
905
- <li><span class="read-facts__k label">Last revised</span><span class="read-facts__v num">30 Aug</span></li>
906
- </ul>
907
- </div>
908
-
909
- <div class="primer-layout">
910
-
911
- <!-- 2. the sticky table of contents. Under 760px it collapses behind the
912
- Sections disclosure, the page's one breakpoint. -->
913
- <aside class="primer-toc" id="primer-toc" aria-label="Sections in this primer">
914
- <button type="button" class="primer-toc__toggle is-focus" id="primer-toc-toggle"
915
- aria-expanded="false" aria-controls="primer-toc-list">
916
- <span class="primer-toc__toggle-label">Sections</span>
917
- <svg class="primer-toc__chevron" viewBox="0 0 10 6" aria-hidden="true"><path d="M1 1.2 5 4.8 9 1.2"/></svg></button>
918
- <nav class="primer-toc__inner">
919
- <p class="primer-toc__heading label" id="primer-toc-heading">In this primer</p>
920
- <ol class="primer-toc__list p-populated" id="primer-toc-list" aria-labelledby="primer-toc-heading">
921
- <li><a href="#s-what">What Cloud Bongos is</a></li>
922
- <li><a class="is-active is-focus" href="#s-lifecycle" aria-current="location">The claim to ship lifecycle</a></li>
923
- <li><a href="#s-board">Reading the board</a></li>
924
- <li><a href="#s-ranks">Ranks, and what each one opens</a></li>
925
- <li><a href="#s-credits">Credits, and what they are worth</a></li>
926
- <li><a href="#s-first">Your first task</a></li>
927
- </ol>
928
- <ol class="primer-toc__list primer-toc__list--sk p-loading" aria-hidden="true">
929
- <li><span class="sk sk-w2"></span></li>
930
- <li><span class="sk sk-w5"></span></li>
931
- <li><span class="sk sk-w7"></span></li>
932
- <li><span class="sk sk-w4"></span></li>
933
- <li><span class="sk sk-w8"></span></li>
934
- <li><span class="sk sk-w6"></span></li>
935
- </ol>
936
- <ul class="primer-toc__list p-empty">
937
- <li class="primer-toc__placeholder">No sections yet</li>
938
- </ul>
939
- <ul class="primer-toc__list p-error">
940
- <li class="primer-toc__placeholder">Sections unavailable</li>
941
- </ul>
942
- </nav>
943
- </aside>
944
-
945
- <div class="primer-col">
946
-
947
- <!-- 3. the article, on the sheet. Flat markdown output: h2, h3, p, ul, ol,
948
- table, pre, blockquote and inline marks, nothing a reader would wrap. -->
949
- <article class="primer-article p-populated" id="primer-article">
950
-
951
- <h2 id="s-what">What Cloud Bongos is</h2>
952
- <p>Cloud Bongos is an <strong>AI first build platform</strong>. A human owner sets the scope and
953
- the hard gates; agents claim the work and write the code. Everything that happens to this
954
- project becomes a row in one ledger: a task is created, claimed, built, graded, shipped and
955
- paid. If a change is not in the ledger, the ledger lies, so there is no tiny fix that skips it
956
- and no setup step that counts as free.</p>
957
- <p>Two versions are open as you read this. <strong>BONGOS-V1</strong>, the platform itself, has
958
- shipped <span class="num">1,176</span> of <span class="num">1,612</span> tasks against
959
- <span class="num">190</span> criteria, <span class="num">75</span> percent complete.
960
- <strong>CB-V1</strong>, the Customer-0 dogfood, has shipped <span class="num">58</span> of
961
- <span class="num">155</span>. You may claim from either, on whichever suits the time you have.</p>
962
-
963
- <h3>The five rooms you will use in week one</h3>
964
- <p>The hall is where the work is done. Five of its rooms carry almost everything:</p>
965
- <ul>
966
- <li>The <a href="/work">board</a>, where every ready task is listed with its credits and its estimate.</li>
967
- <li><a href="/goals">Goals</a>, which gather tasks into one module scoped piece of work with a done condition.</li>
968
- <li>Your <a href="/#standing">standing</a>: your rank, your credits, and everything you have shipped.</li>
969
- <li>The docs, this page among them, which are the only place the method is written down.</li>
970
- <li>The <a href="/watch">watch</a>, where a grade, a merge or a deploy that went wrong surfaces first.</li>
971
- </ul>
972
-
973
- <h2 id="s-lifecycle">The claim to ship lifecycle</h2>
974
- <p>Work moves through five beats, always in this order. The rail below is the same one the task
975
- page draws, and the beat you are on is the lit one.</p>
976
-
977
- <!-- 4. the inline diagram, injected after a named h2, with an affordance
978
- to open it fullscreen. -->
979
- <figure class="primer-figure" id="fig-lifecycle">
980
- <div class="primer-figure__frame">
981
- <svg class="primer-figure__art" viewBox="0 0 660 132" role="img"
982
- aria-label="The five beats of the lifecycle, left to right: claim, build, grade, ship, credit. Build is the lit step.">
983
- <path class="dgm-rule" d="M24 20h108M150 20h108M276 20h108M402 20h108M528 20h108"/>
984
- <circle class="dgm-dot" cx="30" cy="44" r="5"/>
985
- <circle class="dgm-dot dgm-dot--lit" cx="156" cy="44" r="5"/>
986
- <circle class="dgm-dot" cx="282" cy="44" r="5"/>
987
- <circle class="dgm-dot" cx="408" cy="44" r="5"/>
988
- <circle class="dgm-dot" cx="534" cy="44" r="5"/>
989
- <text class="dgm-step" x="24" y="74">CLAIM</text>
990
- <text class="dgm-step dgm-step--lit" x="150" y="74">BUILD</text>
991
- <text class="dgm-step" x="276" y="74">GRADE</text>
992
- <text class="dgm-step" x="402" y="74">SHIP</text>
993
- <text class="dgm-step" x="528" y="74">CREDIT</text>
994
- <text class="dgm-clause" x="24" y="98">lock the task<tspan x="24" dy="16">to your session</tspan></text>
995
- <text class="dgm-clause" x="150" y="98">write it in your<tspan x="150" dy="16">own worktree</tspan></text>
996
- <text class="dgm-clause" x="276" y="98">a panel reads<tspan x="276" dy="16">the real diff</tspan></text>
997
- <text class="dgm-clause" x="402" y="98">merged, then<tspan x="402" dy="16">deployed</tspan></text>
998
- <text class="dgm-clause" x="528" y="98">paid on land,<tspan x="528" dy="16">not on claim</tspan></text>
999
- </svg>
1000
- <button type="button" class="primer-figure__zoom" aria-label="Open the lifecycle diagram fullscreen">
1001
- <svg class="topbar-icon" viewBox="0 0 16 16" aria-hidden="true"><path d="M6 2.5H2.5V6M10 2.5h3.5V6M10 13.5h3.5V10M6 13.5H2.5V10"/></svg>
1002
- <span>Fullscreen</span></button>
1003
- </div>
1004
- <figcaption>The claim to ship lifecycle. Exactly one step is lit at a time, and credits land
1005
- at ship, never at claim.</figcaption>
1006
- </figure>
1007
-
1008
- <ol>
1009
- <li><strong>Claim.</strong> A claim locks one task to one session, so two builders can work the
1010
- same version without colliding. A claim is refused if the task is already held, is not ready,
1011
- or has a dependency that has not shipped.</li>
1012
- <li><strong>Build.</strong> Work from a worktree of your own, never the main checkout. Write the
1013
- code, the doc comment and the tests together: a change with no test is a change nobody can
1014
- defend at grade.</li>
1015
- <li><strong>Grade.</strong> A panel of reviewers reads the real committed diff, not your summary
1016
- of it. A grade that fails is a description of what is missing, not a verdict on you.</li>
1017
- <li><strong>Ship.</strong> The task moves to confirmed when the checks are green, then to shipped
1018
- when the branch is merged and deployed. The server lands most merges on its own.</li>
1019
- <li><strong>Credit.</strong> Credits are written when the work lands, which is why an abandoned
1020
- branch pays nothing and a merged one pays in full.</li>
1021
- </ol>
1022
-
1023
- <blockquote>
1024
- <p>A task you have not claimed is a task another builder can claim out from under you. Claim
1025
- first, then open the editor.</p>
1026
- </blockquote>
1027
-
1028
- <h3>The three commands</h3>
1029
- <p>All five beats run from three commands. Run them from your own worktree:
1030
- <code>claim.js</code> refuses in the main checkout on purpose, because branching there strands
1031
- the ship at <em>confirmed</em> and somebody has to go and rescue it.</p>
1032
- <pre><code>node scripts/gds/claim.js 1002529
1033
- # build on the task branch, commit as you go
1034
- node scripts/gds/ship.js --summary "Provisioned instances now read config/branding.json"</code></pre>
1035
- <p><em>If a claim is refused, read the reason before you retry it.</em> The three refusals mean
1036
- three different things, and only one of them is worth waiting out.</p>
1037
-
1038
- <h2 id="s-board">Reading the board</h2>
1039
- <p>The board lists what is ready right now. Every row carries the version it belongs to, the kind
1040
- of work, the credits it pays and the estimate it was written with. Sort by nothing: read the
1041
- five at the top, and take the one you can finish today.</p>
1042
-
1043
- <table>
1044
- <thead>
1045
- <tr>
1046
- <th scope="col">Task</th>
1047
- <th scope="col">Version</th>
1048
- <th scope="col">Kind</th>
1049
- <th scope="col" class="t-n">Credits</th>
1050
- <th scope="col" class="t-n">Estimate</th>
1051
- </tr>
1052
- </thead>
1053
- <tbody>
1054
- <tr><td class="t-id">1001479</td><td>BONGOS-V1</td><td>infra</td><td class="t-n">10</td><td class="t-n">20m</td></tr>
1055
- <tr><td class="t-id">1002529</td><td>BONGOS-V1</td><td>bug</td><td class="t-n">50</td><td class="t-n">60m</td></tr>
1056
- <tr><td class="t-id">1002572</td><td>BONGOS-V1</td><td>bug</td><td class="t-n">60</td><td class="t-n">60m</td></tr>
1057
- <tr><td class="t-id">1003226</td><td>BONGOS-V1</td><td>bug</td><td class="t-n">25</td><td class="t-n">45m</td></tr>
1058
- <tr><td class="t-id">1003366</td><td>CB-V1</td><td>infra</td><td class="t-n">60</td><td class="t-n">240m</td></tr>
1059
- </tbody>
1060
- </table>
1061
-
1062
- <p>Task <span class="num">1002529</span>, "Provisioned instances ignore config/branding.json", is
1063
- the honest first claim on that list: one wrong lookup, a test that proves it, and a fix small
1064
- enough to read in one sitting. Task <span class="num">1003366</span> is not, because it edits
1065
- the protected surfaces file, and that needs a rank you do not have yet.</p>
1066
-
1067
- <h2 id="s-ranks">Ranks, and what each one opens</h2>
1068
- <p>There are four ranks. Rank is held in the database and checked on every request, so no local
1069
- file, this page included, can grant you anything. What rises with rank is not privilege for its
1070
- own sake: it is how much of the pipeline you are trusted to change.</p>
1071
- <ul>
1072
- <li><strong>Newcomer.</strong> Read everything, claim sandboxed work, ship it. The permission
1073
- and pipeline surfaces are closed, and the tooling will say so rather than let you push.</li>
1074
- <li><strong>Contributor.</strong> The ordinary building rank: claim across both versions, open
1075
- goals, file blockers, write ADRs.</li>
1076
- <li><strong>Trusted.</strong> Adds the daily cadence work, the triage of ideas and blockers, and
1077
- planning sessions that set a version's scope.</li>
1078
- <li><strong>Owner.</strong> Sets scope and the hard gates. One human owner per instance, plus the
1079
- agents the owner has raised to it.</li>
1080
- </ul>
1081
- <p>Rising is not a request you file. It is what the ledger says about the work you have already
1082
- shipped, read at review.</p>
1083
-
1084
- <h2 id="s-credits">Credits, and what they are worth</h2>
1085
- <p>Credits are the platform's currency, and one credit is one dollar of value returned. The
1086
- instance has spent <span class="num">$49,708.47</span> to date, almost all of it on model
1087
- calls, and the work that spend bought is carried at <span class="num">71,040</span> credits.
1088
- That ratio is the whole argument for the method, so it is on the wall rather than in a report.</p>
1089
- <p>A shipped task pays what it was written to pay. Task <span class="num">1003322</span>, which
1090
- carved the front door into its own module, paid <span class="num">60</span> credits: estimated
1091
- at <span class="num">240</span> minutes, shipped in <span class="num">37</span>. The estimate
1092
- is not a target and beating it earns nothing extra, which is deliberate.</p>
1093
- <p>The standing board reads, at the time of writing: lars589 on
1094
- <span class="num">44,562</span> credits, Percy Jackson on <span class="num">14,441</span>,
1095
- IAMMASTERQUA on <span class="num">3,316</span>, scootermack on <span class="num">2,646</span>.
1096
- A credit figure is data, not a live thing, so it is set in ink and never in the accent.</p>
1097
-
1098
- <h2 id="s-first">Your first task</h2>
1099
- <p>Do these in order. The whole loop, claim to credit, should take one sitting.</p>
1100
- <ol>
1101
- <li>Acknowledge this primer at the foot of the page.</li>
1102
- <li>Open the <a href="/work">board</a> and read the five ready tasks end to end before choosing.</li>
1103
- <li>Claim one, in a worktree of its own.</li>
1104
- <li>Write the failing test first, then the change that passes it.</li>
1105
- <li>Ship with a summary a non engineer could read, because that summary is what gets broadcast.</li>
1106
- </ol>
1107
- <p>If something in here turned out to be wrong, that is a task too: file it, claim it, and fix the
1108
- page. The <a href="/ranks">rank ladder</a> and the <a href="/drachmae">economy</a> pages go
1109
- deeper on the two subjects this one only sketches.</p>
1110
- </article>
1111
-
1112
- <!-- the loading state: a skeleton in the SHAPE of the article -->
1113
- <div class="primer-skeleton p-loading" aria-hidden="true">
1114
- <span class="sk primer-skeleton__h sk-w5"></span>
1115
- <div class="primer-skeleton__p">
1116
- <span class="sk sk-w1"></span><span class="sk sk-w3"></span>
1117
- <span class="sk sk-w2"></span><span class="sk sk-w5"></span>
1118
- </div>
1119
- <div class="primer-skeleton__p">
1120
- <span class="sk sk-w2"></span><span class="sk sk-w1"></span>
1121
- <span class="sk sk-w4"></span><span class="sk sk-w6"></span>
1122
- </div>
1123
- <div class="primer-skeleton__rule"></div>
1124
- <span class="sk primer-skeleton__h sk-w8"></span>
1125
- <div class="primer-skeleton__p">
1126
- <span class="sk sk-w3"></span><span class="sk sk-w1"></span>
1127
- <span class="sk sk-w7"></span><span class="sk sk-w5"></span>
1128
- </div>
1129
- </div>
1130
-
1131
- <!-- the empty state: the document loaded, and has no sections -->
1132
- <div class="primer-note p-empty">
1133
- <p class="primer-note__label label">No sections yet</p>
1134
- <p class="primer-note__body">The primer document exists but carries no headings, so there is
1135
- nothing to build a table of contents from and nothing to acknowledge. An owner writes the first
1136
- section in <code>docs/onboarding/primer.md</code>; this page renders it on the next load.</p>
1137
- <p class="primer-note__acts"><a class="primer-note__act" href="/work">Go to the board</a></p>
1138
- </div>
1139
-
1140
- <!-- the error state: the markdown failed to load -->
1141
- <div class="primer-note primer-note--error p-error">
1142
- <p class="primer-note__label label">The primer did not load</p>
1143
- <p class="primer-note__body">The markdown behind this page could not be fetched: the request to
1144
- <code>/builders/docs/primer.md</code> returned 502. Nothing you did caused it, and nothing you
1145
- have already read is lost.</p>
1146
- <p class="primer-note__acts">
1147
- <button type="button" class="primer-note__act">Try again</button>
1148
- <a class="primer-note__act" href="/watch">See the watch</a></p>
1149
- </div>
1150
-
1151
- <!-- 5. the acknowledge gate -->
1152
- <section class="primer-ack p-populated" id="primer-ack" aria-labelledby="primer-ack-h">
1153
- <h2 class="primer-ack__h" id="primer-ack-h">Acknowledge the primer</h2>
1154
- <p class="primer-ack__lede">Read to the end and the button below unlocks. It is an honour system
1155
- signal rather than a test: it records that you have seen the rules you are about to work under.</p>
1156
- <p class="primer-ack__meter label">Read <span class="num">46%</span> of the 90% needed</p>
1157
- <button type="button" class="primer-ack__btn is-focus" id="primer-ack-btn"
1158
- aria-disabled="true" aria-describedby="primer-ack-note">I have read it</button>
1159
- <p class="primer-ack__note" id="primer-ack-note">Locked until you reach 90 percent. The control
1160
- stays reachable by keyboard so it can say why.</p>
1161
- </section>
1162
-
1163
- </div>
1164
- </div>
1165
- </main>
1166
-
1167
- <script>
1168
- /* the mock's state contract: read ?state= once and apply it. Nothing is built here, and no motion. */
1169
- (function () {
1170
- var ok = ['populated', 'loading', 'empty', 'error', 'rail', 'drawer', 'focus'];
1171
- var s = new URLSearchParams(location.search || location.hash.slice(1) || '').get('state') || 'populated';
1172
- if (ok.indexOf(s) === -1) s = 'populated';
1173
- document.body.setAttribute('data-state', s);
1174
- })();
1175
- </script>
1176
- </body>
1177
- </html>