# T07 — Styling Stabilization QA Pass

Date: 2026-03-28  
Task: **T07 — Stabilization QA Pass**  
Scope: QA review of T02–T06 outcomes in `recipe-manager/frontend`

## What was reviewed

Read docs:
- `.harness/styling-stabilization-execution-board.md`
- `.harness/docs/styling-inventory.md`
- `.harness/docs/styling-token-contract.md`
- `.harness/docs/ui-primitive-contract.md`
- `.harness/docs/styling-governance.md`
- `.harness/docs/t05-legacy-style-debt-cleanup.md`
- `docs/visual-audit/after/homepage-qa-note-t04.md`

Inspected implementation surfaces:
- `src/styles/tokens.css`
- `src/theme.ts`
- `src/index.css`
- `src/components/ui/primitives.tsx`
- `src/App.tsx`
- `src/components/MissionControlPanel.tsx`
- `src/pages/RecipeListPage.tsx`
- `src/pages/CookModePage.tsx`
- `src/pages/ImportUrlPage.tsx`
- `src/components/RecipeCard.tsx`
- `src/components/Toast.tsx`
- `src/components/ErrorBoundary.tsx`
- `src/pages/NotFoundPage.tsx`
- `scripts/style-guardrails.mjs`
- `frontend/package.json`

Validation commands:
- `npm run style:guardrails` ✅ pass
- `npm run build` ✅ pass
- `npm run lint` ❌ fails (pre-existing non-styling issues; see findings)
- grep scan for raw palette utilities in app/page/component surfaces

---

## QA findings by severity

### High
1. **Known drift still present in unguarded surfaces (`ErrorBoundary`, `NotFoundPage`)**
   - `src/components/ErrorBoundary.tsx` still uses raw Tailwind palette utilities (`bg-gray-*`, `text-gray-*`, `bg-blue-*`, `text-red-*`).
   - `src/pages/NotFoundPage.tsx` still uses raw palette (`text-gray-*`, `bg-blue-*`).
   - Risk: these are user-visible shell/error states and create immediate visual inconsistency with tokenized surfaces.

### Medium
2. **Guardrail scope is still too narrow for current stabilized claims**
   - Current `style:guardrails` only enforces:
     - `src/App.tsx`
     - `src/components/MissionControlPanel.tsx`
     - `src/components/ui/primitives.tsx`
   - High-drift but now partially stabilized files (e.g., `RecipeListPage`, `ImportUrlPage`, `CookModePage`, `RecipeCard`) are not protected yet.

3. **Residual non-token palette usage remains in otherwise stabilized pages/components**
   - `src/pages/RecipeListPage.tsx`: hero overlay gradient uses `from-slate-900...` / `via-slate-900...`.
   - `src/components/RecipeCard.tsx`: card image overlay uses `from-slate-950...` / `via-slate-900...`.
   - `src/components/Toast.tsx`: close button hover uses `hover:text-gray-200`.
   - These are limited, but they are still direct palette leakage.

4. **Release hygiene risk: lint gate is red**
   - `npm run lint` fails due to existing React/TS lint errors in `App.tsx`, `CookModePage.tsx`, `RecipeDetailPage.tsx`, `api.ts`, `types/api-aux.ts`.
   - Not strictly a styling blocker, but it weakens governance confidence and CI-readiness.

### Low
5. **`theme.ts` still contains non-token hex values in `recipeAccentPalette`**
   - Most token drift was eliminated correctly, but this transitional array still includes raw hex values.
   - This is documented as an exception in T02; low-risk but still outside ideal contract purity.

---

## What is now considered stabilized

- **Token source authority:** `tokens.css` is effectively canonical; `theme.ts` now primarily references CSS vars instead of duplicating hardcoded token values.
- **Primitive layer exists and is adopted:** `UiPage`, `UiSection`, `UiCard`, `UiButton`, `UiChip`, `UiBadge`, `cn()` are implemented and used in key shell/surface paths.
- **App shell conversion landed:** `App.tsx` now follows tokenized/primitive-aligned styling patterns.
- **Mission Control conversion landed:** `MissionControlPanel.tsx` moved onto tokenized primitive usage.
- **Legacy cleanup landed:** `src/App.css` removed; legacy `.card` alias removed from `index.css`.
- **Governance baseline landed:** written governance + runnable guardrail command in package scripts.

---

## What still needs work

1. **Close remaining obvious drift surfaces**
   - Convert `ErrorBoundary` and `NotFoundPage` to tokenized/primitive patterns.

2. **Finish palette cleanup on media overlays/edge controls**
   - Replace remaining `slate-*`/`gray-*` utility references in `RecipeListPage`, `RecipeCard`, and `Toast` with semantic tokens.

3. **Expand guardrail coverage in phases**
   - Add stabilized pages/components to `scripts/style-guardrails.mjs` scope incrementally (start with `NotFoundPage`, `ErrorBoundary`, `RecipeListPage`, `RecipeCard`, `Toast`).

4. **Address lint debt to improve release confidence**
   - Resolve outstanding lint errors (especially `react-hooks/set-state-in-effect` and explicit `any` violations) so governance checks can become stronger CI gates.

5. **Optional contract hardening**
   - Replace non-token hexes in `recipeAccentPalette` with token references.

---

## Recommended next execution-board task

**T08 (new): Guardrail Scope Expansion + Residual Drift Cleanup**

Proposed scope:
- Convert `ErrorBoundary` + `NotFoundPage` to tokenized primitives.
- Remove remaining raw palette classes in `RecipeListPage`, `RecipeCard`, `Toast`.
- Expand `style:guardrails` file scope to include these surfaces.
- Keep changes low-risk and styling-only.

If no new task id is allowed, treat this as **T07 follow-on patch set** before final signoff.

---

## Release gate status (from execution board)

- [x] One canonical token source with no major CSS/TS drift
- [x] Base primitives centralized and used across high-traffic surfaces
- [~] No new ad-hoc color classes outside tokenized set (mostly true, residual exceptions remain)
- [x] Legacy scaffold artifacts removed/documented
- [x] Governance doc + guardrail command exist

Overall: **Near-stable, not fully closed** due to residual palette drift and narrow guardrail scope.

## Ready for review

**Yes (with follow-on cleanup required before final “fully stabilized” signoff).**
