united-tattoo/docs/stories/pub-1-shadcn-ui-consistency.md

13 KiB
Raw Blame History

UT-PUB-01 — ShadCN UI Consistency Across Pages

Status

Ready for Review

Story

As a visitor,
I want the site to provide a consistent ShadCN-based UI across all pages,
so that navigation and interactions feel cohesive and predictable.

Acceptance Criteria

  1. Given any site page
    When I navigate and interact
    Then spacing, typography, components, and transitions are consistent

Tasks / Subtasks

  • Establish consistency audit across key pages (AC: 1)
    • Review /aftercare, /deposit, /terms, /privacy, /book, home, and artist-related pages for spacing/typography/component variance
    • Document variance list and map each to ShadCN primitive or composed component
  • Standardize typography and spacing scales (AC: 1)
    • Align to ShadCN/Tailwind scales per docs/ui-architecture.md "Styling Guidelines"
    • Normalize heading/body sizes and leading across templates/layouts
  • Replace/align components to ShadCN primitives where mismatched (AC: 1)
    • Identify ad-hoc buttons/inputs/cards and replace with registry-aligned ui/* components
    • Ensure variant management via cva() and class merging via cn()
  • Ensure consistent page skeletons and boundaries (AC: 1)
    • Provide/verify loading.tsx and error.tsx per key segments for consistent loading/error states
    • Verify shared page section wrappers (components/layouts or shared) for paddings, max-width, and breakpoints
  • Motion and transition alignment (AC: 1)
    • Use tailwindcss-animate for subtle transitions; avoid custom inline animation styles
    • Verify smooth scroll behavior is consistent where Lenis is used (if applicable to page)
  • Tests and checks (AC: 1)
    • Add RTL tests to verify consistent class patterns on representative pages/components
    • Add visual acceptance notes for spacing/typography on critical templates

Dev Notes

Pulled from project artifacts (do not invent):

  • docs/ui-architecture.md
    • Framework: Next.js 14 App Router with server components by default
    • UI: ShadCN UI + Radix primitives; Tailwind v4 utilities; cva() variants and cn() class merge
    • Styling Guidelines: Tailwind as primary styling, follow ShadCN spacing/typography tokens
    • Routing: Provide loading.tsx and error.tsx for key segments; use route groups for separation
    • Component Standards: Typed components, cva variants, consistent naming (kebab-case files, PascalCase components)
    • Testing Requirements: Vitest + RTL for components; deterministic tests; mock external dependencies
  • docs/PRD.md (Epic C — Public-Facing Website Experience)
    • C1: All pages follow ShadCN baseline; unify typography, spacing, and components
    • C2: Improve core public pages and ensure responsive, mobile-first behavior
  • Existing Source Tree (reference only; verify before edits)
    • app/ (App Router segments), components/ui/ (ShadCN primitives), components/* (composed/shared), styles/globals.css (Tailwind base)

Testing (from docs/ui-architecture.md: Testing Requirements/Best Practices)

  • Unit/Component: Vitest + RTL; Arrange-Act-Assert; deterministic; mock router/network
  • Structure: tests under tests/ with component and integration coverage
  • Goals: Verify applied class patterns for typographic scale and spacing, and presence of ShadCN primitives/variants in representative pages

Change Log

Date Version Description Author
2025-09-19 0.2 PO validation: Ready for Dev Product Owner
2025-09-19 0.1 Initial draft of PUB-01 story Scrum Master

Dev Agent Record

Agent Model Used

Kai (ui-designer) — Model: o3-mini-high

Debug Log References

  • .ai/debug-log.md (no new entries specific to this story)

Completion Notes List

  • Introduced ThemeProvider (next-themes) at app root with defaultTheme="dark" to ensure consistent token rendering across pages.
  • Implemented standardized motion transitions using tailwindcss-animate (animate-in fade-in-50 duration-300) with motion-reduce:animate-none safeguards on Alerts and Cards for Aftercare and Privacy pages.
  • Created SectionWrapper component to standardize page section paddings (px-8 lg:px-16) and applied it across Privacy and Aftercare sections for consistent layout.
  • Added motion-related RTL assertions to verify presence of animate-in and motion-reduce:animate-none.
  • Standardized Aftercare page:
    • Replaced hard-coded bg/text colors with ShadCN tokens (bg-background, text-foreground, text-muted-foreground).
    • Normalized Tabs, Alert, Card usage to registry defaults; removed ad-hoc bg-white/5, border-white/10 overrides.
    • Converted icon/text color cues to token-based (primary/accent/destructive where appropriate).
    • Fixed types (icon ComponentType, Tabs onValueChange) and removed unused imports.
  • Standardized Privacy page:
    • Replaced all ad-hoc color classes (bg-white/5, border-white/10, text-white, text-gray-300) with ShadCN tokens.
    • Normalized Card, Alert, Badge usage to registry defaults with consistent text-muted-foreground.
    • Fixed ESLint apostrophe issues using HTML entities (').
  • Mapped font tokens in globals.css to --font-source-sans and --font-playfair; added .font-playfair utility.
  • Fixed ESLint "any" in ClientLayout retry handler using unknown + type guard.
  • Created comprehensive loading.tsx and error.tsx files for all key segments:
    • /aftercare, /deposit, /terms, /privacy, /book, /artists, /artists/[id], /artists/[id]/book
    • All use ShadCN Skeleton and Alert primitives with consistent design tokens.
  • Added RTL tests for ShadCN UI consistency:
    • AftercarePage: Verifies ShadCN tokens, primitives (Tabs, Alert, Card), and absence of ad-hoc colors.
    • PrivacyPage: Verifies ShadCN tokens, primitives (Alert, Badge, Card), and consistent typography patterns.
    • All tests pass and validate proper ShadCN primitive usage and design token consistency.

File List

  • app/ClientLayout.tsx — add ThemeProvider, fix ESLint type
  • app/globals.css — map font tokens to Source Sans 3 / Playfair, add .font-playfair utility
  • components/aftercare-page.tsx — standardize to ShadCN tokens and primitives; type fixes
  • components/privacy-page.tsx — standardize to ShadCN tokens and primitives; fix ESLint issues
  • components/section-wrapper.tsx — standardize section paddings across pages
  • app/aftercare/loading.tsx — ShadCN Skeleton loading state
  • app/aftercare/error.tsx — ShadCN Alert error state
  • app/deposit/loading.tsx — ShadCN Skeleton loading state
  • app/deposit/error.tsx — ShadCN Alert error state
  • app/terms/loading.tsx — ShadCN Skeleton loading state
  • app/terms/error.tsx — ShadCN Alert error state
  • app/privacy/loading.tsx — ShadCN Skeleton loading state
  • app/privacy/error.tsx — ShadCN Alert error state
  • app/book/loading.tsx — ShadCN Skeleton loading state
  • app/book/error.tsx — ShadCN Alert error state
  • app/artists/loading.tsx — ShadCN Skeleton loading state
  • app/artists/error.tsx — ShadCN Alert error state
  • app/artists/[id]/loading.tsx — ShadCN Skeleton loading state
  • app/artists/[id]/error.tsx — ShadCN Alert error state
  • app/artists/[id]/book/loading.tsx — ShadCN Skeleton loading state
  • app/artists/[id]/book/error.tsx — ShadCN Alert error state
  • tests/components/aftercare-page.test.tsx — RTL tests for ShadCN UI consistency
  • tests/components/privacy-page.test.tsx — RTL tests for ShadCN UI consistency

QA Results

QA Review — Quinn (Test Architect & Quality Advisor) — 2025-09-20

Scope examined:

  • App Router segments inventory (app/*) for loading/error skeletons
  • ShadCN primitives inventory under components/ui/*
  • UI dependency set in package.json (radix, class-variance-authority, tailwindcss-animate, lucide-react)
  • Client scaffolding in app/ClientLayout.tsx (ThemeProvider, providers)
  • Representative page implementation in components/aftercare-page.tsx

Traceability to Acceptance Criteria:

  • AC-1 (Consistency across spacing, typography, components, transitions) maps to Tasks:
    • Consistency audit across key pages
    • Standardize typography/spacing scales
    • Replace/align components to ShadCN primitives
    • Ensure consistent loading/error skeletons
    • Motion/transition alignment
    • Tests/checks for representative pages

Findings:

  1. Segment skeletons (loading.tsx/error.tsx) — Gaps

    • Observed: Only app/error.tsx at root. No loading.tsx or segment-level error.tsx found for: /aftercare, /deposit, /terms, /privacy, /book, /artists (including [id] and [id]/book).
    • Impact: Inconsistent loading/error experiences across critical public routes; user-perceived polish degrades; testing for state patterns is harder.
    • Action: Add loading.tsx (use Skeleton from components/ui/skeleton) and error.tsx (Alert with variant="destructive") per listed segments.
  2. ShadCN primitives and composition — Generally strong

    • Inventory present: robust components/ui/* set (button, card, tabs, alert, toast/sonner, etc.). cva + cn in use (lib/utils.ts).
    • Representative page (/aftercare): Uses Card, Alert, Tabs correctly with design tokens (bg-background, text-foreground, text-muted-foreground).
    • Noted exception: Ad-hoc color "text-white" on an icon within Alert; prefer token-aligned color (e.g., text-foreground or rely on inherited color). This creates potential dark/light mismatch.
  3. Typography and spacing scales — Mostly aligned, needs explicit normalization

    • Fonts and tokens: ThemeProvider defaultTheme="dark" active; globals provide .font-playfair utility per Dev Notes.
    • Pages beyond /aftercare (deposit/terms/privacy/book/artists) not verified for consistent size/leading; standardize heading/body sizes per docs/ui-architecture.md.
    • Action: Document a definitive type ramp (e.g., text-sm/md/lg, leading-relaxed for body) and apply across templates/layouts.
  4. Motion and transitions — Library present, usage not standardized

    • tailwindcss-animate is installed; no consistent usage observed on Tabs/Alerts/Dialogs.
    • Action: Adopt subtle animations per ShadCN patterns (e.g., data-[state=open]:animate-in fade-in-50, zoom-in-95) and avoid custom inline animations.
  5. Tests and checks — Missing coverage for this storys goals

    • tests exists, but no RTL tests asserting class patterns/tokens on representative public pages for this story.
    • Action: Add at least 2 RTL tests:
      • AftercarePage: assert presence of Tabs primitives, tokens (bg-background, text-foreground, text-muted-foreground), and no ad-hoc color classes.
      • One additional page (e.g., /privacy or /deposit): assert standardized heading/body scale and ShadCN primitives usage (Button/Card/etc.).
  6. Accessibility — Generally positive with minor recommendations

    • Decorative hero image on /aftercare has alt=""; good. Icons likely decorative; add aria-hidden="true" for lucide icons where appropriate.
    • Ensure Alert titles/descriptions maintain programmatic association; current Alert usage appears aligned.

Risk profile (probability × impact):

  • Inconsistent skeletons across pages: High × Medium → Priority: High
  • Drifts in spacing/typography between pages: Medium × Medium-High → Priority: High
  • Ad-hoc color usage leading to theme mismatch: Medium × Medium → Priority: Medium
  • Missing RTL tests for consistency: Medium × Medium → Priority: Medium

Test strategy (to satisfy AC-1):

  • RTL component/page tests:
    • AftercarePage: query TabsList/TabsTrigger/TabsContent and assert tokenized classes; check Card/Alert presence by role/text; ensure no inline arbitrary color overrides.
    • Second page: assert heading sizes and body leading; verify ui/* primitives usage (getByRole("button") etc.).
  • Snapshot tests permitted only for stable non-visual structure; prefer explicit class assertions.
  • Visual acceptance notes: Document spacing/typography screenshots for critical templates (not a blocking automated gate).

Gate Decision: PASS

  • Rationale: Loading/error skeletons exist for key segments, tests are green on representative pages, ad-hoc icon color overrides were removed or marked decorative with aria-hidden, and a Typography Ramp is documented in docs/ui-architecture.md and applied to representative pages.
  • Blocking items resolved:
    1. Segment skeletons added for required pages (loading.tsx/error.tsx) using ShadCN primitives.
    2. Ad-hoc text-white icon classes removed; icons now inherit color and include aria-hidden where decorative.
    3. RTL tests added for Aftercare and Privacy covering tokens, primitives, motion, spacing.
    4. Typography Ramp documented in docs/ui-architecture.md and applied to representative pages.
  • Non-blocking recommendations:
    • Standardize subtle transitions via tailwindcss-animate on Tabs/Dialogs/Alerts where applicable.
    • Introduce/verify a shared section wrapper component for paddings, max-width, and breakpoints to minimize drift.
  • Exit criteria for PASS:
    • All blocking items above completed with green tests (npm run test) and manual verify of loading/error states per segment.

Notes:

  • Gate file was not written because qa.qaLocation/gates is not configured in this repo. Provide the location to emit a formal gate YAML if required.