@bongos/core 1.21.27 → 1.21.29
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 +89 -69
- package/docs/api/openapi.json +1 -1
- package/docs/api-reference.md +1 -1
- package/docs/copy-inventory.md +399 -391
- package/docs/copy-registry.json +532 -460
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-inventory.json +68 -0
- package/docs/page-readings.json +3737 -3587
- package/modules/hall-ui/public/atlas.html +3 -1
- package/modules/hall-ui/public/blockers.html +3 -1
- package/modules/hall-ui/public/board-room.html +3 -1
- package/modules/hall-ui/public/city.html +3 -1
- package/modules/hall-ui/public/collab.html +3 -1
- package/modules/hall-ui/public/commands.html +3 -1
- package/modules/hall-ui/public/copy-desk.html +3 -1
- package/modules/hall-ui/public/craft-mode.js +297 -0
- package/modules/hall-ui/public/deploy.html +3 -1
- package/modules/hall-ui/public/diagrams.html +3 -1
- package/modules/hall-ui/public/drachmae.html +3 -1
- package/modules/hall-ui/public/fleet.html +3 -1
- package/modules/hall-ui/public/gate.html +3 -1
- package/modules/hall-ui/public/goal-map.html +3 -1
- package/modules/hall-ui/public/goals.html +3 -1
- package/modules/hall-ui/public/government.html +3 -1
- package/modules/hall-ui/public/idea.html +3 -1
- package/modules/hall-ui/public/ideas.html +3 -1
- package/modules/hall-ui/public/index.html +3 -1
- package/modules/hall-ui/public/modules.html +3 -1
- package/modules/hall-ui/public/primer.html +3 -1
- package/modules/hall-ui/public/profile.html +3 -1
- package/modules/hall-ui/public/project-settings.html +3 -1
- package/modules/hall-ui/public/ranks.html +3 -1
- package/modules/hall-ui/public/roadmap.html +3 -1
- package/modules/hall-ui/public/roster.html +3 -1
- package/modules/hall-ui/public/sessions.html +3 -1
- package/modules/hall-ui/public/settings.html +3 -1
- package/modules/hall-ui/public/shell-trail.js +186 -0
- package/modules/hall-ui/public/shell.js +17 -172
- package/modules/hall-ui/public/street.html +3 -1
- package/modules/hall-ui/public/studio.html +3 -1
- package/modules/hall-ui/public/style.css +228 -0
- package/modules/hall-ui/public/task.html +3 -1
- package/modules/hall-ui/public/thinking.html +3 -1
- package/modules/hall-ui/public/tweak-editor.html +3 -1
- package/modules/hall-ui/public/watch.html +3 -1
- package/modules/hall-ui/public/work.html +3 -1
- package/modules/hall-ui/records/craft-mode.md +22 -0
- package/modules/hall-ui/records/hall-navigation.md +1 -1
- package/modules/provisioning/routes/callback-page.js +28 -65
- package/modules/provisioning/routes/provisioning.js +6 -6
- package/modules/public-landing/public/projects.html +68 -3
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/src/module-api.js +1 -1
- package/tests/craft_mode.mjs +267 -112
- package/tests/goal_map_page.mjs +2 -2
- package/tests/hall_city.mjs +1 -1
- package/tests/hall_fullscreen.mjs +3 -0
- package/tests/hall_street.mjs +1 -1
- package/tests/hall_tweak_editor.mjs +1 -1
- package/tests/nav_permission_atoms.mjs +1 -1
- package/tests/provisioning_callback_page.mjs +5 -5
- package/tests/provisioning_github_app_routes.mjs +24 -25
- package/tests/wizard_auto_open.mjs +94 -0
- package/tests/wizard_intent_resume.mjs +17 -2
|
@@ -91,7 +91,9 @@
|
|
|
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-10-02-
|
|
94
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
95
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
96
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
95
97
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
96
98
|
<script src="/builders/palette.js" defer></script>
|
|
97
99
|
<script src="/builders/atlas.js?v=2026-09-02-index" defer></script>
|
|
@@ -50,7 +50,9 @@
|
|
|
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-10-02-
|
|
53
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
54
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
55
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
54
56
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
55
57
|
<script src="/builders/palette.js" defer></script>
|
|
56
58
|
<!-- shared frontend toolkit (window.OTB — rank labels, number formats) + the
|
|
@@ -60,7 +60,9 @@
|
|
|
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-10-02-
|
|
63
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
64
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
65
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
64
66
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
65
67
|
<script src="/builders/palette.js" defer></script>
|
|
66
68
|
<script src="/builders/dom-utils.js?v=2026-06-16-board"></script>
|
|
@@ -83,7 +83,9 @@
|
|
|
83
83
|
</div>
|
|
84
84
|
</div>
|
|
85
85
|
|
|
86
|
-
<script src="/builders/shell.js?v=2026-10-02-
|
|
86
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
87
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
88
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
87
89
|
<script src="/builders/palette.js" defer></script>
|
|
88
90
|
<script src="/builders/city-draw.js?v=2026-10-02-city1"></script>
|
|
89
91
|
<script src="/builders/city.js?v=2026-10-02-city1"></script>
|
|
@@ -148,7 +148,9 @@
|
|
|
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-10-02-
|
|
151
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
152
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
153
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
152
154
|
<script src="/builders/palette.js" defer></script>
|
|
153
155
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
154
156
|
<script src="/builders/collab-lib.js?v=2026-09-24-archive"></script>
|
|
@@ -54,7 +54,9 @@
|
|
|
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-10-02-
|
|
57
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
58
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
59
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
58
60
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
59
61
|
<script src="/builders/palette.js" defer></script>
|
|
60
62
|
<script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>
|
|
@@ -177,7 +177,9 @@
|
|
|
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-10-02-
|
|
180
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
181
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
182
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
181
183
|
<script src="/builders/palette.js" defer></script>
|
|
182
184
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
183
185
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
// craft-mode.js — the hall's craft mode (task 1004492, goal 1000095 WA6).
|
|
2
|
+
//
|
|
3
|
+
// On entering the hall (once per browser session) a picker asks "What are you
|
|
4
|
+
// doing now?": Building, Artistry, Ideating, Governing, or Legacy mode. The
|
|
5
|
+
// answer is ONE attribute, html[data-craft="<mode>"], that every hall page can
|
|
6
|
+
// read, and a switch in the top bar changes it at any time without a reload.
|
|
7
|
+
// Each change also fires `otb:craft` on document ({ detail: { mode } }).
|
|
8
|
+
//
|
|
9
|
+
// It is a MODE the existing hall wears, never a second hall (the founding-mode
|
|
10
|
+
// precedent, docs/design/project-startup-direction.md). This task only records
|
|
11
|
+
// and shows the choice; the nav, tools and colours that follow it are their own
|
|
12
|
+
// tasks (1004493 onward). Legacy mode is the hall exactly as it was.
|
|
13
|
+
//
|
|
14
|
+
// NO MODE is the default and the fallback: a reader who closes the picker, a
|
|
15
|
+
// browser whose storage throws, a page that opts out — none of them get the
|
|
16
|
+
// attribute, and the hall renders as it did before craft modes existed
|
|
17
|
+
// (tests/craft_mode.mjs pins it). Cosmetic only; nothing is enforced (ADR 0016).
|
|
18
|
+
//
|
|
19
|
+
// Loaded BEFORE shell.js on every hall page. shell.js asks for the switch's
|
|
20
|
+
// markup when it draws the top bar, calls mount() once, and hands onAccess()
|
|
21
|
+
// what /me said — the picker waits for a signed-in builder, so a visitor who
|
|
22
|
+
// is not signed in is never asked.
|
|
23
|
+
(function () {
|
|
24
|
+
'use strict';
|
|
25
|
+
|
|
26
|
+
var ICONS = {
|
|
27
|
+
building: '<path d="M2 13.5h12M3.5 13.5V8.5h4v5M7.5 13.5V4.5h5v9"/>',
|
|
28
|
+
artistry: '<path d="M8 2a6 6 0 1 0 0 12c.9 0 1.4-.6 1.4-1.3 0-.8-.6-1-.6-1.7 0-.6.5-1 1.2-1h1.6A2.4 2.4 0 0 0 14 7.6C14 4.5 11.3 2 8 2Z"/><path d="M5 6.2h.01M7.6 4.6h.01M10.4 5.2h.01M4.6 9h.01" stroke-width="2.2"/>',
|
|
29
|
+
ideating: '<path d="M6 12.5h4M6.6 14.5h2.8M8 1.8a4.2 4.2 0 0 0-2.6 7.5c.6.5 1 1.2 1 2h3.2c0-.8.4-1.5 1-2A4.2 4.2 0 0 0 8 1.8Z"/>',
|
|
30
|
+
governing: '<path d="M2 6 8 2.5 14 6M3.5 6.5v6M6.5 6.5v6M9.5 6.5v6M12.5 6.5v6M2 13.5h12"/>',
|
|
31
|
+
legacy: '<path d="M3 3.5h10v9H3z"/><path d="M3 6.5h10M6 6.5v6"/>',
|
|
32
|
+
modes: '<rect x="2.5" y="2.5" width="4.5" height="4.5" rx="1"/><rect x="9" y="2.5" width="4.5" height="4.5" rx="1"/><rect x="2.5" y="9" width="4.5" height="4.5" rx="1"/><rect x="9" y="9" width="4.5" height="4.5" rx="1"/>',
|
|
33
|
+
};
|
|
34
|
+
// The four crafts, then Legacy. `short` is the switch's label; `line` is the
|
|
35
|
+
// picker's one sentence — what you do in the mode, never a feature not built yet.
|
|
36
|
+
var MODES = [
|
|
37
|
+
{ id: 'building', label: 'Building', short: 'Building', line: 'Claim tasks and ship code.' },
|
|
38
|
+
{ id: 'artistry', label: 'Artistry', short: 'Artistry', line: 'Review how pages look and read.' },
|
|
39
|
+
{ id: 'ideating', label: 'Ideating', short: 'Ideating', line: 'Turn thoughts into ideas.' },
|
|
40
|
+
{ id: 'governing', label: 'Governing', short: 'Governing', line: 'Decide, approve and keep it healthy.' },
|
|
41
|
+
{ id: 'legacy', label: 'Legacy mode', short: 'Legacy', line: 'The hall as it was: every tab, no mode tools or colour.' },
|
|
42
|
+
];
|
|
43
|
+
var IDS = MODES.map(function (m) { return m.id; });
|
|
44
|
+
// sessionStorage: this session's mode, or that the picker was already shown.
|
|
45
|
+
var MODE_KEY = 'hall-craft';
|
|
46
|
+
var ASKED_KEY = 'hall-craft-asked';
|
|
47
|
+
// localStorage: the mode to keep when "Ask me again next session" is unticked.
|
|
48
|
+
var KEEP_KEY = 'hall-craft-keep';
|
|
49
|
+
|
|
50
|
+
function esc(s) {
|
|
51
|
+
return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
|
|
52
|
+
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c];
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function icon(id, cls) {
|
|
56
|
+
return '<svg class="' + cls + '" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' + ICONS[id] + '</svg>';
|
|
57
|
+
}
|
|
58
|
+
function valid(v) { return IDS.indexOf(v) !== -1 ? v : null; }
|
|
59
|
+
function get(store, key) { try { return window[store].getItem(key); } catch (_) { return null; } }
|
|
60
|
+
function set(store, key, v) { try { window[store].setItem(key, v); } catch (_) { /* private mode */ } }
|
|
61
|
+
function drop(store, key) { try { window[store].removeItem(key); } catch (_) { /* private mode */ } }
|
|
62
|
+
// Storage that throws cannot remember that the picker was shown, so it would ask
|
|
63
|
+
// on every page; such a browser is simply never asked (no mode is the fallback).
|
|
64
|
+
function sessionOk() {
|
|
65
|
+
try { window.sessionStorage.setItem(ASKED_KEY + ':probe', '1'); window.sessionStorage.removeItem(ASKED_KEY + ':probe'); return true; } catch (_) { return false; }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// The mode this session is in: chosen this session, else the one kept from an
|
|
69
|
+
// earlier session. null = no mode, which is the hall as it always was.
|
|
70
|
+
function read() {
|
|
71
|
+
return valid(get('sessionStorage', MODE_KEY)) || valid(get('localStorage', KEEP_KEY));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// A page can say it never wears a mode: <body data-craft-mode="off">.
|
|
75
|
+
function pageOptsOut() {
|
|
76
|
+
var b = document.body;
|
|
77
|
+
return !!(b && b.getAttribute && b.getAttribute('data-craft-mode') === 'off');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function apply(mode) {
|
|
81
|
+
var root = document.documentElement;
|
|
82
|
+
if (mode) root.dataset.craft = mode; else delete root.dataset.craft;
|
|
83
|
+
var opts = document.querySelectorAll('#craft-switch [data-craft-opt]');
|
|
84
|
+
for (var i = 0; i < opts.length; i++) {
|
|
85
|
+
var on = opts[i].getAttribute('data-craft-opt') === mode;
|
|
86
|
+
opts[i].setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
87
|
+
}
|
|
88
|
+
var sw = document.getElementById('craft-switch');
|
|
89
|
+
if (sw) sw.classList.toggle('craft-switch--unset', !mode);
|
|
90
|
+
try { document.dispatchEvent(new CustomEvent('otb:craft', { detail: { mode: mode } })); } catch (_) { /* old engine */ }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Choose a mode: this session always; across sessions only when asked to keep it.
|
|
94
|
+
function choose(mode, keep) {
|
|
95
|
+
mode = valid(mode);
|
|
96
|
+
if (!mode) return;
|
|
97
|
+
set('sessionStorage', MODE_KEY, mode);
|
|
98
|
+
set('sessionStorage', ASKED_KEY, '1');
|
|
99
|
+
if (keep === true) set('localStorage', KEEP_KEY, mode);
|
|
100
|
+
else if (keep === false) drop('localStorage', KEEP_KEY);
|
|
101
|
+
else if (get('localStorage', KEEP_KEY)) set('localStorage', KEEP_KEY, mode);
|
|
102
|
+
apply(mode);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ---------- the header switch ----------
|
|
106
|
+
function switchHtml() {
|
|
107
|
+
if (pageOptsOut()) return '';
|
|
108
|
+
var current = read();
|
|
109
|
+
return '<div class="craft-switch' + (current ? '' : ' craft-switch--unset') + '" id="craft-switch" role="group" aria-label="Mode">' +
|
|
110
|
+
MODES.map(function (m) {
|
|
111
|
+
return '<button class="craft-switch__opt craft-switch__opt--' + m.id + '" type="button" data-craft-opt="' + m.id + '"' +
|
|
112
|
+
' aria-pressed="' + (m.id === current ? 'true' : 'false') + '" title="' + esc(m.label + ' — ' + m.line) + '">' +
|
|
113
|
+
icon(m.id, 'craft-switch__icon') + '<span class="craft-switch__label">' + esc(m.short) + '</span></button>';
|
|
114
|
+
}).join('') +
|
|
115
|
+
// At phone width the options fold away and this one button opens the picker.
|
|
116
|
+
'<button class="craft-switch__open" type="button" data-craft-open aria-haspopup="dialog" aria-label="Choose your mode" title="Choose your mode">' +
|
|
117
|
+
icon('modes', 'craft-switch__icon') + '</button>' +
|
|
118
|
+
'</div>';
|
|
119
|
+
}
|
|
120
|
+
function narrow() {
|
|
121
|
+
return !!(window.matchMedia && window.matchMedia('(max-width: 640px)').matches);
|
|
122
|
+
}
|
|
123
|
+
function onSwitchClick(e) {
|
|
124
|
+
var btn = e.target.closest && e.target.closest('button');
|
|
125
|
+
if (!btn) return;
|
|
126
|
+
if (btn.hasAttribute('data-craft-open')) { openPicker(); return; }
|
|
127
|
+
var mode = btn.getAttribute('data-craft-opt');
|
|
128
|
+
// At phone width only the current mode shows; tapping it opens the full picker.
|
|
129
|
+
if (narrow() && btn.getAttribute('aria-pressed') === 'true') { openPicker(); return; }
|
|
130
|
+
choose(mode);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ---------- the picker ----------
|
|
134
|
+
var picker = null, returnFocus = null;
|
|
135
|
+
// Each door's little scene, drawn from the approved prototype: the work desk,
|
|
136
|
+
// the night room, the sky of ideas, the governor city. Fixed positions (a
|
|
137
|
+
// seeded walk), so every visit draws the same picture. Decorative only.
|
|
138
|
+
function seeded(seed) {
|
|
139
|
+
return function () { seed = (seed * 9301 + 49297) % 233280; return seed / 233280; };
|
|
140
|
+
}
|
|
141
|
+
function dot(x, y, r, style, kind) {
|
|
142
|
+
return '<span class="craft-art__dot craft-art__dot--' + kind + '" style="left:' + x + 'px;top:' + y + 'px;width:' + r + 'px;height:' + r + 'px;' + (style || '') + '"></span>';
|
|
143
|
+
}
|
|
144
|
+
function cityPaths() {
|
|
145
|
+
var TW = 26, TH = 13, OX = 150, OY = 30, S = 0.5, out = '';
|
|
146
|
+
var P = function (x, y, z) { return [OX + (x - y) * TW / 2, OY + (x + y) * TH / 2 - (z || 0) * S]; };
|
|
147
|
+
var poly = function (pts) { return 'M' + pts.map(function (p) { return Math.round(p[0] * 10) / 10 + ' ' + Math.round(p[1] * 10) / 10; }).join('L') + 'Z'; };
|
|
148
|
+
var T = ['#25252a', '#18181c', '#3b3b41', 'rgba(255,255,255,.14)'];
|
|
149
|
+
var G = ['rgba(120,140,230,.17)', 'rgba(100,120,210,.12)', 'rgba(150,170,255,.22)', 'rgba(170,190,255,.42)'];
|
|
150
|
+
var face = function (pts, fill, stroke) { out += '<path d="' + poly(pts) + '" fill="' + fill + '" stroke="' + stroke + '"/>'; };
|
|
151
|
+
var box = function (x0, y0, x1, y1, z0, h, t) {
|
|
152
|
+
var z1 = z0 + h;
|
|
153
|
+
face([P(x0, y1, z1), P(x1, y1, z1), P(x1, y1, z0), P(x0, y1, z0)], t[0], t[3]);
|
|
154
|
+
face([P(x1, y1, z1), P(x1, y0, z1), P(x1, y0, z0), P(x1, y1, z0)], t[1], t[3]);
|
|
155
|
+
face([P(x0, y0, z1), P(x1, y0, z1), P(x1, y1, z1), P(x0, y1, z1)], t[2], t[3]);
|
|
156
|
+
};
|
|
157
|
+
face([P(0, 0), P(6, 0), P(6, 6), P(0, 6)], 'rgba(255,255,255,.03)', 'rgba(255,255,255,.12)');
|
|
158
|
+
box(0.4, 0.4, 1.6, 1.6, 0, 30, T); box(2.3, 0.3, 3.7, 1.5, 0, 22, T); box(4.3, 0.4, 5.6, 1.6, 0, 40, T);
|
|
159
|
+
box(0.4, 2.4, 1.6, 3.6, 0, 18, T); box(2.4, 2.4, 3.6, 3.6, 0, 70, T); box(2.65, 2.65, 3.35, 3.35, 70, 26, G);
|
|
160
|
+
box(4.4, 2.4, 5.6, 3.6, 0, 26, G); box(0.4, 4.4, 1.6, 5.6, 0, 34, T);
|
|
161
|
+
return out;
|
|
162
|
+
}
|
|
163
|
+
function artHtml(id) {
|
|
164
|
+
var html = '', rnd, i;
|
|
165
|
+
if (id === 'building') {
|
|
166
|
+
html = '<span class="craft-art__bar" style="left:20px;top:22px;width:110px"></span>' +
|
|
167
|
+
'<span class="craft-art__bar craft-art__bar--dim" style="left:20px;top:42px;width:150px"></span>' +
|
|
168
|
+
'<span class="craft-art__pill" style="left:20px;top:68px"></span><span class="craft-art__card"></span>';
|
|
169
|
+
} else if (id === 'artistry') {
|
|
170
|
+
rnd = seeded(7);
|
|
171
|
+
for (i = 0; i < 14; i++) html += dot(Math.round(rnd() * 250), Math.round(rnd() * 66), rnd() > 0.8 ? 2 : 1, 'opacity:' + (0.4 + rnd() * 0.6).toFixed(2), 'star');
|
|
172
|
+
html += '<span class="craft-art__moon"></span><span class="craft-art__ground"></span>' +
|
|
173
|
+
'<span class="craft-art__house" style="left:24px;height:54px;width:26px"></span><span class="craft-art__house" style="left:60px;height:44px;width:34px"></span>' +
|
|
174
|
+
dot(32, 66, 3, '', 'lit') + dot(70, 72, 3, '', 'lit');
|
|
175
|
+
} else if (id === 'ideating') {
|
|
176
|
+
rnd = seeded(11);
|
|
177
|
+
html = '<span class="craft-art__ring"></span>';
|
|
178
|
+
for (i = 0; i < 18; i++) {
|
|
179
|
+
var proto = rnd() > 0.7, r = proto ? 6 : (rnd() > 0.75 ? 5 : 2);
|
|
180
|
+
html += dot(Math.round(rnd() * 260), Math.round(6 + rnd() * 90), r, '', proto ? 'proto' : (r > 3 ? 'glow' : 'gold'));
|
|
181
|
+
}
|
|
182
|
+
} else if (id === 'governing') {
|
|
183
|
+
html = '<svg class="craft-art__city" viewBox="0 0 300 110" aria-hidden="true">' + cityPaths() + '</svg>';
|
|
184
|
+
}
|
|
185
|
+
return '<span class="craft-art craft-art--' + id + '" aria-hidden="true">' + html + '</span>';
|
|
186
|
+
}
|
|
187
|
+
function pickerHtml(preselect) {
|
|
188
|
+
var doors = MODES.filter(function (m) { return m.id !== 'legacy'; }).map(function (m) {
|
|
189
|
+
return '<button class="craft-door craft-door--' + m.id + (m.id === preselect ? ' craft-door--pre' : '') + '" type="button" data-craft-pick="' + m.id + '">' +
|
|
190
|
+
artHtml(m.id) +
|
|
191
|
+
'<span class="craft-door__head">' + icon(m.id, 'craft-door__icon') + '<span class="craft-door__name">' + esc(m.label) + '</span></span>' +
|
|
192
|
+
'<span class="craft-door__line">' + esc(m.line) + '</span></button>';
|
|
193
|
+
}).join('');
|
|
194
|
+
var legacy = MODES[MODES.length - 1];
|
|
195
|
+
return '<div class="craft-picker__panel" role="dialog" aria-modal="true" aria-labelledby="craft-picker-title" aria-describedby="craft-picker-lede">' +
|
|
196
|
+
'<button class="craft-picker__close" type="button" data-craft-close aria-label="Close without choosing">' +
|
|
197
|
+
'<svg viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><path d="M5 5l8 8M13 5l-8 8"/></svg></button>' +
|
|
198
|
+
'<p class="craft-picker__eyebrow">Builders hall · this session</p>' +
|
|
199
|
+
'<h2 class="craft-picker__title" id="craft-picker-title">What are you doing now?</h2>' +
|
|
200
|
+
'<p class="craft-picker__lede" id="craft-picker-lede">Pick one. You can switch any time from the top bar.</p>' +
|
|
201
|
+
'<div class="craft-picker__doors">' + doors + '</div>' +
|
|
202
|
+
'<div class="craft-picker__foot">' +
|
|
203
|
+
'<label class="craft-picker__again"><input type="checkbox" data-craft-again checked> Ask me again next session</label>' +
|
|
204
|
+
'<span class="craft-picker__side">' +
|
|
205
|
+
(preselect === 'artistry' ? '<span class="craft-picker__hint">Artists start on Artistry.</span>' : '') +
|
|
206
|
+
'<button class="craft-picker__legacy" type="button" data-craft-pick="legacy" title="' + esc(legacy.line) + '">Legacy mode · the hall as it was</button>' +
|
|
207
|
+
'</span>' +
|
|
208
|
+
'</div>' +
|
|
209
|
+
'</div>';
|
|
210
|
+
}
|
|
211
|
+
function focusables() {
|
|
212
|
+
return picker ? Array.prototype.slice.call(picker.querySelectorAll('button, input')) : [];
|
|
213
|
+
}
|
|
214
|
+
function onPickerKey(e) {
|
|
215
|
+
if (!picker) return;
|
|
216
|
+
if (e.key === 'Escape') { e.preventDefault(); closePicker(); return; }
|
|
217
|
+
if (e.key !== 'Tab') return;
|
|
218
|
+
var f = focusables();
|
|
219
|
+
if (!f.length) return;
|
|
220
|
+
var first = f[0], last = f[f.length - 1];
|
|
221
|
+
if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last.focus(); }
|
|
222
|
+
else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first.focus(); }
|
|
223
|
+
}
|
|
224
|
+
function onPickerClick(e) {
|
|
225
|
+
if (e.target === picker) { closePicker(); return; }
|
|
226
|
+
var btn = e.target.closest && e.target.closest('button');
|
|
227
|
+
if (!btn) return;
|
|
228
|
+
if (btn.hasAttribute('data-craft-close')) { closePicker(); return; }
|
|
229
|
+
var mode = btn.getAttribute('data-craft-pick');
|
|
230
|
+
if (!mode) return;
|
|
231
|
+
var again = picker.querySelector('[data-craft-again]');
|
|
232
|
+
choose(mode, !(again && again.checked));
|
|
233
|
+
closePicker();
|
|
234
|
+
}
|
|
235
|
+
function openPicker(preselect) {
|
|
236
|
+
if (picker || pageOptsOut() || !document.body) return;
|
|
237
|
+
set('sessionStorage', ASKED_KEY, '1');
|
|
238
|
+
returnFocus = document.activeElement;
|
|
239
|
+
picker = document.createElement('div');
|
|
240
|
+
picker.className = 'craft-picker';
|
|
241
|
+
picker.id = 'craft-picker';
|
|
242
|
+
picker.innerHTML = pickerHtml(valid(preselect) || read());
|
|
243
|
+
picker.addEventListener('click', onPickerClick);
|
|
244
|
+
document.addEventListener('keydown', onPickerKey, true);
|
|
245
|
+
document.body.appendChild(picker);
|
|
246
|
+
document.documentElement.classList.add('craft-picker-open');
|
|
247
|
+
// Focus the pre-selected door; with none, the close button, so no door looks chosen.
|
|
248
|
+
var pre = picker.querySelector('.craft-door--pre') || picker.querySelector('[data-craft-close]');
|
|
249
|
+
if (pre && pre.focus) pre.focus();
|
|
250
|
+
}
|
|
251
|
+
// Closing without choosing leaves the mode as it was: no mode is the hall as today.
|
|
252
|
+
function closePicker() {
|
|
253
|
+
if (!picker) return;
|
|
254
|
+
document.removeEventListener('keydown', onPickerKey, true);
|
|
255
|
+
if (picker.parentNode) picker.parentNode.removeChild(picker);
|
|
256
|
+
picker = null;
|
|
257
|
+
document.documentElement.classList.remove('craft-picker-open');
|
|
258
|
+
if (returnFocus && returnFocus.focus) { try { returnFocus.focus(); } catch (_) { /* gone */ } }
|
|
259
|
+
returnFocus = null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Artistry is the pre-selection for a builder whose main role is artist.
|
|
263
|
+
function preselectFor(builder) {
|
|
264
|
+
if (!builder) return null;
|
|
265
|
+
var main = builder.main_discipline;
|
|
266
|
+
var crafts = Array.isArray(builder.preferred_disciplines) ? builder.preferred_disciplines : [];
|
|
267
|
+
return (main === 'artist' || (!main && crafts[0] === 'artist')) ? 'artistry' : null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// ---------- the shell's three calls ----------
|
|
271
|
+
var mounted = false;
|
|
272
|
+
function mount() {
|
|
273
|
+
if (pageOptsOut()) return;
|
|
274
|
+
apply(read());
|
|
275
|
+
if (mounted) return;
|
|
276
|
+
mounted = true;
|
|
277
|
+
var sw = document.getElementById('craft-switch');
|
|
278
|
+
if (sw) sw.addEventListener('click', onSwitchClick);
|
|
279
|
+
}
|
|
280
|
+
// Once a signed-in builder is known, ask — unless this session already has a
|
|
281
|
+
// mode, already saw the picker, or the page opts out.
|
|
282
|
+
function onAccess(access, builder) {
|
|
283
|
+
if (!access || access.authed !== true || !builder || pageOptsOut() || !sessionOk()) return;
|
|
284
|
+
if (read() || get('sessionStorage', ASKED_KEY)) return;
|
|
285
|
+
openPicker(preselectFor(builder));
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
window.OTBCraftMode = {
|
|
289
|
+
MODES: IDS.slice(),
|
|
290
|
+
current: read,
|
|
291
|
+
choose: choose,
|
|
292
|
+
open: openPicker,
|
|
293
|
+
switchHtml: switchHtml,
|
|
294
|
+
mount: mount,
|
|
295
|
+
onAccess: onAccess,
|
|
296
|
+
};
|
|
297
|
+
})();
|
|
@@ -74,7 +74,9 @@
|
|
|
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-10-02-
|
|
77
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
78
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
79
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
78
80
|
<script src="/builders/palette.js" defer></script>
|
|
79
81
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
80
82
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -97,7 +97,9 @@
|
|
|
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-10-02-
|
|
100
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
101
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
102
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
101
103
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
102
104
|
<script src="/builders/palette.js" defer></script>
|
|
103
105
|
<script src="/builders/diagram-viewer.js?v=2026-06-14-diagviewer-1" defer></script>
|
|
@@ -98,7 +98,9 @@
|
|
|
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-10-02-
|
|
101
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
102
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
103
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
102
104
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
103
105
|
<script src="/builders/palette.js" defer></script>
|
|
104
106
|
<script src="/builders/md-reader.js?v=2026-09-02-mdreader-2"></script>
|
|
@@ -54,7 +54,9 @@
|
|
|
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-10-02-
|
|
57
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
58
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
59
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
58
60
|
<script src="/builders/palette.js" defer></script>
|
|
59
61
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
60
62
|
<script src="/builders/hall-kit.js"></script>
|
|
@@ -77,7 +77,9 @@
|
|
|
77
77
|
<div id="gate-modal-root"></div>
|
|
78
78
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
79
79
|
|
|
80
|
-
<script src="/builders/shell.js?v=2026-10-02-
|
|
80
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
81
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
82
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
81
83
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
82
84
|
<script src="/builders/palette.js" defer></script>
|
|
83
85
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
@@ -137,7 +137,9 @@
|
|
|
137
137
|
</div>
|
|
138
138
|
</div>
|
|
139
139
|
|
|
140
|
-
<script src="/builders/shell.js?v=2026-10-02-
|
|
140
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
141
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
142
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
141
143
|
<script src="/builders/palette.js" defer></script>
|
|
142
144
|
|
|
143
145
|
<script src="/builders/idea-objects.js?v=2026-09-27-split"></script>
|
|
@@ -230,7 +230,9 @@
|
|
|
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-10-02-
|
|
233
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
234
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
235
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
234
236
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
235
237
|
<script src="/builders/palette.js" defer></script>
|
|
236
238
|
<script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>
|
|
@@ -134,7 +134,9 @@
|
|
|
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-10-02-
|
|
137
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
138
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
139
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
138
140
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
139
141
|
<script src="/builders/palette.js" defer></script>
|
|
140
142
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
|
|
51
51
|
<div id="toast" class="toast" role="status" aria-live="polite" data-visible="0"></div>
|
|
52
52
|
|
|
53
|
-
<script src="/builders/shell.js?v=2026-10-02-
|
|
53
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
54
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
55
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
54
56
|
<script src="/builders/palette.js" defer></script>
|
|
55
57
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib" defer></script>
|
|
56
58
|
<!-- task-detail.js still owns the #/idea/N and #/blocker/N overlay, so a ref
|
|
@@ -225,7 +225,9 @@
|
|
|
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-10-02-
|
|
228
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
229
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
230
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
229
231
|
<script src="/builders/palette.js" defer></script>
|
|
230
232
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
231
233
|
<!-- task 1003069 (R08) — the quick-filing form's routed result links a task
|
|
@@ -106,7 +106,9 @@
|
|
|
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-10-02-
|
|
109
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft" defer></script>
|
|
110
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft" defer></script>
|
|
111
|
+
<script src="/builders/shell.js?v=2026-10-02-craft" defer></script>
|
|
110
112
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
111
113
|
<script src="/builders/palette.js" defer></script>
|
|
112
114
|
<!-- task 2166: the shared component kit (window.OTBKit) — pager/ledger/rail.
|
|
@@ -101,7 +101,9 @@
|
|
|
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-10-02-
|
|
104
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
105
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
106
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
105
107
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
106
108
|
<script src="/builders/palette.js" defer></script>
|
|
107
109
|
<script src="/builders/dom-utils.js?v=2026-06-23-contrib"></script>
|
|
@@ -115,7 +115,9 @@
|
|
|
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-10-02-
|
|
118
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
119
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
120
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
119
121
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
120
122
|
<script src="/builders/palette.js" defer></script>
|
|
121
123
|
<!-- the shared markdown reader (window.OTBMdReader) — primer.js renders through
|
|
@@ -206,7 +206,9 @@
|
|
|
206
206
|
|
|
207
207
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
208
208
|
chrome exists before the page script runs. -->
|
|
209
|
-
<script src="/builders/shell.js?v=2026-10-02-
|
|
209
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
210
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
211
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
210
212
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
211
213
|
<script src="/builders/palette.js" defer></script>
|
|
212
214
|
<!-- shared frontend toolkit (window.OTB) — loaded before profile.js, which pulls from it. -->
|
|
@@ -58,7 +58,9 @@
|
|
|
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-10-02-
|
|
61
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
62
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
63
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
62
64
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
63
65
|
<script src="/builders/palette.js" defer></script>
|
|
64
66
|
<script src="/builders/dom-utils.js?v=2026-06-16-gate"></script>
|
|
@@ -77,7 +77,9 @@
|
|
|
77
77
|
|
|
78
78
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
79
79
|
chrome exists before the page script runs. -->
|
|
80
|
-
<script src="/builders/shell.js?v=2026-10-02-
|
|
80
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
81
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
82
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
81
83
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
82
84
|
<script src="/builders/palette.js" defer></script>
|
|
83
85
|
<!-- shared frontend toolkit (window.OTB) — loaded before ranks.js, which pulls from it. -->
|
|
@@ -41,7 +41,9 @@
|
|
|
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-10-02-
|
|
44
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
45
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
46
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
45
47
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
46
48
|
<script src="/builders/palette.js" defer></script>
|
|
47
49
|
<script src="/builders/dom-utils.js?v=2026-06-14-domutils"></script>
|
|
@@ -53,7 +53,9 @@
|
|
|
53
53
|
|
|
54
54
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
55
55
|
chrome exists before the page script runs. -->
|
|
56
|
-
<script src="/builders/shell.js?v=2026-10-02-
|
|
56
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
57
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
58
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
57
59
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
58
60
|
<script src="/builders/palette.js" defer></script>
|
|
59
61
|
<!-- shared frontend toolkit (window.OTB — rank labels, number formats) + the
|
|
@@ -111,7 +111,9 @@
|
|
|
111
111
|
|
|
112
112
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
113
113
|
chrome exists before the page script runs. -->
|
|
114
|
-
<script src="/builders/shell.js?v=2026-10-02-
|
|
114
|
+
<script src="/builders/shell-trail.js?v=2026-10-02-craft"></script>
|
|
115
|
+
<script src="/builders/craft-mode.js?v=2026-10-02-craft"></script>
|
|
116
|
+
<script src="/builders/shell.js?v=2026-10-02-craft"></script>
|
|
115
117
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
116
118
|
<script src="/builders/palette.js" defer></script>
|
|
117
119
|
<!-- shared frontend toolkit (window.OTB) — loaded BEFORE sessions.js so it can pull from it. -->
|