# T06 — Styling Guardrails + Lightweight Governance

Date: 2026-03-27  
Scope: `recipe-manager/frontend`

## Why this exists

The styling stabilization pass established a token + primitive contract. This governance doc keeps that contract from drifting back into mixed styling modes.

## Canonical styling contract (short version)

1. **Tokens are defined in one place:** `src/styles/tokens.css`
2. **Build UI from shared primitives first:** `src/components/ui/primitives.tsx` + `ui-*` classes from `src/index.css`
3. **Use tokenized values in classes/styles:** `var(--...)` or Tailwind theme aliases mapped to tokens
4. **Do not add new raw Tailwind palette utilities** (e.g. `bg-blue-500`, `text-slate-600`) in stabilized shared surfaces
5. **Do not hardcode hex colors in `className`** (e.g. `bg-[#1f2937]`) for app UI

Reference docs:
- `./styling-token-contract.md`
- `./ui-primitive-contract.md`
- `./t05-legacy-style-debt-cleanup.md`

## Lightweight automated guardrail

A scoped check is available:

```bash
cd frontend
npm run style:guardrails
```

Current guard scope (intentional, low-risk):
- `src/App.tsx`
- `src/components/MissionControlPanel.tsx`
- `src/components/ui/primitives.tsx`

What it flags:
- direct palette utility classes (`bg-blue-*`, `text-slate-*`, etc.)
- hex colors in arbitrary utility classes (`bg-[#...]`, `text-[#...]`, etc.)

If violations are found in guarded files, the script exits non-zero.

## Contributor checklist (copy into PR template/comments as needed)

- [ ] New UI uses `Ui*` primitives or existing `ui-*` classes where possible
- [ ] Any new visual token was added to `tokens.css` first
- [ ] No new hardcoded palette utility classes in stabilized shell/shared primitive areas
- [ ] No new hardcoded hex colors in class utilities for app surfaces
- [ ] `npm run style:guardrails` passes
- [ ] `npm run lint` passes

## Review heuristics for agents/contributors

When touching frontend UI, quickly answer:

1. "Can this use an existing `Ui*` primitive?"
2. "If I need a new color/radius/shadow, did I add a semantic token first?"
3. "Am I introducing a second styling path that future edits will copy?"

If the answer to (3) is yes, pause and refactor to the contract.

## Intentional limitations (for now)

- The guard script is **scoped**, not repo-wide, because existing pages still contain known legacy palette usage (tracked in T01/T04).
- The check is intentionally simple regex-based (fast, no lint plugin churn).
- This is not wired into heavy CI yet; it is run locally and can be added to future CI once high-drift pages are migrated.

## Expansion path after T04/T07

As additional pages are stabilized, add them to `frontend/scripts/style-guardrails.mjs` scope to progressively tighten enforcement without breaking current workflows.
