@bongos/core 1.19.403 → 1.19.405

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,10 @@ 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
+
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
+
59
63
  ## 7. Shot list: real imagery still owed
60
64
 
61
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.403",
3
+ "version": "1.19.405",
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.405",
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.405",
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,57 +94,51 @@ 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
- @keyframes arrive-mark{from{translate:2.6vw 1.8vh;opacity:.36}to{translate:0 0;opacity:1}}
127
115
  /* the breath: a 32s swell, and a 40s hue drift so the iridescence keeps moving */
128
116
  @keyframes breathe{0%{scale:1}50%{scale:1.035}100%{scale:1}}
129
117
  @keyframes sheen{0%{filter:var(--sky-shadow) hue-rotate(0deg)}
130
118
  25%{filter:var(--sky-shadow) hue-rotate(-12deg)}
131
119
  75%{filter:var(--sky-shadow) hue-rotate(12deg)}
132
120
  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}}
121
+ /* the drift (owner, 2026-08-28; task 1003333): the two big plates float like a lava lamp, each on
122
+ its own long loop with unequal periods and phases so they never read as one animation. It rides
123
+ the transform property alone, so it composes with the arrival (translate), the breath (scale)
124
+ and the sheen (filter) instead of fighting them; a translate in percent is a fraction of the
125
+ plate's own box, and it stays inside 5% with rotation inside 1.5deg, so the type over the plate
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.) */
131
+ @keyframes drift-form{
132
+ 0%{transform:translate(0,0) rotate(0deg)}
133
+ 27%{transform:translate(-2.4%,2.6%) rotate(-.9deg)}
134
+ 58%{transform:translate(1.6%,-2.2%) rotate(.7deg)}
135
+ 81%{transform:translate(-1.1%,-1.5%) rotate(-.4deg)}
136
+ 100%{transform:translate(0,0) rotate(0deg)}}
137
+ @keyframes drift-orb{
138
+ 0%{transform:translate(0,0) rotate(0deg)}
139
+ 31%{transform:translate(3.4%,-3%) rotate(1.3deg)}
140
+ 64%{transform:translate(-2.8%,4.2%) rotate(-1.1deg)}
141
+ 100%{transform:translate(0,0) rotate(0deg)}}
148
142
  .scrim{position:absolute;top:calc(var(--top-h) * -1);left:0;right:0;bottom:0;z-index:1;
149
143
  background:var(--sky-scrim);pointer-events:none}
150
144
 
@@ -232,42 +226,9 @@ h1 .whole{white-space:normal;margin-left:0}
232
226
  .lede{position:var(--float2);left:var(--lede-x);top:var(--lede-y);width:var(--lede-w);max-width:100%;
233
227
  font-size:18.5px;line-height:1.42;color:var(--ink-soft);text-shadow:var(--type-halo)}
234
228
 
235
- /* the hero object: the three-quarter chrome pair, an alpha cutout with its own contact shadow */
236
- .mark{position:var(--float2);left:var(--mark-x);top:var(--mark-y);width:var(--mark-w);aspect-ratio:1;
237
- background-image:var(--sky-bongos);background-repeat:no-repeat;background-size:100% auto;
238
- filter:var(--sky-shadow);
239
- pointer-events:none;animation:arrive-mark 700ms cubic-bezier(.16,1,.3,1) 210ms both}
240
-
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 */
229
+ /* the two doors, one joined pill, floating in the lower half of the big blob: below its centre so
230
+ the choice is not the centre of the composition (owner, 2026-08-28; task 1003333). The pair sits
231
+ in its own layer and never moves with the plate that drifts under it. */
271
232
  .doors{position:var(--float2);left:var(--doors-cx);top:var(--doors-cy);transform:var(--doors-shift);
272
233
  display:flex;justify-content:center;pointer-events:auto}
