Skip to content

feat(frontend): Mobile-first product detail redesign — score hero, nutrition bars, allergen badges #781

@ericsocrat

Description

@ericsocrat

Problem Statement

The product detail page is the most-visited page in any food scoring app, yet on mobile (<360px), critical health information overflows, truncates, or becomes unreadable. This page is where consumers make their buy/don't-buy decision — every second of confusion costs trust and engagement.

Current issues identified (from architecture audit):

  1. Score breakdown radar chart overflows on screens <360px — the SVG doesn't scale properly, causing horizontal scroll
  2. Data-heavy tabs (Nutrition, Ingredients, Allergens) cram desktop-density information into mobile — tiny text, cramped tables
  3. Nutrition table uses a desktop-style grid that doesn't adapt for mobile — values are hard to read at arm's length
  4. Score explanation is text-heavy with no visual hierarchy — consumers need to understand their product's health impact in 3 seconds
  5. Allergen matrix is cramped on mobile — critical safety information (contains/traces) needs prominent visual treatment
  6. No visual differentiation between "excellent" and "poor" scores — the score number exists but the emotional impact is missing
  7. Ingredient concern tiers (EFSA 0-3) are shown as raw data — consumers don't understand what "concern tier 2" means

Target user: Average Polish or German consumer, scanning a product in a grocery store aisle, holding their phone in one hand, making a quick health decision. They need to understand the product's health profile in under 5 seconds.


Architectural Evaluation

Approach Verdict Rationale
A. Incremental fixes to existing layout ❌ Rejected Patchwork fixes won't achieve the required UX quality. The page needs a mobile-first redesign.
B. Mobile-first redesign with progressive disclosure ✅ Chosen Design for 320px first, then enhance for tablet/desktop. Use progressive disclosure (summary → detail) to manage information density.
C. Separate mobile and desktop components ❌ Rejected Maintenance nightmare. Single responsive component set is standard modern practice.

Prior art: Yuka's product page — large circular score with color, 3-line summary, expandable detail sections. Simple, immediate, trustworthy.


Design Vision — Mobile Product Detail Page

Above the Fold (First Screen — 5-Second Decision)

┌─────────────────────────────────┐
│  ← Back        ♡  📋  ⚖️       │  Action icons: Favorite, List, Compare
│                                 │
│     [Product Image — large]     │  Full-width hero image
│                                 │
│  ┌─────────────────────────┐   │
│  │    🟢 82 / 100          │   │  Large TryVit Score with
│  │    Excellent             │   │  color-coded circle/ring
│  │    "Low risk to health"  │   │  + one-line human verdict
│  └─────────────────────────┘   │
│                                 │
│  Lay's Oven Baked Original      │  Product name
│  Lay's · Chips · 🇵🇱            │  Brand · Category · Country
│                                 │
│  Nutri-Score: [B]  NOVA: [3]    │  Side-by-side badges
│                                 │
│  ⚠️ Contains: gluten, milk      │  Allergen warnings — prominent
│  ⚠️ May contain: soy, nuts      │  if user has health profile
│                                 │
├─────────────────────────────────┤
│  📊 Nutrition  🧪 Ingredients   │  Swipeable tabs below the fold
│  ⚠️ Allergens  📋 Details       │
└─────────────────────────────────┘

Nutrition Tab (Below the Fold)

  • Visual bars instead of raw table — each nutrient as a horizontal progress bar
  • Color-coded by health impact (green=low, yellow=moderate, red=high)
  • Per 100g default with toggle to per-serving
  • Key nutrients highlighted: Saturated fat, Sugar, Salt, Calories (the 4 most impactful scoring factors)
  • Contextual comparison: "This has 2× more sugar than category average"

Ingredients Tab

  • Clean list with concern-tier color coding (green/yellow/orange/red badges)
  • Additive explanations — tap an E-number to see what it is and why it's concerning
  • Palm oil flag — prominent visual indicator if present
  • Ingredient count badge: "23 ingredients" with context ("typical for this category: 15")

Allergens Tab

  • Two clear sections: "Contains" (definite) and "May Contain / Traces" (possible)
  • Large, tappable allergen badges with icons (🥜 Nuts, 🌾 Gluten, 🥛 Milk)
  • Health profile integration: If user has dairy sensitivity, milk allergen is highlighted in red

Implementation Plan

Phase 1 — Score Hero Section

  • Large color-coded TryVit Score circle/ring component
  • Human-readable verdict text ("Excellent", "Good", "Moderate", "Poor", "Bad")
  • One-line health impact summary
  • Mobile-optimized product image display

Phase 2 — Nutrition Visualization

  • Horizontal bar chart component for nutrients
  • Color coding by health impact thresholds
  • Per-100g / per-serving toggle
  • Category average comparison badges

Phase 3 — Ingredient & Allergen Display

  • Concern-tier colored ingredient list
  • Tappable additive explanations
  • Allergen badge grid with icons
  • Health profile-aware highlighting

Phase 4 — Tab System & Progressive Disclosure

  • Swipeable tab navigation for below-the-fold content
  • Smooth transitions between tabs
  • "Show more" expandable sections within tabs

Technical Implementation

Components to Create/Modify

  • ProductScoreHero.tsx — new: large score display with color ring
  • NutritionBars.tsx — new: visual bar chart for nutrients
  • IngredientList.tsx — refactor: add concern-tier badges, additive explanations
  • AllergenBadges.tsx — new: icon-based allergen display
  • ProductTabs.tsx — refactor: swipeable, mobile-optimized tabs

Data Requirements

  • All data already available via api_product_detail() and api_score_explanation()
  • No new API calls needed — purely a presentation layer improvement
  • Score explanation JSONB already contains factor breakdowns

Test Requirements

Vitest Component Tests

  • ProductScoreHero.test.tsx — renders correct color/label for each band
  • NutritionBars.test.tsx — renders bars with correct proportions
  • AllergenBadges.test.tsx — renders contains vs traces correctly
  • Tab navigation — swipe, click, keyboard accessibility

Playwright E2E

  • Product detail page loads without horizontal scroll on 320px
  • Score section visible above the fold
  • Allergen warnings visible for products with allergens
  • All tabs navigable

Accessibility

  • All interactive elements ≥44×44px tap targets
  • Color-coded elements also have text/icon alternatives
  • Screen reader announces score and health verdict
  • WCAG 2.1 AA contrast ratios for all text on colored backgrounds

Verification Checklist

  • cd frontend && npx tsc --noEmit — 0 errors
  • cd frontend && npx vitest run — all tests pass
  • cd frontend && npx playwright test --project=smoke — passes
  • Manual test on 320px viewport — no horizontal scroll, no text truncation
  • Performance: Lighthouse performance score ≥90 on product page
  • CHANGELOG.md updated under [Unreleased]

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High: significant impact, fix this sprintenhancementNew feature or requestfrontendFrontend / Next.js / ReactmobileuxUser experience improvement

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions