# T721 — today product filters cards

> Status: `done`  
> Milestone: `M2` · Phase B  
> Kind: `feat` · Est. change: `~200 lines`

## Goal

今日商機可按 Brand／Product／fit band 篩選，單卡立即看懂主推產品、兩種分數與主要證據。

## Depends on

- T720

## Inputs

- `apps/web/src/pages/RadarTodayPage.tsx`、`styles/radar.css`
- `../spec.md` §4.4、§5.4

## Outputs

| 路徑 | 動作 | 說明 |
|------|------|------|
| `apps/web/src/pages/RadarTodayPage.tsx` | edit | product filters 與去重卡片 |
| `apps/web/src/components/radar/ProductOpportunityCard.tsx` | add | 主推產品、分數、證據、風險摘要 |
| `apps/web/src/styles/radar.css` | edit | Harbor Desk 卡片與 responsive filters |
| `apps/web/src/pages/RadarTodayPage.test.tsx` | edit | filters／single-card／empty reason |

## Behavior

- Product filter 展示該 match 的證據，但不修改 primary。
- `no_eligible_product_match` 顯示前往全部結果，不顯示空白成功。
- 卡片預設只露一段證據與其他 match 數，控制資訊密度。

## Out of scope

- 四維展開與改 primary（T722）
- 全部結果頁（T723）

## Acceptance

- [x] 雙產品 fixture 只出現一張卡；filter A1/A2 均可找到。

```bash
cd apps/web && npm run test -- RadarTodayPage && npm run check:tokens
```

Implementation result (2026-08-10): Today now sends brand/product/fit filters,
shows primary and independent product-fit scores, and routes the no-eligible
state to All Results without turning it into a blank success state.
