@bongos/core 1.21.112 → 1.21.114
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 +616 -186
- package/.claude/skills/ask-for-help/SKILL.md +1 -1
- package/.claude/skills/bongos-feedback/SKILL.md +1 -1
- package/.claude/skills/builder-sequence/SKILL.md +1 -1
- package/.claude/skills/builder-ship/SKILL.md +1 -0
- package/GOVERNMENT.md +128 -11
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +28 -0
- package/clients/bongos-client/index.cjs +28 -0
- package/clients/bongos-client/index.d.ts +45 -2
- package/clients/bongos-client/index.mjs +28 -0
- package/docs/adr/0372-an-ask-is-stored-per-docket-matter-and-the-server-refuses-slop.md +33 -0
- package/docs/adr/0373-an-ai-session-files-a-blocker-with-an-ask.md +31 -0
- package/docs/adr/0374-a-building-lead-is-a-held-position-appointed-by-a-people-matter.md +30 -0
- package/docs/adr/0375-who-may-build-without-a-vote-comes-from-the-form-of-government.md +38 -0
- package/docs/adr/0376-every-ask-is-routed-to-a-real-seat-on-the-server.md +30 -0
- package/docs/adr/0377-governance-is-a-held-position-read-on-me.md +24 -0
- package/docs/adr/0378-a-leads-build-outs-are-rows-built-at-once-or-by-a-passed-vote.md +33 -0
- package/docs/adr/0379-the-treasury-is-pots-per-goal-a-reserve-and-borrowing-over-real-spend.md +32 -0
- package/docs/adr/0380-a-strictness-preset-is-a-bundle-of-laws-switched-by-one-laws-vote.md +26 -0
- package/docs/adr/README.md +10 -1
- package/docs/api/openapi.json +989 -87
- package/docs/api-reference.md +18 -4
- package/docs/copy-inventory.md +343 -262
- package/docs/copy-registry.json +1223 -426
- package/docs/file-map.md +2 -1
- package/docs/module-api-changelog.md +4 -0
- package/docs/packs/engineer.md +2 -1
- package/docs/page-inventory.json +91 -6
- package/docs/page-readings.json +5017 -4458
- package/modules/builder-settings/law-locks.js +202 -0
- package/modules/builder-settings/routes/settings.js +66 -6
- package/modules/builder-settings/settings.js +7 -0
- package/modules/discord/ship-broadcast.js +22 -13
- package/modules/government/asks-db.js +54 -0
- package/modules/government/asks.js +269 -0
- package/modules/government/board-idea-reads.js +68 -0
- package/modules/government/board.js +21 -57
- package/modules/government/build-rights.js +148 -0
- package/modules/government/buildouts.js +160 -0
- package/modules/government/counts.js +81 -0
- package/modules/government/db.js +242 -0
- package/modules/government/decision-board.js +234 -8
- package/modules/government/decision-rules.js +2 -0
- package/modules/government/docket.js +114 -6
- package/modules/government/law-board.js +131 -0
- package/modules/government/laws.js +241 -0
- package/modules/government/leads.js +170 -0
- package/modules/government/migrations/government_027_laws.sql +143 -0
- package/modules/government/migrations/government_028_asks.sql +57 -0
- package/modules/government/migrations/government_029_leads.sql +135 -0
- package/modules/government/migrations/government_030_buildouts.sql +111 -0
- package/modules/government/migrations/government_031_treasury.sql +107 -0
- package/modules/government/module.json +2 -1
- package/modules/government/pollers/treasury-borrow.js +62 -0
- package/modules/government/positions.js +107 -0
- package/modules/government/presets.js +149 -0
- package/modules/government/routes/government.js +425 -2
- package/modules/government/routing.js +154 -0
- package/modules/government/treasury-db.js +166 -0
- package/modules/government/treasury.js +241 -0
- package/modules/hall-ui/public/atlas.html +2 -2
- package/modules/hall-ui/public/blockers.html +2 -2
- package/modules/hall-ui/public/board-room.html +2 -2
- package/modules/hall-ui/public/board-room.js +2 -0
- package/modules/hall-ui/public/city-draw.js +604 -11
- package/modules/hall-ui/public/city.css +157 -1
- package/modules/hall-ui/public/city.html +37 -7
- package/modules/hall-ui/public/city.js +441 -21
- package/modules/hall-ui/public/city.states.json +110 -5
- package/modules/hall-ui/public/collab.html +2 -2
- package/modules/hall-ui/public/commands.html +2 -2
- package/modules/hall-ui/public/copy-desk.html +2 -2
- package/modules/hall-ui/public/craft-mode.js +112 -29
- package/modules/hall-ui/public/deploy.html +2 -2
- package/modules/hall-ui/public/diagram-viewer.css +12 -0
- package/modules/hall-ui/public/diagram-viewer.js +4 -0
- package/modules/hall-ui/public/diagrams.html +2 -2
- package/modules/hall-ui/public/drachmae.html +2 -2
- package/modules/hall-ui/public/fleet.html +2 -2
- package/modules/hall-ui/public/gate.html +2 -2
- package/modules/hall-ui/public/goal-map.html +2 -2
- package/modules/hall-ui/public/goals.html +2 -2
- package/modules/hall-ui/public/gov-feeds.js +141 -0
- package/modules/hall-ui/public/gov-living.js +1002 -0
- package/modules/hall-ui/public/gov-positions.js +97 -0
- package/modules/hall-ui/public/government.html +2 -2
- package/modules/hall-ui/public/hall-render.js +3 -0
- package/modules/hall-ui/public/idea.html +2 -2
- package/modules/hall-ui/public/ideas.html +2 -2
- package/modules/hall-ui/public/index.html +3 -3
- package/modules/hall-ui/public/modules.html +2 -2
- package/modules/hall-ui/public/my-agents.css +334 -0
- package/modules/hall-ui/public/my-agents.html +72 -0
- package/modules/hall-ui/public/my-agents.js +603 -0
- package/modules/hall-ui/public/my-agents.states.json +37 -0
- package/modules/hall-ui/public/primer.html +2 -2
- package/modules/hall-ui/public/profile-connections.js +40 -28
- package/modules/hall-ui/public/profile.html +2 -2
- package/modules/hall-ui/public/project-settings.html +2 -2
- package/modules/hall-ui/public/ranks.html +2 -2
- package/modules/hall-ui/public/roadmap.html +2 -2
- package/modules/hall-ui/public/room.css +8 -0
- package/modules/hall-ui/public/roster.html +2 -2
- package/modules/hall-ui/public/sessions.html +2 -2
- package/modules/hall-ui/public/settings.html +2 -2
- package/modules/hall-ui/public/shell.js +116 -16
- package/modules/hall-ui/public/street-card.js +18 -1
- package/modules/hall-ui/public/street-deck.css +299 -0
- package/modules/hall-ui/public/street-deck.js +1145 -0
- package/modules/hall-ui/public/street-depth.js +712 -0
- package/modules/hall-ui/public/street-desk.js +5 -2
- package/modules/hall-ui/public/street-draw.js +109 -16
- package/modules/hall-ui/public/street-inside.js +137 -22
- package/modules/hall-ui/public/street-office.js +705 -0
- package/modules/hall-ui/public/street.css +161 -11
- package/modules/hall-ui/public/street.html +41 -11
- package/modules/hall-ui/public/street.js +78 -66
- package/modules/hall-ui/public/street.states.json +129 -21
- package/modules/hall-ui/public/studio.html +2 -2
- package/modules/hall-ui/public/style.css +5 -1
- package/modules/hall-ui/public/task.html +2 -2
- package/modules/hall-ui/public/thinking.html +2 -2
- package/modules/hall-ui/public/tweak-editor.html +2 -2
- package/modules/hall-ui/public/watch.html +2 -2
- package/modules/hall-ui/public/watch.js +14 -1
- package/modules/hall-ui/public/work.html +2 -2
- package/modules/hall-ui/records/living-city.md +57 -0
- package/modules/hall-ui/records/my-agents.md +21 -0
- package/modules/hall-ui/records/oversight-family.md +1 -0
- package/modules/hall-ui/records/profile-connections.md +10 -0
- package/modules/hall-ui/records/reading-rooms.md +2 -0
- package/modules/ideas/routes/blockers.js +92 -3
- package/modules/lifecycle/module.json +2 -1
- package/modules/lifecycle/moving.js +17 -1
- package/modules/lifecycle/routes/moving.js +6 -0
- package/modules/lifecycle/routes/project-settings.js +23 -0
- package/modules/onboarding/approval-broadcast.js +8 -0
- package/modules/onboarding/routes/access-requests.js +16 -6
- package/modules/platform-identity/connections.js +13 -2
- package/modules/platform-identity/routes/connections.js +7 -1
- package/modules/public-landing/public/account-private.states.json +2 -2
- package/modules/public-landing/public/account.html +65 -5
- package/modules/public-landing/public/account.states.json +3 -3
- package/modules/public-landing/public/assets/world/r2-bongos-chrome-b.jpg.json +1 -1
- package/modules/public-landing/public/assets/world/r2-bongos-chrome-b.webp +0 -0
- package/modules/public-landing/public/assets/world/r2-bongos-chrome-b.webp.json +13 -0
- package/modules/public-landing/public/assets/world/r2-chrome-blob-one.jpg.json +1 -1
- package/modules/public-landing/public/assets/world/r2-chrome-blob-one.webp +0 -0
- package/modules/public-landing/public/assets/world/r2-chrome-blob-one.webp.json +13 -0
- package/modules/public-landing/public/assets/world/r2-chrome-blobs-set.jpg.json +1 -1
- package/modules/public-landing/public/assets/world/r2-chrome-blobs-set.webp +0 -0
- package/modules/public-landing/public/assets/world/r2-chrome-blobs-set.webp.json +13 -0
- package/modules/public-landing/public/assets/world.css +4 -4
- package/modules/public-landing/public/connections-empty.states.json +14 -0
- package/modules/public-landing/public/connections-inactive.states.json +14 -0
- package/modules/public-landing/public/connections.html +450 -0
- package/modules/public-landing/public/connections.probes.json +414 -0
- package/modules/public-landing/public/connections.states.json +17 -0
- package/modules/public-landing/public/contact.html +2 -2
- package/modules/public-landing/public/guild.html +2 -2
- package/modules/public-landing/public/index.html +2 -2
- package/modules/public-landing/public/invitations.html +2 -2
- package/modules/public-landing/public/privacy.html +2 -2
- package/modules/public-landing/public/projects.html +2 -2
- package/modules/public-landing/public/projects.probes.json +6 -2
- package/modules/public-landing/public/terms.html +2 -2
- package/modules/ui-design/kit/fixtures/connections-empty.json +12 -0
- package/modules/ui-design/kit/fixtures/connections-inactive.json +7 -0
- package/modules/ui-design/kit/fixtures/connections.json +22 -0
- package/modules/ui-design/kit/serve.js +95 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +128 -0
- package/scripts/discord/README.md +8 -5
- package/scripts/discord/post.js +12 -1
- package/scripts/gds/artifact-audit.js +20 -3
- package/scripts/gds/ask.js +164 -0
- package/scripts/gds/autobongos-run.js +20 -5
- package/scripts/gds/autobongos-tweak-lane.js +262 -0
- package/scripts/gds/autobongos-verify.js +21 -2
- package/scripts/gds/claim.js +2 -0
- package/scripts/gds/government-walk.js +638 -4
- package/scripts/gds/pulse.js +9 -6
- package/scripts/gds/ship-escalation.js +22 -3
- package/scripts/gds/ship-finish.js +5 -4
- package/scripts/gds/ship-merge-gate.js +18 -6
- package/scripts/gds/tweak-halt.js +1 -0
- package/scripts/hall-preview/README.md +41 -1
- package/scripts/hall-preview/pref-writes.js +140 -0
- package/scripts/hall-preview/refresh-fixtures.js +101 -7
- package/scripts/hall-preview/scrub-identity.js +366 -7
- package/scripts/hall-preview/server.js +27 -1
- package/scripts/render-diagrams.sh +4 -2
- package/src/bongos/auth-idp.js +6 -1
- package/src/bongos/project-settings.js +41 -0
- package/src/bongos/route-rank-check.js +27 -0
- package/src/bongos/routes/me.js +68 -7
- package/src/bongos/serve-internal.js +5 -1
- package/src/module-api.js +7 -1
- package/src/platform-server.js +10 -0
- package/tests/application_lifecycle.mjs +47 -5
- package/tests/autobongos_tweak_lane.mjs +208 -0
- package/tests/conductor_main_e2e.mjs +21 -0
- package/tests/connections_api.mjs +18 -0
- package/tests/craft_mode_nav.mjs +5 -3
- package/tests/craft_mode_tallies.mjs +52 -16
- package/tests/discord_approvals.mjs +11 -0
- package/tests/discord_channels.mjs +20 -0
- package/tests/fixtures/gov-seated.mjs +64 -0
- package/tests/fixtures/government-ask-cards.json +1284 -0
- package/tests/government_act_alone_buildings.mjs +1 -0
- package/tests/government_agent_asks.mjs +322 -0
- package/tests/government_asks.mjs +408 -0
- package/tests/government_build_rights.mjs +253 -0
- package/tests/government_buildouts.mjs +382 -0
- package/tests/government_counts.mjs +143 -0
- package/tests/government_decision_rules.mjs +5 -1
- package/tests/government_laws.mjs +488 -0
- package/tests/government_laws_session.mjs +321 -0
- package/tests/government_leads.mjs +375 -0
- package/tests/government_positions.mjs +127 -0
- package/tests/government_presets.mjs +215 -0
- package/tests/government_routes.mjs +8 -1
- package/tests/government_routing.mjs +118 -0
- package/tests/government_seed.mjs +5 -0
- package/tests/government_treasury.mjs +394 -0
- package/tests/governor_docket.mjs +26 -2
- package/tests/hall_buildouts.mjs +208 -0
- package/tests/hall_city.mjs +14 -6
- package/tests/hall_city_living.mjs +617 -0
- package/tests/hall_gov_counts.mjs +336 -0
- package/tests/hall_gov_living.mjs +636 -0
- package/tests/hall_gov_real_site.mjs +655 -0
- package/tests/hall_matter_card.mjs +6 -1
- package/tests/hall_my_agents.mjs +481 -0
- package/tests/hall_nav.mjs +107 -4
- package/tests/hall_page_gate_map.mjs +4 -0
- package/tests/hall_preview_governor_fixtures.mjs +30 -3
- package/tests/hall_preview_scrub.mjs +59 -1
- package/tests/hall_preview_security.mjs +169 -0
- package/tests/hall_reading_world.mjs +44 -0
- package/tests/hall_roster_world.mjs +6 -2
- package/tests/hall_street.mjs +18 -2
- package/tests/hall_street_amend.mjs +1 -1
- package/tests/hall_street_deck.mjs +609 -0
- package/tests/hall_street_depth.mjs +559 -0
- package/tests/hall_street_desk.mjs +1 -1
- package/tests/hall_street_inside.mjs +29 -5
- package/tests/hall_tweak_editor.mjs +4 -1
- package/tests/hub_account_page.mjs +94 -3
- package/tests/hub_connections_page.mjs +507 -0
- package/tests/hub_invite_badge.mjs +1 -1
- package/tests/idp_device_exchange.mjs +18 -0
- package/tests/landing_legal_pages.mjs +8 -5
- package/tests/landing_page.mjs +23 -4
- package/tests/nav_permission_atoms.mjs +4 -1
- package/tests/profile_connections_ui.mjs +88 -25
- package/tests/projects_hub.mjs +15 -0
- package/tests/render_check.mjs +2 -2
- package/tests/ship_broadcast_routing.mjs +57 -16
- package/tests/ship_broadcast_server.mjs +40 -7
- package/tests/ship_merge_gate.mjs +19 -0
- package/tests/ui_design_kit.mjs +2 -2
- package/tests/watch_applications_queue.mjs +23 -0
|
@@ -31,6 +31,28 @@ body[data-page="street"] {
|
|
|
31
31
|
--street-wash: color-mix(in srgb, var(--ink) 4.5%, transparent);
|
|
32
32
|
--street-crate: color-mix(in srgb, var(--ink) 55%, transparent);
|
|
33
33
|
--street-crate-fill: color-mix(in srgb, var(--ink) 4%, transparent);
|
|
34
|
+
/* the living street (task 1004685): the skyline's faces before the haze,
|
|
35
|
+
the skylanes, the pods, a sitting's shaft (an ink wash: paper cannot
|
|
36
|
+
glow) and the edge that keeps a salmon window legible on paper */
|
|
37
|
+
--street-depth-face: var(--bg-card);
|
|
38
|
+
--street-depth-side: color-mix(in srgb, var(--ink) 10%, var(--bg-card));
|
|
39
|
+
--street-depth-edge: color-mix(in srgb, var(--ink) 22%, transparent);
|
|
40
|
+
--street-depth-lane: color-mix(in srgb, var(--ink) 22%, transparent);
|
|
41
|
+
--street-depth-pod: var(--ink);
|
|
42
|
+
--street-depth-shaft: color-mix(in srgb, var(--ink) 9%, transparent);
|
|
43
|
+
--street-depth-needs-edge: var(--accent-deep);
|
|
44
|
+
/* the planes (integration pass): distance is atmosphere. On paper the far row
|
|
45
|
+
fades into the paper through a cool sea haze, the near row a step nearer,
|
|
46
|
+
a fog band dissolves their feet into the ground line, and a lit road is an
|
|
47
|
+
ink wash (paper cannot glow). Task 1004718 deepened the paper haze: the
|
|
48
|
+
rows read as distance (cooler, bluer) rather than as pale paper */
|
|
49
|
+
--street-depth-haze-near: color-mix(in srgb, var(--sea) 12%, color-mix(in srgb, var(--ink) 10%, var(--bg)));
|
|
50
|
+
--street-depth-haze-near-side: color-mix(in srgb, var(--sea) 13%, color-mix(in srgb, var(--ink) 16%, var(--bg)));
|
|
51
|
+
--street-depth-haze-edge: color-mix(in srgb, var(--sea) 14%, color-mix(in srgb, var(--ink) 10%, transparent));
|
|
52
|
+
--street-depth-haze-far: color-mix(in srgb, var(--sea) 17%, color-mix(in srgb, var(--ink) 5%, var(--bg)));
|
|
53
|
+
--street-depth-fog: color-mix(in srgb, var(--sea) 11%, color-mix(in srgb, var(--ink) 3%, var(--bg)));
|
|
54
|
+
--street-depth-pool: color-mix(in srgb, var(--ink) 13%, transparent);
|
|
55
|
+
--street-depth-lane-w: 1.3px;
|
|
34
56
|
}
|
|
35
57
|
html[data-theme="dark"] body[data-page="street"] {
|
|
36
58
|
--street-rule: color-mix(in srgb, var(--ink) 12%, transparent);
|
|
@@ -38,6 +60,18 @@ html[data-theme="dark"] body[data-page="street"] {
|
|
|
38
60
|
--street-accent-text: color-mix(in srgb, var(--accent) 70%, #ffffff);
|
|
39
61
|
--street-glow: 0 0 20px color-mix(in srgb, var(--accent) 50%, transparent);
|
|
40
62
|
--street-crate: color-mix(in srgb, var(--ink) 60%, transparent);
|
|
63
|
+
--street-depth-face: color-mix(in srgb, var(--ink) 14%, var(--bg));
|
|
64
|
+
--street-depth-side: color-mix(in srgb, var(--ink) 8%, var(--bg));
|
|
65
|
+
--street-depth-edge: color-mix(in srgb, var(--ink) 13%, transparent);
|
|
66
|
+
--street-depth-shaft: color-mix(in srgb, var(--ink) 14%, transparent);
|
|
67
|
+
--street-depth-needs-edge: transparent;
|
|
68
|
+
--street-depth-haze-near: color-mix(in srgb, var(--sea) 7%, color-mix(in srgb, var(--ink) 9%, var(--bg)));
|
|
69
|
+
--street-depth-haze-near-side: color-mix(in srgb, var(--sea) 6%, color-mix(in srgb, var(--ink) 5%, var(--bg)));
|
|
70
|
+
--street-depth-haze-edge: color-mix(in srgb, var(--ink) 8%, transparent);
|
|
71
|
+
--street-depth-haze-far: color-mix(in srgb, var(--sea) 12%, color-mix(in srgb, var(--ink) 4%, var(--bg)));
|
|
72
|
+
--street-depth-fog: color-mix(in srgb, var(--sea) 10%, color-mix(in srgb, var(--ink) 5%, var(--bg)));
|
|
73
|
+
--street-depth-pool: color-mix(in srgb, var(--ink) 30%, transparent);
|
|
74
|
+
--street-depth-lane: color-mix(in srgb, var(--ink) 24%, transparent);
|
|
41
75
|
}
|
|
42
76
|
@media (prefers-color-scheme: dark) {
|
|
43
77
|
html:not([data-theme]) body[data-page="street"] {
|
|
@@ -46,6 +80,18 @@ html[data-theme="dark"] body[data-page="street"] {
|
|
|
46
80
|
--street-accent-text: color-mix(in srgb, var(--accent) 70%, #ffffff);
|
|
47
81
|
--street-glow: 0 0 20px color-mix(in srgb, var(--accent) 50%, transparent);
|
|
48
82
|
--street-crate: color-mix(in srgb, var(--ink) 60%, transparent);
|
|
83
|
+
--street-depth-face: color-mix(in srgb, var(--ink) 14%, var(--bg));
|
|
84
|
+
--street-depth-side: color-mix(in srgb, var(--ink) 8%, var(--bg));
|
|
85
|
+
--street-depth-edge: color-mix(in srgb, var(--ink) 13%, transparent);
|
|
86
|
+
--street-depth-shaft: color-mix(in srgb, var(--ink) 14%, transparent);
|
|
87
|
+
--street-depth-needs-edge: transparent;
|
|
88
|
+
--street-depth-haze-near: color-mix(in srgb, var(--sea) 7%, color-mix(in srgb, var(--ink) 9%, var(--bg)));
|
|
89
|
+
--street-depth-haze-near-side: color-mix(in srgb, var(--sea) 6%, color-mix(in srgb, var(--ink) 5%, var(--bg)));
|
|
90
|
+
--street-depth-haze-edge: color-mix(in srgb, var(--ink) 8%, transparent);
|
|
91
|
+
--street-depth-haze-far: color-mix(in srgb, var(--sea) 12%, color-mix(in srgb, var(--ink) 4%, var(--bg)));
|
|
92
|
+
--street-depth-fog: color-mix(in srgb, var(--sea) 10%, color-mix(in srgb, var(--ink) 5%, var(--bg)));
|
|
93
|
+
--street-depth-pool: color-mix(in srgb, var(--ink) 30%, transparent);
|
|
94
|
+
--street-depth-lane: color-mix(in srgb, var(--ink) 24%, transparent);
|
|
49
95
|
}
|
|
50
96
|
}
|
|
51
97
|
|
|
@@ -86,14 +132,23 @@ html[data-fullscreen="on"] .street-top { padding-right: 184px; }
|
|
|
86
132
|
.street-mode svg { display: block; stroke-width: 1.4; }
|
|
87
133
|
|
|
88
134
|
/* the street band: the prototype's 1440-wide artboard, scaled by street.js */
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
135
|
+
/* The living street's parallax (task 1004685) is Keith Clark's, sideways and
|
|
136
|
+
CSS only: the window is the perspective, the sizer and the board keep the
|
|
137
|
+
3D (an overflow other than visible would flatten it, so the sizer clips
|
|
138
|
+
nothing; the window still does), and each skyline row sits deeper and is
|
|
139
|
+
scaled back to its own size, so it slides at a half and a third of the
|
|
140
|
+
scroll. Its transform-origin is the band's middle (y 446 = 196 + 500 / 2,
|
|
141
|
+
the band less its empty sky and bare foot, task 1004718),
|
|
142
|
+
which is the window's middle, so a row only ever moves sideways; with no
|
|
143
|
+
sideways scroll it does not move at all. */
|
|
144
|
+
.street-window { flex: 1 1 auto; min-height: 0; width: 100%; max-width: none; margin: 0; padding: 0; box-sizing: border-box; display: flex; overflow-x: auto; overflow-y: hidden; position: relative; perspective: 1px; perspective-origin: 50% 50%; }
|
|
145
|
+
.street-sizer { position: relative; margin: auto; flex: none; overflow: visible; transform-style: preserve-3d; }
|
|
146
|
+
.street-board { position: absolute; left: 0; top: 0; width: 1440px; height: 900px; transform-origin: 0 0; transform: scale(var(--street-scale, 1)) translateY(-196px); transform-style: preserve-3d; }
|
|
92
147
|
.street-svg { position: absolute; left: 0; top: 0; pointer-events: none; overflow: visible; }
|
|
93
148
|
.street-layer { position: absolute; left: 0; top: 0; width: 100%; height: 900px; pointer-events: none; }
|
|
94
149
|
.street-layer > * { pointer-events: auto; }
|
|
95
150
|
|
|
96
|
-
.street-evening { position: absolute; left: 0; right: 0; top:
|
|
151
|
+
.street-evening { position: absolute; left: 0; right: 0; top: 216px; display: flex; flex-direction: column; align-items: center; gap: 10px; pointer-events: none; z-index: 2; }
|
|
97
152
|
.street-evening[hidden] { display: none; }
|
|
98
153
|
.street-evening__h { margin: 0; font-size: 46px; font-weight: 300; letter-spacing: -0.042em; line-height: 1; }
|
|
99
154
|
.street-evening__line { margin: 0; font-size: 16px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
|
|
@@ -163,6 +218,83 @@ html[data-fullscreen="on"] .street-top { padding-right: 184px; }
|
|
|
163
218
|
.street-sign__figure { font-size: 26px; font-weight: 300; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
|
|
164
219
|
.street-sign__line { font-size: 12.5px; line-height: 1.35; color: var(--ink-soft); }
|
|
165
220
|
|
|
221
|
+
/* ── THE LIVING STREET (task 1004685, the living-city prototype) ──
|
|
222
|
+
Three planes, front-on, in the street's own drawing (street-draw.js
|
|
223
|
+
depthOf). Every colour here is a token; the civic row's own faces are
|
|
224
|
+
drawing data, as before. Motion only says "this is live": the pods, the
|
|
225
|
+
jib, the hook, the scaffold's platform and a sitting's ring, all at 20 s
|
|
226
|
+
or slower and all dead under the kill switch below. */
|
|
227
|
+
.street-depth-layer { position: absolute; left: 0; top: 0; width: 100%; height: 900px; pointer-events: none; }
|
|
228
|
+
/* a skyline row is a 1 px box (its svg paints the row as overflow, street.js
|
|
229
|
+
depthSvg), so its depth never widens the sideways scroll; its origin is the
|
|
230
|
+
band's middle, set from the street's width */
|
|
231
|
+
.street-depth-back { position: absolute; left: 0; top: 0; width: 1px; height: 1px; pointer-events: none; transform-origin: var(--street-depth-ox, 720px) 446px; }
|
|
232
|
+
.street-depth-back--near { transform: translateZ(-1px) scale(2); }
|
|
233
|
+
.street-depth-back--far { transform: translateZ(-2px) scale(3); }
|
|
234
|
+
.street-depth-svg { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; }
|
|
235
|
+
/* BACK: the goals' skyline, hazed toward the void. Atmosphere is the depth cue:
|
|
236
|
+
the near row is a toned silhouette with a hairline, the far row a flat cool
|
|
237
|
+
haze with no edge at all, and the fog band below dissolves both into the
|
|
238
|
+
ground line, so the civic row (no haze, full detail) is the crisp subject */
|
|
239
|
+
.street-depth-sil__face, .street-depth-sil__side { stroke-width: 1; stroke-linejoin: round; }
|
|
240
|
+
.street-depth-back--near .street-depth-sil__face { fill: var(--street-depth-haze-near); stroke: var(--street-depth-haze-edge); }
|
|
241
|
+
.street-depth-back--near .street-depth-sil__side { fill: var(--street-depth-haze-near-side); stroke: var(--street-depth-haze-edge); }
|
|
242
|
+
.street-depth-back--far .street-depth-sil__face, .street-depth-back--far .street-depth-sil__side { fill: var(--street-depth-haze-far); stroke: none; }
|
|
243
|
+
/* the fog band: the skyline's feet fade into the ground line behind the civic row */
|
|
244
|
+
.street-depth-fog { position: absolute; left: 0; top: 404px; width: calc(var(--street-depth-ox, 720px) * 2); height: 156px; pointer-events: none; background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--street-depth-fog) 70%, transparent) 62%, var(--street-depth-fog) 96%); }
|
|
245
|
+
/* a lit road: a pool under a building or district with agents at work, as strong as it is busy */
|
|
246
|
+
.street-depth-pool { position: absolute; height: 40px; margin-top: -4px; pointer-events: none; border-radius: 50%; background: radial-gradient(closest-side, var(--street-depth-pool), transparent); opacity: calc(0.35 + 0.65 * var(--street-depth-pool-a, 0.5)); }
|
|
247
|
+
/* SKY: the skylanes and their pods, one per active claim, a fixed gap apart */
|
|
248
|
+
.street-depth-lane { fill: none; stroke: var(--street-depth-lane); stroke-width: var(--street-depth-lane-w, 1.3px); stroke-linecap: round; }
|
|
249
|
+
.street-depth-pod { position: absolute; left: 0; top: 0; width: 11px; height: 6px; box-sizing: border-box; border-radius: 999px; background: var(--street-depth-pod); box-shadow: inset 0 -1.5px 0 color-mix(in srgb, var(--bg) 35%, transparent); offset-rotate: auto; animation: street-depth-travel 28s linear infinite; }
|
|
250
|
+
.street-depth-train { position: absolute; left: 0; top: 0; height: 6px; margin-top: -3px; offset-rotate: 0deg; offset-distance: 50%; animation: street-depth-shuttle 24s ease-in-out -12s infinite alternate; }
|
|
251
|
+
.street-depth-pod--road { top: 0; offset-path: none; animation: none; }
|
|
252
|
+
/* an open sitting: a shaft of light from the roof (ink, so paper washes rather than glows) */
|
|
253
|
+
.street-depth-shaft { position: absolute; background: linear-gradient(to top, var(--street-depth-shaft), transparent 85%); }
|
|
254
|
+
.street-depth-shaft__track { position: absolute; inset: 0; overflow: hidden; -webkit-mask-image: linear-gradient(to top, transparent, #000 18%, #000 55%, transparent); mask-image: linear-gradient(to top, transparent, #000 18%, #000 55%, transparent); }
|
|
255
|
+
.street-depth-shaft__ring { position: absolute; left: 1px; right: 1px; bottom: 30%; height: 6px; box-sizing: border-box; border-radius: 50%; border: 1px solid color-mix(in srgb, var(--ink) 35%, transparent); animation: street-depth-rise 24s linear infinite; }
|
|
256
|
+
/* FRONT: what needs you lights its floor's windows in salmon, the only salmon
|
|
257
|
+
the street spends besides its pins; the ring beside them fills with age */
|
|
258
|
+
.street-depth-needs { fill: var(--accent); stroke: var(--street-depth-needs-edge); stroke-width: 0.6; }
|
|
259
|
+
.street-depth-age { fill: none; stroke: var(--street-rule-strong); stroke-width: 1.2; }
|
|
260
|
+
.street-depth-age__arc { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; }
|
|
261
|
+
/* construction: a live site's crane (the jib swings, the hook reels, the
|
|
262
|
+
scaffold's platform climbs), and a proposal's parked crane and tally arc */
|
|
263
|
+
.street-depth-crane { fill: none; stroke: color-mix(in srgb, var(--ink) 66%, transparent); stroke-width: 1.15; stroke-linecap: round; stroke-linejoin: round; }
|
|
264
|
+
.street-depth-slab { fill: color-mix(in srgb, var(--ink) 40%, transparent); }
|
|
265
|
+
.street-depth-weight { fill: color-mix(in srgb, var(--ink) 55%, transparent); }
|
|
266
|
+
.street-depth-platform { fill: color-mix(in srgb, var(--ink) 55%, transparent); transform-box: view-box; animation: street-depth-climb 22s ease-in-out infinite alternate; }
|
|
267
|
+
.street-depth-jib { transform-box: view-box; animation: street-depth-swing 26s ease-in-out infinite; }
|
|
268
|
+
.street-depth-line { transform-box: view-box; animation: street-depth-reel 26s ease-in-out infinite; }
|
|
269
|
+
.street-depth-slab { transform-box: view-box; animation: street-depth-hoist 26s ease-in-out infinite; }
|
|
270
|
+
.street-depth-tally { fill: none; stroke: var(--street-rule-strong); stroke-width: 1; stroke-dasharray: 2 3; }
|
|
271
|
+
.street-depth-seat { stroke-width: 1.2; }
|
|
272
|
+
.street-depth-seat--open { fill: var(--bg); stroke: color-mix(in srgb, var(--ink) 55%, transparent); }
|
|
273
|
+
.street-depth-seat--for { fill: var(--ink); stroke: none; }
|
|
274
|
+
.street-depth-seat--against { fill: color-mix(in srgb, var(--ink) 30%, var(--bg)); stroke: none; }
|
|
275
|
+
/* the Lead's name plate at street level; "owner" where nobody holds the building */
|
|
276
|
+
.street-depth-plate { position: absolute; display: flex; justify-content: center; pointer-events: none; }
|
|
277
|
+
.street-depth-plate__t { box-sizing: border-box; max-width: 100%; height: 16px; padding: 0 5px; border: 1px solid var(--street-rule-strong); border-radius: 3px; background: var(--bg); color: var(--ink-soft); font-size: 11px; line-height: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
278
|
+
.street-depth-plate--owner .street-depth-plate__t { border-style: dashed; color: var(--ink-faint); }
|
|
279
|
+
.street-depth-plate--you .street-depth-plate__t { color: var(--ink); border-color: color-mix(in srgb, var(--ink) 60%, transparent); }
|
|
280
|
+
/* the readings as tiles: one number and two words, hidden at zero */
|
|
281
|
+
.street-sign[hidden] { display: none; }
|
|
282
|
+
.street-depth-tile__fig { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
|
|
283
|
+
.street-depth-tile__n { flex: none; }
|
|
284
|
+
.street-depth-tile__words { font-size: 14px; font-weight: 400; letter-spacing: 0; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
285
|
+
/* "N need you" is the door to the decision deck */
|
|
286
|
+
.street-depth-deck { color: inherit; text-decoration: none; border-radius: 999px; padding: 4px 10px; margin: -4px -10px; min-height: 24px; }
|
|
287
|
+
.street-depth-deck::after { content: '→'; font-size: 14px; color: var(--street-accent-text); }
|
|
288
|
+
.street-depth-deck:hover { background: color-mix(in srgb, var(--accent) 9%, transparent); }
|
|
289
|
+
.street-depth-deck:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
|
|
290
|
+
@keyframes street-depth-travel { from { offset-distance: 0%; } to { offset-distance: 100%; } }
|
|
291
|
+
@keyframes street-depth-shuttle { from { offset-distance: 0%; } to { offset-distance: 100%; } }
|
|
292
|
+
@keyframes street-depth-swing { 0%, 100% { transform: scaleX(1); } 50% { transform: scaleX(-1); } }
|
|
293
|
+
@keyframes street-depth-reel { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(0.5); } }
|
|
294
|
+
@keyframes street-depth-hoist { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(var(--street-depth-lift, 0px)); } }
|
|
295
|
+
@keyframes street-depth-climb { from { transform: translateY(var(--street-depth-rise, 0px)); } to { transform: translateY(0); } }
|
|
296
|
+
@keyframes street-depth-rise { from { transform: translateY(calc(var(--street-depth-climb, 200px) * 0.3)) scaleX(0.6); } to { transform: translateY(calc(var(--street-depth-climb, 200px) * -0.7)) scaleX(1.5); } }
|
|
297
|
+
|
|
166
298
|
/* the matter card, over the street (short form until task 1004528) */
|
|
167
299
|
.street-card { position: absolute; left: var(--street-card-x, 32px); bottom: 16px; width: 390px; max-height: 300px; overflow-y: auto; box-sizing: border-box; background: var(--bg-card); border: 1px solid var(--street-rule-strong); border-radius: 16px; z-index: 8; padding: 14px 20px 18px; display: flex; flex-direction: column; gap: 11px; }
|
|
168
300
|
.street-card[hidden] { display: none; }
|
|
@@ -196,6 +328,13 @@ html[data-fullscreen="on"] .street-top { padding-right: 184px; }
|
|
|
196
328
|
.street-hud .street-label { font-size: 11px; }
|
|
197
329
|
.street-hud__n { font-size: 16px; }
|
|
198
330
|
.street-signs { margin: 0 16px; grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 180px; overflow-x: auto; overflow-y: hidden; }
|
|
331
|
+
/* the strip opens on what needs you, so a phone sees it before it scrolls */
|
|
332
|
+
.street-hud .street-depth-deck { order: -1; }
|
|
333
|
+
}
|
|
334
|
+
@media (max-width: 420px) {
|
|
335
|
+
/* the top bar already names the street; the strip keeps the wordmark and the switch.
|
|
336
|
+
The kicker is the page's one h1, so it leaves the eye, not the outline (task 1004718) */
|
|
337
|
+
.street-kicker { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
|
|
199
338
|
}
|
|
200
339
|
@media (max-width: 560px) {
|
|
201
340
|
.street-card { left: 16px; right: 16px; width: auto; }
|
|
@@ -226,12 +365,13 @@ html[data-fullscreen="on"] .street-top { padding-right: 184px; }
|
|
|
226
365
|
.inside-layer { position: absolute; left: 0; top: 0; width: 100%; height: 708px; pointer-events: none; }
|
|
227
366
|
.inside-layer > * { pointer-events: auto; }
|
|
228
367
|
.inside-floor { position: absolute; background: transparent; border: 0; padding: 0; margin: 0; cursor: pointer; border-radius: 0; }
|
|
229
|
-
.inside-floor:hover { outline: 1px solid color-mix(in srgb, var(--
|
|
368
|
+
.inside-floor:hover { outline: 1px solid color-mix(in srgb, var(--ink) 40%, transparent); outline-offset: -3px; }
|
|
230
369
|
|
|
231
370
|
/* the lift: it slides to the chosen floor */
|
|
232
|
-
|
|
371
|
+
/* the lift and the chosen floor are ink: salmon inside a building is only what needs you (task 1004718) */
|
|
372
|
+
.inside-lift { position: absolute; width: 18px; border-radius: 3px; background: var(--ink); display: flex; align-items: center; justify-content: center; pointer-events: none; transition: transform 650ms cubic-bezier(.2,.7,.3,1); }
|
|
233
373
|
.inside-lift[hidden] { display: none; }
|
|
234
|
-
.inside-lift__bar { width: 8px; height: 2px; border-radius: 1px; background: var(--
|
|
374
|
+
.inside-lift__bar { width: 8px; height: 2px; border-radius: 1px; background: var(--bg); }
|
|
235
375
|
.inside-annex { position: absolute; box-sizing: border-box; border: 1px dashed var(--street-rule-strong); display: flex; align-items: flex-end; justify-content: center; padding: 12px; text-align: center; font-size: 12.5px; line-height: 1.4; color: var(--ink-faint); }
|
|
236
376
|
|
|
237
377
|
/* a district: its name, its work labelled on the road, the two-line legend */
|
|
@@ -287,12 +427,16 @@ html[data-fullscreen="on"] .street-top { padding-right: 184px; }
|
|
|
287
427
|
/* the chosen floor, its sign large; the block re-enters on every pick */
|
|
288
428
|
.inside-open { display: flex; flex-direction: column; gap: 10px; }
|
|
289
429
|
.inside-open__head { display: flex; align-items: center; gap: 16px; }
|
|
290
|
-
.inside-plate { width: 64px; height: 64px; flex-shrink: 0; box-sizing: border-box; border-radius: 12px; border: 1px solid
|
|
430
|
+
.inside-plate { width: 64px; height: 64px; flex-shrink: 0; box-sizing: border-box; border-radius: 12px; border: 1px solid var(--street-rule-strong); display: flex; align-items: center; justify-content: center; }
|
|
291
431
|
.inside-plate svg { display: block; }
|
|
292
|
-
.inside-plate path { fill: none; stroke: var(--
|
|
293
|
-
.inside-plate path + path { fill: var(--
|
|
432
|
+
.inside-plate path { fill: none; stroke: var(--ink); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
|
|
433
|
+
.inside-plate path + path { fill: var(--ink); stroke: none; }
|
|
434
|
+
.inside-plate--hot { border-color: color-mix(in srgb, var(--accent) 55%, transparent); }
|
|
435
|
+
.inside-plate--hot path { stroke: var(--accent); }
|
|
436
|
+
.inside-plate--hot path + path { fill: var(--accent); }
|
|
294
437
|
.inside-open__words { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
|
|
295
|
-
.inside-open__kicker { font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--
|
|
438
|
+
.inside-open__kicker { font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }
|
|
439
|
+
.inside-open__kicker--hot { color: var(--street-accent-text); }
|
|
296
440
|
.inside-open__title { margin: 0; font-size: 21px; font-weight: 300; letter-spacing: -0.02em; }
|
|
297
441
|
.inside-line { display: flex; justify-content: space-between; gap: 14px; padding: 9px 0; border-top: 1px solid var(--street-rule); font-size: 14.5px; line-height: 1.4; }
|
|
298
442
|
.inside-line__meta { color: var(--ink-faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
|
|
@@ -428,4 +572,10 @@ html[data-fullscreen="on"] .street-top { padding-right: 184px; }
|
|
|
428
572
|
standing at the chosen floor without travelling there. */
|
|
429
573
|
@media (prefers-reduced-motion: reduce) {
|
|
430
574
|
body[data-page="street"] *, body[data-page="street"] *::before, body[data-page="street"] *::after { animation: none !important; transition: none !important; }
|
|
575
|
+
/* the living street (task 1004685) holds still too: no parallax on scroll.
|
|
576
|
+
Its rest frame is whole: the skyline in place, every pod parked on its
|
|
577
|
+
lane a fixed gap apart (the count is the agents), the crane parked, the
|
|
578
|
+
scaffold at its % complete, the ring in its shaft, the salmon windows lit. */
|
|
579
|
+
.street-window { perspective: none; }
|
|
580
|
+
.street-depth-back { transform: none; }
|
|
431
581
|
}
|
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
links, injected into this head by the server like every hall page's
|
|
12
12
|
(tests/hall_tokens.mjs: no hall page hardcodes a web-font stylesheet). -->
|
|
13
13
|
<link rel="stylesheet" href="/builders/style.css?v=2026-07-02-shell1">
|
|
14
|
-
<link rel="stylesheet" href="/builders/street.css?v=2026-10-
|
|
14
|
+
<link rel="stylesheet" href="/builders/street.css?v=2026-10-09-living3">
|
|
15
15
|
<link rel="stylesheet" href="/builders/street-card.css?v=2026-10-04-record1">
|
|
16
|
+
<link rel="stylesheet" href="/builders/street-deck.css?v=2026-10-13-glass1">
|
|
16
17
|
</head>
|
|
17
18
|
<!-- THE STREET (task 1004525, goal 1000125, R03). The street view of
|
|
18
19
|
docs/design/mocks/governor-city/Street.dc.html (renderVals' street branch,
|
|
@@ -72,12 +73,16 @@
|
|
|
72
73
|
<span class="street-today__pips" id="streetTodayPips" aria-hidden="true"></span>
|
|
73
74
|
<span class="street-today__n" id="streetTodayN">0 decided</span>
|
|
74
75
|
</div>
|
|
75
|
-
|
|
76
|
+
<!-- "needs you N" opens the decision deck (task 1004685): every ask, yours first.
|
|
77
|
+
Both numbers are gov-living.js countsOf, the ones the city, the deck and
|
|
78
|
+
the shell's tally print: needs you (asks on your seats) and moving (tasks
|
|
79
|
+
being built or waiting to land). -->
|
|
80
|
+
<a class="street-hud__item street-depth-deck" id="hudDeck" href="/builders/street#deck">
|
|
76
81
|
<span class="street-hud__dot" id="hudDot" aria-hidden="true"></span>
|
|
77
|
-
<span class="street-label">
|
|
82
|
+
<span class="street-label">to do</span>
|
|
78
83
|
<span class="street-hud__n" id="hudNeeds">—</span>
|
|
79
|
-
</
|
|
80
|
-
<div class="street-hud__item">
|
|
84
|
+
</a>
|
|
85
|
+
<div class="street-hud__item" title="tasks being built or waiting to land">
|
|
81
86
|
<span class="street-hud__dot street-hud__dot--moving" aria-hidden="true"></span>
|
|
82
87
|
<span class="street-label">moving</span>
|
|
83
88
|
<span class="street-hud__n" id="hudMoving">—</span>
|
|
@@ -100,10 +105,20 @@
|
|
|
100
105
|
<p class="street-evening__h">nothing waits on you.</p>
|
|
101
106
|
<p class="street-evening__line" id="streetEveningLine"></p>
|
|
102
107
|
</div>
|
|
108
|
+
<!-- THE LIVING STREET (task 1004685): behind the civic row, the goals'
|
|
109
|
+
skyline in two hazed rows (each its own depth, so it slides slower
|
|
110
|
+
when the street scrolls sideways) and the sky with its skylanes and
|
|
111
|
+
sittings; in front of it, what needs you, construction, the Leads'
|
|
112
|
+
plates and the road. street.js fills them from street-draw.js. -->
|
|
113
|
+
<div class="street-depth-back street-depth-back--far" id="streetDepthFar" aria-hidden="true"></div>
|
|
114
|
+
<div class="street-depth-back street-depth-back--near" id="streetDepthNear" aria-hidden="true"></div>
|
|
115
|
+
<div class="street-depth-fog" id="streetDepthFog" aria-hidden="true"></div>
|
|
116
|
+
<div class="street-depth-layer" id="streetDepthSky" aria-hidden="true"></div>
|
|
103
117
|
<svg class="street-svg" id="streetSvg" width="1440" height="900" viewBox="0 0 1440 900" aria-hidden="true" focusable="false">
|
|
104
118
|
<g id="streetFlat"></g>
|
|
105
119
|
<g id="streetBlds" class="street-blds"></g>
|
|
106
120
|
</svg>
|
|
121
|
+
<div class="street-depth-layer" id="streetDepthFront" aria-hidden="true"></div>
|
|
107
122
|
<div class="street-layer" id="streetCrates" aria-hidden="true"></div>
|
|
108
123
|
<div class="street-layer" id="streetCols"></div>
|
|
109
124
|
<div class="street-layer" id="streetGroups" aria-hidden="true"></div>
|
|
@@ -166,6 +181,10 @@
|
|
|
166
181
|
<span class="inside-meter__line" id="insideGrowth"></span>
|
|
167
182
|
</div>
|
|
168
183
|
</div>
|
|
184
|
+
<!-- the government layer (task 1004685): who leads it, its stack of
|
|
185
|
+
asks, and the Rules law book, the Treasury, the Charter's preset;
|
|
186
|
+
street-office.js fills it -->
|
|
187
|
+
<div class="govx" id="insideGovt" hidden></div>
|
|
169
188
|
<div class="inside-open" id="insideOpenA"></div>
|
|
170
189
|
<div class="inside-open" id="insideOpenB" hidden></div>
|
|
171
190
|
<div class="inside-record">
|
|
@@ -197,6 +216,12 @@
|
|
|
197
216
|
<div class="street-card__body" id="streetCardBody"></div>
|
|
198
217
|
</div>
|
|
199
218
|
|
|
219
|
+
<!-- THE DECISION DECK (task 1004685): #deck and #deck=<building>, one
|
|
220
|
+
ask at a time in the ask format. The street stays in view (task 1004702):
|
|
221
|
+
a glass panel beside the building that asks, a slim bar at the foot.
|
|
222
|
+
street-deck.js draws it. -->
|
|
223
|
+
<section class="deck" id="streetDeck" aria-labelledby="deckTitle" hidden></section>
|
|
224
|
+
|
|
200
225
|
<div class="street-toast" id="streetToast" role="status" aria-live="polite" hidden></div>
|
|
201
226
|
|
|
202
227
|
</main>
|
|
@@ -204,15 +229,20 @@
|
|
|
204
229
|
</div>
|
|
205
230
|
|
|
206
231
|
<script src="/builders/shell-trail.js?v=2026-10-08-city-tab"></script>
|
|
207
|
-
<script src="/builders/craft-mode.js?v=2026-10-
|
|
208
|
-
<script src="/builders/shell.js?v=2026-10-
|
|
232
|
+
<script src="/builders/craft-mode.js?v=2026-10-09-living3"></script>
|
|
233
|
+
<script src="/builders/shell.js?v=2026-10-10-hall-keys1"></script>
|
|
209
234
|
<script src="/builders/palette.js" defer></script>
|
|
210
|
-
<script src="/builders/
|
|
211
|
-
<script src="/builders/
|
|
235
|
+
<script src="/builders/gov-living.js?v=2026-10-09-positions1"></script>
|
|
236
|
+
<script src="/builders/gov-feeds.js?v=2026-10-09-living3"></script>
|
|
237
|
+
<script src="/builders/city-draw.js?v=2026-10-09-living3"></script>
|
|
238
|
+
<script src="/builders/street-draw.js?v=2026-10-09-living3"></script>
|
|
212
239
|
<script src="/builders/street-card.js?v=2026-10-04-record1"></script>
|
|
213
|
-
<script src="/builders/street-inside.js?v=2026-10-
|
|
240
|
+
<script src="/builders/street-inside.js?v=2026-10-09-living3"></script>
|
|
241
|
+
<script src="/builders/street-depth.js?v=2026-10-09-living3"></script>
|
|
214
242
|
<script src="/builders/street-desk.js?v=2026-10-04-record1"></script>
|
|
215
243
|
<script src="/builders/street-amend.js?v=2026-10-02-amend1"></script>
|
|
216
|
-
<script src="/builders/street.js?v=2026-10-
|
|
244
|
+
<script src="/builders/street-deck.js?v=2026-10-13-glass1"></script>
|
|
245
|
+
<script src="/builders/street-office.js?v=2026-10-09-living3"></script>
|
|
246
|
+
<script src="/builders/street.js?v=2026-10-13-glass1"></script>
|
|
217
247
|
</body>
|
|
218
248
|
</html>
|
|
@@ -80,8 +80,11 @@
|
|
|
80
80
|
var NARROW = 900;
|
|
81
81
|
var I = window.GovInside;
|
|
82
82
|
// The artboard's street band: the prototype's 900-high board less its 64 px
|
|
83
|
-
// header and 128 px footer, which this page lays out as real rows
|
|
84
|
-
|
|
83
|
+
// header and 128 px footer, which this page lays out as real rows, and less
|
|
84
|
+
// the empty sky over the skylanes and the bare ground under the brackets
|
|
85
|
+
// (task 1004718): 132 px off the top, 76 off the foot. street.css translateY
|
|
86
|
+
// matches BAND_TOP; street-depth.js skyTop sits 40 under it.
|
|
87
|
+
var BAND_TOP = 196, BAND_H = 500;
|
|
85
88
|
var CARD_W = 390;
|
|
86
89
|
|
|
87
90
|
var $ = function (id) { return document.getElementById(id); };
|
|
@@ -159,9 +162,16 @@
|
|
|
159
162
|
// 1440 x 708 at scale 1 is the prototype exactly. A wider or taller stage
|
|
160
163
|
// grows it, a smaller one shrinks it; a phone keeps it near full size and the
|
|
161
164
|
// street scrolls sideways inside its window, so a pin stays a pin.
|
|
165
|
+
// A stage taller than the street needs (a wide window scales the street to its
|
|
166
|
+
// width) gives the spare height to the foot of the page, under the readings, so
|
|
167
|
+
// the street sits on them with no empty sky above it (task 1004718). The window
|
|
168
|
+
// gives the height back whenever a building's inside is open.
|
|
162
169
|
function fit() {
|
|
170
|
+
var win = $('streetWindow'), inside = $('streetInside');
|
|
171
|
+
var insideOn = !!(inside && !inside.hidden);
|
|
172
|
+
if (win && win.style) win.style.flex = '';
|
|
163
173
|
fitInside();
|
|
164
|
-
var
|
|
174
|
+
var sizer = $('streetSizer'), board = $('streetBoard');
|
|
165
175
|
if (!win || !sizer || !board) return;
|
|
166
176
|
var W = view.model ? view.model.width : S.ARTBOARD_W;
|
|
167
177
|
var cw = win.clientWidth || window.innerWidth || 1440, ch = win.clientHeight || 708;
|
|
@@ -171,6 +181,7 @@
|
|
|
171
181
|
view.scale = s;
|
|
172
182
|
sizer.style.width = Math.round(W * s) + 'px';
|
|
173
183
|
sizer.style.height = Math.round(BAND_H * s) + 'px';
|
|
184
|
+
if (!insideOn && win.style && Math.round(BAND_H * s) < ch - 1) win.style.flex = '0 0 ' + Math.round(BAND_H * s) + 'px';
|
|
174
185
|
board.style.width = W + 'px';
|
|
175
186
|
board.style.setProperty('--street-scale', String(s));
|
|
176
187
|
var svg = $('streetSvg');
|
|
@@ -210,13 +221,26 @@
|
|
|
210
221
|
.then(function (r) { return r && r.ok ? r.json() : null; })
|
|
211
222
|
.catch(function () { return null; });
|
|
212
223
|
}
|
|
224
|
+
// The street's three reads go through gov-feeds.js when it is on the page (one
|
|
225
|
+
// read per feed per page view, shared with the living model and the shell's
|
|
226
|
+
// tally). Every load after the first follows an act, so it reads afresh what an
|
|
227
|
+
// act can change, once: the living model and every count re-read with it.
|
|
228
|
+
function readStreet() {
|
|
229
|
+
var F = window.GovFeeds;
|
|
230
|
+
if (F) {
|
|
231
|
+
if (data.loaded) F.refresh();
|
|
232
|
+
return F.read(['docket', 'goals', 'rollups']).then(function (r) { return [r.docket, r.goals, r.rollups]; });
|
|
233
|
+
}
|
|
234
|
+
return Promise.all([getJson(FEEDS.docket), getJson(FEEDS.goals), getJson(FEEDS.rollups)]);
|
|
235
|
+
}
|
|
213
236
|
function load() {
|
|
214
|
-
return
|
|
237
|
+
return readStreet().then(function (res) {
|
|
215
238
|
data.docket = res[0] && Array.isArray(res[0].matters) ? res[0] : null;
|
|
216
239
|
data.goals = res[1] && Array.isArray(res[1].goals) ? res[1].goals : [];
|
|
217
240
|
data.rollups = res[2] && Array.isArray(res[2].rollups) ? res[2].rollups : [];
|
|
218
241
|
data.loaded = true;
|
|
219
242
|
draw();
|
|
243
|
+
if (window.GovDeck) window.GovDeck.page.draw();
|
|
220
244
|
var viewer = data.docket && data.docket.viewer && data.docket.viewer.id;
|
|
221
245
|
if (viewer == null) return null;
|
|
222
246
|
return getJson(FEEDS.earnings(viewer)).then(function (e) {
|
|
@@ -263,61 +287,18 @@
|
|
|
263
287
|
return el;
|
|
264
288
|
}
|
|
265
289
|
|
|
266
|
-
//
|
|
267
|
-
//
|
|
268
|
-
//
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
el.setAttribute('data-building', p.building);
|
|
279
|
-
at(el, p.x, p.y, S.PIN_W, p.h);
|
|
280
|
-
var label = node('span', 'street-pin__label', p.label);
|
|
281
|
-
if (p.label) label.setAttribute('title', p.label);
|
|
282
|
-
el.appendChild(label);
|
|
283
|
-
var head = node('span', 'street-pin__head');
|
|
284
|
-
if (p.state === 'urgent') head.appendChild(node('span', 'street-pin__ring'));
|
|
285
|
-
if (p.isCount) head.appendChild(node('span', 'street-pin__count', p.count));
|
|
286
|
-
else if (p.state !== 'settled') {
|
|
287
|
-
var svg = document.createElementNS(SVG_NS, 'svg');
|
|
288
|
-
svg.setAttribute('width', '18');
|
|
289
|
-
svg.setAttribute('height', '18');
|
|
290
|
-
svg.setAttribute('viewBox', '0 0 18 18');
|
|
291
|
-
svg.setAttribute('aria-hidden', 'true');
|
|
292
|
-
var fill = document.createElementNS(SVG_NS, 'path');
|
|
293
|
-
fill.setAttribute('d', p.gf || '');
|
|
294
|
-
var line = document.createElementNS(SVG_NS, 'path');
|
|
295
|
-
line.setAttribute('d', p.gl || '');
|
|
296
|
-
svg.appendChild(fill);
|
|
297
|
-
svg.appendChild(line);
|
|
298
|
-
head.appendChild(svg);
|
|
299
|
-
}
|
|
300
|
-
if (!p.isCount && Number(p.count) > 1) head.appendChild(node('span', 'street-pin__badge', p.count));
|
|
301
|
-
el.appendChild(head);
|
|
302
|
-
el.appendChild(node('span', 'street-pin__stem'));
|
|
303
|
-
el.addEventListener('click', function () { openCard(keys[0], el, keys); });
|
|
304
|
-
return el;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
function drawSign(sg) {
|
|
308
|
-
var a = node('a', 'street-sign' + (sg.hot ? ' street-sign--hot' : '') + (sg.here ? ' street-sign--here' : ''));
|
|
309
|
-
a.setAttribute('href', sg.href);
|
|
310
|
-
a.setAttribute('aria-label', sg.aria);
|
|
311
|
-
a.setAttribute('data-reading', sg.key);
|
|
312
|
-
if (sg.here) a.setAttribute('aria-current', 'location');
|
|
313
|
-
var top = node('span', 'street-sign__top');
|
|
314
|
-
top.appendChild(node('span', 'street-sign__dot'));
|
|
315
|
-
top.appendChild(node('span', 'street-label', sg.label));
|
|
316
|
-
a.appendChild(top);
|
|
317
|
-
a.appendChild(node('span', 'street-sign__figure', sg.figure));
|
|
318
|
-
a.appendChild(node('span', 'street-sign__line', sg.line));
|
|
319
|
-
return a;
|
|
320
|
-
}
|
|
290
|
+
// ---------- the exterior's painters live in street-depth.js (task 1004685) ----------
|
|
291
|
+
// A pin, a reading, the depth layers and the living street's reads are
|
|
292
|
+
// GovStreetDepth.page's (street-depth.js); this file hands it the street's
|
|
293
|
+
// data, its card opener and a redraw, and keeps the street's own wiring.
|
|
294
|
+
var X = window.GovStreetDepth.page;
|
|
295
|
+
function drawPin(p) { return X.pin(p, { open: view.open, openCard: openCard }); }
|
|
296
|
+
function drawSign(sg, tile) { return X.sign(sg, tile); }
|
|
297
|
+
function drawDepth(dm, W) { return X.depth(dm, W); }
|
|
298
|
+
// the living model arrives after the street's own reads: the street and the deck draw it
|
|
299
|
+
function loadLiving() { return X.loadLiving(data, function () { draw(); if (window.GovDeck) window.GovDeck.page.draw(); }); }
|
|
300
|
+
function livingModel() { return X.livingModel(data); }
|
|
301
|
+
var living = X.living;
|
|
321
302
|
|
|
322
303
|
function draw() {
|
|
323
304
|
var mode = currentMode();
|
|
@@ -328,8 +309,16 @@
|
|
|
328
309
|
var sizerEl = $('streetSizer');
|
|
329
310
|
var showInside = !!(h && inside && I);
|
|
330
311
|
if (sizerEl) sizerEl.hidden = showInside;
|
|
331
|
-
|
|
312
|
+
// the living street (task 1004685): three planes over the living model
|
|
313
|
+
var lm = livingModel();
|
|
314
|
+
data.living = lm;
|
|
315
|
+
// the header prints the counts every surface prints (gov-living.js countsOf, less
|
|
316
|
+
// what the deck answered here); "—" while the living model is still reading
|
|
317
|
+
var counts = lm && window.GovFeeds ? window.GovFeeds.countsFrom(lm) : (window.GovFeeds && window.GovLiving ? null : undefined);
|
|
318
|
+
data.counts = counts || null;
|
|
319
|
+
var m = S.streetModel({ docket: data.docket, goals: data.goals, rollups: data.rollups, earnings: data.earnings, mode: mode, now: Date.now(), here: here(), depth: true, living: lm, counts: counts, roster: living.feeds ? living.feeds.roster : null });
|
|
332
320
|
view.model = m;
|
|
321
|
+
drawDepth(m.depth, m.width);
|
|
333
322
|
var flat = $('streetFlat'), blds = $('streetBlds');
|
|
334
323
|
clear(flat); clear(blds);
|
|
335
324
|
m.flat.forEach(function (p) { flat.appendChild(pathEl(p)); });
|
|
@@ -375,7 +364,8 @@
|
|
|
375
364
|
m.pins.forEach(function (p) { pins.appendChild(drawPin(p)); });
|
|
376
365
|
|
|
377
366
|
var signs = $('streetSigns'); clear(signs);
|
|
378
|
-
m.
|
|
367
|
+
var tiles = m.depth && data.loaded ? m.depth.tiles : null;
|
|
368
|
+
m.signs.forEach(function (sg) { signs.appendChild(drawSign(sg, tiles ? tiles[sg.key] : undefined)); });
|
|
379
369
|
|
|
380
370
|
var eve = $('streetEvening');
|
|
381
371
|
if (eve) eve.hidden = !(m.evening && !view.open) || showInside;
|
|
@@ -383,6 +373,9 @@
|
|
|
383
373
|
if (eveLine) eveLine.textContent = m.eveningLine;
|
|
384
374
|
|
|
385
375
|
drawToday();
|
|
376
|
+
// "N need you" is the way into the decision deck (V3 builds #deck)
|
|
377
|
+
var deck = $('hudDeck');
|
|
378
|
+
if (deck && m.hud.deck) { deck.setAttribute('href', m.hud.deck.href); deck.setAttribute('aria-label', m.hud.deck.aria); }
|
|
386
379
|
$('hudNeeds').textContent = m.hud.needs;
|
|
387
380
|
$('hudMoving').textContent = m.hud.moving;
|
|
388
381
|
$('hudShare').textContent = m.hud.share;
|
|
@@ -404,6 +397,7 @@
|
|
|
404
397
|
markAnswer();
|
|
405
398
|
fit();
|
|
406
399
|
if (view.open) fillCard();
|
|
400
|
+
loadLiving();
|
|
407
401
|
return m;
|
|
408
402
|
}
|
|
409
403
|
|
|
@@ -438,7 +432,9 @@
|
|
|
438
432
|
var startFloor = st.floor == null && D && data.docket ? D.firstNeeds(st.key, data.docket) : null;
|
|
439
433
|
var cleared = [];
|
|
440
434
|
Object.keys(desk.cleared).forEach(function (k) { var p = k.split(':'); if (p[0] === st.key) cleared.push(Number(p[1])); });
|
|
441
|
-
|
|
435
|
+
// the Lead's office on top, its build-outs and the floors they put up (street-office.js, task 1004711)
|
|
436
|
+
var OP = window.GovOffice && window.GovOffice.page, bi = OP ? OP.input(st.key) : {};
|
|
437
|
+
var bv = I.buildingModel({ key: st.key, docket: data.docket, goals: data.goals, mode: mode, now: Date.now(), floor: st.floor == null ? startFloor : st.floor, drawer: st.drawer, picks: st.picks, cleared: cleared.concat(bi.cleared || []), office: bi.office, works: bi.works, extraFloors: bi.floors });
|
|
442
438
|
// a sitting's ballot is read once, so its row can vote in place
|
|
443
439
|
var C = window.GovMatterCard;
|
|
444
440
|
if (!desk.roomAsked && !data.room && C && data.docket && data.docket.matters.some(function (x) { return x && x.building === st.key && C.needsRoom(x); })) {
|
|
@@ -520,7 +516,7 @@
|
|
|
520
516
|
// the chosen floor: two blocks that take turns, so the block re-enters on every pick
|
|
521
517
|
var on = $(bv.flipA ? 'insideOpenA' : 'insideOpenB'), off = $(bv.flipA ? 'insideOpenB' : 'insideOpenA');
|
|
522
518
|
if (off) { off.hidden = true; clear(off); }
|
|
523
|
-
if (on) { on.hidden = false; fillDesk(on, bv); }
|
|
519
|
+
if (on) { on.hidden = false; if (!(OP && OP.inside(bv, on, $('insideGovt')))) fillDesk(on, bv); }
|
|
524
520
|
setText('insideOnFile', bv.onFile);
|
|
525
521
|
var drawers = $('insideDrawers'); clear(drawers);
|
|
526
522
|
bv.drawers.forEach(function (dw) {
|
|
@@ -571,11 +567,12 @@
|
|
|
571
567
|
el.setAttribute('data-desk', dm.key);
|
|
572
568
|
// the header: the floor's sign, its name, its status
|
|
573
569
|
var head = node('div', 'inside-open__head');
|
|
574
|
-
|
|
570
|
+
// the sign and the kicker are salmon only while the floor needs you (task 1004718)
|
|
571
|
+
var plate = node('span', 'inside-plate' + (dm.hot ? ' inside-plate--hot' : ''));
|
|
575
572
|
plate.appendChild(icon(bv.sym.d, bv.sym.f, 34));
|
|
576
573
|
head.appendChild(plate);
|
|
577
574
|
var words = node('div', 'inside-open__words');
|
|
578
|
-
words.appendChild(node('span', 'inside-open__kicker', 'floor ' + (bv.selFloor + 1)));
|
|
575
|
+
words.appendChild(node('span', 'inside-open__kicker' + (dm.hot ? ' inside-open__kicker--hot' : ''), 'floor ' + (bv.selFloor + 1)));
|
|
579
576
|
words.appendChild(node('h3', 'inside-open__title', dm.name));
|
|
580
577
|
words.appendChild(node('span', 'desk-status' + (dm.hot ? ' desk-status--hot' : ''), dm.status));
|
|
581
578
|
head.appendChild(words);
|
|
@@ -1248,6 +1245,11 @@
|
|
|
1248
1245
|
var ctx = { room: data.room, constitution: data.constitution, now: Date.now(), goals: (data.goals || []).filter(function (g) { return g && g.status === 'open'; }), pick: card.pick };
|
|
1249
1246
|
var cv = D && D.cardFor ? D.cardFor(view.open, data.docket, ctx) : C ? C.model({ docket: data.docket, key: view.open, room: data.room, constitution: data.constitution, now: Date.now() }) : null;
|
|
1250
1247
|
if (!cv) { closeCard(false); return null; }
|
|
1248
|
+
// a stored ask opens as its building's glass card, answered in place (task 1004702)
|
|
1249
|
+
var G = window.GovDeck && window.GovDeck.page, frame = $('streetCard');
|
|
1250
|
+
var glass = !!(G && G.streetCard && G.streetCard($('streetCardBody'), view.open, card.page, { close: function () { closeCard(true); }, turn: function (k) { turnPage(k, 'next'); }, redraw: fillCard, done: function () { if (view.open) fillCard(); } }));
|
|
1251
|
+
if (frame) frame.setAttribute('data-glass', glass ? 'ask' : 'matter');
|
|
1252
|
+
if (glass) { card.cv = cv; placeCard(); return cv; }
|
|
1251
1253
|
var recordable = !!(cv.row && cv.row.choices && cv.row.choices.record && cv.row.choices.record.file);
|
|
1252
1254
|
if (recordable) { var cid = criterionOf(cv.row.card); C.withChecks(cv, rec.checks[cid] || null, rec.checks[cid] === false); }
|
|
1253
1255
|
card.cv = cv;
|
|
@@ -1256,7 +1258,7 @@
|
|
|
1256
1258
|
$('streetCardTitle').textContent = cv.title;
|
|
1257
1259
|
var pager = C.pager ? C.pager(card.page, view.open) : null;
|
|
1258
1260
|
C.render(document, $('streetCardBody'), cv, { act: actOn, openForm: openForm, ask: askFor, more: toggleMore, pick: pickQueued, page: turnPage, record: recordable ? cardRecord(cv) : null }, { form: card.form, ask: card.ask, more: card.more, error: card.error, busy: card.busy, fresh: card.fresh, pager: pager });
|
|
1259
|
-
|
|
1261
|
+
if (frame) frame.setAttribute('data-more', card.more ? 'open' : 'closed');
|
|
1260
1262
|
placeCard();
|
|
1261
1263
|
return cv;
|
|
1262
1264
|
}
|
|
@@ -1312,6 +1314,7 @@
|
|
|
1312
1314
|
var cx = pin ? originX + (pin.x + 55) * view.scale : stageW / 2;
|
|
1313
1315
|
var x = Math.max(16, Math.min(stageW - CARD_W - 16, Math.round(cx - CARD_W / 2)));
|
|
1314
1316
|
card.style.setProperty('--street-card-x', x + 'px');
|
|
1317
|
+
if (window.GovDeck) window.GovDeck.page.placeStreetCard(card, view.open);
|
|
1315
1318
|
}
|
|
1316
1319
|
function openCard(key, opener, keys) {
|
|
1317
1320
|
view.open = key;
|
|
@@ -1322,6 +1325,7 @@
|
|
|
1322
1325
|
if (!fillCard()) return;
|
|
1323
1326
|
el.hidden = false;
|
|
1324
1327
|
draw();
|
|
1328
|
+
placeCard();
|
|
1325
1329
|
var close = $('streetCardClose');
|
|
1326
1330
|
if (close && close.focus) close.focus();
|
|
1327
1331
|
if (card.cv && card.cv.loading) return loadRoom();
|
|
@@ -1333,6 +1337,7 @@
|
|
|
1333
1337
|
card.cv = null; card.form = null; card.ask = null; card.more = false; card.pick = null; card.error = ''; card.busy = false; card.fresh = null; card.page = null;
|
|
1334
1338
|
var el = $('streetCard');
|
|
1335
1339
|
if (el) el.hidden = true;
|
|
1340
|
+
if (window.GovDeck) window.GovDeck.page.unspot();
|
|
1336
1341
|
draw();
|
|
1337
1342
|
// The pins were redrawn, so focus goes back to the new button for the same matter.
|
|
1338
1343
|
if (restore !== false && was && was.getAttribute) {
|
|
@@ -1461,6 +1466,13 @@
|
|
|
1461
1466
|
if (media && media.addEventListener) media.addEventListener('change', function () { if (!storedTheme()) { applyTheme(); draw(); } });
|
|
1462
1467
|
painted = applyTheme();
|
|
1463
1468
|
today = readToday();
|
|
1469
|
+
// the decision deck (#deck) and the government inside each building, over the
|
|
1470
|
+
// street's own senders (street-deck.js, street-office.js; task 1004685)
|
|
1471
|
+
var env = { data: function () { return data; }, getJson: getJson, send: send, say: say, draw: draw, load: load, mode: currentMode, today: function () { return today.n; }, decided: function () { bumpToday(); drawToday(); }, done: function (id) { desk.done[id] = true; }, pickFloor: pickFloor, inside: function () { return view.inside; } };
|
|
1472
|
+
if (window.GovDeck) window.GovDeck.page.mount(env);
|
|
1473
|
+
if (window.GovOffice) window.GovOffice.page.mount(env);
|
|
1474
|
+
// an answer in the deck moves the header's counts as it moves the deck's
|
|
1475
|
+
if (window.GovFeeds) window.GovFeeds.onChange(function () { if (data.loaded) draw(); });
|
|
1464
1476
|
draw();
|
|
1465
1477
|
watchShellTheme();
|
|
1466
1478
|
return load();
|