@bongos/core 1.23.17 → 1.23.19

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 (59) hide show
  1. package/.bongos-core.json +109 -54
  2. package/clients/bongos-client/README.md +1 -1
  3. package/clients/bongos-client/bongos-client.global.js +2 -0
  4. package/clients/bongos-client/index.cjs +2 -0
  5. package/clients/bongos-client/index.d.ts +2 -0
  6. package/clients/bongos-client/index.mjs +2 -0
  7. package/docs/api/openapi.json +22 -1
  8. package/docs/api-reference.md +3 -2
  9. package/docs/copy-inventory.md +985 -934
  10. package/docs/copy-registry.json +1829 -1309
  11. package/docs/module-api-changelog.md +4 -0
  12. package/docs/page-inventory.json +10 -2
  13. package/docs/page-readings.json +601 -576
  14. package/modules/copy-desk/auto-close.js +9 -3
  15. package/modules/copy-desk/page-status.js +25 -13
  16. package/modules/copy-desk/tests/copy_page_auto_close.mjs +8 -0
  17. package/modules/copy-desk/tests/copy_page_status.mjs +2 -2
  18. package/modules/platform-identity/builder-of-the-week.js +48 -20
  19. package/modules/platform-identity/community-crowns.js +176 -0
  20. package/modules/platform-identity/community-leaderboard.js +1 -1
  21. package/modules/platform-identity/migrations/platform_identity_033_period_features.sql +43 -0
  22. package/modules/platform-identity/routes/community-leaderboard.js +25 -3
  23. package/modules/public-landing/public/account.html +3 -2
  24. package/modules/public-landing/public/community-crowns-first.states.json +15 -0
  25. package/modules/public-landing/public/community-crowns-new-year.states.json +15 -0
  26. package/modules/public-landing/public/community-crowns-none.states.json +15 -0
  27. package/modules/public-landing/public/community-empty.states.json +1 -1
  28. package/modules/public-landing/public/community-owner-two.states.json +2 -2
  29. package/modules/public-landing/public/community-owner.states.json +1 -1
  30. package/modules/public-landing/public/community-week-none.states.json +1 -1
  31. package/modules/public-landing/public/community.html +130 -22
  32. package/modules/public-landing/public/community.probes.json +20 -3
  33. package/modules/public-landing/public/community.states.json +8 -6
  34. package/modules/public-landing/public/connections.html +3 -2
  35. package/modules/public-landing/public/contact.html +3 -2
  36. package/modules/public-landing/public/guild.html +3 -2
  37. package/modules/public-landing/public/index.html +3 -2
  38. package/modules/public-landing/public/invitations.html +3 -2
  39. package/modules/public-landing/public/privacy.html +3 -2
  40. package/modules/public-landing/public/projects.html +3 -2
  41. package/modules/public-landing/public/terms.html +3 -2
  42. package/modules/ui-design/kit/fixtures/community-crowns-first.json +6 -0
  43. package/modules/ui-design/kit/fixtures/community-crowns-new-year.json +6 -0
  44. package/modules/ui-design/kit/fixtures/community-crowns-none.json +6 -0
  45. package/modules/ui-design/kit/fixtures/community-crowns.json +6 -0
  46. package/modules/ui-design/kit/serve.js +14 -0
  47. package/package-lock.json +2 -2
  48. package/package.json +1 -1
  49. package/release-notes.json +12 -0
  50. package/scripts/bongos/run-unit-tests.js +4 -0
  51. package/src/module-api.js +1 -1
  52. package/src/platform-server.js +4 -3
  53. package/tests/community_crowns.mjs +369 -0
  54. package/tests/community_crowns_db.mjs +164 -0
  55. package/tests/copy_stuck_page_tweaks.mjs +39 -2
  56. package/tests/hub_account_page.mjs +2 -2
  57. package/tests/hub_community_page.mjs +144 -29
  58. package/tests/landing_legal_pages.mjs +2 -2
  59. package/tests/privacy_matrix.mjs +68 -9
@@ -9,7 +9,7 @@
9
9
  "ignoreConsole": ["/api/(gds|bongos)/me", "/scouting", "\\b40[13]\\b", "Unauthorized", "Forbidden"],
10
10
  "ignoreControls": [".vh"],
11
11
  "states": {
12
- "out-empty": { "auth": false, "actions": [["wait", 400]], "expect": { "visible": ["#boardEmpty", "#boardWindow"], "hidden": ["#boardFailed", "#boardLoading", "#find", "#recruit"], "count": [["#boardList .commRow", 0]], "text": [["#boardEmpty", "No builders on the leaderboard yet."]] } }
12
+ "out-empty": { "auth": false, "url": "/community/leaderboard", "actions": [["wait", 400]], "expect": { "visible": ["#boardEmpty", "#boardWindow"], "hidden": ["#boardFailed", "#boardLoading", "#find", "#recruit"], "count": [["#boardList .commRow", 0]], "text": [["#boardEmpty", "No builders on the leaderboard yet."]] } }
13
13
  },
14
14
  "reducedMotion": { "auth": false, "actions": [["wait", 400]] }
15
15
  }
@@ -9,8 +9,8 @@
9
9
  "ignoreConsole": ["/api/(gds|bongos)/me", "/scouting", "\\b40[13]\\b", "Unauthorized", "Forbidden"],
10
10
  "ignoreControls": [".vh"],
