@bongos/core 1.19.1051 → 1.19.1052
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 +60 -55
- package/docs/copy-inventory.md +85 -79
- package/docs/copy-registry.json +212 -138
- package/docs/module-api-changelog.md +2 -0
- 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/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/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 +77 -1
- package/modules/hall-ui/public/sky-data.js +13 -2
- package/modules/hall-ui/public/sky-interaction.js +13 -8
- package/modules/hall-ui/public/sky-layout.js +6 -1
- package/modules/hall-ui/public/studio.html +10 -4
- package/modules/hall-ui/public/studio.states.json +76 -1
- package/modules/hall-ui/public/style.css +53 -0
- package/modules/hall-ui/public/task.html +1 -1
- package/modules/hall-ui/public/thinking.css +54 -16
- package/modules/hall-ui/public/thinking.html +38 -18
- package/modules/hall-ui/public/thinking.states.json +19 -2
- package/modules/hall-ui/public/watch.html +1 -1
- package/modules/hall-ui/public/work.html +1 -1
- package/modules/hall-ui/records/sky.md +9 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +6 -0
- package/src/module-api.js +1 -1
- package/tests/goal_map_page.mjs +5 -3
- package/tests/hall_audit.mjs +2 -1
- package/tests/hall_fullscreen.mjs +196 -0
- package/tests/nav_permission_atoms.mjs +1 -1
|
@@ -971,6 +971,59 @@ main:focus { outline: none; }
|
|
|
971
971
|
background: var(--accent-tint);
|
|
972
972
|
color: var(--accent-ink);
|
|
973
973
|
}
|
|
974
|
+
/* task 1004327: the full-screen switch — the theme toggle's sibling, on the
|
|
975
|
+
pages that opt in (body[data-fullscreen-switch]). */
|
|
976
|
+
.fullscreen-toggle {
|
|
977
|
+
display: inline-flex;
|
|
978
|
+
align-items: center;
|
|
979
|
+
justify-content: center;
|
|
980
|
+
width: 32px; height: 32px;
|
|
981
|
+
border: 0;
|
|
982
|
+
border-radius: var(--radius-pill);
|
|
983
|
+
background: none;
|
|
984
|
+
color: var(--ink-soft);
|
|
985
|
+
cursor: pointer;
|
|
986
|
+
padding: 0;
|
|
987
|
+
flex-shrink: 0;
|
|
988
|
+
}
|
|
989
|
+
.fullscreen-toggle:hover { color: var(--ink); }
|
|
990
|
+
.fullscreen-toggle svg { width: 16px; height: 16px; }
|
|
991
|
+
|
|
992
|
+
/* FULL SCREEN (html[data-fullscreen="on"], shell.js). The sidebar, the scrim and
|
|
993
|
+
the foot leave the layout; the top bar does NOT leave the document — it
|
|
994
|
+
collapses to the one button that brings the chrome back, floating in the
|
|
995
|
+
corner it already held, so the page keeps exactly one <header> (the kit's
|
|
996
|
+
one-header-main-h1 floor) and the way back is where the way in was. The bar
|
|
997
|
+
stops catching the pointer; only its button does. */
|
|
998
|
+
html[data-fullscreen="on"] .app-sidebar,
|
|
999
|
+
html[data-fullscreen="on"] .app-scrim,
|
|
1000
|
+
html[data-fullscreen="on"] .app-foot { display: none; }
|
|
1001
|
+
html[data-fullscreen="on"] .app-body { margin-left: 0; }
|
|
1002
|
+
html[data-fullscreen="on"] .app-topbar {
|
|
1003
|
+
position: fixed;
|
|
1004
|
+
top: 12px;
|
|
1005
|
+
right: 12px;
|
|
1006
|
+
left: auto;
|
|
1007
|
+
height: auto;
|
|
1008
|
+
padding: 0;
|
|
1009
|
+
gap: 0;
|
|
1010
|
+
background: none;
|
|
1011
|
+
border: 0;
|
|
1012
|
+
backdrop-filter: none;
|
|
1013
|
+
-webkit-backdrop-filter: none;
|
|
1014
|
+
pointer-events: none;
|
|
1015
|
+
}
|
|
1016
|
+
html[data-fullscreen="on"] .app-topbar > :not(.topbar-side),
|
|
1017
|
+
html[data-fullscreen="on"] .topbar-side > :not(.fullscreen-toggle) { display: none; }
|
|
1018
|
+
html[data-fullscreen="on"] .fullscreen-toggle {
|
|
1019
|
+
pointer-events: auto;
|
|
1020
|
+
width: 36px; height: 36px;
|
|
1021
|
+
color: var(--ink);
|
|
1022
|
+
background: var(--glass);
|
|
1023
|
+
box-shadow: inset 0 0 0 1px var(--glass-edge);
|
|
1024
|
+
backdrop-filter: blur(var(--glass-blur));
|
|
1025
|
+
-webkit-backdrop-filter: blur(var(--glass-blur));
|
|
1026
|
+
}
|
|
974
1027
|
.zoom-toggle__pct {
|
|
975
1028
|
font-size: 12px;
|
|
976
1029
|
font-weight: 500;
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
|
|
58
58
|
<!-- The app shell (sidebar + top bar + footer). Dependency-free; runs at parse
|
|
59
59
|
time so the chrome exists before the deferred page scripts execute. -->
|
|
60
|
-
<script src="/builders/shell.js?v=2026-09-
|
|
60
|
+
<script src="/builders/shell.js?v=2026-09-27-fullscreen"></script>
|
|
61
61
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
62
62
|
<script src="/builders/palette.js" defer></script>
|
|
63
63
|
<!-- shared frontend toolkit (window.OTB) — loaded FIRST so task.js can pull from it. -->
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/* modules/hall-ui/public/thinking.css — THE SKY's one sheet (task 1004231 / sky
|
|
2
2
|
part 3 of 5, goal 1000095; ADR 0331). The <style> of
|
|
3
3
|
docs/design/mocks/sky/sky.template.html, verbatim: the owner adopted the
|
|
4
|
-
prototype as the design of record and this sheet is its pixel contract.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
template's values are the contract. Keep it one file (the task says so).
|
|
4
|
+
prototype as the design of record and this sheet is its pixel contract. The
|
|
5
|
+
sky is its own surface (black void, Manrope, JetBrains Mono for figures),
|
|
6
|
+
and the template's values are the contract. Keep it one file (the task says so).
|
|
8
7
|
ONE SHEET, TWO DOORS (part 4, task 1004232): /thinking and /goal-map are the
|
|
9
|
-
same page opened in different lenses, so both
|
|
10
|
-
|
|
8
|
+
same page opened in different lenses, so both are named below.
|
|
9
|
+
IN THE HALL (task 1004327): /thinking now loads style.css and sits in the
|
|
10
|
+
hall chrome; /goal-map is still standalone. So the sky's tokens and ground
|
|
11
|
+
sit on /thinking's STAGE (main.sky-stage) instead of its body — the chrome
|
|
12
|
+
around the stage keeps the hall's own palette in both modes — and the sky's
|
|
13
|
+
few global rules are written :where()-scoped, so they cost no specificity
|
|
14
|
+
(goal-map renders exactly as before) and never reach the chrome. */
|
|
11
15
|
/* The template declared these on :root. They sit on the page's body here,
|
|
12
16
|
with the template's values untouched, because the server splices the
|
|
13
17
|
branding pack's own :root (--ink, --accent, --rule …) into <head> AFTER this
|
|
@@ -17,7 +21,7 @@
|
|
|
17
21
|
its own — tests/hall_reading_world.mjs; color-scheme inherits from body
|
|
18
22
|
too). Same reason `body` below is qualified: a pack backdrop is written as
|
|
19
23
|
`body{background:…}` and the void must win. */
|
|
20
|
-
body[data-page="
|
|
24
|
+
body[data-page="goal-map"], body[data-page="thinking"] .sky-stage {
|
|
21
25
|
color-scheme: dark;
|
|
22
26
|
--void: #000000; --ink: #ffffff; --ink-soft: #c0c0c0; --ink-faint: #a8a8a8; --ink-dim: #65656a; --ink-ghost: #3a3a3f;
|
|
23
27
|
--rule: rgba(255,255,255,.16); --rule-soft: rgba(255,255,255,.08); --glass: rgba(255,255,255,.075); --glass-strong: rgba(255,255,255,.14);
|
|
@@ -26,12 +30,46 @@ body[data-page="thinking"], body[data-page="goal-map"] {
|
|
|
26
30
|
--face: Manrope, "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
27
31
|
}
|
|
28
32
|
html, body { height: 100%; }
|
|
29
|
-
body[data-page="
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.
|
|
33
|
+
body[data-page="goal-map"], body[data-page="thinking"] .sky-stage { margin: 0; background: var(--void); color: var(--ink); font-family: var(--face); font-size: 15px; line-height: 1.5; overflow: hidden; -webkit-font-smoothing: antialiased; }
|
|
34
|
+
body[data-page="thinking"] { overflow: hidden; }
|
|
35
|
+
:where(body[data-page="goal-map"], .sky-stage) button { font-family: inherit; }
|
|
36
|
+
:where(body[data-page="goal-map"], .sky-stage) a { color: var(--accent); }
|
|
37
|
+
:where(body[data-page="goal-map"], .sky-stage) .lbl { font: var(--label); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint); }
|
|
38
|
+
:where(body[data-page="goal-map"], .sky-stage) .mono { font: var(--mono); font-variant-numeric: tabular-nums; }
|
|
34
39
|
[hidden] { display: none !important; }
|
|
40
|
+
|
|
41
|
+
/* THE STAGE (task 1004327). The box under the hall's top bar and beside its
|
|
42
|
+
64px rail — the drawer's phone width has no rail — and, in full screen
|
|
43
|
+
(html[data-fullscreen="on"], shell.js), the whole window. `contain: layout
|
|
44
|
+
paint` makes it the containing block of every position: fixed layer inside
|
|
45
|
+
it, so the template's fixed layout below measures from the stage and needs
|
|
46
|
+
no second copy; sky-layout.js sizes the canvas to the same box. The
|
|
47
|
+
template's four viewport units (100vw, 46vh) became percentages for the
|
|
48
|
+
same reason: a fixed layer's % is its containing block — the stage here,
|
|
49
|
+
the window on /goal-map, where the two are the same number. */
|
|
50
|
+
.sky-stage { position: fixed; top: var(--topbar-h, 56px); left: var(--sidebar-w-rail, 64px); right: 0; bottom: 0; max-width: none; margin: 0; contain: layout paint; }
|
|
51
|
+
html[data-fullscreen="on"] .sky-stage { top: 0; left: 0; }
|
|
52
|
+
@media (max-width: 768px) { .sky-stage { left: 0; } }
|
|
53
|
+
/* The full-screen switch floats top right over the stage, where the sky's
|
|
54
|
+
tools end; the strip steps in by the button's width so nothing sits under it. */
|
|
55
|
+
html[data-fullscreen="on"] .sky-stage .top { padding-right: 64px; }
|
|
56
|
+
/* Under 900 the brand takes a row of its own (the template's rule below), so
|
|
57
|
+
only that row steps in and the tools keep their width. */
|
|
58
|
+
@media (max-width: 900px) {
|
|
59
|
+
html[data-fullscreen="on"] .sky-stage .top { padding-right: 16px; }
|
|
60
|
+
html[data-fullscreen="on"] .sky-stage .brand { padding-right: 48px; }
|
|
61
|
+
}
|
|
62
|
+
/* style.css rules whose names the template also uses — each one reset to what
|
|
63
|
+
the template's page had, at the SAME specificity and earlier than the sky's
|
|
64
|
+
own rules below, so the sky's declarations still win. */
|
|
65
|
+
:where(.sky-stage) * { box-sizing: revert; }
|
|
66
|
+
:where(.sky-stage) a { text-decoration: revert; }
|
|
67
|
+
:where(.sky-stage) .skip { position: static; left: auto; top: auto; z-index: auto; }
|
|
68
|
+
:where(.sky-stage) .filters { align-items: normal; margin: 0; }
|
|
69
|
+
:where(.sky-stage) .foot { margin: 0; border: 0; font-size: inherit; }
|
|
70
|
+
:where(.sky-stage) :focus-visible { outline: revert; outline-offset: revert; box-shadow: revert; border-radius: revert; }
|
|
71
|
+
:where(.sky-stage) input[type="text"], :where(.sky-stage) input[type="search"] { min-height: 0; padding: 1px 2px; border-radius: 0; }
|
|
72
|
+
:where(.sky-stage) a:hover { text-decoration: revert; }
|
|
35
73
|
#sky { position: fixed; inset: 0; display: block; width: 100%; height: 100%; cursor: grab; touch-action: none; }
|
|
36
74
|
#sky.dragging { cursor: grabbing; }
|
|
37
75
|
#sky:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
@@ -55,7 +93,7 @@ a { color: var(--accent); }
|
|
|
55
93
|
.pill.icon::before { display: none; }
|
|
56
94
|
.spot { outline: 2px solid var(--accent) !important; outline-offset: 4px; box-shadow: 0 0 0 8px rgba(251,149,105,.12), 0 0 40px rgba(251,149,105,.35); }
|
|
57
95
|
|
|
58
|
-
.composer { position: fixed; left: 50%; top: calc(76px + env(safe-area-inset-top, 0px)); transform: translateX(-50%); width: min(620px, calc(
|
|
96
|
+
.composer { position: fixed; left: 50%; top: calc(76px + env(safe-area-inset-top, 0px)); transform: translateX(-50%); width: min(620px, calc(100% - 32px)); z-index: 6; display: flex; flex-direction: column; gap: 8px; align-items: center; }
|
|
59
97
|
.composer form { display: flex; width: 100%; height: 48px; border-radius: 999px; background: rgba(0,0,0,.5); box-shadow: inset 0 0 0 1px var(--rule); backdrop-filter: blur(6px); align-items: center; padding: 0 6px 0 22px; gap: 8px; }
|
|
60
98
|
.composer form:focus-within { box-shadow: inset 0 0 0 1px var(--ink-faint); }
|
|
61
99
|
.composer input { flex: 1; min-width: 0; height: 100%; background: transparent; border: 0; color: var(--ink); font: 300 17px/1 var(--face); letter-spacing: -.01em; outline: none; }
|
|
@@ -135,7 +173,7 @@ a { color: var(--accent); }
|
|
|
135
173
|
.jump li button:hover, .jump li button:focus-visible { background: var(--glass); color: var(--ink); }
|
|
136
174
|
.jump li .lbl { flex-shrink: 0; width: 60px; }
|
|
137
175
|
|
|
138
|
-
.tour, .start { position: fixed; left: 50%; bottom: calc(110px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%); width: min(560px, calc(
|
|
176
|
+
.tour, .start { position: fixed; left: 50%; bottom: calc(110px + env(safe-area-inset-bottom, 0px)); transform: translateX(-50%); width: min(560px, calc(100% - 32px)); z-index: 8; padding: 18px 22px 16px; border-radius: 16px; display: flex; flex-direction: column; gap: 10px; }
|
|
139
177
|
.tour .step { display: flex; align-items: center; gap: 10px; }
|
|
140
178
|
.tour .dots { display: flex; gap: 5px; margin-left: auto; }
|
|
141
179
|
.tour .dots i { width: 5px; height: 5px; border-radius: 50%; background: rgba(255,255,255,.2); }
|
|
@@ -203,12 +241,12 @@ a { color: var(--accent); }
|
|
|
203
241
|
.lens button, .pill { height: 32px; padding: 0 12px; font-size: 12px; }
|
|
204
242
|
.pill.icon { width: 32px; }
|
|
205
243
|
.tools { margin-left: auto; }
|
|
206
|
-
.composer { top: calc(186px + env(safe-area-inset-top, 0px)); width: calc(
|
|
244
|
+
.composer { top: calc(186px + env(safe-area-inset-top, 0px)); width: calc(100% - 32px); }
|
|
207
245
|
.composer form { height: 44px; padding-left: 16px; }
|
|
208
246
|
.composer input { font-size: 16px; }
|
|
209
247
|
.gravity { font-size: 11.5px; }
|
|
210
248
|
.jump, .legend, .time { display: none; }
|
|
211
|
-
.room, .panel { left: 10px; right: 10px; width: auto; top: auto; bottom: calc(70px + env(safe-area-inset-bottom, 0px)); max-height:
|
|
249
|
+
.room, .panel { left: 10px; right: 10px; width: auto; top: auto; bottom: calc(70px + env(safe-area-inset-bottom, 0px)); max-height: 46%; }
|
|
212
250
|
.alt { margin-left: 0; text-align: left; }
|
|
213
251
|
.tour, .start { bottom: calc(80px + env(safe-area-inset-bottom, 0px)); }
|
|
214
252
|
.card { max-width: 240px; }
|
|
@@ -12,6 +12,7 @@
|
|
|
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
14
|
The template carried its own Google Fonts link for the same two faces. -->
|
|
15
|
+
<link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
|
|
15
16
|
<link rel="stylesheet" href="/builders/thinking.css?v=2026-09-25-sky4">
|
|
16
17
|
</head>
|
|
17
18
|
<!-- THE SKY (task 1004231 / sky part 3 of 5, goal 1000095; ADR 0331, ADR 0227
|
|
@@ -27,36 +28,49 @@
|
|
|
27
28
|
The file is still `thinking` and the URL still /thinking: this is the
|
|
28
29
|
ideator's home, the page that replaced THE ROOM (task 1004098) — and the
|
|
29
30
|
room survives inside it as the list drawer (L). /sky, the old ambient
|
|
30
|
-
page's URL, 301s here (src/bongos/serve-internal.js).
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
page's URL, 301s here (src/bongos/serve-internal.js).
|
|
32
|
+
|
|
33
|
+
IN THE HALL (task 1004327, owner decision 2026-09-27). The sky used to
|
|
34
|
+
carry no hall chrome; it now sits in the sidebar and top bar like every
|
|
35
|
+
hall page, and the shell's full-screen switch (data-fullscreen-switch)
|
|
36
|
+
hides both so the sky fills the window again, remembered for this page.
|
|
37
|
+
The whole sky lives inside <main class="sky-stage">, which is a
|
|
38
|
+
containing block for its position: fixed layers (thinking.css), so the
|
|
39
|
+
template's fixed layout is unchanged and simply measures from the stage
|
|
40
|
+
instead of the window. The sky's heading is a <div class="brand">, not a
|
|
41
|
+
<header>: the shell's top bar is the page's one <header>, and in full
|
|
42
|
+
screen it stays in the document as the way back.
|
|
33
43
|
|
|
34
44
|
The same markup, sheet and scripts serve THE PROJECT SKY at /goal-map
|
|
35
45
|
(part 4, task 1004232): that body says data-sky-lens="all", so the boot
|
|
36
46
|
opens in "the whole project" and the tour hands back to it. The switcher
|
|
37
47
|
is two doors — "the whole project" leaves for /goal-map from here, and
|
|
38
|
-
"simple" / "your thinking" leave for here from there.
|
|
39
|
-
|
|
48
|
+
"simple" / "your thinking" leave for here from there. /goal-map keeps the
|
|
49
|
+
old standalone form: it is not in the hall chrome (yet). -->
|
|
50
|
+
<body data-page="thinking" data-page-title="Your thinking" data-fullscreen-switch>
|
|
51
|
+
|
|
52
|
+
<div class="app">
|
|
53
|
+
<aside class="app-sidebar" id="app-sidebar" aria-label="Primary"></aside>
|
|
54
|
+
<div class="app-scrim" id="app-scrim" hidden></div>
|
|
55
|
+
<div class="app-body">
|
|
56
|
+
<header class="app-topbar" id="app-topbar"></header>
|
|
40
57
|
|
|
41
58
|
<!-- The one <main> landmark the kit's a11y floor asks of every hall page
|
|
42
|
-
(one-header-main-h1).
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
<main>
|
|
59
|
+
(one-header-main-h1). In the hall (task 1004327) it is the STAGE: the box
|
|
60
|
+
under the top bar and beside the rail that the whole sky is drawn in, and
|
|
61
|
+
the containing block every fixed layer below measures from. -->
|
|
62
|
+
<main id="hall-main" class="sky-stage">
|
|
46
63
|
<canvas id="sky" tabindex="0" role="img" aria-label="The sky, drawn from the ledger. Every thought and goal here is also a row in the list; press L to open it, ? to take the tour."></canvas>
|
|
47
|
-
</main>
|
|
48
64
|
|
|
49
|
-
<!-- The template wrote the whole top strip as the <header
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
same .top strip. No selector names the element, so the render is the
|
|
54
|
-
template's, pixel for pixel. -->
|
|
65
|
+
<!-- The template wrote the whole top strip as the <header>; the sky's first
|
|
66
|
+
build made only the BRAND the header (the kit's top-bar-80px floor). In
|
|
67
|
+
the hall the shell's top bar is the page's header, so the brand is a
|
|
68
|
+
<div> — no selector names the element, so the render is unchanged. -->
|
|
55
69
|
<div class="top">
|
|
56
|
-
<
|
|
70
|
+
<div class="brand">
|
|
57
71
|
<h1>your sky <em id="lensWord">— your thinking</em></h1>
|
|
58
72
|
<div class="stats" id="stats"></div>
|
|
59
|
-
</
|
|
73
|
+
</div>
|
|
60
74
|
<div class="lens" role="group" aria-label="Filter" id="lensGroup">
|
|
61
75
|
<button type="button" id="lensSimple" aria-pressed="false">simple</button>
|
|
62
76
|
<button type="button" id="lensMine" aria-pressed="true">your thinking</button>
|
|
@@ -129,6 +143,12 @@
|
|
|
129
143
|
<div class="alt" id="alt"></div>
|
|
130
144
|
</div>
|
|
131
145
|
</footer>
|
|
146
|
+
</main>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<script src="/builders/shell.js?v=2026-09-27-fullscreen"></script>
|
|
151
|
+
<script src="/builders/palette.js" defer></script>
|
|
132
152
|
|
|
133
153
|
<script src="/builders/idea-objects.js?v=2026-09-25-sky4"></script>
|
|
134
154
|
<script src="/builders/sky-data.js?v=2026-09-25-sky4"></script>
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_": "THE SKY (task 1004231 / sky part 3 of 5, goal 1000095; ADR 0331) through modules/ui-design/kit/render.js. The page draws GET /sky + GET /sky/mine; against the kit's own stub neither exists, so every state below renders the EMPTY sky — a real state the floors must hold in (the composer, the tour, the list drawer and the lenses all exist with no thought filed). To look at the populated sky, run it against the hall-preview harness, whose sky.json + sky__mine.json fixtures carry the wells and one of each of the five objects:\n\n node scripts/hall-preview/server.js --port 4615 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/thinking.states.json --base-in http://localhost:4615 --base-out http://localhost:4615\n\nThe tour opens by itself on a first visit (sky-tour-seen), so states that want the bare sky skip it first.",
|
|
2
|
+
"_": "THE SKY (task 1004231 / sky part 3 of 5, goal 1000095; ADR 0331) through modules/ui-design/kit/render.js. The page draws GET /sky + GET /sky/mine; against the kit's own stub neither exists, so every state below renders the EMPTY sky — a real state the floors must hold in (the composer, the tour, the list drawer and the lenses all exist with no thought filed). To look at the populated sky, run it against the hall-preview harness, whose sky.json + sky__mine.json fixtures carry the wells and one of each of the five objects:\n\n node scripts/hall-preview/server.js --port 4615 --fixture-me\n node modules/ui-design/kit/render.js --states modules/hall-ui/public/thinking.states.json --base-in http://localhost:4615 --base-out http://localhost:4615\n\nThe tour opens by itself on a first visit (sky-tour-seen), so states that want the bare sky skip it first.\n\nIN THE HALL (task 1004327): the page sits in the hall chrome, so it renders in BOTH modes — the chrome follows the hall theme and the sky's stage stays the void in both. The full-* states press the shell's full-screen switch: the sidebar and the top bar leave, and the one button that brings them back floats top right.",
|
|
3
3
|
"page": "/builders/thinking",
|
|
4
4
|
"surface": "hall-ui",
|
|
5
5
|
"stub": { "prefix": "/builders/" },
|
|
6
|
-
"modes": ["dark"],
|
|
7
6
|
"modeQuery": false,
|
|
8
7
|
"ignoreRequests": ["/api/(gds|bongos)/", "fonts\\.g(oogleapis|static)\\.com"],
|
|
9
8
|
"ignoreConsole": ["/api/(gds|bongos)/", "\\b401\\b", "\\b404\\b", "Unauthorized", "Not Found", "load failed", "fonts\\.g(oogleapis|static)\\.com"],
|
|
@@ -38,6 +37,24 @@
|
|
|
38
37
|
"actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200], ["fill", "#thought", "a thought about the sky"], ["wait", 600]],
|
|
39
38
|
"expect": { "visible": ["#composerWrap", "#gravity"] }
|
|
40
39
|
},
|
|
40
|
+
"full": {
|
|
41
|
+
"auth": true,
|
|
42
|
+
"_": "Full screen: the shell's switch pressed — the sky fills the window, and one button brings the chrome back.",
|
|
43
|
+
"actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200], ["click", "#fullscreen-toggle"], ["wait", 400]],
|
|
44
|
+
"expect": { "visible": ["#sky", "#composerWrap", "#fullscreen-toggle"], "hidden": ["#app-sidebar", "#topbar-title"], "attr": [["#fullscreen-toggle", "aria-pressed", "true"]] }
|
|
45
|
+
},
|
|
46
|
+
"full-list": {
|
|
47
|
+
"auth": true,
|
|
48
|
+
"_": "Full screen with the list drawer open (L).",
|
|
49
|
+
"actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200], ["click", "#fullscreen-toggle"], ["wait", 300], ["press", "l"], ["wait", 300]],
|
|
50
|
+
"expect": { "visible": ["#room", "#fullscreen-toggle"], "hidden": ["#app-sidebar"] }
|
|
51
|
+
},
|
|
52
|
+
"full-back": {
|
|
53
|
+
"auth": true,
|
|
54
|
+
"_": "Escape leaves full screen, and the chrome is back.",
|
|
55
|
+
"actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200], ["click", "#fullscreen-toggle"], ["wait", 300], ["focus", "#sky"], ["press", "Escape"], ["wait", 400]],
|
|
56
|
+
"expect": { "visible": ["#app-sidebar", "#topbar-title"], "attr": [["#fullscreen-toggle", "aria-pressed", "false"]] }
|
|
57
|
+
},
|
|
41
58
|
"out": { "auth": false, "actions": [["wait", 600]] }
|
|
42
59
|
},
|
|
43
60
|
"reducedMotion": { "auth": true, "actions": [["wait", 1200], ["clickIfVisible", "#tourSkip"], ["wait", 200]] }
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
|
|
163
163
|
<!-- The app shell (sidebar + top bar). Dependency-free; loaded FIRST so the
|
|
164
164
|
chrome exists before the page script runs. -->
|
|
165
|
-
<script src="/builders/shell.js?v=2026-09-
|
|
165
|
+
<script src="/builders/shell.js?v=2026-09-27-fullscreen"></script>
|
|
166
166
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
167
167
|
<script src="/builders/palette.js" defer></script>
|
|
168
168
|
<!-- shared frontend toolkit (window.OTB) — loaded before watch.js, which pulls from it. -->
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
|
|
172
172
|
<!-- The app shell (sidebar + top bar + footer). Dependency-free; runs at parse
|
|
173
173
|
time so the chrome exists before the deferred page scripts execute. -->
|
|
174
|
-
<script src="/builders/shell.js?v=2026-09-
|
|
174
|
+
<script src="/builders/shell.js?v=2026-09-27-fullscreen"></script>
|
|
175
175
|
<!-- jump palette (Ctrl/Cmd-K). Optional by design: without it the shell's slot stays hidden. -->
|
|
176
176
|
<script src="/builders/palette.js" defer></script>
|
|
177
177
|
<!-- shared frontend toolkit (window.OTB) — loaded FIRST so work.js can pull from it. -->
|
|
@@ -21,3 +21,12 @@ Pinned by `tests/hall_sky.mjs` (31 cases: the reads, the five objects, the two c
|
|
|
21
21
|
- **THE LEDGER DRAWER IS THE ACCESSIBLE PATH** — the old goal map's table, kept (ADR 0227 §11): `L` opens it; every goal is a row that counts both directions of its dependencies ("waits on N · waited on by N") and the panel names them as doors; the filters are alive / wells / settled / collapsed / with routes. Every drawn thing is a row, one key away — spec decision 11's surviving rule.
|
|
22
22
|
- **ADR 0227 §1's refusal stands.** Tasks resolve onto their rings only inside ONE well past the zoom threshold (dust density on the rings below it), never for every goal at once — at the whole-sky fit no task is a body — and there is no "show every task" control anywhere on the page or in the shuttle menu. `tests/goal_map_page.mjs` pins both, plus the nav slot, the two doors, the wells, alive, the routes, the menu, explore, "my ideas", the ledger, the clock, the bands, the tour and a hostile title.
|
|
23
23
|
- **Same tier, same gates as `/thinking`.** `requireBuilderPage` (the tier the map sat on); no hall chrome (`STANDALONE_EXEMPT` in `tests/hall_audit.mjs`); `goal-map.states.json` renders the EMPTY sky against the kit stub like `thinking.states.json`, and the populated sky against the harness (`sky.json` + `sky__mine.json`). `goal-forest-*` (the per-goal forest on the goal detail page) is untouched.
|
|
24
|
+
|
|
25
|
+
## In the hall, with a full-screen switch (task 1004327, BV2.TW20)
|
|
26
|
+
|
|
27
|
+
**Owner decision 2026-09-27: `/thinking` and the studio sit in the hall chrome, and each has one switch that hides it.** `/goal-map` keeps its standalone form (TW21 reshapes it next). What this settled:
|
|
28
|
+
- **The switch is the shell's, not a page's.** A page opts in with `<body data-fullscreen-switch>`; `shell.js` renders `#fullscreen-toggle` as the LAST top-bar control and keeps the state on `html[data-fullscreen="on"]` (the `data-theme` / `data-social` pattern). It is remembered PER PAGE (`hall-fullscreen:<data-page>` in localStorage, try/catch), and Escape leaves — unless the page used that press (it calls `preventDefault`: the sky's tour, menu and pick do) or the focus is in a text field. `tests/hall_fullscreen.mjs` boots the real shell and drives click, reload and Escape.
|
|
29
|
+
- **Full screen collapses the top bar, it does not remove it.** The sidebar, scrim and foot go; the top bar shrinks to its one button, floating top right where it already sat. That keeps exactly one shown `<header>` in both states (the kit's one-header-main-h1 floor) — which is also why the sky's brand and the studio's head are `<div>`s now.
|
|
30
|
+
- **The sky is drawn on a STAGE.** Everything the sky owns lives in `main.sky-stage`, fixed under the top bar and beside the 64px rail (the whole window in full screen, no rail under 768). `contain: layout paint` makes the stage the containing block of every fixed layer, so the template's fixed layout is untouched and simply measures from the stage; its four viewport units became `%` of that box (the same number on `/goal-map`). `SKY.viewport()` gives the canvas its size and the pointer its offset (`S.OX` / `S.OY`), and a `ResizeObserver` re-measures when the switch changes the box without the window resizing.
|
|
31
|
+
- **The sky's palette lives on the stage, not the body, on `/thinking`** — so the chrome around it keeps the hall's own light and dark. `style.css` now loads under `thinking.css`, and the handful of hall rules whose names the template also uses (`.skip`, `.filters`, `.foot`, `:focus-visible`, text inputs, `* { box-sizing }`) are reset under `:where(.sky-stage)` at the same specificity, before the sky's own rules. The sky's global rules are `:where()`-scoped for the same reason, which leaves `/goal-map` byte-for-byte in its old cascade.
|
|
32
|
+
- **Both pages render in both modes now.** The chrome follows the hall theme; the sky's stage is the void in both. The `full` and `full-back` states in both states files (and `full-list` in the sky's) press the switch.
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.1052",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.1052",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.1052",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
package/release-notes.json
CHANGED
|
@@ -7607,5 +7607,11 @@
|
|
|
7607
7607
|
"id": "1004312",
|
|
7608
7608
|
"text": "Tweak Mode is planned and queued. An artist will take a whole page of the site from one calm studio, rewrite every word of it as a document (or offline in Word, uploaded back), and approve the finished page before it goes live"
|
|
7609
7609
|
}
|
|
7610
|
+
],
|
|
7611
|
+
"1.19.1052": [
|
|
7612
|
+
{
|
|
7613
|
+
"id": "1004327",
|
|
7614
|
+
"text": "The studio and Your thinking now sit inside the builders hall like every other page, with the sidebar and the top bar around them. Each has one new button in the top-right corner that goes full screen: the sidebar and top bar"
|
|
7615
|
+
}
|
|
7610
7616
|
]
|
|
7611
7617
|
}
|
package/src/module-api.js
CHANGED
|
@@ -71,7 +71,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
|
|
|
71
71
|
// there. scripts/gds/bump-version.js still rewrites the literal below; it appends
|
|
72
72
|
// the entry to that file. Look for a version's history there, not here.
|
|
73
73
|
// ---------------------------------------------------------------------------
|
|
74
|
-
const CORE_VERSION = '1.19.
|
|
74
|
+
const CORE_VERSION = '1.19.1052'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
75
75
|
|
|
76
76
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
77
77
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
package/tests/goal_map_page.mjs
CHANGED
|
@@ -401,12 +401,14 @@ await test('the page is the sky\'s own surface — the same sheet and the same s
|
|
|
401
401
|
assert.match(html, /<body data-page="goal-map" data-page-title="The sky" data-sky-lens="all">/);
|
|
402
402
|
assert.match(html, /<title>The sky — \{\{worldName\}\}<\/title>/);
|
|
403
403
|
assert.match(html, /<h1>the sky <em id="lensWord">— the whole project<\/em><\/h1>/, 'the h1 is in static markup, so every state has one');
|
|
404
|
-
assert.equal(/shell\.js|style\.css/.test(html), false, 'no hall chrome
|
|
404
|
+
assert.equal(/shell\.js|style\.css/.test(html), false, 'no hall chrome yet — /thinking joined it (task 1004327), the project sky did not');
|
|
405
405
|
const scripts = (h) => [...h.matchAll(/<script src="\/builders\/([^"?]+)\?v=([^"]+)"/g)].map((m) => [m[1], m[2]]);
|
|
406
406
|
assert.deepEqual(scripts(html).map((s) => s[0]), ['idea-objects.js', 'sky-data.js', 'sky-layout.js', 'sky-draw.js', 'sky-interaction.js', 'sky-panel.js', 'sky-composer.js', 'sky-tour.js']);
|
|
407
|
-
|
|
407
|
+
// /thinking also loads the shell (task 1004327); the SKY's files are the same.
|
|
408
|
+
const skyScripts = (h) => scripts(h).filter((s) => s[0] !== 'shell.js');
|
|
409
|
+
assert.deepEqual(skyScripts(html), skyScripts(thinking), 'the two doors load the same sky files at the same stamp');
|
|
408
410
|
assert.equal(html.match(/thinking\.css\?v=([^"]+)/)[1], thinking.match(/thinking\.css\?v=([^"]+)/)[1]);
|
|
409
|
-
assert.match(read('thinking.css'), /body\[data-page="
|
|
411
|
+
assert.match(read('thinking.css'), /body\[data-page="goal-map"\], body\[data-page="thinking"\] \.sky-stage \{/, 'the sheet names both doors: the project sky\'s body, and the stage /thinking draws in inside the hall');
|
|
410
412
|
for (const f of ['goal-map.css', 'goal-map.js', 'goal-map-lib.js']) assert.equal(fs.existsSync(path.join(HALL, f)), false, `${f} is retired`);
|
|
411
413
|
assert.equal(fs.existsSync(path.join(ROOT, 'tests/goal_map_lib.mjs')), false, 'and so is the lib\'s test');
|
|
412
414
|
assert.equal(/goal-map-lib|goal-map\.js|goal-map\.css/.test(html), false);
|
package/tests/hall_audit.mjs
CHANGED
|
@@ -362,8 +362,9 @@ test('the module doc still records where the 2179 density pass landed', () => {
|
|
|
362
362
|
// private copy of the hall's, it is a different surface's own, pinned by
|
|
363
363
|
// tests/hall_sky.mjs against the template. It still stamps the branding token
|
|
364
364
|
// and the pack's font links like every hall page (the server injects them).
|
|
365
|
+
// /thinking left this list in task 1004327 (owner decision 2026-09-27): it sits
|
|
366
|
+
// in the hall chrome now, with the shell's full-screen switch to hide it.
|
|
365
367
|
const STANDALONE_EXEMPT = {
|
|
366
|
-
'thinking.html': 'the sky (task 1004231, ADR 0331) — the design of record is its own surface, not the hall chrome',
|
|
367
368
|
'goal-map.html': 'the project sky (task 1004232) — the same surface as thinking.html, opened in its whole-project lens',
|
|
368
369
|
};
|
|
369
370
|
|