@bongos/core 1.19.404 → 1.19.406

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.
@@ -58,6 +58,8 @@ What the pick settles: the settled constraint (dark-first with a real, tested li
58
58
 
59
59
  **2026-08-28: the owner's review of the shipped hero (task 1003333).** Three corrections to the pick, each overriding this record and `DESIGN.md` where they conflicted: the doors sit in the blob's lower half (stage 73% dark / 75% light, from 53 / 60), not at its centre; the three leader-line figures leave the landing (they read as "random lines" there; the poster card on `/projects` keeps the grammar, task 1003301); and the small bead's orbit is replaced by the big plates themselves drifting like a lava lamp (v1's "drift" of §3, built: `drift-form` 74s, `drift-orb` 58s, transform only, dead under reduced motion; the pointer parallax stays out, no motion in JavaScript). The bead left the hero and survives as the third project orb below the fold. The two feeds that fed only the figures (`/public/cost-summary`, `/public/leaderboard`) leave the page with them.
60
60
 
61
+ **2026-08-28, the second note (task 1003334).** Seeing the before/after of task 1003333, the owner found the chrome bongo pair sitting on the top-right sweeping form did not fit ("the random bongos on the blobs background"). Offered three treatments (remove it from the hero; keep it off the blob on plain black or paper; phones only), the owner picked **remove it from the hero**. The pair is no longer a hero object: `.mark`, its arrival and its tokens leave; it stays as the closing figure, the second project orb and the bar's mark. The sweeping form stays as a bare backdrop. Under 900 the masthead is the big blob alone, with the words keeping the 56vw the pair used to hold above them.
62
+
61
63
  ## 7. Shot list: real imagery still owed
62
64
 
63
65
  No version left a placeholder slot: every image on the three pages is a real plate (the round-2 chrome set, the single blob, the two bongo pairs, the two new blob cutouts) or the real Verro Labs medallion, and the proof is the ledger rendered as page content, so no hall or hub capture is used. What the build will still owe:
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.404",
3
+ "version": "1.19.406",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.404",
9
+ "version": "1.19.406",
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.404",
3
+ "version": "1.19.406",
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",
@@ -112,7 +112,6 @@ main:focus{outline:none;box-shadow:none}
112
112
  /* the authored moment: the forms arrive from slightly apart and converge into place */
113
113
  @keyframes arrive-form{from{translate:3.4vw -2.2vh;opacity:.36}to{translate:0 0;opacity:1}}
114
114
  @keyframes arrive-orb{from{translate:-2.8vw 2.4vh;opacity:.36}to{translate:0 0;opacity:1}}
115
- @keyframes arrive-mark{from{translate:2.6vw 1.8vh;opacity:.36}to{translate:0 0;opacity:1}}
116
115
  /* the breath: a 32s swell, and a 40s hue drift so the iridescence keeps moving */
117
116
  @keyframes breathe{0%{scale:1}50%{scale:1.035}100%{scale:1}}
