From 0743d80b6a43cda177e76c8fb6be6b3017d12918 Mon Sep 17 00:00:00 2001 From: jlightner Date: Fri, 3 Apr 2026 05:52:47 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20Moved=20Table=20of=20Contents=20from=20?= =?UTF-8?q?main=20prose=20column=20to=20sidebar=20top;=20re=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "frontend/src/pages/TechniquePage.tsx" - "frontend/src/components/TableOfContents.tsx" - "frontend/src/App.css" GSD-Task: S04/T01 --- .gsd/DECISIONS.md | 1 + .gsd/milestones/M016/M016-ROADMAP.md | 2 +- .../milestones/M016/slices/S03/S03-SUMMARY.md | 86 +++++++++++++++++++ .gsd/milestones/M016/slices/S03/S03-UAT.md | 68 +++++++++++++++ .../M016/slices/S03/tasks/T02-VERIFY.json | 36 ++++++++ .gsd/milestones/M016/slices/S04/S04-PLAN.md | 42 ++++++++- .../M016/slices/S04/S04-RESEARCH.md | 75 ++++++++++++++++ .../M016/slices/S04/tasks/T01-PLAN.md | 40 +++++++++ .../M016/slices/S04/tasks/T01-SUMMARY.md | 78 +++++++++++++++++ .../M016/slices/S04/tasks/T02-PLAN.md | 40 +++++++++ alembic/versions/014_add_creator_avatar.py | 24 ++++++ backend/models.py | 3 + frontend/src/App.css | 42 ++++----- frontend/src/components/TableOfContents.tsx | 10 +-- frontend/src/pages/TechniquePage.tsx | 5 +- 15 files changed, 520 insertions(+), 32 deletions(-) create mode 100644 .gsd/milestones/M016/slices/S03/S03-SUMMARY.md create mode 100644 .gsd/milestones/M016/slices/S03/S03-UAT.md create mode 100644 .gsd/milestones/M016/slices/S03/tasks/T02-VERIFY.json create mode 100644 .gsd/milestones/M016/slices/S04/S04-RESEARCH.md create mode 100644 .gsd/milestones/M016/slices/S04/tasks/T01-PLAN.md create mode 100644 .gsd/milestones/M016/slices/S04/tasks/T01-SUMMARY.md create mode 100644 .gsd/milestones/M016/slices/S04/tasks/T02-PLAN.md create mode 100644 alembic/versions/014_add_creator_avatar.py diff --git a/.gsd/DECISIONS.md b/.gsd/DECISIONS.md index a33c8bd..16f9ba9 100644 --- a/.gsd/DECISIONS.md +++ b/.gsd/DECISIONS.md @@ -34,3 +34,4 @@ | D026 | | requirement | R033 | validated | Creators browse page shows "Last updated: Apr 2/3" per creator with techniques, omits for 0-technique creators. Homepage recently-added cards show subtle date stamps. Both verified live on ub01:8096. | Yes | agent | | D027 | | requirement | R034 | validated | Homepage renders stats block with real counts from the API: GET /api/v1/stats returns {"technique_count":21,"creator_count":7}, and the frontend scorecard displays "21 ARTICLES" and "7 CREATORS" in cyan-on-dark design. Visual and API verification both pass. | Yes | agent | | D028 | | requirement | R036 | validated | AdminDropdown.tsx now opens on hover at desktop widths (≥769px) via matchMedia guard with 150ms leave delay, while mobile retains tap-to-toggle. Build passes. Satisfies R036 criteria. | Yes | agent | +| D029 | | requirement | R039 | validated | Build output confirms favicon.svg, favicon-32.png, apple-touch-icon.png, og-image.png in dist/. index.html contains all required OG, Twitter card, and favicon meta tags. Inline SVG logo mark present in header. All slice plan verification checks pass. | Yes | agent | diff --git a/.gsd/milestones/M016/M016-ROADMAP.md b/.gsd/milestones/M016/M016-ROADMAP.md index 2541a0e..0add2cf 100644 --- a/.gsd/milestones/M016/M016-ROADMAP.md +++ b/.gsd/milestones/M016/M016-ROADMAP.md @@ -8,7 +8,7 @@ Modernize the public site's visual identity and reading experience: fix landing |----|-------|------|---------|------|------------| | S01 | Landing Page Visual Fixes | low | — | ✅ | Homepage has consistent 42rem max-width, unified spacing, rounded featured card, correct CTA button sizing. | | S02 | Pipeline Admin UI Fixes | low | — | ✅ | Pipeline admin: collapse toggle works, mobile cards truncate, chevrons between stages, filter button group right-aligned, creator dropdown populates. | -| S03 | Brand Minimum (Favicon, OG Tags, Logo) | low | — | ⬜ | Browser tab shows custom favicon. URL sharing produces preview card. Logo visible in header next to Chrysopedia. | +| S03 | Brand Minimum (Favicon, OG Tags, Logo) | low | — | ✅ | Browser tab shows custom favicon. URL sharing produces preview card. Logo visible in header next to Chrysopedia. | | S04 | ToC Modernization | medium | — | ⬜ | Technique page ToC: no counters, left accent bar, On this page heading, active section highlighting on scroll, sticky in sidebar. | | S05 | Sticky Reading Header | medium | S04 | ⬜ | Thin sticky bar appears when scrolling past article title, shows title + current section, slides in/out. | | S06 | Landing Page Personality Pass | low | S01, S03 | ⬜ | Homepage: animated stat count-up, consistent section headings, content above fold, header brand accent with logo. | diff --git a/.gsd/milestones/M016/slices/S03/S03-SUMMARY.md b/.gsd/milestones/M016/slices/S03/S03-SUMMARY.md new file mode 100644 index 0000000..4a69689 --- /dev/null +++ b/.gsd/milestones/M016/slices/S03/S03-SUMMARY.md @@ -0,0 +1,86 @@ +--- +id: S03 +parent: M016 +milestone: M016 +provides: + - favicon.svg and PNG assets in frontend/public/ + - OG/Twitter meta tags in index.html + - Inline SVG logo mark in header brand area +requires: + [] +affects: + - S06 +key_files: + - frontend/public/favicon.svg + - frontend/public/favicon-32.png + - frontend/public/apple-touch-icon.png + - frontend/public/og-image.png + - frontend/index.html + - frontend/src/App.tsx + - frontend/src/App.css +key_decisions: + - Generated PNG assets programmatically using Python stdlib to avoid external image tool dependencies + - Used favicon mark without background rect for inline header logo — decorative with aria-hidden +patterns_established: + - Brand assets in frontend/public/ with SVG primary + PNG fallback pattern + - Inline SVG logo mark with aria-hidden for decorative header elements +observability_surfaces: + - none +drill_down_paths: + - .gsd/milestones/M016/slices/S03/tasks/T01-SUMMARY.md + - .gsd/milestones/M016/slices/S03/tasks/T02-SUMMARY.md +duration: "" +verification_result: passed +completed_at: 2026-04-03T05:48:09.839Z +blocker_discovered: false +--- + +# S03: Brand Minimum (Favicon, OG Tags, Logo) + +**Added favicon (SVG + PNG fallback), apple-touch-icon, OG/Twitter social meta tags, and inline SVG logo mark in header.** + +## What Happened + +Two tasks delivered the full brand minimum. T01 created four static assets in frontend/public/ — an SVG favicon (stylized C arc + dot in #22d3ee on dark background), a 32px PNG fallback, a 180px apple-touch-icon, and a 1200×630 OG social image. All PNGs were generated programmatically using Python stdlib (struct + zlib) to avoid external image tool dependencies. index.html was updated with favicon link tags, OG meta tags (title, description, image, type), Twitter card tags (summary_large_image), and a description meta tag. T02 added the same arc+dot mark as an inline SVG in the header brand area (App.tsx), wrapped in a .app-header__logo span with aria-hidden for decorative semantics. The .app-header__brand container was updated to flex layout with gap for clean logo/text alignment at 24px height. Build passes cleanly (57 modules, 915ms). All assets copy to dist/ and all meta tags appear in the built index.html. + +## Verification + +Ran npm run build (exit 0, 915ms). Verified all 4 assets exist in dist/ (favicon.svg, favicon-32.png, apple-touch-icon.png, og-image.png). Grepped dist/index.html for all required patterns: rel="icon", og:title, og:description, og:image, twitter:card, name="description" — all present. Confirmed app-header__logo class in App.tsx and App.css, inline SVG present in App.tsx, and #22d3ee accent color in favicon.svg. + +## Requirements Advanced + +- R039 — Favicon, OG tags, Twitter card tags, description meta, and inline SVG logo all delivered and verified in build output. + +## Requirements Validated + +- R039 — Build produces favicon.svg, favicon-32.png, apple-touch-icon.png, og-image.png in dist/. index.html contains rel=icon, og:title, og:description, og:image, og:type, twitter:card, twitter:title, twitter:description, twitter:image, and meta description. Header shows inline SVG logo mark. + +## New Requirements Surfaced + +None. + +## Requirements Invalidated or Re-scoped + +None. + +## Deviations + +T01 switched from flat-list pixel generation to scanline-based with bounding-box culling for large PNG generation (OG image) after initial approach timed out. + +## Known Limitations + +OG image uses programmatically generated shapes rather than rendered text — social previews show the brand colors and mark but not the "Chrysopedia" wordmark. Adequate for initial brand presence; can be replaced with a designed asset later. + +## Follow-ups + +Replace programmatic PNGs with professionally designed assets when brand identity matures. Add per-page OG tags (technique pages should have unique og:title/og:description). + +## Files Created/Modified + +- `frontend/public/favicon.svg` — New: SVG favicon with stylized C arc + dot in #22d3ee +- `frontend/public/favicon-32.png` — New: 32px PNG favicon fallback +- `frontend/public/apple-touch-icon.png` — New: 180px Apple touch icon +- `frontend/public/og-image.png` — New: 1200x630 OG social sharing image +- `frontend/index.html` — Added favicon links, OG tags, Twitter card tags, description meta +- `frontend/src/App.tsx` — Added inline SVG logo mark in header brand area +- `frontend/src/App.css` — Added .app-header__logo styles, updated .app-header__brand to flex diff --git a/.gsd/milestones/M016/slices/S03/S03-UAT.md b/.gsd/milestones/M016/slices/S03/S03-UAT.md new file mode 100644 index 0000000..46631e7 --- /dev/null +++ b/.gsd/milestones/M016/slices/S03/S03-UAT.md @@ -0,0 +1,68 @@ +# S03: Brand Minimum (Favicon, OG Tags, Logo) — UAT + +**Milestone:** M016 +**Written:** 2026-04-03T05:48:09.839Z + +# S03 UAT: Brand Minimum (Favicon, OG Tags, Logo) + +## Preconditions +- Frontend built successfully (`cd frontend && npm run build`) +- App running (locally or via Docker on ub01:8096) + +## Test Cases + +### TC1: Favicon displays in browser tab +1. Open the site in a browser +2. **Expected:** Browser tab shows a cyan arc+dot mark on dark background (not the default browser/framework icon) +3. Check favicon source: right-click tab → inspect → should reference `/favicon.svg` + +### TC2: PNG favicon fallback +1. Open the site in a browser that doesn't support SVG favicons (or inspect network tab) +2. **Expected:** `/favicon-32.png` is available as 32x32 fallback +3. Verify: `curl -s http://localhost:8096/favicon-32.png | file -` → should report PNG image data + +### TC3: Apple touch icon +1. Inspect page source or `curl http://localhost:8096/apple-touch-icon.png | file -` +2. **Expected:** Valid 180x180 PNG returned + +### TC4: OG meta tags present for social sharing +1. View page source of the homepage +2. **Expected:** All of these meta tags present in ``: + - `` + - `` + - `` + - `` +3. Verify OG image accessible: `curl -sI http://localhost:8096/og-image.png` → 200 OK + +### TC5: Twitter card meta tags +1. View page source of the homepage +2. **Expected:** + - `` + - `` + - `` + - `` + +### TC6: Description meta tag +1. View page source +2. **Expected:** `` + +### TC7: Logo visible in header +1. Open any page on the site +2. **Expected:** A cyan arc+dot mark (~24px) appears to the left of "Chrysopedia" text in the header +3. The logo should be vertically centered with the text +4. The logo should NOT be announced by screen readers (aria-hidden) + +### TC8: Logo uses correct brand color +1. Inspect the inline SVG in the header +2. **Expected:** SVG paths use `#22d3ee` (cyan accent) — matching the favicon + +### Edge Cases + +### EC1: Social sharing preview +1. Paste the site URL into a social platform preview tool (e.g., Twitter Card Validator, Facebook Sharing Debugger, or opengraph.xyz) +2. **Expected:** Preview card shows "Chrysopedia" title, "Music production technique encyclopedia" description, and the OG image +3. **Note:** OG image URL must be absolute for external validators — current implementation uses relative `/og-image.png` which works when the site has a canonical URL configured + +### EC2: Mobile favicon +1. Open the site on iOS Safari and add to home screen +2. **Expected:** Home screen icon uses the apple-touch-icon (180px version) diff --git a/.gsd/milestones/M016/slices/S03/tasks/T02-VERIFY.json b/.gsd/milestones/M016/slices/S03/tasks/T02-VERIFY.json new file mode 100644 index 0000000..a53862f --- /dev/null +++ b/.gsd/milestones/M016/slices/S03/tasks/T02-VERIFY.json @@ -0,0 +1,36 @@ +{ + "schemaVersion": 1, + "taskId": "T02", + "unitId": "M016/S03/T02", + "timestamp": 1775195225292, + "passed": false, + "discoverySource": "task-plan", + "checks": [ + { + "command": "cd frontend", + "exitCode": 0, + "durationMs": 18, + "verdict": "pass" + }, + { + "command": "npm run build", + "exitCode": 254, + "durationMs": 99, + "verdict": "fail" + }, + { + "command": "grep -q 'app-header__logo' src/App.tsx", + "exitCode": 2, + "durationMs": 14, + "verdict": "fail" + }, + { + "command": "grep -q 'app-header__logo' src/App.css", + "exitCode": 2, + "durationMs": 11, + "verdict": "fail" + } + ], + "retryAttempt": 1, + "maxRetries": 2 +} diff --git a/.gsd/milestones/M016/slices/S04/S04-PLAN.md b/.gsd/milestones/M016/slices/S04/S04-PLAN.md index 9ba497e..d009232 100644 --- a/.gsd/milestones/M016/slices/S04/S04-PLAN.md +++ b/.gsd/milestones/M016/slices/S04/S04-PLAN.md @@ -1,6 +1,46 @@ # S04: ToC Modernization -**Goal:** Modernize technique page table of contents: remove numbered counters, add left accent bar, sentence-case heading, hover backgrounds, IntersectionObserver active section tracking, sticky positioning. +**Goal:** Technique page ToC: no counters, left accent bar, "On this page" heading, active section highlighting on scroll, sticky in sidebar. **Demo:** After this: Technique page ToC: no counters, left accent bar, On this page heading, active section highlighting on scroll, sticky in sidebar. ## Tasks +- [x] **T01: Moved Table of Contents from main prose column to sidebar top; replaced card/counter styling with left accent bar and hover backgrounds** — Move the TableOfContents render from inside technique-columns__main (inside technique-prose) to the top of technique-columns__sidebar. Restyle: remove CSS counters, remove card background, add left accent bar, rename heading to 'On this page', add hover background states on links. + +This slice owns R040 (Table of Contents Modernization). The ToC currently renders at line 425 of TechniquePage.tsx inside the v2 prose section. It needs to move to the sidebar div (line 470). Only render ToC in sidebar for v2 format pages. + +CSS changes in App.css (lines 2034–2108): +- Remove counter-reset, counter-increment, and ::before pseudo-elements +- Remove background/border card styling +- Add border-left: 2px solid var(--color-accent) accent bar +- Add hover background: var(--color-accent-subtle) on links +- Change .technique-toc__title text to be set by the component (not CSS) + +Component changes in TableOfContents.tsx: +- Change heading from 'Contents' to 'On this page' +- Change
    to