@bongos/core 1.19.445 → 1.19.446

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 (40) hide show
  1. package/.bongos-core.json +50 -45
  2. package/docs/copy-inventory.md +353 -352
  3. package/docs/copy-registry.json +397 -388
  4. package/docs/module-api-changelog.md +2 -0
  5. package/modules/hall-ui/public/atlas.html +1 -2
  6. package/modules/hall-ui/public/collab.html +1 -2
  7. package/modules/hall-ui/public/copy-desk.css +11 -11
  8. package/modules/hall-ui/public/copy-desk.html +1 -2
  9. package/modules/hall-ui/public/diagrams.html +1 -2
  10. package/modules/hall-ui/public/drachmae.html +1 -2
  11. package/modules/hall-ui/public/gate.html +1 -2
  12. package/modules/hall-ui/public/goals.html +1 -2
  13. package/modules/hall-ui/public/government.html +1 -2
  14. package/modules/hall-ui/public/harbor.html +1 -2
  15. package/modules/hall-ui/public/idea.html +1 -2
  16. package/modules/hall-ui/public/ideas.css +6 -8
  17. package/modules/hall-ui/public/ideas.html +1 -2
  18. package/modules/hall-ui/public/index.html +3 -4
  19. package/modules/hall-ui/public/modules.html +1 -2
  20. package/modules/hall-ui/public/my-projects.html +1 -2
  21. package/modules/hall-ui/public/not-ready.html +1 -2
  22. package/modules/hall-ui/public/pair.html +1 -2
  23. package/modules/hall-ui/public/people.html +1 -2
  24. package/modules/hall-ui/public/primer.html +1 -2
  25. package/modules/hall-ui/public/profile.html +1 -2
  26. package/modules/hall-ui/public/ranks.html +1 -2
  27. package/modules/hall-ui/public/roadmap.html +1 -2
  28. package/modules/hall-ui/public/scouting.html +1 -2
  29. package/modules/hall-ui/public/sessions.html +1 -2
  30. package/modules/hall-ui/public/settings.html +1 -2
  31. package/modules/hall-ui/public/shell.js +35 -2
  32. package/modules/hall-ui/public/style.css +818 -392
  33. package/modules/hall-ui/public/task.html +1 -2
  34. package/modules/hall-ui/public/watch.css +1 -1
  35. package/modules/hall-ui/public/watch.html +1 -2
  36. package/modules/hall-ui/public/work.html +1 -2
  37. package/package-lock.json +2 -2
  38. package/package.json +1 -1
  39. package/src/module-api.js +1 -1
  40. package/tests/hall_tokens.mjs +371 -0
@@ -1327,5 +1327,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
1327
1327
  landed since 1.19.443 with no explicit bump. run 33334908383. (task 1002620)
1328
1328
  1.19.445 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1329
1329
  landed since 1.19.444 with no explicit bump. run 33337122866. (task 1002620)
1330
+ 1.19.446 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1331
+ landed since 1.19.445 with no explicit bump. run 33341626697. (task 1002620)
1330
1332
  ---------------------------------------------------------------------------
