--- convoy: pricing-online-local brief_number: 9 depends_on: [8] recommended_model: composer-2.5 model_tier: standard files: - components/card-detail/CardDetailPurchaseTab.js - components/card-detail/CardDetailPriceHistoryTab.js - components/CardDetailView.js - lib/use-card-detail.js - test/components/CardDetailPurchaseTab.test.js cross_brief_commitments: - brief: 8 description: | Consumes `/api/cards/[id]/pricing` and `/api/cards/[id]/price-history` response shapes defined in Brief 8. - brief: 13 description: | Brief 13 will add `CardDetailLocalStores` below the purchase panel. Leave a slot in purchase tab wrapper for Brief 13 insertion. --- # Brief 9: Card detail pricing UI ## Goal (1 sentence) Replace placeholder Purchase and Price History tabs with live pricing data, staleness badge, and a simple history chart. ## Files in scope (do not edit anything else) - `components/card-detail/CardDetailPurchaseTab.js` - `components/card-detail/CardDetailPriceHistoryTab.js` - `components/CardDetailView.js` - `lib/use-card-detail.js` - `test/components/CardDetailPurchaseTab.test.js` ## Conventions to follow - Liquid Glass surfaces: `glass-panel`, CSS variables — no hardcoded hex. - Purchase tab: staleness badge, outbound links from API `outbound`. - Price History tab: line chart from `points`; empty state when none. - Reserve insertion point for Brief 13 local stores section. ## Acceptance criteria - [ ] Purchase tab shows DB prices and staleness badge - [ ] Price History tab renders data when points exist; empty state when none - [ ] No placeholder “available soon” copy remains - [ ] Component test verifies staleness badge text - [ ] Tests pass - [ ] No scope expansion ## Rationale (≤3 sentences) Delivers Phase 1 user-facing value on existing tab chrome. Keeps `CardDetailView` thin by extracting tab bodies. Documents insertion point for Phase 2 local stores.