11
11
  "states": {
12
- "in-owner-two": { "auth": true, "actions": [["wait", 600]], "expect": { "visible": ["#boardFor", "#boardForPick"], "value": [["#boardForPick", "0"]], "count": [["#boardForPick option", 2], ["#boardList a.commRecruit", 6]], "href": [["#boardList .commRow:first-child .commRecruit", "https://mercury.example.test/builders/watch?invite=priyanair"]] } },
13
- "in-owner-two-picked": { "auth": true, "actions": [["wait", 600], ["select", "#boardForPick", "1"], ["wait", 200]], "expect": { "value": [["#boardForPick", "1"]], "href": [["#boardList .commRow:first-child .commRecruit", "https://tidepool.example.test/builders/watch?invite=priyanair"]], "attr": [["#boardList .commRow:first-child .commRecruit", "aria-label", "Recruit Priya Nair to Tidepool (opens in a new tab)"]] } }
12
+ "in-owner-two": { "auth": true, "url": "/community/leaderboard", "actions": [["wait", 600]], "expect": { "visible": ["#boardFor", "#boardForPick"], "value": [["#boardForPick", "0"]], "count": [["#boardForPick option", 2], ["#boardList a.commRecruit", 6]], "href": [["#boardList .commRow:first-child .commRecruit", "https://mercury.example.test/builders/watch?invite=priyanair"]] } },
13
+ "in-owner-two-picked": { "auth": true, "url": "/community/leaderboard", "actions": [["wait", 600], ["select", "#boardForPick", "1"], ["wait", 200]], "expect": { "value": [["#boardForPick", "1"]], "href": [["#boardList .commRow:first-child .commRecruit", "https://tidepool.example.test/builders/watch?invite=priyanair"]], "attr": [["#boardList .commRow:first-child .commRecruit", "aria-label", "Recruit Priya Nair to Tidepool (opens in a new tab)"]] } }
14
14
  },
15
15
  "reducedMotion": { "auth": true, "actions": [["wait", 600]] }
16
16
  }
@@ -9,7 +9,7 @@
9
9
  "ignoreConsole": ["/api/(gds|bongos)/me", "/scouting", "\\b40[13]\\b", "Unauthorized", "Forbidden"],
10
10
  "ignoreControls": [".vh"],
11
11
  "states": {
12
- "in-owner": { "auth": true, "actions": [["wait", 600]], "expect": { "visible": ["#board", "#boardFor", "#who"], "hidden": ["#find", "#recruit", "#boardFailed"], "count": [["#boardList .commRow", 6], ["#boardList a.commRecruit", 6]], "text": [["#boardFor", "Recruit opens Mercury’s hall with their name filled in, and you send the invite there."], ["#boardList .commRow:first-child .commRecruit", "Recruit"]], "href": [["#boardList .commRow:first-child .commRecruit", "https://mercury.example.test/builders/watch?invite=priyanair"]] } },
12
+ "in-owner": { "auth": true, "url": "/community/leaderboard", "actions": [["wait", 600]], "expect": { "visible": ["#board", "#boardFor", "#who"], "hidden": ["#find", "#recruit", "#boardFailed"], "count": [["#boardList .commRow", 6], ["#boardList a.commRecruit", 6]], "text": [["#boardFor", "Recruit opens Mercury’s hall with their name filled in, and you send the invite there."], ["#boardList .commRow:first-child .commRecruit", "Recruit"]], "href": [["#boardList .commRow:first-child .commRecruit", "https://mercury.example.test/builders/watch?invite=priyanair"]] } },
13
13
  "in-owner-find": { "auth": true, "url": "/community/find", "actions": [["wait", 600], ["fill", "#findQ", "pri"], ["click", "#findBtn"], ["wait", 300]], "expect": { "visible": ["#find", "#findFor"], "hidden": ["#board", "#recruit"], "count": [["#findList .mineRow", 2], ["#findList .mineRow__actions a.commRecruit", 2]], "href": [["#findList .mineRow:first-child .commRecruit", "https://mercury.example.test/builders/watch?invite=priyanair"]] } }
14
14
  },
15
15
  "reducedMotion": { "auth": true, "actions": [["wait", 600]] }
@@ -10,7 +10,7 @@
10
10
  "ignoreControls": [".vh"],
11
11
  "states": {
12
12
  "out-week-none": { "auth": false, "url": "/community/week", "actions": [["wait", 400]], "expect": { "visible": ["#week", "#weekNone", "#weekRuleH"], "hidden": ["#weekCrown", "#weekLoading", "#weekFailed", "#pastH"], "count": [["#weekPast .commRow", 0]], "text": [["#weekNone", "No builder of the week for 19–25 Oct 2026."]] } },
13
- "out-board-no-crown": { "auth": false, "actions": [["wait", 400]], "expect": { "visible": ["#board", "#boardList"], "hidden": ["#boardCrown"] } }
13
+ "out-board-no-crown": { "auth": false, "url": "/community/leaderboard", "actions": [["wait", 400]], "expect": { "visible": ["#board", "#boardList"], "hidden": ["#boardCrown"] } }
14
14
  },
15
15
  "reducedMotion": { "auth": false, "actions": [["wait", 400]] }
16
16
  }
@@ -5,15 +5,17 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <!-- THE COMMUNITY PAGES (task 1003363; ADR 0217 D1, ADR 0337 D1/D3/D4.1, the community
7
7
  spec docs/specs/bongos-v1-community-tab.md D1/D3/D4/D8). Who is building, across every
8
- project, as four sub-pages of the bar's Community menu (owner, 2026-10-27), all served
9
- from this one file: /community is the leaderboard, /community/week the builder of the
10
- week (task 1002981, spec D5), /community/find the builder search, /community/recruiters
11
- the builders who hide their numbers but are open to recruiters.
8
+ project, as five sub-pages of the bar's Community menu (owner, 2026-10-27), all served
9
+ from this one file: /community is the community home (task 1004902: the builders of the
10
+ week, month and year, and a door to each page), /community/leaderboard the leaderboard,
11
+ /community/week the builder of the week (task 1002981, spec D5), /community/find the
12
+ builder search, /community/recruiters the builders who hide their numbers but are open
13
+ to recruiters.
12
14
  The script shows the section the path names and marks it current in the menu.
13
- VIEWING IS UNGATED (ADR 0217 D1): the leaderboard, the builder of the week and the search
14
- are the same for every viewer, signed in or not. All three reads are public,
15
+ VIEWING IS UNGATED (ADR 0217 D1): the home, the leaderboard, the builder of the week and
16
+ the search are the same for every viewer, signed in or not. All four reads are public,
15
17
  viewer-independent routes (modules/platform-identity/routes/community-leaderboard.js,
16
- which also serves the builder of the week, and community-search.js),
18
+ which also serves the builder of the week and the crowns, and community-search.js),
17
19
  which decide WHO appears through account-visibility.js; these pages add no rule of
18
20
  their own. The one viewer-relative page is the recruiter list: drawn only from a 200 of
19
21
  GET /scouting, whose door (a project owner, or project.curate) is the server's, never
@@ -27,7 +29,7 @@
27
29
  platform-identity is on. noindex until the SEO goal decides (owner, 2026-10-27).
28
30
  Server-stamped like the footer doors: {{…}} tokens filled by landingPage(). -->
29
31
  <title>{{productName}} — Community</title>
30
- <meta name="description" content="Who is building on {{productName}}: the leaderboard across every project, and a search for builders by name.">
32
+ <meta name="description" content="Who is building on {{productName}}: the builders of the week, month and year, the leaderboard across every project, and a search for builders by name.">
31
33
  <meta name="robots" content="noindex">
32
34
  <link rel="preconnect" href="https://fonts.googleapis.com">
33
35
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
@@ -110,6 +112,23 @@
110
112
  .commSub{margin:24px 0 4px;font-family:var(--font-body);font-size:14.5px;font-weight:500;color:var(--ink);}
111
113
  .weekRows .commRow{grid-template-columns:6.5rem 36px minmax(0,1fr) auto;}
112
114
  .weekRows .commPlace{font-family:var(--label-face);}
115
+ /* the community home (task 1004902): the week's, month's and year's crowns side by side in
116
+ the week page's pieces, then a door to each community page */
117
+ .homeCrowns{list-style:none;margin:6px 0 4px;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 clamp(20px,3vw,40px);}
118
+ .homeCard{display:flex;flex-direction:column;align-items:flex-start;gap:14px;min-width:0;padding:20px 0 24px;border-top:1px solid var(--rule-soft);}
119
+ .homeCard .commSub{margin:0;}
120
+ .homeBody{display:flex;flex-direction:column;gap:12px;min-width:0;}
121
+ .homeCard .crownWho .connAv{width:48px;height:48px;}
122
+ .homeCard .crownName{font-size:clamp(20px,2.2vw,24px);}
123
+ .homeCard .crownNums{text-align:left;}
124
+ .homeCard .commMsg{margin:0;}
125
+ .homeLast{margin:0;font-size:13.5px;line-height:1.5;color:var(--ink-soft);}
126
+ .homeLast strong{font-weight:500;color:var(--ink);}
127
+ .homeDoors{list-style:none;display:flex;flex-wrap:wrap;gap:10px 12px;margin:10px 0 0;padding:0;}
128
+ .homeDoors .btn{text-transform:none;}
129
+ @media (max-width:760px){
130
+ .homeCrowns{grid-template-columns:minmax(0,1fr);}
131
+ }
113
132
  @media (max-width:480px){
114
133
  .commCrown{grid-template-columns:minmax(0,1fr);}
115
134
  .crownNums{text-align:left;}
@@ -154,7 +173,8 @@
154
173
  <div class="menuBand" id="menuCommunity" data-menu="community" hidden>
155
174
  <div class="bandIn">
156
175
  <ul class="bandRow">
157
- <li class="bandCell"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
176
+ <li class="bandCell"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li>
177
+ <li class="bandCell"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
158
178
  <li class="bandCell"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li>
159
179
  <li class="bandCell"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li>
160
180
  <li class="bandCell"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li>
@@ -169,7 +189,7 @@
169
189
  <li class="bandCell"><a class="bandT" href="/projects?view=map&amp;sub=table">Table</a><span class="bandC">the same projects as rows</span></li>
170
190
  <li class="bandCell" id="mineCell"><a class="bandT" href="/projects?view=mine">Your projects</a><span class="bandC">the ones you own</span></li>
171
191
  <li class="bandCell"><a class="bandT" href="/projects?view=new">New project</a><span class="bandC">five questions and a home</span></li>
172
- <li class="bandCell bandFold"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li>
192
+ <li class="bandCell bandFold"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li>
173
193
  </ul>
174
194
  </div>
175
195
  </div>
@@ -188,13 +208,38 @@
188
208
  <main class="acct" id="comm">
189
209
  <h1 class="vh">Community</h1>
190
210
 
191
- <!-- FOUR SUB-PAGES, ONE FILE: every section is real markup; the script un-hides the one
192
- the path names (/community, /community/week, /community/find, /community/recruiters). -->
211
+ <!-- FIVE SUB-PAGES, ONE FILE: every section is real markup; the script un-hides the one
212
+ the path names (/community, /community/leaderboard, /community/week, /community/find,
213
+ /community/recruiters). -->
193
214
  <div class="mineExtra">
215
+ <!-- THE COMMUNITY HOME (task 1004902; owner, 2026-10-27): the builders of the week, the
216
+ month and the year from GET /community/crowns (community-crowns.js decides and
217
+ records them), the rule in plain words, then a door to each community page. The
218
+ same for every viewer but "Builders you may know", shown signed in like its menu item. -->
219
+ <section id="home" data-view="home" aria-labelledby="homeH">
220
+ <h2 id="homeH">Top builders</h2>
221
+ <p class="commMsg" id="homeLoading" role="status">Reading the top builders…</p>
222
+ <p class="projMsg err" id="homeFailed" role="alert" hidden></p>
223
+ <ul class="homeCrowns" id="homeCrowns" hidden>
224
+ <li class="homeCard"><h3 class="commSub">Builder of the week</h3><p class="crownWhen" id="crownWeekWhen"></p><div class="homeBody" id="crownWeek"></div></li>
225
+ <li class="homeCard"><h3 class="commSub">Builder of the month</h3><p class="crownWhen" id="crownMonthWhen"></p><div class="homeBody" id="crownMonth"></div></li>
226
+ <li class="homeCard"><h3 class="commSub">Builder of the year</h3><p class="crownWhen" id="crownYearWhen"></p><div class="homeBody" id="crownYear"></div><p class="homeLast" id="crownYearLast" hidden></p></li>
227
+ </ul>
228
+ <p class="commNote" id="homeRule">Each is the builder who earned the most {{currency}} across every project in that time, among the builders who shipped at least one work in it. A tie goes to whoever shipped more works, then to whoever earned more karma. Builders who hide their numbers or keep their account private are not counted. The week and the month are decided once, when they end; the year shows the leader so far, and is decided on 1 January.</p>
229
+ <h3 class="commSub" id="doorsH">Community pages</h3>
230
+ <ul class="homeDoors" aria-labelledby="doorsH">
231
+ <li><a class="btn ghost" href="/community/leaderboard">Leaderboard</a></li>
232
+ <li><a class="btn ghost" href="/community/week">Builder of the week</a></li>
233
+ <li><a class="btn ghost" href="/community/find">Find a builder</a></li>
234
+ <li><a class="btn ghost" href="/community/recruiters">Open to recruiters</a></li>
235
+ <li class="knowCell" hidden><a class="btn ghost" href="/connections#connSuggest">Builders you may know</a></li>
236
+ </ul>
237
+ </section>
238
+
194
239
  <!-- THE LEADERBOARD (spec D3): GET /community/leaderboard, one window and one craft
195
240
  at a time. The server ranks; this page draws its rows in the order and with the
196
241
  `place` it was given, and every count it prints is the length of a list. -->
197
- <section id="board" data-view="leaderboard" aria-labelledby="boardH">
242
+ <section id="board" data-view="leaderboard" aria-labelledby="boardH" hidden>
198
243
  <h2 id="boardH">Leaderboard</h2>
199
244
  <p class="commCrownLine" id="boardCrown" hidden></p>
200
245
  <div class="commFilters">
@@ -236,7 +281,7 @@
236
281
  <p class="commMsg" id="weekNone" hidden></p>
237
282
  <h3 class="commSub" id="weekRuleH">How it is chosen</h3>
238
283
  <p class="commNote">The builder who earned the most {{currency}} across every project in one week, Monday to Sunday (UTC), among the builders who shipped at least one work that week. A tie goes to whoever shipped more works, then to whoever earned more karma. Builders who hide their numbers or keep their account private are not counted.</p>
239
- <p class="commNote">Each week is decided once, the first time anyone opens this page after it ends, and it does not change after that. A project reports a builder’s numbers when they sign in or ship there, so a week counts work when it was reported, not when it was done.</p>
284
+ <p class="commNote">Each week is decided once, the first time a community page asks for it after it ends, and it does not change after that. A project reports a builder’s numbers when they sign in or ship there, so a week counts work when it was reported, not when it was done.</p>
240
285
  <h3 class="commSub" id="pastH" hidden>Past weeks</h3>
241
286
  <ol class="commRows weekRows" id="weekPast" aria-labelledby="pastH"></ol>
242
287
  </section>
@@ -304,10 +349,11 @@
304
349
  var QUERY_MIN = 2;
305
350
  var QUERY_MAX = 100;
306
351
  var CRAFT_WORD = { engineer: 'engineer', artist: 'artist', ideator: 'ideator', ui: 'designer' };
307
- // The four sub-pages this file is served as (platform-server.js's /community routes);
308
- // the path picks one, and its menu items are marked current.
352
+ // The five sub-pages this file is served as (platform-server.js's /community routes);
353
+ // the path picks one, and its menu items are marked current. The home adds no title.
309
354
  var VIEWS = {
310
- leaderboard: { path: '/community', section: 'board', title: 'Leaderboard' },
355
+ home: { path: '/community', section: 'home', title: '' },
356
+ leaderboard: { path: '/community/leaderboard', section: 'board', title: 'Leaderboard' },
311
357
  week: { path: '/community/week', section: 'week', title: 'Builder of the week' },
312
358
  find: { path: '/community/find', section: 'find', title: 'Find a builder' },
313
359
  recruiters: { path: '/community/recruiters', section: 'recruit', title: 'Open to recruiters' },
@@ -354,8 +400,8 @@
354
400
  return what + ' could not be read. Reload the page to try again.';
355
401
  }
356
402
  function viewOf(pathname) {
357
- var m = String(pathname || '').replace(/\/+$/, '').match(/^\/community(?:\/(week|find|recruiters))?$/);
358
- return m ? (m[1] || 'leaderboard') : 'leaderboard';
403
+ var m = String(pathname || '').replace(/\/+$/, '').match(/^\/community(?:\/(leaderboard|week|find|recruiters))?$/);
404
+ return m ? (m[1] || 'home') : 'home';
359
405
  }
360
406
 
361
407
  // ── one builder: the avatar, then the name over the @handle ─────────────────
@@ -523,6 +569,11 @@
523
569
  var box = $('weekCrown');
524
570
  box.textContent = '';
525
571
  if (span) box.appendChild(el('p', 'crownWhen', span));
572
+ fillCrown(box, w);
573
+ box.hidden = false;
574
+ }
575
+ // the winner, their credits and works: the week page's crown and each home card
576
+ function fillCrown(box, w) {
526
577
  var who = el('div', 'crownWho');
527
578
  who.appendChild(face(w));
528
579
  var main = el('div', 'mineRow__main');
@@ -535,7 +586,6 @@
535
586
  nums.appendChild(stat(num(w.credits).toLocaleString(), UNIT));
536
587
  nums.appendChild(stat(String(ships), ships === 1 ? 'work shipped' : 'works shipped'));
537
588
  box.appendChild(nums);
538
- box.hidden = false;
539
589
  }
