codemble 0.6.0__tar.gz → 0.6.2__tar.gz

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.
Files changed (243) hide show
  1. {codemble-0.6.0 → codemble-0.6.2}/CHANGELOG.md +28 -0
  2. {codemble-0.6.0 → codemble-0.6.2}/CLAUDE.md +15 -1
  3. {codemble-0.6.0 → codemble-0.6.2}/PKG-INFO +1 -1
  4. {codemble-0.6.0 → codemble-0.6.2}/codemble/__init__.py +1 -1
  5. codemble-0.6.2/codemble/web_dist/assets/index-CsUbeE2C.css +1 -0
  6. codemble-0.6.0/codemble/web_dist/assets/index-BWorxSL3.js → codemble-0.6.2/codemble/web_dist/assets/index-_4l8WmkY.js +1 -1
  7. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/index.html +2 -2
  8. codemble-0.6.2/docs/releases/v0.6.1.md +39 -0
  9. codemble-0.6.2/docs/releases/v0.6.2.md +25 -0
  10. {codemble-0.6.0 → codemble-0.6.2}/docs-site/package.json +1 -1
  11. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/star-chart.md +4 -0
  12. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/the-galaxy.md +16 -6
  13. {codemble-0.6.0 → codemble-0.6.2}/pyproject.toml +1 -1
  14. {codemble-0.6.0 → codemble-0.6.2}/web/package-lock.json +2 -2
  15. {codemble-0.6.0 → codemble-0.6.2}/web/package.json +2 -2
  16. codemble-0.6.2/web/scripts/check_mode_gate_portal.mjs +13 -0
  17. codemble-0.6.2/web/scripts/check_orbit_pointer_guard.mjs +34 -0
  18. {codemble-0.6.0 → codemble-0.6.2}/web/src/App.jsx +152 -103
  19. {codemble-0.6.0 → codemble-0.6.2}/web/src/GalaxyCanvas.jsx +8 -0
  20. {codemble-0.6.0 → codemble-0.6.2}/web/src/MapView.jsx +37 -1
  21. {codemble-0.6.0 → codemble-0.6.2}/web/src/ModeControl.jsx +9 -2
  22. codemble-0.6.2/web/src/orbitPointerGuard.js +40 -0
  23. {codemble-0.6.0 → codemble-0.6.2}/web/src/styles.css +125 -9
  24. codemble-0.6.0/codemble/web_dist/assets/index-wY0ZuS7b.css +0 -1
  25. {codemble-0.6.0 → codemble-0.6.2}/.env.example +0 -0
  26. {codemble-0.6.0 → codemble-0.6.2}/.gitattributes +0 -0
  27. {codemble-0.6.0 → codemble-0.6.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  28. {codemble-0.6.0 → codemble-0.6.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  29. {codemble-0.6.0 → codemble-0.6.2}/.github/ISSUE_TEMPLATE/early_tester.yml +0 -0
  30. {codemble-0.6.0 → codemble-0.6.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  31. {codemble-0.6.0 → codemble-0.6.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  32. {codemble-0.6.0 → codemble-0.6.2}/.github/dependabot.yml +0 -0
  33. {codemble-0.6.0 → codemble-0.6.2}/.github/workflows/ci.yml +0 -0
  34. {codemble-0.6.0 → codemble-0.6.2}/.github/workflows/pages.yml +0 -0
  35. {codemble-0.6.0 → codemble-0.6.2}/.github/workflows/publish-pypi.yml +0 -0
  36. {codemble-0.6.0 → codemble-0.6.2}/.gitignore +0 -0
  37. {codemble-0.6.0 → codemble-0.6.2}/AGENTS.md +0 -0
  38. {codemble-0.6.0 → codemble-0.6.2}/CODE_OF_CONDUCT.md +0 -0
  39. {codemble-0.6.0 → codemble-0.6.2}/CONTEXT.md +0 -0
  40. {codemble-0.6.0 → codemble-0.6.2}/CONTRIBUTING.md +0 -0
  41. {codemble-0.6.0 → codemble-0.6.2}/LICENSE +0 -0
  42. {codemble-0.6.0 → codemble-0.6.2}/NOTICE +0 -0
  43. {codemble-0.6.0 → codemble-0.6.2}/README.md +0 -0
  44. {codemble-0.6.0 → codemble-0.6.2}/SECURITY.md +0 -0
  45. {codemble-0.6.0 → codemble-0.6.2}/TESTING.md +0 -0
  46. {codemble-0.6.0 → codemble-0.6.2}/assets/demo.gif +0 -0
  47. {codemble-0.6.0 → codemble-0.6.2}/codemble/adapters/__init__.py +0 -0
  48. {codemble-0.6.0 → codemble-0.6.2}/codemble/adapters/base.py +0 -0
  49. {codemble-0.6.0 → codemble-0.6.2}/codemble/adapters/discovery.py +0 -0
  50. {codemble-0.6.0 → codemble-0.6.2}/codemble/adapters/parse_progress.py +0 -0
  51. {codemble-0.6.0 → codemble-0.6.2}/codemble/adapters/project.py +0 -0
  52. {codemble-0.6.0 → codemble-0.6.2}/codemble/adapters/python_ast.py +0 -0
  53. {codemble-0.6.0 → codemble-0.6.2}/codemble/adapters/typescript_tree_sitter.py +0 -0
  54. {codemble-0.6.0 → codemble-0.6.2}/codemble/checks/__init__.py +0 -0
  55. {codemble-0.6.0 → codemble-0.6.2}/codemble/checks/service.py +0 -0
  56. {codemble-0.6.0 → codemble-0.6.2}/codemble/cli.py +0 -0
  57. {codemble-0.6.0 → codemble-0.6.2}/codemble/graph/__init__.py +0 -0
  58. {codemble-0.6.0 → codemble-0.6.2}/codemble/graph/finalize.py +0 -0
  59. {codemble-0.6.0 → codemble-0.6.2}/codemble/graph/layout.py +0 -0
  60. {codemble-0.6.0 → codemble-0.6.2}/codemble/graph/mapview.py +0 -0
  61. {codemble-0.6.0 → codemble-0.6.2}/codemble/lens/__init__.py +0 -0
  62. {codemble-0.6.0 → codemble-0.6.2}/codemble/lens/javascript_typescript.py +0 -0
  63. {codemble-0.6.0 → codemble-0.6.2}/codemble/lens/python.py +0 -0
  64. {codemble-0.6.0 → codemble-0.6.2}/codemble/llm/__init__.py +0 -0
  65. {codemble-0.6.0 → codemble-0.6.2}/codemble/llm/local_status.py +0 -0
  66. {codemble-0.6.0 → codemble-0.6.2}/codemble/llm/providers.py +0 -0
  67. {codemble-0.6.0 → codemble-0.6.2}/codemble/llm/structural.py +0 -0
  68. {codemble-0.6.0 → codemble-0.6.2}/codemble/llm/study.py +0 -0
  69. {codemble-0.6.0 → codemble-0.6.2}/codemble/paths.py +0 -0
  70. {codemble-0.6.0 → codemble-0.6.2}/codemble/progress/__init__.py +0 -0
  71. {codemble-0.6.0 → codemble-0.6.2}/codemble/progress/store.py +0 -0
  72. {codemble-0.6.0 → codemble-0.6.2}/codemble/server/__init__.py +0 -0
  73. {codemble-0.6.0 → codemble-0.6.2}/codemble/server/app.py +0 -0
  74. {codemble-0.6.0 → codemble-0.6.2}/codemble/server/parse_job.py +0 -0
  75. {codemble-0.6.0 → codemble-0.6.2}/codemble/server/project_activation.py +0 -0
  76. {codemble-0.6.0 → codemble-0.6.2}/codemble/server/project_selection.py +0 -0
  77. {codemble-0.6.0 → codemble-0.6.2}/codemble/server/runtime.py +0 -0
  78. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  79. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  80. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  81. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  82. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/shippori-mincho-latin-500-normal-C-QwvIb3.woff +0 -0
  83. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/shippori-mincho-latin-500-normal-XI1O8euf.woff2 +0 -0
  84. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/shippori-mincho-latin-700-normal-CkoCYOiI.woff +0 -0
  85. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/shippori-mincho-latin-700-normal-DHcmzUO5.woff2 +0 -0
  86. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/zen-kaku-gothic-new-latin-400-normal-BEdayliK.woff2 +0 -0
  87. {codemble-0.6.0 → codemble-0.6.2}/codemble/web_dist/assets/zen-kaku-gothic-new-latin-400-normal-CPSmNJAU.woff +0 -0
  88. {codemble-0.6.0 → codemble-0.6.2}/docs/adr/README.md +0 -0
  89. {codemble-0.6.0 → codemble-0.6.2}/docs/plans/2026-07-19-audience-modes-and-local-narration-design.md +0 -0
  90. {codemble-0.6.0 → codemble-0.6.2}/docs/plans/2026-07-19-audience-modes-backend-plan.md +0 -0
  91. {codemble-0.6.0 → codemble-0.6.2}/docs/plans/2026-07-19-audience-modes-frontend-plan.md +0 -0
  92. {codemble-0.6.0 → codemble-0.6.2}/docs/plans/2026-07-19-install-ux-folder-picker-design.md +0 -0
  93. {codemble-0.6.0 → codemble-0.6.2}/docs/plans/2026-07-19-install-ux-folder-picker-plan.md +0 -0
  94. {codemble-0.6.0 → codemble-0.6.2}/docs/plans/2026-07-20-oss-inspired-map-and-constellations.md +0 -0
  95. {codemble-0.6.0 → codemble-0.6.2}/docs/plans/README.md +0 -0
  96. {codemble-0.6.0 → codemble-0.6.2}/docs/plans/phase-1.md +0 -0
  97. {codemble-0.6.0 → codemble-0.6.2}/docs/releases/checklist.md +0 -0
  98. {codemble-0.6.0 → codemble-0.6.2}/docs/releases/v0.1.0.md +0 -0
  99. {codemble-0.6.0 → codemble-0.6.2}/docs/releases/v0.2.0.md +0 -0
  100. {codemble-0.6.0 → codemble-0.6.2}/docs/releases/v0.4.0.md +0 -0
  101. {codemble-0.6.0 → codemble-0.6.2}/docs/releases/v0.5.0.md +0 -0
  102. {codemble-0.6.0 → codemble-0.6.2}/docs/releases/v0.5.1.md +0 -0
  103. {codemble-0.6.0 → codemble-0.6.2}/docs/releases/v0.5.2.md +0 -0
  104. {codemble-0.6.0 → codemble-0.6.2}/docs/releases/v0.5.3.md +0 -0
  105. {codemble-0.6.0 → codemble-0.6.2}/docs/research/2026-07-20-opensource-graph-architecture-inspiration.md +0 -0
  106. {codemble-0.6.0 → codemble-0.6.2}/docs/research/README.md +0 -0
  107. {codemble-0.6.0 → codemble-0.6.2}/docs/superpowers/plans/2026-07-19-galaxy-ux-phase-a.md +0 -0
  108. {codemble-0.6.0 → codemble-0.6.2}/docs/superpowers/plans/2026-07-19-galaxy-ux-phase-b.md +0 -0
  109. {codemble-0.6.0 → codemble-0.6.2}/docs/superpowers/plans/2026-07-19-galaxy-ux-phase-c.md +0 -0
  110. {codemble-0.6.0 → codemble-0.6.2}/docs/superpowers/plans/2026-07-19-galaxy-ux-shared-contract.md +0 -0
  111. {codemble-0.6.0 → codemble-0.6.2}/docs/superpowers/specs/2026-07-19-galaxy-ux-overhaul-design.md +0 -0
  112. {codemble-0.6.0 → codemble-0.6.2}/docs/superpowers/specs/2026-07-21-navigation-design-clarity-design.md +0 -0
  113. {codemble-0.6.0 → codemble-0.6.2}/docs-site/.gitignore +0 -0
  114. {codemble-0.6.0 → codemble-0.6.2}/docs-site/astro.config.mjs +0 -0
  115. {codemble-0.6.0 → codemble-0.6.2}/docs-site/design.md +0 -0
  116. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/favicon-16.png +0 -0
  117. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/favicon-32.png +0 -0
  118. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/icon-180.png +0 -0
  119. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/icon-192.png +0 -0
  120. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/icon-512.png +0 -0
  121. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/icon.svg +0 -0
  122. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/icons/asterism.svg +0 -0
  123. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/icons/install.svg +0 -0
  124. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/mark-animated.svg +0 -0
  125. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/mark.svg +0 -0
  126. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/plates/hero-chart.svg +0 -0
  127. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/plates/hero-field.svg +0 -0
  128. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/plates/hero-gold.svg +0 -0
  129. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/plates/kasumi-rule.svg +0 -0
  130. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/plates/plate-galaxy.svg +0 -0
  131. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/plates/plate-study.svg +0 -0
  132. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/plates/plate-system.svg +0 -0
  133. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/brand/plates/seal.svg +0 -0
  134. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/favicon.svg +0 -0
  135. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/shots/easy-mode.png +0 -0
  136. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/shots/galaxy-lit.png +0 -0
  137. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/shots/galaxy.png +0 -0
  138. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/shots/loading.png +0 -0
  139. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/shots/map-architecture.png +0 -0
  140. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/shots/map-workflow.png +0 -0
  141. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/shots/study-panel.png +0 -0
  142. {codemble-0.6.0 → codemble-0.6.2}/docs-site/public/shots/system.png +0 -0
  143. {codemble-0.6.0 → codemble-0.6.2}/docs-site/scripts/build-plates.mjs +0 -0
  144. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/assets/codemble-mark-dark.svg +0 -0
  145. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/assets/codemble-mark-light.svg +0 -0
  146. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/components/Search.astro +0 -0
  147. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/components/Tatebanko.astro +0 -0
  148. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/architecture.md +0 -0
  149. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/build-from-source.md +0 -0
  150. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/checks-and-lighting.md +0 -0
  151. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/contributing.md +0 -0
  152. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/correctness.md +0 -0
  153. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/early-testing.md +0 -0
  154. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/installation.md +0 -0
  155. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/introduction.md +0 -0
  156. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m1-parser.md +0 -0
  157. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m10-polyglot-release.md +0 -0
  158. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m12-galaxy-look.md +0 -0
  159. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m13-scale.md +0 -0
  160. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m2-galaxy.md +0 -0
  161. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m3-study.md +0 -0
  162. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m4-lens.md +0 -0
  163. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m5-checks.md +0 -0
  164. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m6-release.md +0 -0
  165. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m8-typescript.md +0 -0
  166. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/progress/m9-typescript-lens.md +0 -0
  167. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/quickstart.md +0 -0
  168. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/roadmap.md +0 -0
  169. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content/docs/study-panel.md +0 -0
  170. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/content.config.ts +0 -0
  171. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/pages/index.astro +0 -0
  172. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/styles/custom.css +0 -0
  173. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/styles/landing.css +0 -0
  174. {codemble-0.6.0 → codemble-0.6.2}/docs-site/src/styles/tokens.css +0 -0
  175. {codemble-0.6.0 → codemble-0.6.2}/scripts/dev.sh +0 -0
  176. {codemble-0.6.0 → codemble-0.6.2}/scripts/record_demo.sh +0 -0
  177. {codemble-0.6.0 → codemble-0.6.2}/tests/conftest.py +0 -0
  178. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/check_suites.json +0 -0
  179. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/concepts_sample.py +0 -0
  180. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/impact/alpha.py +0 -0
  181. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/impact/beta.py +0 -0
  182. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/impact/gamma.py +0 -0
  183. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/impact/helpers.py +0 -0
  184. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/impact/noisy.py +0 -0
  185. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/polyglot/python_worker.py +0 -0
  186. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/polyglot/src/broken.ts +0 -0
  187. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/polyglot/src/legacy.js +0 -0
  188. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/polyglot/src/local.js +0 -0
  189. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/polyglot/src/main.ts +0 -0
  190. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/polyglot/src/reexport.ts +0 -0
  191. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/polyglot/src/util.ts +0 -0
  192. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/polyglot/src/widget.tsx +0 -0
  193. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/repeated_calls.py +0 -0
  194. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/.gitignore +0 -0
  195. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/ambiguous.py +0 -0
  196. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/api.py +0 -0
  197. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/app.py +0 -0
  198. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/broken.py +0 -0
  199. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/cli.py +0 -0
  200. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/pkg/__init__.py +0 -0
  201. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/pkg/helpers.py +0 -0
  202. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/pkg/service.py +0 -0
  203. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/pkg/util.py +0 -0
  204. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/runner/__main__.py +0 -0
  205. {codemble-0.6.0 → codemble-0.6.2}/tests/fixtures/sampleproj/shared.py +0 -0
  206. {codemble-0.6.0 → codemble-0.6.2}/tests/test_checks.py +0 -0
  207. {codemble-0.6.0 → codemble-0.6.2}/tests/test_dependency_compatibility.py +0 -0
  208. {codemble-0.6.0 → codemble-0.6.2}/tests/test_graph_finalization.py +0 -0
  209. {codemble-0.6.0 → codemble-0.6.2}/tests/test_mapview.py +0 -0
  210. {codemble-0.6.0 → codemble-0.6.2}/tests/test_parse_job.py +0 -0
  211. {codemble-0.6.0 → codemble-0.6.2}/tests/test_parse_progress.py +0 -0
  212. {codemble-0.6.0 → codemble-0.6.2}/tests/test_progress.py +0 -0
  213. {codemble-0.6.0 → codemble-0.6.2}/tests/test_project_activation.py +0 -0
  214. {codemble-0.6.0 → codemble-0.6.2}/tests/test_project_parser.py +0 -0
  215. {codemble-0.6.0 → codemble-0.6.2}/tests/test_project_selection.py +0 -0
  216. {codemble-0.6.0 → codemble-0.6.2}/tests/test_providers.py +0 -0
  217. {codemble-0.6.0 → codemble-0.6.2}/tests/test_python_ast.py +0 -0
  218. {codemble-0.6.0 → codemble-0.6.2}/tests/test_server.py +0 -0
  219. {codemble-0.6.0 → codemble-0.6.2}/tests/test_smoke.py +0 -0
  220. {codemble-0.6.0 → codemble-0.6.2}/tests/test_structural.py +0 -0
  221. {codemble-0.6.0 → codemble-0.6.2}/tests/test_study.py +0 -0
  222. {codemble-0.6.0 → codemble-0.6.2}/tests/test_typescript_tree_sitter.py +0 -0
  223. {codemble-0.6.0 → codemble-0.6.2}/web/README.md +0 -0
  224. {codemble-0.6.0 → codemble-0.6.2}/web/index.html +0 -0
  225. {codemble-0.6.0 → codemble-0.6.2}/web/scripts/benchmark_learner_projection.mjs +0 -0
  226. {codemble-0.6.0 → codemble-0.6.2}/web/scripts/check_graph_data.mjs +0 -0
  227. {codemble-0.6.0 → codemble-0.6.2}/web/scripts/check_learner_projection.mjs +0 -0
  228. {codemble-0.6.0 → codemble-0.6.2}/web/scripts/check_learner_session.mjs +0 -0
  229. {codemble-0.6.0 → codemble-0.6.2}/web/scripts/check_name_atlas.mjs +0 -0
  230. {codemble-0.6.0 → codemble-0.6.2}/web/scripts/check_project_mapping.mjs +0 -0
  231. {codemble-0.6.0 → codemble-0.6.2}/web/scripts/record_demo.mjs +0 -0
  232. {codemble-0.6.0 → codemble-0.6.2}/web/src/GuidanceLayer.jsx +0 -0
  233. {codemble-0.6.0 → codemble-0.6.2}/web/src/StudyPanel.jsx +0 -0
  234. {codemble-0.6.0 → codemble-0.6.2}/web/src/galaxyEffects.js +0 -0
  235. {codemble-0.6.0 → codemble-0.6.2}/web/src/galaxyMaterials.js +0 -0
  236. {codemble-0.6.0 → codemble-0.6.2}/web/src/graphData.js +0 -0
  237. {codemble-0.6.0 → codemble-0.6.2}/web/src/learnerProjection.js +0 -0
  238. {codemble-0.6.0 → codemble-0.6.2}/web/src/learnerSession.js +0 -0
  239. {codemble-0.6.0 → codemble-0.6.2}/web/src/main.jsx +0 -0
  240. {codemble-0.6.0 → codemble-0.6.2}/web/src/nameAtlas.js +0 -0
  241. {codemble-0.6.0 → codemble-0.6.2}/web/src/projectMapping.js +0 -0
  242. {codemble-0.6.0 → codemble-0.6.2}/web/src/tokens.css +0 -0
  243. {codemble-0.6.0 → codemble-0.6.2}/web/vite.config.js +0 -0
@@ -5,6 +5,34 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning:
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.6.2] - 2026-07-21
9
+
10
+ ### Fixed
11
+ - **The first-run audience question is visible on a fresh narrow window.**
12
+ v0.6.1 moved the audience control into the compact Menu, but its native modal
13
+ stayed inside that closed disclosure. The browser opened an invisible modal
14
+ backdrop that blocked the page. The gate now portals directly to the document
15
+ top layer while the post-choice Easy/Expert toggle remains in the Menu.
16
+
17
+ ## [0.6.1] - 2026-07-21
18
+
19
+ ### Fixed
20
+ - **The full learning loop now fits a 320 px window.** A compact Menu replaces
21
+ the crowded action rail, the architecture Map waits for real layout
22
+ dimensions before fitting, guidance gets its own row instead of covering Map
23
+ controls, and Study becomes a full-stage reading sheet. The header, canvas,
24
+ guidance, and local-only status remain visible without horizontal overflow.
25
+ - **Modules and Find work from the Star chart.** Both global commands now render
26
+ their surface in chart mode instead of accepting a click into hidden state
27
+ that only appeared after returning to the galaxy.
28
+ - **First-run guidance no longer competes with Home calibration.** After an
29
+ audience is chosen, a required Home choice finishes before the three-step
30
+ coach opens, so there is one decision in the foreground at a time.
31
+ - **Canvas clicks no longer corrupt OrbitControls pointer state.** Codemble's
32
+ parser-owned node layout is now explicitly non-draggable, preventing the 3D
33
+ dependency's drag-end bridge from injecting a synthetic touch release into a
34
+ mouse release. A stale-pointer guard and focused contract pin the fallback.
35
+
8
36
  ## [0.6.0] - 2026-07-21
9
37
 
10
38
  ### Added
@@ -168,7 +168,19 @@ Polish, then the coordinated launch (Show HN / X; lit-galaxy GIF as hero).
168
168
  ## Current State **[AGENT-MAINTAINED]**
169
169
 
170
170
  **Current milestone: Phase 1 tester evidence** · Last updated: 2026-07-21 ·
171
- Session note: the v0.6.0 architecture-depth pass is complete in five
171
+ Session note: v0.6.2 is the immediate installed-artifact hotfix for v0.6.1:
172
+ the first-run audience modal now portals to the document top layer, so the
173
+ closed compact Menu cannot hide the dialog while its modal backdrop blocks a
174
+ fresh narrow window. The public PyPI smoke caught the containment defect after
175
+ v0.6.1 publication; v0.6.2 supersedes it rather than pretending an immutable
176
+ artifact can be replaced. v0.6.1 closes the four verified user-flow gaps from the
177
+ 2026-07-21 usability audit: the 320 px shell reserves a usable map/study stage,
178
+ Modules and Find render from the Star chart, required Home calibration finishes
179
+ before coach marks begin, and parser-owned 3D nodes no longer install drag
180
+ controls that can corrupt OrbitControls pointer state. The release is verified
181
+ against the real bundled app at desktop and 320 px widths; the milestone does
182
+ not advance because issue #13 still requires human tester evidence. The v0.6.0
183
+ architecture-depth pass is complete in five
172
184
  behavior-preserving waves: project selection owns the home-jailed filesystem
173
185
  policy; project activation atomically owns parse-to-live binding and graph/map
174
186
  caches; project mapping owns picker attempts, polling, retry, outage, stale
@@ -534,6 +546,8 @@ shows lower repeated-commit work without changing derived values.
534
546
  | 2026-07-21 | Architecture boxes are named by the tail of their file path (`short_label`, map schema 3); `label` keeps the full identifier for title and aria | A box is a fixed width, so its text always truncates on a real project — and truncating a dotted region id rendered `codemble.server.app` and `codemble.server.runtime` as the same glyphs. Identical text for different modules is worse than no label, and it is exactly the kind of wrong a learner cannot detect. The path tail also survives the `__init__.py` collision a basename alone cannot |
535
547
  | 2026-07-21 | The Map gains zoom, Fit, and drag-to-pan; panning rides the container's own scroll and zoom only scales the rendered size | The 2D counterpart of bounded orbit: a 960x2640 diagram in a plain scroll box showed four of nine layers and no way to see the whole shape. Scroll-based panning keeps native scrollbars, keyboard scrolling and screen-reader behaviour intact, and because every coordinate inside the SVG stays backend-computed, React remains a pure renderer of graph-owned geometry. It opens at true size rather than auto-fitting: fitting on mount measured the scroller before layout settled and landed on a scale that was neither fitted nor honest |
536
548
  | 2026-07-21 | v0.6.0 deepens five private boundaries without changing the HTTP, graph, check, persistence, or learner-visible contracts: Project Selection, Project Activation, Project Mapping Run, Name Atlas, and Learner Projection | Approved by UD as five behavior-preserving waves in one release PR. The deletion test now holds at each seam, stale activation and mapping responses lose atomically, and dependency-scoped learner projections measured ~0.331 ms → ~0.001 ms per hover commit on a synthetic 1,000-node project while preserving derived outputs |
549
+ | 2026-07-21 | v0.6.1 treats Modules and Find as global surfaces, sequences first-run decisions as audience → required Home → coach, and makes the 3D parser-owned layout explicitly non-draggable | Approved by UD as implementation of every verified user-flow audit finding. Global commands must never accept hidden state, onboarding must expose one foreground decision at a time, and learners orbit the immutable graph rather than editing its coordinates. The compact shell is a structural breakpoint of the existing Formal Edo interface, not a new visual system |
550
+ | 2026-07-21 | First-run audience modal portals to `document.body`; the persistent Easy/Expert toggle remains in responsive header chrome | A native modal inside the closed compact Menu entered the top layer but inherited `display:none` from its ancestor, leaving an invisible backdrop that blocked fresh mobile runs. Modal ownership is a document boundary, not header layout. Caught only by the clean public v0.6.1 installed-artifact smoke; PyPI immutability requires v0.6.2 rather than replacing 0.6.1 |
537
551
 
538
552
  ## Non-Goals — do NOT build (point here when asked)
539
553
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codemble
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: A learning game that turns the code AI wrote for you into a galaxy you light up by understanding it.
5
5
  Project-URL: Homepage, https://udhawan97.github.io/Codemble/
6
6
  Project-URL: Repository, https://github.com/udhawan97/Codemble
@@ -1,4 +1,4 @@
1
1
  """Codemble — a learning game that turns the code AI wrote for you into a galaxy
2
2
  you light up by understanding it. See CLAUDE.md for the agent brief and roadmap."""
3
3
 
4
- __version__ = "0.6.0"
4
+ __version__ = "0.6.2"
@@ -0,0 +1 @@
1
+ @font-face{font-family:Zen Kaku Gothic New;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/zen-kaku-gothic-new-latin-400-normal-BEdayliK.woff2)format("woff2"),url(/assets/zen-kaku-gothic-new-latin-400-normal-CPSmNJAU.woff)format("woff")}@font-face{font-family:Shippori Mincho;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/shippori-mincho-latin-500-normal-XI1O8euf.woff2)format("woff2"),url(/assets/shippori-mincho-latin-500-normal-C-QwvIb3.woff)format("woff")}@font-face{font-family:Shippori Mincho;font-style:normal;font-display:swap;font-weight:700;src:url(/assets/shippori-mincho-latin-700-normal-DHcmzUO5.woff2)format("woff2"),url(/assets/shippori-mincho-latin-700-normal-CkoCYOiI.woff)format("woff")}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff)format("woff")}@font-face{font-family:JetBrains Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2)format("woff2"),url(/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff)format("woff")}:root{--cm-font-display:"Shippori Mincho", "Hiragino Mincho ProN", "Yu Mincho", serif;--cm-font-body:"Zen Kaku Gothic New", "Hiragino Sans", system-ui, sans-serif;--cm-font-mono:"JetBrains Mono", ui-monospace, monospace;--cm-text-xs:.75rem;--cm-text-sm:.875rem;--cm-text-base:1rem;--cm-text-lg:clamp(1.0625rem, .2vw + 1rem, 1.1875rem);--cm-text-xl:clamp(1.25rem, .5vw + 1.1rem, 1.5rem);--cm-text-2xl:clamp(1.5rem, 1vw + 1.25rem, 2rem);--cm-text-3xl:clamp(1.75rem, 2vw + 1.25rem, 3rem);--cm-text-display:clamp(2.25rem, 4.4vw + .9rem, 4.75rem);--cm-space-2xs:.25rem;--cm-space-xs:.5rem;--cm-space-sm:.75rem;--cm-space-md:1rem;--cm-space-lg:2rem;--cm-space-xl:4rem;--cm-space-2xl:6rem;--cm-space-3xl:9rem;--cm-radius:3px;--cm-radius-lg:6px;--cm-rule:1px;--cm-ease:cubic-bezier(.16, .7, .3, 1);--cm-dur-quick:.16s;--cm-dur-reveal:.42s;--cm-dur-slow:.9s;--cm-z-canvas:0;--cm-z-content:1;--cm-z-rail:40;--cm-z-nav:50}:root[data-theme=dark],:root{--cm-ground:#070b1c;--cm-ground-2:#101a3e;--cm-ground-3:#1a2750;--cm-hairline:#24325c;--cm-hairline-soft:#17203f;--cm-ink:#eef2fa;--cm-ink-2:#9aa8c4;--cm-ink-3:#7d8aa8;--cm-star:#e89b2e;--cm-star-high:#f4c46a;--cm-star-low:#3a2a0c;--cm-star-tint:#e89b2e24;--cm-orbit:#82abec;--cm-orbit-fill:#3f6ac0;--cm-orbit-deep:#2b4d96;--cm-orbit-low:#14264a;--cm-on-fill:#f7faff;--cm-sky-far:#070b1c;--cm-sky-near:#16224a}:root[data-theme=light]{--cm-ground:#faf7f0;--cm-ground-2:#fff;--cm-ground-3:#f2eee4;--cm-hairline:#e6e2d6;--cm-hairline-soft:#efece3;--cm-ink:#101a3e;--cm-ink-2:#3c4a74;--cm-ink-3:#5c688c;--cm-star:#7d4a06;--cm-star-high:#a86408;--cm-star-low:#fff3d6;--cm-star-tint:#7d4a061a;--cm-orbit:#2b4d96;--cm-orbit-fill:#2b4d96;--cm-orbit-deep:#1e3a6e;--cm-orbit-low:#e3ecfb;--cm-on-fill:#faf7f0;--cm-sky-far:#e9edf7;--cm-sky-near:#fff}:root{--cm-route-possible:color-mix(in srgb, var(--cm-ink-2) 30%, var(--cm-ink-3));--cm-node-unlit:color-mix(in srgb, var(--cm-ink-3) 78%, var(--cm-ground));--cm-neb-python:#599079;--cm-neb-js:#8b7ea9;--cm-neb-ts:#568baa;--cm-star-halo:#f2efe9;--cm-label-plate:#090e1cd1;--cm-label-ink:#d6dbe7;--cm-sidebar-width:min(19rem, 82vw);--cm-scrim:color-mix(in srgb, var(--cm-ground) 82%, transparent);--cm-error:oklch(72% .16 28);--cm-space-2xs:.125rem;--cm-space-2xl:6rem;--cm-radius:.25rem;--cm-text-xs:.75rem;--cm-text-sm:.875rem;--cm-text-base:1rem;--cm-text-lg:1.25rem;--cm-text-display:clamp(1.75rem, 3vw + 1rem, 3.25rem);--cm-z-base:1;--cm-z-raised:10;--cm-z-sticky:200;--cm-z-panel:400}*{box-sizing:border-box}html,body,#root{width:100%;min-height:100%;margin:0;overflow-x:clip}body{background:var(--cm-ground);color:var(--cm-ink);font-family:var(--cm-font-body);font-size:var(--cm-text-base);line-height:1.55}button,output{font:inherit}button:focus-visible,[href]:focus-visible,[tabindex]:focus-visible,input:focus-visible{outline:2px solid var(--cm-orbit);outline-offset:3px}.app-shell{background:var(--cm-ground);width:100%;height:100dvh;min-height:100dvh;color:var(--cm-ink);grid-template-rows:auto minmax(0,1fr) auto auto;grid-template-columns:minmax(0,1fr);display:grid;position:relative;overflow:hidden}.instrument-rail{z-index:var(--cm-z-sticky);align-items:center;gap:var(--cm-space-sm) var(--cm-space-md);min-width:0;max-width:100%;padding:var(--cm-space-sm) max(var(--cm-space-md), env(safe-area-inset-right)) var(--cm-space-sm) max(var(--cm-space-md), env(safe-area-inset-left));border-block-end:1px solid var(--cm-hairline);background:var(--cm-ground);grid-row:1;grid-template-columns:minmax(0,1fr) auto;display:grid;position:relative}.brand-lockup{align-items:center;gap:var(--cm-space-sm);min-width:0;display:flex}.brand-lockup div{min-width:0;display:grid}.brand-lockup strong{font-family:var(--cm-font-display);letter-spacing:-.02em;font-weight:700}.brand-lockup span:not(.brand-mark),.home-readout,.location{color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.brand-mark{width:var(--cm-space-md);height:var(--cm-space-md);border:1px solid var(--cm-ink-2);background:var(--cm-ink);border-radius:50%}.location{grid-area:2/1/auto/-1;margin:0}.rail-overflow{grid-area:1/2;justify-self:end}.mobile-menu-trigger{min-width:44px;min-height:44px;padding-inline:var(--cm-space-md);border:1px solid var(--cm-orbit);border-radius:var(--cm-radius);color:var(--cm-orbit);cursor:pointer;place-items:center;font-weight:600;display:grid}.rail-overflow__panel{z-index:var(--cm-z-panel);gap:var(--cm-space-md);max-height:calc(100dvh - 5rem);padding:var(--cm-space-md);border-block:1px solid var(--cm-hairline);background:var(--cm-ground-2);display:none;position:absolute;inset-block-start:100%;inset-inline:0;overflow-y:auto;box-shadow:0 1rem 2.5rem #00000061}.rail-overflow[data-open] .rail-overflow__panel{display:grid}.instrument-rail:has(.rail-overflow[data-open]){z-index:var(--cm-z-panel)}.rail-overflow__panel .rail-actions,.rail-overflow__panel .rail-controls{grid-area:auto;justify-content:start}.rail-action{min-height:44px;padding-inline:var(--cm-space-md);border:1px solid var(--cm-orbit);border-radius:var(--cm-radius);background:var(--cm-ground);color:var(--cm-orbit);cursor:pointer;white-space:nowrap;transition:background-color var(--cm-dur-quick) var(--cm-ease), color var(--cm-dur-quick) var(--cm-ease), transform .1s var(--cm-ease);font-weight:600}@media (hover:hover) and (pointer:fine){.rail-action:hover{background:var(--cm-orbit-low)}}.rail-action:active{transform:translateY(1px)}.rail-action:disabled,.rail-action[aria-disabled=true]{opacity:.5;cursor:not-allowed}.rail-action[data-state=loading]{color:var(--cm-ink-2)}.rail-action[data-state=error]{border-color:var(--cm-error)}.rail-action[data-state=success]{border-color:var(--cm-star);color:var(--cm-star)}.rail-actions{justify-content:end;align-items:center;gap:var(--cm-space-sm);flex-wrap:wrap;grid-area:2/1/auto/-1;min-width:0;display:flex}.rail-controls{align-items:center;gap:var(--cm-space-md);flex-wrap:wrap;grid-area:4/1/auto/-1;min-width:0;display:flex}.switch-project{gap:var(--cm-space-xs);padding:var(--cm-space-sm);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);background:var(--cm-ground-2);display:grid}.switch-project p{max-width:26ch;color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);margin:0}.switch-project__error{color:var(--cm-error)!important}.switch-project>div{gap:var(--cm-space-xs);display:flex}.language-focus{align-items:center;gap:var(--cm-space-sm);min-width:0;color:var(--cm-ink-3);scrollbar-width:none;display:flex;overflow-x:auto}.language-focus::-webkit-scrollbar{display:none}.language-focus__label{font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);text-transform:uppercase;letter-spacing:.08em;flex:none}.language-focus>div{border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);min-width:max-content;display:flex}.language-focus button{justify-content:center;align-items:center;gap:var(--cm-space-xs);min-width:44px;min-height:44px;padding-inline:var(--cm-space-sm);border:0;border-inline-end:1px solid var(--cm-hairline);color:var(--cm-ink-2);cursor:pointer;font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);white-space:nowrap;background:0 0;display:inline-flex}.language-focus button:last-child{border-inline-end:0}.language-focus button[aria-pressed=true]{background:var(--cm-orbit-low);color:var(--cm-orbit)}.language-focus button small{color:var(--cm-ink-3);font-size:inherit;font-variant-numeric:tabular-nums}@media (hover:hover) and (pointer:fine){.language-focus button:hover{background:var(--cm-ground-2);color:var(--cm-ink)}.language-focus button[aria-pressed=true]:hover{background:var(--cm-orbit-low);color:var(--cm-orbit)}}.mode-toggle{align-items:center;gap:var(--cm-space-sm);border:0;grid-area:4/1/auto/-1;min-width:0;margin:0;padding:0;display:flex}.mode-toggle__label{color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);text-transform:uppercase;letter-spacing:.08em;flex:none}.mode-toggle__options{border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);min-width:max-content;display:flex}.mode-toggle__options label{align-items:center;gap:var(--cm-space-2xs);min-width:44px;min-height:44px;padding-inline:var(--cm-space-sm);border-inline-end:1px solid var(--cm-hairline);color:var(--cm-ink-2);cursor:pointer;font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);display:inline-flex}.mode-toggle__options label:last-child{border-inline-end:0}.mode-toggle__options label:has(input:checked){background:var(--cm-orbit-low);color:var(--cm-orbit)}.mode-toggle__options input{width:1rem;height:1rem;accent-color:var(--cm-orbit);margin:0}@media (hover:hover) and (pointer:fine){.mode-toggle__options label:hover{background:var(--cm-ground-2);color:var(--cm-ink)}.mode-toggle__options label:has(input:checked):hover{background:var(--cm-orbit-low);color:var(--cm-orbit)}}.mode-gate{width:min(26rem, calc(100% - var(--cm-space-xl)));max-height:min(86%,30rem);padding:var(--cm-space-lg);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);background:var(--cm-ground-2);color:var(--cm-ink);animation:panel-enter var(--cm-dur-reveal) var(--cm-ease) both;margin:auto;overflow:auto}.mode-gate::backdrop{background:var(--cm-scrim)}.mode-gate h1{overflow-wrap:anywhere;font-family:var(--cm-font-display);font-size:var(--cm-text-xl);margin:0;font-style:normal;line-height:1.15}.mode-gate p{max-width:42ch;margin:var(--cm-space-sm) 0 0;color:var(--cm-ink-2)}.mode-gate__options{border-block-start:1px solid var(--cm-hairline);margin-block-start:var(--cm-space-lg);display:grid}.mode-gate__options button{min-height:52px;padding:var(--cm-space-sm) 0;border:0;border-block-end:1px solid var(--cm-hairline);color:var(--cm-ink);cursor:pointer;font:inherit;text-align:start;background:0 0;font-weight:600}.mode-gate__options button:last-child{border-block-end:0}@media (hover:hover) and (pointer:fine){.mode-gate__options button:hover{color:var(--cm-orbit)}}.map-stage{background:var(--cm-ground);grid-row:2;min-width:0;max-width:100%;min-height:0;position:relative;overflow:clip}.chart-stage{background:var(--cm-ground);grid-row:2;min-width:0;min-height:0;position:relative;overflow:hidden}.chart-stage .star-chart-screen{height:100%}.galaxy-frame,.galaxy-canvas{z-index:var(--cm-z-base);position:absolute;inset:0}.galaxy-frame{overflow:hidden}.galaxy-canvas canvas{display:block}.keyboard-focus{max-width:min(34rem, calc(100% - var(--cm-space-lg)));padding:var(--cm-space-sm) var(--cm-space-md);border-inline-start:2px solid var(--cm-orbit);background:var(--cm-ground-2);color:var(--cm-ink);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);position:absolute;inset-block-end:var(--cm-space-md);inset-inline-start:var(--cm-space-md)}.orientation-bar{z-index:var(--cm-z-raised);gap:var(--cm-space-sm);color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);pointer-events:none;flex-wrap:wrap;margin:0;display:flex;position:absolute;inset-block-start:var(--cm-space-md);inset-inline-start:max(var(--cm-space-md), env(safe-area-inset-left))}.orientation-bar>*+:before{content:"· ";color:var(--cm-hairline)}.orientation-bar__charted{color:var(--cm-ink-2)}.index-sidebar{z-index:var(--cm-z-panel);width:var(--cm-sidebar-width);border-inline-end:1px solid var(--cm-hairline);background:var(--cm-ground-2);flex-direction:column;display:flex;position:absolute;inset-block:0;inset-inline-start:0}@media (width>=60rem){:is(.map-stage:has(.index-sidebar) .galaxy-frame,.map-stage:has(.index-sidebar) .map-view){inset-inline-start:var(--cm-sidebar-width)}:is(.map-stage:has(.index-sidebar) .orientation-bar,.map-stage:has(.index-sidebar) .orientation-copy){inset-inline-start:calc(var(--cm-sidebar-width) + var(--cm-space-md))}}.index-sidebar>header{justify-content:space-between;align-items:center;gap:var(--cm-space-sm);padding:var(--cm-space-sm) var(--cm-space-md);border-block-end:1px solid var(--cm-hairline);display:flex}.index-sidebar h2{color:var(--cm-ink);font-size:var(--cm-text-sm);letter-spacing:.08em;text-transform:uppercase;margin:0}.index-sidebar>header button{border-radius:var(--cm-radius);min-width:32px;min-height:32px;color:var(--cm-ink-2);font-size:var(--cm-text-lg);cursor:pointer;background:0 0;border:1px solid #0000;line-height:1}.index-sidebar>header button:hover,.index-sidebar>header button:focus-visible{border-color:var(--cm-orbit);color:var(--cm-ink)}.index-sidebar__scroll{flex:1;padding-block-end:var(--cm-space-lg);overflow-y:auto}.index-sidebar section{padding-block-start:var(--cm-space-sm)}.index-sidebar h3{padding:var(--cm-space-2xs) var(--cm-space-md);color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);text-overflow:ellipsis;white-space:nowrap;margin:0;font-weight:400;overflow:hidden}.index-sidebar ul{margin:0;padding:0;list-style:none}.index-sidebar li button{align-items:baseline;gap:var(--cm-space-sm);width:100%;min-height:32px;padding:var(--cm-space-2xs) var(--cm-space-md);color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);text-align:start;cursor:pointer;background:0 0;border:0;border-inline-start:2px solid #0000;display:flex}.index-sidebar li button span{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.index-sidebar li button:hover,.index-sidebar li button:focus-visible{border-inline-start-color:var(--cm-orbit);background:var(--cm-ground);color:var(--cm-ink)}.index-sidebar li button[aria-current=true]{border-inline-start-color:var(--cm-orbit);color:var(--cm-ink)}.index-sidebar li button[data-lit] span{color:var(--cm-star-high)}.index-sidebar li em{color:var(--cm-ink-3);font-size:var(--cm-text-xs);font-style:normal}.module-finder{border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);background:var(--cm-ground-2);width:min(34rem,92vw);max-height:70vh;color:var(--cm-ink);padding:0}.module-finder::backdrop{background:var(--cm-scrim)}.module-finder input{width:100%;padding:var(--cm-space-md);border:0;border-block-end:1px solid var(--cm-hairline);color:var(--cm-ink);font-family:var(--cm-font-mono);font-size:var(--cm-text-base);background:0 0}.module-finder input:focus-visible{outline:2px solid var(--cm-orbit);outline-offset:-2px}.module-finder ul{max-height:50vh;padding:var(--cm-space-2xs) 0;margin:0;list-style:none;overflow-y:auto}.module-finder li button{align-items:baseline;gap:var(--cm-space-sm);width:100%;min-height:36px;padding:var(--cm-space-2xs) var(--cm-space-md);color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);text-align:start;cursor:pointer;background:0 0;border:0;border-inline-start:2px solid #0000;display:flex}.module-finder li button[data-active]{border-inline-start-color:var(--cm-orbit);background:var(--cm-ground);color:var(--cm-ink)}.module-finder li strong{font-weight:400}.module-finder li small{color:var(--cm-ink-3);text-overflow:ellipsis;white-space:nowrap;flex:1;overflow:hidden}.module-finder li em{color:var(--cm-star-high);font-style:normal}.module-finder__empty{padding:var(--cm-space-md);color:var(--cm-ink-3);font-size:var(--cm-text-sm);margin:0}.rail-action kbd{color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);margin-inline-start:var(--cm-space-2xs)}.rail-action--toggle[aria-pressed=true]{border-color:var(--cm-orbit);color:var(--cm-orbit)}.orientation-copy{z-index:var(--cm-z-raised);max-width:min(28rem, calc(100% - var(--cm-space-lg)));pointer-events:none;position:absolute;inset-block-start:clamp(var(--cm-space-lg), 8vh, var(--cm-space-2xl));inset-inline-start:max(var(--cm-space-md), env(safe-area-inset-left))}.orientation-copy--system{inset-block-start:var(--cm-space-lg)}.orientation-copy h1,.study-preview h1,.load-state h1,.webgl-error h1{overflow-wrap:anywhere;min-width:0;font-family:var(--cm-font-display);font-size:var(--cm-text-display);letter-spacing:-.035em;margin:0;font-style:normal;font-weight:700;line-height:1.08}.orientation-copy p,.study-preview p{max-width:55ch;margin:var(--cm-space-sm) 0 0;color:var(--cm-ink-2)}.orientation-copy--inline{z-index:auto;pointer-events:auto;flex:none;max-block-size:45%;position:static;overflow-y:auto}.orientation-copy--inline h1{font-size:var(--cm-text-lg)}.orientation-copy--inline p{font-size:var(--cm-text-sm);margin-block-start:var(--cm-space-2xs)}.orientation-copy--inline .check-launch{margin-block-start:var(--cm-space-sm)}.check-launch,.check-primary,.check-close{border:1px solid var(--cm-orbit);border-radius:var(--cm-radius);background:var(--cm-ground);min-height:44px;color:var(--cm-orbit);cursor:pointer;transition:background-color var(--cm-dur-quick) var(--cm-ease), color var(--cm-dur-quick) var(--cm-ease), transform .1s var(--cm-ease);font-weight:600}.check-launch{padding-inline:var(--cm-space-md);pointer-events:auto;margin-block-start:var(--cm-space-md);position:relative}.check-primary{padding-inline:var(--cm-space-lg);justify-self:start}.check-close{padding-inline:var(--cm-space-md);border-color:var(--cm-hairline);color:var(--cm-ink-2)}@media (hover:hover) and (pointer:fine){.check-launch:hover,.check-primary:hover,.check-close:hover{background:var(--cm-orbit-low);color:var(--cm-ink)}}.check-launch:active,.check-primary:active,.check-close:active{transform:translateY(1px)}.check-primary:disabled{opacity:.45;cursor:not-allowed;transform:none}.legend-toggle{z-index:var(--cm-z-sticky);min-height:32px;padding:var(--cm-space-2xs) var(--cm-space-sm);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);background:var(--cm-ground-2);color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);cursor:pointer;position:absolute;inset-block-start:var(--cm-space-md);inset-inline-end:var(--cm-space-md)}.legend-toggle:hover,.legend-toggle:focus-visible{border-color:var(--cm-orbit);color:var(--cm-ink)}.legend-toggle[aria-expanded=true]{border-color:var(--cm-orbit);color:var(--cm-orbit)}.map-legend{z-index:var(--cm-z-raised);gap:var(--cm-space-2xs) var(--cm-space-md);max-height:min(60vh,30rem);padding:var(--cm-space-sm) var(--cm-space-md);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);background:var(--cm-ground-2);color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);grid-template-columns:repeat(2,auto);display:none;position:absolute;inset-block-start:calc(var(--cm-space-md) + 40px);inset-inline-end:var(--cm-space-md);overflow-y:auto}.map-legend span{align-items:center;gap:var(--cm-space-sm);white-space:nowrap;display:inline-flex}.legend-dot{width:var(--cm-space-sm);height:var(--cm-space-sm);border-radius:50%;display:inline-block}.legend-dot--dim{background:var(--cm-ink-3)}.legend-dot--lit{background:var(--cm-star-high)}.legend-dot--partial{background:var(--cm-route-possible)}.legend-route{width:var(--cm-space-md);border-block-start:1px solid var(--cm-ink-3)}.legend-route--possible{border-block-start-color:var(--cm-route-possible)}.partial-summary{border-inline-start:2px solid var(--cm-route-possible);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);padding-inline-start:var(--cm-space-sm);color:var(--cm-ink)!important}.entrypoint-picker{z-index:var(--cm-z-panel);inset-inline:max(var(--cm-space-md), env(safe-area-inset-left));width:min(36rem, calc(100% - var(--cm-space-xl)));max-height:min(76%,42rem);padding:var(--cm-space-lg);border-block:1px solid var(--cm-hairline);background:var(--cm-ground-2);box-shadow:0 0 0 100vmax var(--cm-ground);color:var(--cm-ink);animation:entrypoint-enter var(--cm-dur-reveal) var(--cm-ease) both;margin-inline:auto;position:absolute;inset-block-start:50%;overflow:auto;transform:translateY(-50%)}.entrypoint-picker>p:first-child{color:var(--cm-orbit);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);margin:0}.entrypoint-picker h1{margin:var(--cm-space-sm) 0 0;overflow-wrap:anywhere;font-family:var(--cm-font-display);font-size:var(--cm-text-xl);line-height:1.1}.entrypoint-picker>p:not(:first-child){margin:var(--cm-space-md) 0 0;color:var(--cm-ink-2)}.entrypoint-candidates{border-block-start:1px solid var(--cm-hairline);margin-block-start:var(--cm-space-lg)}.entrypoint-candidates button{gap:var(--cm-space-xs);width:100%;min-height:58px;padding:var(--cm-space-sm) 0;border:0;border-block-end:1px solid var(--cm-hairline);color:var(--cm-ink);cursor:pointer;text-align:start;background:0 0;display:grid}.entrypoint-candidates button span{overflow-wrap:anywhere;font-family:var(--cm-font-mono)}.entrypoint-candidates button small{color:var(--cm-ink-3);font-family:var(--cm-font-mono)}@media (hover:hover) and (pointer:fine){.entrypoint-candidates button:hover{color:var(--cm-orbit)}}.entrypoint-continue{min-height:44px;color:var(--cm-ink-2);cursor:pointer;text-underline-offset:3px;background:0 0;border:0;margin-block-start:var(--cm-space-lg);padding:0;text-decoration:underline}.entrypoint-error{color:var(--cm-error)!important}.illumination-pulse{z-index:var(--cm-z-raised);color:var(--cm-star);pointer-events:none;animation:illumination-pulse .42s var(--cm-ease) both;justify-items:center;display:grid;position:absolute;inset-block-start:50%;inset-inline-start:25%;transform:translate(-50%,-50%)}.illumination-pulse span{filter:drop-shadow(0 0 18px var(--cm-star));font-size:clamp(3rem,8vw,6rem);line-height:1}.illumination-pulse strong{color:var(--cm-ink);font-family:var(--cm-font-display)}.structural-summary p{max-width:62ch;margin:var(--cm-space-sm) 0 0;color:var(--cm-ink)}.mini-constellation{width:100%;max-width:22rem;height:auto;margin-block-start:var(--cm-space-md)}.mini-constellation line{stroke:var(--cm-hairline);stroke-width:1px}.mini-constellation circle{fill:var(--cm-ink-3)}.mini-constellation__self{fill:var(--cm-orbit)}.connections h3{margin:var(--cm-space-lg) 0 0;color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);text-transform:uppercase;letter-spacing:.08em;font-weight:500}.connection-list{margin:var(--cm-space-xs) 0 0;border-block-start:1px solid var(--cm-hairline);padding:0;list-style:none}.connection-list button{gap:var(--cm-space-2xs);width:100%;min-height:52px;padding:var(--cm-space-sm) 0;border:0;border-block-end:1px solid var(--cm-hairline);color:var(--cm-ink);cursor:pointer;text-align:start;background:0 0;display:grid}.connection-name{overflow-wrap:anywhere;font-family:var(--cm-font-mono);font-size:var(--cm-text-sm)}.connection-meta{color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs)}@media (hover:hover) and (pointer:fine){.connection-list button:hover .connection-name{color:var(--cm-orbit)}}.load-state .check-primary,.study-notice .check-primary{justify-self:start;margin-block-start:var(--cm-space-md)}.study-preview{z-index:var(--cm-z-panel);width:100%;min-width:0;max-width:100%;max-height:72%;padding:var(--cm-space-lg) max(var(--cm-space-md), env(safe-area-inset-right)) max(var(--cm-space-lg), env(safe-area-inset-bottom)) max(var(--cm-space-md), env(safe-area-inset-left));border-block-start:1px solid var(--cm-hairline);background:var(--cm-ground-2);color:var(--cm-ink);animation:panel-enter var(--cm-dur-reveal) var(--cm-ease) both;position:absolute;inset-block-end:0;inset-inline:0;overflow:auto}.check-panel{z-index:var(--cm-z-panel);width:100%;min-width:0;max-width:100%;max-height:76%;padding:var(--cm-space-lg) max(var(--cm-space-md), env(safe-area-inset-right)) max(var(--cm-space-lg), env(safe-area-inset-bottom)) max(var(--cm-space-md), env(safe-area-inset-left));border-block-start:1px solid var(--cm-hairline);background:var(--cm-ground-2);color:var(--cm-ink);animation:panel-enter var(--cm-dur-reveal) var(--cm-ease) both;position:absolute;inset-block-end:0;inset-inline:0;overflow:auto}.check-panel__header{justify-content:space-between;align-items:start;gap:var(--cm-space-md);border-block-end:1px solid var(--cm-hairline);padding-block-end:var(--cm-space-lg);display:flex}.check-panel__header p,.check-panel__header h1{margin:0}.check-panel__header p,.check-progress span{color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs)}.check-panel__header h1{overflow-wrap:anywhere;font-family:var(--cm-font-display);font-size:var(--cm-text-xl);margin-block-start:var(--cm-space-xs);line-height:1.1}.check-loading,.check-state,.check-complete,.active-check{margin-block-start:var(--cm-space-lg)}.check-loading,.check-state p,.check-complete p,.active-check fieldset>p{max-width:60ch;color:var(--cm-ink-2)}.check-state h2,.check-complete h2{font-family:var(--cm-font-display);font-size:var(--cm-text-lg);margin:0}.check-state p,.check-complete p{margin:var(--cm-space-sm) 0 0}.check-complete{gap:var(--cm-space-sm);display:grid}.check-complete__star{color:var(--cm-star);font-size:var(--cm-text-display);line-height:1}.check-progress{align-items:center;gap:var(--cm-space-md);grid-template-columns:auto minmax(5rem,1fr);margin-block-end:var(--cm-space-xl);display:grid}.check-progress progress{background:var(--cm-hairline);width:100%;height:2px;color:var(--cm-star);border:0}.check-progress progress::-webkit-progress-bar{background:var(--cm-hairline)}.check-progress progress::-webkit-progress-value{background:var(--cm-star)}.check-progress progress::-moz-progress-bar{background:var(--cm-star)}.active-check{gap:var(--cm-space-lg);display:grid}.active-check fieldset{border:0;min-width:0;margin:0;padding:0}.active-check legend{overflow-wrap:anywhere;max-width:28ch;font-family:var(--cm-font-display);font-size:var(--cm-text-xl);padding:0;font-weight:700;line-height:1.15}.active-check fieldset>p{margin:var(--cm-space-sm) 0 0}.check-options{border-block-start:1px solid var(--cm-hairline);margin-block-start:var(--cm-space-lg)}.check-options label{align-items:center;gap:var(--cm-space-md);min-height:52px;padding-block:var(--cm-space-sm);border-block-end:1px solid var(--cm-hairline);color:var(--cm-ink-2);cursor:pointer;grid-template-columns:auto minmax(0,1fr);display:grid}.check-options label:has(input:checked){color:var(--cm-ink)}.check-options input{width:1rem;height:1rem;accent-color:var(--cm-star);margin:0}.check-options span{overflow-wrap:anywhere;font-family:var(--cm-font-mono);font-size:var(--cm-text-sm)}.check-feedback{gap:var(--cm-space-xs);padding:var(--cm-space-md);border-inline-start:2px solid var(--cm-error);background:var(--cm-ground);color:var(--cm-ink-2);display:grid}.check-feedback strong{color:var(--cm-ink)}.check-feedback span{overflow-wrap:anywhere;font-family:var(--cm-font-mono);font-size:var(--cm-text-xs)}.check-affirmation{align-items:baseline;gap:var(--cm-space-xs);margin:0 0 var(--cm-space-lg);border-inline-start:2px solid var(--cm-star);color:var(--cm-star-high);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);padding-inline-start:var(--cm-space-sm);display:flex}.study-preview__path{font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);color:var(--cm-orbit)!important}.study-preview__header{display:block}.study-preview dl{gap:var(--cm-space-md);margin:var(--cm-space-lg) 0 0;grid-template-columns:repeat(2,minmax(0,1fr));display:grid}.study-preview dl div{border-block-start:1px solid var(--cm-hairline);padding-block-start:var(--cm-space-sm)}.study-preview dt{color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs)}.study-preview dd{margin:var(--cm-space-2xs) 0 0;font-variant-numeric:tabular-nums}.study-content{gap:var(--cm-space-xl);min-width:0;margin-block-start:var(--cm-space-xl);display:grid}.study-content>*{min-width:0}.study-section-heading{justify-content:space-between;align-items:center;gap:var(--cm-space-md);border-block-end:1px solid var(--cm-hairline);padding-block-end:var(--cm-space-sm);display:flex}.study-section-heading h2,.study-notice h2{overflow-wrap:anywhere;min-width:0;font-family:var(--cm-font-display);font-size:var(--cm-text-lg);margin:0;font-style:normal;line-height:1.15}.study-section-heading span{color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);white-space:nowrap}.source-code{width:100%;min-width:0;max-height:22rem;margin:var(--cm-space-md) 0 0;padding:var(--cm-space-sm) 0;border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);background:var(--cm-ground);color:var(--cm-ink);counter-reset:source-line;font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);tab-size:4;line-height:1.65;list-style:none;overflow:auto}.source-code li{min-width:max-content;padding-inline:var(--cm-space-sm) var(--cm-space-md);grid-template-columns:3.25rem minmax(0,1fr);display:grid}.source-code li:before{content:attr(data-line);color:var(--cm-ink-3);text-align:end;-webkit-user-select:none;user-select:none;padding-inline-end:var(--cm-space-md)}.source-code li:target{background:var(--cm-orbit-low)}.source-code code{font:inherit;white-space:pre}.grounded-explanation>p,.study-notice p,.study-loading,.evidence-list p{max-width:65ch;color:var(--cm-ink-2)}.grounded-explanation>p,.study-notice p,.study-loading{margin:var(--cm-space-md) 0 0}.grounded-explanation h3{margin:var(--cm-space-lg) 0 var(--cm-space-sm);font-family:var(--cm-font-display);font-size:var(--cm-text-base);font-style:normal}.source-citation{color:var(--cm-orbit);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);text-underline-offset:2px;text-decoration-thickness:1px}.source-citation:active{color:var(--cm-ink)}@media (hover:hover) and (pointer:fine){.source-citation:hover{color:var(--cm-ink)}}.source-citation--button{cursor:pointer;background:0 0;border:0;padding:0}.source-citation--button:disabled{color:var(--cm-ink-3);cursor:not-allowed}.evidence-list{gap:var(--cm-space-sm);margin:0;padding:0;list-style:none;display:grid}.evidence-list li,.study-notice{padding:var(--cm-space-md);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);background:var(--cm-ground)}.evidence-list p{margin:0 0 var(--cm-space-xs)}.evidence-list strong{overflow-wrap:anywhere;font-family:var(--cm-font-mono);font-size:var(--cm-text-sm);margin-block-end:var(--cm-space-xs);display:block}.lens-notes{margin-block-start:var(--cm-space-sm);display:grid}.lens-note{gap:var(--cm-space-sm);min-width:0;padding-block:var(--cm-space-md);border-block-end:1px solid var(--cm-hairline);display:grid}.lens-note h3{margin:0 0 var(--cm-space-xs);font-family:var(--cm-font-display);font-size:var(--cm-text-base);font-style:normal}.lens-note p{max-width:65ch;margin:0 0 var(--cm-space-sm);color:var(--cm-ink-2)}.lens-note code{min-width:0;padding:var(--cm-space-sm);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);background:var(--cm-ground);color:var(--cm-ink);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);white-space:pre;display:block;overflow-x:auto}.star-chart-screen{min-width:0;padding:var(--cm-space-lg) max(var(--cm-space-md), env(safe-area-inset-right)) var(--cm-space-xl) max(var(--cm-space-md), env(safe-area-inset-left));background:var(--cm-ground);overflow:auto}.star-chart-intro{max-width:72rem;margin-inline:auto;padding-block-end:var(--cm-space-xl);display:block}.star-chart-intro>p:first-child{margin:0 0 var(--cm-space-sm);color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs)}.star-chart-intro h1{overflow-wrap:anywhere;min-width:0;font-family:var(--cm-font-display);font-size:var(--cm-text-display);letter-spacing:-.035em;margin:0;font-style:normal;line-height:1.08}.star-chart-intro>p:not(:first-child){max-width:65ch;margin:var(--cm-space-md) 0 0;color:var(--cm-ink-2)}.star-chart-intro dl{gap:var(--cm-space-md);margin:var(--cm-space-xl) 0 0;padding-block:var(--cm-space-md);border-block:1px solid var(--cm-hairline);grid-template-columns:repeat(3,minmax(0,1fr));display:grid}.star-chart-intro dt,.concept-row dt{color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs)}.star-chart-intro dd{margin:var(--cm-space-xs) 0 0;font-family:var(--cm-font-display);font-size:var(--cm-text-lg);font-variant-numeric:tabular-nums}.concept-ledger{border-block-start:1px solid var(--cm-hairline);max-width:72rem;margin-inline:auto}.concept-row{align-items:center;gap:var(--cm-space-lg);min-width:0;padding-block:var(--cm-space-lg);border-block-end:1px solid var(--cm-hairline);grid-template-columns:minmax(10rem,.7fr) minmax(8rem,1.2fr) auto;display:grid}.concept-row h2{overflow-wrap:anywhere;min-width:0;font-family:var(--cm-font-display);font-size:var(--cm-text-lg);margin:0;font-style:normal}.concept-row>div:first-child>span{color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs)}.concept-meter{background:var(--cm-hairline);height:2px;overflow:hidden}.concept-meter span{background:var(--cm-star);height:100%;display:block}.concept-row dl{align-items:center;gap:var(--cm-space-lg);margin:0;display:flex}.concept-row dl div{min-width:5rem}.concept-row dd{margin:var(--cm-space-xs) 0 0;font-variant-numeric:tabular-nums}.status-line{z-index:var(--cm-z-sticky);justify-content:space-between;gap:var(--cm-space-2xs) var(--cm-space-md);min-width:0;max-width:100%;padding:var(--cm-space-sm) max(var(--cm-space-md), env(safe-area-inset-right)) max(var(--cm-space-sm), env(safe-area-inset-bottom)) max(var(--cm-space-md), env(safe-area-inset-left));border-block-start:1px solid var(--cm-hairline);background:var(--cm-ground);color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);font-variant-numeric:tabular-nums;flex-wrap:wrap;grid-row:4;display:flex;position:relative}.status-line span{white-space:normal}.status-line span:nth-child(2){display:none}.load-state,.webgl-error{align-content:center;gap:var(--cm-space-md);min-height:100dvh;padding:var(--cm-space-lg);background:var(--cm-ground);color:var(--cm-ink);display:grid}.load-state p,.webgl-error p{max-width:65ch;color:var(--cm-ink-2);margin:0}@keyframes panel-enter{0%{opacity:0;transform:translateY(var(--cm-space-md))}to{opacity:1;transform:translateY(0)}}@keyframes entrypoint-enter{0%{opacity:0;transform:translateY(calc(-50% + var(--cm-space-md)))}to{opacity:1;transform:translateY(-50%)}}@keyframes illumination-pulse{0%{opacity:0;transform:translate(-50%,-50%)scale(.75)}45%{opacity:1;transform:translate(-50%,-50%)scale(1.08)}to{opacity:0;transform:translate(-50%,-50%)scale(1)}}@media (width>=40rem){.instrument-rail{grid-template-columns:minmax(0,1fr) auto minmax(0,1fr)}.rail-overflow{display:contents}.mobile-menu-trigger{display:none}.rail-overflow__panel{display:contents;position:static}.location{text-align:center;grid-area:1/2}.rail-action,.home-readout{justify-self:end}.rail-actions{grid-area:1/3}.rail-controls{grid-row:2;justify-self:center}.status-line span{white-space:nowrap;display:inline}.lens-note{gap:var(--cm-space-lg);grid-template-columns:minmax(8rem,.35fr) minmax(0,1fr)}.study-preview{border-block-start:0;border-inline-start:1px solid var(--cm-hairline);width:min(48rem,60%);max-height:none;inset-block:0;inset-inline-start:auto}.check-panel{border-block-start:0;border-inline-start:1px solid var(--cm-hairline);width:min(42rem,56%);max-height:none;inset-block:0;inset-inline-start:auto}}@media (width<=39.999rem){.study-preview,.check-panel{border-block-start:0;max-height:none;inset:0}}@media (width<=48rem){.illumination-pulse{inset-block-start:35%;inset-inline-start:50%}.star-chart-intro dl{grid-template-columns:1fr}.concept-row{gap:var(--cm-space-md);grid-template-columns:1fr}.concept-row dl{justify-content:space-between}}@media (width>=60rem){.map-legend:not([hidden]){display:grid}.chart-stage:has(.index-sidebar) .star-chart-screen{margin-inline-start:var(--cm-sidebar-width)}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition-duration:.15s!important;animation-duration:.15s!important;animation-iteration-count:1!important}.study-preview,.check-panel,.mode-gate{animation-name:panel-enter-reduced}.entrypoint-picker{animation-name:entrypoint-enter-reduced}.illumination-pulse{animation-name:illumination-pulse-reduced}}@keyframes panel-enter-reduced{0%{opacity:0}to{opacity:1}}@keyframes entrypoint-enter-reduced{0%{opacity:0}to{opacity:1}}@keyframes illumination-pulse-reduced{0%{opacity:0}50%{opacity:1}to{opacity:0}}.picker-screen{gap:var(--cm-space-lg);min-height:100vh;padding:var(--cm-space-2xl) var(--cm-space-xl);flex-direction:column;max-width:44rem;margin:0 auto;display:flex}.picker-wordmark{font-family:var(--cm-font-display);font-size:var(--cm-text-sm);letter-spacing:.2em;text-transform:uppercase;color:var(--cm-ink-3)}.picker-subtitle{color:var(--cm-ink-2);font-size:var(--cm-text-sm)}.picker-recents ul,.picker-browser ul{margin:var(--cm-space-sm) 0 0;gap:var(--cm-space-2xs);flex-direction:column;padding:0;list-style:none;display:flex}.picker-recents button,.picker-browser ul button{justify-content:space-between;gap:var(--cm-space-sm);width:100%;padding:var(--cm-space-xs) var(--cm-space-sm);background:var(--cm-ground-2);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);color:var(--cm-ink);font-family:var(--cm-font-mono);font-size:var(--cm-text-sm);text-align:left;cursor:pointer;display:flex}.picker-recents button:hover,.picker-recents button:focus-visible,.picker-browser ul button:hover,.picker-browser ul button:focus-visible{border-color:var(--cm-orbit)}.picker-recents button{flex-wrap:wrap}.picker-recent-path{overflow-wrap:anywhere;min-width:0}.picker-recent-lit{color:var(--cm-star);white-space:nowrap}.picker-path{font-family:var(--cm-font-mono);font-size:var(--cm-text-sm);color:var(--cm-ink-2);overflow-wrap:anywhere}.picker-scale,.picker-error{border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);padding:var(--cm-space-sm);font-size:var(--cm-text-sm)}.picker-error{color:var(--cm-error)}.picker-select{padding:var(--cm-space-xs) var(--cm-space-lg);background:var(--cm-orbit-low);border:1px solid var(--cm-orbit);border-radius:var(--cm-radius);color:var(--cm-ink);font-size:var(--cm-text-base);cursor:pointer;align-self:flex-start}.picker-select:disabled{opacity:.6;cursor:progress}.layer-switcher{border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);display:inline-flex;overflow:hidden}.layer-switcher button{padding:var(--cm-space-2xs) var(--cm-space-sm);color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);cursor:pointer;background:0 0;border:0}.layer-switcher button[aria-pressed=true]{background:var(--cm-orbit-low);color:var(--cm-ink)}.map-view{gap:var(--cm-space-sm);padding:var(--cm-space-md);background:var(--cm-ground);flex-direction:column;display:flex;position:absolute;inset:0;overflow:hidden}.map-tabs{gap:var(--cm-space-xs);flex:none;display:flex}.map-tabs button{padding:var(--cm-space-2xs) var(--cm-space-sm);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);cursor:pointer;background:0 0}.map-tabs button[aria-pressed=true]{border-color:var(--cm-orbit);color:var(--cm-ink)}.map-canvas{flex-direction:column;flex:auto;min-height:0;display:flex;position:relative}.map-zoom{z-index:var(--cm-z-raised);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);background:var(--cm-ground-2);gap:1px;display:flex;position:absolute;inset-block-start:var(--cm-space-sm);inset-inline-end:var(--cm-space-sm)}.map-zoom button{min-width:34px;min-height:30px;color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);cursor:pointer;background:0 0;border:0}.map-zoom button:hover:not(:disabled),.map-zoom button:focus-visible{color:var(--cm-orbit)}.map-zoom button:disabled{color:var(--cm-ink-3);cursor:default}.map-scroll{cursor:grab;flex:auto;overflow:auto}.map-scroll[data-panning]{cursor:grabbing;-webkit-user-select:none;user-select:none}.map-canvas__sized{min-width:100%}.architecture-map,.workflow-tree{min-height:0;display:block}.architecture-map__edges path{color:var(--cm-hairline);stroke:currentColor;fill:none;stroke-linecap:round;stroke-linejoin:round}.architecture-map__edges path.is-cycle{color:var(--cm-route-possible)}.architecture-map__arrow{color:var(--cm-hairline)}.architecture-map__arrow.is-cycle{color:var(--cm-route-possible)}.workflow-tree__edges path{stroke:var(--cm-hairline);stroke-width:1.2px;fill:none}.architecture-map__box rect{fill:var(--cm-ground-2);stroke:var(--cm-hairline)}.architecture-map__box .box-tint{stroke:none}.architecture-map__box text{fill:var(--cm-ink);font-family:var(--cm-font-mono);font-size:13px}.architecture-map__box .box-meta{fill:var(--cm-ink-3);font-size:11px}.architecture-map__box[data-partial=true] rect:first-of-type{stroke:var(--cm-route-possible)}.architecture-map__box .box-partial{fill:var(--cm-route-possible);stroke:none}.architecture-map__box[data-understood=true] rect:first-of-type{stroke:var(--cm-star-high)}.architecture-map__box[data-home=true] rect:first-of-type{stroke-width:2px}.architecture-map__box[data-reachable=false] rect:first-of-type{stroke-dasharray:4 3}.architecture-map__box:focus-visible rect:first-of-type,.workflow-tree__row:focus-visible circle{outline:2px solid var(--cm-orbit);outline-offset:2px}.architecture-map__box,.workflow-tree__row{cursor:pointer}.workflow-tree__row circle{fill:var(--cm-ink-3)}.workflow-tree__row[data-partial=true] circle,.workflow-tree__row[data-cut] circle{fill:var(--cm-route-possible)}.workflow-tree__row[data-understood=true] circle{fill:var(--cm-star-high)}.workflow-tree__row text{fill:var(--cm-ink);font-family:var(--cm-font-mono);font-size:13px}.workflow-tree__row .row-meta{fill:var(--cm-ink-3);font-size:11px}.architecture-map__box[data-selected=true] rect:first-of-type{outline:2px solid var(--cm-orbit);outline-offset:3px}.workflow-tree__row[data-selected=true] circle{stroke:var(--cm-orbit);stroke-width:2px}.map-note,.map-loading{color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);flex:none;margin:0}.map-state{text-align:center;max-width:46ch;color:var(--cm-ink-2);margin:auto}.hint-chip{z-index:var(--cm-z-raised);align-items:center;gap:var(--cm-space-sm);min-width:0;padding:var(--cm-space-sm) var(--cm-space-md);border-block:1px solid var(--cm-orbit);background:var(--cm-ground-2);color:var(--cm-ink);font-size:var(--cm-text-sm);flex-wrap:wrap;grid-row:3;display:flex;position:static}.hint-chip small{color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs)}.hint-chip button{padding:var(--cm-space-2xs) var(--cm-space-sm);border:1px solid var(--cm-orbit);border-radius:var(--cm-radius);color:var(--cm-orbit);font-size:var(--cm-text-xs);cursor:pointer;background:0 0}@media (width>=40rem){.hint-chip{max-width:calc(100% - var(--cm-space-lg));border:1px solid var(--cm-orbit);border-radius:var(--cm-radius);grid-row:auto;position:absolute;inset-block-end:calc(3.5rem + var(--cm-space-md));inset-inline-start:var(--cm-space-md)}}.location button{color:var(--cm-orbit);font:inherit;cursor:pointer;background:0 0;border:0;padding:0}.location button[disabled]{color:var(--cm-ink-2);cursor:default}.location button:not([disabled]):hover{text-decoration:underline}.coach-marks{inset-block:auto var(--cm-space-lg);width:min(38ch, calc(100% - var(--cm-space-lg)));padding:var(--cm-space-md);border:1px solid var(--cm-orbit);border-radius:var(--cm-radius);background:var(--cm-ground-2);color:var(--cm-ink);margin-inline:auto;inset-inline:0}.coach-marks::backdrop{background:var(--cm-scrim)}.coach-marks__progress{margin:0 0 var(--cm-space-2xs);color:var(--cm-ink-3);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs)}.coach-marks h1{margin:0 0 var(--cm-space-xs);font-size:var(--cm-text-lg)}.coach-marks__actions{justify-content:space-between;gap:var(--cm-space-sm);margin-block-start:var(--cm-space-md);display:flex}.coach-skip{color:var(--cm-ink-3);cursor:pointer;background:0 0;border:0}.legend-tint{width:var(--cm-space-sm);height:var(--cm-space-sm);border-radius:2px;display:inline-block}.legend-tint--python{background:var(--cm-neb-python)}.legend-tint--javascript{background:var(--cm-neb-js)}.legend-tint--typescript{background:var(--cm-neb-ts)}.legend-route--dashed{border-block-start-style:dashed}.legend-size{width:var(--cm-space-md);height:var(--cm-space-sm);background:var(--cm-ink-3);border-radius:50%;display:inline-block}.legend-brightness{width:var(--cm-space-md);height:var(--cm-space-sm);background:linear-gradient(90deg, var(--cm-node-unlit), var(--cm-ink-2));display:inline-block}.app-shell[data-mode=easy]{--cm-text-xs:.8125rem;--cm-text-sm:.9375rem;--cm-text-base:1.125rem;--cm-text-lg:1.375rem;--cm-space-sm:1rem;--cm-space-md:1.375rem;--cm-space-lg:2.5rem;font-size:var(--cm-text-base);line-height:1.7}.app-shell[data-mode=easy] .orientation-copy p,.app-shell[data-mode=easy] .study-preview p,.app-shell[data-mode=easy] .grounded-explanation>p,.app-shell[data-mode=easy] .study-notice p,.app-shell[data-mode=easy] .evidence-list p,.app-shell[data-mode=easy] .lens-note p,.app-shell[data-mode=easy] .active-check fieldset>p,.app-shell[data-mode=easy] .check-state p,.app-shell[data-mode=easy] .check-complete p,.app-shell[data-mode=easy] .check-loading{max-width:46ch}.app-shell[data-mode=easy] .language-focus__label,.app-shell[data-mode=easy] .mode-toggle__label{text-transform:none;letter-spacing:normal}.loading-screen{gap:var(--cm-space-md);max-width:44rem;min-height:100vh;padding:var(--cm-space-lg) max(var(--cm-space-md), env(safe-area-inset-right)) var(--cm-space-lg) max(var(--cm-space-md), env(safe-area-inset-left));align-content:center;justify-items:start;margin:0 auto;display:grid}.loading-header h1{min-width:0;margin:var(--cm-space-2xs) 0 0;font-family:var(--cm-font-display);font-size:var(--cm-text-xl);overflow-wrap:anywhere;line-height:1.15}.loading-path{font-family:var(--cm-font-mono);font-size:var(--cm-text-sm);color:var(--cm-ink-2)}.loading-subtitle{margin:var(--cm-space-xs) 0 0;color:var(--cm-ink-2);font-size:var(--cm-text-sm)}.loading-stages{gap:var(--cm-space-2xs);width:100%;margin:0;padding:0;list-style:none;display:grid}.loading-stages li{justify-content:space-between;gap:var(--cm-space-sm);padding:var(--cm-space-xs) var(--cm-space-sm);border-left:2px solid var(--cm-hairline);color:var(--cm-ink-3);font-size:var(--cm-text-sm);flex-wrap:wrap;display:flex}.loading-stages li[data-state=active]{border-left-color:var(--cm-orbit);color:var(--cm-ink)}.loading-stages li[data-state=done]{border-left-color:var(--cm-orbit-deep);color:var(--cm-ink-2)}.loading-stages small{font-family:var(--cm-font-mono);color:var(--cm-ink-2)}.loading-meter{width:100%;height:var(--cm-space-xs);accent-color:var(--cm-orbit)}.loading-live{color:var(--cm-ink);font-size:var(--cm-text-sm)}.loading-error{border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);width:100%;padding:var(--cm-space-sm);color:var(--cm-ink-2);font-size:var(--cm-text-sm)}.loading-actions{gap:var(--cm-space-sm);flex-wrap:wrap;display:flex}.loading-actions button{padding:var(--cm-space-xs) var(--cm-space-md)}.picker-scale h2,.picker-failure h2{margin:0 0 var(--cm-space-xs);font-family:var(--cm-font-display);font-size:var(--cm-text-base)}.picker-scale-scopes{gap:var(--cm-space-xs);margin:var(--cm-space-sm) 0;flex-wrap:wrap;padding:0;list-style:none;display:flex}.picker-scale-scopes button{align-items:flex-start;gap:var(--cm-space-2xs);min-height:44px;padding:var(--cm-space-2xs) var(--cm-space-sm);background:var(--cm-ground-2);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);color:var(--cm-ink);font-family:var(--cm-font-mono);font-size:var(--cm-text-sm);cursor:pointer;flex-direction:column;display:flex}.picker-scale-scopes button:hover:not(:disabled),.picker-scale-scopes button:focus-visible{border-color:var(--cm-orbit)}.picker-scale-scopes button:disabled{opacity:.6;cursor:progress}.picker-scale-scopes small{color:var(--cm-ink-2)}.picker-path-entry{gap:var(--cm-space-xs);flex-wrap:wrap;align-items:center;display:flex}.picker-path-entry label{color:var(--cm-ink-2)}.picker-path-entry input{min-width:0;min-height:44px;padding:var(--cm-space-2xs) var(--cm-space-xs);background:var(--cm-ground);border:1px solid var(--cm-hairline);border-radius:var(--cm-radius);color:var(--cm-ink);font-family:var(--cm-font-mono);font-size:var(--cm-text-sm);flex:14rem}.picker-path-entry button{min-height:44px;padding:var(--cm-space-2xs) var(--cm-space-md);background:var(--cm-orbit-low);border:1px solid var(--cm-orbit);border-radius:var(--cm-radius);color:var(--cm-ink);font-size:var(--cm-text-sm);cursor:pointer}.picker-path-entry button:disabled{opacity:.6;cursor:not-allowed}.picker-failure{border:1px solid var(--cm-error);border-radius:var(--cm-radius);padding:var(--cm-space-sm);font-size:var(--cm-text-sm)}.picker-failure>p{margin:0 0 var(--cm-space-sm);color:var(--cm-ink-2)}.picker-failure__detail{gap:var(--cm-space-2xs);display:grid}.picker-failure__detail span{color:var(--cm-ink-3);font-size:var(--cm-text-xs);text-transform:uppercase;letter-spacing:.08em}.picker-failure__detail code{max-height:8rem;padding:var(--cm-space-xs);background:var(--cm-ground-2);border-radius:var(--cm-radius);color:var(--cm-ink-2);font-family:var(--cm-font-mono);font-size:var(--cm-text-xs);overflow-wrap:anywhere;display:block;overflow:auto}.picker-failure .picker-select{min-height:44px;font-size:var(--cm-text-sm);align-self:flex-start}.progress-reset{align-items:center;gap:var(--cm-space-sm);max-width:72rem;margin:var(--cm-space-lg) auto 0;padding-top:var(--cm-space-md);border-top:1px solid var(--cm-hairline);flex-wrap:wrap;display:flex}.progress-reset p{color:var(--cm-ink-2);font-size:var(--cm-text-sm);margin:0}.progress-reset button{min-height:44px;padding-inline:var(--cm-space-md);font-size:var(--cm-text-sm)}.progress-reset--confirming{justify-items:start;gap:var(--cm-space-sm);display:grid}.progress-reset--confirming>p[role=alert]{max-width:60ch;color:var(--cm-ink)}.progress-reset--confirming>div{gap:var(--cm-space-sm);flex-wrap:wrap;display:flex}.progress-reset__confirm{border-color:var(--cm-error);color:var(--cm-error)}.progress-reset__error{color:var(--cm-error)}