synthos 0.7.2 → 0.9.0
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/README.md +215 -65
- package/default-pages/application/page.html +42 -0
- package/default-pages/application/page.json +10 -0
- package/default-pages/elevenlabs_effects_studio/page.html +1363 -0
- package/default-pages/elevenlabs_effects_studio/page.json +11 -0
- package/default-pages/elevenlabs_voice_studio/page.html +801 -0
- package/default-pages/elevenlabs_voice_studio/page.json +11 -0
- package/default-pages/{json_tools.html → json_tools/page.html} +13 -11
- package/default-pages/json_tools/page.json +10 -0
- package/default-pages/my_notes/notes/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json +5 -0
- package/default-pages/my_notes/page.html +132 -0
- package/default-pages/{my_notes.json → my_notes/page.json} +2 -2
- package/default-pages/neon_asteroids/files/Ambient_Space.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Ambient_Space2.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Ambient_Space3.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Asteroid_Explosion.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Hyperspace_Jump.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Laser_Fire.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Menu_Navigate.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Power_Up_Collect.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Saucer_Alert.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Ship_Thrust.mp3 +0 -0
- package/default-pages/neon_asteroids/files/effects.json +74 -0
- package/default-pages/neon_asteroids/page.html +1822 -0
- package/default-pages/{neon_asteroids.json → neon_asteroids/page.json} +3 -3
- package/default-pages/oregon_trail/page.html +323 -0
- package/default-pages/oregon_trail/page.json +12 -0
- package/default-pages/retro_game_starter/page.html +1308 -0
- package/default-pages/retro_game_starter/page.json +12 -0
- package/default-pages/{sidebar_builder.html → sidebar_page/page.html} +12 -10
- package/default-pages/sidebar_page/page.json +10 -0
- package/default-pages/{solar_explorer.html → solar_explorer/page.html} +24 -29
- package/default-pages/{solar_explorer.json → solar_explorer/page.json} +4 -4
- package/default-pages/{solar_tutorial.html → solar_tutorial/page.html} +12 -10
- package/default-pages/solar_tutorial/page.json +10 -0
- package/default-pages/{two-panel_builder.html → two-panel_page/page.html} +13 -11
- package/default-pages/two-panel_page/page.json +10 -0
- package/default-pages/us_map/page.html +193 -0
- package/default-pages/us_map/page.json +12 -0
- package/default-pages/us_map_1850/page.html +326 -0
- package/default-pages/us_map_1850/page.json +12 -0
- package/default-pages/western_cities_1850/page.html +527 -0
- package/default-pages/western_cities_1850/page.json +12 -0
- package/default-themes/aurora-dawn.json +19 -0
- package/default-themes/aurora-dawn.v3.css +198 -0
- package/default-themes/aurora-dusk.json +19 -0
- package/default-themes/aurora-dusk.v3.css +200 -0
- package/default-themes/cosmos-dawn.json +19 -0
- package/default-themes/cosmos-dawn.v3.css +198 -0
- package/default-themes/cosmos-dusk.json +19 -0
- package/default-themes/cosmos-dusk.v3.css +200 -0
- package/default-themes/high-contrast-dark.json +19 -0
- package/default-themes/high-contrast-dark.v3.css +200 -0
- package/default-themes/high-contrast-light.json +19 -0
- package/default-themes/high-contrast-light.v3.css +198 -0
- package/default-themes/{nebula-dawn.css → nebula-dawn.v2.css} +134 -0
- package/default-themes/nebula-dawn.v3.css +199 -0
- package/default-themes/{nebula-dusk.css → nebula-dusk.v2.css} +128 -0
- package/default-themes/nebula-dusk.v3.css +201 -0
- package/default-themes/solar-flare-dawn.json +19 -0
- package/default-themes/solar-flare-dawn.v3.css +198 -0
- package/default-themes/solar-flare-dusk.json +19 -0
- package/default-themes/solar-flare-dusk.v3.css +200 -0
- package/dist/agents/a2a/a2aProvider.d.ts.map +1 -0
- package/dist/agents/a2a/a2aProvider.js +126 -0
- package/dist/agents/a2a/a2aProvider.js.map +1 -0
- package/dist/agents/discovery.d.ts.map +1 -0
- package/dist/agents/discovery.js +52 -0
- package/dist/agents/discovery.js.map +1 -0
- package/dist/agents/index.d.ts +7 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +20 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/openclaw/gatewayManager.d.ts +117 -0
- package/dist/agents/openclaw/gatewayManager.d.ts.map +1 -0
- package/dist/agents/openclaw/gatewayManager.js +486 -0
- package/dist/agents/openclaw/gatewayManager.js.map +1 -0
- package/dist/agents/openclaw/openclawProvider.d.ts.map +1 -0
- package/dist/agents/openclaw/openclawProvider.js +237 -0
- package/dist/agents/openclaw/openclawProvider.js.map +1 -0
- package/dist/agents/openclaw/sshTunnelManager.d.ts +25 -0
- package/dist/agents/openclaw/sshTunnelManager.d.ts.map +1 -0
- package/dist/agents/openclaw/sshTunnelManager.js +359 -0
- package/dist/agents/openclaw/sshTunnelManager.js.map +1 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +6 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/builders/anthropic.d.ts +31 -0
- package/dist/builders/anthropic.d.ts.map +1 -0
- package/dist/builders/anthropic.js +227 -0
- package/dist/builders/anthropic.js.map +1 -0
- package/dist/builders/fireworksai.d.ts +9 -0
- package/dist/builders/fireworksai.d.ts.map +1 -0
- package/dist/builders/fireworksai.js +57 -0
- package/dist/builders/fireworksai.js.map +1 -0
- package/dist/builders/index.d.ts +13 -0
- package/dist/builders/index.d.ts.map +1 -0
- package/dist/builders/index.js +31 -0
- package/dist/builders/index.js.map +1 -0
- package/dist/builders/openai.d.ts +8 -0
- package/dist/builders/openai.d.ts.map +1 -0
- package/dist/builders/openai.js +87 -0
- package/dist/builders/openai.js.map +1 -0
- package/dist/builders/types.d.ts +54 -0
- package/dist/builders/types.d.ts.map +1 -0
- package/dist/builders/types.js +211 -0
- package/dist/builders/types.js.map +1 -0
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +3 -2
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/registry.d.ts +2 -1
- package/dist/connectors/registry.d.ts.map +1 -1
- package/dist/connectors/registry.js +65 -96
- package/dist/connectors/registry.js.map +1 -1
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/customizer/Customizer.d.ts +57 -0
- package/dist/customizer/Customizer.d.ts.map +1 -0
- package/dist/customizer/Customizer.js +124 -0
- package/dist/customizer/Customizer.js.map +1 -0
- package/dist/customizer/index.d.ts.map +1 -0
- package/dist/customizer/index.js +9 -0
- package/dist/customizer/index.js.map +1 -0
- package/dist/files.d.ts +17 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +75 -1
- package/dist/files.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +10 -6
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +97 -86
- package/dist/init.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +142 -145
- package/dist/migrations.js.map +1 -1
- package/dist/models/anthropic.d.ts +24 -0
- package/dist/models/anthropic.d.ts.map +1 -0
- package/dist/models/anthropic.js +103 -0
- package/dist/models/anthropic.js.map +1 -0
- package/dist/models/chainOfThought.d.ts.map +1 -0
- package/dist/models/chainOfThought.js +45 -0
- package/dist/models/chainOfThought.js.map +1 -0
- package/dist/models/fireworksai.d.ts.map +1 -0
- package/dist/models/fireworksai.js +141 -0
- package/dist/models/fireworksai.js.map +1 -0
- package/dist/models/index.d.ts +7 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +20 -1
- package/dist/models/index.js.map +1 -1
- package/dist/models/logCompletePrompt.d.ts.map +1 -0
- package/dist/models/logCompletePrompt.js +23 -0
- package/dist/models/logCompletePrompt.js.map +1 -0
- package/dist/models/openai.d.ts +24 -0
- package/dist/models/openai.d.ts.map +1 -0
- package/dist/models/openai.js +101 -0
- package/dist/models/openai.js.map +1 -0
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/providers.js +12 -4
- package/dist/models/providers.js.map +1 -1
- package/dist/models/types.d.ts +53 -2
- package/dist/models/types.d.ts.map +1 -1
- package/dist/models/types.js +21 -0
- package/dist/models/types.js.map +1 -1
- package/dist/models/utils.d.ts.map +1 -0
- package/dist/models/utils.js +21 -0
- package/dist/models/utils.js.map +1 -0
- package/dist/pages.d.ts +30 -7
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +177 -55
- package/dist/pages.js.map +1 -1
- package/dist/scripts.d.ts.map +1 -1
- package/dist/scripts.js +4 -3
- package/dist/scripts.js.map +1 -1
- package/dist/service/createCompletePrompt.d.ts.map +1 -1
- package/dist/service/createCompletePrompt.js +9 -6
- package/dist/service/createCompletePrompt.js.map +1 -1
- package/dist/service/generateImage.d.ts.map +1 -1
- package/dist/service/generateImage.js +3 -3
- package/dist/service/generateImage.js.map +1 -1
- package/dist/service/server.d.ts.map +1 -1
- package/dist/service/server.js +39 -7
- package/dist/service/server.js.map +1 -1
- package/dist/service/transformPage.d.ts +47 -18
- package/dist/service/transformPage.d.ts.map +1 -1
- package/dist/service/transformPage.js +559 -270
- package/dist/service/transformPage.js.map +1 -1
- package/dist/service/useAgentRoutes.d.ts +5 -0
- package/dist/service/useAgentRoutes.d.ts.map +1 -0
- package/dist/service/useAgentRoutes.js +392 -0
- package/dist/service/useAgentRoutes.js.map +1 -0
- package/dist/service/useApiRoutes.d.ts.map +1 -1
- package/dist/service/useApiRoutes.js +380 -138
- package/dist/service/useApiRoutes.js.map +1 -1
- package/dist/service/useConnectorRoutes.d.ts.map +1 -1
- package/dist/service/useConnectorRoutes.js +20 -9
- package/dist/service/useConnectorRoutes.js.map +1 -1
- package/dist/service/useFileRoutes.d.ts +4 -0
- package/dist/service/useFileRoutes.d.ts.map +1 -0
- package/dist/service/useFileRoutes.js +122 -0
- package/dist/service/useFileRoutes.js.map +1 -0
- package/dist/service/usePageRoutes.d.ts.map +1 -1
- package/dist/service/usePageRoutes.js +660 -68
- package/dist/service/usePageRoutes.js.map +1 -1
- package/dist/service/useSharedDataRoutes.d.ts +4 -0
- package/dist/service/useSharedDataRoutes.d.ts.map +1 -0
- package/dist/service/useSharedDataRoutes.js +104 -0
- package/dist/service/useSharedDataRoutes.js.map +1 -0
- package/dist/service/useSharedFileRoutes.d.ts +4 -0
- package/dist/service/useSharedFileRoutes.d.ts.map +1 -0
- package/dist/service/useSharedFileRoutes.js +121 -0
- package/dist/service/useSharedFileRoutes.js.map +1 -0
- package/dist/settings.d.ts +3 -1
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +5 -8
- package/dist/settings.js.map +1 -1
- package/dist/synthos-cli.d.ts.map +1 -1
- package/dist/synthos-cli.js +4 -3
- package/dist/synthos-cli.js.map +1 -1
- package/dist/themes.d.ts +15 -0
- package/dist/themes.d.ts.map +1 -1
- package/dist/themes.js +106 -20
- package/dist/themes.js.map +1 -1
- package/migration-rules/v1-to-v2.md +193 -0
- package/migration-rules/v2-to-v3.md +481 -0
- package/package.json +15 -11
- package/required-pages/builder/page.html +43 -0
- package/required-pages/builder/page.json +10 -0
- package/required-pages/pages/page.html +924 -0
- package/required-pages/pages/page.json +10 -0
- package/required-pages/settings/page.html +1753 -0
- package/required-pages/settings/page.json +10 -0
- package/required-pages/synthos_apis/page.html +846 -0
- package/required-pages/synthos_apis/page.json +10 -0
- package/required-pages/{synthos_scripts.html → synthos_scripts/page.html} +13 -11
- package/required-pages/synthos_scripts/page.json +10 -0
- package/service-connectors/airtable/connector.json +27 -0
- package/service-connectors/alpha-vantage/connector.json +26 -0
- package/service-connectors/brave-search/connector.json +26 -0
- package/service-connectors/cloudinary/connector.json +27 -0
- package/service-connectors/deepl/connector.json +28 -0
- package/service-connectors/elevenlabs/connector.json +30 -0
- package/service-connectors/giphy/connector.json +27 -0
- package/service-connectors/github/connector.json +29 -0
- package/service-connectors/huggingface/connector.json +27 -0
- package/service-connectors/imgur/connector.json +29 -0
- package/service-connectors/instagram/connector.json +43 -0
- package/service-connectors/jira/connector.json +28 -0
- package/service-connectors/mapbox/connector.json +26 -0
- package/service-connectors/nasa/connector.json +27 -0
- package/service-connectors/newsapi/connector.json +27 -0
- package/service-connectors/notion/connector.json +28 -0
- package/service-connectors/open-exchange-rates/connector.json +27 -0
- package/service-connectors/openweathermap/connector.json +26 -0
- package/service-connectors/pexels/connector.json +27 -0
- package/service-connectors/resend/connector.json +29 -0
- package/service-connectors/rss2json/connector.json +27 -0
- package/service-connectors/sendgrid/connector.json +27 -0
- package/service-connectors/spoonacular/connector.json +28 -0
- package/service-connectors/stability-ai/connector.json +27 -0
- package/service-connectors/twilio/connector.json +28 -0
- package/service-connectors/unsplash/connector.json +27 -0
- package/service-connectors/wolfram-alpha/connector.json +26 -0
- package/service-connectors/youtube-data/connector.json +30 -0
- package/src/agents/a2a/a2aProvider.ts +110 -0
- package/src/agents/discovery.ts +74 -0
- package/src/agents/index.ts +6 -0
- package/src/agents/openclaw/gatewayManager.ts +570 -0
- package/src/agents/openclaw/openclawProvider.ts +259 -0
- package/src/agents/openclaw/sshTunnelManager.ts +393 -0
- package/src/agents/types.ts +82 -0
- package/src/builders/anthropic.ts +283 -0
- package/src/builders/fireworksai.ts +59 -0
- package/src/builders/index.ts +33 -0
- package/src/builders/openai.ts +89 -0
- package/src/builders/types.ts +261 -0
- package/src/connectors/index.ts +3 -1
- package/src/connectors/registry.ts +40 -96
- package/src/connectors/types.ts +25 -0
- package/src/customizer/Customizer.ts +151 -0
- package/src/customizer/index.ts +5 -0
- package/src/files.ts +71 -0
- package/src/index.ts +2 -1
- package/src/init.ts +138 -97
- package/src/migrations.ts +148 -145
- package/src/models/anthropic.ts +119 -0
- package/src/models/chainOfThought.ts +56 -0
- package/src/models/fireworksai.ts +143 -0
- package/src/models/index.ts +7 -1
- package/src/models/logCompletePrompt.ts +25 -0
- package/src/models/openai.ts +110 -0
- package/src/models/providers.ts +12 -3
- package/src/models/types.ts +97 -2
- package/src/models/utils.ts +16 -0
- package/src/pages.ts +176 -54
- package/src/scripts.ts +2 -2
- package/src/service/createCompletePrompt.ts +3 -1
- package/src/service/generateImage.ts +2 -2
- package/src/service/server.ts +39 -8
- package/src/service/transformPage.ts +605 -301
- package/src/service/useAgentRoutes.ts +428 -0
- package/src/service/useApiRoutes.ts +309 -45
- package/src/service/useConnectorRoutes.ts +21 -10
- package/src/service/useFileRoutes.ts +127 -0
- package/src/service/usePageRoutes.ts +736 -75
- package/src/service/useSharedDataRoutes.ts +106 -0
- package/src/service/useSharedFileRoutes.ts +126 -0
- package/src/settings.ts +8 -10
- package/src/synthos-cli.ts +4 -3
- package/src/themes.ts +103 -20
- package/static-files/favicon.svg +12 -0
- package/static-files/fluentlm-instructions.llmd +868 -0
- package/static-files/fluentlm-instructions.md +1595 -0
- package/static-files/fluentlm.css +4844 -0
- package/static-files/fluentlm.js +3602 -0
- package/static-files/fluentlm.min.css +1 -0
- package/static-files/fluentlm.min.js +1 -0
- package/static-files/helpers.v3.js +304 -0
- package/static-files/page.v3.js +1290 -0
- package/static-files/recommended-frameworks.llmd +81 -0
- package/static-files/recommended-frameworks.md +137 -0
- package/static-files/retro-game.js +877 -0
- package/static-files/shell.css +797 -0
- package/static-files/theme-dark.css +169 -0
- package/static-files/theme-light.css +169 -0
- package/tests/anthropic.spec.ts +84 -0
- package/tests/builders.spec.ts +139 -0
- package/tests/chainOfThought.spec.ts +108 -0
- package/tests/ensureScripts.spec.ts +82 -0
- package/tests/files.spec.ts +233 -0
- package/tests/fireworksai.spec.ts +92 -0
- package/tests/logCompletePrompt.spec.ts +74 -0
- package/tests/migrations.spec.ts +79 -1
- package/tests/openai.spec.ts +71 -0
- package/tests/pages.spec.ts +226 -1
- package/tests/providers.spec.ts +144 -0
- package/tests/scripts.spec.ts +209 -0
- package/tests/transformPage.spec.ts +456 -0
- package/tests/types.spec.ts +23 -0
- package/default-pages/app_builder.html +0 -40
- package/default-pages/app_builder.json +0 -1
- package/default-pages/json_tools.json +0 -1
- package/default-pages/my_notes.html +0 -33
- package/default-pages/neon_asteroids.html +0 -77
- package/default-pages/sidebar_builder.json +0 -1
- package/default-pages/solar_tutorial.json +0 -1
- package/default-pages/two-panel_builder.json +0 -1
- package/dist/connectors/index.d.ts +0 -3
- package/dist/connectors/types.d.ts +0 -61
- package/dist/index.d.ts +0 -7
- package/dist/migrations.d.ts +0 -11
- package/dist/models/providers.d.ts +0 -7
- package/dist/scripts.d.ts +0 -14
- package/dist/service/createCompletePrompt.d.ts +0 -5
- package/dist/service/debugLog.d.ts +0 -11
- package/dist/service/generateImage.d.ts +0 -32
- package/dist/service/index.d.ts +0 -8
- package/dist/service/modelInstructions.d.ts +0 -7
- package/dist/service/requiresSettings.d.ts +0 -3
- package/dist/service/server.d.ts +0 -4
- package/dist/service/useApiRoutes.d.ts +0 -4
- package/dist/service/useConnectorRoutes.d.ts +0 -4
- package/dist/service/useDataRoutes.d.ts +0 -4
- package/dist/service/usePageRoutes.d.ts +0 -5
- package/dist/synthos-cli.d.ts +0 -2
- package/images/home.png +0 -0
- package/images/page-management.png +0 -0
- package/images/settings.png +0 -0
- package/images/synthos-square.png +0 -0
- package/page-scripts/helpers-v2.js +0 -121
- package/page-scripts/page-v2.js +0 -615
- package/required-pages/builder.html +0 -74
- package/required-pages/builder.json +0 -1
- package/required-pages/pages.html +0 -196
- package/required-pages/pages.json +0 -1
- package/required-pages/settings.html +0 -841
- package/required-pages/settings.json +0 -1
- package/required-pages/synthos_apis.html +0 -272
- package/required-pages/synthos_apis.json +0 -1
- package/required-pages/synthos_scripts.json +0 -1
|
@@ -6,22 +6,24 @@
|
|
|
6
6
|
<link id="theme-css" rel="stylesheet" href="/api/theme.css" data-locked="true">
|
|
7
7
|
<style>.sidebar-panel{width:300px;height:100%;position:relative;z-index:1;flex-shrink:0;overflow-y:auto}.sidebar-title{font-size:1.4em;font-weight:700;background:linear-gradient(90deg,var(--accent-primary),var(--accent-tertiary));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;border-bottom:2px solid var(--border-color);padding-bottom:.3em;margin-bottom:1em;text-shadow:0 0 30px var(--accent-glow)}.sidebar-content{background:linear-gradient(135deg,rgba(102,126,234,.1) 0,rgba(118,75,162,.1) 100%);border:1px solid var(--border-color);border-radius:12px;padding:20px;box-shadow:0 4px 20px var(--accent-glow)}.sidebar-content p{color:rgba(224,224,224,.9);line-height:1.7;margin-bottom:1em}.sidebar-content p:last-child{margin-bottom:0}.sidebar-section{margin-top:1.2em;padding-top:1em;border-top:1px solid var(--border-color)}.sidebar-section-title{font-size:1.2em;font-weight:600;background:linear-gradient(90deg,var(--accent-primary),var(--accent-tertiary));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;margin-bottom:.6em}.sidebar-list{margin:0 0 1em 20px}.sidebar-list li{margin-bottom:.4em;color:rgba(224,224,224,.85)}.sidebar-list li::marker{color:var(--accent-tertiary)}.sidebar-quote{margin:1em 0;padding:12px 20px;border-left:4px solid var(--accent-secondary);background:linear-gradient(135deg,rgba(102,126,234,.15) 0,rgba(118,75,162,.15) 100%);border-radius:0 10px 10px 0;font-style:italic;color:var(--text-secondary)}.sidebar-code{background:rgba(138,43,226,.25);padding:3px 7px;border-radius:5px;font-family:'Fira Code','Courier New',monospace;color:var(--accent-tertiary);border:1px solid rgba(240,147,251,.2);font-size:.9em}.sidebar-link{color:var(--accent-tertiary);text-decoration:none;border-bottom:1px solid transparent;transition:.3s}.sidebar-link:hover{border-bottom-color:var(--accent-tertiary);text-shadow:0 0 10px var(--accent-glow)}.light-mode .sidebar-content p{color:rgba(45,38,64,.9)}.light-mode .sidebar-list li{color:rgba(45,38,64,.85)}</style>
|
|
8
8
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.1/marked.min.js"></script>
|
|
9
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
|
9
10
|
<script id="page-info" src="/api/page-info.js?page=sidebar"></script>
|
|
10
11
|
<style id="placeholder-styles">.content-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;min-height:300px;color:var(--text-secondary);text-align:center;padding:40px;opacity:0.7;transition:opacity 0.3s ease}.content-placeholder .placeholder-icon{font-size:4em;margin-bottom:20px;animation:float 3s ease-in-out infinite}.content-placeholder .placeholder-text{font-size:1.4em;font-weight:600;background:linear-gradient(90deg,var(--accent-primary),var(--accent-tertiary));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;margin-bottom:10px}.content-placeholder .placeholder-hint{font-size:0.95em;color:var(--text-secondary);opacity:0.8}@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}.viewer-panel:has(.content-placeholder ~ *:not(.sidebar-panel):not(.loading-overlay):not(#loadingOverlay)) .content-placeholder{display:none}.light-mode .content-placeholder{color:var(--text-secondary)}</style></head>
|
|
11
12
|
<body>
|
|
13
|
+
<div class="shell-toolbar" data-locked="true">
|
|
14
|
+
<button class="shell-toolbar-btn" id="builderToggle" aria-label="Page Builder" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M7 18.5H6.2c-1.77 0-3.2-1.43-3.2-3.2V7.7C3 5.93 4.43 4.5 6.2 4.5h11.6c1.77 0 3.2 1.43 3.2 3.2v7.6c0 1.77-1.43 3.2-3.2 3.2H12l-4.2 3.2c-.5.38-1.2.02-1.2-.6V18.5Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><circle cx="8.5" cy="11.5" r="1" fill="currentColor"/><circle cx="12" cy="11.5" r="1" fill="currentColor"/><circle cx="15.5" cy="11.5" r="1" fill="currentColor"/></svg></button>
|
|
15
|
+
<button class="shell-toolbar-btn" id="pagesBtn" aria-label="View All Pages" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none"><rect x="3" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 7.5h5M6 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 7.5h5M21 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="3" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 22.5h5M6 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 22.5h5M21 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
|
|
16
|
+
<button class="shell-toolbar-btn" id="saveBtn" aria-label="Save Page" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M17 21v-8H7v8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M7 3v5h8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></button>
|
|
17
|
+
<div class="shell-toolbar-spacer" data-locked="true"></div>
|
|
18
|
+
<button class="shell-toolbar-btn" id="settingsBtn" aria-label="Settings" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" stroke="currentColor" stroke-width="1.8"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
|
19
|
+
</div>
|
|
12
20
|
<div class="chat-panel" data-locked="true">
|
|
13
|
-
<div class="chat-header" data-locked="true">
|
|
21
|
+
<div class="chat-header" data-locked="true"><span>Page Builder</span><button class="chat-header-close" id="builderClose" aria-label="Close builder" data-locked="true">×</button></div>
|
|
14
22
|
<div class="chat-messages" id="chatMessages" data-locked="true">
|
|
15
23
|
<div class="chat-message"><p><strong>SynthOS:</strong> Welcome to the Sidebar template! You can ask me to modify the <strong>content area</strong> on the left or customize the <strong>sidebar</strong> on the right. Just let me know what you'd like to create.</p></div>
|
|
16
|
-
</div>
|
|
17
|
-
<div class="link-group" data-locked="true">
|
|
18
|
-
<a href="#" id="saveLink" data-locked="true">Save</a>
|
|
19
|
-
<a href="/pages" id="pagesLink" data-locked="true">Pages</a>
|
|
20
|
-
<a href="#" id="resetLink" data-locked="true">Reset</a>
|
|
21
|
-
</div>
|
|
24
|
+
</div>
|
|
22
25
|
<form action="/" method="POST" id="chatForm" data-locked="true">
|
|
23
|
-
<
|
|
24
|
-
<button type="submit" class="chat-submit" data-locked="true">Send</button>
|
|
26
|
+
<textarea class="chat-input" id="chatInput" name="message" rows="2" placeholder="Type a message..." data-locked="true"></textarea>
|
|
25
27
|
</form>
|
|
26
28
|
</div>
|
|
27
29
|
<div class="viewer-panel" id="viewerPanel" style="display: flex !important; flex-direction: row !important; align-items: stretch !important;"><div id="contentPlaceholder" class="content-placeholder"><div class="placeholder-icon">✨</div><div class="placeholder-text">Your content will appear here</div><div class="placeholder-hint">Ask SynthOS to add something!</div></div>
|
|
@@ -46,4 +48,4 @@
|
|
|
46
48
|
<div id="thoughts" style="display: none;" data-locked="true"></div>
|
|
47
49
|
|
|
48
50
|
|
|
49
|
-
<script id="page-helpers" src="/api/page-helpers.js?v=
|
|
51
|
+
<script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script><script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script></body></html>
|
|
@@ -163,18 +163,7 @@
|
|
|
163
163
|
color: #f093fb;
|
|
164
164
|
}
|
|
165
165
|
</style><style id="settings-modal-styles">
|
|
166
|
-
.settings-overlay
|
|
167
|
-
position: fixed;
|
|
168
|
-
top: 0; left: 0; right: 0; bottom: 0;
|
|
169
|
-
background: rgba(0,0,0,0.6);
|
|
170
|
-
z-index: 9999;
|
|
171
|
-
display: none;
|
|
172
|
-
align-items: center;
|
|
173
|
-
justify-content: center;
|
|
174
|
-
}
|
|
175
|
-
.settings-overlay.active {
|
|
176
|
-
display: flex;
|
|
177
|
-
}
|
|
166
|
+
/* .settings-overlay extends .modal-overlay from theme CSS */
|
|
178
167
|
.settings-modal {
|
|
179
168
|
background: rgba(15, 15, 35, 0.95);
|
|
180
169
|
backdrop-filter: blur(16px);
|
|
@@ -415,10 +404,19 @@
|
|
|
415
404
|
background: rgba(255,255,255,0.1);
|
|
416
405
|
color: #f093fb;
|
|
417
406
|
}
|
|
418
|
-
</style
|
|
407
|
+
</style>
|
|
408
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
|
409
|
+
</head>
|
|
419
410
|
<body>
|
|
411
|
+
<div class="shell-toolbar" data-locked="true">
|
|
412
|
+
<button class="shell-toolbar-btn" id="builderToggle" aria-label="Page Builder" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M7 18.5H6.2c-1.77 0-3.2-1.43-3.2-3.2V7.7C3 5.93 4.43 4.5 6.2 4.5h11.6c1.77 0 3.2 1.43 3.2 3.2v7.6c0 1.77-1.43 3.2-3.2 3.2H12l-4.2 3.2c-.5.38-1.2.02-1.2-.6V18.5Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><circle cx="8.5" cy="11.5" r="1" fill="currentColor"/><circle cx="12" cy="11.5" r="1" fill="currentColor"/><circle cx="15.5" cy="11.5" r="1" fill="currentColor"/></svg></button>
|
|
413
|
+
<button class="shell-toolbar-btn" id="pagesBtn" aria-label="View All Pages" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none"><rect x="3" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 7.5h5M6 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 7.5h5M21 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="3" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 22.5h5M6 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 22.5h5M21 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
|
|
414
|
+
<button class="shell-toolbar-btn" id="saveBtn" aria-label="Save Page" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M17 21v-8H7v8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M7 3v5h8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></button>
|
|
415
|
+
<div class="shell-toolbar-spacer" data-locked="true"></div>
|
|
416
|
+
<button class="shell-toolbar-btn" id="settingsBtn" aria-label="Settings" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" stroke="currentColor" stroke-width="1.8"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
|
417
|
+
</div>
|
|
420
418
|
<div class="chat-panel" data-locked="true">
|
|
421
|
-
<div class="chat-header" data-locked="true">
|
|
419
|
+
<div class="chat-header" data-locked="true"><span>Page Builder</span><button class="chat-header-close" id="builderClose" aria-label="Close builder" data-locked="true">×</button></div>
|
|
422
420
|
<div class="chat-messages" id="chatMessages" data-locked="true">
|
|
423
421
|
<div class="chat-message"><p><strong>SynthOS:</strong> Welcome to the <strong>Solar Explorer</strong></p>
|
|
424
422
|
<p><strong>Main View Controls:</strong></p>
|
|
@@ -437,15 +435,9 @@
|
|
|
437
435
|
</ul>
|
|
438
436
|
<p><strong>Solar Explorer Panel</strong> (top-right): Ask any question about the solar system!</p>
|
|
439
437
|
<p>Try clicking on Jupiter or Saturn to see their impressive moon systems! 🪐</p></div>
|
|
440
|
-
</div>
|
|
441
|
-
<div class="link-group" data-locked="true">
|
|
442
|
-
<a href="#" id="saveLink" data-locked="true">Save</a>
|
|
443
|
-
<a href="/pages" id="pagesLink" data-locked="true">Pages</a>
|
|
444
|
-
<a href="#" id="resetLink" data-locked="true">Reset</a>
|
|
445
|
-
</div>
|
|
438
|
+
</div>
|
|
446
439
|
<form action="/" method="POST" id="chatForm" data-locked="true">
|
|
447
|
-
<
|
|
448
|
-
<button type="submit" class="chat-submit" data-locked="true">Send</button>
|
|
440
|
+
<textarea class="chat-input" id="chatInput" name="message" rows="2" placeholder="Type a message..." data-locked="true"></textarea>
|
|
449
441
|
</form>
|
|
450
442
|
</div>
|
|
451
443
|
<div class="viewer-panel full-viewer" id="viewerPanel" style="background: #0a0a19;">
|
|
@@ -535,7 +527,7 @@
|
|
|
535
527
|
<button id="openSettings">⚙️ Settings</button>
|
|
536
528
|
</div>
|
|
537
529
|
<div id="loadingOverlay" class="loading-overlay"><div class="spinner"></div></div>
|
|
538
|
-
<div id="settingsOverlay" class="settings-overlay">
|
|
530
|
+
<div id="settingsOverlay" class="modal-overlay settings-overlay">
|
|
539
531
|
<div class="settings-modal">
|
|
540
532
|
<h2>⚙️ Explorer Settings</h2>
|
|
541
533
|
|
|
@@ -1845,24 +1837,27 @@ animate();
|
|
|
1845
1837
|
// Always reload from server when opening to ensure fresh data
|
|
1846
1838
|
await loadSettings();
|
|
1847
1839
|
applySettingsToUI();
|
|
1848
|
-
overlay.classList.add('
|
|
1840
|
+
overlay.classList.add('show');
|
|
1849
1841
|
});
|
|
1850
1842
|
|
|
1851
1843
|
cancelBtn.addEventListener('click', function() {
|
|
1852
|
-
overlay.classList.remove('
|
|
1844
|
+
overlay.classList.remove('show');
|
|
1853
1845
|
applySettingsToUI(); // revert UI to saved
|
|
1854
1846
|
});
|
|
1855
1847
|
|
|
1848
|
+
var overlayMouseDownTarget = null;
|
|
1849
|
+
overlay.addEventListener('mousedown', function(e) { overlayMouseDownTarget = e.target; });
|
|
1856
1850
|
overlay.addEventListener('click', function(e) {
|
|
1857
|
-
if (e.target === overlay) {
|
|
1858
|
-
overlay.classList.remove('
|
|
1851
|
+
if (e.target === overlay && overlayMouseDownTarget === overlay) {
|
|
1852
|
+
overlay.classList.remove('show');
|
|
1859
1853
|
applySettingsToUI();
|
|
1860
1854
|
}
|
|
1855
|
+
overlayMouseDownTarget = null;
|
|
1861
1856
|
});
|
|
1862
1857
|
|
|
1863
1858
|
saveBtn.addEventListener('click', async function() {
|
|
1864
1859
|
await saveSettings();
|
|
1865
|
-
overlay.classList.remove('
|
|
1860
|
+
overlay.classList.remove('show');
|
|
1866
1861
|
});
|
|
1867
1862
|
|
|
1868
1863
|
// Helper to build audience instruction for prompts
|
|
@@ -1953,4 +1948,4 @@ animate();
|
|
|
1953
1948
|
return convertDistString(str, window.explorerSettings.distUnit);
|
|
1954
1949
|
};
|
|
1955
1950
|
})();
|
|
1956
|
-
</script><script id="page-helpers" src="/api/page-helpers.js?v=
|
|
1951
|
+
</script><script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script><script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script></body></html>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"title": "Solar Explorer",
|
|
3
3
|
"categories": [
|
|
4
|
-
"
|
|
4
|
+
"Educational"
|
|
5
5
|
],
|
|
6
6
|
"pinned": false,
|
|
7
|
-
"showInAll":
|
|
7
|
+
"showInAll": false,
|
|
8
8
|
"createdDate": "2026-02-15T11:12:27.724Z",
|
|
9
9
|
"lastModified": "2026-02-15T11:12:27.724Z",
|
|
10
|
-
"pageVersion":
|
|
10
|
+
"pageVersion": 3,
|
|
11
11
|
"mode": "locked"
|
|
12
|
-
}
|
|
12
|
+
}
|
|
@@ -123,26 +123,28 @@
|
|
|
123
123
|
}
|
|
124
124
|
</style>
|
|
125
125
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.1/marked.min.js"></script>
|
|
126
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
|
126
127
|
<script id="page-info" src="/api/page-info.js?page=solar_system"></script>
|
|
127
128
|
<style id="tutorial-link-styles">.tutorial-link{color:#667eea;text-decoration:underline;cursor:pointer;transition:color 0.2s}.tutorial-link:hover{color:#f093fb}.light-mode .tutorial-link{color:#667eea}.light-mode .tutorial-link:hover{color:#764ba2}</style><style id="detail-card-options">.card-showcase{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:none;gap:30px;z-index:200;padding:20px}.card-showcase.active{display:flex}.planet-detail-card{width:240px;background:rgba(255,255,255,.1);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.2);border-radius:12px;padding:16px;color:#fff;box-shadow:0 8px 32px rgba(0,0,0,.3);position:absolute;pointer-events:none;opacity:0;transition:opacity .2s;z-index:150}.planet-detail-card.visible{opacity:1;pointer-events:auto}.planet-detail-card .planet-header{display:flex;align-items:center;gap:10px;margin-bottom:12px;padding-bottom:10px;border-bottom:1px solid rgba(255,255,255,.15)}.planet-detail-card .planet-icon{width:32px;height:32px;border-radius:50%;box-shadow:0 0 12px rgba(255,200,100,.3);flex-shrink:0}.planet-detail-card .planet-name{font-size:18px;font-weight:600;background:linear-gradient(135deg,#f093fb,#667eea);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.planet-detail-card .stat-row{display:flex;justify-content:space-between;padding:6px 0;font-size:12px;border-bottom:1px solid rgba(255,255,255,.08)}.planet-detail-card .stat-row:last-of-type{border-bottom:none}.planet-detail-card .stat-label{color:rgba(255,255,255,.5)}.planet-detail-card .stat-value{color:#fff;font-weight:500}.planet-detail-card .fun-fact{margin-top:12px;padding:10px;background:rgba(102,126,234,.15);border-radius:8px;font-size:11px;color:rgba(255,255,255,.9);line-height:1.4;display:none}.planet-detail-card .fun-fact-label{color:#f093fb;font-weight:600;margin-bottom:4px;display:block}.planet-detail-card .question-section{margin-top:12px;display:none}.planet-detail-card .question-input{width:100%;padding:10px;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.2);border-radius:8px;color:#fff;font-size:12px;outline:none;box-sizing:border-box}.planet-detail-card .question-input::placeholder{color:rgba(255,255,255,.4)}.planet-detail-card .question-input:focus{border-color:#667eea;box-shadow:0 0 10px rgba(102,126,234,.3)}.planet-detail-card .ai-answer{margin-top:10px;padding:10px;background:rgba(240,147,251,.1);border-radius:8px;font-size:11px;color:rgba(255,255,255,.9);line-height:1.4;border-left:2px solid #f093fb;max-height:120px;overflow-y:auto;display:none}.planet-detail-card .ai-answer.visible{display:block}.planet-detail-card .ai-answer::-webkit-scrollbar{width:4px}.planet-detail-card .ai-answer::-webkit-scrollbar-track{background:rgba(255,255,255,.05);border-radius:2px}.planet-detail-card .ai-answer::-webkit-scrollbar-thumb{background:rgba(240,147,251,.3);border-radius:2px}.planet-detail-card .ai-answer::-webkit-scrollbar-thumb:hover{background:rgba(240,147,251,.5)}.planet-detail-card.mode-funfact .fun-fact{display:block}.planet-detail-card.mode-funfact .question-section{display:none}.planet-detail-card.mode-question .fun-fact{display:none}.planet-detail-card.mode-question .question-section{display:block}.light-mode .planet-detail-card{background:rgba(45,38,64,.9);border-color:rgba(118,75,162,.3)}.light-mode .planet-detail-card .stat-label{color:rgba(255,255,255,.6)}.light-mode .planet-detail-card .question-input{background:rgba(255,255,255,.15);border-color:rgba(255,255,255,.25)}</style><style id="detail-view-styles">.detail-view-container{position:absolute;top:0;left:0;width:100%;height:100%;display:none;background:#0a0a19}.detail-view-container.active{display:flex}.detail-planet-area{flex:1;position:relative;display:flex;align-items:center;justify-content:center}.detail-planet-canvas{width:100%;height:100%}.detail-sidebar{width:300px;background:rgba(15,15,35,.95);border-left:1px solid rgba(138,43,226,.3);padding:20px;overflow-y:auto;display:flex;flex-direction:column;gap:15px}.detail-sidebar .planet-detail-card{position:relative;opacity:1;pointer-events:auto;width:100%;box-sizing:border-box}.back-button{padding:10px 20px;border:none;border-radius:15px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;cursor:pointer;font-size:13px;transition:.3s;margin-bottom:10px}.back-button:hover{transform:scale(1.05);box-shadow:0 0 15px rgba(102,126,234,.5)}.moon-speed-control{background:rgba(255,255,255,.1);padding:12px;border-radius:10px;margin-top:10px}.moon-speed-control label{color:#b794f6;font-size:12px;display:block;margin-bottom:8px}.moon-speed-control input[type="range"]{width:100%;accent-color:#f093fb}.moon-detail-card{position:absolute;width:200px;background:rgba(255,255,255,.1);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.2);border-radius:10px;padding:12px;color:#fff;box-shadow:0 8px 32px rgba(0,0,0,.3);pointer-events:none;opacity:0;transition:opacity .2s;z-index:200}.moon-detail-card.visible{opacity:1}.moon-detail-card .moon-name{font-size:14px;font-weight:600;background:linear-gradient(135deg,#f093fb,#667eea);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;margin-bottom:8px}.moon-detail-card .moon-stat{display:flex;justify-content:space-between;padding:4px 0;font-size:11px;border-bottom:1px solid rgba(255,255,255,.08)}.moon-detail-card .moon-stat:last-of-type{border-bottom:none}.moon-detail-card .moon-stat-label{color:rgba(255,255,255,.5)}.moon-detail-card .moon-stat-value{color:#fff}.moon-detail-card .moon-fun-fact{margin-top:8px;padding:8px;background:rgba(102,126,234,.15);border-radius:6px;font-size:10px;color:rgba(255,255,255,.9);line-height:1.4}.light-mode .detail-view-container{background:#0a0a19}.light-mode .detail-sidebar{background:rgba(15,15,35,.95)}</style>
|
|
128
129
|
<script id="planet-details" type="application/json" data-locked="true">{"sun":{"name":"The Sun","type":"G-type main-sequence star","diameter":"1,392,700 km","surfaceTemp":"5,500°C","funFact":"Contains 99.86% of the Solar System's mass and could fit 1.3 million Earths inside it."},"planets":{"mercury":{"name":"Mercury","color":"#b5b5b5","type":"Terrestrial","diameter":"4,879 km","distance":"57.9 million km","orbitalPeriod":"88 Earth days","dayLength":"59 Earth days","surfaceTemp":"-180°C to 430°C","moons":0,"funFact":"Despite being closest to the Sun, Mercury isn't the hottest planet. Its lack of atmosphere means heat escapes quickly at night."},"venus":{"name":"Venus","color":"#e6c87a","type":"Terrestrial","diameter":"12,104 km","distance":"108.2 million km","orbitalPeriod":"225 Earth days","dayLength":"243 Earth days","surfaceTemp":"465°C","moons":0,"funFact":"Venus rotates backwards compared to other planets, so the Sun rises in the west and sets in the east."},"earth":{"name":"Earth","color":"#6b93d6","type":"Terrestrial","diameter":"12,742 km","distance":"149.6 million km","orbitalPeriod":"365.25 days","dayLength":"24 hours","surfaceTemp":"-89°C to 57°C","moons":1,"funFact":"Earth is the only planet not named after a Greek or Roman god. Its name comes from Old English meaning 'ground'.","moonData":{"luna":{"name":"Luna (The Moon)","diameter":"3,474 km","distance":"384,400 km","distanceKm":384400,"orbitalPeriod":"27.3 days","funFact":"The Moon is slowly drifting away from Earth at about 3.8 cm per year."}}},"mars":{"name":"Mars","color":"#c1440e","type":"Terrestrial","diameter":"6,779 km","distance":"227.9 million km","orbitalPeriod":"687 Earth days","dayLength":"24.6 hours","surfaceTemp":"-125°C to 20°C","moons":2,"funFact":"Mars has the largest volcano in the solar system, Olympus Mons, which is nearly 3 times the height of Mount Everest.","moonData":{"phobos":{"name":"Phobos","diameter":"22.4 km","distance":"9,376 km","distanceKm":9376,"orbitalPeriod":"7.7 hours","funFact":"Phobos orbits Mars faster than Mars rotates, so it rises in the west and sets in the east."},"deimos":{"name":"Deimos","diameter":"12.4 km","distance":"23,463 km","distanceKm":23463,"orbitalPeriod":"30.3 hours","funFact":"Deimos is one of the smallest moons in the solar system and may be a captured asteroid."}}},"jupiter":{"name":"Jupiter","color":"#d4a574","type":"Gas Giant","diameter":"139,820 km","distance":"778.5 million km","orbitalPeriod":"11.86 Earth years","dayLength":"9.9 hours","surfaceTemp":"-110°C","moons":95,"funFact":"Jupiter's Great Red Spot is a storm that has been raging for at least 400 years and is larger than Earth.","moonData":{"io":{"name":"Io","diameter":"3,643 km","distance":"421,700 km","distanceKm":421700,"orbitalPeriod":"1.77 days","funFact":"Io is the most volcanically active body in the solar system with over 400 active volcanoes."},"europa":{"name":"Europa","diameter":"3,122 km","distance":"671,034 km","distanceKm":671034,"orbitalPeriod":"3.55 days","funFact":"Europa likely has a subsurface ocean containing more water than all of Earth's oceans combined."},"ganymede":{"name":"Ganymede","diameter":"5,268 km","distance":"1,070,400 km","distanceKm":1070400,"orbitalPeriod":"7.15 days","funFact":"Ganymede is the largest moon in the solar system, even bigger than the planet Mercury."},"callisto":{"name":"Callisto","diameter":"4,821 km","distance":"1,882,700 km","distanceKm":1882700,"orbitalPeriod":"16.69 days","funFact":"Callisto has the oldest and most heavily cratered surface in the solar system."}}},"saturn":{"name":"Saturn","color":"#f4d59e","type":"Gas Giant","diameter":"116,460 km","distance":"1.43 billion km","orbitalPeriod":"29.46 Earth years","dayLength":"10.7 hours","surfaceTemp":"-140°C","moons":146,"funFact":"Saturn's density is so low that it would float if you could find a bathtub big enough to hold it.","moonData":{"mimas":{"name":"Mimas","diameter":"396 km","distance":"185,520 km","distanceKm":185520,"orbitalPeriod":"0.94 days","funFact":"Mimas has a giant crater that makes it look like the Death Star from Star Wars."},"enceladus":{"name":"Enceladus","diameter":"504 km","distance":"238,020 km","distanceKm":238020,"orbitalPeriod":"1.37 days","funFact":"Enceladus shoots geysers of water ice into space, suggesting a subsurface ocean."},"tethys":{"name":"Tethys","diameter":"1,062 km","distance":"294,619 km","distanceKm":294619,"orbitalPeriod":"1.89 days","funFact":"Tethys has a massive canyon called Ithaca Chasma that stretches 2,000 km across its surface."},"dione":{"name":"Dione","diameter":"1,123 km","distance":"377,396 km","distanceKm":377396,"orbitalPeriod":"2.74 days","funFact":"Dione has wispy ice cliffs and may have a subsurface ocean beneath its icy crust."},"rhea":{"name":"Rhea","diameter":"1,527 km","distance":"527,040 km","distanceKm":527040,"orbitalPeriod":"4.52 days","funFact":"Rhea may have its own faint ring system, which would make it the only moon known to have rings."},"titan":{"name":"Titan","diameter":"5,150 km","distance":"1,221,870 km","distanceKm":1221870,"orbitalPeriod":"15.95 days","funFact":"Titan is the only moon with a dense atmosphere and has lakes of liquid methane on its surface."},"iapetus":{"name":"Iapetus","diameter":"1,469 km","distance":"3,560,820 km","distanceKm":3560820,"orbitalPeriod":"79.32 days","funFact":"Iapetus has one hemisphere as dark as coal and the other as bright as snow, giving it a striking two-toned appearance."}}},"uranus":{"name":"Uranus","color":"#d1e7e7","type":"Ice Giant","diameter":"50,724 km","distance":"2.87 billion km","orbitalPeriod":"84.01 Earth years","dayLength":"17.2 hours","surfaceTemp":"-195°C","moons":28,"funFact":"Uranus rotates on its side with an axial tilt of 98°, possibly due to a collision with an Earth-sized object.","moonData":{"miranda":{"name":"Miranda","diameter":"472 km","distance":"129,390 km","distanceKm":129390,"orbitalPeriod":"1.41 days","funFact":"Miranda has the tallest known cliff in the solar system, Verona Rupes, at 20 km high."},"ariel":{"name":"Ariel","diameter":"1,158 km","distance":"191,020 km","distanceKm":191020,"orbitalPeriod":"2.52 days","funFact":"Ariel is the brightest of Uranus's moons and has extensive canyon systems."},"umbriel":{"name":"Umbriel","diameter":"1,169 km","distance":"266,000 km","distanceKm":266000,"orbitalPeriod":"4.14 days","funFact":"Umbriel is the darkest of Uranus's major moons, with a mysterious bright ring on its surface called Wunda crater."},"titania":{"name":"Titania","diameter":"1,578 km","distance":"435,910 km","distanceKm":435910,"orbitalPeriod":"8.71 days","funFact":"Titania is the largest moon of Uranus and may have a subsurface ocean."},"oberon":{"name":"Oberon","diameter":"1,523 km","distance":"583,520 km","distanceKm":583520,"orbitalPeriod":"13.46 days","funFact":"Oberon has a mountain that rises about 6 km above the surrounding terrain."}}},"neptune":{"name":"Neptune","color":"#5b5ddf","type":"Ice Giant","diameter":"49,244 km","distance":"4.5 billion km","orbitalPeriod":"164.8 Earth years","dayLength":"16.1 hours","surfaceTemp":"-200°C","moons":16,"funFact":"Neptune has the strongest winds in the solar system, reaching speeds of 2,100 km/h.","moonData":{"triton":{"name":"Triton","diameter":"2,707 km","distance":"354,760 km","distanceKm":354760,"orbitalPeriod":"5.88 days (retrograde)","funFact":"Triton orbits Neptune backwards and is slowly spiraling inward, destined to be torn apart in about 3.6 billion years."},"proteus":{"name":"Proteus","diameter":"420 km","distance":"117,647 km","distanceKm":117647,"orbitalPeriod":"1.12 days","funFact":"Proteus is Neptune's second largest moon and is irregularly shaped — it's about as large as an object can be without being pulled into a sphere by its own gravity."},"nereid":{"name":"Nereid","diameter":"340 km","distance":"5,513,400 km","distanceKm":5513400,"orbitalPeriod":"360.14 days","funFact":"Nereid has one of the most eccentric orbits of any known moon in the solar system."}}},"pluto":{"name":"Pluto","color":"#a89f91","type":"Dwarf Planet","diameter":"2,377 km","distance":"5.9 billion km","orbitalPeriod":"248 Earth years","dayLength":"6.4 Earth days","surfaceTemp":"-230°C","moons":5,"funFact":"Pluto has a heart-shaped glacier called Tombaugh Regio that's larger than Texas.","moonData":{"charon":{"name":"Charon","diameter":"1,212 km","distance":"19,571 km","distanceKm":19571,"orbitalPeriod":"6.4 days","funFact":"Charon is so large relative to Pluto that they orbit a point in space between them, making them a 'double dwarf planet'."},"styx":{"name":"Styx","diameter":"16 km","distance":"42,656 km","distanceKm":42656,"orbitalPeriod":"20.16 days","funFact":"Styx is the smallest and last-discovered moon of Pluto, found in 2012 by the Hubble Space Telescope."},"nix":{"name":"Nix","diameter":"50 km","distance":"48,694 km","distanceKm":48694,"orbitalPeriod":"24.85 days","funFact":"Nix rotates chaotically due to the gravitational influence of Pluto and Charon."},"kerberos":{"name":"Kerberos","diameter":"19 km","distance":"57,783 km","distanceKm":57783,"orbitalPeriod":"32.17 days","funFact":"Kerberos is surprisingly small and dark, defying predictions that it would be large and bright."},"hydra":{"name":"Hydra","diameter":"51 km","distance":"64,738 km","distanceKm":64738,"orbitalPeriod":"38.2 days","funFact":"Hydra is shaped like a potato and tumbles unpredictably as it orbits."}}}}}</script>
|
|
129
130
|
</head>
|
|
130
131
|
<body>
|
|
132
|
+
<div class="shell-toolbar" data-locked="true">
|
|
133
|
+
<button class="shell-toolbar-btn" id="builderToggle" aria-label="Page Builder" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M7 18.5H6.2c-1.77 0-3.2-1.43-3.2-3.2V7.7C3 5.93 4.43 4.5 6.2 4.5h11.6c1.77 0 3.2 1.43 3.2 3.2v7.6c0 1.77-1.43 3.2-3.2 3.2H12l-4.2 3.2c-.5.38-1.2.02-1.2-.6V18.5Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><circle cx="8.5" cy="11.5" r="1" fill="currentColor"/><circle cx="12" cy="11.5" r="1" fill="currentColor"/><circle cx="15.5" cy="11.5" r="1" fill="currentColor"/></svg></button>
|
|
134
|
+
<button class="shell-toolbar-btn" id="pagesBtn" aria-label="View All Pages" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none"><rect x="3" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 7.5h5M6 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 7.5h5M21 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="3" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 22.5h5M6 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 22.5h5M21 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
|
|
135
|
+
<button class="shell-toolbar-btn" id="saveBtn" aria-label="Save Page" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M17 21v-8H7v8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M7 3v5h8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></button>
|
|
136
|
+
<div class="shell-toolbar-spacer" data-locked="true"></div>
|
|
137
|
+
<button class="shell-toolbar-btn" id="settingsBtn" aria-label="Settings" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" stroke="currentColor" stroke-width="1.8"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
|
138
|
+
</div>
|
|
131
139
|
<div class="chat-panel" data-locked="true">
|
|
132
|
-
<div class="chat-header" data-locked="true">
|
|
140
|
+
<div class="chat-header" data-locked="true"><span>Page Builder</span><button class="chat-header-close" id="builderClose" aria-label="Close builder" data-locked="true">×</button></div>
|
|
133
141
|
<div class="chat-messages" id="chatMessages" data-locked="true">
|
|
134
142
|
<div class="chat-message"><p><strong>SynthOS:</strong> Welcome to this Solar Tutorial! I'll guide you through building interactive features for this simulation of the Solar System. Let's start with something simple: <a href="#" class="tutorial-link" data-message="add a reverse time button">add a reverse time button</a> so users can watch planets orbit backwards!</p></div>
|
|
135
143
|
|
|
136
144
|
|
|
137
|
-
</div>
|
|
138
|
-
<div class="link-group" data-locked="true">
|
|
139
|
-
<a href="#" id="saveLink" data-locked="true">Save</a>
|
|
140
|
-
<a href="/pages" id="pagesLink" data-locked="true">Pages</a>
|
|
141
|
-
<a href="#" id="resetLink" data-locked="true">Reset</a>
|
|
142
|
-
</div>
|
|
145
|
+
</div>
|
|
143
146
|
<form action="/" method="POST" id="chatForm" data-locked="true">
|
|
144
|
-
<
|
|
145
|
-
<button type="submit" class="chat-submit" data-locked="true">Send</button>
|
|
147
|
+
<textarea class="chat-input" id="chatInput" name="message" rows="2" placeholder="Type a message..." data-locked="true"></textarea>
|
|
146
148
|
</form>
|
|
147
149
|
</div>
|
|
148
150
|
<div class="viewer-panel full-viewer" id="viewerPanel" style="background: #0a0a19;">
|
|
@@ -473,4 +475,4 @@ animate();
|
|
|
473
475
|
|
|
474
476
|
|
|
475
477
|
<script id="tutorial-links">document.addEventListener('click',function(e){if(e.target.classList.contains('tutorial-link')){e.preventDefault();const message=e.target.getAttribute('data-message');const chatInput=document.getElementById('chatInput');if(chatInput&&message){chatInput.value=message;chatInput.focus()}}});</script>
|
|
476
|
-
<script id="page-helpers" src="/api/page-helpers.js?v=
|
|
478
|
+
<script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script><script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script></body></html>
|
|
@@ -7,22 +7,24 @@
|
|
|
7
7
|
<style>.application-panel{width:100%;max-width:900px;height:calc(100vh - 50px);display:flex;flex-direction:column;position:relative;z-index:1;border-radius:15px;overflow:hidden;border:1px solid var(--border-color);box-shadow:0 0 40px var(--accent-glow)}.application-header{font-size:18px;font-weight:600;padding:14px 20px;background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary));color:#fff;text-align:center;text-shadow:0 2px 8px rgba(0,0,0,.3);letter-spacing:1px}.application-content{flex:1;display:flex;flex-direction:column;background:rgba(15,15,35,.6);overflow:hidden}.application-content.vertical{flex-direction:row}.application-bottom,.application-top{flex-basis:50%;padding:20px;overflow-y:auto;display:flex;flex-direction:column}.application-top{background:linear-gradient(180deg,rgba(102,126,234,.1) 0,rgba(118,75,162,.05) 100%);border-bottom:none}.application-bottom{background:linear-gradient(180deg,rgba(118,75,162,.05) 0,rgba(240,147,251,.1) 100%)}.application-content.vertical .application-top{background:linear-gradient(90deg,rgba(102,126,234,.1) 0,rgba(118,75,162,.05) 100%)}.application-content.vertical .application-bottom{background:linear-gradient(90deg,rgba(118,75,162,.05) 0,rgba(240,147,251,.1) 100%)}.application-left{flex-basis:50%;padding:20px;overflow-y:auto;display:flex;flex-direction:column;background:linear-gradient(90deg,rgba(102,126,234,.1) 0,rgba(118,75,162,.05) 100%)}.application-right{flex-basis:50%;padding:20px;overflow-y:auto;display:flex;flex-direction:column;background:linear-gradient(90deg,rgba(118,75,162,.05) 0,rgba(240,147,251,.1) 100%)}.application-bottom p,.application-top p,.application-left p,.application-right p{color:var(--text-secondary);font-size:14px;line-height:1.6}.panel-title{font-size:14px;font-weight:600;color:var(--accent-tertiary);margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--border-color);text-transform:uppercase;letter-spacing:1px}.splitter{height:8px;background:linear-gradient(90deg,var(--accent-primary),var(--accent-secondary),var(--accent-tertiary));cursor:row-resize;flex-shrink:0;position:relative;transition:.2s}.splitter::before{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:40px;height:4px;background:rgba(255,255,255,.3);border-radius:2px}.splitter:hover{background:linear-gradient(90deg,var(--accent-tertiary),var(--accent-secondary),var(--accent-primary));box-shadow:0 0 15px var(--accent-glow)}.splitter.vertical{width:8px;height:auto;cursor:col-resize;background:linear-gradient(180deg,var(--accent-primary),var(--accent-secondary),var(--accent-tertiary))}.splitter.vertical::before{width:4px;height:40px}.splitter.vertical:hover{background:linear-gradient(180deg,var(--accent-tertiary),var(--accent-secondary),var(--accent-primary))}</style>
|
|
8
8
|
<style id="placeholder-styles">.content-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:1;min-height:100px;color:var(--text-secondary);text-align:center;padding:20px;opacity:0.7;transition:opacity 0.3s ease}.content-placeholder .placeholder-icon{font-size:2.5em;margin-bottom:12px;animation:float 3s ease-in-out infinite}.content-placeholder .placeholder-text{font-size:1.1em;font-weight:600;background:linear-gradient(90deg,var(--accent-primary),var(--accent-tertiary));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;margin-bottom:6px}.content-placeholder .placeholder-hint{font-size:0.85em;color:var(--text-secondary);opacity:0.8}@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}.light-mode .content-placeholder{color:var(--text-secondary)}.light-mode .application-content{background:rgba(245,245,250,.6)}.light-mode .application-top{background:linear-gradient(180deg,rgba(102,126,234,.05) 0,rgba(118,75,162,.02) 100%)}.light-mode .application-bottom{background:linear-gradient(180deg,rgba(118,75,162,.02) 0,rgba(240,147,251,.05) 100%)}.light-mode .application-content.vertical .application-top{background:linear-gradient(90deg,rgba(102,126,234,.05) 0,rgba(118,75,162,.02) 100%)}.light-mode .application-content.vertical .application-bottom{background:linear-gradient(90deg,rgba(118,75,162,.02) 0,rgba(240,147,251,.05) 100%)}.light-mode .application-left{background:linear-gradient(90deg,rgba(102,126,234,.05) 0,rgba(118,75,162,.02) 100%)}.light-mode .application-right{background:linear-gradient(90deg,rgba(118,75,162,.02) 0,rgba(240,147,251,.05) 100%)}</style>
|
|
9
9
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.1/marked.min.js"></script>
|
|
10
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
|
10
11
|
<script id="page-info" src="/api/page-info.js?page=split-application"></script>
|
|
11
12
|
</head>
|
|
12
13
|
<body>
|
|
14
|
+
<div class="shell-toolbar" data-locked="true">
|
|
15
|
+
<button class="shell-toolbar-btn" id="builderToggle" aria-label="Page Builder" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M7 18.5H6.2c-1.77 0-3.2-1.43-3.2-3.2V7.7C3 5.93 4.43 4.5 6.2 4.5h11.6c1.77 0 3.2 1.43 3.2 3.2v7.6c0 1.77-1.43 3.2-3.2 3.2H12l-4.2 3.2c-.5.38-1.2.02-1.2-.6V18.5Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><circle cx="8.5" cy="11.5" r="1" fill="currentColor"/><circle cx="12" cy="11.5" r="1" fill="currentColor"/><circle cx="15.5" cy="11.5" r="1" fill="currentColor"/></svg></button>
|
|
16
|
+
<button class="shell-toolbar-btn" id="pagesBtn" aria-label="View All Pages" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none"><rect x="3" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 7.5h5M6 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 7.5h5M21 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="3" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 22.5h5M6 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 22.5h5M21 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
|
|
17
|
+
<button class="shell-toolbar-btn" id="saveBtn" aria-label="Save Page" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M17 21v-8H7v8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M7 3v5h8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></button>
|
|
18
|
+
<div class="shell-toolbar-spacer" data-locked="true"></div>
|
|
19
|
+
<button class="shell-toolbar-btn" id="settingsBtn" aria-label="Settings" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" stroke="currentColor" stroke-width="1.8"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
|
20
|
+
</div>
|
|
13
21
|
<div class="chat-panel" data-locked="true">
|
|
14
|
-
<div class="chat-header" data-locked="true">
|
|
22
|
+
<div class="chat-header" data-locked="true"><span>Page Builder</span><button class="chat-header-close" id="builderClose" aria-label="Close builder" data-locked="true">×</button></div>
|
|
15
23
|
<div class="chat-messages" id="chatMessages" data-locked="true">
|
|
16
24
|
<div class="chat-message"><p><strong>SynthOS:</strong> Welcome to the <strong>Two-Panel</strong> layout template! By default, panels are stacked <strong>top/bottom</strong> (horizontal splitter). You can ask me to switch to <strong>left/right</strong> (vertical splitter) at any time. Just tell me what you'd like in each panel!</p></div>
|
|
17
|
-
</div>
|
|
18
|
-
<div class="link-group" data-locked="true">
|
|
19
|
-
<a href="#" id="saveLink" data-locked="true">Save</a>
|
|
20
|
-
<a href="/pages" id="pagesLink" data-locked="true">Pages</a>
|
|
21
|
-
<a href="#" id="resetLink" data-locked="true">Reset</a>
|
|
22
|
-
</div>
|
|
25
|
+
</div>
|
|
23
26
|
<form action="/" method="POST" id="chatForm" data-locked="true">
|
|
24
|
-
<
|
|
25
|
-
<button type="submit" class="chat-submit" data-locked="true">Send</button>
|
|
27
|
+
<textarea class="chat-input" id="chatInput" name="message" rows="2" placeholder="Type a message..." data-locked="true"></textarea>
|
|
26
28
|
</form>
|
|
27
29
|
</div>
|
|
28
30
|
<div class="viewer-panel" id="viewerPanel">
|
|
@@ -61,6 +63,6 @@ If the user says "top/bottom", "stacked", or "horizontal" — switch to horizont
|
|
|
61
63
|
When switching orientation, preserve existing panel content.</div>
|
|
62
64
|
<div id="thoughts" style="display: none;" data-locked="true"></div>
|
|
63
65
|
<script id="splitter-logic">const splitter=document.getElementById("splitter"),content=document.getElementById("applicationContent");let isDragging=false;function getOrientation(){return content.dataset.orientation||"horizontal"}splitter.addEventListener("mousedown",()=>{isDragging=true;document.body.style.cursor=getOrientation()==="vertical"?"col-resize":"row-resize"});document.addEventListener("mousemove",e=>{if(!isDragging)return;const rect=content.getBoundingClientRect();const panels=content.querySelectorAll(':scope > :not(.splitter)');if(panels.length<2)return;const first=panels[0],second=panels[1];if(getOrientation()==="vertical"){const pct=(e.clientX-rect.left)/rect.width*100;if(pct>10&&pct<90){first.style.flexBasis=pct+"%";second.style.flexBasis=(100-pct)+"%"}}else{const pct=(e.clientY-rect.top)/rect.height*100;if(pct>10&&pct<90){first.style.flexBasis=pct+"%";second.style.flexBasis=(100-pct)+"%"}}});document.addEventListener("mouseup",()=>{isDragging=false;document.body.style.cursor="default"});</script>
|
|
64
|
-
<script id="page-helpers" src="/api/page-helpers.js?v=
|
|
65
|
-
<script id="page-script" src="/api/page-script.js?v=
|
|
66
|
+
<script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script>
|
|
67
|
+
<script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script>
|
|
66
68
|
</body></html>
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en"><head>
|
|
2
|
+
<meta charset="UTF-8">
|
|
3
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
4
|
+
<title>SynthOS</title>
|
|
5
|
+
<script id="theme-info" src="/api/theme-info.js" data-locked="true"></script>
|
|
6
|
+
<link id="theme-css" rel="stylesheet" href="/api/theme.css" data-locked="true">
|
|
7
|
+
<style>.idle-container{position:absolute;width:100%;height:100%;pointer-events:none;opacity:1;transition:opacity 1s ease-out}.idle-container.hidden{opacity:0}.breathing-orb{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:80px;height:80px;border-radius:50%;background:radial-gradient(circle,rgba(102,126,234,.15) 0,transparent 70%);animation:4s ease-in-out infinite breathe}.breathing-orb::before{content:'';position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:8px;height:8px;border-radius:50%;background:rgba(183,148,246,.6);box-shadow:0 0 20px rgba(183,148,246,.4);animation:4s ease-in-out infinite core-pulse}@keyframes breathe{0%,100%{width:80px;height:80px;opacity:.3}50%{width:120px;height:120px;opacity:.6}}@keyframes core-pulse{0%,100%{opacity:.4;box-shadow:0 0 20px rgba(183,148,246,.3)}50%{opacity:.8;box-shadow:0 0 30px rgba(183,148,246,.5)}}.orbit-ring{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:200px;height:200px;border:1px solid rgba(102,126,234,.1);border-radius:50%;animation:20s linear infinite orbit-rotate}.orbit-ring::after{content:'';position:absolute;top:-3px;left:50%;transform:translateX(-50%);width:6px;height:6px;background:rgba(240,147,251,.5);border-radius:50%;box-shadow:0 0 10px rgba(240,147,251,.3)}@keyframes orbit-rotate{from{transform:translate(-50%,-50%) rotate(0)}to{transform:translate(-50%,-50%) rotate(360deg)}}</style>
|
|
8
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"></script>
|
|
9
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.1/marked.min.js"></script>
|
|
10
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.1.0/mermaid.min.js"></script>
|
|
11
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
|
12
|
+
<script id="page-info" src="/api/page-info.js?page=builder"></script>
|
|
13
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.2/topojson.min.js" id="topojson-lib"></script><style id="us-map-styles">
|
|
14
|
+
#us-map-container {
|
|
15
|
+
width: 100%;
|
|
16
|
+
height: 100%;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
background: var(--bg-primary);
|
|
22
|
+
position: relative;
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
}
|
|
25
|
+
#us-map-container h2 {
|
|
26
|
+
color: var(--text-primary);
|
|
27
|
+
margin: 0;
|
|
28
|
+
padding: 12px 0 4px 0;
|
|
29
|
+
font-size: 1.4rem;
|
|
30
|
+
font-weight: 600;
|
|
31
|
+
letter-spacing: 0.02em;
|
|
32
|
+
}
|
|
33
|
+
#us-map-svg {
|
|
34
|
+
width: 100%;
|
|
35
|
+
flex: 1;
|
|
36
|
+
min-height: 0;
|
|
37
|
+
}
|
|
38
|
+
#us-map-svg .state {
|
|
39
|
+
fill: var(--accent-primary);
|
|
40
|
+
stroke: var(--bg-primary);
|
|
41
|
+
stroke-width: 1;
|
|
42
|
+
cursor: pointer;
|
|
43
|
+
transition: fill 0.2s ease;
|
|
44
|
+
}
|
|
45
|
+
#us-map-svg .state:hover {
|
|
46
|
+
fill: var(--accent-tertiary);
|
|
47
|
+
}
|
|
48
|
+
#us-map-svg .state-border {
|
|
49
|
+
fill: none;
|
|
50
|
+
stroke: var(--bg-primary);
|
|
51
|
+
stroke-width: 1.5;
|
|
52
|
+
}
|
|
53
|
+
#us-map-svg .nation-border {
|
|
54
|
+
fill: none;
|
|
55
|
+
stroke: var(--text-secondary);
|
|
56
|
+
stroke-width: 1.5;
|
|
57
|
+
}
|
|
58
|
+
#map-tooltip {
|
|
59
|
+
position: absolute;
|
|
60
|
+
pointer-events: none;
|
|
61
|
+
background: var(--bg-tertiary);
|
|
62
|
+
color: var(--text-primary);
|
|
63
|
+
border: 1px solid var(--border-color);
|
|
64
|
+
border-radius: 6px;
|
|
65
|
+
padding: 6px 12px;
|
|
66
|
+
font-size: 0.9rem;
|
|
67
|
+
font-weight: 500;
|
|
68
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.12);
|
|
69
|
+
opacity: 0;
|
|
70
|
+
transition: opacity 0.15s ease;
|
|
71
|
+
z-index: 10;
|
|
72
|
+
}
|
|
73
|
+
.light-mode #us-map-svg .state {
|
|
74
|
+
fill: var(--accent-primary);
|
|
75
|
+
stroke: var(--bg-primary);
|
|
76
|
+
}
|
|
77
|
+
.light-mode #us-map-svg .state:hover {
|
|
78
|
+
fill: var(--accent-tertiary);
|
|
79
|
+
}
|
|
80
|
+
</style></head>
|
|
81
|
+
<body>
|
|
82
|
+
<div class="shell-toolbar" data-locked="true">
|
|
83
|
+
<button class="shell-toolbar-btn" id="builderToggle" aria-label="Page Builder" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M7 18.5H6.2c-1.77 0-3.2-1.43-3.2-3.2V7.7C3 5.93 4.43 4.5 6.2 4.5h11.6c1.77 0 3.2 1.43 3.2 3.2v7.6c0 1.77-1.43 3.2-3.2 3.2H12l-4.2 3.2c-.5.38-1.2.02-1.2-.6V18.5Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><circle cx="8.5" cy="11.5" r="1" fill="currentColor"/><circle cx="12" cy="11.5" r="1" fill="currentColor"/><circle cx="15.5" cy="11.5" r="1" fill="currentColor"/></svg></button>
|
|
84
|
+
<button class="shell-toolbar-btn" id="pagesBtn" aria-label="View All Pages" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none"><rect x="3" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 7.5h5M6 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="3" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 7.5h5M21 10h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="3" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M6 22.5h5M6 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><rect x="18" y="18" width="11" height="12" rx="1.5" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M21 22.5h5M21 25h3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg></button>
|
|
85
|
+
<button class="shell-toolbar-btn" id="saveBtn" aria-label="Save Page" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M17 21v-8H7v8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/><path d="M7 3v5h8" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/></svg></button>
|
|
86
|
+
<div class="shell-toolbar-spacer" data-locked="true"></div>
|
|
87
|
+
<button class="shell-toolbar-btn" id="settingsBtn" aria-label="Settings" data-locked="true"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" stroke="currentColor" stroke-width="1.8"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg></button>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="chat-panel" data-locked="true">
|
|
90
|
+
<div class="chat-header" data-locked="true"><span>Page Builder</span><button class="chat-header-close" id="builderClose" aria-label="Close builder" data-locked="true">×</button></div>
|
|
91
|
+
<div class="chat-messages" id="chatMessages" data-locked="true">
|
|
92
|
+
<div class="chat-message" id="defaultGreeting"><p><strong>SynthOS:</strong> Here's your interactive US map! You can customize it by adding data to visualize — just tell me what you'd like to overlay. Here are a couple of ideas:
|
|
93
|
+
<ul style="margin:8px 0 4px 0;padding-left:20px;">
|
|
94
|
+
<li><strong>Population by state</strong> — color-coded choropleth showing population density</li>
|
|
95
|
+
<li><strong>Election results</strong> — red/blue map of voting outcomes by state</li>
|
|
96
|
+
<li><strong>Custom data</strong> — provide your own values per state (sales figures, temperatures, rankings, etc.)</li>
|
|
97
|
+
</ul>
|
|
98
|
+
What data would you like to see on the map?</p></div>
|
|
99
|
+
|
|
100
|
+
</div> <form action="/" method="POST" id="chatForm" data-locked="true">
|
|
101
|
+
<textarea class="chat-input" id="chatInput" name="message" rows="2" placeholder="Type a message..." data-locked="true"></textarea>
|
|
102
|
+
</form>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="viewer-panel full-viewer" id="viewerPanel"><div id="us-map-container">
|
|
105
|
+
<h2>United States</h2>
|
|
106
|
+
<svg id="us-map-svg"></svg>
|
|
107
|
+
<div id="map-tooltip"></div>
|
|
108
|
+
</div>
|
|
109
|
+
<div id="loadingOverlay" class="loading-overlay"><div class="spinner"></div></div></div>
|
|
110
|
+
<div id="instructions" style="display: none;" data-locked="true"></div>
|
|
111
|
+
<div id="thoughts" style="display: none;" data-locked="true"></div>
|
|
112
|
+
<script id="idle-animation">function hideIdleAnimation(){const idleContainer=document.getElementById("idleAnimation");idleContainer&&(idleContainer.classList.add("hidden"),setTimeout(()=>{idleContainer.style.display="none"},1e3))}function showIdleAnimation(){const idleContainer=document.getElementById("idleAnimation");idleContainer&&(idleContainer.style.display="block",setTimeout(()=>{idleContainer.classList.remove("hidden")},10))}</script>
|
|
113
|
+
<button class="chat-toggle" aria-label="Toggle chat panel">
|
|
114
|
+
<span class="chat-toggle-dots">
|
|
115
|
+
<span class="chat-toggle-dot"></span>
|
|
116
|
+
<span class="chat-toggle-dot"></span>
|
|
117
|
+
<span class="chat-toggle-dot"></span>
|
|
118
|
+
</span>
|
|
119
|
+
</button>
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
<script id="us-map-script">
|
|
123
|
+
(function() {
|
|
124
|
+
function initMap() {
|
|
125
|
+
if (typeof topojson === 'undefined') {
|
|
126
|
+
setTimeout(initMap, 100);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const container = document.getElementById('us-map-container');
|
|
131
|
+
const svg = d3.select('#us-map-svg');
|
|
132
|
+
const tooltip = document.getElementById('map-tooltip');
|
|
133
|
+
|
|
134
|
+
const width = container.clientWidth;
|
|
135
|
+
const height = container.clientHeight - 50;
|
|
136
|
+
|
|
137
|
+
svg.attr('viewBox', `0 0 ${width} ${height}`)
|
|
138
|
+
.attr('preserveAspectRatio', 'xMidYMid meet');
|
|
139
|
+
|
|
140
|
+
const projection = d3.geoAlbersUsa()
|
|
141
|
+
.fitSize([width - 40, height - 20], { type: 'Sphere' })
|
|
142
|
+
.translate([width / 2, height / 2]);
|
|
143
|
+
|
|
144
|
+
const path = d3.geoPath().projection(projection);
|
|
145
|
+
|
|
146
|
+
d3.json('https://cdn.jsdelivr.net/npm/us-atlas@3/states-10m.json').then(function(us) {
|
|
147
|
+
const states = topojson.feature(us, us.objects.states);
|
|
148
|
+
|
|
149
|
+
svg.selectAll('.state')
|
|
150
|
+
.data(states.features)
|
|
151
|
+
.enter()
|
|
152
|
+
.append('path')
|
|
153
|
+
.attr('class', 'state')
|
|
154
|
+
.attr('d', path)
|
|
155
|
+
.on('mousemove', function(event, d) {
|
|
156
|
+
tooltip.textContent = d.properties.name;
|
|
157
|
+
tooltip.style.opacity = '1';
|
|
158
|
+
const rect = container.getBoundingClientRect();
|
|
159
|
+
const x = event.clientX - rect.left + 12;
|
|
160
|
+
const y = event.clientY - rect.top - 30;
|
|
161
|
+
tooltip.style.left = x + 'px';
|
|
162
|
+
tooltip.style.top = y + 'px';
|
|
163
|
+
})
|
|
164
|
+
.on('mouseleave', function() {
|
|
165
|
+
tooltip.style.opacity = '0';
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
svg.append('path')
|
|
169
|
+
.datum(topojson.mesh(us, us.objects.states, (a, b) => a !== b))
|
|
170
|
+
.attr('class', 'state-border')
|
|
171
|
+
.attr('d', path);
|
|
172
|
+
|
|
173
|
+
svg.append('path')
|
|
174
|
+
.datum(topojson.mesh(us, us.objects.nation))
|
|
175
|
+
.attr('class', 'nation-border')
|
|
176
|
+
.attr('d', path);
|
|
177
|
+
}).catch(function(err) {
|
|
178
|
+
console.error('Failed to load US map data:', err);
|
|
179
|
+
container.innerHTML = '<p style="color:var(--text-secondary);text-align:center;padding:2rem;">Failed to load map data. Please try again.</p>';
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
window.addEventListener('resize', function() {
|
|
183
|
+
const w = container.clientWidth;
|
|
184
|
+
const h = container.clientHeight - 50;
|
|
185
|
+
svg.attr('viewBox', `0 0 ${w} ${h}`);
|
|
186
|
+
projection.fitSize([w - 40, h - 20], { type: 'Sphere' }).translate([w / 2, h / 2]);
|
|
187
|
+
svg.selectAll('path').attr('d', path);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
initMap();
|
|
192
|
+
})();
|
|
193
|
+
</script><script id="page-helpers" src="/api/page-helpers.js?v=3" data-locked="true"></script><script id="page-script" src="/api/page-script.js?v=3" data-locked="true"></script></body></html>
|