@bongos/core 1.19.725 → 1.19.727
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 +179 -494
- package/.devcontainer/Dockerfile +1 -1
- package/.devcontainer/devcontainer.json +2 -2
- package/.devcontainer/healthcheck.sh +1 -1
- package/.devcontainer/init-firewall.sh +1 -1
- package/.devcontainer/post-create.sh +2 -2
- package/.env.local.example +1 -1
- package/Dockerfile +1 -1
- package/docs/copy-inventory.md +1 -1
- package/docs/copy-registry.json +9 -9
- package/docs/module-api-changelog.md +4 -0
- package/docs/recipes/devbox-app-release.md +4 -4
- package/modules/dev-box/app/scripts/dmgbuild-settings.py +5 -5
- package/modules/dev-box/app/scripts/gen-brand.js +1 -1
- package/modules/dev-box/app/src/brand.js +1 -1
- package/modules/dev-box/app/test/unit.mjs +16 -16
- package/modules/dev-box/box-access.js +1 -1
- package/modules/dev-box/routes/box.js +1 -1
- package/modules/discord/discord-approvals.js +1 -1
- package/modules/grading/grader-model.js +1 -1
- package/modules/grading/grader-prompt.js +1 -1
- package/modules/grading/grader-workers/quality.js +1 -1
- package/modules/hall-ui/module.json +1 -1
- package/modules/hall-ui/public/brand-apply.js +1 -1
- package/modules/hall-ui/public/shell.js +1 -1
- package/modules/hall-ui/public/work.js +1 -1
- package/modules/lifecycle/conflict-resolve.js +1 -1
- package/modules/lifecycle/db-analytics.js +1 -1
- package/modules/lifecycle/routes/analytics.js +1 -1
- package/modules/onboarding/approval-broadcast.js +1 -1
- package/modules/onboarding/onboarding.js +1 -1
- package/modules/provisioning/tests/liveness.mjs +1 -1
- package/modules/public-landing/public/index.html +1 -1
- package/modules/public-landing/public/projects-floor.states.json +2 -2
- package/modules/public-landing/public/projects.probes.json +4 -4
- package/modules/public-landing/public/projects.states.json +2 -2
- package/modules/status-ui/module.json +1 -1
- package/modules/status-ui/public/status.js +4 -4
- package/modules/status-ui/public/style.css +1 -1
- package/modules/ui-design/kit/fixtures/cost-summary.json +1 -1
- package/modules/ui-design/kit/fixtures/featured-hub.json +1 -1
- package/modules/ui-design/kit/fixtures/featured.json +1 -1
- package/modules/ui-design/kit/fixtures/leaderboard.json +1 -1
- package/modules/ui-design/kit/fixtures/my-projects.json +1 -1
- package/modules/ui-design/kit/fixtures/progress.json +1 -1
- package/modules/ui-design/kit/fixtures/recent-shipped.json +1 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/cron/style_guide_audit.sh +1 -1
- package/scripts/discord/lib.js +1 -1
- package/scripts/discord/post.js +1 -1
- package/scripts/gds/audit-authorship.sh +1 -1
- package/scripts/gds/audit-replay.sh +29 -2
- package/scripts/gds/audit-ships.js +1 -1
- package/scripts/gds/backfill-sessions.js +2 -2
- package/scripts/gds/cf-tunnel.js +4 -4
- package/scripts/gds/claude-materialize.js +2 -2
- package/scripts/gds/cli-lib.js +6 -6
- package/scripts/gds/cutover-codemod.js +1 -1
- package/scripts/gds/dev-lib.js +2 -2
- package/scripts/gds/diagnose-achievements.js +2 -2
- package/scripts/gds/fitness-checks-identity.js +6 -4
- package/scripts/gds/gate-review.js +14 -6
- package/scripts/gds/gen-diagrams.js +1 -1
- package/scripts/gds/leak-scan-allowlist.js +293 -0
- package/scripts/gds/learning-capture.js +1 -1
- package/scripts/gds/linkify-refs.js +2 -2
- package/scripts/gds/local-preview-lib.js +1 -1
- package/scripts/gds/mirror-lineage-check.js +1 -1
- package/scripts/gds/mirror-redact.js +17 -2
- package/scripts/gds/newcomer-floor.templates.json +1 -1
- package/scripts/gds/package-core.js +18 -1
- package/scripts/gds/paste-token.js +1 -1
- package/scripts/gds/provision-units.js +2 -2
- package/scripts/gds/publish-manifest.js +15 -0
- package/scripts/gds/repo-metrics.js +1 -1
- package/scripts/gds/sandbox-stage.js +1 -1
- package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +1 -1
- package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +1 -1
- package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +1 -1
- package/scripts/gds/seed-bongos-tasks.js +2 -2
- package/scripts/gds/seed-gds-v4-tasks.js +1 -1
- package/scripts/gds/seed-medusa-tasks.js +10 -10
- package/scripts/gds/seed-module-upstreaming.js +1 -1
- package/scripts/gds/seed-productization-tasks.js +6 -6
- package/scripts/gds/seed-provisioning-tasks.js +2 -2
- package/scripts/gds/seed-staging.sh +19 -6
- package/scripts/gds/ship-deploy-target.js +1 -1
- package/scripts/gds/ship-flow.js +1 -1
- package/scripts/gds/smoke-gds.js +1 -1
- package/scripts/status-probe.mjs +2 -2
- package/src/bongos/auth-discord.js +2 -2
- package/src/bongos/live-channel.js +1 -1
- package/src/bongos/permission-path-check.js +80 -3
- package/src/bongos/pool.js +1 -1
- package/src/bongos/routes/auth.js +11 -11
- package/src/bongos/routes/security.js +1 -1
- package/src/bongos/routes.js +1 -1
- package/src/branding.js +1 -1
- package/src/devbox-downloads.js +1 -1
- package/src/instance-config.js +2 -2
- package/src/module-api.js +1 -1
- package/src/module-loader/provenance.js +2 -2
- package/tests/art_stage.mjs +2 -2
- package/tests/auth_anthropic_identity.mjs +1 -1
- package/tests/auth_duplicate_cookie.mjs +1 -1
- package/tests/auth_error_brand.mjs +1 -1
- package/tests/auth_inactive_builder.mjs +1 -1
- package/tests/backup_cli.mjs +4 -4
- package/tests/bongos_box_connect.mjs +2 -2
- package/tests/bongos_downloads.mjs +2 -2
- package/tests/bongos_login.mjs +5 -5
- package/tests/box_connect_e2e.mjs +2 -2
- package/tests/box_dns_repoint.mjs +10 -10
- package/tests/box_host_keys.mjs +1 -1
- package/tests/box_onboard.mjs +9 -9
- package/tests/box_scope_session.mjs +1 -1
- package/tests/box_terminal_ssrf.mjs +7 -7
- package/tests/boxes.mjs +9 -9
- package/tests/branding.mjs +2 -2
- package/tests/bump_version.mjs +2 -2
- package/tests/cf_tunnel.mjs +40 -40
- package/tests/cli_token_reissue.mjs +7 -7
- package/tests/cloud_bongos_pack.mjs +1 -1
- package/tests/currency_label.mjs +8 -8
- package/tests/dev_lib.mjs +4 -4
- package/tests/devbox_dmg_backdrop.mjs +1 -1
- package/tests/devbox_downloads.mjs +2 -2
- package/tests/devbox_icons.mjs +1 -1
- package/tests/discord_approvals.mjs +1 -1
- package/tests/discord_oauth.mjs +2 -2
- package/tests/executed_closure.mjs +6 -1
- package/tests/first_admin_bootstrap.mjs +1 -1
- package/tests/gate_approvals.mjs +5 -5
- package/tests/government_protected_surfaces.mjs +137 -0
- package/tests/grade_aggregates_unavailable.mjs +1 -1
- package/tests/hook_user_agents.mjs +2 -2
- package/tests/init.mjs +6 -6
- package/tests/instance_config.mjs +1 -1
- package/tests/instance_manifest.mjs +5 -5
- package/tests/instance_mismatch_guard.mjs +13 -13
- package/tests/leak_scan_allowlist.mjs +94 -0
- package/tests/migrate_root_resolution.mjs +4 -4
- package/tests/mirror_redact.mjs +28 -4
- package/tests/module_catalog.mjs +5 -5
- package/tests/module_submissions.mjs +3 -3
- package/tests/package_core.mjs +1 -1
- package/tests/parallel-load.mjs +6 -6
- package/tests/projects_hub.mjs +2 -2
- package/tests/provision.mjs +50 -50
- package/tests/provisioning_github_app_routes.mjs +1 -1
- package/tests/provisioning_onboard_mode.mjs +2 -2
- package/tests/publish_reconciler.mjs +4 -4
- package/tests/sandbox_stage.mjs +1 -1
- package/tests/scrubber_corpus.mjs +3 -3
- package/tests/search_isolation.mjs +1 -1
- package/tests/session_records.mjs +1 -1
- package/tests/ship_card.mjs +6 -6
- package/tests/ship_ci_deploy.mjs +1 -1
- package/tests/single_host_hall.mjs +9 -9
- package/tests/smoke_preflight.mjs +1 -1
- package/tests/smoke_target.mjs +1 -1
- package/tests/status-probe.mjs +1 -1
- package/tests/status_mirror_sync.mjs +1 -1
- package/docs/adr/0004-amazonprimea-name-and-trademark-acceptance.md +0 -45
- package/docs/design/mocks/_schemes.css +0 -604
- package/docs/design/mocks/component-sheet.html +0 -428
- package/docs/design/mocks/hall/_tokens.css +0 -370
- package/docs/design/mocks/hall/board/v1.html +0 -846
- package/docs/design/mocks/hall/board/v2.html +0 -858
- package/docs/design/mocks/hall/board/v3.html +0 -884
- package/docs/design/mocks/hall/goals/v1.html +0 -1212
- package/docs/design/mocks/hall/goals/v2.html +0 -1192
- package/docs/design/mocks/hall/goals/v3.html +0 -1205
- package/docs/design/mocks/hall/hall-sheet.html +0 -244
- package/docs/design/mocks/hall/reading/v1.html +0 -1125
- package/docs/design/mocks/hall/reading/v2.html +0 -1177
- package/docs/design/mocks/hall/reading/v3.html +0 -1150
- package/docs/design/mocks/hall/settings/v1.html +0 -1238
- package/docs/design/mocks/hall/settings/v2.html +0 -1235
- package/docs/design/mocks/hall/settings/v3.html +0 -1299
- package/docs/design/mocks/hall/task/v1.html +0 -633
- package/docs/design/mocks/hall/task/v2.html +0 -646
- package/docs/design/mocks/hall/task/v3.html +0 -647
- package/docs/design/mocks/hub/assets/r3-space-deepfield-half.jpg +0 -0
- package/docs/design/mocks/hub/assets/r3-space-deepfield-half.jpg.json +0 -13
- package/docs/design/mocks/hub/assets/r3-space-dust-half.jpg +0 -0
- package/docs/design/mocks/hub/assets/r3-space-dust-half.jpg.json +0 -13
- package/docs/design/mocks/hub/assets/r3-space-nebula-half.jpg +0 -0
- package/docs/design/mocks/hub/assets/r3-space-nebula-half.jpg.json +0 -13
- package/docs/design/mocks/hub/assets/r3-space-starfield-half.jpg +0 -0
- package/docs/design/mocks/hub/assets/r3-space-starfield-half.jpg.json +0 -13
- package/docs/design/mocks/hub/hub-sheet.html +0 -192
- package/docs/design/mocks/hub/mine.html +0 -465
- package/docs/design/mocks/hub/picker.html +0 -421
- package/docs/design/mocks/hub/planets.html +0 -356
- package/docs/design/mocks/hub/v1.html +0 -1209
- package/docs/design/mocks/hub/v2.html +0 -1257
- package/docs/design/mocks/hub/v3.html +0 -1496
- package/docs/design/mocks/hub/wizard.html +0 -421
- package/docs/design/mocks/landing/landing-sheet.html +0 -131
- package/docs/design/mocks/landing/v1.html +0 -956
- package/docs/design/mocks/landing/v2.html +0 -708
- package/docs/design/mocks/landing/v3.html +0 -911
- package/docs/design/mocks/landing-page-mock.html +0 -687
- package/docs/design/mocks/landing-palettes.html +0 -103
- package/docs/design/mocks/projects-hub-mock.html +0 -991
- package/docs/design/mocks/projects-hub-variants.html +0 -146
- package/docs/design/mocks/projects-page-mock.html +0 -167
- package/docs/design/mocks/world/blue-hud/_tokens.css +0 -246
- package/docs/design/mocks/world/blue-hud/hall.html +0 -595
- package/docs/design/mocks/world/blue-hud/landing.html +0 -424
- package/docs/design/mocks/world/blue-hud/status.html +0 -410
- package/docs/design/mocks/world/chrome-blobs/_tokens.css +0 -479
- package/docs/design/mocks/world/chrome-blobs/hall.html +0 -553
- package/docs/design/mocks/world/chrome-blobs/landing-b.html +0 -581
- package/docs/design/mocks/world/chrome-blobs/landing.html +0 -328
- package/docs/design/mocks/world/chrome-blobs/status.html +0 -416
- package/docs/design/mocks/world/natgeo-editorial/_tokens.css +0 -377
- package/docs/design/mocks/world/natgeo-editorial/hall.html +0 -649
- package/docs/design/mocks/world/natgeo-editorial/landing-b.html +0 -743
- package/docs/design/mocks/world/natgeo-editorial/landing.html +0 -475
- package/docs/design/mocks/world/natgeo-editorial/status.html +0 -437
- package/docs/design/mocks/world/organic-cards/_tokens.css +0 -462
- package/docs/design/mocks/world/organic-cards/hall.html +0 -625
- package/docs/design/mocks/world/organic-cards/landing-b.html +0 -736
- package/docs/design/mocks/world/organic-cards/landing.html +0 -420
- package/docs/design/mocks/world/organic-cards/status.html +0 -458
- package/docs/design/mocks/world/world-sheet.html +0 -156
|
@@ -1,1257 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<script>
|
|
6
|
-
(function(){try{var q=new URLSearchParams(location.search || location.hash.slice(1) || (window.__Q || '')).get('mode');var m=(q==='light'||q==='dark')?q:localStorage.getItem('cb-color-mode');if(m==='light'||m==='dark')document.documentElement.setAttribute('data-mode',m);}catch(e){}})();
|
|
7
|
-
</script>
|
|
8
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
9
|
-
<title>The project map, Cloud Bongos</title>
|
|
10
|
-
<link rel="icon" href="data:,">
|
|
11
|
-
|
|
12
|
-
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
13
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
14
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400&family=Manrope:wght@300;400;500;600&display=swap">
|
|
15
|
-
<link rel="stylesheet" href="../../../../modules/public-landing/public/assets/cosmos.css">
|
|
16
|
-
<style>
|
|
17
|
-
body{
|
|
18
|
-
/* v2 "the hairline" — the world's derived tier for this surface, by the recipes in DESIGN.md's
|
|
19
|
-
frontmatter and the same derived names the landing's own sheet uses. cosmos.css already carries the fifteen contract
|
|
20
|
-
tokens in both modes and owns --line (a hairline COLOUR here) and --ok/--warn/--err (the hub's
|
|
21
|
-
fixed status vocabulary); none of those four is restated. --accent-on, --accent-soft, --card and
|
|
22
|
-
--ctl-line are cosmos's too and are taken, not redeclared. */
|
|
23
|
-
--glass:color-mix(in srgb,var(--ink) 5%,transparent);
|
|
24
|
-
--glass-strong:color-mix(in srgb,var(--ink) 8%,transparent);
|
|
25
|
-
--glass-edge:color-mix(in srgb,var(--ink) 12%,transparent);
|
|
26
|
-
--accent-lift:color-mix(in srgb,var(--accent) 58%,#ffffff);
|
|
27
|
-
--void-pill:rgba(0,0,0,.55);
|
|
28
|
-
--void-ink:#ffffff;
|
|
29
|
-
--focus:var(--accent-deep);
|
|
30
|
-
--type-halo:none;
|
|
31
|
-
--label-face:var(--font-mono);
|
|
32
|
-
--label-size:11px;
|
|
33
|
-
--label-space:.12em;
|
|
34
|
-
--radius:16px;
|
|
35
|
-
--radius-sm:10px;
|
|
36
|
-
--radius-pill:999px;
|
|
37
|
-
--top-h:64px;
|
|
38
|
-
--gutter:clamp(16px,4vw,34px);
|
|
39
|
-
--leader-len:68px;
|
|
40
|
-
}
|
|
41
|
-
:root[data-mode="dark"] body{
|
|
42
|
-
--glass:rgba(255,255,255,.11);
|
|
43
|
-
--glass-strong:rgba(255,255,255,.17);
|
|
44
|
-
--glass-edge:rgba(255,255,255,.13);
|
|
45
|
-
--focus:var(--accent);
|
|
46
|
-
--type-halo:0 2px 18px rgba(0,0,0,.94),0 0 54px rgba(0,0,0,.72);
|
|
47
|
-
--label-face:var(--font-body);
|
|
48
|
-
--label-size:11.5px;
|
|
49
|
-
--label-space:.1em;
|
|
50
|
-
}
|
|
51
|
-
@media (prefers-color-scheme:dark){
|
|
52
|
-
:root:not([data-mode="light"]) body{
|
|
53
|
-
--glass:rgba(255,255,255,.11);
|
|
54
|
-
--glass-strong:rgba(255,255,255,.17);
|
|
55
|
-
--glass-edge:rgba(255,255,255,.13);
|
|
56
|
-
--focus:var(--accent);
|
|
57
|
-
--type-halo:0 2px 18px rgba(0,0,0,.94),0 0 54px rgba(0,0,0,.72);
|
|
58
|
-
--label-face:var(--font-body);
|
|
59
|
-
--label-size:11.5px;
|
|
60
|
-
--label-space:.1em;
|
|
61
|
-
}
|
|
62
|
-
:root:not([data-mode="light"]) .sun{display:block}
|
|
63
|
-
:root:not([data-mode="light"]) .moon{display:none}
|
|
64
|
-
}
|
|
65
|
-
:root[data-mode="dark"] .sun{display:block}
|
|
66
|
-
:root[data-mode="dark"] .moon{display:none}
|
|
67
|
-
.sun{display:none}
|
|
68
|
-
|
|
69
|
-
/* the two-tone ring, on every control, menu item and the search field. .is-focus paints the same
|
|
70
|
-
declaration so a query string can show a ring :focus-visible cannot be forced into. */
|
|
71
|
-
:focus-visible,.trig.is-focus,.bandT.is-focus,.qWrap.is-focus .qField,.qField:focus-within{outline:2px solid var(--focus);outline-offset:3px;box-shadow:0 0 0 8px var(--bg)}
|
|
72
|
-
.qInput:focus-visible{outline:none;box-shadow:none}
|
|
73
|
-
.skip{position:absolute;left:-9999px;top:0;z-index:100;min-height:24px;display:inline-flex;align-items:center;
|
|
74
|
-
padding:11px 18px;border-radius:var(--radius-pill);background:var(--bg-card);color:var(--ink);
|
|
75
|
-
border:1px solid var(--rule);font-size:15px;text-decoration:none}
|
|
76
|
-
.skip:focus{left:14px;top:14px}
|
|
77
|
-
main:focus{outline:none;box-shadow:none}
|
|
78
|
-
.ic{fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round}
|
|
79
|
-
|
|
80
|
-
/* ============ THE BAR: no pill. the page ground, closed by one hairline. ============ */
|
|
81
|
-
.bar{position:relative;z-index:40;display:flex;align-items:center;gap:22px;height:var(--top-h);
|
|
82
|
-
padding:0 var(--gutter);background:var(--bg);border-bottom:1px solid var(--rule)}
|
|
83
|
-
.barLeft{display:flex;align-items:center;gap:26px;flex:1 1 auto;min-width:0}
|
|
84
|
-
.barRight{display:flex;align-items:center;gap:20px;flex:none}
|
|
85
|
-
.barMark{display:inline-flex;align-items:center;gap:10px;min-height:44px;flex:none;
|
|
86
|
-
font-family:var(--font-display);font-size:17px;font-weight:500;letter-spacing:-.015em;color:var(--ink);
|
|
87
|
-
text-decoration:none;text-shadow:var(--type-halo)}
|
|
88
|
-
.barMark svg{width:23px;height:18px;display:block;flex:none}
|
|
89
|
-
.barMark:hover{color:var(--ink)}
|
|
90
|
-
|
|
91
|
-
/* the search: no field chrome, one bottom hairline that takes the ink on focus */
|
|
92
|
-
.qWrap{display:flex;align-items:baseline;gap:12px;flex:0 1 340px;min-width:0;
|
|
93
|
-
border-radius:var(--radius-sm)}
|
|
94
|
-
.qField{flex:1 1 auto;min-width:0;display:flex;align-items:center;min-height:44px;
|
|
95
|
-
border-bottom:1px solid var(--rule);transition:border-color 200ms cubic-bezier(.2,.7,.3,1)}
|
|
96
|
-
.qWrap:focus-within .qField,.qWrap.is-focus .qField{border-bottom-color:var(--ink)}
|
|
97
|
-
.qInput{width:100%;min-width:0;min-height:32px;padding:0 0 4px;background:none;border:0;outline:none;
|
|
98
|
-
color:var(--ink);font-family:var(--label-face);font-size:13px;letter-spacing:.01em}
|
|
99
|
-
.qInput::placeholder{color:var(--ink-faint);font-family:var(--label-face)}
|
|
100
|
-
.qIcon{display:none;flex:none;width:17px;height:17px;margin-right:8px;color:var(--ink-faint)}
|
|
101
|
-
.qCount{flex:none;font-family:var(--font-mono);font-size:11.5px;color:var(--ink-faint);
|
|
102
|
-
font-variant-numeric:tabular-nums;white-space:nowrap}
|
|
103
|
-
/* under 480 the field folds into this magnifier (see the 480 query); above it, never shown */
|
|
104
|
-
.qToggle{display:none;align-items:center;justify-content:center;width:44px;height:44px;flex:none;
|
|
105
|
-
cursor:pointer;background:none;border:0;border-radius:var(--radius-pill);color:var(--ink-soft);
|
|
106
|
-
transition:color 200ms cubic-bezier(.2,.7,.3,1)}
|
|
107
|
-
.qToggle svg{width:19px;height:19px}
|
|
108
|
-
.qToggle:hover,.qToggle[aria-expanded="true"]{color:var(--ink)}
|
|
109
|
-
|
|
110
|
-
/* the right group is lowercase text; the OPEN trigger is underlined in the accent, because an
|
|
111
|
-
open menu is the live thing on the bar */
|
|
112
|
-
.trig{display:inline-flex;align-items:center;gap:7px;min-height:44px;padding:0;cursor:pointer;
|
|
113
|
-
background:none;border:0;border-radius:var(--radius-sm);
|
|
114
|
-
font-family:var(--font-body);font-size:15px;font-weight:400;text-transform:lowercase;
|
|
115
|
-
color:var(--ink-soft);transition:color 200ms cubic-bezier(.2,.7,.3,1)}
|
|
116
|
-
.trig:hover,.trig.is-hover{color:var(--ink)}
|
|
117
|
-
.trig[aria-expanded="true"]{color:var(--ink);text-decoration:underline;text-decoration-color:var(--accent);
|
|
118
|
-
text-decoration-thickness:2px;text-underline-offset:7px}
|
|
119
|
-
.trig .cv{width:13px;height:13px;flex:none;transition:transform 200ms cubic-bezier(.2,.7,.3,1)}
|
|
120
|
-
.trig[aria-expanded="true"] .cv{transform:rotate(180deg)}
|
|
121
|
-
.whoTrig{gap:9px}
|
|
122
|
-
.whoTrig img{width:26px;height:26px;border-radius:var(--radius-pill);object-fit:cover;flex:none;
|
|
123
|
-
border:1px solid var(--rule)}
|
|
124
|
-
.whoName{max-width:14ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
125
|
-
.modeBtn{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;
|
|
126
|
-
cursor:pointer;background:none;border:0;border-radius:var(--radius-pill);color:var(--ink-soft);
|
|
127
|
-
transition:color 200ms cubic-bezier(.2,.7,.3,1)}
|
|
128
|
-
.modeBtn:hover{color:var(--ink)}
|
|
129
|
-
.modeBtn svg{width:20px;height:20px}
|
|
130
|
-
/* the one filled shape on a bar with no pills */
|
|
131
|
-
.signinDoor{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 26px;
|
|
132
|
-
border-radius:var(--radius-pill);background:color-mix(in srgb,var(--ink) 92%,var(--bg));color:var(--bg);
|
|
133
|
-
font-size:15px;font-weight:500;text-transform:lowercase;text-decoration:none;
|
|
134
|
-
transition:background 200ms cubic-bezier(.2,.7,.3,1)}
|
|
135
|
-
.signinDoor:hover{background:var(--ink)}
|
|
136
|
-
|
|
137
|
-
/* ============ THE BAND: the menu is not a floating card. it unfolds under the bar's edge,
|
|
138
|
-
full width, and pushes the page down. ============ */
|
|
139
|
-
.band{position:relative;z-index:39;background:var(--bg-card);border-bottom:1px solid var(--rule);
|
|
140
|
-
animation:bandIn 220ms cubic-bezier(.16,1,.3,1) both}
|
|
141
|
-
@keyframes bandIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
|
|
142
|
-
.bandIn{padding:20px var(--gutter) 28px}
|
|
143
|
-
.bandRow{display:grid;grid-template-columns:repeat(3,1fr);gap:0 34px;list-style:none;margin:0;padding:0}
|
|
144
|
-
.bandCell{position:relative;border-top:1px solid var(--rule-soft);padding:15px 0 0}
|
|
145
|
-
.bandCell.is-now::before{content:"";position:absolute;left:0;right:0;top:-1px;height:2px;background:var(--accent)}
|
|
146
|
-
.bandT{display:inline-block;padding:2px 0;font-family:var(--font-display);font-size:24px;
|
|
147
|
-
font-weight:300;line-height:1.14;letter-spacing:-.03em;text-transform:lowercase;
|
|
148
|
-
color:var(--ink-soft);text-decoration:none;transition:color 200ms cubic-bezier(.2,.7,.3,1)}
|
|
149
|
-
.bandT::after{content:"";position:absolute;inset:0}
|
|
150
|
-
.bandCell.is-now .bandT,.bandCell:hover .bandT,.bandCell.is-hover .bandT{color:var(--ink)}
|
|
151
|
-
.bandCell:hover,.bandCell.is-hover{border-top-color:var(--ink-faint)}
|
|
152
|
-
.bandC{display:block;margin-top:5px;font-size:13.5px;line-height:1.45;color:var(--ink-soft)}
|
|
153
|
-
.bandProfile{display:flex;align-items:flex-end;justify-content:space-between;gap:34px;flex-wrap:wrap}
|
|
154
|
-
.bandWho{display:flex;align-items:center;gap:10px;padding-top:15px;border-top:1px solid var(--rule-soft);
|
|
155
|
-
flex:0 1 auto;font-family:var(--label-face);font-size:var(--label-size);
|
|
156
|
-
letter-spacing:var(--label-space);text-transform:uppercase;color:var(--ink-faint)}
|
|
157
|
-
.bandWho img{width:30px;height:30px;border-radius:var(--radius-pill);object-fit:cover;
|
|
158
|
-
border:1px solid var(--rule)}
|
|
159
|
-
.bandProfile .bandRow{display:flex;justify-content:flex-end;gap:30px;flex:0 1 auto}
|
|
160
|
-
.bandProfile .bandCell,.bandProfile .bandSlot{flex:0 0 168px;text-align:right}
|
|
161
|
-
/* the deferred Settings item: a place it would go, rendering nothing at all - not even the
|
|
162
|
-
hairline that declares a list item in this band. never a disabled item. */
|
|
163
|
-
.bandSlot{border:0}
|
|
164
|
-
|
|
165
|
-
/* ============ the carried surfaces: only the hit-area floors the world asks for ============ */
|
|
166
|
-
.toolbar .search{display:none}
|
|
167
|
-
.tbl th button{min-height:24px;display:inline-flex;align-items:center}
|
|
168
|
-
.search input{min-height:24px}
|
|
169
|
-
.foot a,.finePrint a,.lede a{display:inline-block;padding:3px 0;min-height:24px}
|
|
170
|
-
#sub-table-body{overflow-x:auto}
|
|
171
|
-
.hallGlyph{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;
|
|
172
|
-
border-radius:var(--radius-sm);color:var(--ink-faint);transition:color 200ms cubic-bezier(.2,.7,.3,1)}
|
|
173
|
-
.hallGlyph:hover{color:var(--accent-deep)}
|
|
174
|
-
.hallGlyph svg{width:18px;height:18px}
|
|
175
|
-
.tbl .colHall{width:1%;padding-left:0;padding-right:6px}
|
|
176
|
-
.viewTitle{font-family:var(--font-display);font-weight:700;font-size:clamp(24px,3.4vw,32px);
|
|
177
|
-
letter-spacing:-.5px;line-height:1.15;margin-bottom:8px}
|
|
178
|
-
.hero .viewTitle{font-size:clamp(26px,3.8vw,36px);color:var(--chrome-ink);text-shadow:var(--chrome-glow)}
|
|
179
|
-
.bongos{display:block;width:100%;height:auto;overflow:visible}
|
|
180
|
-
.panel{display:none}
|
|
181
|
-
.panel.on{display:block}
|
|
182
|
-
.wizField{display:block;margin-bottom:18px}
|
|
183
|
-
.wizField>span{display:block;font-size:13.5px;font-weight:700;color:var(--ink-soft);margin-bottom:7px}
|
|
184
|
-
#view-new input[type=text]{width:100%;font-family:var(--font-body);font-size:17px;font-weight:600;
|
|
185
|
-
color:var(--ink);background:var(--bg-card);border:2px solid var(--ctl-line);border-radius:14px;
|
|
186
|
-
padding:13px 16px;outline:none}
|
|
187
|
-
#view-new input[type=text]::placeholder{color:var(--ink-faint);font-weight:500}
|
|
188
|
-
.hint{font-size:13px;font-weight:600;color:var(--ink-faint);margin-top:7px;min-height:18px}
|
|
189
|
-
.nav{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:8px}
|
|
190
|
-
.createSplit{display:grid;grid-template-columns:1fr 300px;gap:var(--pad-md);align-items:center}
|
|
191
|
-
.steps{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:22px}
|
|
192
|
-
.viewWrap{padding-bottom:40px}
|
|
193
|
-
#view-mine .hero,#view-new .hero{max-width:none}
|
|
194
|
-
.gh{width:16px;height:16px;fill:currentColor}
|
|
195
|
-
.finePrint{font-size:12.5px;color:var(--ink-faint);line-height:1.5;margin-top:14px}
|
|
196
|
-
.mineEmpty{font-size:13.5px;color:var(--ink-faint);margin:10px 0}
|
|
197
|
-
.loading{font-size:14px;color:var(--ink-faint);margin-bottom:14px}
|
|
198
|
-
.empty{text-align:center;padding:26px 0}
|
|
199
|
-
.empty p{font-size:15px;color:var(--ink-soft);margin-bottom:16px;max-width:52ch;margin-left:auto;margin-right:auto}
|
|
200
|
-
|
|
201
|
-
/* ============ THE CARD: "the specimen" ============ */
|
|
202
|
-
.projCard{position:relative;container-type:inline-size;display:flex;flex-direction:column;
|
|
203
|
-
width:min(560px,100%);text-align:left;background:var(--bg-card);border:1px solid var(--rule);
|
|
204
|
-
border-radius:var(--radius);box-shadow:none;padding:0 0 26px;overflow:hidden}
|
|
205
|
-
.projCard:not(.has-art){padding-top:26px}
|
|
206
|
-
.cardScrim:not([hidden]) .projCard{animation:pcIn 260ms cubic-bezier(.16,1,.3,1) both}
|
|
207
|
-
@keyframes pcIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
|
|
208
|
-
.projCard .cardArt{order:0;display:block;width:100%;aspect-ratio:5/2;object-fit:cover;
|
|
209
|
-
object-position:50% 100%;transform:scale(2);transform-origin:20% 96%}
|
|
210
|
-
.projCard .cardX{position:absolute;top:12px;right:12px;z-index:4;display:inline-flex;
|
|
211
|
-
align-items:center;justify-content:center;width:30px;height:30px;border:0;
|
|
212
|
-
border-radius:var(--radius-pill);background:var(--glass-strong);color:var(--ink);cursor:pointer}
|
|
213
|
-
.projCard.has-art .cardX{background:var(--void-pill);color:var(--void-ink)}
|
|
214
|
-
.projCard .cardX svg{width:15px;height:15px}
|
|
215
|
-
.projCard .cardDot{order:1;align-self:flex-start;display:block;width:54px;height:54px;
|
|
216
|
-
border-radius:50%;margin:0 0 16px 26px;background:var(--acc,var(--accent));box-shadow:none}
|
|
217
|
-
.projCard.has-art .cardDot{position:absolute;z-index:3;left:24px;top:calc(100cqw / 2.5 - 27px);
|
|
218
|
-
margin:0;border:4px solid var(--bg-card)}
|
|
219
|
-
.projCard h3{order:3;margin:0;padding:0 26px;font-family:var(--font-display);font-size:32px;
|
|
220
|
-
font-weight:300;line-height:1.08;letter-spacing:-.03em;color:var(--ink)}
|
|
221
|
-
.projCard.has-art h3{margin-top:44px}
|
|
222
|
-
.projCard .cardTag{order:4;margin:9px 0 0;padding:0 26px;font-size:14.5px;line-height:1.5;
|
|
223
|
-
color:var(--ink-soft);max-width:46ch}
|
|
224
|
-
/* the relationship is a mono label, not a pill: it is a fact about you, not a control */
|
|
225
|
-
.projCard .cardRel{order:5;display:block;margin:14px 0 0;padding:0 26px;background:none;
|
|
226
|
-
border-radius:0;font-family:var(--label-face);font-size:var(--label-size);
|
|
227
|
-
letter-spacing:var(--label-space);text-transform:uppercase;color:var(--ink-faint)}
|
|
228
|
-
.projCard .cardFaces{order:6;display:flex;align-items:center;margin:18px 0 0;padding:0 26px}
|
|
229
|
-
.projCard .cardFaces img{width:28px;height:28px;border-radius:50%;object-fit:cover;
|
|
230
|
-
border:2px solid var(--bg-card);margin-right:-8px}
|
|
231
|
-
.projCard .facesMore{margin-left:16px;font-family:var(--font-mono);font-size:11.5px;
|
|
232
|
-
color:var(--ink-faint);font-variant-numeric:tabular-nums}
|
|
233
|
-
|
|
234
|
-
/* the two figures. with art they are leader-line callouts ON the banner; with none they are the
|
|
235
|
-
two-up band, which is also what every card becomes under 560. */
|
|
236
|
-
.projCard .cardFigs{order:7;display:flex;gap:38px;margin:20px 0 0;padding:0 26px}
|
|
237
|
-
.cardCall{display:block}
|
|
238
|
-
.lead{display:none;width:var(--leader-len);height:26px;margin-bottom:10px;overflow:visible;
|
|
239
|
-
color:color-mix(in srgb,var(--ink) 78%,transparent)}
|
|
240
|
-
.fig{display:block;position:relative;width:fit-content;font-family:var(--font-display);
|
|
241
|
-
font-size:clamp(21px,5cqw,28px);font-weight:300;letter-spacing:-.025em;line-height:1;
|
|
242
|
-
font-variant-numeric:tabular-nums;color:var(--ink);text-shadow:var(--type-halo)}
|
|
243
|
-
.cap{display:block;position:relative;width:fit-content;margin-top:7px;font-size:13px;
|
|
244
|
-
color:var(--ink-soft);text-shadow:var(--type-halo)}
|
|
245
|
-
@media (min-width:561px){
|
|
246
|
-
.projCard.has-art .cardFigs{position:absolute;z-index:2;left:0;right:0;top:0;
|
|
247
|
-
height:calc(100cqw / 2.5);margin:0;padding:0;display:block;pointer-events:none}
|
|
248
|
-
.projCard.has-art .cardCall{position:absolute;width:max-content;max-width:42%}
|
|
249
|
-
.projCard.has-art .cardCall.a{left:26px;top:14px}
|
|
250
|
-
.projCard.has-art .cardCall.b{right:26px;top:calc(100cqw / 2.5 - 112px);text-align:right}
|
|
251
|
-
.projCard.has-art .cardCall.b .fig,.projCard.has-art .cardCall.b .cap{margin-left:auto}
|
|
252
|
-
.projCard.has-art .cardCall .lead{display:block}
|
|
253
|
-
.projCard.has-art .cardCall.b .lead{transform:scaleX(-1);margin-left:auto}
|
|
254
|
-
/* each callout carries ONE feathered patch of the CARD ground under its figure and caption
|
|
255
|
-
together: SOLID to 10px past every edge of the glyph boxes (no column of the text ever sits
|
|
256
|
-
on the fade), then a 34px feather to nothing, so the patch reads as haze in the art and never
|
|
257
|
-
as a slab of paint on it. The feather is a mask, not a shadow (the world has no shadow
|
|
258
|
-
vocabulary). It starts under the figure, never behind the leader. */
|
|
259
|
-
.projCard.has-art .cardCall::before{content:"";position:absolute;
|
|
260
|
-
left:-44px;right:-44px;top:18px;bottom:-24px;z-index:-1;pointer-events:none;
|
|
261
|
-
background:var(--bg-card);border-radius:44px/30px;filter:blur(3px);
|
|
262
|
-
-webkit-mask-image:linear-gradient(90deg,transparent,var(--ink) 34px,var(--ink) calc(100% - 34px),transparent),
|
|
263
|
-
linear-gradient(180deg,transparent,var(--ink) 10px,var(--ink) calc(100% - 12px),transparent);
|
|
264
|
-
-webkit-mask-composite:source-in;
|
|
265
|
-
mask-image:linear-gradient(90deg,transparent,var(--ink) 34px,var(--ink) calc(100% - 34px),transparent),
|
|
266
|
-
linear-gradient(180deg,transparent,var(--ink) 10px,var(--ink) calc(100% - 12px),transparent);
|
|
267
|
-
mask-composite:intersect}
|
|
268
|
-
}
|
|
269
|
-
.projCard .cardMeta{order:8;display:grid;grid-template-columns:auto 1fr;justify-content:normal;
|
|
270
|
-
gap:0;margin:22px 0 0;padding:0 26px;text-align:left}
|
|
271
|
-
.cardMeta dt{font-family:var(--label-face);font-size:var(--label-size);letter-spacing:var(--label-space);
|
|
272
|
-
text-transform:uppercase;color:var(--ink-faint);padding:11px 20px 11px 0;
|
|
273
|
-
border-top:1px solid var(--rule-soft);line-height:19px}
|
|
274
|
-
.cardMeta dd{margin:0;padding:11px 0;text-align:right;font-size:14px;color:var(--ink);
|
|
275
|
-
border-top:1px solid var(--rule-soft);font-variant-numeric:tabular-nums}
|
|
276
|
-
.cardMeta .ownerAv{display:inline-block;width:16px;height:16px;border-radius:50%;object-fit:cover;
|
|
277
|
-
vertical-align:-3px;margin-right:6px}
|
|
278
|
-
.projCard .cardActions{order:9;display:flex;align-items:center;justify-content:flex-start;
|
|
279
|
-
gap:22px;flex-wrap:wrap;margin:24px 0 0;padding:0 26px}
|
|
280
|
-
.pcDoor{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:0 30px;
|
|
281
|
-
border-radius:var(--radius-pill);background:var(--accent);color:var(--accent-on);font-size:16px;
|
|
282
|
-
font-weight:500;text-transform:lowercase;text-decoration:none;
|
|
283
|
-
transition:background 200ms cubic-bezier(.2,.7,.3,1)}
|
|
284
|
-
.pcDoor:hover{background:var(--accent-lift);color:var(--accent-on)}
|
|
285
|
-
.pcHall{display:inline-flex;align-items:center;gap:8px;min-height:24px;color:var(--accent-deep);
|
|
286
|
-
font-size:15px;text-transform:lowercase;text-decoration:underline;text-underline-offset:4px}
|
|
287
|
-
.pcHall svg{width:17px;height:17px}
|
|
288
|
-
|
|
289
|
-
/* ============ the boards ============ */
|
|
290
|
-
#board{padding:26px var(--gutter) 60px}
|
|
291
|
-
.boardTitle{font-family:var(--label-face);font-size:var(--label-size);letter-spacing:var(--label-space);
|
|
292
|
-
text-transform:uppercase;color:var(--ink-faint);margin-bottom:22px}
|
|
293
|
-
.boardRow{border-top:1px solid var(--rule);padding-top:0;margin-bottom:38px}
|
|
294
|
-
.boardLbl{display:block;font-family:var(--font-mono);font-size:11.5px;color:var(--ink-faint);
|
|
295
|
-
padding:9px 0 12px}
|
|
296
|
-
.boardGrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(400px,1fr));gap:34px;
|
|
297
|
-
align-items:start}
|
|
298
|
-
.boardCell .projCard{width:100%}
|
|
299
|
-
.boardStack{display:flex;flex-direction:column;gap:6px}
|
|
300
|
-
.boardSpec{border-top:1px solid var(--rule);margin-bottom:30px}
|
|
301
|
-
.boardSpec .qWrap{width:340px;padding-top:16px}
|
|
302
|
-
|
|
303
|
-
@media (max-width:900px){
|
|
304
|
-
body{--top-h:60px}
|
|
305
|
-
.bar{gap:10px;padding:0 12px}
|
|
306
|
-
.barLeft{gap:12px}
|
|
307
|
-
.barRight{gap:12px}
|
|
308
|
-
.barMark{min-width:44px;justify-content:center}
|
|
309
|
-
.barMark span{display:none}
|
|
310
|
-
.qWrap{flex:1 1 90px;max-width:340px;gap:8px}
|
|
311
|
-
.trig{font-size:13.5px}
|
|
312
|
-
.whoName{display:none}
|
|
313
|
-
.modeBtn{width:40px;height:40px}
|
|
314
|
-
.modeBtn svg{width:18px;height:18px}
|
|
315
|
-
.signinDoor{padding:0 16px;font-size:13.5px}
|
|
316
|
-
.bandIn{padding:0 12px 16px}
|
|
317
|
-
.bandRow{grid-template-columns:1fr;gap:0}
|
|
318
|
-
.bandT{font-size:20px}
|
|
319
|
-
.bandProfile{display:block}
|
|
320
|
-
.bandProfile .bandRow{display:block;text-align:left}
|
|
321
|
-
.bandProfile .bandCell,.bandProfile .bandSlot{flex:none;text-align:left}
|
|
322
|
-
.bandWho{padding-bottom:14px}
|
|
323
|
-
.createSplit{grid-template-columns:1fr}
|
|
324
|
-
.bongoCell{display:none}
|
|
325
|
-
.boardGrid{grid-template-columns:1fr}
|
|
326
|
-
}
|
|
327
|
-
@media (max-width:640px){
|
|
328
|
-
.barRight{gap:8px}
|
|
329
|
-
.bar{gap:8px;padding:0 10px}
|
|
330
|
-
.projCard h3{font-size:26px;padding:0 20px}
|
|
331
|
-
.projCard .cardMeta{padding:0 20px}
|
|
332
|
-
.cardTag,.cardRel,.cardFaces,.cardFigs,.cardMeta,.cardActions{padding-left:20px;padding-right:20px}
|
|
333
|
-
.cardDot{margin-left:20px}
|
|
334
|
-
.projCard.has-art .cardDot{left:18px}
|
|
335
|
-
.cardActions{gap:16px}
|
|
336
|
-
}
|
|
337
|
-
@media (max-width:480px){
|
|
338
|
-
/* no field this narrow can hold a query beside four controls (45px at 320 with the word gone),
|
|
339
|
-
so the search folds into a magnifier in the field's place; pressed, it drops ONE hairline row
|
|
340
|
-
of the page ground under the bar carrying the full-width field and its count, and the sky's
|
|
341
|
-
spotlight reports what the query matched. Escape, or an opening menu, folds it back. */
|
|
342
|
-
.qToggle{display:inline-flex}
|
|
343
|
-
.qWrap{display:none}
|
|
344
|
-
.qWrap.is-open:not([hidden]){display:flex;position:absolute;left:0;right:0;top:100%;z-index:41;
|
|
345
|
-
align-items:center;gap:10px;max-width:none;height:52px;padding:0 10px;border-radius:0;
|
|
346
|
-
background:var(--bg);border-bottom:1px solid var(--rule)}
|
|
347
|
-
.qWrap.is-open .qField{min-height:40px}
|
|
348
|
-
.qIcon{display:block}
|
|
349
|
-
.bar{gap:6px}
|
|
350
|
-
.barLeft{gap:8px}
|
|
351
|
-
.barRight{gap:6px}
|
|
352
|
-
.signinDoor{padding:0 13px}
|
|
353
|
-
}
|
|
354
|
-
</style>
|
|
355
|
-
</head>
|
|
356
|
-
<body>
|
|
357
|
-
<!--
|
|
358
|
-
v2 "THE HAIRLINE" — the /projects hub recomposed inside DESIGN.md's chrome world (task 1003299,
|
|
359
|
-
goal 1000080). A MOCK: it writes no build file. Sky, orbs, hover card, toolbar, table, mine view,
|
|
360
|
-
new view and footer are carried verbatim from public-landing/projects.html and render from the
|
|
361
|
-
shipping cosmos.css; the bar, the two menus, the search and the poster card are this version.
|
|
362
|
-
|
|
363
|
-
THESIS. Hairlines, not containers. The hub is an Operate surface and the world's structure rule is
|
|
364
|
-
already the answer to a bar: 1px rules separate, nothing is boxed. So there is no pill on this bar
|
|
365
|
-
at all. Its ground IS the page ground, closed by one hairline, and the only filled shape it can
|
|
366
|
-
ever hold is the sign-in door. The menus refuse to be floating cards: each is a full-width BAND
|
|
367
|
-
that unfolds under the bar's edge and PUSHES the page down, so a destination is a place the page
|
|
368
|
-
opens into rather than a list that hovers over it. The card follows the same logic one step
|
|
369
|
-
further: it is a specimen sheet, its two figures annotated ON the art with the landing's own
|
|
370
|
-
leader-line callouts, its facts a mono ledger of hairline rows.
|
|
371
|
-
|
|
372
|
-
BAR. Ground var(--bg) (the same value the sky paints, so the difference is read by the 1px
|
|
373
|
-
var(--rule) bottom edge, not by a tone), 64px, not sticky, gutter clamp(16px,4vw,34px) so it lines
|
|
374
|
-
up with the toolbar under it. LEFT: the bongo-pair glyph + "Cloud Bongos" as plain type (Manrope
|
|
375
|
-
500, 17px, -0.015em) linking home, then the search - a bare field with only a bottom hairline that
|
|
376
|
-
takes var(--ink) on focus, a var(--label-face) placeholder, 340px flexible, the count to its right
|
|
377
|
-
in var(--ink-faint), tabular. No magnifier above 480: the field is bare by thesis and the label
|
|
378
|
-
names it; under 480 the field folds into a 44px magnifier that drops one hairline row under the
|
|
379
|
-
bar (see 390).
|
|
380
|
-
RIGHT: "Projects" with a caret, a 20px glyph mode toggle in a 44px hit area, and the identity as
|
|
381
|
-
avatar + login + caret. Every right-group control is lowercase text with no chrome; the open
|
|
382
|
-
trigger takes a 2px accent underline, because an open menu is the live thing on the bar. Signed
|
|
383
|
-
out the identity slot is the landing's sign-in door verbatim (inverted ink, lowercase) - one
|
|
384
|
-
filled pill on a bar that has no others.
|
|
385
|
-
|
|
386
|
-
MENU. Not a panel: a BAND. var(--bg-card) ground, a 1px var(--rule) bottom edge, full bleed, three
|
|
387
|
-
cells in a hairline-separated row, each a lowercase display title (Manrope 300, 24px) over one
|
|
388
|
-
clause in var(--ink-soft); the whole cell is the target (the anchor's ::after stretches over it).
|
|
389
|
-
The current view carries a 2px accent hairline on its TOP edge - the rail-step-lit grammar from
|
|
390
|
-
DESIGN.md, moved onto a menu - plus var(--ink) ink and aria-current="page". The profile band is
|
|
391
|
-
the same band: the identity in its left cell, "My projects" / a deferred Settings slot that renders
|
|
392
|
-
nothing / "Sign out" right-aligned. Opening pushes the page down (the sky moves, the bar does not
|
|
393
|
-
float); one authored move, a 6px rise + fade over 220ms on the world's exponential ease-out, dead
|
|
394
|
-
under the kill switch. Escape closes and returns focus to the trigger; Tab walks the items; Arrow
|
|
395
|
-
keys move between them; a click outside closes.
|
|
396
|
-
|
|
397
|
-
CARD. min(560px,100%), var(--bg-card) on a 1px var(--rule) edge, 16px, no shadow. Six regions,
|
|
398
|
-
flat children of the card, in the brief's order. (1) the banner, a bare 5:2 <img> cropped into the
|
|
399
|
-
chrome of the platform's own social card. (2) the two figures as LEADER-LINE CALLOUTS on it, a 1px
|
|
400
|
-
diagonal leader, a 300-weight tabular figure and a 13px caption, each carrying its own feathered
|
|
401
|
-
patch of the card ground behind the glyphs only. (3) the accent disc, 54px, half over the banner's
|
|
402
|
-
lower edge at the left, ringed 4px in the card ground so it sits ON the card. (4) name at the
|
|
403
|
-
headline scale (Manrope 300, 32px), tagline, and the relationship as a mono label rather than a
|
|
404
|
-
pill - it is a fact about you, not a control. (5) faces, five 28px avatars at -8px overlap ringed
|
|
405
|
-
in the card ground, +N past five. (6) the facts as a two-column mono ledger, label left in
|
|
406
|
-
var(--label-face), value right and tabular, ONE hairline per row (both cells stretch to the row, so
|
|
407
|
-
the rule never steps at the column boundary); then ONE accent door
|
|
408
|
-
("Open site") with the hall entry beside it as an underlined var(--accent-deep) text link. With no
|
|
409
|
-
art the callouts become the two-up band and the disc returns to the top of the card body; the
|
|
410
|
-
ladder holds down to the floor (disc, name, tagline, relationship, one door).
|
|
411
|
-
|
|
412
|
-
LIGHT. Paper with hairlines. Nothing inverts: the bar is var(--bg) closed by var(--rule), the band
|
|
413
|
-
is var(--bg-card) on var(--bg) and the difference is read by its edge, the card is var(--bg-card)
|
|
414
|
-
on paper. The only mode-swapped materials are the label face (mono on paper, the body face on
|
|
415
|
-
black), the focus colour (var(--accent-deep) light, var(--accent) dark) and the black type halo,
|
|
416
|
-
which is dark-only. No black panel ever lands on the light page.
|
|
417
|
-
|
|
418
|
-
390. The bar keeps ONE row at 60px down to 320: the wordmark folds away and the glyph stays, and
|
|
419
|
-
the search keeps a real (narrower) field rather than collapsing to an icon - a bare field has no
|
|
420
|
-
chrome to protect, and hiding the map's only filter to save 90px is the wrong trade down to 480. Under 480
|
|
421
|
-
the row cannot carry a field that holds a query beside four controls (the field measured 45px at
|
|
422
|
-
320 with the word gone), so the search folds into a 44px magnifier in the field's place; pressed,
|
|
423
|
-
it drops ONE hairline row of the page ground under the bar, full width, carrying the field and its
|
|
424
|
-
count, and Escape or an opening menu folds it back. The filter is never hidden, one press away,
|
|
425
|
-
and the row is this version's own grammar. From 481 to 640 the count stays in the bar, where it
|
|
426
|
-
fits. (An earlier draft of this note dropped the count at 640 "because
|
|
427
|
-
the toolbar already carries it" - it does not: this version moved the search, and #mapCount with
|
|
428
|
-
it, out of the toolbar.) The search is capped at its desktop width under 900, so it shrinks with
|
|
429
|
-
the viewport instead of swelling into the space the folded wordmark frees. Both bands stack to one
|
|
430
|
-
cell per row, the profile band included. Under 560 the card's callouts become the two-up band -
|
|
431
|
-
the same fallback the no-art rung uses, so the mobile card and the artless card are one
|
|
432
|
-
composition rather than two.
|
|
433
|
-
|
|
434
|
-
BEYOND THE SKIN
|
|
435
|
-
- [given] The nav row leaves the bar; Projects becomes a right-group band. COLLISION:
|
|
436
|
-
projects_hub_pre_uat.mjs:203 pins cosmos's `.shell .navrow{position:absolute;left:50%;...}` rule -
|
|
437
|
-
deleting .navrow from cosmos.css breaks it; retarget or keep a .navrow rule.
|
|
438
|
-
projects_hub.mjs:42-43 stays SAFE only while each band item keeps `href="?view=<v>" data-nav="<v>"`
|
|
439
|
-
as adjacent attributes, which this mock does.
|
|
440
|
-
- [given] Home is removed; the logo is home. COLLISION: projects_hub.mjs:40 (the Home-link regex)
|
|
441
|
-
breaks hard; :46 and :48 (`a.dataset.nav === 'home'`) go dead. Retarget :40 to the mark.
|
|
442
|
-
- [given] The hall pill leaves the bar and becomes a per-project affordance. COLLISION:
|
|
443
|
-
landing_page.mjs:214/217/220 and projects_hub.mjs:105 all pin `{{buildersOrigin}}` in the hub and
|
|
444
|
-
the pill is the only match. ARCHITECTURE: `clientBranding()` withholds domains and a {{token}} is
|
|
445
|
-
one value per instance, so "only where the hall address differs" needs a NEW per-project field on
|
|
446
|
-
/projects/featured (or /my-projects); it cannot be a token.
|
|
447
|
-
- [given] The map search moves into the bar and hides on mine/new. SAFE: cosmos keeps
|
|
448
|
-
`.search:focus-within` and `.mineBar .search .count{display:none;}`; pageInert's pinned selector
|
|
449
|
-
string already covers a bar-hosted search through `header.shell`.
|
|
450
|
-
- [given] A profile band on the chip. WATCH: projects.html:5307 uses a SINGULAR
|
|
451
|
-
`querySelector('[data-nav="mine"]')`; the band's "Your projects" is that one node here, but a
|
|
452
|
-
second `data-nav="mine"` anywhere (e.g. a profile item pointing at ?view=mine) becomes a latent
|
|
453
|
-
signed-out bug. Use querySelectorAll.
|
|
454
|
-
- [consequence] Nothing is removed from the sky. The brief's "retire the top wash" applies to the
|
|
455
|
-
landing (--sky-topscrim); the hub's `.sky` is already a flat var(--sky-bg) with no scrim, so a
|
|
456
|
-
grounded bar costs it nothing.
|
|
457
|
-
- [consequence] The sky gets its height back. `.field{height:calc(100vh - 232px)}` was measured
|
|
458
|
-
against a 69px bar plus a three-control toolbar; a 64px bar and a two-control toolbar leave
|
|
459
|
-
~30px unclaimed at 1440, and at 390 the old three-row stack (161px of bar + three toolbar rows)
|
|
460
|
-
becomes one 60px row plus one toolbar row. Retarget the 232.
|
|
461
|
-
- [consequence] `#mapCount` leaves the toolbar with the search and its string changes from
|
|
462
|
-
"N projects" to "1 of 4" while a query is live. SAFE: projects_hub.mjs:389/393 pin the
|
|
463
|
-
computation (`var shown = list.length + (selfShown ? 1 : 0)`), not the wording; the copy registry
|
|
464
|
-
must be regenerated.
|
|
465
|
-
- [consequence] The document ships ONE first-level heading, and it sits directly under the main
|
|
466
|
-
element rather than inside #view-map, so the mine and new views are not left with no top-level
|
|
467
|
-
heading at all; setView rewrites its text ("The project map" / "Your projects" / "Start a
|
|
468
|
-
project"). Today projects.html carries ten (one per view and per wizard panel), only ever one
|
|
469
|
-
visible; the rest are demoted a level. COLLISION: projects_hub_pre_uat.mjs:451 pins the literal
|
|
470
|
-
adjacency of the view-map section and the visually-hidden "The project map" heading; that
|
|
471
|
-
assertion moves with the heading.
|
|
472
|
-
- [given] builders leaves the facts for the figure band and becomes a callout on the art.
|
|
473
|
-
COLLISION: projects_hub.mjs:496-498 and :586-602 pin id="cardBuilders" inside the card slice and
|
|
474
|
-
its cardFact('cardBuilders', ...) wiring (HUB-TESTS.md:94 and :97); both must be retargeted to
|
|
475
|
-
the figure, or the ledger keeps a fifth row this composition does not have.
|
|
476
|
-
- [consequence] A hall glyph adds a 7th cell to the table. COLLISION: projects_hub.mjs:531-535
|
|
477
|
-
requires the <th> count, #selfRow's <td> count and the generated-row template to match - all
|
|
478
|
-
three must gain the cell together.
|
|
479
|
-
- [proposal] The toolbar becomes a second hairline row under the bar (Sky | Table and Only mine as
|
|
480
|
-
lowercase text controls on one rule), so the map reads as two rules and then sky. Not built here:
|
|
481
|
-
the toolbar is out of this round's scope. COLLISION: none in the static tests; cosmos's `.seg` and
|
|
482
|
-
`.switch` are only pinned by the contrast PAIRS table.
|
|
483
|
-
- [proposal] The mine view's empty state becomes a band of the same grammar (one title, one clause,
|
|
484
|
-
one door) instead of a centred card, so "you own nothing yet" reads like a destination rather
|
|
485
|
-
than an error. COLLISION: projects_hub_pre_uat.mjs pins the empty-state copy, not its markup.
|
|
486
|
-
- [proposal] `About` (goal 1000063) becomes a FOURTH cell of the Projects band. The grid already
|
|
487
|
-
takes it; the order Map / Your projects / New project / About keeps every pinned regex intact.
|
|
488
|
-
- [proposal] The card grows from cosmos's `width:min(420px,100%)` to min(560px,100%). The poster
|
|
489
|
-
needs the width; no test pins it.
|
|
490
|
-
- [proposal] The table's "unknown" mark is an em dash, which the world's taste ban forbids and the
|
|
491
|
-
card already refuses ("absent facts HIDE, never dash"). Propose a middot or an empty cell.
|
|
492
|
-
COLLISION: projects_hub.mjs:564-580 pins `p.builders == null ? '—'` and tagsHtml's `return '—'`.
|
|
493
|
-
In this mock every carried em dash is written as the entity `—` so the render is byte-for-
|
|
494
|
-
byte today's while the mock's own copy check stays honest about dashes THIS version authored.
|
|
495
|
-
- [proposal] Three carried controls sit under the world's 24px floor and this mock floors them
|
|
496
|
-
page-locally: the footer links (no vertical padding), the table's sort buttons (`all:unset`) and
|
|
497
|
-
the `.search` inputs (13px, no padding). COLLISION: projects_hub_pre_uat.mjs:430-433 pins
|
|
498
|
-
`.tbl th button{all:unset;cursor:pointer;}` verbatim in cosmos - adding a min-height there needs
|
|
499
|
-
the literal retargeted.
|
|
500
|
-
- [proposal] "Runs" is the label of the TAGS field, not of an address. The brief's Data pins
|
|
501
|
-
cloudbongos.com as the platform's Runs, and this card renders the ADDRESS on every rung (Off the
|
|
502
|
-
Boats: amazonprimea.com) so the ladder reads Runs one way; the table keeps the module list in
|
|
503
|
-
its Runs column. Propose splitting them: an address fact ("Runs") and a separate tags fact.
|
|
504
|
-
COLLISION: projects_hub.mjs:586-602 wires cardFact('cardRuns', tagsHtml(p.tags)) and
|
|
505
|
-
HUB-TESTS.md:120 pins tagsHtml([]) returning "core"; both move with the split.
|
|
506
|
-
- [proposal] Faces and shipped-in-30-days do not exist on any feed. /projects/featured carries
|
|
507
|
-
art_url (unread) and owner_avatar only; there is no avatar list and no shipped_30d. Both need new
|
|
508
|
-
enrichment fields in modules/platform-identity/project-stats.js + routes/projects.js.
|
|
509
|
-
|
|
510
|
-
DATA. Real, fetched 2026-08-27. Builder jaxri (avatar from the live GitHub CDN). Catalog: Off the
|
|
511
|
-
Boats / Demo / Emersonian Circles from /projects/featured, plus the apex self row. Orbs carry the
|
|
512
|
-
inline styles the live page computes: the list is name-sorted, so Demo takes ORB_SLOTS[0]
|
|
513
|
-
(22%,30%,74px), Emersonian Circles [1] (78%,66%,60px), Off the Boats [2] (33%,74%,56px), and
|
|
514
|
-
assignAccents() sorts the catalog by origin, giving Off the Boats var(--sea), Demo
|
|
515
|
-
var(--terracotta), Emersonian Circles var(--gold-soft); the self orb is var(--accent) at 122px,
|
|
516
|
-
50%/44%. The `card` rung is the platform: builders 9 (the apex leaderboard's rows with credits
|
|
517
|
-
above zero), shipped in 30 days 30+ (the feed caps at 30 rows and all 30 fall inside the window),
|
|
518
|
-
faces jaxri / lars589 / IAMMASTERQUA / scootermack / LarsCode +4, Type hidden (null in the feed),
|
|
519
|
-
Runs "cloudbongos.com" (the brief's Data pins the address; the field the card reads today is tags,
|
|
520
|
-
which renders "core" for an instance with none - see the proposal above), Owner lars589, Listed
|
|
521
|
-
Jul 14, 2026 (the Demo row's date, as the brief allows, since the apex has no listing row of its
|
|
522
|
-
own). The `card-member` rung is Off the Boats: builders 13 from ITS leaderboard (the featured
|
|
523
|
-
feed's 11 is a different count from a different source and is what the table row shows), shipped in
|
|
524
|
-
30 days a real 0 (its newest ship is 2026-06-30), faces 5 + 8, and NO hall entry because its hall
|
|
525
|
-
is amazonprimea.com/builders, the same address as its site. ART: the platform has no art_url, so
|
|
526
|
-
the banner is public-landing/assets/world/og-card.jpg - a real 1200x630 capture of the built
|
|
527
|
-
landing, the platform's art in the only sense the platform has one - cropped 5:2 and scaled into
|
|
528
|
-
its chrome so the landing's own headline stays out of frame. No other image is invented.
|
|
529
|
-
MEMBERSHIP is illustrative: jaxri is rendered as a member (you build here) of both the platform and
|
|
530
|
-
Off the Boats, per the brief; the live /my-projects fixture returns nothing.
|
|
531
|
-
|
|
532
|
-
TOKENS. Declared on body: --glass, --glass-strong, --glass-edge, --accent-lift, --void-pill,
|
|
533
|
-
--void-ink, --focus, --type-halo, --label-face, --label-size, --label-space, --radius, --radius-sm,
|
|
534
|
-
--radius-pill, --top-h, plus this page's --gutter and --leader-len. The eight that actually flip
|
|
535
|
-
between modes (--glass, --glass-strong, --glass-edge, --focus, --type-halo, --label-face,
|
|
536
|
-
--label-size, --label-space) are the ones restated in the dark block and its byte-identical
|
|
537
|
-
prefers-color-scheme twin; the rest are declared once, which is also what lets the 900px block
|
|
538
|
-
take --top-h to 60px without a (0,2,1) dark rule outranking it. Taken from
|
|
539
|
-
cosmos.css unchanged: the fifteen contract tokens, --accent-on, --accent-soft, --card, --ctl-line,
|
|
540
|
-
--font-mono, --pad-*, and the four names that keep cosmos's meaning here and are never redeclared -
|
|
541
|
-
--line (a hairline COLOUR, not a width) and --ok / --warn / --err (the hub's fixed status
|
|
542
|
-
vocabulary its chips depend on). Two recipes are adapted because a mock may carry no new literal:
|
|
543
|
-
--focus resolves to var(--accent-deep) in light rather than world.css's mix toward #3a1400, and
|
|
544
|
-
--accent-on is cosmos's color-mix rather than DESIGN.md's #2a1305.
|
|
545
|
-
-->
|
|
546
|
-
<div class="sky" aria-hidden="true">
|
|
547
|
-
<span class="star" style="top:2%;left:12%;width:2px;height:2px;"></span>
|
|
548
|
-
<span class="star" style="top:5%;left:28%;width:1.5px;height:1.5px;animation-delay:.7s;"></span>
|
|
549
|
-
<span class="star" style="top:3%;left:47%;width:2px;height:2px;animation-delay:1.4s;"></span>
|
|
550
|
-
<span class="star" style="top:8%;left:63%;width:1.5px;height:1.5px;animation-delay:.3s;"></span>
|
|
551
|
-
<span class="star" style="top:4%;left:78%;width:2.5px;height:2.5px;animation-delay:2s;"></span>
|
|
552
|
-
<span class="star" style="top:10%;left:88%;width:1.5px;height:1.5px;animation-delay:1s;"></span>
|
|
553
|
-
<span class="star" style="top:14%;left:20%;width:1.5px;height:1.5px;animation-delay:1.8s;"></span>
|
|
554
|
-
<span class="star" style="top:22%;left:55%;width:2px;height:2px;animation-delay:.5s;"></span>
|
|
555
|
-
<span class="star" style="top:34%;left:36%;width:1.5px;height:1.5px;animation-delay:2.4s;"></span>
|
|
556
|
-
<span class="star" style="top:30%;left:78%;width:1.5px;height:1.5px;animation-delay:1.2s;"></span>
|
|
557
|
-
<span class="star" style="top:48%;left:8%;width:2px;height:2px;animation-delay:.9s;"></span>
|
|
558
|
-
<span class="star" style="top:55%;left:90%;width:1.5px;height:1.5px;animation-delay:1.6s;"></span>
|
|
559
|
-
<span class="star" style="top:68%;left:24%;width:1.5px;height:1.5px;animation-delay:2.1s;"></span>
|
|
560
|
-
<span class="star" style="top:76%;left:64%;width:2px;height:2px;animation-delay:.4s;"></span>
|
|
561
|
-
<span class="star" style="top:88%;left:42%;width:1.5px;height:1.5px;animation-delay:1.9s;"></span>
|
|
562
|
-
</div>
|
|
563
|
-
|
|
564
|
-
<svg width="0" height="0" style="position:absolute" aria-hidden="true" focusable="false">
|
|
565
|
-
<symbol id="i-caret" viewBox="0 0 20 20"><path class="ic" d="m5.6 8 4.4 4.4L14.4 8"/></symbol>
|
|
566
|
-
<symbol id="i-hall" viewBox="0 0 20 20"><path class="ic" d="M2.8 7.4 10 3.5l7.2 3.9"/><path class="ic" d="M5.2 8.8v5.6M10 8.8v5.6M14.8 8.8v5.6"/><path class="ic" d="M3.4 16.3h13.2"/></symbol>
|
|
567
|
-
<symbol id="i-close" viewBox="0 0 20 20"><path class="ic" d="M5.6 5.6l8.8 8.8M14.4 5.6l-8.8 8.8"/></symbol>
|
|
568
|
-
</svg>
|
|
569
|
-
|
|
570
|
-
<a class="skip" href="#hubMain">Skip to content</a>
|
|
571
|
-
|
|
572
|
-
<header class="bar">
|
|
573
|
-
<div class="barLeft">
|
|
574
|
-
<a class="barMark" href="/" aria-label="Cloud Bongos, home">
|
|
575
|
-
<svg viewBox="0 0 26 20" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.4"
|
|
576
|
-
stroke-linecap="round" stroke-linejoin="round">
|
|
577
|
-
<ellipse cx="8.4" cy="5.6" rx="6.6" ry="2.9"/>
|
|
578
|
-
<path d="M1.8 5.6v6.6a6.6 2.9 0 0 0 13.2 0V5.6"/>
|
|
579
|
-
<ellipse cx="19.6" cy="8.4" rx="4.7" ry="2.1"/>
|
|
580
|
-
<path d="M14.9 8.4v4.6a4.7 2.1 0 0 0 9.4 0V8.4"/>
|
|
581
|
-
</svg>
|
|
582
|
-
<span>Cloud Bongos</span>
|
|
583
|
-
</a>
|
|
584
|
-
<button class="qToggle" type="button" aria-expanded="false" aria-controls="qWrap" aria-label="Search projects">
|
|
585
|
-
<svg viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor"
|
|
586
|
-
stroke-width="1.6" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.5-3.5"/></svg>
|
|
587
|
-
</button>
|
|
588
|
-
<div class="qWrap" id="qWrap">
|
|
589
|
-
<div class="qField">
|
|
590
|
-
<svg class="qIcon" viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor"
|
|
591
|
-
stroke-width="1.6" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.5-3.5"/></svg>
|
|
592
|
-
<label class="vh" for="mapQ">Search projects</label>
|
|
593
|
-
<input class="qInput" type="text" id="mapQ" placeholder="Find a project" aria-label="Search projects">
|
|
594
|
-
</div>
|
|
595
|
-
<span class="qCount" id="mapCount">4 projects</span>
|
|
596
|
-
</div>
|
|
597
|
-
</div>
|
|
598
|
-
<div class="barRight">
|
|
599
|
-
<button class="trig projTrig" type="button" data-menu="projects" aria-expanded="false" aria-controls="menuProjects">Projects<svg class="cv" aria-hidden="true"><use href="#i-caret"></use></svg></button>
|
|
600
|
-
<button class="modeBtn" type="button" aria-label="Toggle light or dark">
|
|
601
|
-
<svg class="moon" viewBox="0 0 20 20" aria-hidden="true" fill="none" stroke="currentColor"
|
|
602
|
-
stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">
|
|
603
|
-
<path d="M16.2 12.4A6.8 6.8 0 0 1 7.6 3.8a6.8 6.8 0 1 0 8.6 8.6z"/>
|
|
604
|
-
</svg>
|
|
605
|
-
<svg class="sun" viewBox="0 0 20 20" aria-hidden="true" fill="none" stroke="currentColor"
|
|
606
|
-
stroke-width="1.4" stroke-linecap="round">
|
|
607
|
-
<circle cx="10" cy="10" r="3.9"/>
|
|
608
|
-
<path d="M10 1.6v2.1M10 16.3v2.1M1.6 10h2.1M16.3 10h2.1M4.1 4.1l1.5 1.5M14.4 14.4l1.5 1.5M15.9 4.1l-1.5 1.5M5.6 14.4l-1.5 1.5"/>
|
|
609
|
-
</svg>
|
|
610
|
-
</button>
|
|
611
|
-
<button class="trig whoTrig" type="button" data-menu="profile" aria-expanded="false" aria-controls="menuProfile" aria-label="Account, jaxri"><img src="https://avatars.githubusercontent.com/u/64553469?v=4" alt=""><span class="whoName">jaxri</span><svg class="cv" aria-hidden="true"><use href="#i-caret"></use></svg></button>
|
|
612
|
-
<a class="signinDoor" href="/api/bongos/auth/web/start?return=/projects" hidden>Sign in</a>
|
|
613
|
-
</div>
|
|
614
|
-
</header>
|
|
615
|
-
|
|
616
|
-
<div class="band" id="menuProjects" data-menu="projects" hidden>
|
|
617
|
-
<div class="bandIn">
|
|
618
|
-
<ul class="bandRow">
|
|
619
|
-
<li class="bandCell is-now" data-view="map"><a class="bandT" href="?view=map" data-nav="map" aria-current="page">Map</a><span class="bandC">the sky of every project</span></li>
|
|
620
|
-
<li class="bandCell" data-view="mine"><a class="bandT" href="?view=mine" data-nav="mine">Your projects</a><span class="bandC">the ones you own or build on</span></li>
|
|
621
|
-
<li class="bandCell" data-view="new"><a class="bandT" href="?view=new" data-nav="new">New project</a><span class="bandC">five questions and a home</span></li>
|
|
622
|
-
</ul>
|
|
623
|
-
</div>
|
|
624
|
-
</div>
|
|
625
|
-
|
|
626
|
-
<div class="band" id="menuProfile" data-menu="profile" hidden>
|
|
627
|
-
<div class="bandIn bandProfile">
|
|
628
|
-
<p class="bandWho"><img src="https://avatars.githubusercontent.com/u/64553469?v=4" alt="">jaxri</p>
|
|
629
|
-
<ul class="bandRow">
|
|
630
|
-
<li class="bandCell"><a class="bandT" href="https://builders.cloudbongos.com/my-projects">My projects</a></li>
|
|
631
|
-
<li class="bandSlot" aria-hidden="true"></li>
|
|
632
|
-
<li class="bandCell"><a class="bandT" href="/api/bongos/auth/logout">Sign out</a></li>
|
|
633
|
-
</ul>
|
|
634
|
-
</div>
|
|
635
|
-
</div>
|
|
636
|
-
|
|
637
|
-
<main id="hubMain">
|
|
638
|
-
<h1 class="vh" id="pageH1">The project map</h1>
|
|
639
|
-
<section id="view-map">
|
|
640
|
-
<div class="toolbar">
|
|
641
|
-
<div class="seg" role="group" aria-label="Map display">
|
|
642
|
-
<button type="button" id="sub-sky" aria-pressed="true">Sky</button>
|
|
643
|
-
<button type="button" id="sub-table" aria-pressed="false">Table</button>
|
|
644
|
-
</div>
|
|
645
|
-
|
|
646
|
-
<label class="switch" title="Show only projects you own or build on">
|
|
647
|
-
<input type="checkbox" id="onlyMine"><span class="track"></span> Only mine
|
|
648
|
-
</label>
|
|
649
|
-
</div>
|
|
650
|
-
|
|
651
|
-
<div class="fieldWrap" id="sub-sky-body">
|
|
652
|
-
<div class="field" id="orbField">
|
|
653
|
-
<div class="ground"></div>
|
|
654
|
-
<div class="stars" id="mapStars" aria-hidden="true"></div>
|
|
655
|
-
<div class="skyCam" id="skyCam">
|
|
656
|
-
<!--apex-only:start-->
|
|
657
|
-
<a class="worldOrb" id="selfOrb" href="/" data-rel="builder" style="--acc:var(--accent);--d:122px;left:50%;top:44%">
|
|
658
|
-
<span class="badge">you build here</span>
|
|
659
|
-
<span class="disc"></span>
|
|
660
|
-
<span class="nm" data-brand-product-inline>Cloud Bongos</span>
|
|
661
|
-
<span class="sub">this platform</span>
|
|
662
|
-
</a>
|
|
663
|
-
<!--apex-only:end-->
|
|
664
|
-
<a class="worldOrb" data-generated data-rel="none" data-origin="https://demo.cloudbongos.com" href="https://demo.cloudbongos.com" target="_blank" rel="noopener" title="A live demo instance on Cloud Bongos." style="--acc:var(--terracotta);--d:74px;left:22%;top:30%">
|
|
665
|
-
<span class="disc"></span>
|
|
666
|
-
<span class="nm">Demo</span>
|
|
667
|
-
</a>
|
|
668
|
-
<a class="worldOrb" data-generated data-rel="none" data-origin="https://emersonian-circles.cloudbongos.com" href="https://emersonian-circles.cloudbongos.com" target="_blank" rel="noopener" title="An independent project built on Cloud Bongos." style="--acc:var(--gold-soft);--d:60px;left:78%;top:66%">
|
|
669
|
-
<span class="disc"></span>
|
|
670
|
-
<span class="nm">Emersonian Circles</span>
|
|
671
|
-
</a>
|
|
672
|
-
<a class="worldOrb" data-generated data-rel="builder" data-origin="https://amazonprimea.com" href="https://amazonprimea.com" target="_blank" rel="noopener" title="A singular shop, and a broader videogame in a persistent ancient Greek world that collides with modern day commerce & products." style="--acc:var(--sea);--d:56px;left:33%;top:74%">
|
|
673
|
-
<span class="badge">you build here</span>
|
|
674
|
-
<span class="disc"></span>
|
|
675
|
-
<span class="nm">Off the Boats</span>
|
|
676
|
-
</a>
|
|
677
|
-
</div>
|
|
678
|
-
<div class="fieldEmpty">
|
|
679
|
-
<p id="emptyMsg">You don’t own or build on anything here yet.</p>
|
|
680
|
-
<span class="sub">Turn the filter off to see what everyone else is building — or start your own.</span>
|
|
681
|
-
<a class="btn small" href="?view=new" data-nav-to="new">Start a project</a>
|
|
682
|
-
</div>
|
|
683
|
-
<div class="hintbar"><span><kbd>drag</kbd> pan</span><span><kbd>scroll</kbd> zoom</span><span><kbd>click a project</kbd> open it</span></div>
|
|
684
|
-
<div class="hoverCard" id="hoverCard" hidden aria-hidden="true"></div>
|
|
685
|
-
</div>
|
|
686
|
-
</div>
|
|
687
|
-
|
|
688
|
-
<div class="wrap viewWrap" id="sub-table-body" hidden>
|
|
689
|
-
<table class="tbl">
|
|
690
|
-
<thead>
|
|
691
|
-
<tr>
|
|
692
|
-
<th class="colName" data-sort="name" aria-sort="ascending"><button type="button" class="thSort">Project</button></th>
|
|
693
|
-
<th class="colType">Type</th>
|
|
694
|
-
<th class="right" data-sort="builders"><button type="button" class="thSort">Builders</button></th>
|
|
695
|
-
<th class="colTags">Runs</th>
|
|
696
|
-
<th class="right colStatus">Status</th>
|
|
697
|
-
<th class="colHall"></th>
|
|
698
|
-
<th class="colGo"></th>
|
|
699
|
-
</tr>
|
|
700
|
-
</thead>
|
|
701
|
-
<tbody id="mapRows">
|
|
702
|
-
<!--apex-only:start-->
|
|
703
|
-
<tr id="selfRow">
|
|
704
|
-
<td class="colName"><span class="pname"><span class="pdot" style="--acc:var(--accent)"></span>
|
|
705
|
-
<span><span class="ptitle" data-brand-product-inline>Cloud Bongos</span><span id="selfPill"> <span class="pill">you build here</span></span><br>
|
|
706
|
-
<span class="ptag">this platform</span></span></span></td>
|
|
707
|
-
<td class="colType">—</td>
|
|
708
|
-
<td class="right num" id="selfBuilders">9</td>
|
|
709
|
-
<td class="colTags" id="selfTags">—</td>
|
|
710
|
-
<td class="right colStatus"><span class="chip calm"><span class="cdot"></span>—</span></td>
|
|
711
|
-
<td class="colHall"><a class="hallGlyph" href="https://builders.cloudbongos.com" aria-label="Builders' hall"><svg aria-hidden="true"><use href="#i-hall"></use></svg></a></td>
|
|
712
|
-
<td class="colGo"><a class="btn small ghost" href="/">Open →</a></td>
|
|
713
|
-
</tr>
|
|
714
|
-
<!--apex-only:end-->
|
|
715
|
-
<tr data-generated>
|
|
716
|
-
<td class="colName"><span class="pname"><span class="pdot" style="--acc:var(--terracotta)"></span>
|
|
717
|
-
<span><span class="ptitle">Demo</span><br>
|
|
718
|
-
<span class="ptag">A live demo instance on Cloud Bongos.</span></span></span></td>
|
|
719
|
-
<td class="colType">—</td>
|
|
720
|
-
<td class="right num">1</td>
|
|
721
|
-
<td class="colTags"><span class="tags">core</span></td>
|
|
722
|
-
<td class="right colStatus"><span class="chip calm"><span class="cdot"></span>—</span></td>
|
|
723
|
-
<td class="colHall"></td>
|
|
724
|
-
<td class="colGo"><a class="btn small ghost" href="https://demo.cloudbongos.com" target="_blank" rel="noopener">Open →</a></td>
|
|
725
|
-
</tr>
|
|
726
|
-
<tr data-generated>
|
|
727
|
-
<td class="colName"><span class="pname"><span class="pdot" style="--acc:var(--gold-soft)"></span>
|
|
728
|
-
<span><span class="ptitle">Emersonian Circles</span><br>
|
|
729
|
-
<span class="ptag">An independent project built on Cloud Bongos.</span></span></span></td>
|
|
730
|
-
<td class="colType">—</td>
|
|
731
|
-
<td class="right num">1</td>
|
|
732
|
-
<td class="colTags"><span class="tags">core</span></td>
|
|
733
|
-
<td class="right colStatus"><span class="chip calm"><span class="cdot"></span>—</span></td>
|
|
734
|
-
<td class="colHall"></td>
|
|
735
|
-
<td class="colGo"><a class="btn small ghost" href="https://emersonian-circles.cloudbongos.com" target="_blank" rel="noopener">Open →</a></td>
|
|
736
|
-
</tr>
|
|
737
|
-
<tr data-generated>
|
|
738
|
-
<td class="colName"><span class="pname"><span class="pdot" style="--acc:var(--sea)"></span>
|
|
739
|
-
<span><span class="ptitle">Off the Boats</span> <span class="pill">you build here</span><br>
|
|
740
|
-
<span class="ptag">A singular shop, and a broader videogame in a persistent ancient Greek world that collides with modern day commerce & products.</span></span></span></td>
|
|
741
|
-
<td class="colType"><span class="typeTag">Game</span></td>
|
|
742
|
-
<td class="right num">11</td>
|
|
743
|
-
<td class="colTags"><span class="tags"><span>art-pipeline</span> <span>character-anim</span> <span>demo</span> <span>+1</span></span></td>
|
|
744
|
-
<td class="right colStatus"><span class="chip calm"><span class="cdot"></span>—</span></td>
|
|
745
|
-
<td class="colHall"></td>
|
|
746
|
-
<td class="colGo"><a class="btn small ghost" href="https://amazonprimea.com" target="_blank" rel="noopener">Open →</a></td>
|
|
747
|
-
</tr>
|
|
748
|
-
</tbody>
|
|
749
|
-
</table>
|
|
750
|
-
<p class="finePrint" style="text-align:center">Sort by Project or Builders.</p>
|
|
751
|
-
</div>
|
|
752
|
-
|
|
753
|
-
<div class="cardScrim" id="cardScrim" hidden>
|
|
754
|
-
<div class="projCard has-art" id="projCard" role="dialog" aria-modal="true" aria-labelledby="cardName">
|
|
755
|
-
<button type="button" class="cardX" id="cardClose" aria-label="Close"><svg aria-hidden="true"><use href="#i-close"></use></svg></button>
|
|
756
|
-
<img class="cardArt" id="cardArt" src="../../../../modules/public-landing/public/assets/world/og-card.jpg" alt="">
|
|
757
|
-
<p class="cardFigs" id="cardFigs">
|
|
758
|
-
<span class="cardCall a" id="figA"><svg class="lead" viewBox="0 0 68 26" preserveAspectRatio="none" aria-hidden="true"><line x1="0" y1="25" x2="67" y2="1" stroke="currentColor" stroke-width="1" vector-effect="non-scaling-stroke"/></svg><span class="fig" id="figABig">9</span><span class="cap">builders</span></span>
|
|
759
|
-
<span class="cardCall b" id="figB"><svg class="lead" viewBox="0 0 68 26" preserveAspectRatio="none" aria-hidden="true"><line x1="0" y1="25" x2="67" y2="1" stroke="currentColor" stroke-width="1" vector-effect="non-scaling-stroke"/></svg><span class="fig" id="figBBig">30+</span><span class="cap">shipped in 30 days</span></span>
|
|
760
|
-
</p>
|
|
761
|
-
<span class="cardDot" id="cardDot" style="--acc:var(--accent)"></span>
|
|
762
|
-
<h3 id="cardName">Cloud Bongos</h3>
|
|
763
|
-
<p class="cardTag" id="cardTag">Building Digitally, as simple as Bongos.</p>
|
|
764
|
-
<p class="cardRel" id="cardRel">you build here</p>
|
|
765
|
-
<p class="cardFaces" id="cardFaces"><img src="https://avatars.githubusercontent.com/u/64553469?v=4" alt=""><img src="https://avatars.githubusercontent.com/u/283020391?v=4" alt=""><img src="https://avatars.githubusercontent.com/u/290184380?v=4" alt=""><img src="https://avatars.githubusercontent.com/u/295990394?v=4" alt=""><img src="https://avatars.githubusercontent.com/u/35337514?v=4" alt=""><span class="facesMore" id="facesMore">+4</span></p>
|
|
766
|
-
<dl class="cardMeta" id="cardMeta">
|
|
767
|
-
<dt id="cardTypeL" data-fact="Type" hidden>Type</dt><dd id="cardType" data-fact="Type" hidden></dd>
|
|
768
|
-
<dt id="cardRunsL" data-fact="Runs">Runs</dt><dd id="cardRuns" data-fact="Runs">cloudbongos.com</dd>
|
|
769
|
-
<dt id="cardOwnerL" data-fact="Owner">Owner</dt><dd id="cardOwner" data-fact="Owner"><img class="ownerAv" src="https://avatars.githubusercontent.com/u/283020391?v=4" alt=""><span class="cardOwnerName" id="cardOwnerName">lars589</span></dd>
|
|
770
|
-
<dt id="cardListedL" data-fact="Listed">Listed</dt><dd id="cardListed" data-fact="Listed">Jul 14, 2026</dd>
|
|
771
|
-
</dl>
|
|
772
|
-
<div class="cardActions" id="cardActions"><a class="pcDoor cardOpen" id="cardOpen" href="https://cloudbongos.com">Open site</a><a class="pcHall cardHall" id="cardHall" href="https://builders.cloudbongos.com"><svg aria-hidden="true"><use href="#i-hall"></use></svg>Builders' hall</a></div>
|
|
773
|
-
</div>
|
|
774
|
-
</div>
|
|
775
|
-
</section>
|
|
776
|
-
|
|
777
|
-
<section id="view-mine" hidden>
|
|
778
|
-
<div class="wrap viewWrap">
|
|
779
|
-
<div class="hero" style="padding-left:0;padding-right:0">
|
|
780
|
-
<h2 class="viewTitle">Your projects</h2>
|
|
781
|
-
<p class="lede">Every project you own — what it is, whether it is answering, and the controls that matter.
|
|
782
|
-
Each card says what the platform <b>last verified</b>, and when.</p>
|
|
783
|
-
</div>
|
|
784
|
-
|
|
785
|
-
<div class="card">
|
|
786
|
-
<section id="gate" hidden>
|
|
787
|
-
<p class="lede">Every project you own, in one place — its live status, its address, and the controls that matter. Sign in with GitHub to see yours.</p>
|
|
788
|
-
<a class="btn" id="signin" href="/api/bongos/auth/web/start?return=/projects%3Fview%3Dmine">
|
|
789
|
-
<svg class="gh" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
|
|
790
|
-
Sign in with GitHub
|
|
791
|
-
</a>
|
|
792
|
-
</section>
|
|
793
|
-
|
|
794
|
-
<section id="mine">
|
|
795
|
-
<div class="mineBar" id="mineBar">
|
|
796
|
-
<div class="search">
|
|
797
|
-
<svg viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="M20 20l-3.5-3.5"/></svg>
|
|
798
|
-
<input type="text" id="mineQ" placeholder="Search your projects by name, repo or address…" aria-label="Search your projects">
|
|
799
|
-
<span class="count" id="mineCount"></span>
|
|
800
|
-
</div>
|
|
801
|
-
<div class="filters" role="group" aria-label="Filter by state">
|
|
802
|
-
<button type="button" data-f="all" aria-controls="projectsList" aria-pressed="true">All <span class="n">0</span></button>
|
|
803
|
-
<button type="button" data-f="live" aria-controls="projectsList" aria-pressed="false">Live <span class="n">0</span></button>
|
|
804
|
-
<button type="button" data-f="attention" aria-controls="projectsList" aria-pressed="false">Needs you <span class="n">0</span></button>
|
|
805
|
-
<button type="button" data-f="working" aria-controls="projectsList" aria-pressed="false">Working <span class="n">0</span></button>
|
|
806
|
-
<button type="button" data-f="gone" aria-controls="projectsList" aria-pressed="false">Torn down <span class="n">0</span></button>
|
|
807
|
-
</div>
|
|
808
|
-
</div>
|
|
809
|
-
|
|
810
|
-
<section class="empty" id="empty">
|
|
811
|
-
<p>You don't own any projects yet. Name one, pick a home for its code, and it gets an address of its own in this sky.</p>
|
|
812
|
-
<a class="btn" href="?view=new" data-nav-to="new">Create your first project</a>
|
|
813
|
-
</section>
|
|
814
|
-
<ul class="projects" id="projectsList"></ul>
|
|
815
|
-
<p class="finePrint">Buttons here ask the platform to act; each card reports only what was verified, and when. A standup keeps going even with this tab closed.</p>
|
|
816
|
-
</section>
|
|
817
|
-
</div>
|
|
818
|
-
</div>
|
|
819
|
-
</section>
|
|
820
|
-
|
|
821
|
-
<section id="view-new" hidden>
|
|
822
|
-
<div class="wrap viewWrap">
|
|
823
|
-
<div class="card">
|
|
824
|
-
<ol class="steps" aria-label="Creation steps">
|
|
825
|
-
<li class="now" data-step="1" aria-current="step"><span class="snum">1</span><span class="slbl">Name</span></li>
|
|
826
|
-
<li data-step="2"><span class="snum">2</span><span class="slbl">Type</span></li>
|
|
827
|
-
<li data-step="3"><span class="snum">3</span><span class="slbl">Home</span></li>
|
|
828
|
-
<li data-step="4"><span class="snum">4</span><span class="slbl">Address</span></li>
|
|
829
|
-
<li data-step="5"><span class="snum">5</span><span class="slbl">Create</span></li>
|
|
830
|
-
</ol>
|
|
831
|
-
|
|
832
|
-
<div class="createSplit">
|
|
833
|
-
<div>
|
|
834
|
-
<section class="panel" id="panel-gate" aria-labelledby="gate-h">
|
|
835
|
-
<h2 class="viewTitle" id="gate-h">Create a project</h2>
|
|
836
|
-
<p class="lede">Your own <strong data-brand-product-inline>Cloud Bongos</strong> project: its own repository, its own home on the web, and a hall of AI builders who do the building. You set the direction; agents lay down the code. Sign in with GitHub so the project belongs to <em>you</em> from the very first beat.</p>
|
|
837
|
-
<a class="btn big" id="wizSignin" href="/api/bongos/auth/web/start?return=/projects%3Fview%3Dnew&repos=1">
|
|
838
|
-
<svg class="gh" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
|
|
839
|
-
Sign in with GitHub
|
|
840
|
-
</a>
|
|
841
|
-
<p class="finePrint" id="wizScopeNote">Signing in asks GitHub for repository access. GitHub words this as access to <em>all</em> your repositories — that is the only permission it offers that can write to a private repo. We use it to create (or read) the one repo your project lives in and push its starting files. Nothing else is touched.</p>
|
|
842
|
-
<p class="finePrint">Free while we find our feet. Your project’s repo and server are yours —
|
|
843
|
-
<span data-brand-product-inline>Cloud Bongos</span> is <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank" rel="noopener">open source (AGPL-3.0)</a>
|
|
844
|
-
and capture-resistant by design.</p>
|
|
845
|
-
</section>
|
|
846
|
-
|
|
847
|
-
<section class="panel on" id="panel-name" aria-labelledby="name-h">
|
|
848
|
-
<h2 class="viewTitle" id="name-h">Start a project</h2>
|
|
849
|
-
<p class="lede">Your own project: its own repository, its own home on the web, and a hall of AI builders
|
|
850
|
-
who do the building. You set the direction; agents lay down the code.</p>
|
|
851
|
-
<form id="newForm" data-next="2">
|
|
852
|
-
<label class="wizField"><span>Project name</span>
|
|
853
|
-
<input type="text" id="newName" placeholder="What should it be called?" autocomplete="off" maxlength="80" aria-label="Project name">
|
|
854
|
-
<div class="hint" id="h-name"> </div>
|
|
855
|
-
</label>
|
|
856
|
-
<div class="nav">
|
|
857
|
-
<span></span>
|
|
858
|
-
<button type="submit" class="btn">Continue →</button>
|
|
859
|
-
</div>
|
|
860
|
-
</form>
|
|
861
|
-
<p class="finePrint">Free while we find our feet. Your project’s repo and server are yours —
|
|
862
|
-
<span data-brand-product-inline>Cloud Bongos</span> is <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank" rel="noopener">open source (AGPL-3.0)</a>
|
|
863
|
-
and capture-resistant by design.</p>
|
|
864
|
-
</section>
|
|
865
|
-
</div>
|
|
866
|
-
|
|
867
|
-
<div class="bongoCell">
|
|
868
|
-
<svg class="bongos" viewBox="0 0 440 320" role="img" aria-label="A pair of bongo drums" style="--skin-hi:#fffdf7;--skin-mid:#f4e6cd;--skin-lo:#cdb896;--drum-shadow:#000000">
|
|
869
|
-
<defs>
|
|
870
|
-
<linearGradient id="shellBig" x1="0" y1="0" x2="1" y2="0.35">
|
|
871
|
-
<stop offset="0%" stop-color="var(--accent-deep)"/><stop offset="16%" stop-color="var(--accent)"/>
|
|
872
|
-
<stop offset="48%" stop-color="var(--accent)"/><stop offset="86%" stop-color="var(--accent-deep)"/>
|
|
873
|
-
<stop offset="100%" stop-color="var(--accent-deep)"/>
|
|
874
|
-
</linearGradient>
|
|
875
|
-
<linearGradient id="shellSml" x1="0" y1="0" x2="1" y2="0.35">
|
|
876
|
-
<stop offset="0%" stop-color="var(--accent-deep)"/><stop offset="18%" stop-color="var(--terracotta)"/>
|
|
877
|
-
<stop offset="55%" stop-color="var(--terracotta)"/><stop offset="100%" stop-color="var(--accent-deep)"/>
|
|
878
|
-
</linearGradient>
|
|
879
|
-
<radialGradient id="skin" cx="0.36" cy="0.26" r="0.9">
|
|
880
|
-
<stop offset="0%" stop-color="var(--skin-hi)"/><stop offset="58%" stop-color="var(--skin-mid)"/>
|
|
881
|
-
<stop offset="100%" stop-color="var(--skin-lo)"/>
|
|
882
|
-
</radialGradient>
|
|
883
|
-
<radialGradient id="halo" cx="0.5" cy="0.5" r="0.5">
|
|
884
|
-
<stop offset="0%" stop-color="var(--accent)" stop-opacity="0.30"/>
|
|
885
|
-
<stop offset="48%" stop-color="var(--accent)" stop-opacity="0.13"/>
|
|
886
|
-
<stop offset="100%" stop-color="var(--accent)" stop-opacity="0"/>
|
|
887
|
-
</radialGradient>
|
|
888
|
-
<filter id="soft" x="-60%" y="-160%" width="220%" height="420%"><feGaussianBlur stdDeviation="9"/></filter>
|
|
889
|
-
</defs>
|
|
890
|
-
<ellipse class="glow" cx="222" cy="170" rx="215" ry="140" fill="url(#halo)"/>
|
|
891
|
-
<ellipse class="bshadow" cx="220" cy="286" rx="142" ry="14" fill="var(--drum-shadow)" opacity=".22" filter="url(#soft)"/>
|
|
892
|
-
<path d="M 214,196 C 232,188 250,188 264,196 L 258,232 C 244,225 230,225 219,232 Z" fill="var(--accent-deep)"/>
|
|
893
|
-
<path d="M 214,196 C 232,188 250,188 264,196 L 262,205 C 247,197 231,197 216,205 Z" fill="var(--ink)" opacity=".22"/>
|
|
894
|
-
<g class="drumBig">
|
|
895
|
-
<path d="M 74,118 C 76,166 90,228 98,266 A 52,17 0 0 0 202,266 C 210,228 224,166 226,118 Z" fill="url(#shellBig)"/>
|
|
896
|
-
<path d="M 172,124 C 174,176 186,232 192,268 A 52,17 0 0 0 202,266 C 210,228 224,166 226,118 Z" fill="var(--ink)" opacity=".17"/>
|
|
897
|
-
<path d="M 92,126 C 94,174 104,230 110,266 A 52,17 0 0 1 100,267 C 92,230 78,172 76,124 Z" fill="#fff" opacity=".20"/>
|
|
898
|
-
<ellipse cx="150" cy="121" rx="80" ry="29" fill="var(--accent-deep)"/>
|
|
899
|
-
<ellipse cx="150" cy="117" rx="80" ry="29" fill="var(--accent)"/>
|
|
900
|
-
<ellipse cx="150" cy="117" rx="80" ry="29" fill="#fff" opacity=".13"/>
|
|
901
|
-
<ellipse cx="150" cy="118" rx="70" ry="24" fill="url(#skin)"/>
|
|
902
|
-
<ellipse cx="150" cy="118" rx="70" ry="24" fill="none" stroke="var(--ink)" stroke-opacity=".09" stroke-width="1.4"/>
|
|
903
|
-
<ellipse cx="150" cy="118" rx="55" ry="18" fill="none" stroke="var(--ink)" stroke-opacity=".045" stroke-width="1"/>
|
|
904
|
-
<g fill="var(--accent-deep)">
|
|
905
|
-
<path d="M 78,138 l 9,0 -1.5,20 -6,0 z"/><path d="M 120,148 l 9,0 -1,21 -7,0 z"/>
|
|
906
|
-
<path d="M 172,148 l 9,0 -1,21 -7,0 z"/><path d="M 214,138 l 9,0 -1.5,20 -6,0 z"/>
|
|
907
|
-
</g>
|
|
908
|
-
</g>
|
|
909
|
-
<g class="drumSml">
|
|
910
|
-
<path d="M 240,134 C 242,178 252,230 258,266 A 40,13 0 0 0 338,266 C 344,230 354,178 356,134 Z" fill="url(#shellSml)"/>
|
|
911
|
-
<path d="M 314,140 C 316,186 324,234 328,268 A 40,13 0 0 0 338,266 C 344,230 354,178 356,134 Z" fill="var(--ink)" opacity=".19"/>
|
|
912
|
-
<path d="M 254,140 C 256,182 264,232 268,266 A 40,13 0 0 1 260,267 C 254,232 244,182 242,138 Z" fill="#fff" opacity=".17"/>
|
|
913
|
-
<ellipse cx="296" cy="137" rx="60" ry="22" fill="var(--accent-deep)"/>
|
|
914
|
-
<ellipse cx="296" cy="133" rx="60" ry="22" fill="var(--terracotta)"/>
|
|
915
|
-
<ellipse cx="296" cy="133" rx="60" ry="22" fill="#fff" opacity=".13"/>
|
|
916
|
-
<ellipse cx="296" cy="134" rx="51" ry="18" fill="url(#skin)"/>
|
|
917
|
-
<ellipse cx="296" cy="134" rx="51" ry="18" fill="none" stroke="var(--ink)" stroke-opacity=".09" stroke-width="1.4"/>
|
|
918
|
-
<ellipse cx="296" cy="134" rx="39" ry="13" fill="none" stroke="var(--ink)" stroke-opacity=".045" stroke-width="1"/>
|
|
919
|
-
<g fill="var(--accent-deep)">
|
|
920
|
-
<path d="M 243,152 l 8,0 -1,17 -6,0 z"/><path d="M 276,160 l 8,0 -1,18 -6,0 z"/>
|
|
921
|
-
<path d="M 312,160 l 8,0 -1,18 -6,0 z"/><path d="M 345,152 l 8,0 -1,17 -6,0 z"/>
|
|
922
|
-
</g>
|
|
923
|
-
</g>
|
|
924
|
-
</svg>
|
|
925
|
-
</div>
|
|
926
|
-
</div>
|
|
927
|
-
</div>
|
|
928
|
-
</div>
|
|
929
|
-
</section>
|
|
930
|
-
</main>
|
|
931
|
-
|
|
932
|
-
<footer class="foot"><!--apex-only:start--><span>A non-profit, capture-resistant commons. </span><!--apex-only:end-->Built by agents, on <span data-brand-product-inline>Cloud Bongos</span>. <a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank" rel="noopener">Open source (AGPL-3.0)</a>.<nav class="footNav" aria-label="Site"><a href="/privacy">Privacy</a><a href="/terms">Terms</a><a href="/contact">Contact</a></nav></footer>
|
|
933
|
-
|
|
934
|
-
<div id="board" hidden></div>
|
|
935
|
-
|
|
936
|
-
<script>
|
|
937
|
-
/* The mock's state contract. It reads ?state= once on load and applies ONE state; the default is
|
|
938
|
-
in-map. ?mode= is handled by the pre-paint script in <head>. No JS motion, and no markup built from strings: every
|
|
939
|
-
string is markup or textContent, every board specimen is a cloneNode of the real component. */
|
|
940
|
-
(function () {
|
|
941
|
-
var $ = function (id) { return document.getElementById(id); };
|
|
942
|
-
var AV = 'https://avatars.githubusercontent.com/u/';
|
|
943
|
-
|
|
944
|
-
var STATES = {
|
|
945
|
-
'out-map': { on: 0, view: 'map', sub: 'sky' },
|
|
946
|
-
'in-map': { on: 1, view: 'map', sub: 'sky' },
|
|
947
|
-
'in-map-projects': { on: 1, view: 'map', sub: 'sky', menu: 'projects' },
|
|
948
|
-
'in-map-profile': { on: 1, view: 'map', sub: 'sky', menu: 'profile' },
|
|
949
|
-
'in-map-focus': { on: 1, view: 'map', sub: 'sky', menu: 'projects', ring: 1 },
|
|
950
|
-
'in-map-search': { on: 1, view: 'map', sub: 'sky', q: 'emer' },
|
|
951
|
-
'in-mine': { on: 1, view: 'mine' },
|
|
952
|
-
'in-new': { on: 1, view: 'new' },
|
|
953
|
-
'out-new': { on: 0, view: 'new' },
|
|
954
|
-
'in-table': { on: 1, view: 'map', sub: 'table' },
|
|
955
|
-
'card': { on: 1, view: 'map', sub: 'sky', card: 'self' },
|
|
956
|
-
'card-member': { on: 1, view: 'map', sub: 'sky', card: 'otb' },
|
|
957
|
-
'card-noart': { on: 1, view: 'map', sub: 'sky', card: 'self', noart: 1 },
|
|
958
|
-
'card-nofaces': { on: 1, view: 'map', sub: 'sky', card: 'self', nofaces: 1 },
|
|
959
|
-
'card-onefig': { on: 1, view: 'map', sub: 'sky', card: 'self', onefig: 1 },
|
|
960
|
-
'card-nofig': { on: 1, view: 'map', sub: 'sky', card: 'self', nofig: 1 },
|
|
961
|
-
'card-floor': { on: 1, view: 'map', sub: 'sky', card: 'self', floor: 1 }
|
|
962
|
-
};
|
|
963
|
-
|
|
964
|
-
var CARDS = {
|
|
965
|
-
self: {
|
|
966
|
-
acc: 'var(--accent)', name: 'Cloud Bongos', tag: 'Building Digitally, as simple as Bongos.',
|
|
967
|
-
rel: 'you build here', art: 1,
|
|
968
|
-
faces: [AV + '64553469?v=4', AV + '283020391?v=4', AV + '290184380?v=4', AV + '295990394?v=4', AV + '35337514?v=4'],
|
|
969
|
-
more: '+4', builders: '9', shipped: '30+',
|
|
970
|
-
type: '', runs: 'cloudbongos.com', owner: 'lars589', ownerAv: AV + '283020391?v=4', listed: 'Jul 14, 2026',
|
|
971
|
-
site: 'https://cloudbongos.com', hall: 'https://builders.cloudbongos.com'
|
|
972
|
-
},
|
|
973
|
-
otb: {
|
|
974
|
-
acc: 'var(--sea)', name: 'Off the Boats',
|
|
975
|
-
tag: 'A singular shop, and a broader videogame in a persistent ancient Greek world that collides with modern day commerce & products.',
|
|
976
|
-
rel: 'you build here', art: 0,
|
|
977
|
-
faces: [AV + '283020391?v=4', AV + '293641659?v=4', AV + '290184380?v=4', AV + '295990394?v=4', AV + '35337514?v=4'],
|
|
978
|
-
more: '+8', builders: '13', shipped: '0',
|
|
979
|
-
type: 'Game', runs: 'amazonprimea.com', owner: 'lars589',
|
|
980
|
-
ownerAv: AV + '283020391?v=4', listed: 'Jul 15, 2026',
|
|
981
|
-
site: 'https://amazonprimea.com', hall: ''
|
|
982
|
-
}
|
|
983
|
-
};
|
|
984
|
-
|
|
985
|
-
/* the field's starfield: the same deterministic walk the live page runs (projects.html:2272) */
|
|
986
|
-
(function starfield() {
|
|
987
|
-
var frag = document.createDocumentFragment();
|
|
988
|
-
for (var i = 0; i < 90; i++) {
|
|
989
|
-
var s = document.createElement('i');
|
|
990
|
-
s.style.left = ((i * 37 + 11) % 100) + '%';
|
|
991
|
-
s.style.top = ((i * 61 + 7) % 100) + '%';
|
|
992
|
-
s.style.opacity = (0.25 + ((i * 13) % 50) / 100).toFixed(2);
|
|
993
|
-
frag.appendChild(s);
|
|
994
|
-
}
|
|
995
|
-
$('mapStars').appendChild(frag);
|
|
996
|
-
})();
|
|
997
|
-
|
|
998
|
-
function each(root, sel, fn) { Array.prototype.forEach.call(root.querySelectorAll(sel), fn); }
|
|
999
|
-
|
|
1000
|
-
/* one function paints the bar, its two bands and the toolbar, scoped to any root: the page for a
|
|
1001
|
-
single state, a cloned row for a board. */
|
|
1002
|
-
function applyBar(root, cfg) {
|
|
1003
|
-
var onView = cfg.view || 'map';
|
|
1004
|
-
each(root, '.signinDoor', function (n) { n.hidden = !!cfg.on; });
|
|
1005
|
-
each(root, '.whoTrig', function (n) { n.hidden = !cfg.on; });
|
|
1006
|
-
each(root, '.qWrap', function (n) { n.hidden = onView !== 'map'; });
|
|
1007
|
-
each(root, '.qToggle', function (n) { n.hidden = onView !== 'map'; });
|
|
1008
|
-
each(root, '.band', function (b) { b.hidden = b.getAttribute('data-menu') !== cfg.menu; });
|
|
1009
|
-
each(root, '.trig', function (t) {
|
|
1010
|
-
t.setAttribute('aria-expanded', t.getAttribute('data-menu') === cfg.menu ? 'true' : 'false');
|
|
1011
|
-
});
|
|
1012
|
-
each(root, '.bandCell[data-view]', function (c) {
|
|
1013
|
-
var now = c.getAttribute('data-view') === onView;
|
|
1014
|
-
c.classList.toggle('is-now', now);
|
|
1015
|
-
var a = c.querySelector('a');
|
|
1016
|
-
if (!a) return;
|
|
1017
|
-
if (now) a.setAttribute('aria-current', 'page'); else a.removeAttribute('aria-current');
|
|
1018
|
-
});
|
|
1019
|
-
each(root, '.qInput', function (i) { i.value = cfg.q || ''; });
|
|
1020
|
-
each(root, '.qCount', function (c) { c.textContent = cfg.q ? '1 of 4' : '4 projects'; });
|
|
1021
|
-
each(root, '.qWrap', function (w) { w.classList.toggle('is-focus', !!cfg.q); });
|
|
1022
|
-
each(root, '.qWrap', function (w) { w.classList.toggle('is-open', !!cfg.q); });
|
|
1023
|
-
each(root, '.qToggle', function (b) { b.setAttribute('aria-expanded', cfg.q ? 'true' : 'false'); });
|
|
1024
|
-
each(root, '.switch', function (s) { s.hidden = !cfg.on; });
|
|
1025
|
-
if (cfg.ring) {
|
|
1026
|
-
each(root, '#menuProjects .bandCell:nth-child(2) .bandT, .band[data-menu="projects"] .bandCell:nth-child(2) .bandT',
|
|
1027
|
-
function (a) { a.classList.add('is-focus'); });
|
|
1028
|
-
each(root, '.whoTrig', function (t) { t.classList.add('is-focus'); });
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
function applyCard(card, d, opt) {
|
|
1033
|
-
var art = !!d.art && !opt.noart && !opt.floor;
|
|
1034
|
-
card.classList.toggle('has-art', art);
|
|
1035
|
-
each(card, '.cardArt', function (n) { n.hidden = !art; });
|
|
1036
|
-
each(card, '.cardDot', function (n) { n.style.setProperty('--acc', d.acc); });
|
|
1037
|
-
card.querySelector('h3').textContent = d.name;
|
|
1038
|
-
each(card, '.cardTag', function (n) { n.textContent = d.tag; });
|
|
1039
|
-
each(card, '.cardRel', function (n) { n.textContent = d.rel; n.hidden = !d.rel; });
|
|
1040
|
-
|
|
1041
|
-
each(card, '.cardFaces', function (n) { n.hidden = !!opt.nofaces || !!opt.floor; });
|
|
1042
|
-
each(card, '.cardFaces img', function (img, i) { img.src = d.faces[i]; });
|
|
1043
|
-
each(card, '.facesMore', function (n) { n.textContent = d.more; });
|
|
1044
|
-
|
|
1045
|
-
var noA = !!opt.floor || !!opt.nofig;
|
|
1046
|
-
var noB = noA || !!opt.onefig;
|
|
1047
|
-
each(card, '.cardFigs', function (n) { n.hidden = noA; });
|
|
1048
|
-
each(card, '.cardCall.b', function (n) { n.hidden = noB; });
|
|
1049
|
-
each(card, '.cardCall.a .fig', function (n) { n.textContent = d.builders; });
|
|
1050
|
-
each(card, '.cardCall.b .fig', function (n) { n.textContent = d.shipped; });
|
|
1051
|
-
|
|
1052
|
-
each(card, '.cardMeta', function (n) { n.hidden = !!opt.floor; });
|
|
1053
|
-
var pair = function (label, value) {
|
|
1054
|
-
var dd = card.querySelector('dd[data-fact="' + label + '"]');
|
|
1055
|
-
var dt = card.querySelector('dt[data-fact="' + label + '"]');
|
|
1056
|
-
if (!dd || !dt) return;
|
|
1057
|
-
dd.hidden = dt.hidden = !value;
|
|
1058
|
-
if (value && label !== 'Owner') dd.textContent = value;
|
|
1059
|
-
};
|
|
1060
|
-
pair('Type', d.type);
|
|
1061
|
-
pair('Runs', d.runs);
|
|
1062
|
-
pair('Owner', d.owner);
|
|
1063
|
-
pair('Listed', d.listed);
|
|
1064
|
-
each(card, '.cardOwnerName', function (n) { n.textContent = d.owner; });
|
|
1065
|
-
each(card, '.ownerAv', function (n) { n.src = d.ownerAv; });
|
|
1066
|
-
|
|
1067
|
-
each(card, '.cardOpen', function (n) { n.href = d.site; });
|
|
1068
|
-
each(card, '.cardHall', function (n) { n.hidden = !d.hall || !!opt.floor; if (d.hall) n.href = d.hall; });
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
/* board specimens are clones of the real components; ids are stripped so the page keeps one of
|
|
1072
|
-
each and a scoped query inside a row can never reach out of it. */
|
|
1073
|
-
function clone(node) {
|
|
1074
|
-
var c = node.cloneNode(true);
|
|
1075
|
-
c.removeAttribute('id');
|
|
1076
|
-
c.removeAttribute('hidden');
|
|
1077
|
-
each(c, '[id]', function (n) { n.removeAttribute('id'); });
|
|
1078
|
-
return c;
|
|
1079
|
-
}
|
|
1080
|
-
function labelled(parent, text, cls) {
|
|
1081
|
-
var wrap = document.createElement('div');
|
|
1082
|
-
wrap.className = cls;
|
|
1083
|
-
var lbl = document.createElement('span');
|
|
1084
|
-
lbl.className = 'boardLbl';
|
|
1085
|
-
lbl.textContent = text;
|
|
1086
|
-
wrap.appendChild(lbl);
|
|
1087
|
-
parent.appendChild(wrap);
|
|
1088
|
-
return wrap;
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
var state = new URLSearchParams(location.search || location.hash.slice(1) || (window.__Q || '')).get('state') || 'in-map';
|
|
1092
|
-
var board = $('board');
|
|
1093
|
-
var header = document.querySelector('header.bar');
|
|
1094
|
-
var bandP = $('menuProjects');
|
|
1095
|
-
var bandU = $('menuProfile');
|
|
1096
|
-
var toolbar = document.querySelector('.toolbar');
|
|
1097
|
-
var scrim = $('cardScrim');
|
|
1098
|
-
var card = $('projCard');
|
|
1099
|
-
|
|
1100
|
-
if (state.indexOf('board-') === 0) {
|
|
1101
|
-
document.querySelector('.sky').hidden = true;
|
|
1102
|
-
document.querySelector('.skip').hidden = true;
|
|
1103
|
-
header.hidden = true;
|
|
1104
|
-
bandP.hidden = true;
|
|
1105
|
-
bandU.hidden = true;
|
|
1106
|
-
$('hubMain').hidden = true;
|
|
1107
|
-
document.querySelector('.foot').hidden = true;
|
|
1108
|
-
board.hidden = false;
|
|
1109
|
-
|
|
1110
|
-
var title = document.createElement('p');
|
|
1111
|
-
title.className = 'boardTitle';
|
|
1112
|
-
board.appendChild(title);
|
|
1113
|
-
|
|
1114
|
-
if (state === 'board-bar') {
|
|
1115
|
-
title.textContent = 'v2 the hairline / the bar, every state';
|
|
1116
|
-
['out-map', 'in-map', 'in-map-projects', 'in-map-profile', 'in-map-focus', 'in-map-search', 'in-mine', 'in-new']
|
|
1117
|
-
.forEach(function (s) {
|
|
1118
|
-
var row = labelled(board, s, 'boardRow');
|
|
1119
|
-
var h = clone(header); var b1 = clone(bandP); var b2 = clone(bandU); var tb = clone(toolbar);
|
|
1120
|
-
row.appendChild(h); row.appendChild(b1); row.appendChild(b2); row.appendChild(tb);
|
|
1121
|
-
var cfg = STATES[s];
|
|
1122
|
-
applyBar(row, cfg);
|
|
1123
|
-
tb.hidden = cfg.view !== 'map';
|
|
1124
|
-
});
|
|
1125
|
-
} else if (state === 'board-card') {
|
|
1126
|
-
title.textContent = 'v2 the hairline / the poster card, the whole ladder';
|
|
1127
|
-
var grid = document.createElement('div');
|
|
1128
|
-
grid.className = 'boardGrid';
|
|
1129
|
-
board.appendChild(grid);
|
|
1130
|
-
['card', 'card-member', 'card-noart', 'card-nofaces', 'card-onefig', 'card-nofig', 'card-floor']
|
|
1131
|
-
.forEach(function (s) {
|
|
1132
|
-
var cell = labelled(grid, s, 'boardCell');
|
|
1133
|
-
var c = clone(card);
|
|
1134
|
-
cell.appendChild(c);
|
|
1135
|
-
applyCard(c, CARDS[STATES[s].card], STATES[s]);
|
|
1136
|
-
});
|
|
1137
|
-
} else if (state === 'board-menu') {
|
|
1138
|
-
title.textContent = 'v2 the hairline / the band and the search, component states';
|
|
1139
|
-
var specs = [
|
|
1140
|
-
['the trigger, closed', 'projects', null, null],
|
|
1141
|
-
['the band, open', 'projects', 'projects', null],
|
|
1142
|
-
['keyboard focus on an item', 'projects', 'projects', 'focus'],
|
|
1143
|
-
['hover on an item', 'projects', 'projects', 'hover'],
|
|
1144
|
-
['the profile band, open', 'profile', 'profile', null]
|
|
1145
|
-
];
|
|
1146
|
-
specs.forEach(function (sp) {
|
|
1147
|
-
var row = labelled(board, sp[0], 'boardSpec');
|
|
1148
|
-
var h = clone(header); var b1 = clone(bandP); var b2 = clone(bandU);
|
|
1149
|
-
row.appendChild(h); row.appendChild(b1); row.appendChild(b2);
|
|
1150
|
-
applyBar(row, { on: 1, view: 'map', menu: sp[2] });
|
|
1151
|
-
if (sp[3] === 'focus') each(row, '.band:not([hidden]) .bandCell:nth-child(2) .bandT', function (a) { a.classList.add('is-focus'); });
|
|
1152
|
-
if (sp[3] === 'hover') each(row, '.band:not([hidden]) .bandCell:nth-child(2)', function (c) { c.classList.add('is-hover'); });
|
|
1153
|
-
});
|
|
1154
|
-
[['the search, at rest', '', 0], ['the search, focused', '', 1], ['the search, with a value', 'emer', 0]]
|
|
1155
|
-
.forEach(function (sp) {
|
|
1156
|
-
var row = labelled(board, sp[0], 'boardSpec');
|
|
1157
|
-
var q = clone(document.querySelector('.qWrap'));
|
|
1158
|
-
row.appendChild(q);
|
|
1159
|
-
each(q, '.qInput', function (i) { i.value = sp[1]; });
|
|
1160
|
-
each(q, '.qCount', function (c) { c.textContent = sp[1] ? '1 of 4' : '4 projects'; });
|
|
1161
|
-
if (sp[2]) q.classList.add('is-focus');
|
|
1162
|
-
});
|
|
1163
|
-
}
|
|
1164
|
-
return;
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
var cfg = STATES[state] || STATES['in-map'];
|
|
1168
|
-
applyBar(document, cfg);
|
|
1169
|
-
['map', 'mine', 'new'].forEach(function (v) { $('view-' + v).hidden = (v !== cfg.view); });
|
|
1170
|
-
$('pageH1').textContent = cfg.view === 'mine' ? 'Your projects'
|
|
1171
|
-
: cfg.view === 'new' ? (cfg.on ? 'Start a project' : 'Create a project')
|
|
1172
|
-
: 'The project map';
|
|
1173
|
-
$('sub-sky-body').hidden = cfg.sub === 'table';
|
|
1174
|
-
$('sub-table-body').hidden = cfg.sub !== 'table';
|
|
1175
|
-
$('sub-sky').setAttribute('aria-pressed', cfg.sub === 'table' ? 'false' : 'true');
|
|
1176
|
-
$('sub-table').setAttribute('aria-pressed', cfg.sub === 'table' ? 'true' : 'false');
|
|
1177
|
-
$('gate').hidden = !!cfg.on;
|
|
1178
|
-
$('mine').hidden = !cfg.on;
|
|
1179
|
-
$('panel-gate').classList.toggle('on', !cfg.on);
|
|
1180
|
-
$('panel-name').classList.toggle('on', !!cfg.on);
|
|
1181
|
-
|
|
1182
|
-
/* the spotlight is the live page's, not this version's: a query dims what does not match and
|
|
1183
|
-
leaves it as backdrop, out of the tab order. */
|
|
1184
|
-
if (cfg.q) {
|
|
1185
|
-
each(document, '.worldOrb', function (o) {
|
|
1186
|
-
var hit = /emersonian/i.test(o.textContent);
|
|
1187
|
-
o.classList.add(hit ? 'match' : 'dim');
|
|
1188
|
-
if (!hit) { o.setAttribute('aria-hidden', 'true'); o.tabIndex = -1; }
|
|
1189
|
-
});
|
|
1190
|
-
$('mapQ').value = 'emer';
|
|
1191
|
-
document.querySelector('.qWrap').classList.add('is-focus');
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
if (cfg.card) {
|
|
1195
|
-
scrim.hidden = false;
|
|
1196
|
-
applyCard(card, CARDS[cfg.card], cfg);
|
|
1197
|
-
}
|
|
1198
|
-
|
|
1199
|
-
/* the disclosure: Escape closes and hands focus back, a click outside closes, the arrows walk
|
|
1200
|
-
the items. The open move itself is CSS, so the kill switch owns it. */
|
|
1201
|
-
/* the folded search (under 480): the magnifier opens one row under the bar and hands focus to
|
|
1202
|
-
the field; Escape folds it and returns focus; an opening menu folds it. Above 480 the class
|
|
1203
|
-
is inert: the field is always in the bar. */
|
|
1204
|
-
var qWrap = document.querySelector('.qWrap');
|
|
1205
|
-
var qToggle = document.querySelector('.qToggle');
|
|
1206
|
-
function setSearch(open) {
|
|
1207
|
-
qWrap.classList.toggle('is-open', open);
|
|
1208
|
-
qToggle.setAttribute('aria-expanded', open ? 'true' : 'false');
|
|
1209
|
-
}
|
|
1210
|
-
qToggle.addEventListener('click', function () {
|
|
1211
|
-
var open = qToggle.getAttribute('aria-expanded') !== 'true';
|
|
1212
|
-
setSearch(open);
|
|
1213
|
-
if (open) $('mapQ').focus();
|
|
1214
|
-
});
|
|
1215
|
-
|
|
1216
|
-
each(document, '.trig', function (t) {
|
|
1217
|
-
t.addEventListener('click', function () {
|
|
1218
|
-
setSearch(false);
|
|
1219
|
-
var name = t.getAttribute('data-menu');
|
|
1220
|
-
var open = t.getAttribute('aria-expanded') !== 'true';
|
|
1221
|
-
each(document, '.trig', function (o) { o.setAttribute('aria-expanded', 'false'); });
|
|
1222
|
-
each(document, '.band', function (b) { b.hidden = true; });
|
|
1223
|
-
if (!open) return;
|
|
1224
|
-
t.setAttribute('aria-expanded', 'true');
|
|
1225
|
-
var band = document.querySelector('.band[data-menu="' + name + '"]');
|
|
1226
|
-
band.hidden = false;
|
|
1227
|
-
});
|
|
1228
|
-
});
|
|
1229
|
-
document.addEventListener('keydown', function (ev) {
|
|
1230
|
-
var open = document.querySelector('.band:not([hidden])');
|
|
1231
|
-
if (!open && ev.key === 'Escape' && qWrap.classList.contains('is-open') && getComputedStyle(qToggle).display !== 'none') {
|
|
1232
|
-
setSearch(false);
|
|
1233
|
-
qToggle.focus();
|
|
1234
|
-
return;
|
|
1235
|
-
}
|
|
1236
|
-
if (!open) return;
|
|
1237
|
-
if (ev.key === 'Escape') {
|
|
1238
|
-
var trig = document.querySelector('.trig[aria-expanded="true"]');
|
|
1239
|
-
open.hidden = true;
|
|
1240
|
-
if (trig) { trig.setAttribute('aria-expanded', 'false'); trig.focus(); }
|
|
1241
|
-
return;
|
|
1242
|
-
}
|
|
1243
|
-
if (ev.key !== 'ArrowDown' && ev.key !== 'ArrowUp') return;
|
|
1244
|
-
var items = Array.prototype.slice.call(open.querySelectorAll('a'));
|
|
1245
|
-
var at = items.indexOf(document.activeElement);
|
|
1246
|
-
ev.preventDefault();
|
|
1247
|
-
items[(at + (ev.key === 'ArrowDown' ? 1 : items.length - 1) + items.length) % items.length].focus();
|
|
1248
|
-
});
|
|
1249
|
-
document.addEventListener('click', function (ev) {
|
|
1250
|
-
if (ev.target.closest && (ev.target.closest('.band') || ev.target.closest('.trig'))) return;
|
|
1251
|
-
each(document, '.trig', function (o) { o.setAttribute('aria-expanded', 'false'); });
|
|
1252
|
-
each(document, '.band', function (b) { b.hidden = true; });
|
|
1253
|
-
});
|
|
1254
|
-
})();
|
|
1255
|
-
</script>
|
|
1256
|
-
</body>
|
|
1257
|
-
</html>
|