@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.
- package/.bongos-core.json +14 -14
- package/docs/adr/0196-chrome-world-token-contract-and-the-landing-sheets.md +2 -0
- package/docs/copy-inventory.md +78 -82
- package/docs/copy-registry.json +94 -130
- package/docs/design/landing-page-direction-v2.md +4 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/public-landing/index.html +80 -268
- package/src/module-api.js +5 -1
- package/tests/landing_page.mjs +98 -28
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
|
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
|
-
/*
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
|
236
|
-
|
|
237
|
-
|
|
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 .
|
|
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
|
|
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
|
|
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) *
|
|
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
|
|
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) *
|
|
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
|
|
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) *
|
|
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
|
|
740
|
-
choice: the two doors, joined, floating
|
|
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
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
the
|
|
747
|
-
|
|
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
|
|
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
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
a
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
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
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
the
|
|
775
|
-
|
|
776
|
-
|
|
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
|
|
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.
|
|
1285
|
-
|
|
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
|
|
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.
|
|
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');
|