@bongos/core 1.24.32 → 1.24.33
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 +16 -16
- package/docs/copy-inventory.md +7 -7
- package/docs/copy-registry.json +7 -7
- package/docs/module-api-changelog.md +2 -0
- package/docs/page-readings.json +211 -211
- package/modules/hall-ui/public/craft-mode.js +14 -5
- package/modules/hall-ui/public/style.css +23 -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/craft_mode_looks.mjs +16 -6
|
@@ -216,20 +216,29 @@
|
|
|
216
216
|
// under the brand (artHtml, the picker's own art, so the two never drift).
|
|
217
217
|
// Building and no mode have no entry here and wear nothing.
|
|
218
218
|
var LOOKS = { artistry: 'the studio · night', ideating: 'the sky', governing: 'the city' };
|
|
219
|
+
// The plate is the Home button in every mode (owner, 2026-11-04, task 1005065): the
|
|
220
|
+
// mode's scene with a home mark over it. Building wears no look, so its plate shows
|
|
221
|
+
// the city, the scene its Home is.
|
|
222
|
+
var PLATE_ART = { building: 'governing', artistry: 'artistry', ideating: 'ideating', governing: 'governing' };
|
|
223
|
+
var HOME_MARK = '<span class="craft-plate__home" aria-hidden="true"><svg viewBox="0 0 18 18" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linejoin="round">' +
|
|
224
|
+
'<path d="M3 8.5 9 3l6 5.5V15a1 1 0 0 1-1 1h-3.5v-4h-3v4H4a1 1 0 0 1-1-1V8.5Z"/></svg></span>';
|
|
219
225
|
function remove(el) { if (el && el.parentNode) el.parentNode.removeChild(el); }
|
|
220
226
|
function applyLook(mode) {
|
|
221
227
|
var look = Object.prototype.hasOwnProperty.call(LOOKS, mode) ? LOOKS[mode] : null;
|
|
228
|
+
var art = Object.prototype.hasOwnProperty.call(PLATE_ART, mode) ? PLATE_ART[mode] : null;
|
|
222
229
|
var plate = document.getElementById('craft-plate');
|
|
223
|
-
if (plate && plate.getAttribute('data-plate') !== (
|
|
230
|
+
if (plate && plate.getAttribute('data-plate') !== (art ? mode : null)) { remove(plate); plate = null; }
|
|
224
231
|
var nav = document.getElementById('app-sidebar');
|
|
225
|
-
var brand =
|
|
232
|
+
var brand = art && nav && nav.querySelector ? nav.querySelector('.app-sidebar__brand') : null;
|
|
226
233
|
if (!plate && brand && brand.parentNode) {
|
|
227
|
-
plate = document.createElement('
|
|
234
|
+
plate = document.createElement('a');
|
|
228
235
|
plate.id = 'craft-plate';
|
|
229
236
|
plate.className = 'craft-plate';
|
|
237
|
+
plate.setAttribute('href', '/');
|
|
238
|
+
plate.setAttribute('aria-label', 'Home');
|
|
239
|
+
plate.setAttribute('title', 'Home');
|
|
230
240
|
plate.setAttribute('data-plate', mode);
|
|
231
|
-
plate.
|
|
232
|
-
plate.innerHTML = artHtml(mode);
|
|
241
|
+
plate.innerHTML = artHtml(art) + HOME_MARK;
|
|
233
242
|
brand.parentNode.insertBefore(plate, brand.nextSibling);
|
|
234
243
|
}
|
|
235
244
|
var mark = document.getElementById('craft-eyebrow');
|
|
@@ -1614,6 +1614,9 @@ html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing
|
|
|
1614
1614
|
never redrawn: each scene's pieces are placed from its edges or its centre. */
|
|
1615
1615
|
.craft-plate {
|
|
1616
1616
|
position: relative;
|
|
1617
|
+
display: block;
|
|
1618
|
+
color: inherit;
|
|
1619
|
+
text-decoration: none;
|
|
1617
1620
|
height: 40px;
|
|
1618
1621
|
margin: 10px 8px 0;
|
|
1619
1622
|
border-radius: var(--radius-sm);
|
|
@@ -1631,6 +1634,26 @@ html:is([data-craft="artistry"], [data-craft="ideating"], [data-craft="governing
|
|
|
1631
1634
|
transform-origin: 0 0;
|
|
1632
1635
|
}
|
|
1633
1636
|
.craft-plate .craft-art__city { top: 0; }
|
|
1637
|
+
/* At the plate's size the studio's houses vanished into the night (owner, 2026-11-04):
|
|
1638
|
+
lift them off the sky so the scene reads. The picker's larger door is unchanged. */
|
|
1639
|
+
.craft-plate .craft-art__house { background: #232b4d; }
|
|
1640
|
+
/* The plate is the Home button (task 1005065): a home mark sits over the scene. */
|
|
1641
|
+
.craft-plate__home {
|
|
1642
|
+
position: absolute;
|
|
1643
|
+
left: 50%;
|
|
1644
|
+
top: 50%;
|
|
1645
|
+
width: 24px;
|
|
1646
|
+
height: 24px;
|
|
1647
|
+
margin: -12px 0 0 -12px;
|
|
1648
|
+
display: grid;
|
|
1649
|
+
place-items: center;
|
|
1650
|
+
border-radius: 999px;
|
|
1651
|
+
color: #fff;
|
|
1652
|
+
background: var(--scrim);
|
|
1653
|
+
}
|
|
1654
|
+
.craft-plate__home svg { width: 14px; height: 14px; }
|
|
1655
|
+
.craft-plate:hover .craft-plate__home { background: rgba(0, 0, 0, .8); }
|
|
1656
|
+
.craft-plate:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
|
|
1634
1657
|
.app-sidebar:hover .craft-plate,
|
|
1635
1658
|
.app-sidebar:focus-within .craft-plate { height: 64px; margin: 10px 16px 0; }
|
|
1636
1659
|
.app-sidebar:hover .craft-plate .craft-art,
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.33",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.24.
|
|
9
|
+
"version": "1.24.33",
|
|
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.24.
|
|
3
|
+
"version": "1.24.33",
|
|
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
|
@@ -11151,5 +11151,11 @@
|
|
|
11151
11151
|
"id": "1005064",
|
|
11152
11152
|
"text": "The governor's Home is now the street: choosing Owner on Home takes you straight to it, so each of the four crafts has its own Home."
|
|
11153
11153
|
}
|
|
11154
|
+
],
|
|
11155
|
+
"1.24.33": [
|
|
11156
|
+
{
|
|
11157
|
+
"id": "1005065",
|
|
11158
|
+
"text": "The small picture at the top of the sidebar is now the Home button in every mode, with a home icon on it."
|
|
11159
|
+
}
|
|
11154
11160
|
]
|
|
11155
11161
|
}
|
package/src/module-api.js
CHANGED
|
@@ -81,7 +81,7 @@ const { sleep } = require('./sleep');
|
|
|
81
81
|
// MAJOR (see allowBoxScope below): passes the request through untouched.
|
|
82
82
|
function deprecatedNoopMiddleware(_req, _res, next) { next(); }
|
|
83
83
|
|
|
84
|
-
const CORE_VERSION = '1.24.
|
|
84
|
+
const CORE_VERSION = '1.24.33'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
85
85
|
|
|
86
86
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
87
87
|
// Usage: const log = api.logger('discord'); log.info('mounted');
|
|
@@ -86,25 +86,33 @@ test('each looked mode frames its own door scene under the brand, and names itse
|
|
|
86
86
|
const plate = p.plates()[0];
|
|
87
87
|
assert.equal(p.brand.nextSibling, plate, `${m}: the plate sits right under the brand`);
|
|
88
88
|
assert.equal(plate.getAttribute('data-plate'), m);
|
|
89
|
-
assert.equal(plate.
|
|
90
|
-
assert.equal(plate.
|
|
89
|
+
assert.equal(plate.tagName, 'A', `${m}: the plate is a link`);
|
|
90
|
+
assert.equal(plate.getAttribute('href'), '/', `${m}: the plate goes Home`);
|
|
91
|
+
assert.equal(plate.getAttribute('aria-label'), 'Home', `${m}: named Home for a screen reader`);
|
|
92
|
+
assert.ok(plate.innerHTML.startsWith(p.craft.artHtml(m)), `${m}: the plate IS the picker's door art, not a second copy`);
|
|
93
|
+
assert.match(plate.innerHTML, /class="craft-plate__home" aria-hidden="true"/, `${m}: a home mark sits over the scene`);
|
|
91
94
|
assert.equal(p.marks().length, 1, `${m}: exactly one eyebrow`);
|
|
92
95
|
assert.equal(p.title.nextSibling, p.marks()[0], `${m}: the eyebrow sits right after the page title`);
|
|
93
96
|
assert.equal(p.marks()[0].textContent, WORDS[m], `${m}: in the prototype's own words`);
|
|
94
97
|
}
|
|
95
98
|
});
|
|
96
99
|
|
|
97
|
-
test('BUILDING AND NO MODE WEAR NO LOOK: no
|
|
100
|
+
test('BUILDING AND NO MODE WEAR NO LOOK: no eyebrow; Building keeps only the Home plate, showing the city', () => {
|
|
98
101
|
const none = boot();
|
|
99
102
|
assert.equal(none.root.dataset.craft, undefined);
|
|
100
103
|
assert.equal(none.plates().length + none.marks().length, 0, 'no mode draws nothing');
|
|
101
104
|
for (const m of ['building']) {
|
|
102
105
|
const p = boot({ 'hall-craft': m });
|
|
103
|
-
assert.equal(p.
|
|
106
|
+
assert.equal(p.marks().length, 0, `${m} at boot names no look`);
|
|
107
|
+
assert.equal(p.plates().length, 1, `${m}: the Home plate is there too (task 1005065)`);
|
|
108
|
+
assert.equal(p.plates()[0].getAttribute('data-plate'), m);
|
|
109
|
+
assert.ok(p.plates()[0].innerHTML.startsWith(p.craft.artHtml('governing')), `${m}: its plate shows the city`);
|
|
104
110
|
p.craft.choose('governing');
|
|
105
111
|
assert.equal(p.plates().length, 1);
|
|
112
|
+
assert.equal(p.plates()[0].getAttribute('data-plate'), 'governing', 'switching mode swaps the plate');
|
|
106
113
|
p.craft.choose(m);
|
|
107
|
-
assert.equal(p.
|
|
114
|
+
assert.equal(p.marks().length, 0, `switching to ${m} removes the eyebrow`);
|
|
115
|
+
assert.equal(p.plates()[0].getAttribute('data-plate'), m, 'and swaps the plate back');
|
|
108
116
|
}
|
|
109
117
|
assert.deepEqual(Object.keys(none.craft.LOOKS).sort(), [...LOOKED].sort(), 'only the three crafts have a look');
|
|
110
118
|
});
|
|
@@ -112,7 +120,7 @@ test('BUILDING AND NO MODE WEAR NO LOOK: no plate, no eyebrow, and switching to
|
|
|
112
120
|
test('the art is drawn once: craft-mode.js has one artHtml and exports it', () => {
|
|
113
121
|
assert.equal(CRAFT.match(/function artHtml\(/g).length, 1);
|
|
114
122
|
assert.match(CRAFT, /artHtml: artHtml,/);
|
|
115
|
-
assert.match(CRAFT, /plate\.innerHTML = artHtml\(
|
|
123
|
+
assert.match(CRAFT, /plate\.innerHTML = artHtml\(art\) \+ HOME_MARK;/);
|
|
116
124
|
});
|
|
117
125
|
|
|
118
126
|
// Every selector in style.css that names a craft mode.
|
|
@@ -163,6 +171,8 @@ test('the shared treatment, the eyebrow and the plate are written as the directi
|
|
|
163
171
|
}
|
|
164
172
|
assert.match(CSS, /@media \(max-width: 640px\) \{ \.craft-eyebrow \{ display: none; \} \}/, 'the eyebrow is hidden on a phone');
|
|
165
173
|
assert.match(CSS, /\.craft-plate \{[^}]*height: 40px;/, '40px in the closed rail');
|
|
174
|
+
assert.match(CSS, /\.craft-plate__home \{[^}]*width: 24px;[^}]*height: 24px;/, 'the home mark clears the 24px floor');
|
|
175
|
+
assert.match(CSS, /\.craft-plate:focus-visible \{ outline: 2px solid var\(--focus\);/, 'the Home plate shows keyboard focus');
|
|
166
176
|
assert.match(CSS, /\.app-sidebar:focus-within \.craft-plate \{ height: 64px;/, '64px when the rail opens');
|
|
167
177
|
assert.match(CSS, /html\[data-theme="light"\] \.craft-plate \.craft-art__city \{ filter: invert\(1\) hue-rotate\(180deg\); \}/,
|
|
168
178
|
'the light city is the dark one inverted, not a second drawing');
|