From 71096d1d2f4f0d9a6b056629ac3a7a573f74972e Mon Sep 17 00:00:00 2001 From: msrivas-7 Date: Mon, 7 Sep 2026 16:45:04 -0700 Subject: [PATCH 1/4] feat(marketing): launch continuous glyph-field homepage --- docs/MARKETING_PARTICLE_STUDY.md | 173 +++++ docs/images/marketing-redesign/hero.png | Bin 0 -> 61855 bytes .../images/marketing-redesign/walkthrough.png | Bin 0 -> 78168 bytes e2e/specs/marketing.spec.ts | 191 ++++-- frontend/package-lock.json | 65 ++ frontend/package.json | 2 + frontend/src/App.tsx | 2 +- frontend/src/PublicApp.tsx | 68 +- .../marketing/study/MarketingHomepage.tsx | 387 +++++++++++ .../marketing/study/ParticleField.tsx | 611 ++++++++++++++++++ .../features/marketing/study/geometry.test.ts | 71 ++ .../src/features/marketing/study/geometry.ts | 127 ++++ .../marketing/study/interaction.test.ts | 109 ++++ .../features/marketing/study/interaction.ts | 83 +++ .../src/features/marketing/study/study.css | 568 ++++++++++++++++ frontend/src/productContract.test.ts | 31 +- frontend/vite.config.ts | 17 +- 17 files changed, 2415 insertions(+), 90 deletions(-) create mode 100644 docs/MARKETING_PARTICLE_STUDY.md create mode 100644 docs/images/marketing-redesign/hero.png create mode 100644 docs/images/marketing-redesign/walkthrough.png create mode 100644 frontend/src/features/marketing/study/MarketingHomepage.tsx create mode 100644 frontend/src/features/marketing/study/ParticleField.tsx create mode 100644 frontend/src/features/marketing/study/geometry.test.ts create mode 100644 frontend/src/features/marketing/study/geometry.ts create mode 100644 frontend/src/features/marketing/study/interaction.test.ts create mode 100644 frontend/src/features/marketing/study/interaction.ts create mode 100644 frontend/src/features/marketing/study/study.css diff --git a/docs/MARKETING_PARTICLE_STUDY.md b/docs/MARKETING_PARTICLE_STUDY.md new file mode 100644 index 00000000..756a6a39 --- /dev/null +++ b/docs/MARKETING_PARTICLE_STUDY.md @@ -0,0 +1,173 @@ +# CodeTutor homepage: glyph-field redesign + +Status: design approved by the user on 2026-09-07; production integration and +local validation complete. PR review, CI, merge and production verification remain. + +Experiment harness: `1692c52e-76b0-4fa4-ae20-a334eb578724`. +Branch-bound release harness: `79523664-9004-44ba-97b6-6ad58d64c4e2`. +Evidence: `.agent-harness/browser-evidence/1692c52e-76b0-4fa4-ae20-a334eb578724/`. + +## Scope and release gates + +Redesign the public homepage only. Preserve the headline, acquisition and returning +learner destinations, account options, footer links and public metadata. +Editor, lessons, welcome, auth, admin, backend, AI behavior and quotas stay unchanged. +Both the lightweight public router and the already-loaded full app use the same +homepage. The local `?motionStudy=1` link still works but no longer gates the design. + +The user approved taking the design through thorough validation, a published PR, +Codex review and resolution of actionable threads, green CI, merge, deployment, +then actual-browser production verification. Earlier local-only restrictions are +superseded by that explicit authorization. A green unit suite alone is insufficient. + +## Approved experience + +- One continuous original code-glyph field on a near-black page. Ice-blue, amber, + violet and white light come from the particles, not a blue background wash. +- A large centered bracket hero disperses into the margins while text is read. + The field regroups centrally between sections; no assembled side illustrations. +- Numerous tiny fragments, readable glyphs and rare large highlights. Size, symbol + and palette use independent seeded channels; largest sprites are not all pluses. +- Persistent faint atmosphere also drifts and responds to the pointer. +- Swept mouse paths impart momentum. Circular gestures add subtle swirl, followed + by gentle recovery; drag/arrow rotation is separate and bounded. +- Manual Read / Ask / Check demonstration follows one average-score mistake, + useful tutor hint, correction and learner explanation. It is explicitly labeled + illustrative, not a live AI response or execution. +- The header contains only brand and sign-in/dashboard navigation. Local testing + controls, density selector, theme toggle and free/card/time fine print are gone. +- The user chose system Reduce Motion handling instead of a pause button after + comparing Astra. Reduced-motion and compact layouts show static original glyphs. + The public composition stays dark under either system color preference. + +The hero is deliberately more cinematic than the baseline. On a 960×863 viewport, +the primary CTA follows the artwork below the first screen; there is no scroll +lock, forced delay or interaction gate. This approved hierarchy change must be +called out in the PR. It is not a measured conversion improvement. + +## Reference research + +[OpenAI GPT-6 Astra](https://openai.com/index/gpt-6-astra/) was inspected through +actual Codex in-app scrolling from hero to footer, representative demo tabs, +pointer sweeps/circles, drag/arrow controls and reduced-motion emulation. + +| Observation | Transferable principle | +| --- | --- | +| Luminous 6, cursor and later blossom, rather than a shape for every paragraph | Give important chapters meaningful visual markers | +| Sculptures disperse around reading content; faint particles remain | Coordinate one field around attention, not separate decorative widgets | +| Wide demos alternate with narrower explanation and manual tabs | Keep evidence legible and pacing under visitor control | +| Pointer movement and whole-form rotation behave differently | Separate local momentum from sculpture rotation | +| Footnotes/footer become quieter | Continuity need not mean identical intensity everywhere | + +Loaded public code identifies Next.js, Three.js, React Three Fiber, custom GLSL, +shape samples, pointer-motion/coasting state and renderer quality limits. It also +contains postprocessing integration; presence does not prove every option runs. +Public build artifacts inspected through browser DevTools: + +- [Astra geometry/shader](https://openai.com/_next/static/immutable/chunks/1rfzm7jt1igp4.js) +- [Configuration/React integration](https://openai.com/_next/static/immutable/chunks/1kdmy-p0oag4x.js) +- [Three renderer](https://openai.com/_next/static/immutable/chunks/1a43l2lhrwu30.js) +- [Postprocessing integration](https://openai.com/_next/static/immutable/chunks/2_rkuko8hans4.js) + +These are version-specific evidence, not stable APIs. One direct HTTP request met +a protection challenge; research used already-loaded public scripts, without +bypass. No reference code, shapes or assets are copied into this implementation. + +### Reduced motion: verified + +Astra exposes replay and drag/arrow rotation, but no particle pause toggle. With +`prefers-reduced-motion: reduce` emulated and the page reloaded, its hero remains +visible but static. Screenshots across pointer sweeps were byte-identical. The +loaded component gates continuous scene rendering and scroll effects on that +preference and resets pointer state. Clearing it restores changing frames. +Screenshot: `astra-reduced-motion.png`. This does not audit every embedded video +or establish whole-site accessibility compliance. + +## Architecture and alternatives + +| Choice | Rationale | +| --- | --- | +| Direct Three.js Points and original glyph atlas | One scene/draw call, not a DOM element per glyph | +| DOM-derived scroll keyframes | Reversible native scrolling; no scroll hijacking | +| 420 foreground + 630 ambient glyphs, capped DPR 1.5 | Current visual choice; not claimed as an optimized device-independent density | +| Four morph targets | Brackets, book, conversation and check reinforce programming/learning | +| Per-glyph velocity and damped return | Cursor gestures feel carried rather than radially repelled | +| Static SVG fallback, lazy renderer | Text and acquisition remain available before graphics load or after failure | +| Manual demo tabs | No timed content replacement while someone reads | +| Shared production homepage in both routers | Direct visits and returns from the editor cannot show different designs | + +CSS/Framer Motion remain suited to ordinary DOM effects, but not a separate node +for every particle. React Three Fiber adds no needed capability for this single +scene; raw WebGL/WebGPU adds engine responsibility without demonstrated benefit. +No bloom/postprocessing is needed. Three's scene/math core is packaged separately +from WebGL renderer code, behind the lazy renderer boundary; budgets remain intact. + +Rejected through user/browser feedback: disconnected side sculptures, dust-only +particles, correlated large-plus symbols, radial repulsion, and local testing +chrome. The current curvature refinement adds up to 40% carry only to curved +strokes; straight sweeps retain the preceding response. Deterministic tests cover +clockwise/counterclockwise direction, release, distant particles and long frames. + +References: [Three batching](https://threejs.org/manual/en/optimize-lots-of-objects.html), +[resource cleanup](https://threejs.org/manual/en/cleanup.html), +[rendering on demand](https://threejs.org/manual/en/rendering-on-demand.html), +[WCAG pause/stop/hide](https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html), +[animation from interactions](https://www.w3.org/WAI/WCAG22/Understanding/animation-from-interactions.html). +The user-approved preference-based approach has no independent on-page stop +mechanism. Matching Astra does not itself prove WCAG conformance. + +## Verification ledger + +Actual-browser observations use rebuilt Docker frontend images, not Playwright +as a substitute. CI-oriented automation supplements those interactions. + +| Check | Evidence / state | +| --- | --- | +| Reference and baseline | Full reference scroll, targeted gestures and reduced motion; original hero/header/footer compared before activation | +| Centered continuity | Production-route and optimized-build hero, forward/reverse scroll and walkthrough verified; UX-195 tall-screen initial dispersion corrected and rechecked at 1440×1320 | +| Keyboard | Corrected DOM order: header → artwork → CTA; arrows and Tab exit work; Ask → Tab/Space → Check works | +| Responsive | 390×844 and 320×740 have no document overflow and all stages work; code fits at 320; 768×900 restores one canvas | +| Theme/reduced motion | Light system preference preserves intended dark composition; reduce removes canvas/rotation and keeps SVGs; clearing it restores one ready canvas | +| Graphics recovery | Optimized build: blocked graphics download leaves Read/Ask/Check usable, Reload recovers; context loss leaves demo usable, Retry restores rendering and focuses headline; automatic restoration also exercised locally | +| Public controls | No testing controls or pause; footer destinations restored; actual Continue → dashboard → sign-out → Privacy → home → anonymous first lesson → skip intro/welcome reaches enabled editor controls | +| Automated | Full frontend suite: 569 tests; typecheck/build; 16 homepage + zero-state first-journey E2E checks passed with retries disabled | +| Performance | Lighthouse homepage performance 0.98, LCP 2104 ms, CLS 0, TBT 0; why-not page 0.99/LCP 1955 ms. Local optimized desktop sample: 60 frame intervals, median 16.7 ms, p95 16.8 ms, max 17.5 ms at 1280×720/DPR 2 (renderer cap 1.5) | +| PR/release | Not opened; must obtain Codex review, resolve actionable threads, pass CI, then verify deployed production | + +Review images, captured from the optimized local build without changing page content: +[hero](images/marketing-redesign/hero.png) and +[walkthrough](images/marketing-redesign/walkthrough.png). +Harness evidence additionally includes `optimized-mobile-320.png`, +`optimized-reduced-motion.png`, `final-desktop-check.png` and +`astra-reduced-motion.png`. Earlier `public-preview-*` images show superseded UI. +The harness audit binds this evidence to the staged code fingerprint; the PR +identifies its commit. These are local-build images, not production proof. + +The first production integration hit the unchanged 120 KB per-chunk gzip budget: +graphics chunk 131,439 bytes; all JS 632,053 bytes, below the 700 KB total budget. +Splitting the actual Three package core from its WebGL renderer corrected the +packaging without raising limits. Final all-JS gzip is 633,893 bytes; largest chunk +90,511 bytes; CSS 19,657 bytes; HTML 1,194 bytes. Both graphics chunks remain lazy, +and their successful load/render was verified in the optimized build. +Development-server timings are not production payload benchmarks; the brief +desktop frame sample is not GPU time, sustained load or low-end-device proof. + +### Finding added during final validation + +- **UX-195 — tall viewport disperses the hero before scrolling:** closed locally. + A negative scroll anchor placed the initial sculpture in its departure phase. + Clamp shape anchors to reachable scroll positions; regression covers 720, + 1000 and 1320px viewport heights. Actual 1440×1320 browser replay confirms a + complete initial bracket form; production confirmation remains required. + +## Completion checklist + +- [x] Reference behavior and public implementation researched. +- [x] Original glyph design iterated with the user. +- [x] Explicit design and conditional release approval recorded. +- [x] Substantial local browser evidence and deterministic checks. +- [x] Final production-route browser pass, screenshots and performance checks. +- [x] Full relevant automated checks and asset budgets green. +- [ ] Independent reader review, clean diff, harness and commit. +- [ ] Published PR, clear Codex review, actionable threads resolved, green CI. +- [ ] Merge, successful deployment, deployed-site browser verification. diff --git a/docs/images/marketing-redesign/hero.png b/docs/images/marketing-redesign/hero.png new file mode 100644 index 0000000000000000000000000000000000000000..b2617c7a2ad089c4ea12a483e117523d54571bef GIT binary patch literal 61855 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 m&c8@CzH< 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 literal 0 HcmV?d00001 diff --git a/e2e/specs/marketing.spec.ts b/e2e/specs/marketing.spec.ts index 8cc03fd7..8932375a 100644 --- a/e2e/specs/marketing.spec.ts +++ b/e2e/specs/marketing.spec.ts @@ -1,8 +1,8 @@ -// Phase 22C: marketing page (`/`) e2e. Exercises: +// Public glyph homepage (`/`) e2e. Preserves Phase 22C acquisition contracts: // - anonymous visitor lands on / and sees the hero claim + nav // - the primary CTA starts the no-signup lesson; signup is secondary // - "Sign in" anchor leads to /login -// - "How it works" anchor smooth-scrolls to the Section 2 content +// - the walkthrough anchor reaches reversible Read / Ask / Check content // - logged-in users hitting / are NOT redirected; they see the // marketing page with a "Dashboard" affordance and a CTA that // points at /start with "Continue learning" copy @@ -36,12 +36,11 @@ test.describe("marketing page (Phase 22C) — anonymous", () => { await expect(hero).toBeVisible({ timeout: 5_000 }); await expect(hero).toHaveText(HERO_CLAIM); - // Match-cut panel renders a JetBrains Mono code line — the typewriter - // is mid-animation when the assertion runs, so we assert on the string - // literal "Maya" we know lands within the first ~250ms (line 1 of - // the new Python TypeError beat). - const monoLine = page.getByText(/Maya/, { exact: false }); - await expect(monoLine.first()).toBeVisible({ timeout: 5_000 }); + // The linked walkthrough is authored HTML, never a simulated live AI call. + await expect( + page.getByText("Illustrative walkthrough · not live AI"), + ).toBeVisible(); + await expect(page.getByText("average.py", { exact: true })).toBeVisible(); // Primary CTA (in-hero). Two CTAs on the page (hero + repeat) — // both share the label, so .first() is fine. @@ -49,10 +48,9 @@ test.describe("marketing page (Phase 22C) — anonymous", () => { await expect(heroCta.first()).toBeVisible(); const heroHref = await heroCta.first().getAttribute("href"); expect(heroHref).toMatch(/\/try\/lesson\/python-fundamentals\/hello-world/); - await expect(page.getByRole("link", { name: /create a free account/i })).toHaveAttribute( - "href", - /\/signup/, - ); + await expect( + page.getByRole("link", { name: /create an account/i }), + ).toHaveAttribute("href", /\/signup/); // Top-right Sign in anchor (in the marketing nav). const signIn = page.getByRole("link", { name: /^sign in$/i }).first(); @@ -60,48 +58,80 @@ test.describe("marketing page (Phase 22C) — anonymous", () => { await expect(signIn).toHaveAttribute("href", /\/login/); }); - test("clicking the primary CTA navigates directly to the no-signup lesson", async ({ page }) => { + test("clicking the primary CTA navigates directly to the no-signup lesson", async ({ + page, + }) => { await page.goto("/"); - const cta = page.getByRole("link", { name: /try your first lesson/i }).first(); + const cta = page + .getByRole("link", { name: /try your first lesson/i }) + .first(); await cta.click(); await expect(page).toHaveURL( /\/try\/lesson\/python-fundamentals\/hello-world$/, ); }); - test("primary action is visible without scrolling on a common laptop screen", async ({ browser }) => { - const context = await browser.newContext({ viewport: { width: 1280, height: 720 } }); + test("cinematic introduction never gates the primary action or traps scrolling", async ({ + browser, + }) => { + const context = await browser.newContext({ + viewport: { width: 1280, height: 720 }, + }); const page = await context.newPage(); await page.goto("/"); - const cta = page.getByRole("link", { name: /try your first lesson/i }).first(); + const cta = page + .getByRole("link", { name: /try your first lesson/i }) + .first(); await expect(cta).toBeVisible(); - const box = await cta.boundingBox(); - expect(box).not.toBeNull(); - expect(box!.y + box!.height).toBeLessThanOrEqual(720); + // Approved redesign puts the artwork before the headline/CTA. Verify + // access instead of retaining the superseded above-the-fold composition. expect(await page.evaluate(() => window.scrollY)).toBe(0); + await cta.scrollIntoViewIfNeeded(); + await expect(cta).toBeInViewport(); + await cta.click(); + await expect(page).toHaveURL( + /\/try\/lesson\/python-fundamentals\/hello-world$/, + ); await context.close(); }); - test("the three How-it-works beats render below the hero", async ({ + test("the linked Read Ask Check walkthrough is reversible and useful", async ({ page, }) => { await page.goto("/"); - // Force the section into viewport for assertion. JSDOM-style hash - // anchors are flakey under Lenis smooth-scroll; we scroll the - // element into view directly instead. - await page.locator("#how-it-works").scrollIntoViewIfNeeded(); - - await expect(page.getByRole("heading", { name: "Read." })).toBeVisible(); - await expect(page.getByRole("heading", { name: "Ask." })).toBeVisible(); - await expect(page.getByRole("heading", { name: "Check." })).toBeVisible(); + await page.getByRole("link", { name: /See how learning happens/ }).click(); + await expect(page).toHaveURL(/#study-demo$/); + const stages = page.getByRole("group", { name: "Walkthrough stages" }); + await stages.getByRole("button", { name: /Ask/ }).click(); + await expect(page.getByText(/Trace total after each pass/)).toBeVisible(); + await stages.getByRole("button", { name: /Check/ }).click(); + await expect(page.locator(".study-output samp")).toHaveText("8.0"); + await expect( + page.getByText(/Assignment kept only the last score/), + ).toBeVisible(); + await stages.getByRole("button", { name: /Read/ }).click(); + await expect(page.locator(".study-output samp")).toHaveText( + "3.3333333333333335", + ); + await expect(stages.getByRole("button", { name: /Read/ })).toHaveAttribute( + "aria-pressed", + "true", + ); }); - test("essential How-it-works copy is never animation-gated at zero opacity", async ({ page }) => { + test("essential How-it-works copy is never animation-gated at zero opacity", async ({ + page, + }) => { await page.goto("/"); - const section = page.locator("#how-it-works"); - const hiddenEssential = await section.locator("h3, p").evaluateAll((nodes) => - nodes.filter((node) => Number.parseFloat(getComputedStyle(node).opacity) === 0).length, - ); + const section = page.locator("#study-demo"); + const hiddenEssential = await section + .locator("h3, p") + .evaluateAll( + (nodes) => + nodes.filter( + (node) => Number.parseFloat(getComputedStyle(node).opacity) === 0, + ).length, + ); expect(hiddenEssential).toBe(0); }); @@ -143,6 +173,53 @@ test.describe("marketing page (Phase 22C) — anonymous", () => { }); test.describe("marketing page (Phase 22C) — reduced motion", () => { + test("responds to a live reduced-motion change without losing demo state", async ({ + page, + }) => { + await page.goto("/"); + await page + .getByRole("group", { name: "Walkthrough stages" }) + .getByRole("button", { name: /Check/ }) + .click(); + await page.emulateMedia({ reducedMotion: "reduce" }); + await expect(page.locator(".motion-study-canvas canvas")).toHaveCount(0); + await expect(page.locator("[data-field-interaction]")).toHaveCount(0); + await expect(page.locator(".study-output samp")).toHaveText("8.0"); + await expect( + page.getByRole("button", { name: /pause animation/i }), + ).toHaveCount(0); + await page.emulateMedia({ reducedMotion: "no-preference" }); + await expect(page.locator(".study-output samp")).toHaveText("8.0"); + await expect( + page.getByRole("link", { name: /try your first lesson/i }).first(), + ).toHaveAttribute("href", /\/try\/lesson\//); + }); + + test("graphics module failure leaves content usable and reload recovers", async ({ + page, + }) => { + await page.emulateMedia({ reducedMotion: "no-preference" }); + await page.route("**/ParticleField*", (route) => route.abort()); + await page.goto("/"); + await expect(page.getByText(/Motion could not load/)).toBeVisible(); + await page + .getByRole("group", { name: "Walkthrough stages" }) + .getByRole("button", { name: /Ask/ }) + .click(); + await expect(page.getByText(/Trace total after each pass/)).toBeVisible(); + await page.unroute("**/ParticleField*"); + await page.getByRole("button", { name: "Reload page" }).click(); + await expect(page.getByRole("heading", { level: 1 })).toHaveText( + HERO_CLAIM, + ); + await expect(page.getByText(/Motion could not load/)).toHaveCount(0); + await expect( + page + .getByRole("group", { name: "Walkthrough stages" }) + .getByRole("button", { name: /Read/ }), + ).toHaveAttribute("aria-pressed", "true"); + }); + test("renders the hero in its final state statically", async ({ page }) => { // Force the prefers-reduced-motion media query BEFORE navigation so // the very first render of MatchCutHero sees `reduce === true` and @@ -157,15 +234,12 @@ test.describe("marketing page (Phase 22C) — reduced motion", () => { await expect(hero).toBeVisible({ timeout: 3_000 }); await expect(hero).toHaveText(HERO_CLAIM); - // The match-cut panel skips its scheduled beats and renders the - // final state directly — code visible AND tutor question visible - // from first paint, no waiting on the ~8.4s play-through. - await expect(page.getByText(/Maya/).first()).toBeVisible({ - timeout: 3_000, - }); + await expect(page.locator(".motion-study-canvas canvas")).toHaveCount(0); + await expect(page.locator("[data-field-interaction]")).toHaveCount(0); + await expect(page.locator(".study-still")).toHaveCount(3); await expect( - page.getByText(/Why does this fail when points is 100\?/), - ).toBeVisible({ timeout: 3_000 }); + page.getByRole("heading", { name: "Find the average score" }), + ).toBeVisible(); // CTA still functions. const cta = page @@ -176,7 +250,9 @@ test.describe("marketing page (Phase 22C) — reduced motion", () => { expect(box?.height ?? 0).toBeGreaterThanOrEqual(44); }); - test("360px viewport has no essential horizontal overflow", async ({ browser }) => { + test("360px viewport has no essential horizontal overflow", async ({ + browser, + }) => { const context = await browser.newContext({ viewport: { width: 360, height: 800 }, isMobile: true, @@ -198,7 +274,11 @@ test.describe("marketing page (Phase 22C) — mobile viewport", () => { // iPhone 13 portrait dimensions. Setting just the viewport (rather // than `...devices["iPhone 13"]`) sidesteps Playwright's "can't // change defaultBrowserType inside describe" constraint. - test.use({ viewport: { width: 390, height: 844 }, isMobile: true, hasTouch: true }); + test.use({ + viewport: { width: 390, height: 844 }, + isMobile: true, + hasTouch: true, + }); test("renders without horizontal overflow at iPhone 13 width", async ({ page, @@ -242,19 +322,16 @@ authedTest.describe("marketing page (Phase 22C) — authed nav swap", () => { }, ); - authedTest( - "clicking Dashboard navigates to /start", - async ({ page }) => { - await page.goto("/"); - // The URL assertion below owns navigation readiness. Avoid making the - // click also wait for every scheduled navigation because the public-app - // auth handoff can replace the active React subtree during that wait. - await page.getByRole("link", { name: /^dashboard/i }).click({ - noWaitAfter: true, - }); - await authedExpect(page).toHaveURL(/\/start$/, { timeout: 5_000 }); - }, - ); + authedTest("clicking Dashboard navigates to /start", async ({ page }) => { + await page.goto("/"); + // The URL assertion below owns navigation readiness. Avoid making the + // click also wait for every scheduled navigation because the public-app + // auth handoff can replace the active React subtree during that wait. + await page.getByRole("link", { name: /^dashboard/i }).click({ + noWaitAfter: true, + }); + await authedExpect(page).toHaveURL(/\/start$/, { timeout: 5_000 }); + }); authedTest( "primary CTA reads 'Continue learning' and points at /start when authed", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 73810d19..df035dba 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -21,6 +21,7 @@ "react-markdown": "10.1.0", "react-router-dom": "^7.18.2", "remark-gfm": "4.0.1", + "three": "0.185.1", "zustand": "^4.5.4" }, "devDependencies": { @@ -31,6 +32,7 @@ "@types/node": "^25.6.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", + "@types/three": "0.185.4", "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.19", "chrome-launcher": "1.2.1", @@ -341,6 +343,13 @@ "node": ">=6.9.0" } }, + "node_modules/@dimforge/rapier3d-compat": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz", + "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -2448,6 +2457,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@tweenjs/tween.js": { + "version": "23.1.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", + "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -2650,6 +2666,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/stats.js": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", + "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/tedious": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", @@ -2660,12 +2683,41 @@ "@types/node": "*" } }, + "node_modules/@types/three": { + "version": "0.185.4", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.185.4.tgz", + "integrity": "sha512-gAsBIC07NIFrxjbf7tH2t71c38uulFfk/RFoC7FNBSjMRAQ8J1x/RBvusX0N5PJouaYFJawXQqfCQ0RKUx/1nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@dimforge/rapier3d-compat": "~0.12.0", + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": ">=0.5.17", + "fflate": "~0.8.2", + "meshoptimizer": "~1.1.1" + } + }, + "node_modules/@types/three/node_modules/fflate": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz", + "integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, + "node_modules/@types/webxr": { + "version": "0.5.24", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz", + "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", @@ -5172,6 +5224,13 @@ "node": ">= 8" } }, + "node_modules/meshoptimizer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-1.1.1.tgz", + "integrity": "sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g==", + "dev": true, + "license": "MIT" + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", @@ -7227,6 +7286,12 @@ "dev": true, "license": "MIT" }, + "node_modules/three": { + "version": "0.185.1", + "resolved": "https://registry.npmjs.org/three/-/three-0.185.1.tgz", + "integrity": "sha512-5aojFCXKwnjBRZvUnt3WFfEcvUJgkN5LlijRFN95hMy8WVkG4I0QNcJE+OuWvuJ0bOdStrbfXn0pkd6/QyiAlg==", + "license": "MIT" + }, "node_modules/tiny-inflate": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", diff --git a/frontend/package.json b/frontend/package.json index 1c364980..cfc4215b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -30,6 +30,7 @@ "react-markdown": "10.1.0", "react-router-dom": "^7.18.2", "remark-gfm": "4.0.1", + "three": "0.185.1", "zustand": "^4.5.4" }, "devDependencies": { @@ -40,6 +41,7 @@ "@types/node": "^25.6.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", + "@types/three": "0.185.4", "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.19", "chrome-launcher": "1.2.1", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 928d89cb..135d5ca7 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -10,7 +10,7 @@ import { RequireAdmin } from "./auth/RequireAdmin"; import { HydrationGate } from "./auth/HydrationGate"; import { WelcomeBackOverlay } from "./features/firstRun/WelcomeBackOverlay"; import { ReplayReturnFocus } from "./auth/ReplayReturnFocus"; -const MarketingPage = lazy(() => import("./pages/MarketingPage")); +const MarketingPage = lazy(() => import("./features/marketing/study/MarketingHomepage")); const WhyNotChatGPTPage = lazy(() => import("./pages/WhyNotChatGPTPage")); const StartPage = lazy(() => import("./pages/StartPage")); const EditorPage = lazy(() => import("./pages/EditorPage")); diff --git a/frontend/src/PublicApp.tsx b/frontend/src/PublicApp.tsx index ddcfc5a2..e4ce8d97 100644 --- a/frontend/src/PublicApp.tsx +++ b/frontend/src/PublicApp.tsx @@ -1,10 +1,11 @@ -import { lazy, Suspense, useEffect, useState } from "react"; +import { lazy, Suspense } from "react"; import { Route, Routes } from "react-router-dom"; import type { ReactNode } from "react"; -import CompactMarketingPage from "./pages/CompactMarketingPage"; import WhyNotChatGPTPage from "./pages/WhyNotChatGPTPage"; -const MarketingPage = lazy(() => import("./pages/MarketingPage")); +const MarketingHomepage = lazy( + () => import("./features/marketing/study/MarketingHomepage"), +); const TrustPage = lazy(() => import("./pages/TrustPage")); const FullApp = lazy(async () => { const [appModule, { initAuth }] = await Promise.all([ @@ -31,22 +32,6 @@ function PublicSurface({ children }: { children: ReactNode }) { return

{children}
; } -function MarketingEntry() { - const [compact, setCompact] = useState(() => - window.matchMedia("(max-width: 640px)").matches, - ); - - useEffect(() => { - const query = window.matchMedia("(max-width: 640px)"); - const update = () => setCompact(query.matches); - update(); - query.addEventListener("change", update); - return () => query.removeEventListener("change", update); - }, []); - - return compact ? : ; -} - /** * Lightweight route shell for acquisition and trust surfaces. * @@ -59,11 +44,46 @@ export default function PublicApp() { return ( }> - } /> - } /> - } /> - } /> - } /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> } /> diff --git a/frontend/src/features/marketing/study/MarketingHomepage.tsx b/frontend/src/features/marketing/study/MarketingHomepage.tsx new file mode 100644 index 00000000..2f7fcfa0 --- /dev/null +++ b/frontend/src/features/marketing/study/MarketingHomepage.tsx @@ -0,0 +1,387 @@ +import { + Component, + lazy, + Suspense, + useEffect, + useRef, + useState, + type ReactNode, +} from "react"; +import { Link } from "react-router-dom"; +import { Wordmark } from "../../../components/Wordmark"; +import { FIRST_LESSON_CONTRACT } from "../../../productContract"; +import { pickHeroCopy } from "../heroCopy"; +import { useMarketingAuth } from "../useMarketingAuth"; +import { + createShape, + particleIdentity, + particleSeed, + type Shape, +} from "./geometry"; +import "./study.css"; + +const ParticleField = lazy(() => import("./ParticleField")); +class MotionBoundary extends Component< + { children: ReactNode }, + { failed: boolean } +> { + state = { failed: false }; + static getDerivedStateFromError() { + return { failed: true }; + } + render() { + return this.state.failed ? ( +

+ Motion could not load. The walkthrough is still available.{" "} + +

+ ) : ( + this.props.children + ); + } +} +const stages = [ + { + name: "Read", + shape: "read", + title: "Start with something you can reason about.", + description: + "Read a short lesson. Try a prediction. Then run real code and see where your understanding meets the result.", + heading: "Find the average score", + prompt: + "These scores are 6, 8, and 10. What average would you expect? Read the loop before you run it.", + output: "3.3333333333333335", + note: "The result is surprising. That is a useful place to start.", + }, + { + name: "Ask", + shape: "ask", + title: "A useful question changes what you notice.", + description: + "Your tutor helps you inspect your own work. A specific hint gives you a next step without taking the thinking away.", + heading: "Look at what changes", + prompt: + "Trace total after each pass through the loop. Does total = score add to the previous total, or replace it? What would you need to keep?", + output: "After each pass: 6 → 8 → 10", + note: "A concrete trace. A question you can answer. The next step is yours.", + }, + { + name: "Check", + shape: "check", + title: "Code that works. Understanding that stays.", + description: + "Check your work, then explain the idea in your own words. Finishing means more than getting a green result.", + heading: "Explain your change", + prompt: + "Why does adding to total keep all three scores, while assigning score to total does not?", + output: "8.0", + note: "The learner changed the accumulation. The tutor did not supply the solution.", + }, +] as const; + +function StillArt({ shape }: { shape: Shape }) { + const points = createShape(shape, 90); + const glyphs = ["{", "}", "<", ">", "[", "]", ";", "+"]; + return ( + + ); +} + +export default function MarketingHomepage() { + const headline = useRef(null); + const [root, setRoot] = useState(null); + const [staticMode, setStaticMode] = useState( + () => + matchMedia("(prefers-reduced-motion: reduce), (max-width: 640px)") + .matches, + ); + const [status, setStatus] = useState<"loading" | "ready" | "unavailable">( + "loading", + ); + const [attempt, setAttempt] = useState(0); + const [stage, setStage] = useState(0); + const { isLoggedIn } = useMarketingAuth(); + const copy = pickHeroCopy(); + const current = stages[stage]!; + const animate = !staticMode; + const destination = isLoggedIn ? "/start" : FIRST_LESSON_CONTRACT.route; + const cta = isLoggedIn ? "Continue learning" : "Try your first lesson"; + useEffect(() => { + const query = matchMedia( + "(prefers-reduced-motion: reduce), (max-width: 640px)", + ); + const update = () => setStaticMode(query.matches); + query.addEventListener("change", update); + return () => query.removeEventListener("change", update); + }, []); + return ( +
+ ); +} diff --git a/frontend/src/features/marketing/study/ParticleField.tsx b/frontend/src/features/marketing/study/ParticleField.tsx new file mode 100644 index 00000000..50a2d342 --- /dev/null +++ b/frontend/src/features/marketing/study/ParticleField.tsx @@ -0,0 +1,611 @@ +import { useEffect, useRef } from "react"; +import * as THREE from "three"; +import { + createScatter, + createShape, + particleIdentity, + particleSeed, + smoothProgress, + shapeScrollAnchor, + type Shape, +} from "./geometry"; +import { + advanceGlyphMotion, + curveCarry, + type PointerStroke, +} from "./interaction"; + +interface Props { + root: HTMLElement; + light: boolean; + count: number; + onStatus: (status: "loading" | "ready" | "unavailable") => void; +} + +// Original shader: no reference-site implementation or art is copied. +const vertexShader = ` + attribute vec3 readShape; + attribute vec3 askShape; + attribute vec3 checkShape; + attribute vec3 scatter; + attribute float seed; + attribute vec2 identity; + attribute float background; + attribute vec2 displacement; + uniform vec4 weights; + uniform float spread; + uniform vec2 viewport; + uniform float clock; + uniform float scale; + uniform float dpr; + uniform vec2 center; + uniform vec2 pointer; + uniform vec2 tilt; + uniform float pointerActive; + uniform float scrollOffset; + uniform vec2 atmosphereShift; + varying float brightness; + varying float glyphIndex; + varying float spectrum; + varying float ambientGlyph; + void main() { + vec3 p = position * weights.x + readShape * weights.y + askShape * weights.z + checkShape * weights.w; + float yaw = sin(clock * .16) * .035 + tilt.x; + float pitch = tilt.y; + p = vec3(p.x*cos(yaw)+p.z*sin(yaw), p.y, -p.x*sin(yaw)+p.z*cos(yaw)); + p = vec3(p.x, p.y*cos(pitch)-p.z*sin(pitch), p.y*sin(pitch)+p.z*cos(pitch)); + p.xy *= scale; + p.xy += center; + vec2 dispersed = scatter.xy * viewport * .5; + dispersed += vec2(sin(clock*.13+seed*23.0)*8.0,cos(clock*.10+seed*19.0)*6.0); + dispersed += atmosphereShift*(.3+seed*.7); + p.xy = mix(p.xy, dispersed, spread); + if (background > .5) { + // A persistent distant field never participates in shape assembly. + // Wrap beyond the viewport; only a small fraction of page scroll becomes parallax. + p.x = scatter.x * viewport.x * .5 + sin(clock*.16+seed*20.0)*10.0 + atmosphereShift.x*(.4+seed*.6); + p.y = mod(scatter.y*viewport.y*.5 + scrollOffset*(.025+seed*.035) + + cos(clock*.12+seed*15.0)*7.0 + atmosphereShift.y*(.4+seed*.6) + + viewport.y*.6, viewport.y*1.2)-viewport.y*.6; + p.z = -.4; + } + p.xy += displacement; + p.z *= scale; + brightness = .4 + .6 * seed; + glyphIndex = floor(identity.x * 7.999); + spectrum = identity.y; + ambientGlyph = background; + gl_Position = projectionMatrix * modelViewMatrix * vec4(p,1.0); + // A long-tailed size distribution, not a field of equal-size text icons: + // tiny distant fragments, readable mid-size glyphs, rare luminous anchors. + float foregroundSize = 4.0 + pow(seed,2.0)*13.0 + pow(seed,24.0)*28.0; + float backgroundSize = 2.0 + pow(seed,2.0)*5.0 + pow(seed,24.0)*7.0; + gl_PointSize = mix(foregroundSize,backgroundSize,background) * dpr; + } +`; +const fragmentShader = ` + uniform vec3 tint; + uniform float opacity; + uniform sampler2D glyphAtlas; + uniform float highlight; + varying float brightness; + varying float glyphIndex; + varying float spectrum; + varying float ambientGlyph; + void main() { + vec2 uv = vec2((glyphIndex + gl_PointCoord.x) / 8.0, 1.0-gl_PointCoord.y); + float alpha = texture2D(glyphAtlas, uv).a * brightness * mix(opacity,.42,ambientGlyph); + if(alpha<.01) discard; + // Stable spectral identity: predominantly ice, with warm and violet accents. + // The page stays neutral; the glyphs carry the color and light. + vec3 spectral = spectrum < .52 ? vec3(.46,.77,1.0) + : spectrum < .74 ? vec3(1.0,.62,.34) + : spectrum < .89 ? vec3(.72,.59,1.0) : vec3(.88,.97,1.0); + vec3 color = mix(tint, spectral, highlight); + gl_FragColor = vec4(mix(color, vec3(1.0), pow(brightness,10.0)*highlight*.7),alpha); + } +`; + +export default function ParticleField({ root, light, count, onStatus }: Props) { + const host = useRef(null); + useEffect(() => { + const element = host.current; + if (!element) return; + onStatus("loading"); + let renderer: THREE.WebGLRenderer; + try { + renderer = new THREE.WebGLRenderer({ + alpha: true, + antialias: false, + powerPreference: "low-power", + }); + } catch { + onStatus("unavailable"); + return; + } + element.appendChild(renderer.domElement); + const scene = new THREE.Scene(); + const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0.1, 2000); + camera.position.z = 1000; + const geometry = new THREE.BufferGeometry(); + const ambientCount = Math.round(count * 1.5); + const total = count + ambientCount; + const shapes = Object.fromEntries( + (["code", "read", "ask", "check"] as Shape[]).map((s) => { + const positions = new Float32Array(total * 3); + positions.set(createShape(s, count)); + return [s, positions]; + }), + ) as Record; + geometry.setAttribute( + "position", + new THREE.BufferAttribute(shapes.code, 3), + ); + geometry.setAttribute( + "readShape", + new THREE.BufferAttribute(shapes.read, 3), + ); + geometry.setAttribute("askShape", new THREE.BufferAttribute(shapes.ask, 3)); + geometry.setAttribute( + "checkShape", + new THREE.BufferAttribute(shapes.check, 3), + ); + const scattered = new Float32Array(total * 3); + scattered.set(createScatter(count)); + for (let i = count; i < total; i++) { + scattered[i * 3] = particleSeed(i * 3) * 2 - 1; + scattered[i * 3 + 1] = particleSeed(i * 3 + 1) * 2.4 - 1.2; + } + geometry.setAttribute("scatter", new THREE.BufferAttribute(scattered, 3)); + geometry.setAttribute( + "seed", + new THREE.BufferAttribute( + Float32Array.from({ length: total }, (_, i) => particleSeed(i)), + 1, + ), + ); + geometry.setAttribute( + "identity", + new THREE.BufferAttribute( + Float32Array.from( + Array.from({ length: total }, (_, i) => particleIdentity(i)).flat(), + ), + 2, + ), + ); + geometry.setAttribute( + "background", + new THREE.BufferAttribute( + Float32Array.from({ length: total }, (_, i) => (i >= count ? 1 : 0)), + 1, + ), + ); + const offsets = new Float32Array(total * 2); + const velocities = new Float32Array(total * 2); + const displacement = new THREE.BufferAttribute(offsets, 2).setUsage( + THREE.DynamicDrawUsage, + ); + geometry.setAttribute("displacement", displacement); + // One original code-symbol atlas, not hundreds of animated DOM text nodes. + const atlasCanvas = document.createElement("canvas"); + atlasCanvas.width = 512; + atlasCanvas.height = 64; + const context = atlasCanvas.getContext("2d"); + if (!context) { + renderer.dispose(); + renderer.domElement.remove(); + geometry.dispose(); + onStatus("unavailable"); + return; + } + context.font = "500 44px monospace"; + context.textAlign = "center"; + context.textBaseline = "middle"; + context.fillStyle = "#ffffff"; + context.shadowColor = "#ffffff"; + context.shadowBlur = light ? 0 : 7; + ["{", "}", "<", ">", "[", "]", ";", "+"].forEach((glyph, i) => + context.fillText(glyph, i * 64 + 32, 33), + ); + const atlas = new THREE.CanvasTexture(atlasCanvas); + atlas.minFilter = THREE.LinearFilter; + atlas.magFilter = THREE.LinearFilter; + atlas.generateMipmaps = false; + const uniforms = { + atmosphereShift: { value: new THREE.Vector2() }, + scrollOffset: { value: 0 }, + tilt: { value: new THREE.Vector2() }, + glyphAtlas: { value: atlas }, + highlight: { value: light ? 0 : 1 }, + weights: { value: new THREE.Vector4(1, 0, 0, 0) }, + spread: { value: 1 }, + viewport: { value: new THREE.Vector2() }, + clock: { value: 0 }, + scale: { value: 180 }, + dpr: { value: 1 }, + center: { value: new THREE.Vector2() }, + pointer: { value: new THREE.Vector2(-10000, -10000) }, + pointerActive: { value: 0 }, + tint: { value: new THREE.Color(light ? "#086b91" : "#82d6fa") }, + opacity: { value: 1 }, + }; + const material = new THREE.ShaderMaterial({ + uniforms, + vertexShader, + fragmentShader, + transparent: true, + depthWrite: false, + depthTest: false, + blending: light ? THREE.NormalBlending : THREE.AdditiveBlending, + }); + const points = new THREE.Points(geometry, material); + points.frustumCulled = false; + scene.add(points); + let width = innerWidth, + height = innerHeight, + frame = 0, + last = 0, + elapsed = 0, + disposed = false, + ready = false, + contextLost = false; + let pointerTarget = 0; + const pointerPosition = new THREE.Vector2(-10000, -10000); + const strokes: PointerStroke[] = []; + let previousPointer: { x: number; y: number; time: number } | null = null; + let previousStroke: PointerStroke | null = null; + const tiltTarget = new THREE.Vector2(); + let drag: { + id: number; + x: number; + y: number; + element: HTMLElement; + } | null = null; + let anchors: HTMLElement[] = []; + const resize = () => { + width = innerWidth; + height = innerHeight; + renderer.setPixelRatio(Math.min(devicePixelRatio, 1.5)); + renderer.setSize(width, height); + uniforms.viewport.value.set(width, height); + uniforms.dpr.value = renderer.getPixelRatio(); + camera.left = -width / 2; + camera.right = width / 2; + camera.top = height / 2; + camera.bottom = -height / 2; + camera.updateProjectionMatrix(); + anchors = Array.from( + root.querySelectorAll("[data-particle-shape]"), + ); + }; + const move = (event: PointerEvent) => { + pointerPosition.set( + event.clientX - width / 2, + height / 2 - event.clientY, + ); + const target = event.target instanceof Element ? event.target : null; + const control = target?.closest("a,button,input,select,pre"); + pointerTarget = + event.pointerType === "mouse" && + (!control || control.hasAttribute("data-field-interaction")) + ? 1 + : 0; + if (pointerTarget) { + const next = { + x: pointerPosition.x, + y: pointerPosition.y, + time: event.timeStamp, + }; + if (previousPointer && next.time - previousPointer.time < 160) { + const stroke: PointerStroke = { + x0: previousPointer.x, + y0: previousPointer.y, + x1: next.x, + y1: next.y, + }; + stroke.curve = curveCarry(previousStroke, stroke); + strokes.push(stroke); + previousStroke = stroke; + if (strokes.length > 64) strokes.shift(); + } else previousStroke = null; + previousPointer = next; + } else { + previousPointer = null; + previousStroke = null; + } + if (drag && drag.id === event.pointerId) { + tiltTarget.set( + Math.max(-0.16, Math.min(0.16, (event.clientX - drag.x) * 0.001)), + Math.max(-0.12, Math.min(0.12, (event.clientY - drag.y) * 0.001)), + ); + } + }; + const leave = () => { + pointerTarget = 0; + previousPointer = null; + previousStroke = null; + tiltTarget.set(0, 0); + }; + const down = (event: PointerEvent) => { + const target = + event.target instanceof Element + ? event.target.closest("[data-field-interaction]") + : null; + if (!target || event.pointerType !== "mouse" || event.button !== 0) + return; + drag = { + id: event.pointerId, + x: event.clientX, + y: event.clientY, + element: target, + }; + target.setPointerCapture(event.pointerId); + }; + const up = (event: PointerEvent) => { + if (drag?.id === event.pointerId) { + if (drag.element.hasPointerCapture(event.pointerId)) + drag.element.releasePointerCapture(event.pointerId); + drag = null; + tiltTarget.set(0, 0); + } + }; + const key = (event: KeyboardEvent) => { + if ( + !(event.target instanceof Element) || + !event.target.hasAttribute("data-field-interaction") || + event.altKey || + event.ctrlKey || + event.metaKey || + event.shiftKey + ) + return; + const steps: Record = { + ArrowLeft: [-0.035, 0], + ArrowRight: [0.035, 0], + ArrowUp: [0, -0.035], + ArrowDown: [0, 0.035], + }; + const step = steps[event.key]; + if (!step) return; + event.preventDefault(); + tiltTarget.set( + Math.max(-0.16, Math.min(0.16, tiltTarget.x + step[0])), + Math.max(-0.12, Math.min(0.12, tiltTarget.y + step[1])), + ); + }; + const render = (now: number) => { + if (disposed || contextLost || document.hidden) return; + const dt = Math.min((now - last) / 1000 || 0, 0.05); + last = now; + elapsed += dt; + uniforms.clock.value = elapsed; + uniforms.scrollOffset.value = scrollY; + const states = anchors.map((anchor) => { + const rect = anchor.getBoundingClientRect(); + return { + shape: (anchor.dataset.particleShape || "code") as Shape, + at: shapeScrollAnchor(rect.top + scrollY + rect.height / 2, height), + x: rect.left + rect.width / 2 - width / 2, + y: height / 2 - rect.top - rect.height / 2, + size: Math.min(rect.width, rect.height) * 0.42, + spread: 0, + }; + }); + const [hero, demo, closing] = states; + const demoSurface = root + .querySelector(".study-demo-surface") + ?.getBoundingClientRect(); + const heroCopy = root + .querySelector(".study-hero-copy") + ?.getBoundingClientRect(); + if (hero && demo && closing && demoSurface && heroCopy) { + // Continuous keyframes, not nearest-anchor selection. Between chapters the + // same particles remain visible in a quiet edge field around the content. + // Every sculpture is central. The field retreats to the margins only + // while content is read, then gathers in the next open central interval. + const heroClearAt = Math.max( + hero.at + 1, + heroCopy.top + scrollY - height * 0.55, + ); + const clearAt = Math.max( + demo.at + 1, + demoSurface.top + scrollY - height * 0.38, + ); + const keys = [ + hero, + { ...hero, at: heroClearAt, spread: 1 }, + { + ...demo, + at: Math.max(heroClearAt + 1, demo.at - height * 0.75), + spread: 1, + }, + { ...demo, at: demo.at - height * 0.12 }, + demo, + { ...demo, at: Math.min(clearAt - 1, demo.at + height * 0.27) }, + { ...demo, at: clearAt, spread: 1 }, + { + ...closing, + at: Math.max(clearAt + 1, closing.at - height * 0.75), + spread: 1, + }, + closing, + ]; + keys.sort((a, b) => a.at - b.at); + let a = keys[0]!, + b = a; + for (let i = 1; i < keys.length; i++) { + b = keys[i]!; + if (scrollY <= b.at) break; + a = b; + } + const p = + a === b + ? 0 + : smoothProgress((scrollY - a.at) / Math.max(1, b.at - a.at)); + const blend = 1 - Math.exp(-dt * 3); + const weight = (shape: Shape) => + (a.shape === shape ? 1 - p : 0) + (b.shape === shape ? p : 0); + const desired = new THREE.Vector4( + weight("code"), + weight("read"), + weight("ask"), + weight("check"), + ); + uniforms.weights.value.lerp(desired, blend); + const spread = a.spread + (b.spread - a.spread) * p; + uniforms.spread.value += + (Math.max(spread, 1 - smoothProgress(elapsed / 1.5)) - + uniforms.spread.value) * + blend; + uniforms.opacity.value = + (1 - uniforms.spread.value) * 0.94 + + uniforms.spread.value * (light ? 0.5 : 0.6); + uniforms.center.value.lerp( + new THREE.Vector2(a.x + (b.x - a.x) * p, a.y + (b.y - a.y) * p), + blend, + ); + uniforms.scale.value += + (a.size + (b.size - a.size) * p - uniforms.scale.value) * blend; + } + uniforms.pointerActive.value += + (pointerTarget - uniforms.pointerActive.value) * Math.min(1, dt * 8); + uniforms.pointer.value.lerp(pointerPosition, 1 - Math.exp(-dt * 6)); + uniforms.tilt.value.lerp(tiltTarget, 1 - Math.exp(-dt * 2.2)); + uniforms.atmosphereShift.value.lerp( + new THREE.Vector2( + (pointerPosition.x / width) * 14 * pointerTarget, + (pointerPosition.y / height) * 14 * pointerTarget, + ), + 1 - Math.exp(-dt * 1.4), + ); + // Stateful, damped return: moving the cursor away does not reset a glyph + // to its home position on the next frame. The same spring handles release. + const weights = uniforms.weights.value; + const scale = uniforms.scale.value, + spread = uniforms.spread.value; + const yaw = Math.sin(elapsed * 0.16) * 0.035 + uniforms.tilt.value.x; + const pitch = uniforms.tilt.value.y; + for (let i = 0; i < total; i++) { + const j = i * 3, + seed = particleSeed(i); + let x = + shapes.code[j]! * weights.x + + shapes.read[j]! * weights.y + + shapes.ask[j]! * weights.z + + shapes.check[j]! * weights.w; + let y = + shapes.code[j + 1]! * weights.x + + shapes.read[j + 1]! * weights.y + + shapes.ask[j + 1]! * weights.z + + shapes.check[j + 1]! * weights.w; + const z = + shapes.code[j + 2]! * weights.x + + shapes.read[j + 2]! * weights.y + + shapes.ask[j + 2]! * weights.z + + shapes.check[j + 2]! * weights.w; + const rotatedZ = -x * Math.sin(yaw) + z * Math.cos(yaw); + x = x * Math.cos(yaw) + z * Math.sin(yaw); + y = y * Math.cos(pitch) - rotatedZ * Math.sin(pitch); + x = + (x * scale + uniforms.center.value.x) * (1 - spread) + + (scattered[j]! * width * 0.5 + + Math.sin(elapsed * 0.13 + seed * 23) * 8 + + uniforms.atmosphereShift.value.x * (0.3 + seed * 0.7)) * + spread; + y = + (y * scale + uniforms.center.value.y) * (1 - spread) + + (scattered[j + 1]! * height * 0.5 + + Math.cos(elapsed * 0.1 + seed * 19) * 6 + + uniforms.atmosphereShift.value.y * (0.3 + seed * 0.7)) * + spread; + if (i >= count) { + x = + scattered[j]! * width * 0.5 + + Math.sin(elapsed * 0.16 + seed * 20) * 10 + + uniforms.atmosphereShift.value.x * (0.4 + seed * 0.6); + const raw = + scattered[j + 1]! * height * 0.5 + + scrollY * (0.025 + seed * 0.035) + + Math.cos(elapsed * 0.12 + seed * 15) * 7 + + uniforms.atmosphereShift.value.y * (0.4 + seed * 0.6) + + height * 0.6; + y = + (((raw % (height * 1.2)) + height * 1.2) % (height * 1.2)) - + height * 0.6; + } + advanceGlyphMotion( + offsets, + velocities, + i, + x, + y, + strokes, + dt, + i >= count, + ); + } + strokes.length = 0; + displacement.needsUpdate = true; + renderer.render(scene, camera); + if (!ready) { + ready = true; + onStatus("ready"); + } + frame = requestAnimationFrame(render); + }; + const visibility = () => { + cancelAnimationFrame(frame); + last = performance.now(); + if (!document.hidden && !contextLost && !disposed) + frame = requestAnimationFrame(render); + }; + const lost = (event: Event) => { + event.preventDefault(); + cancelAnimationFrame(frame); + contextLost = true; + ready = false; + onStatus("unavailable"); + }; + const restored = () => { + if (disposed) return; + contextLost = false; + onStatus("loading"); + resize(); + visibility(); + }; + resize(); + frame = requestAnimationFrame(render); + window.addEventListener("resize", resize); + root.addEventListener("pointermove", move, { passive: true }); + root.addEventListener("pointerleave", leave); + root.addEventListener("pointerdown", down); + root.addEventListener("pointerup", up); + root.addEventListener("pointercancel", up); + root.addEventListener("keydown", key); + root.addEventListener("focusout", leave); + document.addEventListener("visibilitychange", visibility); + renderer.domElement.addEventListener("webglcontextlost", lost); + renderer.domElement.addEventListener("webglcontextrestored", restored); + return () => { + disposed = true; + cancelAnimationFrame(frame); + window.removeEventListener("resize", resize); + root.removeEventListener("pointermove", move); + root.removeEventListener("pointerleave", leave); + root.removeEventListener("pointerdown", down); + root.removeEventListener("pointerup", up); + root.removeEventListener("pointercancel", up); + root.removeEventListener("keydown", key); + root.removeEventListener("focusout", leave); + document.removeEventListener("visibilitychange", visibility); + renderer.domElement.removeEventListener("webglcontextlost", lost); + renderer.domElement.removeEventListener("webglcontextrestored", restored); + geometry.dispose(); + material.dispose(); + atlas.dispose(); + renderer.dispose(); + renderer.domElement.remove(); + }; + }, [root, light, count, onStatus]); + return
+ + Skip to the product walkthrough + + {root && animate && ( + + + + + + )} +
+ + + + +
+ {animate && status === "unavailable" && ( +

+ Motion is unavailable. You can still explore the walkthrough.{" "} + +

+ )} + +
+
+ + {animate && status === "ready" && ( +
+
+

A coding tutor. Not a shortcut.

+

+ {copy.claim} +

+

+ {copy.subhead}. Read, experiment, and ask better questions. Build an + understanding that belongs to you. +

+ + {cta} + + + See how learning happens + +
+
+ +
+
+
+

01 — The learning loop

+

+ From “why?” +
+ to “I see it.” +

+
+
+ +
+
+
+
+ {stages.map((item, i) => ( + + ))} + + Illustrative walkthrough · not live AI + +
+
+
+
+ average.py + Python +
+
+                
+                  
+                    # Find the average of three scores
+                  
+                  {"\n"}scores = [6, 8, 10
+                  ]{"\n"}total = 0
+                  {"\n\n"}
+                  for score{" "}
+                  in scores:{"\n"}
+                  
+                    {"    "}
+                    total {stage === 2 ? "+=" : "="} score
+                  
+                  {"\n\n"}average = total /{" "}
+                  len(scores){"\n"}
+                  print(average)
+                
+              
+
+ + {stage === 1 ? "Trace the loop" : "Example output"} + + {current.output} +
+
+
+

+ {stage === 0 ? "Your lesson" : "Your tutor"} +

+

{current.heading}

+ {stage === 1 && ( +

+ “I expected 8. Why am I getting 3.33?” +

+ )} +

{current.prompt}

+ {stage === 2 && ( +

+ “Assignment kept only the last score. Adding each score keeps + the running total: 24 divided by 3 is 8.” +

+ )} +

{current.note}

+
+
+
+

{current.title}

+

{current.description}

+
+
+
+ +
+
+ +
+
+

02 — Your next line

+

+ Less copying. +
+ More understanding. +

+

+ A lesson, an editor, and a tutor to help you think it through. Start + with one small program. +

+ + {cta} + +
+
+ +