540
590
  function pastRow(p) {
541
591
  var li = el('li', 'commRow');
@@ -570,6 +620,63 @@
570
620
  });
571
621
  }
572
622
 
623
+ // ── the community home: the builders of the week, month and year (task 1004902) ──
624
+ // community-crowns.js decides and records each; this draws what it was sent.
625
+ var LONG_MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
626
+ function utcDay(iso) {
627
+ var d = new Date(String(iso) + 'T00:00:00Z');
628
+ return /^\d{4}-\d{2}-\d{2}$/.test(String(iso)) && isFinite(d.getTime()) ? d : null;
629
+ }
630
+ function monthLabel(iso) {
631
+ var d = utcDay(iso);
632
+ return d ? LONG_MONTHS[d.getUTCMonth()] + ' ' + d.getUTCFullYear() : '';
633
+ }
634
+ function dayLabel(iso) {
635
+ var d = utcDay(iso);
636
+ return d ? d.getUTCDate() + ' ' + MONTHS[d.getUTCMonth()] + ' ' + d.getUTCFullYear() : '';
637
+ }
638
+ function homeCard(id, when, w, none) {
639
+ $(id + 'When').textContent = when;
640
+ var box = $(id);
641
+ box.textContent = '';
642
+ if (w) fillCrown(box, w);
643
+ else box.appendChild(el('p', 'commMsg', none));
644
+ }
645
+ function loadHome() {
646
+ return read('/community/crowns').then(function (r) {
647
+ $('homeLoading').hidden = true;
648
+ if (!r.ok) {
649
+ $('homeFailed').textContent = failText(r.status, 'The top builders');
650
+ $('homeFailed').hidden = false;
651
+ return;
652
+ }
653
+ var week = r.data.week || {};
654
+ var month = r.data.month || {};
655
+ var year = r.data.year || {};
656
+ var span = weekSpan(week.start, true);
657
+ homeCard('crownWeek', span, week.winner, span ? 'No builder of the week for ' + span + '.' : 'No builder of the week yet.');
658
+ var mon = monthLabel(month.start);
659
+ homeCard('crownMonth', mon, month.winner, month.first_crown
660
+ ? 'The first builder of the month is named on ' + dayLabel(month.first_crown) + '.'
661
+ : (mon ? 'No builder of the month for ' + mon + '.' : 'No builder of the month yet.'));
662
+ var y = utcDay(year.start);
663
+ var yr = y ? String(y.getUTCFullYear()) : '';
664
+ var since = year.since && year.since !== year.start ? dayLabel(year.since) : '';
665
+ homeCard('crownYear', yr ? yr + ' so far' + (since ? ', since ' + since : '') : '', year.winner, yr ? 'No builder of ' + yr + ' yet.' : 'No builder of the year yet.');
666
+ var last = year.last && year.last.winner;
667
+ var lastYear = year.last && utcDay(year.last.start);
668
+ var line = $('crownYearLast');
669
+ line.textContent = '';
670
+ line.hidden = !(last && lastYear);
671
+ if (last && lastYear) {
672
+ line.appendChild(el('span', null, lastYear.getUTCFullYear() + ': '));
673
+ line.appendChild(el('strong', null, last.display_name || last.handle || last.github_login || 'Builder'));
674
+ line.appendChild(el('span', null, ', ' + num(last.credits).toLocaleString() + ' ' + UNIT));
675
+ }
676
+ $('homeCrowns').hidden = false;
677
+ });
678
+ }
679
+
573
680
  // ── the search ──────────────────────────────────────────────────────────────
