@bongos/core 1.19.403 → 1.19.404

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.
@@ -56,6 +56,8 @@ The world round's light landing rehoused the chrome in a black specimen panel an
56
56
 
57
57
  What the pick settles: the settled constraint (dark-first with a real, tested light mode) stands for the landing; the light cutouts (`r2-chrome-blobs-set-cut.png`, `r2-chrome-blob-one-cut.png`, `r2-bongos-chrome-a-cut.png`) are production material for the light mode, so the build's asset set is the three black plates plus the three cutouts. v1 and v2 stay on disk as built and verified; what they leave behind for the build: v1's pointer parallax as an optional second layer of the drift, v2's beat rail down the margin of the live ledger (the reviewer's strongest below-the-fold block of the round) as the ledger proof's alternative form, and v2's mode-invariant black stage as the pattern for any surface that must keep black in light.
58
58
 
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
+
59
61
  ## 7. Shot list: real imagery still owed
60
62
 
61
63
  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.403",
3
+ "version": "1.19.404",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.403",
9
+ "version": "1.19.404",
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.403",
3
+ "version": "1.19.404",
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",
@@ -75,7 +75,7 @@ ol,ul{list-style:none;padding:0}
75
75
  main:focus{outline:none;box-shadow:none}
76
76
 
77
77
  /* ===================== the chrome field =====================
78
- Three plates, each one crop of one rendered plate. In dark the plates are the black-ground JPEGs
78
+ Two plates, each one crop of one rendered plate. In dark the plates are the black-ground JPEGs
79
79
  composited with lighten; in light they are the alpha cutouts on the pale ground with a contact
80
80
  shadow, so the same sculpture reads as objects on paper. Crop maths: size/position derive from the
81
81
  crop rectangle [u0,u1] x [v0,v1] and the plate aspect, so a layer scales with its own width token. */
@@ -94,35 +94,24 @@ main:focus{outline:none;box-shadow:none}
94
94
  background-size:calc(var(--form-w) * 1.35135) auto;
95
95
  background-position:calc(var(--form-w) * -.2973) 0;
96
96
  -webkit-mask-image:var(--form-mask);mask-image:var(--form-mask);
97
- animation:arrive-form 700ms cubic-bezier(.16,1,.3,1) both}
97
+ animation:arrive-form 700ms cubic-bezier(.16,1,.3,1) both,drift-form 74s ease-in-out infinite}
98
98
 
99
99
  /* r2-chrome-blob-one, cropped to the form's own silhouette u[.14,.865] v[.172,.808] : the big round
100
- blob the doors float inside. The single-blob plate is used rather than the set's round blob
100
+ blob the doors float over. The single-blob plate is used rather than the set's round blob
101
101
  because the set's runs off its own lower edge, and a form cropped by nothing is what light mode
102
- needs. This is the one that breathes, and the only one the hue drift moves. */
102
+ needs. This is the one that breathes, and the only one the hue drift moves; it also drifts. */
103
103
  .orb{left:var(--orb-x);top:var(--orb-y);width:var(--orb-w);aspect-ratio:1.13994;
104
104
  background-image:var(--sky-bead);
105
105
  background-size:calc(var(--orb-w) * 1.37931) auto;
106
106
  background-position:calc(var(--orb-w) * -.1931) calc(var(--orb-w) * -.23724);
107
107
  animation:arrive-orb 700ms cubic-bezier(.16,1,.3,1) 70ms both,
108
108
  breathe 32s ease-in-out 700ms infinite,
109
- sheen 40s ease-in-out infinite}
110
-
111
- /* r2-chrome-blobs-set, u[.808,.952] v[.50,.84] : the set's own small bead, the third form in the
112
- plate, orbiting the big blob. Its centre token is the blob's centre; the orbit translates it out
113
- by --orbit-r and walks it round in twelve steps. */
114
- .bead{left:calc(var(--bead-cx) - var(--bead-w) / 2);
115
- top:calc(var(--bead-cy) - var(--bead-w) * .65885);
116
- width:var(--bead-w);aspect-ratio:.75891;background-image:var(--sky-set);
117
- background-size:calc(var(--bead-w) * 6.94444) auto;
118
- background-position:calc(var(--bead-w) * -5.61111) calc(var(--bead-w) * -1.93798);
119
- translate:var(--orbit-r) 0;
120
- animation:arrive-bead 700ms cubic-bezier(.16,1,.3,1) 140ms both,orbit 60s linear infinite}
109
+ sheen 40s ease-in-out infinite,
110
+ drift-orb 58s ease-in-out infinite}
121
111
 
122
112
  /* the authored moment: the forms arrive from slightly apart and converge into place */
123
113
  @keyframes arrive-form{from{translate:3.4vw -2.2vh;opacity:.36}to{translate:0 0;opacity:1}}
124
114
  @keyframes arrive-orb{from{translate:-2.8vw 2.4vh;opacity:.36}to{translate:0 0;opacity:1}}
125
- @keyframes arrive-bead{from{scale:.78;opacity:0}to{scale:1;opacity:1}}
126
115
  @keyframes arrive-mark{from{translate:2.6vw 1.8vh;opacity:.36}to{translate:0 0;opacity:1}}
127
116
  /* the breath: a 32s swell, and a 40s hue drift so the iridescence keeps moving */
128
117
  @keyframes breathe{0%{scale:1}50%{scale:1.035}100%{scale:1}}
@@ -130,21 +119,24 @@ main:focus{outline:none;box-shadow:none}
130
119
  25%{filter:var(--sky-shadow) hue-rotate(-12deg)}
131
120
  75%{filter:var(--sky-shadow) hue-rotate(12deg)}
132
121
  100%{filter:var(--sky-shadow) hue-rotate(0deg)}}
133
- /* a 60s circular path, walked as twelve steps on the translate property */
134
- @keyframes orbit{
135
- 0%{translate:calc(var(--orbit-r) * 1) 0}
136
- 8.333%{translate:calc(var(--orbit-r) * .866) calc(var(--orbit-r) * .5)}
137
- 16.666%{translate:calc(var(--orbit-r) * .5) calc(var(--orbit-r) * .866)}
138
- 25%{translate:0 calc(var(--orbit-r) * 1)}
139
- 33.333%{translate:calc(var(--orbit-r) * -.5) calc(var(--orbit-r) * .866)}
140
- 41.666%{translate:calc(var(--orbit-r) * -.866) calc(var(--orbit-r) * .5)}
141
- 50%{translate:calc(var(--orbit-r) * -1) 0}
142
- 58.333%{translate:calc(var(--orbit-r) * -.866) calc(var(--orbit-r) * -.5)}
143
- 66.666%{translate:calc(var(--orbit-r) * -.5) calc(var(--orbit-r) * -.866)}
144
- 75%{translate:0 calc(var(--orbit-r) * -1)}
145
- 83.333%{translate:calc(var(--orbit-r) * .5) calc(var(--orbit-r) * -.866)}
146
- 91.666%{translate:calc(var(--orbit-r) * .866) calc(var(--orbit-r) * -.5)}
147
- 100%{translate:calc(var(--orbit-r) * 1) 0}}
122
+ /* the drift (owner, 2026-08-28; task 1003333): the two big plates float like a lava lamp, each on
123
+ its own long loop with unequal periods and phases so they never read as one animation. It rides
124
+ the transform property alone, so it composes with the arrival (translate), the breath (scale)
125
+ and the sheen (filter) instead of fighting them; a translate in percent is a fraction of the
126
+ 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. */
129
+ @keyframes drift-form{
130
+ 0%{transform:translate(0,0) rotate(0deg)}
131
+ 27%{transform:translate(-2.4%,2.6%) rotate(-.9deg)}
132
+ 58%{transform:translate(1.6%,-2.2%) rotate(.7deg)}
133
+ 81%{transform:translate(-1.1%,-1.5%) rotate(-.4deg)}
134
+ 100%{transform:translate(0,0) rotate(0deg)}}
135
+ @keyframes drift-orb{
136
+ 0%{transform:translate(0,0) rotate(0deg)}
137
+ 31%{transform:translate(3.4%,-3%) rotate(1.3deg)}
138
+ 64%{transform:translate(-2.8%,4.2%) rotate(-1.1deg)}
139
+ 100%{transform:translate(0,0) rotate(0deg)}}
148
140
  .scrim{position:absolute;top:calc(var(--top-h) * -1);left:0;right:0;bottom:0;z-index:1;
149
141
  background:var(--sky-scrim);pointer-events:none}
150
142
 
@@ -238,36 +230,9 @@ h1 .whole{white-space:normal;margin-left:0}
238
230
  filter:var(--sky-shadow);
239
231
  pointer-events:none;animation:arrive-mark 700ms cubic-bezier(.16,1,.3,1) 210ms both}
240
232
 
241
- /* leader-line callouts: annotations on the object, on real ledger numbers */
242
- .callout{position:var(--float2);z-index:0}
243
- /* Every callout carries its own ground, and only where the ink is: a feathered patch of the page
244
- ground behind the figure and behind the caption, never the leader and never past the glyphs.
245
- The plates scale with the viewport WIDTH while the type is fixed in px, so between about 1000
246
- and 1300px the lit chrome walks under a caption that sits on black (or paper) at 1440; no
247
- single position clears every width. One box spanning the leader's full width used to reach a
248
- plate's rim and cut a flat-edged card out of it in light; sized to the glyphs and faded to
249
- nothing at its own edge, the ground reads as haze wherever it does meet the sculpture. */
250
- .fig::before,.cap::before{content:"";position:absolute;left:-20px;right:-20px;top:-10px;bottom:-8px;
251
- z-index:-1;filter:blur(8px);pointer-events:none;
252
- /* the solid core must reach the glyph box's CORNERS (an ellipse inscribed in the box misses
253
- them, and the first and last letters of a wide caption then sit on the feather); measured at
254
- 1024 to 1920 in both modes at four animation phases */
255
- background:radial-gradient(ellipse 62% 75% at 50% 50%,var(--bg) 0 88%,transparent 100%)}
256
- .fig:empty::before{display:none} /* a child instance has no figure for a ground to carry */
257
- .c1{left:var(--c1-x);top:var(--c1-y)}
258
- .c2{left:var(--c2-x);top:var(--c2-y)}
259
- .c3{left:var(--c3-x);top:var(--c3-y)}
260
- .leader{display:block;width:var(--leader-len);height:30px;margin-bottom:12px;overflow:visible;
261
- color:var(--ink-soft);opacity:.7}
262
- .c2 .leader{transform:var(--c2-flip)}
263
- .c3 .leader{transform:var(--c3-flip)}
264
- .fig{display:block;position:relative;width:fit-content;max-width:100%;
265
- min-height:1em;font-size:clamp(24px,2.4vw,34px);font-weight:300;letter-spacing:-.025em;
266
- font-variant-numeric:tabular-nums;color:var(--ink);line-height:1;text-shadow:var(--type-halo)}
267
- .cap{display:block;position:relative;width:fit-content;max-width:100%;
268
- margin-top:8px;font-size:14px;color:var(--ink-soft);text-shadow:var(--type-halo)}
269
-
270
- /* the two doors, one joined pill, floating inside the big blob */
233
+ /* the two doors, one joined pill, floating in the lower half of the big blob: below its centre so
234
+ the choice is not the centre of the composition (owner, 2026-08-28; task 1003333). The pair sits
235
+ in its own layer and never moves with the plate that drifts under it. */
271
236
  .doors{position:var(--float2);left:var(--doors-cx);top:var(--doors-cy);transform:var(--doors-shift);
272
237
  display:flex;justify-content:center;pointer-events:auto}
