From 50c33119024baedacb1156e10cfecd11cee4a748 Mon Sep 17 00:00:00 2001 From: AndresL230 <190146319+AndresL230@users.noreply.github.com> Date: Sat, 1 Aug 2026 10:52:01 -0700 Subject: [PATCH 01/20] docs(spec): landing page below the hero (#344 phase 2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Interactive knowledge graph replaces the 340vh scroll-jacked HowItWorks, then three feature bands and a four-tile bento of real app surfaces. The structural argument is a density rhythm — the graph is the densest thing on the page, bands decompress, the bento re-energizes, and a closing band gives the CTA a run-up rather than ending on a grid tile. The content argument matters more than the visual one. Tutor chat, Notes, Gradebook and Flashcards are shipped surfaces the current six-feature list never mentions, so the page undersells the product more than it under-designs it. That is the likeliest root of #344's 'feels generic'. Live LLM generation on the public page was considered and rejected for now: most convincing option, but it puts an unauthenticated billable endpoint on the most-crawled page on the site. Recorded as a second pass behind a rate-limited endpoint. Co-Authored-By: Claude Opus 5 --- .../2026-08-01-landing-below-hero-design.md | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 docs/superpowers/specs/2026-08-01-landing-below-hero-design.md diff --git a/docs/superpowers/specs/2026-08-01-landing-below-hero-design.md b/docs/superpowers/specs/2026-08-01-landing-below-hero-design.md new file mode 100644 index 00000000..348bbcf8 --- /dev/null +++ b/docs/superpowers/specs/2026-08-01-landing-below-hero-design.md @@ -0,0 +1,231 @@ +# Landing page — everything below the hero + +Design for #344 (`[p1] frontend PRIORITY - Landing page redesign`), phase 2. +Phase 1 was 8fb7949, which deleted unreachable effects and orphaned CSS. + +## Problem + +Below the hero, the landing page currently runs a 340vh scroll-jacked +`HowItWorks` (677 lines of framer-motion, a Seed→Sprout→Tree metaphor over a +mocked `AppWindow`), then a six-row hairline feature catalog, then a CTA and +footer. + +#344 names five complaints. Restated as causes rather than symptoms: + +1. The graph — the product's actual differentiator — is a **movie you watch**, + not a thing you touch. +2. The features describe **generic capabilities**, not the pages Sapling + actually ships. +3. The section carries scaffolding that exists to explain the scaffolding: a + left-side step indicator, "drag"/"scroll" hint copy, per-step preview + buttons. +4. It doesn't look impressive enough to hold a visitor. +5. It "feels generic," with nothing that could only be Sapling. + +Point 5 is the one worth restating: **the page undersells the product more than +it under-designs it.** Tutor chat, Notes, Gradebook and Flashcards are all +shipped surfaces that the current six-feature list never mentions. Fixing that +does more for "feels generic" than any amount of new motion. + +## Goals + +- Make the knowledge graph manipulable, with the explanatory copy receding as + the visitor engages. +- Present real Sapling surfaces instead of abstract capability names. +- Delete the scaffolding #344 lists. +- Keep the page fast and crawlable — this is the most-indexed surface on the + site. + +## Non-goals + +- The hero, nav, and intro overlay are **untouched**. So are the sign-in and + beta/newsletter modals. +- No live LLM generation on the public page (see Rejected alternatives). +- No backend work. Every graph in this design is a static fixture. + +## Architecture + +Hero (unchanged) +1. Interactive graph +2. Band — Universal Upload +3. Band — Adaptive quizzes +4. Bento — Tutor chat, Notes, Study Rooms, Gradebook +5. Band — knows what to review, and when +6. CTA +7. Footer (kept, tightened) + +The ordering is a density rhythm: the graph is the densest thing on the page, +two bands decompress, the bento re-energizes, and the final band closes on a +claim so the CTA has a run-up. A grid's last tile is a weak place to ask for a +signup. + +The three bands carry one arc — **material in → practice → retention** — rather +than three disconnected pitches. Band surfaces alternate sides. + +### 1. Interactive graph + +Replaces `HowItWorks` entirely. Roughly full-viewport, below the fold. + +- Three course chips (`CS 210`, `MA 242`, `SM 275`). Picking one animates that + course's concept graph into existence, node by node. +- Once assembled: drag nodes, hover for a concept blurb, click a node to expand + its children. +- The instructional copy fades as the visitor interacts — the fade is driven by + first interaction, not by a timer. +- No side step indicator, no "drag me" hint, no per-step buttons. + +Data is a static fixture module — three hand-authored course graphs, each a +`{nodes, edges}` shape mirroring the real `graph_nodes` / `graph_edges` +semantics (mastery tiers included, so the colour language matches the app and +the hero legend). + +### 2, 3, 5. Bands + +Full-width. One built product surface on one side, copy on the other, +alternating. Surfaces are recreated in-page in the hero's liquid-glass +language — not screenshots. The repo has no product screenshots, and the hero +already recreates surfaces this way (`CS 101 · 55% mastered`, the mastery +legend, `Total nodes 2,413`), so this stays consistent, themeable, and +responsive. + +| Band | Surface | Claim | +|---|---|---| +| 2 | Upload / extraction | syllabus, textbook, lecture notes → concepts on your graph | +| 3 | Quiz | presses where you're strong, meets you where you struggle | +| 5 | Review scheduling | knows what to review, and when | + +Band 5 folds together what are today two separate features (Adaptive Study +Paths, Spaced Repetition) — they make one claim, not two. + +### 4. Bento + +Asymmetric grid, four tiles, varying sizes: **Tutor chat**, **Notes**, +**Study Rooms**, **Gradebook**. Static surface recreations; no per-tile buttons. + +Flashcards and the knowledge graph are deliberately out — the graph is section 1, +and Flashcards is the surface you'd least lead with. + +### 6, 7. CTA and footer + +CTA keeps its current copy and `startOnboarding` behaviour. Footer keeps its +links and credit line; spacing tightened to match the new rhythm. + +## Component boundaries + +`(public)/page.tsx` is already ~935 lines and would grow. New work lands in +`components/marketing/` as focused files, imported by `page.tsx`: + +- `KnowledgeGraphDemo/` — the interactive graph. Split so the canvas/SVG + renderer, the layout+animation logic, and the fixture data are separately + readable and testable. +- `FeatureBand.tsx` — presentational; takes a side, copy, and a surface node. +- `SurfaceBento.tsx` — the four-tile grid. +- `surfaces/` — the in-page product recreations (upload, quiz, review, tutor, + notes, rooms, gradebook), each self-contained. + +`HowItWorks.tsx` is deleted, along with its `next/dynamic` import and the +340vh placeholder in `page.tsx`. + +## Motion + +**The helix fires once.** #344 asks for "3D helix animations"; the budget is +spent in a single place — nodes arriving along a helical path as the graph +assembles after a course chip is picked. That is a real 3D helix, at the exact +moment the page makes its argument. Bands and bento get quiet entrance +transitions only. + +Scattering helix motifs through every section is how a page becomes generic +rather than less so, and the hero already runs a full canvas RAF loop directly +above this. + +**Reduced motion and test mode.** The graph parks on a static, fully-laid-out +frame under `prefers-reduced-motion: reduce` and under `IS_TEST_MODE`, matching +how the hero canvas already behaves. A parked graph must still be *complete* — +laid out and readable, not blank. Any randomness routes through +`lib/testMode`'s `random()` / `now()` so the E2E lane is deterministic. + +## Performance + +- The graph component lazy-loads via `next/dynamic` below the fold, following + the existing `HowItWorks` precedent — but with SSR **kept** so crawlers still + receive the section's marketing copy, which is why the current code avoids + `ssr: false`. +- Its RAF loop must not start until the section is near the viewport, and must + stop when it leaves. The hero's canvas is already running above it. +- Placeholder height must match the resolved section height so nothing below + shifts during chunk load (CLS). + +## Styling + +Everything is scoped under `.landing-page`, which re-declares the same token +names as the warm app shell (`docs/frontend-rhythm-audit.md`). New CSS must be +added inside that scope and must not leak token redefinitions outward — this is +the documented cause of the "get-started/beta feels off" class of bug. + +## Testing + +- **Unit/vitest**: fixture graph shape (every edge references a real node; no + orphans), band alternation, reduced-motion parking. +- **Testids**: new interactive surfaces need a prefix registered per + `docs/frontend-testids.md` §"Adding a surface" — add the row, add the owning + file to the lint block's `files` array, and run `npm run lint`, which + enumerates interactive elements still missing testids. +- **E2E journey** (`frontend/e2e/`, fixtures-based `test` from + `support/fixtures.ts`): the landing page renders the graph section; picking a + course chip assembles a graph; interacting fades the instructional copy; the + page still routes to onboarding from both CTAs. Auto-waiting `expect` only, + no timeouts. +- `public-seo.spec.ts` already asserts the landing page ships social cards and a + canonical URL — it must stay green, which is the guard on not breaking SSR. + +## What gets deleted + +- `components/marketing/HowItWorks.tsx` (677 lines) and its dynamic import +- Seed / Sprout / Tree SVG components and the `AppWindow` mock +- the left-side step indicator, drag/scroll hint copy, per-step preview buttons +- the six-row hairline feature catalog and its "— end of catalog" rule +- any CSS in `globals.css` left orphaned by the above + +## Rejected alternatives + +**Live generation on the public page.** Letting a visitor type any topic and +generating a real graph is the most convincing option — it *is* the product +rather than a picture of it. Rejected for now: it puts an unauthenticated, +billable LLM endpoint on the most-crawled page on the site, with real cost, +rate-limiting, prompt-abuse and slow-Gemini failure modes. It is a strong second +pass once the section exists and can sit behind a hardened, rate-limited +endpoint. + +**Sticky rail with a swapping panel.** Compact, but it is a left-side index that +scroll-drives a panel — close to the "left side page indication" #344 explicitly +asks to remove. + +**Straight to bento after the graph.** Rejected on pacing: the graph is dense +and immersive, and a dense grid immediately after gives the eye nowhere to rest. + +**Screenshots for the feature surfaces.** No product screenshots exist in the +repo, and in-page recreations stay themeable, responsive, and consistent with +the hero's existing glass cards. + +## Sequencing + +This is two shippable pieces, and they should not land as one PR. + +1. **The graph** — section 1, plus deleting `HowItWorks` and the old catalog. + The page is coherent at the end of this step: graph, then CTA, then footer. +2. **Bands, bento, and the seven surface recreations** — sections 2–5. + +Step 1 carries the risk and the reviewer attention; step 2 is mostly +presentational and parallelises well across the seven surfaces. Splitting also +means a mediocre graph gets caught before seven surfaces are built on top of it. + +## Risks + +- The interactive graph is the largest single build here and carries the page. + If it lands mediocre, the redesign fails regardless of the rest. +- Three bands plus a bento plus a full-viewport graph makes a long page. Each + band has to earn its height; if one reads as filler during implementation, cut + it rather than pad it. +- Two graph renderings now exist on one page (the hero's atmospheric canvas and + this labelled interactive one). They must read as deliberately different — + atmosphere versus instrument — not as the same effect twice. From 06912187e5cfaf02a0ecc55d6b061435272dce5a Mon Sep 17 00:00:00 2001 From: AndresL230 <190146319+AndresL230@users.noreply.github.com> Date: Sat, 1 Aug 2026 10:58:45 -0700 Subject: [PATCH 02/20] docs(plan): landing interactive graph, step 1 (#344) Seven tasks: fixtures, layout+helix math, component, assembly, interaction, page wiring with the HowItWorks/catalog deletions, and the e2e journey. Self-review found one real gap and it is recorded in the plan rather than papered over: the spec lists drag alongside hover and expand, and Task 5 implements hover and the copy fade only. Dragging needs a pointer-capture and SVG coordinate-mapping decision (getScreenCTM) that deserves its own review gate, so it is called out as 5b/5c rather than hidden inside a step. Co-Authored-By: Claude Opus 5 --- .../plans/2026-08-01-landing-graph-step1.md | 1136 +++++++++++++++++ 1 file changed, 1136 insertions(+) create mode 100644 docs/superpowers/plans/2026-08-01-landing-graph-step1.md diff --git a/docs/superpowers/plans/2026-08-01-landing-graph-step1.md b/docs/superpowers/plans/2026-08-01-landing-graph-step1.md new file mode 100644 index 00000000..ed4c813a --- /dev/null +++ b/docs/superpowers/plans/2026-08-01-landing-graph-step1.md @@ -0,0 +1,1136 @@ +# Landing Interactive Graph (step 1) Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace the 340vh scroll-jacked `HowItWorks` section with an interactive knowledge-graph demo the visitor manipulates, and delete the old six-row feature catalog. + +**Architecture:** A pure-data fixture module (three hand-authored course graphs), a pure-math layout module (deterministic radial layout + a helical entry path), and one client component that composes them. No backend, no network, no LLM. The component lazy-loads below the fold with SSR kept on so crawlers still receive its copy. + +**Tech Stack:** Next.js 16 App Router, React, TypeScript, inline SVG (no new dependency), vitest + @testing-library/react, Playwright. + +**Scope:** This is step 1 of `docs/superpowers/specs/2026-08-01-landing-below-hero-design.md`. Sections 2–5 of that spec (bands, bento, seven surface recreations) are step 2 and get their own plan. At the end of this plan the page is coherent: hero → graph → CTA → footer. + +## Global Constraints + +- Hero, nav, and intro overlay in `frontend/src/app/(public)/page.tsx` are **untouched**. So are `SignInModal` and the beta/newsletter modal. +- **No new npm dependency.** Rendering is inline SVG; framer-motion is not used by the new component. +- All randomness and clock reads go through `@/lib/testMode` (`random()`, `now()`), never `Math.random()` / `Date.now()` — the E2E lane sets `NEXT_PUBLIC_TEST_MODE=1` and requires a deterministic DOM. +- Under `prefers-reduced-motion: reduce` **or** `IS_TEST_MODE`, the graph parks on a **complete, laid-out, readable** frame — never blank, never mid-assembly. +- New CSS lives inside the `.landing-page` scope in `frontend/src/app/globals.css`. Do not redefine design tokens outside that scope (`docs/frontend-rhythm-audit.md` — this is the documented cause of the pre-auth/app-shell drift bugs). +- Any `