@bongos/core 1.20.50 → 1.20.52
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.
- package/.bongos-core.json +172 -62
- package/docs/copy-inventory.md +54 -52
- package/docs/copy-registry.json +106 -88
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-inventory.json +6 -1
- package/docs/page-readings.json +449 -427
- package/modules/hall-ui/public/atlas.html +1 -1
- package/modules/hall-ui/public/blockers.html +1 -1
- package/modules/hall-ui/public/board-room.html +1 -1
- package/modules/hall-ui/public/collab.html +1 -1
- package/modules/hall-ui/public/commands.html +1 -1
- package/modules/hall-ui/public/copy-desk.html +1 -1
- package/modules/hall-ui/public/deploy.html +1 -1
- package/modules/hall-ui/public/diagrams.html +1 -1
- package/modules/hall-ui/public/drachmae.html +1 -1
- package/modules/hall-ui/public/fleet.html +1 -1
- package/modules/hall-ui/public/gate.html +1 -1
- package/modules/hall-ui/public/goal-map.html +29 -14
- package/modules/hall-ui/public/goal-map.states.json +12 -0
- package/modules/hall-ui/public/goals.html +1 -1
- package/modules/hall-ui/public/government.html +1 -1
- package/modules/hall-ui/public/idea.html +1 -1
- package/modules/hall-ui/public/ideas.html +1 -1
- package/modules/hall-ui/public/index.html +1 -1
- package/modules/hall-ui/public/modules.html +1 -1
- package/modules/hall-ui/public/primer.html +1 -1
- package/modules/hall-ui/public/profile.html +1 -1
- package/modules/hall-ui/public/project-settings.html +1 -1
- package/modules/hall-ui/public/ranks.html +1 -1
- package/modules/hall-ui/public/roadmap.html +1 -1
- package/modules/hall-ui/public/roster.html +1 -1
- package/modules/hall-ui/public/sessions.html +1 -1
- package/modules/hall-ui/public/settings.html +1 -1
- package/modules/hall-ui/public/shell.js +145 -15
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/style.css +61 -5
- package/modules/hall-ui/public/task.html +1 -1
- package/modules/hall-ui/public/thinking.css +15 -11
- package/modules/hall-ui/public/thinking.html +1 -1
- package/modules/hall-ui/public/tweak-editor.css +6 -0
- package/modules/hall-ui/public/tweak-editor.html +2 -2
- package/modules/hall-ui/public/watch.html +1 -1
- package/modules/hall-ui/public/work.html +1 -1
- package/modules/hall-ui/records/hall-navigation.md +22 -0
- package/modules/hall-ui/records/sky.md +2 -0
- package/modules/provisioning/soft-limits.js +17 -0
- package/modules/public-landing/public/assets/world/r5-life-1-primordial-sea-cut.webp +0 -0
- package/modules/public-landing/public/assets/world/r5-life-1-primordial-sea-cut.webp.json +16 -0
- package/modules/public-landing/public/assets/world/r5-life-1-primordial-sea.jpg +0 -0
- package/modules/public-landing/public/assets/world/r5-life-1-primordial-sea.jpg.json +16 -0
- package/modules/public-landing/public/assets/world/r5-life-2-first-cells-cut.webp +0 -0
- package/modules/public-landing/public/assets/world/r5-life-2-first-cells-cut.webp.json +16 -0
- package/modules/public-landing/public/assets/world/r5-life-2-first-cells.jpg +0 -0
- package/modules/public-landing/public/assets/world/r5-life-2-first-cells.jpg.json +16 -0
- package/modules/public-landing/public/assets/world/r5-life-3-genome-cut.webp +0 -0
- package/modules/public-landing/public/assets/world/r5-life-3-genome-cut.webp.json +16 -0
- package/modules/public-landing/public/assets/world/r5-life-3-genome.jpg +0 -0
- package/modules/public-landing/public/assets/world/r5-life-3-genome.jpg.json +16 -0
- package/modules/public-landing/public/assets/world/r5-life-4-membrane-cut.webp +0 -0
- package/modules/public-landing/public/assets/world/r5-life-4-membrane-cut.webp.json +16 -0
- package/modules/public-landing/public/assets/world/r5-life-4-membrane.jpg +0 -0
- package/modules/public-landing/public/assets/world/r5-life-4-membrane.jpg.json +16 -0
- package/modules/public-landing/public/assets/world/r5-life-5-nervous-system-cut.webp +0 -0
- package/modules/public-landing/public/assets/world/r5-life-5-nervous-system-cut.webp.json +16 -0
- package/modules/public-landing/public/assets/world/r5-life-5-nervous-system.jpg +0 -0
- package/modules/public-landing/public/assets/world/r5-life-5-nervous-system.jpg.json +16 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +16 -0
- package/src/module-api.js +1 -1
- package/tests/genesis_life_plates.mjs +63 -0
- package/tests/goal_map_page.mjs +10 -7
- package/tests/hall_audit.mjs +3 -4
- package/tests/hall_fullscreen.mjs +99 -14
- package/tests/hall_tweak_editor.mjs +1 -1
- package/tests/nav_permission_atoms.mjs +1 -1
- package/tests/provisioning_planet_physics.mjs +14 -0
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
|
|
92
92
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
93
93
|
|
|
94
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
94
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
95
95
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
96
96
|
<script src="/builders/palette.js" defer></script>
|
|
97
97
|
<script src="/builders/atlas.js?v=2026-09-02-index" defer></script>
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
52
52
|
chrome exists before the page script runs. -->
|
|
53
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
53
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
54
54
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
55
55
|
<script src="/builders/palette.js" defer></script>
|
|
56
56
|
<!-- shared frontend toolkit (window.OTB — rank labels, number formats) + the
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
|
|
61
61
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
62
62
|
|
|
63
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
63
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
64
64
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
65
65
|
<script src="/builders/palette.js" defer></script>
|
|
66
66
|
<script src="/builders/dom-utils.js?v=2026-06-16-board"></script>
|
|
@@ -148,7 +148,7 @@
|
|
|
148
148
|
|
|
149
149
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
150
150
|
|
|
151
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
151
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
152
152
|
<script src="/builders/palette.js" defer></script>
|
|
153
153
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
154
154
|
<script src="/builders/collab-lib.js?v=2026-09-24-archive"></script>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
|
|
55
55
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
56
56
|
|
|
57
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
57
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
58
58
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
59
59
|
<script src="/builders/palette.js" defer></script>
|
|
60
60
|
<script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>
|
|
@@ -177,7 +177,7 @@
|
|
|
177
177
|
|
|
178
178
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
179
179
|
|
|
180
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
180
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
181
181
|
<script src="/builders/palette.js" defer></script>
|
|
182
182
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
183
183
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
|
|
75
75
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
76
76
|
|
|
77
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
77
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
78
78
|
<script src="/builders/palette.js" defer></script>
|
|
79
79
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
80
80
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
|
|
98
98
|
<!-- The app shell (sidebar + top bar + footer). Dependency-free; runs at parse
|
|
99
99
|
time so the chrome exists before the deferred page scripts execute. -->
|
|
100
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
100
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
101
101
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
102
102
|
<script src="/builders/palette.js" defer></script>
|
|
103
103
|
<script src="/builders/diagram-viewer.js?v=2026-06-14-diagviewer-1" defer></script>
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
|
|
99
99
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
100
100
|
|
|
101
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
101
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
102
102
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
103
103
|
<script src="/builders/palette.js" defer></script>
|
|
104
104
|
<script src="/builders/md-reader.js?v=2026-09-02-mdreader-2"></script>
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
|
|
55
55
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
56
56
|
|
|
57
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
57
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
58
58
|
<script src="/builders/palette.js" defer></script>
|
|
59
59
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
60
60
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
<div id="gate-modal-root"></div>
|
|
77
77
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
78
78
|
|
|
79
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
79
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
80
80
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
81
81
|
<script src="/builders/palette.js" defer></script>
|
|
82
82
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
<!-- The faces (Manrope, JetBrains Mono) come from the branding pack's font
|
|
12
12
|
links, injected into this head by the server like every hall page's
|
|
13
13
|
(tests/hall_tokens.mjs: no hall page hardcodes a web-font stylesheet). -->
|
|
14
|
+
<link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
|
|
14
15
|
<link rel="stylesheet" href="/builders/thinking.css?v=2026-09-27-split">
|
|
15
16
|
</head>
|
|
16
17
|
<!-- THE PROJECT SKY (task 1004232 / sky part 4 of 5, goal 1000095; ADR 0331,
|
|
@@ -34,32 +35,40 @@
|
|
|
34
35
|
laid over the map), routes, the ledger drawer. The ideator's pills
|
|
35
36
|
(recent, claude layer, my influence) are /thinking's alone, and nothing
|
|
36
37
|
here leaves for that page as a lens. The same rule as
|
|
37
|
-
/thinking on chrome:
|
|
38
|
-
|
|
39
|
-
the
|
|
38
|
+
/thinking on chrome: IN THE HALL (task 1004430) — the sidebar and the top
|
|
39
|
+
bar hold it like every hall page, and the shell's full-screen switch hides
|
|
40
|
+
both so the sky fills the window again, remembered for this page. The whole
|
|
41
|
+
sky lives inside <main class="sky-stage">, the containing block its fixed
|
|
42
|
+
layers measure from (thinking.css). The hall's doors (the goal, the task,
|
|
43
|
+
the record) still open from the panel.
|
|
40
44
|
|
|
41
45
|
ADR 0227 §1's refusal stands here: tasks are drawn only inside ONE goal
|
|
42
46
|
once its well is past the zoom threshold (dust density on its rings below
|
|
43
47
|
it), never for every goal at once, and there is no "show every task"
|
|
44
48
|
control — tests/goal_map_page.mjs pins both. -->
|
|
45
|
-
<body data-page="goal-map" data-page-title="The sky" data-sky-lens="all">
|
|
49
|
+
<body data-page="goal-map" data-page-title="The sky" data-sky-lens="all" data-fullscreen-switch>
|
|
50
|
+
|
|
51
|
+
<div class="app">
|
|
52
|
+
<aside class="app-sidebar" id="app-sidebar" aria-label="Primary"></aside>
|
|
53
|
+
<div class="app-scrim" id="app-scrim" hidden></div>
|
|
54
|
+
<div class="app-body">
|
|
55
|
+
<header class="app-topbar" id="app-topbar"></header>
|
|
46
56
|
|
|
47
57
|
<!-- The one <main> landmark the kit's a11y floor asks of every hall page
|
|
48
|
-
(one-header-main-h1).
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<main>
|
|
58
|
+
(one-header-main-h1). In the hall (task 1004430) it is the STAGE, as on
|
|
59
|
+
/thinking: the box under the top bar and beside the rail the whole sky is
|
|
60
|
+
drawn in. -->
|
|
61
|
+
<main id="hall-main" class="sky-stage">
|
|
52
62
|
<canvas id="sky" tabindex="0" role="img" aria-label="The sky, drawn from the ledger: every goal a gravity well, every dependency a route. Every goal here is also a row in the ledger; press L to open it, ? to take the tour."></canvas>
|
|
53
|
-
</main>
|
|
54
63
|
|
|
55
|
-
<!-- The
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
<!-- The BRAND (the h1 and the figures), with the tools its siblings in the
|
|
65
|
+
same .top strip. In the hall the shell's top bar is the page's one
|
|
66
|
+
<header>, so the brand is a <div> — thinking.html's shape. -->
|
|
58
67
|
<div class="top">
|
|
59
|
-
<
|
|
68
|
+
<div class="brand">
|
|
60
69
|
<h1>the sky <em id="lensWord">— the whole project</em></h1>
|
|
61
70
|
<div class="stats" id="stats"></div>
|
|
62
|
-
</
|
|
71
|
+
</div>
|
|
63
72
|
<div class="tools" id="tools">
|
|
64
73
|
<button type="button" class="pill" id="roomBtn" aria-pressed="false" title="The same sky, as a list (L)">list</button>
|
|
65
74
|
<button type="button" class="pill" id="exploreBtn" aria-pressed="true" title="Explore: the sky reveals itself as you follow routes from where you begin.">explore</button>
|
|
@@ -124,6 +133,12 @@
|
|
|
124
133
|
<div class="alt" id="alt"></div>
|
|
125
134
|
</div>
|
|
126
135
|
</footer>
|
|
136
|
+
</main>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
141
|
+
<script src="/builders/palette.js" defer></script>
|
|
127
142
|
|
|
128
143
|
<script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
|
|
129
144
|
<!-- task 1004402: the UAT state words the rings share with the goal page. -->
|
|
@@ -32,6 +32,18 @@
|
|
|
32
32
|
"actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200], ["press", "l"], ["wait", 300]],
|
|
33
33
|
"expect": { "visible": ["#room", "#rows"] }
|
|
34
34
|
},
|
|
35
|
+
"full": {
|
|
36
|
+
"auth": true,
|
|
37
|
+
"_": "In the hall (task 1004430): the shell's full-screen switch pressed — the sky fills the window, and one button, in the card tone so it reads on the void, brings the chrome back.",
|
|
38
|
+
"actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200], ["clickIfVisible", "#startOpts [data-start=\"all\"]"], ["wait", 300], ["click", "#fullscreen-toggle"], ["wait", 400]],
|
|
39
|
+
"expect": { "visible": ["#sky", "#fullscreen-toggle"], "hidden": ["#app-sidebar", "#topbar-title"], "attr": [["#fullscreen-toggle", "aria-pressed", "true"]] }
|
|
40
|
+
},
|
|
41
|
+
"full-back": {
|
|
42
|
+
"auth": true,
|
|
43
|
+
"_": "Escape leaves full screen, and the chrome is back.",
|
|
44
|
+
"actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200], ["clickIfVisible", "#startOpts [data-start=\"all\"]"], ["wait", 300], ["click", "#fullscreen-toggle"], ["wait", 300], ["focus", "#sky"], ["press", "Escape"], ["wait", 400]],
|
|
45
|
+
"expect": { "visible": ["#app-sidebar", "#topbar-title"], "attr": [["#fullscreen-toggle", "aria-pressed", "false"]] }
|
|
46
|
+
},
|
|
35
47
|
"out": { "auth": false, "actions": [["wait", 600]] }
|
|
36
48
|
},
|
|
37
49
|
"reducedMotion": { "auth": true, "actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200]] }
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
|
|
231
231
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
232
232
|
|
|
233
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
233
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
234
234
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
235
235
|
<script src="/builders/palette.js" defer></script>
|
|
236
236
|
<script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
|
|
135
135
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
136
136
|
|
|
137
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
137
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
138
138
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
139
139
|
<script src="/builders/palette.js" defer></script>
|
|
140
140
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
|
|
53
53
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
54
54
|
|
|
55
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
55
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
56
56
|
<script src="/builders/palette.js" defer></script>
|
|
57
57
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib" defer></script>
|
|
58
58
|
<!-- task-detail.js still owns the #/idea/N and #/blocker/N overlay, so a ref
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
|
|
226
226
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
227
227
|
|
|
228
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
228
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
229
229
|
<script src="/builders/palette.js" defer></script>
|
|
230
230
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
231
231
|
<!-- task 1003069 (R08) — the quick-filing form's routed result links a task
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
<script src="/builders/brand-apply.js?v=2026-06-27-r75" defer></script>
|
|
107
107
|
<!-- The app shell (sidebar + top bar + view router). Dependency-free; loaded
|
|
108
108
|
BEFORE builders.js so the chrome ids exist when events are wired. -->
|
|
109
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
109
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2" defer></script>
|
|
110
110
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
111
111
|
<script src="/builders/palette.js" defer></script>
|
|
112
112
|
<!-- task 2166: the shared component kit (window.OTBKit) — pager/ledger/rail.
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
|
|
102
102
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
103
103
|
|
|
104
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
104
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
105
105
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
106
106
|
<script src="/builders/palette.js" defer></script>
|
|
107
107
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
|
|
116
116
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
117
117
|
|
|
118
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
118
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
119
119
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
120
120
|
<script src="/builders/palette.js" defer></script>
|
|
121
121
|
<!-- the shared markdown reader (window.OTBMdReader) — primer.js renders through
|
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
|
|
188
188
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
189
189
|
chrome exists before the page script runs. -->
|
|
190
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
190
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
191
191
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
192
192
|
<script src="/builders/palette.js" defer></script>
|
|
193
193
|
<!-- shared frontend toolkit (window.OTB) — loaded before profile.js, which pulls from it. -->
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
|
|
59
59
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
60
60
|
|
|
61
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
61
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
62
62
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
63
63
|
<script src="/builders/palette.js" defer></script>
|
|
64
64
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
|
|
69
69
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
70
70
|
chrome exists before the page script runs. -->
|
|
71
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
71
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
72
72
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
73
73
|
<script src="/builders/palette.js" defer></script>
|
|
74
74
|
<!-- shared frontend toolkit (window.OTB) — loaded before ranks.js, which pulls from it. -->
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
|
|
42
42
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
43
43
|
|
|
44
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
44
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
45
45
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
46
46
|
<script src="/builders/palette.js" defer></script>
|
|
47
47
|
<script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
52
52
|
chrome exists before the page script runs. -->
|
|
53
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
53
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
54
54
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
55
55
|
<script src="/builders/palette.js" defer></script>
|
|
56
56
|
<!-- shared frontend toolkit (window.OTB — rank labels, number formats) + the
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
|
|
100
100
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
101
101
|
chrome exists before the page script runs. -->
|
|
102
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
102
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
103
103
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
104
104
|
<script src="/builders/palette.js" defer></script>
|
|
105
105
|
<!-- shared frontend toolkit (window.OTB) — loaded BEFORE sessions.js so it can pull from it. -->
|
|
@@ -400,7 +400,7 @@
|
|
|
400
400
|
|
|
401
401
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
402
402
|
chrome exists before the page scripts run. -->
|
|
403
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
403
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
404
404
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
405
405
|
<script src="/builders/palette.js" defer></script>
|
|
406
406
|
<!-- shared frontend toolkit (window.OTB) — loaded before consuming IIFEs. -->
|
|
@@ -479,6 +479,7 @@
|
|
|
479
479
|
'<button class="topbar-menu" id="topbar-menu" type="button" aria-label="Open navigation" aria-expanded="false">' +
|
|
480
480
|
'<svg viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M3 5h12M3 9h12M3 13h12"/></svg>' +
|
|
481
481
|
'</button>' +
|
|
482
|
+
backLinkHtml() +
|
|
482
483
|
'<h2 class="topbar-title" id="topbar-title"></h2>' +
|
|
483
484
|
'<div class="topbar-side"><span class="topbar-note" id="welcome-line"></span>' +
|
|
484
485
|
// task 2178: the jump-palette slot. Rendered inert + hidden — palette.js
|
|
@@ -494,30 +495,133 @@
|
|
|
494
495
|
'<button class="theme-toggle" id="theme-toggle" type="button" aria-label="Switch theme"></button>' +
|
|
495
496
|
// task 1004327: the full-screen switch, LAST so it sits in the corner the
|
|
496
497
|
// collapsed bar keeps in full screen — the one control that stays put.
|
|
498
|
+
// task 1004430: on every page now, unless the page opts out.
|
|
497
499
|
(fullscreenPage() ? '<button class="fullscreen-toggle" id="fullscreen-toggle" type="button" aria-pressed="false"></button>' : '') +
|
|
498
500
|
'</div>';
|
|
499
501
|
var t = document.getElementById('topbar-title');
|
|
500
502
|
if (t) t.textContent = title;
|
|
501
503
|
}
|
|
502
504
|
|
|
503
|
-
// ----------
|
|
504
|
-
//
|
|
505
|
-
//
|
|
506
|
-
//
|
|
507
|
-
//
|
|
508
|
-
//
|
|
509
|
-
//
|
|
505
|
+
// ---------- the Back link (task 1004430) ----------
|
|
506
|
+
// A page reached by a link INSIDE another hall page — a profile opened from
|
|
507
|
+
// Builders, a task from a goal — shows "← <that page>" at the head of the top
|
|
508
|
+
// bar, so browsing a list and its records is a round trip. A sidebar hop is
|
|
509
|
+
// not a drill-down and shows none: the sidebar click leaves a one-shot note
|
|
510
|
+
// (sessionStorage) naming its target, and the page it lands on reads it.
|
|
511
|
+
// The origin is `?from=` (a link that knows where it came from), else the
|
|
512
|
+
// same-origin referrer. A page drawing its own back link (.rec-back — task,
|
|
513
|
+
// idea — or any element marked data-own-back, the tweak editor's "← studio")
|
|
514
|
+
// keeps it and the bar adds no second one.
|
|
515
|
+
var NAV_HOP_KEY = 'hall-nav-hop';
|
|
516
|
+
function hallPath(url) {
|
|
517
|
+
return String(url.pathname).replace(/^\/builders(?=\/|$)/, '').replace(/\.html$/, '').replace(/\/index$/, '') || '/';
|
|
518
|
+
}
|
|
519
|
+
function backOrigin() {
|
|
520
|
+
var hop = null;
|
|
521
|
+
try {
|
|
522
|
+
hop = window.sessionStorage.getItem(NAV_HOP_KEY);
|
|
523
|
+
window.sessionStorage.removeItem(NAV_HOP_KEY);
|
|
524
|
+
} catch (_) { /* private mode: no note, so fall through */ }
|
|
525
|
+
if (hop && hop === hallPath(location)) return null;
|
|
526
|
+
if (!document.querySelector || document.querySelector('.rec-back, [data-own-back]')) return null;
|
|
527
|
+
var here = hallPath(location) + (location.search || '');
|
|
528
|
+
var from = null;
|
|
529
|
+
var viaReferrer = false;
|
|
530
|
+
try {
|
|
531
|
+
var q = new URLSearchParams(location.search || '').get('from');
|
|
532
|
+
if (q) from = new URL(q, location.origin);
|
|
533
|
+
else if (document.referrer) { from = new URL(document.referrer); viaReferrer = true; }
|
|
534
|
+
} catch (_) { return null; }
|
|
535
|
+
if (!from || from.origin !== location.origin) return null;
|
|
536
|
+
var path = hallPath(from);
|
|
537
|
+
if (/^\/(api|auth|lib)(\/|$)/.test(path)) return null;
|
|
538
|
+
// The back link keeps the origin's query (a filtered list) but never its
|
|
539
|
+
// own ?from=, which would chain one page's way back into the next.
|
|
540
|
+
var params = new URLSearchParams(from.search);
|
|
541
|
+
params.delete('from');
|
|
542
|
+
var search = params.toString() ? '?' + params.toString() : '';
|
|
543
|
+
if (path + search === here) return null;
|
|
544
|
+
return { href: path + search + (from.hash || ''), path: path, label: backLabel(path, from.hash), viaReferrer: viaReferrer };
|
|
545
|
+
}
|
|
546
|
+
function backLabel(path, hash) {
|
|
547
|
+
if (path === '/') {
|
|
548
|
+
var m = /^#\/(task|idea|blocker)\/(\d+)/.exec(hash || '');
|
|
549
|
+
return m ? m[1] + ' ' + m[2] : (/^#standing/.test(hash || '') ? 'Standing' : 'Home');
|
|
550
|
+
}
|
|
551
|
+
var rec = /^\/(task|idea)\/(\d+)$/.exec(path);
|
|
552
|
+
if (rec) return rec[1] + ' ' + rec[2];
|
|
553
|
+
if (path === '/goals' && /^#\/goal\/\d+/.test(hash || '')) return 'goal ' + hash.split('/')[2];
|
|
554
|
+
for (var g = 0; g < NAV.length; g++) {
|
|
555
|
+
for (var i = 0; i < NAV[g].items.length; i++) {
|
|
556
|
+
if (NAV[g].items[i].href === path) return NAV[g].items[i].label;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return 'Back';
|
|
560
|
+
}
|
|
561
|
+
var BACK = null;
|
|
562
|
+
function backLinkHtml() {
|
|
563
|
+
BACK = backOrigin();
|
|
564
|
+
if (!BACK) return '';
|
|
565
|
+
return '<a class="topbar-back" id="topbar-back" href="' + esc(BACK.href) + '" title="Back to ' + esc(BACK.label) + '">' +
|
|
566
|
+
'<svg viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M11 4 6 9l5 5"/></svg>' +
|
|
567
|
+
'<span class="topbar-back__label">' + esc(BACK.label) + '</span></a>';
|
|
568
|
+
}
|
|
569
|
+
// Back through history when the origin IS the previous entry, so the list
|
|
570
|
+
// comes back where the reader left it (its scroll, its filters); the href
|
|
571
|
+
// stays the real address for a new tab or a lost history.
|
|
572
|
+
function onBackClick(e) {
|
|
573
|
+
if (!BACK || !BACK.viaReferrer || e.metaKey || e.ctrlKey || e.shiftKey || e.button > 0) return;
|
|
574
|
+
if (window.history && window.history.length > 1) { e.preventDefault(); window.history.back(); }
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// ---------- full screen (task 1004327; standard since task 1004430) ----------
|
|
578
|
+
// One switch on EVERY shelled page: it hides the sidebar, the top bar and the
|
|
579
|
+
// foot so the page fills the window, and the same button (the only thing left
|
|
580
|
+
// of the top bar) brings them back. Escape leaves too. A page opts OUT with
|
|
581
|
+
// <body data-fullscreen-switch="off">. A page that carries the bare attribute
|
|
582
|
+
// lays itself out for full screen (the sky, the studio); every other page is
|
|
583
|
+
// `plain` and style.css only steps its content clear of the corner button.
|
|
584
|
+
// The state is html[data-fullscreen="on"] — the data-theme / data-social
|
|
585
|
+
// pattern — so the chrome's hiding is style.css's, and a page that lays itself
|
|
586
|
+
// out against the chrome reads the same attribute.
|
|
510
587
|
//
|
|
511
588
|
// Remembered PER PAGE (`hall-fullscreen:<data-page>`): full screen is a choice
|
|
512
589
|
// about one surface, and the studio's must not follow the reader to the sky.
|
|
513
590
|
// Storage can throw in a private window; the chrome then just shows, which is
|
|
514
|
-
// the honest default.
|
|
591
|
+
// the honest default. Because it is remembered, a page can OPEN in full screen,
|
|
592
|
+
// so entering it says once how to leave (the hint below) — task 1004430 found
|
|
593
|
+
// /thinking read as "stuck without its bars" when nothing did.
|
|
515
594
|
var FULLSCREEN_KEY = 'hall-fullscreen:';
|
|
595
|
+
function fullscreenAttr() {
|
|
596
|
+
var b = document.body;
|
|
597
|
+
return b && b.getAttribute ? b.getAttribute('data-fullscreen-switch') : null;
|
|
598
|
+
}
|
|
516
599
|
function fullscreenPage() {
|
|
517
600
|
var b = document.body;
|
|
518
|
-
if (!b ||
|
|
601
|
+
if (!b || fullscreenAttr() === 'off' || !document.getElementById('app-topbar')) return null;
|
|
519
602
|
return (b.dataset && b.dataset.page) || 'page';
|
|
520
603
|
}
|
|
604
|
+
var fullscreenHintTimer = null;
|
|
605
|
+
function showFullscreenHint() {
|
|
606
|
+
try {
|
|
607
|
+
var hint = document.getElementById('fullscreen-hint');
|
|
608
|
+
if (!hint) {
|
|
609
|
+
hint = document.createElement('div');
|
|
610
|
+
hint.id = 'fullscreen-hint';
|
|
611
|
+
hint.className = 'fullscreen-hint';
|
|
612
|
+
hint.setAttribute('role', 'status');
|
|
613
|
+
document.body.appendChild(hint);
|
|
614
|
+
}
|
|
615
|
+
hint.textContent = 'Full screen — press Esc, or the button in the corner, to bring the bars back.';
|
|
616
|
+
hint.hidden = false;
|
|
617
|
+
window.clearTimeout(fullscreenHintTimer);
|
|
618
|
+
fullscreenHintTimer = window.setTimeout(function () { hint.hidden = true; }, 4500);
|
|
619
|
+
} catch (_) { /* cosmetic */ }
|
|
620
|
+
}
|
|
621
|
+
function hideFullscreenHint() {
|
|
622
|
+
var hint = document.getElementById('fullscreen-hint');
|
|
623
|
+
if (hint) hint.hidden = true;
|
|
624
|
+
}
|
|
521
625
|
function storedFullscreen() {
|
|
522
626
|
var page = fullscreenPage();
|
|
523
627
|
if (!page) return false;
|
|
@@ -532,13 +636,19 @@
|
|
|
532
636
|
if (!fullscreenPage()) on = false;
|
|
533
637
|
var root = document.documentElement;
|
|
534
638
|
if (on) root.dataset.fullscreen = 'on'; else delete root.dataset.fullscreen;
|
|
639
|
+
if (on && fullscreenAttr() === null) root.dataset.fullscreenPlain = 'on'; else delete root.dataset.fullscreenPlain;
|
|
640
|
+
if (on) showFullscreenHint(); else hideFullscreenHint();
|
|
535
641
|
var btn = document.getElementById('fullscreen-toggle');
|
|
536
642
|
if (btn) {
|
|
537
|
-
var label = on ? '
|
|
643
|
+
var label = on ? 'Exit full screen (Esc)' : 'Full screen — hide the sidebar and top bar';
|
|
538
644
|
btn.setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
539
|
-
btn.setAttribute('aria-label', on ? '
|
|
645
|
+
btn.setAttribute('aria-label', on ? 'Exit full screen' : 'Full screen');
|
|
540
646
|
btn.title = label;
|
|
541
|
-
|
|
647
|
+
// task 1004430: in full screen the way back is a labelled pill, not a
|
|
648
|
+
// bare glyph — it is the only chrome left, so it says what it does.
|
|
649
|
+
btn.innerHTML = on
|
|
650
|
+
? FULLSCREEN_ICONS.leave + '<span class="fullscreen-toggle__label" aria-hidden="true">Exit full screen</span>'
|
|
651
|
+
: FULLSCREEN_ICONS.enter;
|
|
542
652
|
}
|
|
543
653
|
if (on) closeDrawer();
|
|
544
654
|
}
|
|
@@ -1184,8 +1294,14 @@
|
|
|
1184
1294
|
return;
|
|
1185
1295
|
}
|
|
1186
1296
|
var a = e.target.closest && e.target.closest('a');
|
|
1187
|
-
if (a)
|
|
1297
|
+
if (a) {
|
|
1298
|
+
// A sidebar hop is not a drill-down: the page it opens shows no Back link.
|
|
1299
|
+
try { window.sessionStorage.setItem(NAV_HOP_KEY, hallPath(new URL(a.href, location.href))); } catch (_) { /* private mode */ }
|
|
1300
|
+
closeDrawer();
|
|
1301
|
+
}
|
|
1188
1302
|
});
|
|
1303
|
+
var back = document.getElementById('topbar-back');
|
|
1304
|
+
if (back) back.addEventListener('click', onBackClick);
|
|
1189
1305
|
if (IS_INDEX) {
|
|
1190
1306
|
window.addEventListener('hashchange', function () { route(); });
|
|
1191
1307
|
}
|
|
@@ -1209,13 +1325,23 @@
|
|
|
1209
1325
|
// Non-index pages: probe /api/bongos/me for cosmetic nav gating (the index's
|
|
1210
1326
|
// builders.js owns the call there and reports via applyAccess). A 401 keeps
|
|
1211
1327
|
// page behavior unchanged — each page's own script decides how to handle auth.
|
|
1212
|
-
function
|
|
1328
|
+
function markOwnProfile(me) {
|
|
1329
|
+
var id = new URLSearchParams(window.location.search || '').get('id');
|
|
1330
|
+
if (String(me.builder.id) !== String(id)) return;
|
|
1331
|
+
document.querySelectorAll('#app-sidebar .nav-item').forEach(function (a) {
|
|
1332
|
+
var target = a.getAttribute('href');
|
|
1333
|
+
if (target === '/roster') a.classList.remove('nav-item--active');
|
|
1334
|
+
if (target === '/profile') a.classList.add('nav-item--active');
|
|
1335
|
+
});
|
|
1336
|
+
}
|
|
1337
|
+
function probeMe(otherProfile) {
|
|
1213
1338
|
api.request('GET', '/api/bongos/me').then(function (res) {
|
|
1214
1339
|
if (res.status === 401) { applyAccess({ authed: false }); return null; }
|
|
1215
1340
|
if (!res.ok) return null;
|
|
1216
1341
|
return res.data;
|
|
1217
1342
|
}).then(function (me) {
|
|
1218
1343
|
if (!me || !me.builder) return;
|
|
1344
|
+
if (otherProfile) markOwnProfile(me);
|
|
1219
1345
|
var stages = (me.onboarding && me.onboarding.stages) || [];
|
|
1220
1346
|
var showWork = stages.some(function (s) { return s.id === 'ship_three' && s.is_current && !s.cleared; });
|
|
1221
1347
|
applyAccess({
|
|
@@ -1256,11 +1382,15 @@
|
|
|
1256
1382
|
} else {
|
|
1257
1383
|
// mark the current page in the sidebar
|
|
1258
1384
|
var path = window.location.pathname.replace(/^\/builders/, '').replace(/\.html$/, '') || '/';
|
|
1385
|
+
// task 1004430: someone else's profile belongs to Builders, not to your own
|
|
1386
|
+
// Profile; probeMe hands the mark back if the id turns out to be yours.
|
|
1387
|
+
var otherProfile = path === '/profile' && /(^|[?&])id=/.test(window.location.search || '');
|
|
1388
|
+
if (otherProfile) path = '/roster';
|
|
1259
1389
|
document.querySelectorAll('#app-sidebar .nav-item').forEach(function (a) {
|
|
1260
1390
|
var target = a.getAttribute('href');
|
|
1261
1391
|
if (target && !a.dataset.view && target === path) a.classList.add('nav-item--active');
|
|
1262
1392
|
});
|
|
1263
|
-
probeMe();
|
|
1393
|
+
probeMe(otherProfile);
|
|
1264
1394
|
}
|
|
1265
1395
|
|
|
1266
1396
|
window.OTBShell = {
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
|
|
177
177
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
178
178
|
|
|
179
|
-
<script src="/builders/shell.js?v=2026-09-30-
|
|
179
|
+
<script src="/builders/shell.js?v=2026-09-30-navback2"></script>
|
|
180
180
|
<script src="/builders/palette.js" defer></script>
|
|
181
181
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
182
182
|
<!-- The kit, for its ONE renderer: the full-size ship-time visual figure
|