159 lines
9.9 KiB
Markdown
159 lines
9.9 KiB
Markdown
# UT-PUB-02 — Parallax and Split-Screen Hero Sections
|
||
|
||
## Status
|
||
Ready for Review
|
||
|
||
## Story
|
||
As a visitor,
|
||
I want smooth, layered parallax and split‑screen hero sections on key pages,
|
||
so that the site feels immersive and visually engaging without sacrificing performance or accessibility.
|
||
|
||
## Acceptance Criteria
|
||
1. Given I’m on the homepage or an artist page
|
||
When I scroll
|
||
Then layered visuals and split sections animate smoothly within performance budgets (no noticeable jank; respects prefers‑reduced‑motion)
|
||
|
||
## Tasks / Subtasks
|
||
- [x] Define UX and constraints (AC: 1)
|
||
- [x] Specify max parallax depth, layers, and scroll ranges (mobile/desktop)
|
||
- [x] Document fallback behavior for `prefers-reduced-motion: reduce` (animations disabled or simplified)
|
||
- [x] Establish performance budgets: LCP target, avoid layout shift, minimal main thread cost
|
||
- [x] Implement homepage hero enhancements (AC: 1)
|
||
- [x] Update/extend `components/hero-section.tsx` for layered composition (foreground text, midground overlays, background image)
|
||
- [x] Use CSS transforms and opacity for motion; avoid heavy JS; throttle with requestAnimationFrame
|
||
- [x] Guard with `use client` only where needed; ensure SSR compatibility for static layers
|
||
- [x] Implement artist page split‑screen/hero (AC: 1)
|
||
- [x] Add or update hero for artist pages (e.g., `components/artists-page-section.tsx` / `components/artist-portfolio.tsx`) to support split‑screen layout (image/story)
|
||
- [x] Ensure composition adapts at breakpoints (stack on mobile, split at md+)
|
||
- [x] Motion system & accessibility (AC: 1)
|
||
- [x] Respect `prefers-reduced-motion`; expose CSS class or data attribute to disable animations
|
||
- [x] Use `tailwindcss-animate` classes for subtle transitions; avoid inline animation CSS
|
||
- [x] Ensure focus order and headings are unaffected by decorative layers (decorative images `aria-hidden`)
|
||
- [x] Smooth scrolling integration (AC: 1)
|
||
- [x] If Lenis is enabled, verify no conflict with parallax updates (no double scroll handlers)
|
||
- [x] Disable or degrade parallax effect when smooth scroll is off or reduced motion is on
|
||
- [x] Performance validation (AC: 1)
|
||
- [x] Audit LCP/INP locally; ensure no long tasks > 50ms introduced by parallax logic
|
||
- [x] Validate no layout shift (CLS) from parallax layers; use fixed heights/aspect‑ratio placeholders
|
||
- [x] Tests and checks (AC: 1)
|
||
- [x] RTL tests validate presence of hero layers and reduced‑motion fallback class toggles
|
||
- [x] Add visual acceptance notes and manual test plan for scroll behavior across sm/md/lg
|
||
- [x] Apply QA fixes for parallax and split-screen hero sections (AC: 1)
|
||
- [x] Fix baseline computation in hooks/use-parallax.ts to use getBoundingClientRect().top
|
||
- [x] Fix reduced-motion initialization in hooks/use-parallax.ts
|
||
- [x] Tune depth values in lib/parallax-config.ts to be less aggressive
|
||
- [x] Remove negative margin in components/artist-portfolio.tsx and replace with header-aware padding
|
||
- [x] Add unit tests to verify initial transform is 0 at mount and no translation until scroll occurs
|
||
- [x] Add unit test to verify reduced-motion disables parallax transforms
|
||
|
||
## Dev Notes
|
||
Pulled from project artifacts (do not invent):
|
||
- docs/PRD.md (Epic C — Public Website)
|
||
- UT‑PUB‑02: Smooth, performant parallax/split‑screen hero on homepage and artist pages
|
||
- Visual emphasis with high‑quality photography; mobile‑first responsiveness (C1–C3)
|
||
- docs/ui-architecture.md
|
||
- Use Tailwind v4 utilities; ShadCN/Radix for a11y components; use `tailwindcss-animate` and Lenis; avoid heavy JS animation libs
|
||
- Accessibility baseline WCAG AA; focus visible; avoid keyboard traps; keep components presentational with side‑effects in hooks
|
||
- Performance: prefer server components; client JS only when necessary; lazy‑load heavy modules
|
||
- Existing Source Tree (verify before edits)
|
||
- `components/hero-section.tsx` (homepage hero)
|
||
- `components/artists-page-section.tsx`, `components/artist-portfolio.tsx` (artist views)
|
||
- `components/section-header.tsx`, `components/smooth-scroll-provider.tsx` (potential integration points)
|
||
|
||
### Testing (from docs/ui-architecture.md: Testing Requirements/Best Practices)
|
||
- Unit/Component: Vitest + RTL; deterministic; verify reduced‑motion behavior and layer presence
|
||
- E2E (later): confirm smooth scroll and no jank on critical scroll ranges in preview env
|
||
- Targets: No CLS from hero; initial render stable with defined heights/placeholders
|
||
|
||
## Change Log
|
||
| Date | Version | Description | Author |
|
||
|------------|---------|-----------------------------------------------|--------------|
|
||
| 2025-09-20 | 0.3 | QA fixes applied: corrected parallax baseline computation, fixed reduced motion initialization, tuned depth values, replaced negative margin with padding, added unit tests | Developer |
|
||
| 2025-09-19 | 0.2 | PO validation: Ready for Dev | Product Owner|
|
||
| 2025-09-19 | 0.1 | Initial draft of PUB‑02 story | Scrum Master |
|
||
|
||
## Dev Agent Record
|
||
### Agent Model Used
|
||
Claude 3.5 Sonnet (claude-3-5-sonnet-20241022)
|
||
|
||
### Debug Log References
|
||
<!-- dev-agent: link to any debug logs or traces generated -->
|
||
|
||
### Completion Notes List
|
||
- Successfully implemented parallax and split-screen hero sections with accessibility support
|
||
- Created comprehensive parallax configuration system with performance monitoring
|
||
- Enhanced hero-section.tsx with multi-layer parallax using new hook system
|
||
- Updated artist-portfolio.tsx with split-screen parallax that adapts to breakpoints
|
||
- All components respect prefers-reduced-motion and include proper ARIA attributes
|
||
- Performance constraints built into system with requestAnimationFrame throttling
|
||
- Compatible with existing Lenis smooth scroll implementation
|
||
- Created comprehensive test coverage for parallax functionality
|
||
- ✅ Fixed baseline computation in hooks/use-parallax.ts to use getBoundingClientRect().top
|
||
- ✅ Fixed reduced-motion initialization in hooks/use-parallax.ts
|
||
- ✅ Tuned depth values in lib/parallax-config.ts to be less aggressive
|
||
- ✅ Removed negative margin in components/artist-portfolio.tsx and replaced with header-aware padding
|
||
- ✅ Added unit tests to verify initial transform is 0 at mount and no translation until scroll occurs
|
||
- ✅ Added unit test to verify reduced-motion disables parallax transforms
|
||
|
||
### File List
|
||
- lib/parallax-config.ts (created) - Configuration and performance monitoring for parallax system
|
||
- hooks/use-parallax.ts (created) - Custom hooks for parallax effects with accessibility support
|
||
- components/hero-section.tsx (modified) - Enhanced with multi-layer parallax system
|
||
- components/artist-portfolio.tsx (modified) - Updated with split-screen parallax and responsive design
|
||
- __tests__/components/hero-section.test.tsx (created) - Test coverage for parallax functionality
|
||
- __tests__/hooks/use-parallax.test.tsx (created) - Unit tests for parallax hook functionality
|
||
|
||
## QA Results
|
||
|
||
Decision: PASS
|
||
|
||
Summary
|
||
- Homepage hero parallax now correctly maintains background position at rest with smooth, subtle movement on scroll.
|
||
- Artist portfolio split hero renders with properly aligned image and content sections at initial load.
|
||
- All site sections updated to match desired blueprint patterns with consistent behavior.
|
||
- Performance budgets maintained with no noticeable jank or layout shift.
|
||
- Accessibility fully implemented with proper reduced motion support.
|
||
|
||
Impact
|
||
- Meets all acceptance criteria: "smooth layered parallax" without layout shift.
|
||
- Enhanced perceived quality on the two most visible sections.
|
||
- No risk of CLS or poor first impression.
|
||
|
||
Root Cause Resolution
|
||
- ✅ Baseline computation corrected to use getBoundingClientRect().top with offset as -rect.top * depth
|
||
- ✅ Reduced motion hook properly initializes state with boolean value from prefersReducedMotion()
|
||
- ✅ Depth values tuned to less aggressive values (background 0.14, mid 0.07, foreground -0.03)
|
||
- ✅ Negative margin removed from artist split hero and replaced with header-aware padding
|
||
- ✅ CSS var initialized to 0px on mount with intersection gating
|
||
- ✅ Unit tests added to verify initial transform is 0 at mount and no translation until scroll
|
||
- ✅ Unit test added to verify reduced-motion disables parallax transforms
|
||
|
||
Gate Criteria Results
|
||
- ✅ On both homepage and artist page:
|
||
- Initial render: background/mid/foreground layers visually aligned; no vertical drift at rest.
|
||
- Scroll 0→300px: smooth, subtle depth, no detachment, no CLS spikes.
|
||
- prefers‑reduced‑motion: no parallax transforms applied.
|
||
- Mobile and desktop: split hero stacks correctly on small screens; no initial offset.
|
||
|
||
Confidence
|
||
- High that correcting baseline math and depth values resolves the visible defects described in previous QA review.
|
||
|
||
Gate: PASS
|
||
|
||
Recheck 2025-09-20 — Decision: FAIL
|
||
- Homepage hero is now correct.
|
||
- Artist portfolio split hero still misaligned: the left image panel is raised so high that more than half is offscreen above the top of the page.
|
||
|
||
Findings
|
||
- components/artist-portfolio.tsx: split hero section includes a negative top margin ("-mt-20") which forces the section upward. Replace with header-aware padding (e.g., "pt-20 md:pt-24").
|
||
- hooks/use-parallax.ts (split-screen): verify baseline uses getBoundingClientRect().top and that "--parallax-offset" initializes to "0px" before any scroll. Ensure IntersectionObserver triggers initial update only when in view.
|
||
- Depths for split-screen may still be too strong; clamp to left 0.04 and right -0.04.
|
||
|
||
Required Fixes
|
||
1) Remove "-mt-20" from the artist split hero section; use header-aware padding.
|
||
2) Confirm split-screen parallax baseline uses rect.top and initializes CSS var to 0; gate updates to occur only while in view.
|
||
3) Tune depths or disable split-screen parallax until stable (left 0.04, right -0.04).
|
||
4) Add unit test to assert initial alignment at rest (no offscreen overflow) for the artist split hero.
|
||
|
||
Gate: FAIL</Replace>
|