118
117
  @keyframes sheen{0%{filter:var(--sky-shadow) hue-rotate(0deg)}
@@ -124,8 +123,11 @@ main:focus{outline:none;box-shadow:none}
124
123
  the transform property alone, so it composes with the arrival (translate), the breath (scale)
125
124
  and the sheen (filter) instead of fighting them; a translate in percent is a fraction of the
126
125
  plate's own box, and it stays inside 5% with rotation inside 1.5deg, so the type over the plate
127
- keeps its ground. 0% is the graded frame: the rest frame is the composition. The bongo pair
128
- never drifts; a still object is what the moving ground is read against. */
126
+ keeps its ground. 0% is the graded frame: the rest frame is the composition. Only the plates
127
+ move; the type and the doors sit still in their own layer, which is what the moving ground is
128
+ read against. (The chrome bongo pair that sat still on the sweeping form left the hero with the
129
+ owner's second note, task 1003334; it stays as the closing figure, a project orb and the bar's
130
+ mark.) */
129
131
  @keyframes drift-form{
130
132
  0%{transform:translate(0,0) rotate(0deg)}
131
133
  27%{transform:translate(-2.4%,2.6%) rotate(-.9deg)}
@@ -224,12 +226,6 @@ h1 .whole{white-space:normal;margin-left:0}
224
226
  .lede{position:var(--float2);left:var(--lede-x);top:var(--lede-y);width:var(--lede-w);max-width:100%;
225
227
  font-size:18.5px;line-height:1.42;color:var(--ink-soft);text-shadow:var(--type-halo)}
226
228
 
227
- /* the hero object: the three-quarter chrome pair, an alpha cutout with its own contact shadow */
228
- .mark{position:var(--float2);left:var(--mark-x);top:var(--mark-y);width:var(--mark-w);aspect-ratio:1;
229
- background-image:var(--sky-bongos);background-repeat:no-repeat;background-size:100% auto;
230
- filter:var(--sky-shadow);
231
- pointer-events:none;animation:arrive-mark 700ms cubic-bezier(.16,1,.3,1) 210ms both}
232
-
233
229
  /* the two doors, one joined pill, floating in the lower half of the big blob: below its centre so
234
230
  the choice is not the centre of the composition (owner, 2026-08-28; task 1003333). The pair sits
235
231
  in its own layer and never moves with the plate that drifts under it. */
@@ -395,9 +391,6 @@ body{
395
391
  --orb-w:48vw;
396
392
  --orb-x:32vw;
397
393
  --orb-y:calc(var(--vh) * 32);
398
- --mark-w:22vw;
399
- --mark-x:78vw;
400
- --mark-y:calc(var(--vh) * 13);
401
394
  --doors-cx:56vw;
402
395
  --doors-cy:calc(var(--vh) * 75);
403
396
  }
@@ -440,9 +433,6 @@ body{
440
433
  --orb-w:54vw;
441
434
  --orb-x:5vw;
442
435
  --orb-y:calc(var(--vh) * 24);
443
- --mark-w:27vw;
444
- --mark-x:71vw;
445
- --mark-y:calc(var(--vh) * 12);
446
436
  --doors-cx:32vw;
447
437
  --doors-cy:calc(var(--vh) * 73);
448
438
  }
@@ -486,9 +476,6 @@ body{
486
476
  --orb-w:54vw;
487
477
  --orb-x:5vw;
488
478
  --orb-y:calc(var(--vh) * 24);
489
- --mark-w:27vw;
490
- --mark-x:71vw;
491
- --mark-y:calc(var(--vh) * 12);
492
479
  --doors-cx:32vw;
493
480
  --doors-cy:calc(var(--vh) * 73);
494
481
  }
@@ -516,9 +503,10 @@ body{
516
503
  .bandProfile .bandCell,.bandProfile .bandSlot{flex:none;text-align:left}
517
504
  .bandWho{padding-bottom:14px}
518
505
  .hero{min-height:0;padding-bottom:36px}
506
+ /* the masthead is the big blob alone (task 1003334): the words start where they did when the
507
+ bongo pair stood above them, so the blob's crown stays the first thing on a phone */
519
508
  .layer{display:flex;flex-direction:column;align-items:center;text-align:center;
520
- top:0;left:auto;right:auto;bottom:auto;padding-top:12px;pointer-events:auto}
521
- .mark{order:1;margin:0 auto}
509
+ top:0;left:auto;right:auto;bottom:auto;padding-top:calc(12px + 56vw);pointer-events:auto}
522
510
  h1{order:2;margin-top:14px}
523
511
  h1 .l2{margin-left:0}
524
512
  .lede{order:3;margin:16px auto 0}
@@ -559,9 +547,6 @@ body{
559
547
  --orb-w:92vw;
560
548
  --orb-x:4vw;
561
549
  --orb-y:-6vh;
562
- --mark-w:56vw;
563
- --mark-x:0;
564
- --mark-y:0;
565
550
  --doors-cx:0;--doors-cy:0;
566
551
  }
567
552
  :root[data-mode="dark"] body{
@@ -583,9 +568,6 @@ body{
583
568
  --orb-w:150vw;
584
569
  --orb-x:-25vw;
585
570
  --orb-y:22vh;
586
- --mark-w:56vw;
587
- --mark-x:0;
588
- --mark-y:0;
589
571
  --doors-cx:0;--doors-cy:0;
590
572
  }
591
573
  }
@@ -610,9 +592,6 @@ body{
610
592
  --orb-w:150vw;
611
593
  --orb-x:-25vw;
612
594
  --orb-y:22vh;
613
- --mark-w:56vw;
614
- --mark-x:0;
615
- --mark-y:0;
616
595
  --doors-cx:0;--doors-cy:0;
617
596
  }
618
597
  }
@@ -624,12 +603,13 @@ THESIS: the owner's template, built as a working front door. One chrome sculptur
624
603
  first viewport, the headline crosses it in two lines, and the only thing on the big blob is the
625
604
  choice: the two doors, joined, floating in its lower half.
626
605
  FIRST VIEWPORT (1440, dark): the big round blob 54vw at the centre-left, its top crossed by the
627
- h1's second line; the sweeping form across the upper right with the three-quarter chrome bongo pair
628
- sitting on it; the lede top-left under the first line; the joined door pill in the blob's lower
629
- half, below its centre, primary carrying the one warm accent, its ground half black so the
630
- sculpture still reads through it; nothing else is written on the sculpture (the owner's review of
631
- 2026-08-28, task 1003333, took the three leader-line figures off the landing; the poster card on
632
- /projects keeps that grammar); the pipeline rail lives below the fold.
606
+ h1's second line; the sweeping form across the upper right as a bare backdrop; the lede top-left
607
+ under the first line; the joined door pill in the blob's lower half, below its centre, primary
608
+ carrying the one warm accent, its ground half black so the sculpture still reads through it;
609
+ nothing else sits on the sculpture. The owner's review of 2026-08-28 took the three leader-line
610
+ figures off the landing (task 1003333; the poster card on /projects keeps that grammar) and then
611
+ the chrome bongo pair that sat on the sweeping form (task 1003334; it stays as the closing figure,
612
+ the second project orb and the bar's mark). The pipeline rail lives below the fold.
633
613
  STAGE: every vertical token in the hero is a percentage of a FLOORED stage, max(100dvh, 900px),
634
614
  not of the raw viewport. At 900 and taller the frame above is reproduced exactly; a shorter laptop
635
615
  viewport (1536x730, 1440x760) scrolls the last of the hero instead of recomposing it, which is what
@@ -648,13 +628,13 @@ under a slow hue drift (plus or minus 12 degrees, 40s) so the iridescence keeps
648
628
  big plates float like a lava lamp on their own long loops (the sweeping form 74s, the blob 58s;
649
629
  translate inside 5% of each plate's own box, rotation inside 1.5deg, on the transform property
650
630
  alone). The authored moment is the arrival: the forms converge from slightly apart into place in
651
- 700ms. All CSS, all on the plates themselves so the lighten group is never broken; the doors and the
652
- bongo pair sit in their own layer and never move with a plate. The world layer's reduced-motion
631
+ 700ms. All CSS, all on the plates themselves so the lighten group is never broken; the type and the
632
+ doors sit in their own layer and never move with a plate. The world layer's reduced-motion
653
633
  kill switch stops every one of them, and the still frame (every plate at 0%, blob at rest, no hue
654
634
  shift) is the composition.
655
635
  LIGHT ANSWER, "the rebuilt light mode": no black panel anywhere. The same sculpture, cut out with
656
636
  real alpha, sits directly on the pale ground with a soft contact shadow so it reads as objects on
657
- paper. The blob and the bongo pair are whole; the sweeping form is deliberately not, it carries a
637
+ paper. The blob is whole; the sweeping form is deliberately not, it carries a
658
638
  gradient mask that dissolves its left edge and it bleeds off the right of the viewport, which is how
659
639
  a form that wide stays a backdrop and not a fourth object. The type moves off the chrome onto clean
660
640
  paper at the left. The doors keep their place in the blob's lower half on a near opaque pale
@@ -765,9 +745,6 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
765
745
 
766
746
  <p class="lede">AI agents claim tasks and ship the code. You set the direction and the gates.</p>
767
747
 
768
- <div class="mark" role="img"
769
- aria-label="A pair of bongo drums in mirror-polished chrome, seen from three quarters"></div>
770
-
771
748
  <div class="doors">
772
749
  <div class="doorbar">
773
750
  <a class="door" href="/projects">Find a project to join</a>
package/src/module-api.js CHANGED
@@ -1248,8 +1248,12 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
1248
1248
  // landed since 1.19.402 with no explicit bump. run 33208825538. (task 1002620)
1249
1249
  // 1.19.404 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1250
1250
  // landed since 1.19.403 with no explicit bump. run 33211074633. (task 1002620)
1251
+ // 1.19.405 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1252
+ // landed since 1.19.404 with no explicit bump. run 33212035244. (task 1002620)
1253
+ // 1.19.406 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1254
+ // landed since 1.19.405 with no explicit bump. run 33213981964. (task 1002620)
1251
1255
  // ---------------------------------------------------------------------------
1252
- const CORE_VERSION = '1.19.404'; // CI auto-patch carrier (ADR 0161); see changelog above
1256
+ const CORE_VERSION = '1.19.406'; // CI auto-patch carrier (ADR 0161); see changelog above
1253
1257
 
1254
1258
  // A namespaced logger so a module's log lines are attributable + consistent.
1255
1259
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -317,7 +317,7 @@ test('the signature animations are plain declarations, so the switch reaches the
317
317
  for (const name of [
318
318
  'breathe', 'sheen', // the breath
319
319
  'drift-form', 'drift-orb', // the drift (task 1003333)
320
- 'arrive-form', 'arrive-orb', 'arrive-mark', // the authored moment
320
+ 'arrive-form', 'arrive-orb', // the authored moment
321
321
  ]) {
322
322
  assert.match(PAGE_CSS, new RegExp(`@keyframes\\s+${name}\\s*\\{`), `@keyframes ${name} is gone`);
323
323
  assert.match(PAGE_CSS, new RegExp(`animation:[^;}]*\\b${name}\\b`), `nothing runs ${name}`);
@@ -343,7 +343,7 @@ test('the breath stays slow and the arrival stays brief', () => {
343
343
  assert.ok(form >= 30, 'the sweeping form drifts over 74s; under 30s it paddles');
344
344
  assert.ok(orb >= 30, 'the blob drifts over 58s; under 30s it paddles');
345
345
  assert.notEqual(form, orb, 'equal periods would make the two plates read as one animation');
346
- for (const arrive of ['arrive-form', 'arrive-orb', 'arrive-mark']) {
346
+ for (const arrive of ['arrive-form', 'arrive-orb']) {
347
347
  assert.ok(period(arrive, 'ms') <= 800, `${arrive} holds the first paint too long`);
348
348
  }
349
349
  });
@@ -398,13 +398,25 @@ test('the big plates drift on transform alone, and the still object never does (
398
398
  }
399
399
  const form = PAGE_CSS.match(/\n\.form\{[^}]*\}/);
400
400
  const orb = PAGE_CSS.match(/\n\.orb\{[^}]*\}/);
401
- const mark = PAGE_CSS.match(/\n\.mark\{[^}]*\}/);
402
401
  assert.match(form[0], /animation:[^}]*\bdrift-form\b/, 'the sweeping form drifts');
403
402
  assert.match(orb[0], /animation:[^}]*\bdrift-orb\b/, 'the big blob drifts');
