@bongos/core 1.19.391 → 1.19.393
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 +53 -18
- package/clients/bongos-client/index.d.ts +1 -1
- package/docs/api/openapi.json +4 -0
- package/docs/api-reference.md +1 -1
- package/docs/design/mocks/hub/hub-sheet.html +192 -0
- package/docs/design/mocks/hub/v1.html +1209 -0
- package/docs/design/mocks/hub/v2.html +1257 -0
- package/docs/design/mocks/hub/v3.html +1496 -0
- package/docs/design/projects-hub-direction-v2.md +108 -0
- package/modules/platform-identity/migrations/platform_identity_011_project_visibility.sql +57 -0
- package/modules/platform-identity/platform-identity.js +73 -10
- package/modules/platform-identity/routes/projects.js +7 -1
- package/modules/platform-identity/tests/platform-identity.mjs +106 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/run-unit-tests.js +5 -0
- package/src/module-api.js +5 -1
- package/tests/project_visibility_db.mjs +175 -0
package/.bongos-core.json
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/gds/package-core.js",
|
|
5
|
-
"core_version": "1.19.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.393",
|
|
6
|
+
"core_contract": "1.19.393",
|
|
7
|
+
"source_commit": "e4673d8af6d2b24d57be0c3a9d31c15627ef07db",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-
|
|
9
|
+
"built_at": "2026-08-28T13:49:26.259Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
|
-
"docs_redacted":
|
|
12
|
+
"docs_redacted": 340,
|
|
13
13
|
"agent_docs_stubbed": 22,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 1630,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 1992,
|
|
20
|
+
"tree_sha256": "f327722f7c80662fb8f132891464528b071371bd874c73487b6f3a55b6424113",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -367,7 +367,7 @@
|
|
|
367
367
|
{
|
|
368
368
|
"path": "clients/bongos-client/index.d.ts",
|
|
369
369
|
"mode": "0000644",
|
|
370
|
-
"sha256": "
|
|
370
|
+
"sha256": "e2924c48715177477a8f828e2118f832acad6b3f63ae7b4fe5f124e80a4e7c17"
|
|
371
371
|
},
|
|
372
372
|
{
|
|
373
373
|
"path": "clients/bongos-client/index.mjs",
|
|
@@ -1487,12 +1487,12 @@
|
|
|
1487
1487
|
{
|
|
1488
1488
|
"path": "docs/api-reference.md",
|
|
1489
1489
|
"mode": "0000644",
|
|
1490
|
-
"sha256": "
|
|
1490
|
+
"sha256": "3e488311a87f4db6ffbb85b26c7a61fba0204ff6cc1cc8ab6c09b2ae21cea24b"
|
|
1491
1491
|
},
|
|
1492
1492
|
{
|
|
1493
1493
|
"path": "docs/api/openapi.json",
|
|
1494
1494
|
"mode": "0000644",
|
|
1495
|
-
"sha256": "
|
|
1495
|
+
"sha256": "6e93e2f283103158bc46062459b79b5528424ffb57f4730eb29a1cdba1b4976b"
|
|
1496
1496
|
},
|
|
1497
1497
|
{
|
|
1498
1498
|
"path": "docs/architecture.md",
|
|
@@ -1569,6 +1569,26 @@
|
|
|
1569
1569
|
"mode": "0000644",
|
|
1570
1570
|
"sha256": "c77dbf2152c6109b6ce925e2badf6dfaa74f74c2d0cb7eb76fa1101eec7b3310"
|
|
1571
1571
|
},
|
|
1572
|
+
{
|
|
1573
|
+
"path": "docs/design/mocks/hub/hub-sheet.html",
|
|
1574
|
+
"mode": "0000644",
|
|
1575
|
+
"sha256": "195002c1d320a42f15bcae68d38fd60d49facd339a34a32860b32cbebcbf15a7"
|
|
1576
|
+
},
|
|
1577
|
+
{
|
|
1578
|
+
"path": "docs/design/mocks/hub/v1.html",
|
|
1579
|
+
"mode": "0000644",
|
|
1580
|
+
"sha256": "a71d44848f98465aa5bfea1af4786c1c15841b94acd479a88f73260666812215"
|
|
1581
|
+
},
|
|
1582
|
+
{
|
|
1583
|
+
"path": "docs/design/mocks/hub/v2.html",
|
|
1584
|
+
"mode": "0000644",
|
|
1585
|
+
"sha256": "5ba56b1c17921bd19032d74e7547339946e260841889fc1af35d8e07c6962cf7"
|
|
1586
|
+
},
|
|
1587
|
+
{
|
|
1588
|
+
"path": "docs/design/mocks/hub/v3.html",
|
|
1589
|
+
"mode": "0000644",
|
|
1590
|
+
"sha256": "fe34413d588f2b1afd327a9246a8ce5c995cbe7e5e50232db8115d8e615b6c5d"
|
|
1591
|
+
},
|
|
1572
1592
|
{
|
|
1573
1593
|
"path": "docs/design/mocks/landing-page-mock.html",
|
|
1574
1594
|
"mode": "0000644",
|
|
@@ -1744,6 +1764,11 @@
|
|
|
1744
1764
|
"mode": "0000644",
|
|
1745
1765
|
"sha256": "8a8430af4bbf082d3bab28d5b82b353a6921782014c2852a87eb1056ba101722"
|
|
1746
1766
|
},
|
|
1767
|
+
{
|
|
1768
|
+
"path": "docs/design/projects-hub-direction-v2.md",
|
|
1769
|
+
"mode": "0000644",
|
|
1770
|
+
"sha256": "a29bd3d9cfe29b4eb7dff290134d818996f691e7669d7c8f1abee3c3fd57422b"
|
|
1771
|
+
},
|
|
1747
1772
|
{
|
|
1748
1773
|
"path": "docs/design/projects-hub-direction.md",
|
|
1749
1774
|
"mode": "0000644",
|
|
@@ -4679,6 +4704,11 @@
|
|
|
4679
4704
|
"mode": "0000644",
|
|
4680
4705
|
"sha256": "8f03dc84d8fe3864aa5f933512df71259c266e8a16214a926cf89eaf01cc5668"
|
|
4681
4706
|
},
|
|
4707
|
+
{
|
|
4708
|
+
"path": "modules/platform-identity/migrations/platform_identity_011_project_visibility.sql",
|
|
4709
|
+
"mode": "0000644",
|
|
4710
|
+
"sha256": "18e3641beba26d8a515616ba9bdb1bcc83151e620d6e038243d7d67850da3be8"
|
|
4711
|
+
},
|
|
4682
4712
|
{
|
|
4683
4713
|
"path": "modules/platform-identity/module.json",
|
|
4684
4714
|
"mode": "0000644",
|
|
@@ -4687,7 +4717,7 @@
|
|
|
4687
4717
|
{
|
|
4688
4718
|
"path": "modules/platform-identity/platform-identity.js",
|
|
4689
4719
|
"mode": "0000644",
|
|
4690
|
-
"sha256": "
|
|
4720
|
+
"sha256": "89672916aa04ee2246df97e008ff1b42cd2945321760452676b80b26301a4783"
|
|
4691
4721
|
},
|
|
4692
4722
|
{
|
|
4693
4723
|
"path": "modules/platform-identity/pollers/code-sweep.js",
|
|
@@ -4712,7 +4742,7 @@
|
|
|
4712
4742
|
{
|
|
4713
4743
|
"path": "modules/platform-identity/routes/projects.js",
|
|
4714
4744
|
"mode": "0000644",
|
|
4715
|
-
"sha256": "
|
|
4745
|
+
"sha256": "fc7be0e85b029ae4cd252ad9978bf64d481b743d1fc99143cf8c6bb250636bda"
|
|
4716
4746
|
},
|
|
4717
4747
|
{
|
|
4718
4748
|
"path": "modules/platform-identity/routes/public-profile.js",
|
|
@@ -4732,7 +4762,7 @@
|
|
|
4732
4762
|
{
|
|
4733
4763
|
"path": "modules/platform-identity/tests/platform-identity.mjs",
|
|
4734
4764
|
"mode": "0000644",
|
|
4735
|
-
"sha256": "
|
|
4765
|
+
"sha256": "dfb9a451afa52143f9d68aef371432e38b318d94fa83c8322f1dfd831780cd9c"
|
|
4736
4766
|
},
|
|
4737
4767
|
{
|
|
4738
4768
|
"path": "modules/platform-identity/ui/.gitkeep",
|
|
@@ -5122,12 +5152,12 @@
|
|
|
5122
5152
|
{
|
|
5123
5153
|
"path": "package-lock.json",
|
|
5124
5154
|
"mode": "0000644",
|
|
5125
|
-
"sha256": "
|
|
5155
|
+
"sha256": "e07dabb4292a7652cbd2f4bf6092eb6e4037693fcd55ee4964cb6b091749228d"
|
|
5126
5156
|
},
|
|
5127
5157
|
{
|
|
5128
5158
|
"path": "package.json",
|
|
5129
5159
|
"mode": "0000644",
|
|
5130
|
-
"sha256": "
|
|
5160
|
+
"sha256": "f8304e8d1f9338bccfae2cac3ea289dd58262eeccf5820857145a5490660a2e8"
|
|
5131
5161
|
},
|
|
5132
5162
|
{
|
|
5133
5163
|
"path": "public-docs/index.html",
|
|
@@ -6337,7 +6367,7 @@
|
|
|
6337
6367
|
{
|
|
6338
6368
|
"path": "scripts/gds/run-unit-tests.js",
|
|
6339
6369
|
"mode": "0000644",
|
|
6340
|
-
"sha256": "
|
|
6370
|
+
"sha256": "29ee6bd76bdfb65522170808b6e636032079a145df4f995570901fb4f05b6035"
|
|
6341
6371
|
},
|
|
6342
6372
|
{
|
|
6343
6373
|
"path": "scripts/gds/sandbox-stage.js",
|
|
@@ -7117,7 +7147,7 @@
|
|
|
7117
7147
|
{
|
|
7118
7148
|
"path": "src/module-api.js",
|
|
7119
7149
|
"mode": "0000644",
|
|
7120
|
-
"sha256": "
|
|
7150
|
+
"sha256": "14825991cbc68b5a14edfedbcb6ed78739254bc02ea966ce02516f65c9d5abc0"
|
|
7121
7151
|
},
|
|
7122
7152
|
{
|
|
7123
7153
|
"path": "src/module-loader/catalog.js",
|
|
@@ -9124,6 +9154,11 @@
|
|
|
9124
9154
|
"mode": "0000644",
|
|
9125
9155
|
"sha256": "6bd78c47b6dbbdd81f862df8afdc0b514e27f0ffb71d14161ac8feb19f9fbe19"
|
|
9126
9156
|
},
|
|
9157
|
+
{
|
|
9158
|
+
"path": "tests/project_visibility_db.mjs",
|
|
9159
|
+
"mode": "0000644",
|
|
9160
|
+
"sha256": "cf233daef30554217cfcde137ad0718e2bcef3f3504198769dea6448a90af3b0"
|
|
9161
|
+
},
|
|
9127
9162
|
{
|
|
9128
9163
|
"path": "tests/projects_hub.mjs",
|
|
9129
9164
|
"mode": "0000644",
|
|
@@ -296,7 +296,7 @@ export interface PostMyProjectsJoinRequest { origin: string }
|
|
|
296
296
|
export interface PostMyProjectsJoinResponse { ok: boolean; status: unknown; project: unknown; message: unknown }
|
|
297
297
|
export interface PostOverrideRequestsIdDecideRequest { decision: string; note?: string }
|
|
298
298
|
export interface PostProjectsInviteRequest { client_id: string; github_login: string }
|
|
299
|
-
export interface PostProjectsRequest { origin: string; name: string; tagline?: string; art_url?: string; type?: string }
|
|
299
|
+
export interface PostProjectsRequest { origin: string; name: string; tagline?: string; description?: string; art_url?: string; type?: string }
|
|
300
300
|
export interface PostProjectsResponse { project: unknown }
|
|
301
301
|
export interface PostProvisioningInstancesIdDomainRequest { domain: string }
|
|
302
302
|
export interface PostProvisioningInstancesIdDomainResponse { ok: boolean; changed: boolean; queued: unknown; domain: unknown; message: unknown }
|
package/docs/api/openapi.json
CHANGED
|
@@ -19040,6 +19040,10 @@
|
|
|
19040
19040
|
"type": "string",
|
|
19041
19041
|
"maxLength": 400
|
|
19042
19042
|
},
|
|
19043
|
+
"description": {
|
|
19044
|
+
"type": "string",
|
|
19045
|
+
"maxLength": 2000
|
|
19046
|
+
},
|
|
19043
19047
|
"art_url": {
|
|
19044
19048
|
"type": "string",
|
|
19045
19049
|
"maxLength": 2048
|
package/docs/api-reference.md
CHANGED
|
@@ -415,7 +415,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
415
415
|
| Method | Path | Rank | Body | Description |
|
|
416
416
|
|---|---|---|---|---|
|
|
417
417
|
| GET | `/api/bongos/projects` | `metic+archon` | — | the full curation list (includes unfeatured + owner attribution). |
|
|
418
|
-
| POST | `/api/bongos/projects` | `metic+archon` | `origin`, `name`, `tagline`, `art_url`, `type` | create / update a catalog entry (manual seed for hand-wired instances; federated projects auto-catalogue at registration). |
|
|
418
|
+
| POST | `/api/bongos/projects` | `metic+archon` | `origin`, `name`, `tagline`, `description`, `art_url`, `type` | create / update a catalog entry (manual seed for hand-wired instances; federated projects auto-catalogue at registration). |
|
|
419
419
|
| PATCH | `/api/bongos/projects/:id/featured` | `metic+archon` | `featured` | the feature / unfeature control (the ADR 0141 §5 curation gate). |
|
|
420
420
|
| GET | `/api/bongos/projects/featured` | `public` | — | a curated public showcase; no auth by design. |
|
|
421
421
|
| POST | `/api/bongos/projects/invite` | `metic+archon` | `client_id`, `github_login` | invite a builder into a project (ADR 0141 §5, task #1002115). |
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Hub composition round: bar, dropdowns, search and the poster card, three versions (task 1003299)</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root{--ink:#14151a;--soft:#585c6b;--faint:#8a8fa0;--line:#d9dce5;--bg:#f3f4f8;--card:#ffffff;--kick:#0b5fff;}
|
|
9
|
+
:root[data-mode="dark"]{--ink:#f1f2f7;--soft:#a9aec0;--faint:#737890;--line:#2a2e3b;--bg:#0c0e14;--card:#151822;--kick:#7aa2ff;}
|
|
10
|
+
@media (prefers-color-scheme:dark){:root:not([data-mode="light"]){--ink:#f1f2f7;--soft:#a9aec0;--faint:#737890;--line:#2a2e3b;--bg:#0c0e14;--card:#151822;--kick:#7aa2ff;}}
|
|
11
|
+
*{box-sizing:border-box;margin:0;padding:0}
|
|
12
|
+
body{background:var(--bg);color:var(--ink);font-family:system-ui,-apple-system,"Segoe UI",sans-serif;padding:clamp(18px,3vw,40px);-webkit-font-smoothing:antialiased;line-height:1.5}
|
|
13
|
+
h1{font-size:clamp(22px,3vw,32px);letter-spacing:-.4px;margin-bottom:6px}
|
|
14
|
+
.sub{color:var(--soft);max-width:100ch;font-size:14.5px;margin-bottom:8px}
|
|
15
|
+
.sub b{color:var(--ink)}
|
|
16
|
+
.read{border-left:3px solid var(--kick);padding:10px 14px;margin:14px 0 18px;font-size:14px;max-width:110ch;background:color-mix(in srgb,var(--kick) 7%,transparent);border-radius:0 8px 8px 0}
|
|
17
|
+
.read code{font-family:ui-monospace,Consolas,monospace;font-size:12.5px}
|
|
18
|
+
.read ol,.read ul{margin:6px 0 0 18px}
|
|
19
|
+
.bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:6px 0 22px;position:sticky;top:0;background:var(--bg);padding:10px 0;z-index:5;border-bottom:1px solid var(--line)}
|
|
20
|
+
.bar span{font-size:11px;letter-spacing:.6px;text-transform:uppercase;color:var(--faint);margin-left:10px}
|
|
21
|
+
.bar span:first-child{margin-left:0}
|
|
22
|
+
.bar button,.bar select{cursor:pointer;font:inherit;font-weight:600;font-size:13px;padding:6px 14px;border-radius:999px;border:1.5px solid var(--line);background:var(--card);color:var(--ink)}
|
|
23
|
+
.bar button[aria-pressed="true"]{background:var(--ink);color:var(--card);border-color:var(--ink)}
|
|
24
|
+
.cand{background:var(--card);border:1.5px solid var(--line);border-radius:16px;padding:16px 18px 18px;margin-bottom:22px}
|
|
25
|
+
.kick{font-size:11px;letter-spacing:.9px;text-transform:uppercase;color:var(--kick);font-weight:700}
|
|
26
|
+
.cand h2{font-size:20px;margin:2px 0 4px;letter-spacing:-.2px}
|
|
27
|
+
.meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:8px 22px;font-size:13.5px;color:var(--soft);margin:6px 0 12px}
|
|
28
|
+
.meta b{color:var(--ink);font-weight:600}
|
|
29
|
+
.meta ul{margin:2px 0 0 16px}
|
|
30
|
+
.tiles{display:grid;grid-template-columns:3fr 3fr 1fr 1fr;gap:12px;align-items:start;margin-bottom:12px}
|
|
31
|
+
.boards{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;align-items:start}
|
|
32
|
+
@media (max-width:1100px){.tiles{grid-template-columns:1fr 1fr}.boards{grid-template-columns:1fr}}
|
|
33
|
+
@media (max-width:640px){.tiles{grid-template-columns:1fr}}
|
|
34
|
+
.tile{border:1px solid var(--line);border-radius:10px;overflow:hidden;background:var(--bg)}
|
|
35
|
+
.tileHead{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:6px 10px;font-size:12px;color:var(--soft);border-bottom:1px solid var(--line)}
|
|
36
|
+
.tileHead a{color:var(--kick);font-weight:600;text-decoration:none;white-space:nowrap}
|
|
37
|
+
.frame{position:relative;width:100%;aspect-ratio:1440/900;overflow:hidden}
|
|
38
|
+
.frame iframe{position:absolute;top:0;left:0;width:1440px;height:900px;border:0;transform-origin:0 0}
|
|
39
|
+
.phone .frame{aspect-ratio:390/844}
|
|
40
|
+
.phone .frame iframe{width:390px;height:844px}
|
|
41
|
+
.tall .frame{aspect-ratio:1440/2400}
|
|
42
|
+
.tall .frame iframe{height:2400px}
|
|
43
|
+
.decide{border:1.5px solid var(--kick);border-radius:16px;padding:16px 18px;margin-bottom:22px;font-size:14px;max-width:120ch}
|
|
44
|
+
.decide h2{font-size:18px;margin-bottom:6px}
|
|
45
|
+
.decide ol,.decide ul{margin:6px 0 0 20px}
|
|
46
|
+
.decide li{margin:4px 0}
|
|
47
|
+
footer{color:var(--faint);font-size:12.5px;margin-top:28px}
|
|
48
|
+
</style>
|
|
49
|
+
<script>
|
|
50
|
+
(function(){try{var q=new URLSearchParams(location.search).get('mode');var m=(q==='light'||q==='dark')?q:'dark';document.documentElement.setAttribute('data-mode',m);}catch(e){}})();
|
|
51
|
+
</script>
|
|
52
|
+
</head>
|
|
53
|
+
<body>
|
|
54
|
+
|
|
55
|
+
<h1>The /projects hub in the chrome world: three versions of the bar, the dropdowns, the search and the poster card</h1>
|
|
56
|
+
<p class="sub">Round 4 of the apex pass (task 1003299, goal 1000080), after the landing was built and <code>DESIGN.md</code> recorded the world. Each version keeps the sky, the orbs, the hover card, the toolbar, the table (plus a hall glyph), the mine view and the new view exactly as they ship today, and recomposes what the owner settled: <b>one grounded top bar</b> (not sticky), the logo as home, a <b>Projects dropdown</b> holding Map / Your projects / New project, a <b>profile dropdown</b> on the identity chip, the <b>map search in the bar</b> (hidden off the map), no Home, no hall pill (hall entry becomes a per-project affordance), and the <b>poster card</b> with its degradation ladder. Mocks are judged <b>dark first</b>; flip to light. Open this sheet from the checkout that holds <code>docs/design/mocks/hub/</code>; the tiles are local iframes.</p>
|
|
57
|
+
|
|
58
|
+
<div class="read">
|
|
59
|
+
<b>How to read the three.</b> Same givens, same real data, same state contract, same sky. What differs is the bar's material, the menu's mechanism and the card's composition. <b>v1 "the shelf"</b>: the landing's pill grammar set down on a real shelf; floating card panels. <b>v2 "the hairline"</b>: no pills, hairlines only; the menu unfolds as a full-width band under the bar; the card's figures are leader-line callouts on the art. <b>v3 "the glass strip"</b>: one continuous glass surface the sky shows through; segments and attached glass panels; the card's name sits on the art. The state picker flips every version to the same state at once; <b>boards</b> show every bar state, the whole card ladder and the menu component on one tall page each. <code>open full</code> walks any state at full size.
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div class="decide" id="decision">
|
|
63
|
+
<h2>The decision this round asks of the owner</h2>
|
|
64
|
+
<ol>
|
|
65
|
+
<li><b>Pick one version</b> (or name a merge: for example v1's bar with v3's card).</li>
|
|
66
|
+
<li><b>Beyond the skin.</b> Each version's head comment lists what changes on the page beyond restyling, each item tagged <code>given</code> / <code>consequence</code> / <code>proposal</code>. The proposals are yours to take or leave; they are summarised per version below and in <code>docs/design/projects-hub-direction-v2.md</code>.</li>
|
|
67
|
+
<li><b>Two things the build needs that no feed carries yet</b> (not a design question, recorded so the pick is informed): the faces and the shipped-in-30-days figure need new enrichment fields; a per-project hall address is needed to know where the hall entry shows.</li>
|
|
68
|
+
</ol>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<div class="bar">
|
|
72
|
+
<span>mode</span>
|
|
73
|
+
<button data-md="dark" aria-pressed="true" type="button">dark</button>
|
|
74
|
+
<button data-md="light" aria-pressed="false" type="button">light</button>
|
|
75
|
+
<span>state</span>
|
|
76
|
+
<select id="statePick" aria-label="State shown in the first tile of every version">
|
|
77
|
+
<option value="in-map-projects">signed in, map, Projects menu open</option>
|
|
78
|
+
<option value="in-map">signed in, map</option>
|
|
79
|
+
<option value="out-map">signed out, map</option>
|
|
80
|
+
<option value="in-map-profile">signed in, profile menu open</option>
|
|
81
|
+
<option value="in-map-focus">keyboard focus in the menu</option>
|
|
82
|
+
<option value="in-map-search">search focused with a query</option>
|
|
83
|
+
<option value="in-mine">your projects (search hidden)</option>
|
|
84
|
+
<option value="in-new">new project (search hidden)</option>
|
|
85
|
+
<option value="out-new">signed out, new project</option>
|
|
86
|
+
<option value="in-table">table view with the hall glyph</option>
|
|
87
|
+
</select>
|
|
88
|
+
<span>card</span>
|
|
89
|
+
<select id="cardPick" aria-label="Card state shown in the second tile of every version">
|
|
90
|
+
<option value="card">the platform's own project, everything present</option>
|
|
91
|
+
<option value="card-member">Off the Boats: no art, a real zero, no hall entry</option>
|
|
92
|
+
<option value="card-noart">no art</option>
|
|
93
|
+
<option value="card-nofaces">no faces</option>
|
|
94
|
+
<option value="card-onefig">one figure</option>
|
|
95
|
+
<option value="card-nofig">no figures</option>
|
|
96
|
+
<option value="card-floor">everything null: today's card</option>
|
|
97
|
+
</select>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<section class="cand" id="v1">
|
|
101
|
+
<div class="kick">v1 · the shelf</div>
|
|
102
|
+
<h2>The landing's pill grammar, set down on a real shelf</h2>
|
|
103
|
+
<div class="meta"><div><b>The bar:</b> the landing's pills on a <code>bg-frame</code> shelf, 72px, hairline edge; the search a glass pill in the left group.</div><div><b>The menu:</b> a floating card panel, 240px, 8px under its trigger; the current view a 6px accent dot.</div><div><b>The card:</b> the poster as a stack: banner, disc, name, faces, a two-up figure band, hairline ledger rows, the landing's door bar.</div><div><b>Proposes:</b> About in the menu; the card at 560; Runs as the address; the empty state as a hairline; <code>not checked</code> for the status cell.</div></div>
|
|
104
|
+
<div class="tiles">
|
|
105
|
+
<div class="tile" data-v="v1" data-kind="state"><div class="tileHead"><span class="lab">in-map-projects</span><a class="open" href="v1.html?mode=dark&state=in-map-projects" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v1, the bar state picked above, 1440" loading="lazy"></iframe></div></div>
|
|
106
|
+
<div class="tile" data-v="v1" data-kind="card"><div class="tileHead"><span class="lab">card</span><a class="open" href="v1.html?mode=dark&state=card" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v1, the card state picked above, 1440" loading="lazy"></iframe></div></div>
|
|
107
|
+
<div class="tile phone" data-v="v1" data-kind="fixed" data-state="in-map-projects"><div class="tileHead"><span class="lab">390 · menu open</span><a class="open" href="v1.html?mode=dark&state=in-map-projects" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v1 at 390, the Projects menu open" loading="lazy"></iframe></div></div>
|
|
108
|
+
<div class="tile phone" data-v="v1" data-kind="fixed" data-state="card"><div class="tileHead"><span class="lab">390 · card</span><a class="open" href="v1.html?mode=dark&state=card" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v1 at 390, the card" loading="lazy"></iframe></div></div>
|
|
109
|
+
</div>
|
|
110
|
+
<div class="boards">
|
|
111
|
+
<div class="tile tall" data-v="v1" data-kind="fixed" data-state="board-bar"><div class="tileHead"><span class="lab">board · every bar state</span><a class="open" href="v1.html?mode=dark&state=board-bar" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v1, the bar states board" loading="lazy"></iframe></div></div>
|
|
112
|
+
<div class="tile tall" data-v="v1" data-kind="fixed" data-state="board-card"><div class="tileHead"><span class="lab">board · the card ladder</span><a class="open" href="v1.html?mode=dark&state=board-card" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v1, the card ladder board" loading="lazy"></iframe></div></div>
|
|
113
|
+
<div class="tile tall" data-v="v1" data-kind="fixed" data-state="board-menu"><div class="tileHead"><span class="lab">board · the menu and the search</span><a class="open" href="v1.html?mode=dark&state=board-menu" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v1, the menu component board" loading="lazy"></iframe></div></div>
|
|
114
|
+
</div>
|
|
115
|
+
</section>
|
|
116
|
+
|
|
117
|
+
<section class="cand" id="v2">
|
|
118
|
+
<div class="kick">v2 · the hairline</div>
|
|
119
|
+
<h2>Hairlines, not containers: the menu unfolds as a band under the bar</h2>
|
|
120
|
+
<div class="meta"><div><b>The bar:</b> no pills; the page ground closed by one hairline, 64px; a bare search field with a bottom hairline; lowercase text triggers, the open one underlined in the accent.</div><div><b>The menu:</b> a full-width band that unfolds under the bar and pushes the page down; three titled cells; the current one lit by a 2px accent hairline on top.</div><div><b>The card:</b> the specimen: the two figures as leader-line callouts on the art; a mono ledger; one accent door plus the hall as a text link.</div><div><b>Proposes:</b> the toolbar as a hairline row; the empty state as a band; About as a fourth cell; the card at 560; the under-24px controls floored.</div></div>
|
|
121
|
+
<div class="tiles">
|
|
122
|
+
<div class="tile" data-v="v2" data-kind="state"><div class="tileHead"><span class="lab">in-map-projects</span><a class="open" href="v2.html?mode=dark&state=in-map-projects" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v2, the bar state picked above, 1440" loading="lazy"></iframe></div></div>
|
|
123
|
+
<div class="tile" data-v="v2" data-kind="card"><div class="tileHead"><span class="lab">card</span><a class="open" href="v2.html?mode=dark&state=card" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v2, the card state picked above, 1440" loading="lazy"></iframe></div></div>
|
|
124
|
+
<div class="tile phone" data-v="v2" data-kind="fixed" data-state="in-map-projects"><div class="tileHead"><span class="lab">390 · menu open</span><a class="open" href="v2.html?mode=dark&state=in-map-projects" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v2 at 390, the Projects menu open" loading="lazy"></iframe></div></div>
|
|
125
|
+
<div class="tile phone" data-v="v2" data-kind="fixed" data-state="card"><div class="tileHead"><span class="lab">390 · card</span><a class="open" href="v2.html?mode=dark&state=card" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v2 at 390, the card" loading="lazy"></iframe></div></div>
|
|
126
|
+
</div>
|
|
127
|
+
<div class="boards">
|
|
128
|
+
<div class="tile tall" data-v="v2" data-kind="fixed" data-state="board-bar"><div class="tileHead"><span class="lab">board · every bar state</span><a class="open" href="v2.html?mode=dark&state=board-bar" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v2, the bar states board" loading="lazy"></iframe></div></div>
|
|
129
|
+
<div class="tile tall" data-v="v2" data-kind="fixed" data-state="board-card"><div class="tileHead"><span class="lab">board · the card ladder</span><a class="open" href="v2.html?mode=dark&state=board-card" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v2, the card ladder board" loading="lazy"></iframe></div></div>
|
|
130
|
+
<div class="tile tall" data-v="v2" data-kind="fixed" data-state="board-menu"><div class="tileHead"><span class="lab">board · the menu and the search</span><a class="open" href="v2.html?mode=dark&state=board-menu" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v2, the menu component board" loading="lazy"></iframe></div></div>
|
|
131
|
+
</div>
|
|
132
|
+
</section>
|
|
133
|
+
|
|
134
|
+
<section class="cand" id="v3">
|
|
135
|
+
<div class="kick">v3 · the glass strip</div>
|
|
136
|
+
<h2>One continuous glass surface the sky shows through</h2>
|
|
137
|
+
<div class="meta"><div><b>The bar:</b> one continuous glass plate over the sky, 64px; the search fused into it; the right end cut into three segments by hairlines.</div><div><b>The menu:</b> a card panel welded to the strip's bottom edge; the current view marked by an accent bar at its left.</div><div><b>The card:</b> the room: the name on the art's lower third over a card-ground scrim; a shelf line with the disc, the relationship and the faces; figures and facts as one hairline ledger; a full-width door bar.</div><div><b>Proposes:</b> the card at 640; the hover card on the panel's glass; search by tag; the table scrolling in its panel on a phone; the wizard's bongo pair on the chrome ramp; a rule for dark art on a paper card.</div></div>
|
|
138
|
+
<div class="tiles">
|
|
139
|
+
<div class="tile" data-v="v3" data-kind="state"><div class="tileHead"><span class="lab">in-map-projects</span><a class="open" href="v3.html?mode=dark&state=in-map-projects" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v3, the bar state picked above, 1440" loading="lazy"></iframe></div></div>
|
|
140
|
+
<div class="tile" data-v="v3" data-kind="card"><div class="tileHead"><span class="lab">card</span><a class="open" href="v3.html?mode=dark&state=card" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v3, the card state picked above, 1440" loading="lazy"></iframe></div></div>
|
|
141
|
+
<div class="tile phone" data-v="v3" data-kind="fixed" data-state="in-map-projects"><div class="tileHead"><span class="lab">390 · menu open</span><a class="open" href="v3.html?mode=dark&state=in-map-projects" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v3 at 390, the Projects menu open" loading="lazy"></iframe></div></div>
|
|
142
|
+
<div class="tile phone" data-v="v3" data-kind="fixed" data-state="card"><div class="tileHead"><span class="lab">390 · card</span><a class="open" href="v3.html?mode=dark&state=card" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v3 at 390, the card" loading="lazy"></iframe></div></div>
|
|
143
|
+
</div>
|
|
144
|
+
<div class="boards">
|
|
145
|
+
<div class="tile tall" data-v="v3" data-kind="fixed" data-state="board-bar"><div class="tileHead"><span class="lab">board · every bar state</span><a class="open" href="v3.html?mode=dark&state=board-bar" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v3, the bar states board" loading="lazy"></iframe></div></div>
|
|
146
|
+
<div class="tile tall" data-v="v3" data-kind="fixed" data-state="board-card"><div class="tileHead"><span class="lab">board · the card ladder</span><a class="open" href="v3.html?mode=dark&state=board-card" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v3, the card ladder board" loading="lazy"></iframe></div></div>
|
|
147
|
+
<div class="tile tall" data-v="v3" data-kind="fixed" data-state="board-menu"><div class="tileHead"><span class="lab">board · the menu and the search</span><a class="open" href="v3.html?mode=dark&state=board-menu" target="_blank" rel="noopener">open full</a></div><div class="frame"><iframe title="v3, the menu component board" loading="lazy"></iframe></div></div>
|
|
148
|
+
</div>
|
|
149
|
+
</section>
|
|
150
|
+
|
|
151
|
+
<footer>Task 1003299 · goal 1000080 · mocks under <code>docs/design/mocks/hub/</code> · the world: <code>DESIGN.md</code>, ADR 0196 · the record: <code>docs/design/projects-hub-direction-v2.md</code>.</footer>
|
|
152
|
+
|
|
153
|
+
<script>
|
|
154
|
+
(function () {
|
|
155
|
+
var mode = document.documentElement.getAttribute('data-mode') || 'dark';
|
|
156
|
+
var state = 'in-map-projects', card = 'card';
|
|
157
|
+
function src(v, st) { return v + '.html?mode=' + mode + '&state=' + st; }
|
|
158
|
+
function paint() {
|
|
159
|
+
document.querySelectorAll('.tile[data-v]').forEach(function (t) {
|
|
160
|
+
var v = t.getAttribute('data-v'), kind = t.getAttribute('data-kind');
|
|
161
|
+
var st = kind === 'state' ? state : kind === 'card' ? card : t.getAttribute('data-state');
|
|
162
|
+
var f = t.querySelector('iframe'), a = t.querySelector('a.open');
|
|
163
|
+
var u = src(v, st);
|
|
164
|
+
if (f.getAttribute('src') !== u) f.setAttribute('src', u);
|
|
165
|
+
if (a) a.setAttribute('href', u);
|
|
166
|
+
var lab = t.querySelector('.lab'); if (lab && (kind === 'state' || kind === 'card')) lab.textContent = st;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
document.querySelectorAll('.bar button[data-md]').forEach(function (b) {
|
|
170
|
+
b.addEventListener('click', function () {
|
|
171
|
+
mode = b.getAttribute('data-md');
|
|
172
|
+
document.documentElement.setAttribute('data-mode', mode);
|
|
173
|
+
document.querySelectorAll('.bar button[data-md]').forEach(function (x) { x.setAttribute('aria-pressed', String(x === b)); });
|
|
174
|
+
paint();
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
document.getElementById('statePick').addEventListener('change', function (e) { state = e.target.value; paint(); });
|
|
178
|
+
document.getElementById('cardPick').addEventListener('change', function (e) { card = e.target.value; paint(); });
|
|
179
|
+
function scale() {
|
|
180
|
+
document.querySelectorAll('.frame').forEach(function (fr) {
|
|
181
|
+
var f = fr.querySelector('iframe'); if (!f) return;
|
|
182
|
+
var w = parseFloat(f.style.width || f.getAttribute('width')) || (fr.closest('.phone') ? 390 : 1440);
|
|
183
|
+
f.style.transform = 'scale(' + (fr.clientWidth / w) + ')';
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
window.addEventListener('resize', scale);
|
|
187
|
+
paint(); scale();
|
|
188
|
+
window.addEventListener('load', scale);
|
|
189
|
+
})();
|
|
190
|
+
</script>
|
|
191
|
+
</body>
|
|
192
|
+
</html>
|