574
681
  function say(text, kind) {
575
682
  var s = $('findStatus');
@@ -696,10 +803,11 @@
696
803
  Array.prototype.forEach.call(document.querySelectorAll('a[href="' + view.path + '"]'), function (a) {
697
804
  a.setAttribute('aria-current', 'page');
698
805
  });
699
- document.title = document.title + ' · ' + view.title;
806
+ if (view.title) document.title = document.title + ' · ' + view.title;
700
807
  $('signinTop').setAttribute('href', '/api/bongos/auth/web/start?return=' + view.path + '&repos=1');
701
808
  if (VIEW === 'leaderboard') { loadBoard(); read('/community/builder-of-the-week').then(crownLine); }
702
- if (VIEW === 'week') loadWeek();
809
+ if (VIEW === 'home') loadHome();
810
+ else if (VIEW === 'week') loadWeek();
703
811
  else if (VIEW === 'recruiters') bar.ready.then(function (me) { if (me) loadRecruit(); else showRecruit('recruitDoor'); });
704
812
  else bar.ready.then(function (me) { if (me) loadOwned(me, $(VIEW === 'find' ? 'findFor' : 'boardFor')); });
705
813
  })();
@@ -4,23 +4,39 @@
4
4
  "surface": "public-landing",
5
5
  "probes": [
6
6
  {
7
- "name": "community signed out: the leaderboard for everyone; Community the current section, Leaderboard the current item",
7
+ "name": "community home signed out: the three crowns and a door to each page; Community home the current item",
8
8
  "auth": false,
9
9
  "width": 1440,
10
10
  "steps": [["wait", 400], ["click", "#commTrig"], ["wait", 150]],
11
+ "expect": {
12
+ "open": "#menuCommunity",
13
+ "visible": ["#homeCrowns", "#signinTop"],
14
+ "hidden": ["#board", "#find", "#recruit", ".homeDoors .knowCell"],
15
+ "count": [["#homeCrowns .crownName", 3], [".homeDoors li:not([hidden])", 4], ["#menuCommunity a[aria-current=\"page\"]", 1]],
16
+ "attr": [["#commTrig", "aria-current", "true"]],
17
+ "href": [["#menuCommunity a[aria-current=\"page\"]", "/community"], [".homeDoors li:first-child a", "/community/leaderboard"], ["#signinTop", "/api/bongos/auth/web/start?return=/community&repos=1"]]
18
+ }
19
+ },
20
+ {
21
+ "name": "community leaderboard signed out: the board for everyone; Community the current section, Leaderboard the current item",
22
+ "auth": false,
23
+ "width": 1440,
24
+ "url": "/community/leaderboard",
25
+ "steps": [["wait", 400], ["click", "#commTrig"], ["wait", 150]],
11
26
  "expect": {
12
27
  "open": "#menuCommunity",
13
28
  "visible": ["#boardList", "#signinTop"],
14
- "hidden": ["#find", "#recruit"],
29
+ "hidden": ["#home", "#find", "#recruit"],
15
30
  "count": [["#boardList .commRow", 6], ["#menuCommunity a[aria-current=\"page\"]", 1]],
16
31
  "attr": [["#commTrig", "aria-current", "true"]],
17
- "href": [["#menuCommunity a[aria-current=\"page\"]", "/community"], ["#signinTop", "/api/bongos/auth/web/start?return=/community&repos=1"]]
32
+ "href": [["#menuCommunity a[aria-current=\"page\"]", "/community/leaderboard"], ["#signinTop", "/api/bongos/auth/web/start?return=/community/leaderboard&repos=1"]]
18
33
  }
19
34
  },
20
35
  {
21
36
  "name": "community: the 7-day window from the dropdown re-reads the board",
22
37
  "auth": false,
23
38
  "width": 1440,
39
+ "url": "/community/leaderboard",
24
40
  "steps": [["wait", 400], ["select", "#boardWindow", "7d"], ["wait", 300]],
25
41
  "expect": {
26
42
  "count": [["#boardList .commRow", 2]],
@@ -32,6 +48,7 @@
32
48
  "name": "community: a craft filters the board and renumbers nothing the server did not",
33
49
  "auth": false,
34
50
  "width": 390,
51
+ "url": "/community/leaderboard",
35
52
  "steps": [["wait", 400], ["click", "#craftTabs [data-craft=\"engineer\"]"], ["wait", 300]],
36
53
  "expect": {
37
54
  "count": [["#boardList .commRow", 3]],
@@ -8,11 +8,13 @@
8
8
  "ignoreConsole": ["/api/(gds|bongos)/me", "/scouting", "\\b40[13]\\b", "Unauthorized", "Forbidden"],
9
9
  "ignoreControls": [".vh"],
10
10
  "states": {
11
- "out": { "auth": false, "actions": [["wait", 400]], "expect": { "visible": ["#board", "#boardList", "#boardWindow", "#signinTop", "#projTrig", "#boardCrown"], "hidden": ["#week", "#find", "#recruit", "#who", "#boardLoading", "#boardFailed", "#boardEmpty"], "href": [["#boardCrown a", "/community/week"]], "count": [["#boardList .commRow", 6]], "value": [["#boardWindow", "all"]], "attr": [["#craftTabs [data-craft=\"\"]", "aria-pressed", "true"], ["#commTrig", "aria-current", "true"], ["#menuCommunity a[href=\"/community\"]", "aria-current", "page"]], "text": [["#boardList .commRow:first-child .mineRow__name", "Priya Nair"], ["#boardList .commRow:first-child .commNum", "18,420"], ["#boardList .commRow:first-child .mineRow__hint", "212 works shipped · 64 karma"], ["#boardNote", "Credits earned across every project, since each builder started."], ["#boardCrown", "Builder of the week: Ada Okafor, 1,240 credits, 19–25 Oct"]] } },
12
- "out-30d": { "auth": false, "actions": [["wait", 400], ["select", "#boardWindow", "30d"], ["wait", 300]], "expect": { "count": [["#boardList .commRow", 3]], "value": [["#boardWindow", "30d"]], "text": [["#boardList .commRow:first-child .mineRow__name", "Ada Okafor"], ["#boardNote", "Credits earned in the last 30 days, across every project."]] } },
13
- "out-artists": { "auth": false, "actions": [["wait", 400], ["click", "#craftTabs [data-craft=\"artist\"]"], ["wait", 300]], "expect": { "count": [["#boardList .commRow", 1]], "text": [["#boardList .commRow:first-child .mineRow__name", "Ada Okafor"], ["#boardList .commRow:first-child .commPlace", "1"]] } },
14
- "out-community-band": { "auth": false, "actions": [["wait", 400], ["clickIfVisible", "#commTrig"], ["wait", 300]], "expect": { "hidden": ["#menuCommunity .knowCell"], "count": [["#menuCommunity .bandCell:not([hidden])", 4]], "attr": [["#menuCommunity a[href=\"/community\"]", "aria-current", "page"]] } },
15
- "in-community-band": { "auth": true, "actions": [["wait", 400], ["clickIfVisible", "#commTrig"], ["wait", 300]], "expect": { "count": [["#menuCommunity .bandCell:not([hidden])", 5]], "href": [["#menuCommunity .knowCell a", "/connections#connSuggest"]] } },
11
+ "out": { "auth": false, "actions": [["wait", 400]], "expect": { "visible": ["#home", "#homeCrowns", "#crownWeek .crownName", "#crownMonth .crownName", "#crownYear .crownName", "#homeRule", "#signinTop"], "hidden": ["#board", "#week", "#find", "#recruit", "#who", "#homeLoading", "#homeFailed", "#crownYearLast", ".homeDoors .knowCell"], "count": [[".homeDoors li:not([hidden])", 4]], "href": [[".homeDoors li:first-child a", "/community/leaderboard"]], "attr": [["#commTrig", "aria-current", "true"], ["#menuCommunity a[href=\"/community\"]", "aria-current", "page"]], "text": [["#crownWeekWhen", "26 Oct – 1 Nov 2026"], ["#crownWeek .crownName", "Ada Okafor"], ["#crownMonthWhen", "October 2026"], ["#crownMonth .crownName", "Priya Nair"], ["#crownMonth .crownNums div:first-child .commNum", "6,120"], ["#crownYearWhen", "2026 so far, since 27 Sep 2026"], ["#crownYear .crownName", "Maximiliana van der Berghe-Lindqvist"]] } },
12
+ "in": { "auth": true, "actions": [["wait", 600]], "expect": { "visible": ["#home", "#homeCrowns", "#who", ".homeDoors .knowCell"], "hidden": ["#board", "#signinTop", "#homeFailed"], "count": [[".homeDoors li:not([hidden])", 5]], "href": [[".homeDoors .knowCell a", "/connections#connSuggest"]] } },
13
+ "out-board": { "auth": false, "url": "/community/leaderboard", "actions": [["wait", 400]], "expect": { "visible": ["#board", "#boardList", "#boardWindow", "#signinTop", "#projTrig", "#boardCrown"], "hidden": ["#home", "#week", "#find", "#recruit", "#who", "#boardLoading", "#boardFailed", "#boardEmpty"], "href": [["#boardCrown a", "/community/week"]], "count": [["#boardList .commRow", 6]], "value": [["#boardWindow", "all"]], "attr": [["#craftTabs [data-craft=\"\"]", "aria-pressed", "true"], ["#commTrig", "aria-current", "true"], ["#menuCommunity a[href=\"/community/leaderboard\"]", "aria-current", "page"]], "text": [["#boardList .commRow:first-child .mineRow__name", "Priya Nair"], ["#boardList .commRow:first-child .commNum", "18,420"], ["#boardList .commRow:first-child .mineRow__hint", "212 works shipped · 64 karma"], ["#boardNote", "Credits earned across every project, since each builder started."], ["#boardCrown", "Builder of the week: Ada Okafor, 1,240 credits, 19–25 Oct"]] } },
14
+ "out-30d": { "auth": false, "url": "/community/leaderboard", "actions": [["wait", 400], ["select", "#boardWindow", "30d"], ["wait", 300]], "expect": { "count": [["#boardList .commRow", 3]], "value": [["#boardWindow", "30d"]], "text": [["#boardList .commRow:first-child .mineRow__name", "Ada Okafor"], ["#boardNote", "Credits earned in the last 30 days, across every project."]] } },
15
+ "out-artists": { "auth": false, "url": "/community/leaderboard", "actions": [["wait", 400], ["click", "#craftTabs [data-craft=\"artist\"]"], ["wait", 300]], "expect": { "count": [["#boardList .commRow", 1]], "text": [["#boardList .commRow:first-child .mineRow__name", "Ada Okafor"], ["#boardList .commRow:first-child .commPlace", "1"]] } },
16
+ "out-community-band": { "auth": false, "actions": [["wait", 400], ["clickIfVisible", "#commTrig"], ["wait", 300]], "expect": { "hidden": ["#menuCommunity .knowCell"], "count": [["#menuCommunity .bandCell:not([hidden])", 5]], "attr": [["#menuCommunity a[href=\"/community\"]", "aria-current", "page"]] } },
17
+ "in-community-band": { "auth": true, "actions": [["wait", 400], ["clickIfVisible", "#commTrig"], ["wait", 300]], "expect": { "count": [["#menuCommunity .bandCell:not([hidden])", 6]], "href": [["#menuCommunity .knowCell a", "/connections#connSuggest"]] } },
16
18
  "in-projects-band": { "auth": true, "actions": [["wait", 400], ["click", "#projTrig"], ["wait", 300]], "expect": { "visible": ["#menuProjects"], "count": [["#menuProjects .knowCell:not([hidden])", 1]] } },
17
19
  "out-projects-band": { "auth": false, "actions": [["wait", 400], ["click", "#projTrig"], ["wait", 300]], "expect": { "visible": ["#menuProjects"], "attr": [["#menuProjects a[href=\"/community\"]", "aria-current", "page"]] } },
18
20
  "out-week": { "auth": false, "url": "/community/week", "actions": [["wait", 400]], "expect": { "visible": ["#week", "#weekCrown", "#pastH", "#weekPast"], "hidden": ["#board", "#find", "#recruit", "#weekLoading", "#weekFailed", "#weekNone"], "count": [["#weekPast .commRow", 4]], "attr": [["#menuCommunity a[href=\"/community/week\"]", "aria-current", "page"]], "text": [["#weekCrown .crownWhen", "19–25 Oct 2026"], ["#weekCrown .crownName", "Ada Okafor"], ["#weekCrown .crownNums div:first-child .commNum", "1,240"], ["#weekCrown .crownNums div:last-child .commUnit", "works shipped"], ["#weekPast .commRow:first-child .commPlace", "12–18 Oct"], ["#weekPast .commRow:nth-child(3) .commPlace", "28 Sep – 4 Oct"]] } },
@@ -21,7 +23,7 @@
21
23
  "out-find-search": { "auth": false, "url": "/community/find", "actions": [["wait", 400], ["fill", "#findQ", "pri"], ["click", "#findBtn"], ["wait", 300]], "expect": { "count": [["#findList .mineRow", 2]], "text": [["#findStatus", "2 builders found."], ["#findList .mineRow:first-child .mineRow__hint", "engineer · designer"]] } },
22
24
  "out-recruiters": { "auth": false, "url": "/community/recruiters", "actions": [["wait", 400]], "expect": { "visible": ["#recruit", "#recruitDoor", "#recruitSignin"], "hidden": ["#board", "#find", "#recruitLoading", "#recruitClosed"], "count": [["#recruitList .mineRow", 0]], "attr": [["#menuCommunity a[href=\"/community/recruiters\"]", "aria-current", "page"]] } },
23
25
  "in-recruiters": { "auth": true, "url": "/community/recruiters", "actions": [["wait", 600]], "expect": { "visible": ["#recruit", "#recruitClosed", "#who"], "hidden": ["#recruitDoor", "#recruitLoading", "#recruitFailed"], "count": [["#recruitList .mineRow", 0]] } },
24
- "in": { "auth": true, "actions": [["wait", 600]], "expect": { "visible": ["#board", "#who"], "hidden": ["#find", "#recruit", "#signinTop", "#boardFailed"], "count": [["#boardList .commRow", 6]] } }
26
+ "in-board": { "auth": true, "url": "/community/leaderboard", "actions": [["wait", 600]], "expect": { "visible": ["#board", "#who"], "hidden": ["#find", "#recruit", "#signinTop", "#boardFailed"], "count": [["#boardList .commRow", 6]] } }
25
27
  },
26
28
  "reducedMotion": { "auth": false, "actions": [["wait", 400]] }
27
29
  }
@@ -90,7 +90,8 @@
90
90
  <div class="menuBand" id="menuCommunity" data-menu="community" hidden>
91
91
  <div class="bandIn">
92
92
  <ul class="bandRow">
93
- <li class="bandCell"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
93
+ <li class="bandCell"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li>
94
+ <li class="bandCell"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
94
95
  <li class="bandCell"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li>
95
96
  <li class="bandCell"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li>
96
97
  <li class="bandCell"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li>
@@ -105,7 +106,7 @@
105
106
  <li class="bandCell"><a class="bandT" href="/projects?view=map&amp;sub=table">Table</a><span class="bandC">the same projects as rows</span></li>
106
107
  <li class="bandCell" id="mineCell"><a class="bandT" href="/projects?view=mine">Your projects</a><span class="bandC">the ones you own</span></li>
107
108
  <li class="bandCell"><a class="bandT" href="/projects?view=new">New project</a><span class="bandC">five questions and a home</span></li>
108
- <li class="bandCell bandFold"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li>
109
+ <li class="bandCell bandFold"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li>
109
110
  </ul>
110
111
  </div>
111
112
  </div>
@@ -70,7 +70,8 @@
70
70
  <!--apex-only:start--><div class="menuBand" id="menuCommunity" data-menu="community" hidden>
71
71
  <div class="bandIn">
72
72
  <ul class="bandRow">
73
- <li class="bandCell"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
73
+ <li class="bandCell"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li>
74
+ <li class="bandCell"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
74
75
  <li class="bandCell"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li>
75
76
  <li class="bandCell"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li>
76
77
  <li class="bandCell"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li>
@@ -85,7 +86,7 @@
85
86
  <li class="bandCell"><a class="bandT" href="/projects?view=map&amp;sub=table">Table</a><span class="bandC">the same projects as rows</span></li>
86
87
  <li class="bandCell" id="mineCell"><a class="bandT" href="/projects?view=mine">Your projects</a><span class="bandC">the ones you own</span></li>
87
88
  <li class="bandCell"><a class="bandT" href="/projects?view=new">New project</a><span class="bandC">five questions and a home</span></li>
88
- <!--apex-only:start--><li class="bandCell bandFold"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li><!--apex-only:end-->
89
+ <!--apex-only:start--><li class="bandCell bandFold"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li><!--apex-only:end-->
89
90
  </ul>
90
91
  </div>
91
92
  </div>
@@ -145,7 +145,8 @@
145
145
  <div class="menuBand" id="menuCommunity" data-menu="community" hidden>
146
146
  <div class="bandIn">
147
147
  <ul class="bandRow">
148
- <li class="bandCell"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
148
+ <li class="bandCell"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li>
149
+ <li class="bandCell"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
149
150
  <li class="bandCell"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li>
150
151
  <li class="bandCell"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li>
151
152
  <li class="bandCell"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li>
@@ -160,7 +161,7 @@
160
161
  <li class="bandCell"><a class="bandT" href="/projects?view=map&amp;sub=table">Table</a><span class="bandC">the same projects as rows</span></li>
161
162
  <li class="bandCell" id="mineCell"><a class="bandT" href="/projects?view=mine">Your projects</a><span class="bandC">the ones you own</span></li>
162
163
  <li class="bandCell"><a class="bandT" href="/projects?view=new">New project</a><span class="bandC">five questions and a home</span></li>
163
- <li class="bandCell bandFold"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li>
164
+ <li class="bandCell bandFold"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li>
164
165
  </ul>
165
166
  </div>
166
167
  </div>
@@ -719,7 +719,8 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
719
719
  <!--apex-only:start--><div class="menuBand" id="menuCommunity" data-menu="community" hidden>
720
720
  <div class="bandIn">
721
721
  <ul class="bandRow">
722
- <li class="bandCell"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
722
+ <li class="bandCell"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li>
723
+ <li class="bandCell"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
723
724
  <li class="bandCell"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li>
724
725
  <li class="bandCell"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li>
725
726
  <li class="bandCell"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li>
@@ -734,7 +735,7 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
734
735
  <li class="bandCell"><a class="bandT" href="/projects?view=map&amp;sub=table">Table</a><span class="bandC">sky project directory</span></li>
735
736
  <li class="bandCell" id="mineCell" hidden><a class="bandT" href="/projects?view=mine">Your projects</a><span class="bandC">the ones you own</span></li>
736
737
  <li class="bandCell"><a class="bandT" href="/projects?view=new">+ Create New Project</a><span class="bandC">fresh start/fresh idea</span></li>
737
- <!--apex-only:start--><li class="bandCell bandFold"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li><!--apex-only:end-->
738
+ <!--apex-only:start--><li class="bandCell bandFold"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li><!--apex-only:end-->
738
739
  </ul>
739
740
  <!-- About and Docs are site pages, not project views: they live in the footer row with
740
741
  Privacy / Terms / Contact (owner, 2026-08-28; task 1003332). -->
@@ -100,7 +100,8 @@
100
100
  <div class="menuBand" id="menuCommunity" data-menu="community" hidden>
101
101
  <div class="bandIn">
102
102
  <ul class="bandRow">
103
- <li class="bandCell"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
103
+ <li class="bandCell"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li>
104
+ <li class="bandCell"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
104
105
  <li class="bandCell"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li>
105
106
  <li class="bandCell"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li>
106
107
  <li class="bandCell"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li>
@@ -115,7 +116,7 @@
115
116
  <li class="bandCell"><a class="bandT" href="/projects?view=map&amp;sub=table">Table</a><span class="bandC">the same projects as rows</span></li>
116
117
  <li class="bandCell" id="mineCell"><a class="bandT" href="/projects?view=mine">Your projects</a><span class="bandC">the ones you own</span></li>
117
118
  <li class="bandCell"><a class="bandT" href="/projects?view=new">New project</a><span class="bandC">five questions and a home</span></li>
118
- <li class="bandCell bandFold"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li>
119
+ <li class="bandCell bandFold"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li>
119
120
  </ul>
120
121
  </div>
121
122
  </div>
@@ -69,7 +69,8 @@
69
69
  <!--apex-only:start--><div class="menuBand" id="menuCommunity" data-menu="community" hidden>
70
70
  <div class="bandIn">
71
71
  <ul class="bandRow">
72
- <li class="bandCell"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
72
+ <li class="bandCell"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li>
73
+ <li class="bandCell"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li>
73
74
  <li class="bandCell"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li>
74
75
  <li class="bandCell"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li>
75
76
  <li class="bandCell"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li>
@@ -84,7 +85,7 @@
84
85
  <li class="bandCell"><a class="bandT" href="/projects?view=map&amp;sub=table">Table</a><span class="bandC">the same projects as rows</span></li>
85
86
  <li class="bandCell" id="mineCell"><a class="bandT" href="/projects?view=mine">Your projects</a><span class="bandC">the ones you own</span></li>
86
87
  <li class="bandCell"><a class="bandT" href="/projects?view=new">New project</a><span class="bandC">five questions and a home</span></li>
87
- <!--apex-only:start--><li class="bandCell bandFold"><a class="bandT" href="/community">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li><!--apex-only:end-->
88
+ <!--apex-only:start--><li class="bandCell bandFold"><a class="bandT" href="/community">Community home</a><span class="bandC">the builders of the week, month and year</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/leaderboard">Leaderboard</a><span class="bandC">who earned the most, across every project</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/week">Builder of the week</a><span class="bandC">the top earner of each week, and how it is chosen</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/find">Find a builder</a><span class="bandC">anyone building here, by name or role</span></li><li class="bandCell bandFold"><a class="bandT" href="/community/recruiters">Open to recruiters</a><span class="bandC">who is open to recruiting, for project owners</span></li><li class="bandCell bandFold knowCell" hidden><a class="bandT" href="/connections#connSuggest">Builders you may know</a><span class="bandC">connections or projects in common</span></li><!--apex-only:end-->
88
89
  </ul>
89
90
  </div>
90
91
  </div>