404
- assert.doesNotMatch(mark[0], /drift/, 'the bongo pair is the still object the moving ground is read against');
405
403
  assert.doesNotMatch(PAGE_CSS, /\.doors\{[^}]*animation/, 'the doors never move with a plate');
406
404
  });
407
405
 
406
+ test('the chrome bongo pair is not a hero object; it keeps the closing figure, the orb and the bar (task 1003334)', () => {
407
+ // the owner's second note: the pair sitting on the top-right blob did not fit. It leaves the hero
408
+ // at every width; the phone masthead is the big blob alone, with the words starting where they
409
+ // did when the pair stood above them.
410
+ const hero = HTML.split('<section class="hero">')[1].split('</section>')[0];
411
+ assert.doesNotMatch(hero, /class="mark"|role="img"|bongo drums/, 'a hero object came back');
412
+ assert.doesNotMatch(PAGE_CSS, /\n\.mark\{|--mark-[wxy]|@keyframes\s+arrive-mark\b/, 'the hero object\'s CSS survived');
413
+ assert.match(PAGE_CSS, /\.layer\{[^}]*padding-top:calc\(12px \+ 56vw\)/, 'under 900 the words keep the height the object held');
414
+ // the pair is still the world's object elsewhere on the page
415
+ assert.match(PAGE_CSS, /\.close \.closemark\{[^}]*--sky-bongos/, 'the closing figure is the pair');
416
+ assert.match(PAGE_CSS, /\.o2\{[^}]*--bead-src:var\(--sky-bongos\)/, 'the second project orb is the pair');
417
+ assert.match(HTML, /<a class="barMark" href="\/"[^>]*>\s*<svg viewBox="0 0 26 20"/, 'the bar keeps the mark');
418
+ });
419
+
408
420
  // ── the live-data contract ─────────────────────────────────────────────────
409
421
  // Five public feeds fill the page after it has already rendered a real, baked
410
422
  // state. Everything here is invisible to a passing render: a feed renamed, an