273
234
  .doorbar{display:inline-flex;align-items:center;gap:6px;padding:7px;border-radius:var(--radius-pill);
@@ -295,7 +256,7 @@ h2{font-family:var(--font-display);font-weight:300;font-size:clamp(26px,3.1vw,42
295
256
  text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
296
257
 
297
258
  /* 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
259
+ same [u0,u1] x [v0,v1] crop maths .form and .orb use, so the constellation is three forms and not
299
260
  one silhouette repeated: the round blob, the chrome pair, the set's small bead. Only those three
300
261
  are WHOLE. A rectangle cannot isolate the set's other two forms: the sweeping one runs off the
301
262
  plate's top over half its width and the round one off its bottom over a third, and either crop
@@ -392,12 +353,12 @@ footer a{display:inline-block;min-height:24px;padding:3px 0;line-height:1.24;
392
353
  /* ===================== page-local tokens: LIGHT is the base ===================== */
393
354
  /* Light is the rebuilt answer: no black panel. The same sculpture sits directly on the pale ground
394
355
  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. */
356
+ doors keep their place over the object. */
396
357
  body{
397
358
  /* THE STAGE. The hero composition was graded at 1440x900 and its vertical tokens are
398
359
  percentages of THIS box, not of the viewport: max(100dvh,900px) reproduces the graded frame
399
360
  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
361
+ recompose (raw vh ran the h1 through the lede
401
362
  at every height under about 820). --vh is one percent of the stage. */
402
363
  --stage:max(100dvh,900px);
403
364
  --vh:calc(var(--stage) / 100);
@@ -423,7 +384,6 @@ body{
423
384
  --lede-x:3vw;
424
385
  --lede-y:calc(var(--vh) * 32);
425
386
  --lede-w:320px;
426
- --leader-len:170px;
427
387
  --form-mask:linear-gradient(to right,transparent 0 36%,#000 52%);
428
388
  --form-w:52vw;
429
389
  --form-x:56vw;
@@ -431,23 +391,8 @@ body{
431
391
  --orb-w:48vw;
432
392
  --orb-x:32vw;
433
393
  --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
- --mark-w:22vw;
439
- --mark-x:78vw;
440
- --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
394
  --doors-cx:56vw;
450
- --doors-cy:calc(var(--vh) * 60);
395
+ --doors-cy:calc(var(--vh) * 75);
451
396
  }
452
397
 
453
398
  :root[data-mode="dark"] body{
@@ -459,7 +404,7 @@ body{
459
404
  /* THE STAGE. The hero composition was graded at 1440x900 and its vertical tokens are
460
405
  percentages of THIS box, not of the viewport: max(100dvh,900px) reproduces the graded frame
461
406
  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
407
+ recompose (raw vh ran the h1 through the lede
463
408
  at every height under about 820). --vh is one percent of the stage. */
464
409
  --stage:max(100dvh,900px);
465
410
  --vh:calc(var(--stage) / 100);
@@ -481,7 +426,6 @@ body{
481
426
  --lede-x:3vw;
482
427
  --lede-y:calc(var(--vh) * 38);
483
428
  --lede-w:300px;
484
- --leader-len:104px;
485
429
  --form-mask:linear-gradient(to right,transparent 0 34%,#000 50%),linear-gradient(to bottom,#000 0 44%,transparent 54%);
486
430
  --form-w:70vw;
487
431
  --form-x:40vw;
@@ -489,31 +433,8 @@ body{
489
433
  --orb-w:54vw;
490
434
  --orb-x:5vw;
491
435
  --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
- --mark-w:27vw;
497
- --mark-x:71vw;
498
- --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
436
  --doors-cx:32vw;
516
- --doors-cy:calc(var(--vh) * 53);
437
+ --doors-cy:calc(var(--vh) * 73);
517
438
  }
518
439
 
519
440
  @media (prefers-color-scheme:dark){
@@ -526,7 +447,7 @@ body{
526
447
  /* THE STAGE. The hero composition was graded at 1440x900 and its vertical tokens are
527
448
  percentages of THIS box, not of the viewport: max(100dvh,900px) reproduces the graded frame
528
449
  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
450
+ recompose (raw vh ran the h1 through the lede
530
451
  at every height under about 820). --vh is one percent of the stage. */
531
452
  --stage:max(100dvh,900px);
532
453
  --vh:calc(var(--stage) / 100);
@@ -548,7 +469,6 @@ body{
548
469
  --lede-x:3vw;
549
470
  --lede-y:calc(var(--vh) * 38);
550
471
  --lede-w:300px;
551
- --leader-len:104px;
552
472
  --form-mask:linear-gradient(to right,transparent 0 34%,#000 50%),linear-gradient(to bottom,#000 0 44%,transparent 54%);
553
473
  --form-w:70vw;
554
474
  --form-x:40vw;
@@ -556,31 +476,8 @@ body{
556
476
  --orb-w:54vw;
557
477
  --orb-x:5vw;
558
478
  --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
- --mark-w:27vw;
564
- --mark-x:71vw;
565
- --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
479
  --doors-cx:32vw;
583
- --doors-cy:calc(var(--vh) * 53);
480
+ --doors-cy:calc(var(--vh) * 73);
584
481
  }
585
482
  }
586
483
 
@@ -606,22 +503,16 @@ body{
606
503
  .bandProfile .bandCell,.bandProfile .bandSlot{flex:none;text-align:left}
607
504
  .bandWho{padding-bottom:14px}
608
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 */
609
508
  .layer{display:flex;flex-direction:column;align-items:center;text-align:center;
610
- top:0;left:auto;right:auto;bottom:auto;padding-top:12px;pointer-events:auto}
611
- .mark{order:1;margin:0 auto}
509
+ top:0;left:auto;right:auto;bottom:auto;padding-top:calc(12px + 56vw);pointer-events:auto}
612
510
  h1{order:2;margin-top:14px}
613
511
  h1 .l2{margin-left:0}
614
512
  .lede{order:3;margin:16px auto 0}
615
513
  .doors{order:4;margin-top:26px;width:100%}
616
514
  .doorbar{width:100%}
617
515
  .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
516
  .band{padding:52px 20px}
626
517
  .orbs{gap:26px;margin-top:36px;align-items:flex-end}
627
518
  .orb-item{margin-bottom:0}
@@ -648,7 +539,6 @@ body{
648
539
  --lede-x:0;
649
540
  --lede-y:0;
650
541
  --lede-w:34ch;
651
- --leader-len:100%;
652
542
  --sky-mask:none;
653
543
  --sky-scrim:none;
654
544
  --form-w:0px;
@@ -657,14 +547,6 @@ body{
657
547
  --orb-w:92vw;
658
548
  --orb-x:4vw;
659
549
  --orb-y:-6vh;
660
- --bead-w:0px;
661
- --bead-cx:-200vw;
662
- --bead-cy:0;
663
- --orbit-r:0px;
664
- --mark-w:56vw;
665
- --mark-x:0;
666
- --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
550
  --doors-cx:0;--doors-cy:0;
669
551
  }
670
552
  :root[data-mode="dark"] body{
@@ -678,7 +560,6 @@ body{
678
560
  --lede-x:0;
679
561
  --lede-y:0;
680
562
  --lede-w:34ch;
681
- --leader-len:100%;
682
563
  --sky-mask:linear-gradient(to bottom,#000 0 88%,transparent 100%);
683
564
  --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
565
  --form-w:0px;
@@ -687,14 +568,6 @@ body{
687
568
  --orb-w:150vw;
688
569
  --orb-x:-25vw;
689
570
  --orb-y:22vh;
690
- --bead-w:0px;
691
- --bead-cx:-200vw;
692
- --bead-cy:0;
693
- --orbit-r:0px;
694
- --mark-w:56vw;
695
- --mark-x:0;
696
- --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
571
  --doors-cx:0;--doors-cy:0;
699
572
  }
700
573
  }
@@ -711,7 +584,6 @@ body{
711
584
  --lede-x:0;
712
585
  --lede-y:0;
713
586
  --lede-w:34ch;
714
- --leader-len:100%;
715
587
  --sky-mask:linear-gradient(to bottom,#000 0 88%,transparent 100%);
716
588
  --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
589
  --form-w:0px;
@@ -720,14 +592,6 @@ body{
720
592
  --orb-w:150vw;
721
593
  --orb-x:-25vw;
722
594
  --orb-y:22vh;
723
- --bead-w:0px;
724
- --bead-cx:-200vw;
725
- --bead-cy:0;
726
- --orbit-r:0px;
727
- --mark-w:56vw;
728
- --mark-x:0;
729
- --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
595
  --doors-cx:0;--doors-cy:0;
732
596
  }
733
597
  }
@@ -736,52 +600,49 @@ body{
736
600
  <body>
737
601
  <!--
738
602
  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.
603
+ first viewport, the headline crosses it in two lines, and the only thing on the big blob is the
604
+ choice: the two doors, joined, floating in its lower half.
741
605
  FIRST VIEWPORT (1440, dark): the big round blob 54vw at the centre-left, its top crossed by the
742
- 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.
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.
748
613
  STAGE: every vertical token in the hero is a percentage of a FLOORED stage, max(100dvh, 900px),
749
614
  not of the raw viewport. At 900 and taller the frame above is reproduced exactly; a shorter laptop
750
615
  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.
616
+ used to run the h1 through the lede.
754
617
  PLATES: /assets/world/, six files with provenance sidecars, referenced only through the world
755
618
  layer's paired tokens. The big blob is r2-chrome-blob-one, not the set's round blob, because the
756
619
  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.
620
+ sweeping form is the set, cropped to the plate's full height so its lower edge falls where the
621
+ plate is already empty. The set's small bead is no longer a hero plate (it orbited the blob until
622
+ task 1003333); it survives below the fold as the third project orb. The three project orbs are
623
+ three DIFFERENT objects on the same crop maths (the round blob, the chrome pair, the set's small
624
+ bead) so one silhouette is not repeated down the page, and the closing figure is the pair again,
625
+ over the doors.
626
+ SIGNATURE, "the breath" and "the drift": the big blob breathes (scale 1 to 1.035, 32s ease-in-out)
627
+ under a slow hue drift (plus or minus 12 degrees, 40s) so the iridescence keeps moving, and both
628
+ big plates float like a lava lamp on their own long loops (the sweeping form 74s, the blob 58s;
629
+ translate inside 5% of each plate's own box, rotation inside 1.5deg, on the transform property
630
+ alone). The authored moment is the arrival: the forms converge from slightly apart into place in
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
633
+ kill switch stops every one of them, and the still frame (every plate at 0%, blob at rest, no hue
634
+ shift) is the composition.
769
635
  LIGHT ANSWER, "the rebuilt light mode": no black panel anywhere. The same sculpture, cut out with
770
636
  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.
637
+ paper. The blob is whole; the sweeping form is deliberately not, it carries a
638
+ gradient mask that dissolves its left edge and it bleeds off the right of the viewport, which is how
639
+ a form that wide stays a backdrop and not a fourth object. The type moves off the chrome onto clean
640
+ paper at the left. The doors keep their place in the blob's lower half on a near opaque pale
641
+ ground. At 390 light inverts the stack: the sculpture is a masthead at the top and every word sits
642
+ on paper under it.
778
643
  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
644
+ baked apex number sits inside apex-only sentinels so a child instance shows an empty ledger until
780
645
  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
646
  data-ledger="line" = the first progress row whose status is building (else the first row), read
786
647
  as "<shipped> of <total> shipped on <V>"; data-ledger="meter" is that ratio.
787
648
  data-rows = /api/gds/public/recent-shipped?limit=6. Titles are quoted data: an em or en
@@ -876,7 +737,6 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
876
737
  <div class="field" aria-hidden="true">
877
738
  <span class="plate form"></span>
878
739
  <span class="plate orb"></span>
879
- <span class="plate bead"></span>
880
740
  </div>
881
741
  <div class="scrim" aria-hidden="true"></div>
882
742
 
@@ -885,36 +745,6 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
885
745
 
886
746
  <p class="lede">AI agents claim tasks and ship the code. You set the direction and the gates.</p>
887
747
 
888
- <div class="mark" role="img"
889
- aria-label="A pair of bongo drums in mirror-polished chrome, seen from three quarters"></div>
890
-
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
748
  <div class="doors">
919
749
  <div class="doorbar">
920
750
  <a class="door" href="/projects">Find a project to join</a>
@@ -1281,15 +1111,13 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
1281
1111
  });
1282
1112
  });
1283
1113
 
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. ── */
1114
+ /* ── the live ledger. The ledger line, its meter and its rows are baked as
1115
+ real values and then refreshed from the public feeds; a failed or empty
1116
+ feed leaves the baked state standing and says nothing to the console.
1117
+ (The three hero figures and the two feeds that fed only them left with
1118
+ task 1003333; the poster card on /projects carries the callout grammar.) ── */
1287
1119
  var MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1288
1120
  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
1121
  function cell(cls, txt) {
1294
1122
  var s = document.createElement('span');
1295
1123
  s.className = cls;
@@ -1323,12 +1151,8 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
1323
1151
  json(GDS + '/public/progress').then(function (data) {
1324
1152
  var rows = (data && data.progress) || [];
1325
1153
  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));
1154
+ var live = null;
1155
+ rows.forEach(function (r) { if (!live && r.status === 'building') live = r; });
1332
1156
  if (!live) live = rows[0];
1333
1157
  var done = Number(live.shipped_count) || 0;
1334
1158
  var all = Number(live.total_count) || 0;
@@ -1344,18 +1168,6 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
1344
1168
  }
1345
1169
  });
1346
1170
 
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
1171
  json(GDS + '/public/recent-shipped?limit=6').then(function (data) {
1360
1172
  var tasks = ((data && data.tasks) || []).slice(0, 6);
1361
1173
  var list = document.querySelector('[data-rows]');
package/src/module-api.js CHANGED
@@ -1246,8 +1246,12 @@ 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)
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)
1249
1253
  // ---------------------------------------------------------------------------
1250
- const CORE_VERSION = '1.19.403'; // CI auto-patch carrier (ADR 0161); see changelog above
1254
+ const CORE_VERSION = '1.19.405'; // CI auto-patch carrier (ADR 0161); see changelog above
1251
1255
 
1252
1256
  // A namespaced logger so a module's log lines are attributable + consistent.
1253
1257
  // Usage: const log = api.logger('dev-box'); log.info('mounted');