diff --git a/.gsd/milestones/M009/M009-ROADMAP.md b/.gsd/milestones/M009/M009-ROADMAP.md index 0c0785f..1f74de6 100644 --- a/.gsd/milestones/M009/M009-ROADMAP.md +++ b/.gsd/milestones/M009/M009-ROADMAP.md @@ -6,6 +6,6 @@ The homepage is Chrysopedia's front door. Right now it's a search box — functi ## Slice Overview | ID | Slice | Risk | Depends | Done | After this | |----|-------|------|---------|------|------------| -| S01 | Homepage Hero & Value Proposition | medium | — | ⬜ | Homepage shows tagline, value description, how-it-works steps, Start Exploring CTA, and popular topic quick-links above the fold | +| S01 | Homepage Hero & Value Proposition | medium | — | ✅ | Homepage shows tagline, value description, how-it-works steps, Start Exploring CTA, and popular topic quick-links above the fold | | S02 | About Page | low | — | ⬜ | About page at /about explains what Chrysopedia is, how content is extracted, and who maintains it. Link visible in footer. | | S03 | Featured Content & Content Teasers | low | S01 | ⬜ | Homepage shows a featured technique spotlight and Recently Added section with enriched cards | diff --git a/.gsd/milestones/M009/slices/S01/S01-SUMMARY.md b/.gsd/milestones/M009/slices/S01/S01-SUMMARY.md new file mode 100644 index 0000000..86c3383 --- /dev/null +++ b/.gsd/milestones/M009/slices/S01/S01-SUMMARY.md @@ -0,0 +1,81 @@ +--- +id: S01 +parent: M009 +milestone: M009 +provides: + - Homepage hero section with tagline, value prop, how-it-works, CTA — S03 builds on this layout for featured content +requires: + [] +affects: + - S03 +key_files: + - frontend/src/pages/Home.tsx + - frontend/src/App.css +key_decisions: + - Used cyan accent numbered circles for how-it-works steps to match existing design language + - Used uppercase secondary-text heading for Popular Topics to differentiate from primary content hierarchy + - Popular topics pills link to /search?q={topic}&scope=topics rather than a dedicated topic detail page +patterns_established: + - Homepage content sections use BEM naming under .home- prefix (home-hero__title, home-how-it-works__step, home-popular-topics) + - Optional data-driven sections (popular topics) silently hide on API error — no error UI for non-critical homepage enrichment +observability_surfaces: + - none +drill_down_paths: + - .gsd/milestones/M009/slices/S01/tasks/T01-SUMMARY.md + - .gsd/milestones/M009/slices/S01/tasks/T02-SUMMARY.md +duration: "" +verification_result: passed +completed_at: 2026-03-31T05:38:05.139Z +blocker_discovered: false +--- + +# S01: Homepage Hero & Value Proposition + +**Homepage now shows tagline, value proposition, 3-step how-it-works grid, Start Exploring CTA, and popular topic quick-links — all above the fold.** + +## What Happened + +The homepage previously had an empty h1 and only a subtitle with search bar. Two tasks transformed it into a proper landing experience: + +**T01** added the hero tagline "Production Knowledge, Distilled", a value proposition paragraph explaining what Chrysopedia does, a 3-column how-it-works grid (Creators Share Techniques → AI Extracts Key Moments → You Find Answers Fast) with cyan accent numbered circles, and a prominent "Start Exploring" CTA button linking to /topics. All styling uses existing CSS custom properties. Responsive stacking at 640px. + +**T02** added a Popular Topics section that fetches from the existing topics API, flattens all sub_topics across categories, sorts by technique_count descending, takes the top 8, and renders them as clickable pill links navigating to /search?q={topic}&scope=topics. Section is hidden when no data or API error — graceful degradation. CSS uses the existing pill token system with bordered hover state. + +Both tasks touched only Home.tsx and App.css. No new dependencies, no API changes, no backend work required. + +## Verification + +Frontend build passes with zero errors (46 modules transformed, 52KB CSS, 224KB JS). Verified all planned elements present in source: h1 tagline, value-prop paragraph, how-it-works grid with 3 steps, CTA link to /topics, popularTopics state/fetch/render, pill links with search scope. CSS classes confirmed present for all new components including responsive rules. + +## Requirements Advanced + +None. + +## Requirements Validated + +None. + +## New Requirements Surfaced + +None. + +## Requirements Invalidated or Re-scoped + +None. + +## Deviations + +T02 removed an unused TopicCategory type import that caused TS6133 — minor cleanup, no functional impact. + +## Known Limitations + +Popular topics section fetches the full topics list and filters client-side. Fine for current dataset size but would benefit from a dedicated API endpoint if topic count grows significantly. + +## Follow-ups + +None. + +## Files Created/Modified + +- `frontend/src/pages/Home.tsx` — Added hero tagline, value proposition, how-it-works grid, CTA button, and popular topics pill section with API fetch +- `frontend/src/App.css` — Added styles for value-prop, how-it-works grid, CTA button, popular topics pills, and responsive breakpoints diff --git a/.gsd/milestones/M009/slices/S01/S01-UAT.md b/.gsd/milestones/M009/slices/S01/S01-UAT.md new file mode 100644 index 0000000..b1d993a --- /dev/null +++ b/.gsd/milestones/M009/slices/S01/S01-UAT.md @@ -0,0 +1,45 @@ +# S01: Homepage Hero & Value Proposition — UAT + +**Milestone:** M009 +**Written:** 2026-03-31T05:38:05.139Z + +## UAT: Homepage Hero & Value Proposition + +### Preconditions +- Chrysopedia stack running (web UI accessible at configured URL) +- At least one topic with sub-topics exists in the database (for popular topics to render) + +### Test 1: Hero Content Visible +1. Navigate to the homepage (/) +2. **Expected:** Page shows heading "Production Knowledge, Distilled" +3. **Expected:** Below the heading, a paragraph explains what Chrysopedia does — mentions extracting techniques from creator tutorials +4. **Expected:** Search bar remains visible and prominent + +### Test 2: How-It-Works Grid +1. On the homepage, locate the how-it-works section +2. **Expected:** Three steps displayed in a row (desktop): (1) Creators Share Techniques, (2) AI Extracts Key Moments, (3) You Find Answers Fast +3. **Expected:** Each step has a numbered circle with cyan accent color and a short description +4. Resize browser to <640px width +5. **Expected:** Steps stack vertically + +### Test 3: Start Exploring CTA +1. On the homepage, locate the "Start Exploring" button +2. Click the button +3. **Expected:** Navigates to /topics page + +### Test 4: Popular Topics Pills +1. Navigate back to homepage (/) +2. **Expected:** A "Popular Topics" section appears with up to 8 pill/chip links +3. **Expected:** Pills are ordered by technique count (most popular first) +4. Click any topic pill +5. **Expected:** Navigates to /search?q={topic_name}&scope=topics with relevant results + +### Test 5: Popular Topics — Empty State +1. If no topics exist in the database (or API is down), navigate to homepage +2. **Expected:** Popular Topics section is completely hidden — no heading, no empty container, no error message + +### Test 6: Visual Hierarchy +1. On desktop (>768px), load the homepage +2. **Expected:** Hero title and search bar are visible without scrolling +3. **Expected:** How-it-works section and CTA are below but reachable with minimal scroll +4. **Expected:** Popular topics pills visually complement but don't compete with the search bar diff --git a/.gsd/milestones/M009/slices/S01/tasks/T02-VERIFY.json b/.gsd/milestones/M009/slices/S01/tasks/T02-VERIFY.json new file mode 100644 index 0000000..7677895 --- /dev/null +++ b/.gsd/milestones/M009/slices/S01/tasks/T02-VERIFY.json @@ -0,0 +1,16 @@ +{ + "schemaVersion": 1, + "taskId": "T02", + "unitId": "M009/S01/T02", + "timestamp": 1774935430315, + "passed": true, + "discoverySource": "task-plan", + "checks": [ + { + "command": "cd frontend", + "exitCode": 0, + "durationMs": 6, + "verdict": "pass" + } + ] +} diff --git a/.gsd/milestones/M009/slices/S02/S02-PLAN.md b/.gsd/milestones/M009/slices/S02/S02-PLAN.md index f0303b2..e91d8ad 100644 --- a/.gsd/milestones/M009/slices/S02/S02-PLAN.md +++ b/.gsd/milestones/M009/slices/S02/S02-PLAN.md @@ -1,6 +1,10 @@ # S02: About Page -**Goal:** Project credibility — users can learn who made this and why +**Goal:** About page at /about explains what Chrysopedia is, how content is extracted, and who maintains it. Footer link navigates to it. **Demo:** After this: About page at /about explains what Chrysopedia is, how content is extracted, and who maintains it. Link visible in footer. ## Tasks +- [x] **T01: Added /about page with three content sections (what, how, who) and an About link in the footer** — Create the About.tsx page component with three content sections (what Chrysopedia is, how content is extracted, who maintains it), add a /about route in App.tsx, add an About link in AppFooter.tsx, and add .about-* styles in App.css following existing BEM and CSS custom property patterns. + - Estimate: 30m + - Files: frontend/src/pages/About.tsx, frontend/src/App.tsx, frontend/src/components/AppFooter.tsx, frontend/src/App.css + - Verify: cd frontend && npx tsc --noEmit && npm run build diff --git a/.gsd/milestones/M009/slices/S02/S02-RESEARCH.md b/.gsd/milestones/M009/slices/S02/S02-RESEARCH.md new file mode 100644 index 0000000..f13f3fa --- /dev/null +++ b/.gsd/milestones/M009/slices/S02/S02-RESEARCH.md @@ -0,0 +1,40 @@ +# S02 Research — About Page + +## Summary + +Static informational page at `/about` explaining what Chrysopedia is, how content is extracted, and who maintains it. No backend work. Three changes: new page component, new route in App.tsx, footer link. + +## Recommendation + +Follow existing page patterns exactly. This is the simplest possible slice — a single static React component with CSS, wired into the router and linked from the footer. + +## Implementation Landscape + +### Files to Create +- `frontend/src/pages/About.tsx` — static page component + +### Files to Modify +- `frontend/src/App.tsx` — add `} />` +- `frontend/src/components/AppFooter.tsx` — add "About" link (use react-router-dom `Link`, not ``) +- `frontend/src/App.css` — add `.about-*` styles + +### Existing Patterns to Follow +- **Page structure:** Wrap in a container div with page-specific class (e.g. `
`). See Home.tsx for hero/section pattern. +- **Routing:** App.tsx uses `react-router-dom` `Routes`/`Route`. Import lazy or direct, add `} />`. +- **Footer:** `AppFooter.tsx` currently has version info, build date, commit hash, and GitHub link. Add an "About" `` before or after the GitHub link, with the same `app-footer__sep` separator pattern. +- **CSS variables:** All colors use `var(--color-*)` custom properties defined in `:root` in App.css (77 tokens per D017). Use `--color-text-primary`, `--color-text-secondary`, `--color-text-muted`, `--color-surface-secondary`, `--color-accent`, `--color-border` etc. +- **BEM-ish naming:** Classes follow `block__element` pattern (e.g. `home-hero__title`, `nav-card__desc`). + +### Content for the About Page +The roadmap specifies three content areas: +1. **What Chrysopedia is** — a knowledge base of music production techniques extracted from creator tutorials +2. **How content is extracted** — mirrors the Home "how it works" 3-step flow (creators share → AI extracts → you search), but with more detail about the pipeline (transcription, LLM extraction, review, synthesis) +3. **Who maintains it** — link to xpltdco GitHub org, note it's an XPLTD project + +### Verification +- `cd frontend && npx tsc --noEmit` — zero TypeScript errors +- `cd frontend && npm run build` — production build succeeds +- Visual: navigate to `/about` in browser, confirm content renders, confirm footer link works + +### Natural Task Decomposition +This is a single-task slice. Creating the component, adding the route, adding the footer link, and adding CSS are tightly coupled and trivial — splitting further adds overhead without value. One task: "Implement About page with route and footer link." diff --git a/.gsd/milestones/M009/slices/S02/tasks/T01-PLAN.md b/.gsd/milestones/M009/slices/S02/tasks/T01-PLAN.md new file mode 100644 index 0000000..037bad6 --- /dev/null +++ b/.gsd/milestones/M009/slices/S02/tasks/T01-PLAN.md @@ -0,0 +1,27 @@ +--- +estimated_steps: 1 +estimated_files: 4 +skills_used: [] +--- + +# T01: Implement About page with route and footer link + +Create the About.tsx page component with three content sections (what Chrysopedia is, how content is extracted, who maintains it), add a /about route in App.tsx, add an About link in AppFooter.tsx, and add .about-* styles in App.css following existing BEM and CSS custom property patterns. + +## Inputs + +- ``frontend/src/App.tsx` — existing routing structure to add /about route` +- ``frontend/src/components/AppFooter.tsx` — existing footer to add About link` +- ``frontend/src/App.css` — existing CSS custom properties and BEM patterns` +- ``frontend/src/pages/Home.tsx` — reference for page component structure and hero/section patterns` + +## Expected Output + +- ``frontend/src/pages/About.tsx` — new About page component with three content sections` +- ``frontend/src/App.tsx` — modified with /about route and About import` +- ``frontend/src/components/AppFooter.tsx` — modified with About link using react-router-dom Link` +- ``frontend/src/App.css` — modified with .about-* styles` + +## Verification + +cd frontend && npx tsc --noEmit && npm run build diff --git a/.gsd/milestones/M009/slices/S02/tasks/T01-SUMMARY.md b/.gsd/milestones/M009/slices/S02/tasks/T01-SUMMARY.md new file mode 100644 index 0000000..99843a4 --- /dev/null +++ b/.gsd/milestones/M009/slices/S02/tasks/T01-SUMMARY.md @@ -0,0 +1,81 @@ +--- +id: T01 +parent: S02 +milestone: M009 +provides: [] +requires: [] +affects: [] +key_files: ["frontend/src/pages/About.tsx", "frontend/src/App.tsx", "frontend/src/components/AppFooter.tsx", "frontend/src/App.css"] +key_decisions: ["Used CSS counter-based numbered pipeline steps rather than manual numbering for the extraction pipeline section"] +patterns_established: [] +drill_down_paths: [] +observability_surfaces: [] +duration: "" +verification_result: "npx tsc --noEmit passed with zero errors. npm run build produced the production bundle successfully (47 modules, no warnings)." +completed_at: 2026-03-31T05:41:48.153Z +blocker_discovered: false +--- + +# T01: Added /about page with three content sections (what, how, who) and an About link in the footer + +> Added /about page with three content sections (what, how, who) and an About link in the footer + +## What Happened +--- +id: T01 +parent: S02 +milestone: M009 +key_files: + - frontend/src/pages/About.tsx + - frontend/src/App.tsx + - frontend/src/components/AppFooter.tsx + - frontend/src/App.css +key_decisions: + - Used CSS counter-based numbered pipeline steps rather than manual numbering for the extraction pipeline section +duration: "" +verification_result: passed +completed_at: 2026-03-31T05:41:48.153Z +blocker_discovered: false +--- + +# T01: Added /about page with three content sections (what, how, who) and an About link in the footer + +**Added /about page with three content sections (what, how, who) and an About link in the footer** + +## What Happened + +Created About.tsx with three sections: what Chrysopedia is, a five-step pipeline breakdown explaining how content is extracted, and a maintainer section linking to the xpltd GitHub org and repo. Added the /about route in App.tsx between admin routes and the fallback. Added an About link as the last item in AppFooter.tsx using react-router-dom Link. Added .about-* styles in App.css following existing BEM and custom property patterns, including a responsive breakpoint for the hero title. + +## Verification + +npx tsc --noEmit passed with zero errors. npm run build produced the production bundle successfully (47 modules, no warnings). + +## Verification Evidence + +| # | Command | Exit Code | Verdict | Duration | +|---|---------|-----------|---------|----------| +| 1 | `cd frontend && npx tsc --noEmit` | 0 | ✅ pass | 2200ms | +| 2 | `cd frontend && npm run build` | 0 | ✅ pass | 1200ms | + + +## Deviations + +None. + +## Known Issues + +None. + +## Files Created/Modified + +- `frontend/src/pages/About.tsx` +- `frontend/src/App.tsx` +- `frontend/src/components/AppFooter.tsx` +- `frontend/src/App.css` + + +## Deviations +None. + +## Known Issues +None. diff --git a/frontend/src/App.css b/frontend/src/App.css index 4816e47..b475eab 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -3354,3 +3354,126 @@ a.app-footer__repo:hover { gap: 0.3rem; text-decoration: none; } + +/* ── About page ───────────────────────────────────────────────────────────── */ + +.about { + max-width: 44rem; + margin: 0 auto; + padding: 2rem 1.5rem 3rem; +} + +.about-hero { + text-align: center; + margin-bottom: 2.5rem; +} + +.about-hero__title { + font-size: 2rem; + font-weight: 700; + color: var(--color-text-primary); + margin: 0 0 0.5rem; +} + +.about-hero__subtitle { + font-size: 1.05rem; + color: var(--color-text-secondary); + margin: 0; +} + +.about-section { + margin-bottom: 2rem; +} + +.about-section__heading { + font-size: 1.25rem; + font-weight: 600; + color: var(--color-text-primary); + margin: 0 0 0.75rem; +} + +.about-section__text { + color: var(--color-text-secondary); + line-height: 1.7; + margin: 0 0 0.75rem; +} + +.about-pipeline { + list-style: none; + counter-reset: pipeline; + padding: 0; + margin: 1rem 0; + display: flex; + flex-direction: column; + gap: 0.75rem; +} + +.about-pipeline__step { + counter-increment: pipeline; + display: flex; + align-items: baseline; + gap: 0.75rem; + color: var(--color-text-secondary); + line-height: 1.6; + padding: 0.75rem 1rem; + background: var(--color-bg-surface); + border-radius: 0.5rem; + border: 1px solid var(--color-border); +} + +.about-pipeline__step::before { + content: counter(pipeline); + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.5rem; + height: 1.5rem; + font-size: 0.75rem; + font-weight: 700; + color: var(--color-accent); + background: var(--color-accent-subtle); + border-radius: 50%; + flex-shrink: 0; +} + +.about-pipeline__step strong { + color: var(--color-text-primary); +} + +.about-link { + color: var(--color-accent); + text-decoration: none; + transition: color 0.15s; +} + +.about-link:hover { + color: var(--color-accent-hover); +} + +.about-cta { + text-align: center; + margin-top: 2.5rem; +} + +.about-cta__btn { + display: inline-block; +} + +/* Footer about link */ + +.app-footer__about { + color: var(--color-text-muted); + text-decoration: none; + transition: color 0.15s; +} + +a.app-footer__about:hover, +.app-footer__about:hover { + color: var(--color-accent); +} + +@media (max-width: 600px) { + .about-hero__title { + font-size: 1.5rem; + } +} diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index e92edb1..c22b061 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -7,6 +7,7 @@ import CreatorDetail from "./pages/CreatorDetail"; import TopicsBrowse from "./pages/TopicsBrowse"; import AdminReports from "./pages/AdminReports"; import AdminPipeline from "./pages/AdminPipeline"; +import About from "./pages/About"; import AdminDropdown from "./components/AdminDropdown"; import AppFooter from "./components/AppFooter"; @@ -43,6 +44,9 @@ export default function App() { } /> } /> + {/* Info routes */} + } /> + {/* Fallback */} } /> diff --git a/frontend/src/components/AppFooter.tsx b/frontend/src/components/AppFooter.tsx index e2899fa..9162e61 100644 --- a/frontend/src/components/AppFooter.tsx +++ b/frontend/src/components/AppFooter.tsx @@ -1,5 +1,7 @@ const REPO_URL = "https://github.com/xpltdco/chrysopedia"; +import { Link } from "react-router-dom"; + export default function AppFooter() { const commitUrl = __GIT_COMMIT__ !== "dev" @@ -37,6 +39,10 @@ export default function AppFooter() { > GitHub + · + + About + ); } diff --git a/frontend/src/pages/About.tsx b/frontend/src/pages/About.tsx new file mode 100644 index 0000000..4830581 --- /dev/null +++ b/frontend/src/pages/About.tsx @@ -0,0 +1,94 @@ +import { Link } from "react-router-dom"; + +export default function About() { + return ( +
+
+

About Chrysopedia

+

+ A structured knowledge base for music production techniques +

+
+ +
+

What Is Chrysopedia?

+

+ Chrysopedia turns long-form music production tutorials into a + searchable, structured knowledge base. Instead of scrubbing through + hours of video looking for the one technique you need, you can search + by topic, creator, or keyword and jump straight to the insight. +

+

+ The name comes from chrysopoeia — the art of transmutation. + We transmute raw video content into distilled, accessible knowledge. +

+
+ +
+

How Content Is Extracted

+

+ Videos are processed through a multi-stage pipeline that transcribes + audio, identifies key moments, classifies topics, and generates + structured technique pages — all using a combination of speech + recognition and large language models. +

+
    +
  1. + Transcription — Audio is converted to timestamped + text +
  2. +
  3. + Key Moment Detection — The transcript is analyzed + to find discrete techniques and insights +
  4. +
  5. + Topic Classification — Each moment is tagged with + categories and sub-topics +
  6. +
  7. + Page Generation — Structured technique pages are + written with context, steps, and creator attribution +
  8. +
  9. + Indexing — Content is embedded for semantic search +
  10. +
+

+ Every technique page links back to its source video and creator, + preserving attribution throughout. +

+
+ +
+

Who Maintains This

+

+ Chrysopedia is built and maintained by{" "} + + xpltd + + . The project is open source on{" "} + + GitHub + + . +

+
+ +
+ + Start Exploring + +
+
+ ); +} diff --git a/frontend/tsconfig.app.tsbuildinfo b/frontend/tsconfig.app.tsbuildinfo index 7db0d54..0bc3fdb 100644 --- a/frontend/tsconfig.app.tsbuildinfo +++ b/frontend/tsconfig.app.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/public-client.ts","./src/components/AdminDropdown.tsx","./src/components/AppFooter.tsx","./src/components/CategoryIcons.tsx","./src/components/CopyLinkButton.tsx","./src/components/CreatorAvatar.tsx","./src/components/ReportIssueModal.tsx","./src/pages/AdminPipeline.tsx","./src/pages/AdminReports.tsx","./src/pages/CreatorDetail.tsx","./src/pages/CreatorsBrowse.tsx","./src/pages/Home.tsx","./src/pages/SearchResults.tsx","./src/pages/TechniquePage.tsx","./src/pages/TopicsBrowse.tsx"],"version":"5.6.3"} \ No newline at end of file +{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/public-client.ts","./src/components/AdminDropdown.tsx","./src/components/AppFooter.tsx","./src/components/CategoryIcons.tsx","./src/components/CopyLinkButton.tsx","./src/components/CreatorAvatar.tsx","./src/components/ReportIssueModal.tsx","./src/pages/About.tsx","./src/pages/AdminPipeline.tsx","./src/pages/AdminReports.tsx","./src/pages/CreatorDetail.tsx","./src/pages/CreatorsBrowse.tsx","./src/pages/Home.tsx","./src/pages/SearchResults.tsx","./src/pages/TechniquePage.tsx","./src/pages/TopicsBrowse.tsx"],"version":"5.6.3"} \ No newline at end of file