273
238
  .doorbar{display:inline-flex;align-items:center;gap:6px;padding:7px;border-radius:var(--radius-pill);
@@ -295,7 +260,7 @@ h2{font-family:var(--font-display);font-weight:300;font-size:clamp(26px,3.1vw,42
295
260
  text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
296
261
 
297
262
  /* Living proof: real projects as chrome beads. Each project is a DIFFERENT object, addressed by the
298
- same [u0,u1] x [v0,v1] crop maths .form and .bead use, so the constellation is three forms and not
263
+ same [u0,u1] x [v0,v1] crop maths .form and .orb use, so the constellation is three forms and not
299
264
  one silhouette repeated: the round blob, the chrome pair, the set's small bead. Only those three
300
265
  are WHOLE. A rectangle cannot isolate the set's other two forms: the sweeping one runs off the
301
266
  plate's top over half its width and the round one off its bottom over a third, and either crop
@@ -392,12 +357,12 @@ footer a{display:inline-block;min-height:24px;padding:3px 0;line-height:1.24;
392
357
  /* ===================== page-local tokens: LIGHT is the base ===================== */
393
358
  /* Light is the rebuilt answer: no black panel. The same sculpture sits directly on the pale ground
394
359
  as alpha cutouts with a soft contact shadow, the type moves to clean paper on the left, and the
395
- doors and callouts keep their geometry as annotations on the object. */
360
+ doors keep their place over the object. */
396
361
  body{
397
362
  /* THE STAGE. The hero composition was graded at 1440x900 and its vertical tokens are
398
363
  percentages of THIS box, not of the viewport: max(100dvh,900px) reproduces the graded frame
399
364
  byte for byte at 900 and taller, and lets a shorter laptop viewport scroll rather than
400
- recompose (raw vh ran the h1 through the lede and walked the third callout onto lit chrome
365
+ recompose (raw vh ran the h1 through the lede
401
366
  at every height under about 820). --vh is one percent of the stage. */
402
367
  --stage:max(100dvh,900px);
403
368
  --vh:calc(var(--stage) / 100);
@@ -423,7 +388,6 @@ body{
423
388
  --lede-x:3vw;
424
389
  --lede-y:calc(var(--vh) * 32);
425
390
  --lede-w:320px;
426
- --leader-len:170px;
427
391
  --form-mask:linear-gradient(to right,transparent 0 36%,#000 52%);
428
392
  --form-w:52vw;
429
393
  --form-x:56vw;
@@ -431,23 +395,11 @@ body{
431
395
  --orb-w:48vw;
432
396
  --orb-x:32vw;
433
397
  --orb-y:calc(var(--vh) * 32);
434
- --bead-w:7.2vw;
435
- --bead-cx:56vw;
436
- --bead-cy:calc(var(--vh) * 66);
437
- --orbit-r:11vw;
438
398
  --mark-w:22vw;
439
399
  --mark-x:78vw;
440
400
  --mark-y:calc(var(--vh) * 13);
441
- --c1-x:63vw;
442
- --c1-y:calc(var(--vh) * 15);
443
- --c2-x:22vw;
444
- --c2-y:calc(var(--vh) * 66);
445
- --c2-flip:none;
446
- --c3-x:20vw;
447
- --c3-y:calc(var(--vh) * 44);
448
- --c3-flip:none;
449
401
  --doors-cx:56vw;
450
- --doors-cy:calc(var(--vh) * 60);
402
+ --doors-cy:calc(var(--vh) * 75);
451
403
  }
452
404
 
453
405
  :root[data-mode="dark"] body{
@@ -459,7 +411,7 @@ body{
459
411
  /* THE STAGE. The hero composition was graded at 1440x900 and its vertical tokens are
460
412
  percentages of THIS box, not of the viewport: max(100dvh,900px) reproduces the graded frame
461
413
  byte for byte at 900 and taller, and lets a shorter laptop viewport scroll rather than
462
- recompose (raw vh ran the h1 through the lede and walked the third callout onto lit chrome
414
+ recompose (raw vh ran the h1 through the lede
463
415
  at every height under about 820). --vh is one percent of the stage. */
464
416
  --stage:max(100dvh,900px);
465
417
  --vh:calc(var(--stage) / 100);
@@ -481,7 +433,6 @@ body{
481
433
  --lede-x:3vw;
482
434
  --lede-y:calc(var(--vh) * 38);
483
435
  --lede-w:300px;
484
- --leader-len:104px;
485
436
  --form-mask:linear-gradient(to right,transparent 0 34%,#000 50%),linear-gradient(to bottom,#000 0 44%,transparent 54%);
486
437
  --form-w:70vw;
487
438
  --form-x:40vw;
@@ -489,31 +440,11 @@ body{
489
440
  --orb-w:54vw;
490
441
  --orb-x:5vw;
491
442
  --orb-y:calc(var(--vh) * 24);
492
- --bead-w:8.3vw;
493
- --bead-cx:32vw;
494
- --bead-cy:calc(var(--vh) * 62);
495
- --orbit-r:15vw;
496
443
  --mark-w:27vw;
497
444
  --mark-x:71vw;
498
445
  --mark-y:calc(var(--vh) * 12);
499
- --c1-x:61vw;
500
- /* bound to WIDTH, not to the stage: the caption sits a whisker above the sweeping form's lit
501
- ridge, and the form is sized from vw, so the ridge walks with the viewport WIDTH. The graded
502
- 1440 height put "tasks shipped" straight on the lit band at 1366 and 1280 (2.7:1). Hold the
503
- graded value at 1440 and wider, then lift the block as the viewport narrows, floored so it
504
- never climbs behind the top bar. */
505
- --c1-y:max(70px, calc(var(--vh) * 13 - max(0px, (1440px - 100vw) * 0.32)));
506
- --c2-x:64vw;
507
- --c2-y:calc(var(--vh) * 74);
508
- --c2-flip:scaleX(-1);
509
- --c3-x:70vw;
510
- /* bound to the sweeping form, not to the stage: the form is sized from vw, so a stage-anchored
511
- callout slides up onto its lit lower lobe as the viewport widens. This is the graded 1440x900
512
- position expressed as a fraction of the form's own height. */
513
- --c3-y:calc(var(--form-y) + var(--form-w) / 1.32584 * 0.793136);
514
- --c3-flip:scaleX(-1);
515
446
  --doors-cx:32vw;
516
- --doors-cy:calc(var(--vh) * 53);
447
+ --doors-cy:calc(var(--vh) * 73);
517
448
  }
518
449
 
519
450
  @media (prefers-color-scheme:dark){
@@ -526,7 +457,7 @@ body{
526
457
  /* THE STAGE. The hero composition was graded at 1440x900 and its vertical tokens are
527
458
  percentages of THIS box, not of the viewport: max(100dvh,900px) reproduces the graded frame
528
459
  byte for byte at 900 and taller, and lets a shorter laptop viewport scroll rather than
529
- recompose (raw vh ran the h1 through the lede and walked the third callout onto lit chrome
460
+ recompose (raw vh ran the h1 through the lede
530
461
  at every height under about 820). --vh is one percent of the stage. */
531
462
  --stage:max(100dvh,900px);
532
463
  --vh:calc(var(--stage) / 100);
@@ -548,7 +479,6 @@ body{
548
479
  --lede-x:3vw;
549
480
  --lede-y:calc(var(--vh) * 38);
550
481
  --lede-w:300px;
551
- --leader-len:104px;
552
482
  --form-mask:linear-gradient(to right,transparent 0 34%,#000 50%),linear-gradient(to bottom,#000 0 44%,transparent 54%);
553
483
  --form-w:70vw;
554
484
  --form-x:40vw;
@@ -556,31 +486,11 @@ body{
556
486
  --orb-w:54vw;
557
487
  --orb-x:5vw;
558
488
  --orb-y:calc(var(--vh) * 24);
559
- --bead-w:8.3vw;
560
- --bead-cx:32vw;
561
- --bead-cy:calc(var(--vh) * 62);
562
- --orbit-r:15vw;
563
489
  --mark-w:27vw;
564
490
  --mark-x:71vw;
565
491
  --mark-y:calc(var(--vh) * 12);
566
- --c1-x:61vw;
567
- /* bound to WIDTH, not to the stage: the caption sits a whisker above the sweeping form's lit
568
- ridge, and the form is sized from vw, so the ridge walks with the viewport WIDTH. The graded
569
- 1440 height put "tasks shipped" straight on the lit band at 1366 and 1280 (2.7:1). Hold the
570
- graded value at 1440 and wider, then lift the block as the viewport narrows, floored so it
571
- never climbs behind the top bar. */
572
- --c1-y:max(70px, calc(var(--vh) * 13 - max(0px, (1440px - 100vw) * 0.32)));
573
- --c2-x:64vw;
574
- --c2-y:calc(var(--vh) * 74);
575
- --c2-flip:scaleX(-1);
576
- --c3-x:70vw;
577
- /* bound to the sweeping form, not to the stage: the form is sized from vw, so a stage-anchored
578
- callout slides up onto its lit lower lobe as the viewport widens. This is the graded 1440x900
579
- position expressed as a fraction of the form's own height. */
580
- --c3-y:calc(var(--form-y) + var(--form-w) / 1.32584 * 0.793136);
581
- --c3-flip:scaleX(-1);
582
492
  --doors-cx:32vw;
583
- --doors-cy:calc(var(--vh) * 53);
493
+ --doors-cy:calc(var(--vh) * 73);
584
494
  }
585
495
  }
586
496
 
@@ -615,13 +525,6 @@ body{
615
525
  .doors{order:4;margin-top:26px;width:100%}
616
526
  .doorbar{width:100%}
617
527
  .door{flex:1;padding:0 8px;font-size:15px;text-align:center;min-height:46px}
618
- .callout{flex:1}
619
- .fig::before,.cap::before{display:none} /* the row sits on the masthead scrim; the callouts flow, so no ground */
620
- .callouts-row{order:5;display:flex;gap:12px;width:100%;margin-top:34px;text-align:left}
621
- .leader{height:22px;margin-bottom:8px}
622
- .c2 .leader,.c3 .leader{transform:none}
623
- .fig{font-size:22px}
624
- .cap{font-size:12.5px}
625
528
  .band{padding:52px 20px}
626
529
  .orbs{gap:26px;margin-top:36px;align-items:flex-end}
627
530
  .orb-item{margin-bottom:0}
@@ -648,7 +551,6 @@ body{
648
551
  --lede-x:0;
649
552
  --lede-y:0;
650
553
  --lede-w:34ch;
651
- --leader-len:100%;
652
554
  --sky-mask:none;
653
555
  --sky-scrim:none;
654
556
  --form-w:0px;
@@ -657,14 +559,9 @@ body{
657
559
  --orb-w:92vw;
658
560
  --orb-x:4vw;
659
561
  --orb-y:-6vh;
660
- --bead-w:0px;
661
- --bead-cx:-200vw;
662
- --bead-cy:0;
663
- --orbit-r:0px;
664
562
  --mark-w:56vw;
665
563
  --mark-x:0;
666
564
  --mark-y:0;
667
- --c1-x:0;--c1-y:0;--c2-x:0;--c2-y:0;--c2-flip:none;--c3-x:0;--c3-y:0;--c3-flip:none;
668
565
  --doors-cx:0;--doors-cy:0;
669
566
  }
670
567
  :root[data-mode="dark"] body{
@@ -678,7 +575,6 @@ body{
678
575
  --lede-x:0;
679
576
  --lede-y:0;
680
577
  --lede-w:34ch;
681
- --leader-len:100%;
682
578
  --sky-mask:linear-gradient(to bottom,#000 0 88%,transparent 100%);
683
579
  --sky-scrim:linear-gradient(to top,rgba(0,0,0,.94) 0 170px,rgba(0,0,0,0) 340px),radial-gradient(128% 46% at 50% 38%,rgba(0,0,0,.9),rgba(0,0,0,.5) 54%,rgba(0,0,0,0) 88%);
684
580
  --form-w:0px;
@@ -687,14 +583,9 @@ body{
687
583
  --orb-w:150vw;
688
584
  --orb-x:-25vw;
689
585
  --orb-y:22vh;
690
- --bead-w:0px;
691
- --bead-cx:-200vw;
692
- --bead-cy:0;
693
- --orbit-r:0px;
694
586
  --mark-w:56vw;
695
587
  --mark-x:0;
696
588
  --mark-y:0;
697
- --c1-x:0;--c1-y:0;--c2-x:0;--c2-y:0;--c2-flip:none;--c3-x:0;--c3-y:0;--c3-flip:none;
698
589
  --doors-cx:0;--doors-cy:0;
699
590
  }
700
591
  }
@@ -711,7 +602,6 @@ body{
711
602
  --lede-x:0;
712
603
  --lede-y:0;
713
604
  --lede-w:34ch;
714
- --leader-len:100%;
715
605
  --sky-mask:linear-gradient(to bottom,#000 0 88%,transparent 100%);
716
606
  --sky-scrim:linear-gradient(to top,rgba(0,0,0,.94) 0 170px,rgba(0,0,0,0) 340px),radial-gradient(128% 46% at 50% 38%,rgba(0,0,0,.9),rgba(0,0,0,.5) 54%,rgba(0,0,0,0) 88%);
717
607
  --form-w:0px;
@@ -720,14 +610,9 @@ body{
720
610
  --orb-w:150vw;
721
611
  --orb-x:-25vw;
722
612
  --orb-y:22vh;
723
- --bead-w:0px;
724
- --bead-cx:-200vw;
725
- --bead-cy:0;
726
- --orbit-r:0px;
727
613
  --mark-w:56vw;
728
614
  --mark-x:0;
729
615
  --mark-y:0;
730
- --c1-x:0;--c1-y:0;--c2-x:0;--c2-y:0;--c2-flip:none;--c3-x:0;--c3-y:0;--c3-flip:none;
731
616
  --doors-cx:0;--doors-cy:0;
732
617
  }
733
618
  }
@@ -736,52 +621,48 @@ body{
736
621
  <body>
737
622
  <!--
738
623
  THESIS: the owner's template, built as a working front door. One chrome sculpture holds the whole
739
- first viewport, the headline crosses it in two lines, and the only thing inside the big blob is the
740
- choice: the two doors, joined, floating at its centre where the template floats its pill.
624
+ first viewport, the headline crosses it in two lines, and the only thing on the big blob is the
625
+ choice: the two doors, joined, floating in its lower half.
741
626
  FIRST VIEWPORT (1440, dark): the big round blob 54vw at the centre-left, its top crossed by the
742
627
  h1's second line; the sweeping form across the upper right with the three-quarter chrome bongo pair
743
- sitting on it; the lede top-left under the first line; three leader-line callouts on real ledger
744
- numbers, each on black rather than on chrome (upper right beside the bongos, mid right, and lower
745
- right past the blob's shoulder, its leader flipped so the line still gestures back at the form);
746
- the joined door pill at the blob's centre, primary carrying the one warm accent, its ground half
747
- black so the sculpture still reads through it; the pipeline rail lives below the fold.
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.
748
633
  STAGE: every vertical token in the hero is a percentage of a FLOORED stage, max(100dvh, 900px),
749
634
  not of the raw viewport. At 900 and taller the frame above is reproduced exactly; a shorter laptop
750
635
  viewport (1536x730, 1440x760) scrolls the last of the hero instead of recomposing it, which is what
751
- used to run the h1 through the lede and slide the third callout onto the lit chrome. The third
752
- callout is the one exception: it is anchored to the sweeping form's own box, because that form is
753
- sized from vw, so at 1536 and wider a stage-anchored callout still met its lit lower lobe.
636
+ used to run the h1 through the lede.
754
637
  PLATES: /assets/world/, six files with provenance sidecars, referenced only through the world
755
638
  layer's paired tokens. The big blob is r2-chrome-blob-one, not the set's round blob, because the
756
639
  set's runs off its own lower edge and a form cropped by nothing is what a pale ground needs; the
757
- orbiting bead is the set's third form; the sweeping form is the set, cropped to the plate's full
758
- height so its lower edge falls where the plate is already empty. Below the fold the three project
759
- orbs are three DIFFERENT objects on the same crop maths (the round blob, the chrome pair, the set's
760
- small bead) so one silhouette is not repeated down the page, and the closing figure is the pair
761
- again, over the doors.
762
- SIGNATURE, "the breath": the big blob breathes (scale 1 to 1.035, 32s ease-in-out) under a slow hue
763
- drift (plus or minus 12 degrees, 40s) so the iridescence keeps moving, and a chrome bead orbits it on
764
- a 60s circular path walked as twelve steps of the translate property. The authored moment is the
765
- arrival: the three forms converge from slightly apart into place in 700ms. All CSS, all on the plates
766
- themselves so the lighten group is never broken; the doors sit in their own layer and never scale
767
- with the blob. The world layer's reduced-motion kill switch stops every one of them, and the still
768
- frame (bead at three o'clock, blob at rest, no hue shift) is the composition.
640
+ sweeping form is the set, cropped to the plate's full height so its lower edge falls where the
641
+ plate is already empty. The set's small bead is no longer a hero plate (it orbited the blob until
642
+ task 1003333); it survives below the fold as the third project orb. The three project orbs are
643
+ three DIFFERENT objects on the same crop maths (the round blob, the chrome pair, the set's small
644
+ bead) so one silhouette is not repeated down the page, and the closing figure is the pair again,
645
+ over the doors.
646
+ SIGNATURE, "the breath" and "the drift": the big blob breathes (scale 1 to 1.035, 32s ease-in-out)
647
+ under a slow hue drift (plus or minus 12 degrees, 40s) so the iridescence keeps moving, and both
648
+ big plates float like a lava lamp on their own long loops (the sweeping form 74s, the blob 58s;
649
+ translate inside 5% of each plate's own box, rotation inside 1.5deg, on the transform property
650
+ 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
653
+ kill switch stops every one of them, and the still frame (every plate at 0%, blob at rest, no hue
654
+ shift) is the composition.
769
655
  LIGHT ANSWER, "the rebuilt light mode": no black panel anywhere. The same sculpture, cut out with
770
656
  real alpha, sits directly on the pale ground with a soft contact shadow so it reads as objects on
771
- paper. The blob, the orbiting bead and the bongo pair are whole; the sweeping form is deliberately
772
- not, it carries a gradient mask that dissolves its left edge and it bleeds off the right of the
773
- viewport, which is how a form that wide stays a backdrop and not a fourth object. The type moves off
774
- the chrome onto clean paper at the left, and the callouts become margin annotations whose leader
775
- lines reach in far enough to meet the silhouette. The doors keep their place at the blob's centre on
776
- a near opaque pale ground. At 390 light inverts the stack: the sculpture is a masthead at the top and
777
- every word sits on paper under it.
657
+ paper. The blob and the bongo pair are whole; the sweeping form is deliberately not, it carries a
658
+ gradient mask that dissolves its left edge and it bleeds off the right of the viewport, which is how
659
+ a form that wide stays a backdrop and not a fourth object. The type moves off the chrome onto clean
660
+ paper at the left. The doors keep their place in the blob's lower half on a near opaque pale
661
+ ground. At 390 light inverts the stack: the sculpture is a masthead at the top and every word sits
662
+ on paper under it.
778
663
  DATA (baked values are real, fetched 2026-08-27T18:00Z; the page then renders them LIVE and every
779
- baked apex number sits inside apex-only sentinels so a child instance shows an empty figure until
664
+ baked apex number sits inside apex-only sentinels so a child instance shows an empty ledger until
780
665
  its own feed answers):
781
- data-fig="shipped" = the sum of shipped_count over every row of /api/gds/public/progress.
782
- data-fig="value" = total_value_credits from /api/gds/public/cost-summary.
783
- data-fig="builders" = the entries in /api/gds/public/leaderboard with total_credits above zero,
784
- captioned "builders holding credits" because that is what it counts.
785
666
  data-ledger="line" = the first progress row whose status is building (else the first row), read
786
667
  as "<shipped> of <total> shipped on <V>"; data-ledger="meter" is that ratio.
787
668
  data-rows = /api/gds/public/recent-shipped?limit=6. Titles are quoted data: an em or en
@@ -876,7 +757,6 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
876
757
  <div class="field" aria-hidden="true">
877
758
  <span class="plate form"></span>
878
759
  <span class="plate orb"></span>
879
- <span class="plate bead"></span>
880
760
  </div>
881
761
  <div class="scrim" aria-hidden="true"></div>
882
762
 
@@ -888,33 +768,6 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
888
768
  <div class="mark" role="img"
889
769
  aria-label="A pair of bongo drums in mirror-polished chrome, seen from three quarters"></div>
890
770
 
891
- <div class="callouts-row">
892
- <div class="callout c1">
893
- <svg class="leader" viewBox="0 0 104 30" aria-hidden="true" preserveAspectRatio="none">
894
- <line x1="0" y1="29" x2="103" y2="1" stroke="currentColor" stroke-width="1"
895
- vector-effect="non-scaling-stroke"/>
896
- </svg>
897
- <span class="fig" data-fig="shipped"><!--apex-only:start-->2,107<!--apex-only:end--></span>
898
- <span class="cap">tasks shipped</span>
899
- </div>
900
- <div class="callout c2">
901
- <svg class="leader" viewBox="0 0 104 30" aria-hidden="true" preserveAspectRatio="none">
902
- <line x1="0" y1="29" x2="103" y2="1" stroke="currentColor" stroke-width="1"
903
- vector-effect="non-scaling-stroke"/>
904
- </svg>
905
- <span class="fig" data-fig="value"><!--apex-only:start-->69,790<!--apex-only:end--></span>
906
- <span class="cap">credits of value</span>
907
- </div>
908
- <div class="callout c3">
909
- <svg class="leader" viewBox="0 0 104 30" aria-hidden="true" preserveAspectRatio="none">
910
- <line x1="0" y1="29" x2="103" y2="1" stroke="currentColor" stroke-width="1"
911
- vector-effect="non-scaling-stroke"/>
912
- </svg>
913
- <span class="fig" data-fig="builders"><!--apex-only:start-->9<!--apex-only:end--></span>
914
- <span class="cap">builders holding credits</span>
915
- </div>
916
- </div>
917
-
918
771
  <div class="doors">
919
772
  <div class="doorbar">
920
773
  <a class="door" href="/projects">Find a project to join</a>
@@ -1281,15 +1134,13 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
1281
1134
  });
1282
1135
  });
1283
1136
 
1284
- /* ── the live ledger. Every figure and row on this page is baked as a real
1285
- value and then refreshed from the public feeds; a failed or empty feed
1286
- leaves the baked state standing and says nothing to the console. ── */
1137
+ /* ── the live ledger. The ledger line, its meter and its rows are baked as
1138
+ real values and then refreshed from the public feeds; a failed or empty
1139
+ feed leaves the baked state standing and says nothing to the console.
1140
+ (The three hero figures and the two feeds that fed only them left with
1141
+ task 1003333; the poster card on /projects carries the callout grammar.) ── */
1287
1142
  var MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1288
1143
  function num(n) { return Number(n).toLocaleString('en-US'); }
1289
- function setFig(key, value) {
1290
- var el = document.querySelector('[data-fig="' + key + '"]');
1291
- if (el) el.textContent = value;
1292
- }
1293
1144
  function cell(cls, txt) {
1294
1145
  var s = document.createElement('span');
1295
1146
  s.className = cls;
@@ -1323,12 +1174,8 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
1323
1174
  json(GDS + '/public/progress').then(function (data) {
1324
1175
  var rows = (data && data.progress) || [];
1325
1176
  if (!rows.length) return;
1326
- var total = 0, live = null;
1327
- rows.forEach(function (r) {
1328
- total += Number(r.shipped_count) || 0;
1329
- if (!live && r.status === 'building') live = r;
1330
- });
1331
- setFig('shipped', num(total));
1177
+ var live = null;
1178
+ rows.forEach(function (r) { if (!live && r.status === 'building') live = r; });
1332
1179
  if (!live) live = rows[0];
1333
1180
  var done = Number(live.shipped_count) || 0;
1334
1181
  var all = Number(live.total_count) || 0;
@@ -1344,18 +1191,6 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
1344
1191
  }
1345
1192
  });
1346
1193
 
1347
- json(GDS + '/public/cost-summary').then(function (data) {
1348
- if (data && data.total_value_credits != null) setFig('value', num(data.total_value_credits));
1349
- });
1350
-
1351
- json(GDS + '/public/leaderboard').then(function (data) {
1352
- var rows = (data && data.leaderboard) || [];
1353
- if (!rows.length) return;
1354
- var held = 0;
1355
- rows.forEach(function (r) { if (Number(r.total_credits) > 0) held++; });
1356
- setFig('builders', num(held));
1357
- });
1358
-
1359
1194
  json(GDS + '/public/recent-shipped?limit=6').then(function (data) {
1360
1195
  var tasks = ((data && data.tasks) || []).slice(0, 6);
1361
1196
  var list = document.querySelector('[data-rows]');
package/src/module-api.js CHANGED
@@ -1246,8 +1246,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
1246
1246
  // landed since 1.19.401 with no explicit bump. run 33206226800. (task 1002620)
1247
1247
  // 1.19.403 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1248
1248
  // landed since 1.19.402 with no explicit bump. run 33208825538. (task 1002620)
1249
+ // 1.19.404 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1250
+ // landed since 1.19.403 with no explicit bump. run 33211074633. (task 1002620)
1249
1251
  // ---------------------------------------------------------------------------
1250
- const CORE_VERSION = '1.19.403'; // CI auto-patch carrier (ADR 0161); see changelog above
1252
+ const CORE_VERSION = '1.19.404'; // CI auto-patch carrier (ADR 0161); see changelog above
1251
1253
 
1252
1254
  // A namespaced logger so a module's log lines are attributable + consistent.
1253
1255
  // Usage: const log = api.logger('dev-box'); log.info('mounted');