1331
1333
  ```
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='25' font-size='26' text-anchor='middle'>🪘</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/atlas.css">
14
13
  </head>
@@ -20,7 +19,7 @@
20
19
  <div class="app-body">
21
20
  <header class="app-topbar" id="app-topbar"></header>
22
21
  <div class="app-content">
23
- <main>
22
+ <main id="hall-main">
24
23
  <!-- The atlas chrome rides the hall tokens (pack + dark aware, task 1737);
25
24
  only the semantic node/edge palette stays instance-independent so a
26
25
  pack can never scramble the map's color-coded meaning (ADR 0094). -->
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/collab.css">
14
13
  </head>
@@ -24,7 +23,7 @@
24
23
  <p class="page-head__sub" id="cb-sub">Loading…</p>
25
24
  </div>
26
25
 
27
- <main>
26
+ <main id="hall-main">
28
27
  <!-- ASKED OF YOU comes first: it is the half where someone is waiting on a
29
28
  human. Your own asks are below, because they are a status check, not a
30
29
  call to act. -->
@@ -17,9 +17,9 @@
17
17
  flex-direction: column;
18
18
  gap: 0.15rem;
19
19
  padding: 0.75rem 0.9rem;
20
- border: 1px solid var(--line, rgba(255, 255, 255, 0.12));
20
+ border: 1px solid var(--rule-soft);
21
21
  border-radius: 0.5rem;
22
- background: var(--panel, rgba(255, 255, 255, 0.03));
22
+ background: var(--surface-2);
23
23
  }
24
24
  .cd-stat__n { font-size: 1.6rem; font-weight: 700; line-height: 1.1; }
25
25
  .cd-stat__l { font-size: 0.8rem; opacity: 0.7; }
@@ -28,7 +28,7 @@
28
28
  .cd-note code {
29
29
  padding: 0.05rem 0.3rem;
30
30
  border-radius: 0.25rem;
31
- background: var(--panel, rgba(255, 255, 255, 0.06));
31
+ background: var(--surface-2);
32
32
  font-size: 0.95em;
33
33
  }
34
34
 
@@ -40,9 +40,9 @@
40
40
  .cd-dialog__input,
41
41
  .cd-dialog__text {
42
42
  padding: 0.4rem 0.6rem;
43
- border: 1px solid var(--line, rgba(255, 255, 255, 0.15));
43
+ border: 1px solid var(--rule-soft);
44
44
  border-radius: 0.35rem;
45
- background: var(--panel, rgba(0, 0, 0, 0.2));
45
+ background: var(--bg-deep);
46
46
  color: inherit;
47
47
  font: inherit;
48
48
  }
@@ -56,9 +56,9 @@
56
56
 
57
57
  .cd-card {
58
58
  padding: 0.85rem 1rem;
59
- border: 1px solid var(--line, rgba(255, 255, 255, 0.12));
59
+ border: 1px solid var(--rule-soft);
60
60
  border-radius: 0.5rem;
61
- background: var(--panel, rgba(255, 255, 255, 0.03));
61
+ background: var(--surface-2);
62
62
  }
63
63
  .cd-card--slim { padding: 0.6rem 0.8rem; }
64
64
  .cd-card__head { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin-bottom: 0.4rem; }
@@ -85,7 +85,7 @@
85
85
  .cd-tag {
86
86
  display: inline-block;
87
87
  padding: 0.1rem 0.45rem;
88
- border: 1px solid var(--line, rgba(255, 255, 255, 0.18));
88
+ border: 1px solid var(--rule);
89
89
  border-radius: 999px;
90
90
  font-size: 0.72rem;
91
91
  letter-spacing: 0.02em;
@@ -103,9 +103,9 @@
103
103
  .cd-dialog {
104
104
  width: min(34rem, 92vw);
105
105
  padding: 1.25rem;
106
- border: 1px solid var(--line, rgba(255, 255, 255, 0.18));
106
+ border: 1px solid var(--rule);
107
107
  border-radius: 0.6rem;
108
- background: var(--bg, #12131a);
108
+ background: var(--bg-card);
109
109
  color: inherit;
110
110
  }
111
111
  .cd-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
@@ -115,5 +115,5 @@
115
115
  .cd-dialog__hint { display: block; font-weight: 400; font-size: 0.78rem; opacity: 0.65; line-height: 1.45; margin-top: 0.1rem; }
116
116
  .cd-dialog__select, .cd-dialog__input, .cd-dialog__text { width: 100%; }
117
117
  .cd-dialog__text { resize: vertical; line-height: 1.5; }
118
- .cd-dialog__err { min-height: 1.2rem; margin: 0.5rem 0 0; font-size: 0.85rem; color: var(--danger, #ff8080); line-height: 1.45; }
118
+ .cd-dialog__err { min-height: 1.2rem; margin: 0.5rem 0 0; font-size: 0.85rem; color: var(--danger); line-height: 1.45; }
119
119
  .cd-dialog__actions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 0.9rem; }
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/copy-desk.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="cd-sub">Loading the copy desk…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <!-- The counts. Deliberately four numbers and not a dashboard: open work,
27
26
  the fast pile (targets that have since been edited away), untouched
28
27
  duplicates, and how big the inventory is. -->
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/diagram-viewer.css?v=2026-06-14-diagviewer-1">
14
13
  <style>
@@ -42,7 +41,7 @@
42
41
  <p class="page-head__sub">Five diagrams that show, at a glance, how work flows through {{worldName}}'s development system. <em>Drag to pan, scroll to zoom</em> — or open any diagram fullscreen.</p>
43
42
  </div>
44
43
 
45
- <main>
44
+ <main id="hall-main">
46
45
 
47
46
  <section class="scroll" aria-labelledby="legend-h">
48
47
  <h2 id="legend-h" class="scroll__h">Reading the diagrams</h2>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>◈</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/primer.css?v=2026-07-02-shell1">
14
13
  </head>
@@ -28,7 +27,7 @@
28
27
  <p class="page-head__sub">How you get paid, and how you earn trust — the reward model in plain language. About a five-minute read.</p>
29
28
  </div>
30
29
 
31
- <main>
30
+ <main id="hall-main">
32
31
  <div class="primer-layout">
33
32
 
34
33
  <!-- Sticky left-rail table of contents, built from the article's h2s. -->
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/gate.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="gate-sub">Loading…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <p class="gate-sealed" id="gate-sealed" hidden>Archons only.</p>
27
26
 
28
27
  <section id="gate-body" hidden>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-03-goals1">
13
12
  <!-- Page-local styles (task 2171) — extracted from the old inline <style>
14
13
  block per the hall placement rules; shared pager/filter/tab/count-pill
@@ -35,7 +34,7 @@
35
34
  <p class="page-head__sub" id="goals-sub">Loading goals…</p>
36
35
  </div>
37
36
 
38
- <main>
37
+ <main id="hall-main">
39
38
  <!-- LIST view -->
40
39
  <section id="goals-list-view" aria-labelledby="goals-list-h">
41
40
  <h2 id="goals-list-h" class="sr-only">All goals</h2>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/government.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="gov-sub">Loading…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <p class="gov-sealed" id="gov-sealed" hidden>Archons only.</p>
27
26
 
28
27
  <section id="gov-body" hidden>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/harbor.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="harbor-sub">Loading dev boxes…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <p class="harbor-sealed" id="harbor-sealed" hidden>Archons only.</p>
27
26
 
28
27
  <section id="harbor-body" hidden>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/idea.css">
14
13
  </head>
@@ -28,7 +27,7 @@
28
27
  <p class="page-head__sub" id="idea-sub">Loading idea…</p>
29
28
  </div>
30
29
 
31
- <main>
30
+ <main id="hall-main">
32
31
  <section class="scroll" id="idea-scroll" aria-labelledby="idea-h">
33
32
  <div id="idea-body">
34
33
  <p class="deeplink-card__title" id="idea-h">Loading…</p>
@@ -6,14 +6,12 @@
6
6
  meter alongside, collapsing to one column where there is no room for it.
7
7
 
8
8
  USES THE REAL TOKEN NAMES — --border / --surface-2 / --accent / --ok / --warn /
9
- --danger / --radius. Note for anyone copying a sibling sheet: copy-desk.css
10
- reaches for `var(--line, rgba(255,255,255,.12))` and `var(--panel, …)`, and
11
- NEITHER --line NOR --panel is defined in style.css — so those fallbacks apply,
12
- and they assume a dark ground the hall does not have by default (--bg is
13
- #f5f6f8). Borders drawn that way are invisible on the light theme. This sheet
14
- deliberately does not inherit that. The hall's dark theme flips only the
15
- neutrals, so every token below re-derives on its own and this page needs no
16
- theme-specific block at all. */
9
+ --danger / --radius, so every token below re-derives on its own and this page
10
+ needs no theme-specific block at all. (The sibling trap this note used to warn
11
+ about — copy-desk.css reaching for an undefined --line / --panel and getting a
12
+ dark-ground fallback on the light theme — was fixed in task 1003303, when the
13
+ chrome-world tier defined --line as a WIDTH and those borders would otherwise
14
+ have gone invalid.) */
17
15
 
18
16
  /* The composer and its meter sit side by side once there is room. Below that
19
17
  width the meter stacks ABOVE the fields — a readout you cannot see while
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/ideas.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="fi-sub">Loading the idea template…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <!-- The spark queue (task 1002930 / R154). ABOVE the composer, because
27
26
  "what is already waiting" is the thing to scan before starting
28
27
  something new — and because a queue nobody sees is not a pickup
@@ -14,7 +14,6 @@
14
14
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
15
15
  <link rel="preconnect" href="https://fonts.googleapis.com">
16
16
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
17
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
18
17
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
19
18
  </head>
20
19
  <body data-page="home">
@@ -41,12 +40,12 @@
41
40
  — core (hall-widgets.js) and module-contributed (a module's own client
42
41
  script) — registers into the hall-widget registry (window.OTB,
43
42
  dom-utils.js), and builders.js stamps the registered <section>s into the
44
- view containers below (falling back to <main> itself). The registry stays
43
+ view containers below (falling back to <main id="hall-main"> itself). The registry stays
45
44
  the single source of truth for what the hall shows; a fitness check
46
45
  (scripts/gds/fitness.js checkHallSectionRegistry) reds the build if a
47
- <section class="scroll"> is hardcoded back inside this <main>. The
46
+ <section class="scroll"> is hardcoded back inside this <main id="hall-main">. The
48
47
  .view/.view-zone wrappers are shell layout only. -->
49
- <main class="app-views">
48
+ <main class="app-views" id="hall-main">
50
49
  <section class="view" id="view-home" data-view-title="Home">
51
50
  <div class="view-zone" id="zone-home-banner">
52
51
  <!-- Landing card for signed-out visitors (builders.js renderLanding)
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/modules.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="modules-sub">Loading modules…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <!-- Browse — one filter over both grids below (task 1001772). -->
27
26
  <div class="mod-browse">
28
27
  <label class="mod-browse__label" for="mod-search">Search the catalog</label>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/my-projects.css">
14
13
  </head>
@@ -24,7 +23,7 @@
24
23
  <p class="page-head__sub">Every project you build on across the platform.</p>
25
24
  </div>
26
25
 
27
- <main>
26
+ <main id="hall-main">
28
27
  <section class="scroll" aria-labelledby="owned-h">
29
28
  <h2 id="owned-h" class="scroll__h">Projects you own</h2>
30
29
  <div id="owned"><p class="empty">—</p></div>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  </head>
14
13
  <body data-page="not-ready" data-page-title="Locked">
@@ -19,7 +18,7 @@
19
18
  <div class="app-body">
20
19
  <header class="app-topbar" id="app-topbar"></header>
21
20
  <div class="app-content">
22
- <main>
21
+ <main id="hall-main">
23
22
  <section class="scroll">
24
23
  <h2 class="scroll__h">Not yet available</h2>
25
24
  <p class="scroll__lede">This page unlocks as you advance.</p>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/pair.css">
14
13
  </head>
@@ -21,7 +20,7 @@
21
20
  <header class="app-topbar" id="app-topbar"></header>
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="pair-sub">Reading the request…</p></div>
24
- <main>
23
+ <main id="hall-main">
25
24
  <section class="scroll" id="pair-scroll" aria-labelledby="pair-h">
26
25
  <h2 id="pair-h" class="scroll__h">A device is asking to act as you</h2>
27
26
  <div id="pair-body">
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  </head>
14
13
  <body data-page="people" data-page-title="People">
@@ -23,7 +22,7 @@
23
22
  <p class="page-head__sub">Everyone building across hosted projects, ranked by track record. Descriptive only — cross-project numbers never carry authority here.</p>
24
23
  </div>
25
24
 
26
- <main>
25
+ <main id="hall-main">
27
26
  <section class="scroll" id="people-scroll" aria-labelledby="people-h">
28
27
  <h2 id="people-h" class="scroll__h">Builder directory</h2>
29
28
  <div id="people-filters"></div>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <link rel="stylesheet" href="/builders/primer.css?v=2026-07-02-shell1">
14
13
  <link rel="stylesheet" href="/builders/diagram-viewer.css?v=2026-06-14-diagviewer-1">
@@ -31,7 +30,7 @@
31
30
  <p class="page-head__sub">Everything a new builder needs before claiming their first task. About a ten-minute read.</p>
32
31
  </div>
33
32
 
34
- <main>
33
+ <main id="hall-main">
35
34
  <div class="primer-layout">
36
35
 
37
36
  <!-- Sticky left-rail table of contents. Built from the article's h2s after
@@ -13,7 +13,6 @@
13
13
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
14
14
  <link rel="preconnect" href="https://fonts.googleapis.com">
15
15
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
16
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
17
16
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
18
17
  </head>
19
18
  <body data-page="profile" data-page-title="Profile">
@@ -28,7 +27,7 @@
28
27
  <p class="page-head__sub" id="profile-sub">Loading profile…</p>
29
28
  </div>
30
29
 
31
- <main>
30
+ <main id="hall-main">
32
31
  <!-- Standing — avatar, name, rank badge, member-since. Filled by profile.js. -->
33
32
  <section class="scroll" id="standing-scroll" aria-labelledby="standing-h">
34
33
  <h2 id="standing-h" class="sr-only">Standing</h2>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  </head>
14
13
  <body data-page="ranks" data-page-title="Ranks">
@@ -23,7 +22,7 @@
23
22
  <p class="page-head__sub" id="ranks-sub">Loading your rank…</p>
24
23
  </div>
25
24
 
26
- <main>
25
+ <main id="hall-main">
27
26
  <!-- Current rank summary — filled by ranks.js once /me resolves. -->
28
27
  <section class="scroll" id="standing-scroll" aria-labelledby="standing-h">
29
28
  <h2 id="standing-h" class="scroll__h">Where you stand</h2>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-24-deck1">
13
12
  <link rel="stylesheet" href="/builders/roadmap.css">
14
13
  </head>
@@ -24,7 +23,7 @@
24
23
  <p class="page-head__sub" id="roadmap-sub">Loading the roadmap…</p>
25
24
  </div>
26
25
 
27
- <main>
26
+ <main id="hall-main">
28
27
  <div id="rm-root">
29
28
  <div class="profile__placeholder">Loading the roadmap…</div>
30
29
  </div>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <style>
14
13
  #body .who { font-weight: 600; }
@@ -26,7 +25,7 @@
26
25
  <p class="page-head__sub">Builders active across all hosted projects — an internal talent view. Descriptive only; it grants no authority anywhere.</p>
27
26
  </div>
28
27
 
29
- <main>
28
+ <main id="hall-main">
30
29
  <section class="scroll" aria-labelledby="scouting-h">
31
30
  <h2 id="scouting-h" class="scroll__h">Cross-project builders</h2>
32
31
  <div id="body" class="profile__placeholder">Loading…</div>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-06-04-sessions">
13
12
  <link rel="stylesheet" href="/builders/sessions.css">
14
13
  </head>
@@ -22,7 +21,7 @@
22
21
  <div class="app-content">
23
22
  <div class="page-head"><p class="page-head__sub" id="ledger-sub">Loading sessions…</p></div>
24
23
 
25
- <main>
24
+ <main id="hall-main">
26
25
  <!-- Access notice — shown by sessions.js when the viewer is not an Archon. -->
27
26
  <section class="scroll" id="gate-scroll" aria-labelledby="gate-h" hidden>
28
27
  <h2 id="gate-h" class="scroll__h">Archons only</h2>
@@ -8,7 +8,6 @@
8
8
  <link rel="icon" href="data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text x='16' y='24' font-size='24' text-anchor='middle' font-family='sans-serif'>⌂</text></svg>">
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
12
11
  <link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
13
12
  <!-- Page-local styles (task 2172) — extracted from the old inline <style>
14
13
  block per the hall placement rules; the rail comes from style.css's
@@ -25,7 +24,7 @@
25
24
  <div class="app-content">
26
25
  <div class="page-head"><p class="page-head__sub" id="settings-sub">Loading your preferences…</p></div>
27
26
 
28
- <main>
27
+ <main id="hall-main">
29
28
  <!-- Not-signed-in notice — shown by settings.js before it redirects, and
30
29
  as a fallback if reading the viewer fails. Deliberately OUTSIDE the
31
30
  grouped layout: full-width, ungrouped. -->
@@ -259,13 +259,23 @@
259
259
  ' title="' + esc(it.label) + '" hidden>' + icon(it.icon) +
260
260
  '<span class="nav-item__label">' + esc(it.label) + '</span></a>';
261
261
  }).join('');
262
+ // task 1003303: aria-controls names the region the head discloses. The
263
+ // frozen markup carried aria-expanded pointing at nothing, which is an
264
+ // accessibility gap a screen reader cannot recover from. The items get a
265
+ // wrapper to be that region; its class deliberately does NOT begin with
266
+ // "nav-group", because tests/hall_nav.mjs splits the sidebar on that
267
+ // string to find groups and a matching wrapper would parse as a phantom
268
+ // one. `data-gate` stays immediately after the class for the same reason.
262
269
  var head = g.group
263
- ? '<button type="button" class="nav-group__head" data-gate="' + (g.gate || 'always') + '" data-group="' + esc(groupId) + '" aria-expanded="' + (collapsed ? 'false' : 'true') + '" hidden>' +
270
+ ? '<button type="button" class="nav-group__head" data-gate="' + (g.gate || 'always') + '" data-group="' + esc(groupId) + '" aria-expanded="' + (collapsed ? 'false' : 'true') + '" aria-controls="nav-items-' + esc(groupId) + '" hidden>' +
264
271
  '<span class="nav-group__head-label">' + esc(g.group) + '</span>' + chevronIcon() +
265
272
  '</button>'
266
273
  : '';
274
+ var body = collapsible
275
+ ? '<div class="nav-items" id="nav-items-' + esc(groupId) + '">' + items + '</div>'
276
+ : items;
267
277
  return '<div class="nav-group' + (collapsible ? ' nav-group--collapsible' : '') + (collapsed ? ' nav-group--collapsed' : '') + '"' +
268
- (collapsible ? ' data-group="' + esc(groupId) + '"' : '') + '>' + head + items + '</div>';
278
+ (collapsible ? ' data-group="' + esc(groupId) + '"' : '') + '>' + head + body + '</div>';
269
279
  }).join('');
270
280
 
271
281
  el.innerHTML =
@@ -423,6 +433,28 @@
423
433
  history.replaceState(null, '', window.location.pathname + rest + window.location.hash);
424
434
  }
425
435
 
436
+ // task 1003303: the skip link, rendered once here rather than pasted into 27
437
+ // heads. The hall had none, which is a platform floor (DESIGN.md
438
+ // §Accessibility Floors) and, with the sidebar first in the DOM, meant a
439
+ // keyboard reader walked the whole nav before reaching the page on every
440
+ // page. It is the first focusable thing in the document and it targets a
441
+ // <main> made focusable but never ringed, so focus actually lands there.
442
+ function renderSkipLink() {
443
+ // Both mounts are looked up BY ID, not by selector: every hall page carries
444
+ // #app-sidebar and gives its <main> id="hall-main" for exactly this, and
445
+ // getElementById is the only lookup the hall's vm test stubs implement.
446
+ var main = document.getElementById('hall-main');
447
+ var sidebar = document.getElementById('app-sidebar');
448
+ if (!main || !sidebar || !sidebar.parentNode) return;
449
+ main.setAttribute('tabindex', '-1');
450
+ var a = document.createElement('a');
451
+ a.className = 'skip';
452
+ a.href = '#hall-main';
453
+ a.textContent = 'Skip to content';
454
+ // Before the sidebar, so it is the first focusable thing in the document.
455
+ sidebar.parentNode.insertBefore(a, sidebar);
456
+ }
457
+
426
458
  function renderFoot() {
427
459
  var el = document.getElementById('app-foot');
428
460
  if (!el) return;
@@ -676,6 +708,7 @@
676
708
 
677
709
  // ---------- boot (defer = DOM parsed; render synchronously) ----------
678
710
 
711
+ renderSkipLink();
679
712
  renderSidebar();
680
713
  renderTopbar();
681
714
  renderDeniedNotice();