Kick off a new Chemistry learning section, visual-first (a three.js CSS3D periodic table) rather than text-first — the analog of our C# programming lessons, where content reveals only as the learner earns the understanding to see it. Basis: the three.js example https://threejs.org/examples/css3d_periodictable.html.
This ticket tracks Phase 1 (shipped by the linked PR) and records the phased roadmap.
Phase 1 (this PR) — the faithful landing
Learn → Chemistry lands on the CSS3D periodic table rendering exactly like the demo: all 118 elements, the four layouts (table / sphere / helix / grid), TWEEN morphing, trackball orbit + zoom. No click handling, modal, or gating yet.
Decomposition into our Angular v22 ecosystem:
App-local under projects/spikersoft/src/app/_components/learning/chemistry/ (matches the other three.js scenes and Learning tiles — no new Nx lib).
Element data ported verbatim (periodic-table.data.ts); layout math extracted to a pure, unit-tested function (periodic-table.layouts.ts).
PeriodicTableComponent — dynamic three + three/addons/{renderers/CSS3DRenderer,controls/TrackballControls,libs/tween.module} imports, ViewEncapsulation.None scoped under .chemistry-periodic-table (tiles are created imperatively), zoneless rAF loop, disciplined teardown.
ChemistryLandingPageComponent — @defer (on viewport) route wrapper (epic #722 E6), so the three.js payload splits out of the route chunk.
Wiring: route in routes.ts (public) + e2e/support/route-manifest.ts; menu entry in desktop #learnMenu and the mobile drawer; en/es i18n.
Acceptance criteria (Phase 1)
Learn → Chemistry (desktop + mobile) routes to /chemistry
CSS3D periodic table renders like the demo; all four layouts + orbit/zoom work
three.js absent from the initial bundle — loads only via the deferred scene chunk
unit tests, nx build spikersoft, lint/prettier/stylelint, i18n scan all green
Roadmap (later PRs, designed but not built here)
Phase 2 — click → in-scene detail. CSS3D tiles are real DOM, so clicks are plain DOM listeners (no raycasting); disambiguate click vs TrackballControls drag. Clicked tile TWEEN-zooms to center and expands into a detail card; rest of the table dims.
Phase 3 — progressive unlock. Author chemistry as backend Kind.Tutorial lesson strategies with real Prerequisites (Mongo-hydrated, reuse /api/Lessons/progress + ProgressSyncService); reuse the client-side isUnlocked = prerequisites.every(p => completedSet.has(p)) derivation. Not-yet-understood elements render as an obscured placeholder tile ("?" silhouette, slot kept, identity hidden) until unlocked. Note: today's unlock derivation is client-side only for authed users — hard server-side element locking, if wanted, is net-new work modeled on the anonymous-horizon 423 path.
## Why
Kick off a new **Chemistry** learning section, visual-first (a three.js CSS3D periodic table) rather than text-first — the analog of our C# programming lessons, where content reveals only as the learner earns the understanding to see it. Basis: the three.js example https://threejs.org/examples/css3d_periodictable.html.
This ticket tracks **Phase 1** (shipped by the linked PR) and records the phased roadmap.
## Phase 1 (this PR) — the faithful landing
`Learn → Chemistry` lands on the CSS3D periodic table rendering exactly like the demo: all 118 elements, the four layouts (table / sphere / helix / grid), TWEEN morphing, trackball orbit + zoom. No click handling, modal, or gating yet.
Decomposition into our Angular v22 ecosystem:
- App-local under `projects/spikersoft/src/app/_components/learning/chemistry/` (matches the other three.js scenes and Learning tiles — no new Nx lib).
- Element data ported verbatim (`periodic-table.data.ts`); layout math extracted to a pure, unit-tested function (`periodic-table.layouts.ts`).
- `PeriodicTableComponent` — dynamic `three` + `three/addons/{renderers/CSS3DRenderer,controls/TrackballControls,libs/tween.module}` imports, `ViewEncapsulation.None` scoped under `.chemistry-periodic-table` (tiles are created imperatively), zoneless rAF loop, disciplined teardown.
- `ChemistryLandingPageComponent` — `@defer (on viewport)` route wrapper (epic #722 E6), so the three.js payload splits out of the route chunk.
- Wiring: route in `routes.ts` (public) + `e2e/support/route-manifest.ts`; menu entry in desktop `#learnMenu` and the mobile drawer; en/es i18n.
### Acceptance criteria (Phase 1)
- [x] `Learn → Chemistry` (desktop + mobile) routes to `/chemistry`
- [x] CSS3D periodic table renders like the demo; all four layouts + orbit/zoom work
- [x] three.js absent from the initial bundle — loads only via the deferred scene chunk
- [x] unit tests, `nx build spikersoft`, lint/prettier/stylelint, i18n scan all green
## Roadmap (later PRs, designed but not built here)
- **Phase 2 — click → in-scene detail.** CSS3D tiles are real DOM, so clicks are plain DOM listeners (no raycasting); disambiguate click vs TrackballControls drag. Clicked tile TWEEN-zooms to center and expands into a detail card; rest of the table dims.
- **Phase 3 — progressive unlock.** Author chemistry as backend `Kind.Tutorial` lesson strategies with real `Prerequisites` (Mongo-hydrated, reuse `/api/Lessons/progress` + `ProgressSyncService`); reuse the client-side `isUnlocked = prerequisites.every(p => completedSet.has(p))` derivation. Not-yet-understood elements render as an **obscured placeholder tile** ("?" silhouette, slot kept, identity hidden) until unlocked. Note: today's unlock derivation is client-side only for authed users — hard server-side element locking, if wanted, is net-new work modeled on the anonymous-horizon 423 path.
PR open: spikerj/spikersoft-angular#467 (branch feat/chemistry-periodic-table, base master). Phase 1 — the periodic-table landing. Will comment the merge SHA and close this ticket once it merges.
PR open: spikerj/spikersoft-angular#467 (branch `feat/chemistry-periodic-table`, base `master`). Phase 1 — the periodic-table landing. Will comment the merge SHA and close this ticket once it merges.
Phase 1 merged to master via spikerj/spikersoft-angular#467 (feature commit 8d3ead4d, merge 9f2efa6b4fd5). The faithful CSS3D periodic-table landing is live. Closing — follow-up work (sizing polish, camera reset/axis views, in-scene element zoom, and Phase-3 unlock gating) will be tracked under its own tickets.
Phase 1 merged to `master` via spikerj/spikersoft-angular#467 (feature commit `8d3ead4d`, merge `9f2efa6b4fd5`). The faithful CSS3D periodic-table landing is live. Closing — follow-up work (sizing polish, camera reset/axis views, in-scene element zoom, and Phase-3 unlock gating) will be tracked under its own tickets.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why
Kick off a new Chemistry learning section, visual-first (a three.js CSS3D periodic table) rather than text-first — the analog of our C# programming lessons, where content reveals only as the learner earns the understanding to see it. Basis: the three.js example https://threejs.org/examples/css3d_periodictable.html.
This ticket tracks Phase 1 (shipped by the linked PR) and records the phased roadmap.
Phase 1 (this PR) — the faithful landing
Learn → Chemistrylands on the CSS3D periodic table rendering exactly like the demo: all 118 elements, the four layouts (table / sphere / helix / grid), TWEEN morphing, trackball orbit + zoom. No click handling, modal, or gating yet.Decomposition into our Angular v22 ecosystem:
projects/spikersoft/src/app/_components/learning/chemistry/(matches the other three.js scenes and Learning tiles — no new Nx lib).periodic-table.data.ts); layout math extracted to a pure, unit-tested function (periodic-table.layouts.ts).PeriodicTableComponent— dynamicthree+three/addons/{renderers/CSS3DRenderer,controls/TrackballControls,libs/tween.module}imports,ViewEncapsulation.Nonescoped under.chemistry-periodic-table(tiles are created imperatively), zoneless rAF loop, disciplined teardown.ChemistryLandingPageComponent—@defer (on viewport)route wrapper (epic #722 E6), so the three.js payload splits out of the route chunk.routes.ts(public) +e2e/support/route-manifest.ts; menu entry in desktop#learnMenuand the mobile drawer; en/es i18n.Acceptance criteria (Phase 1)
Learn → Chemistry(desktop + mobile) routes to/chemistrynx build spikersoft, lint/prettier/stylelint, i18n scan all greenRoadmap (later PRs, designed but not built here)
Kind.Tutoriallesson strategies with realPrerequisites(Mongo-hydrated, reuse/api/Lessons/progress+ProgressSyncService); reuse the client-sideisUnlocked = prerequisites.every(p => completedSet.has(p))derivation. Not-yet-understood elements render as an obscured placeholder tile ("?" silhouette, slot kept, identity hidden) until unlocked. Note: today's unlock derivation is client-side only for authed users — hard server-side element locking, if wanted, is net-new work modeled on the anonymous-horizon 423 path.PR open: spikerj/spikersoft-angular#467 (branch
feat/chemistry-periodic-table, basemaster). Phase 1 — the periodic-table landing. Will comment the merge SHA and close this ticket once it merges.Phase 1 merged to
mastervia spikerj/spikersoft-angular#467 (feature commit8d3ead4d, merge9f2efa6b4fd5). The faithful CSS3D periodic-table landing is live. Closing — follow-up work (sizing polish, camera reset/axis views, in-scene element zoom, and Phase-3 unlock gating) will be tracked under its own tickets.