# Migrating Consumer Repos to Canonical Tokens

This doc describes how to wire `mvp2` and `outlex-corporate-website` to consume `outlex-design/tokens/tokens.css` as the source of truth.

## Phase 0d — minimum (this PR)

**Goal**: prove the wire works without rewriting either consumer's existing token system.

### Step 1: Symlink canonical tokens into each consumer

```bash
# mvp2
ln -sf ~/outlex-design/tokens/tokens.css ~/mvp2/src/styles/outlex-tokens.css

# outlex-corporate-website
ln -sf ~/outlex-design/tokens/tokens.css ~/outlex-corporate-website/src/styles/outlex-tokens.css
```

Both consumers now have a file at `src/styles/outlex-tokens.css` that resolves to the canonical. CI guard (`scripts/compare-tokens.sh`) verifies it.

### Step 2: Run the CI guard locally

```bash
bash ~/outlex-design/scripts/compare-tokens.sh ~/mvp2/src/styles/outlex-tokens.css
bash ~/outlex-design/scripts/compare-tokens.sh ~/outlex-corporate-website/src/styles/outlex-tokens.css
```

Expected: both pass with hash match.

### Step 3 (deferred to Phase 0d-followup): rewire imports

This is a real refactor — touching the load order of CSS variables in two production codebases. Treat as its own PR with full test coverage.

---

## Phase 0d-followup — wire imports (separate PR)

### mvp2

Current: `mvp2/src/index.css` declares ~230 lines of CSS custom properties under `:root` (lines 21-230).

**Target structure**:

```css
/* mvp2/src/index.css — TOP of file */
@import './styles/outlex-tokens.css';   /* Canonical brand tokens load first */
@import './styles/motion.css';
@import './styles/entry-surfaces-v7.css';
/* ...rest unchanged */
```

Then in the existing `:root` block:
- **DELETE** declarations for tokens now in canonical: `--background`, `--foreground`, `--primary`, `--accent-sage`, `--accent-amber`, `--accent-terracotta`, `--danger`, `--border`, `--muted-foreground`, `--mark-gradient-blue`, `--mark-gradient-teal`, `--shadow-warm-base` (HSL component form). These now live in canonical.
- **KEEP** product-internal tokens that have no brand equivalent: `--card`, `--popover`, `--secondary`, `--primary-foreground`, `--accent`, `--insight-*`, `--sidebar-*`, all `--text-*` semantic aliases, all `--state-*` interaction tokens, all `--shadow-button-*`, all `--shadow-card-*`, focus rings (mvp2 has more variants than canonical), etc.
- **VERIFY** with `npm run build` that no Tailwind utility breaks.

### outlex-corporate-website

Current: `outlex-corporate-website/src/index.css` declares ~30 CSS custom properties.

**Target**:

```css
@import './styles/outlex-tokens.css';
@tailwind base;
@tailwind components;
@tailwind utilities;
```

Then DELETE the entire `@layer base { :root { ... } }` block — every token in it is either now in canonical OR can be rebuilt from canonical names.

**Specifically resolve**:
- `--secondary: 125 15% 49%; /* #7A9E7E sage */` → drop. Use `--outlex-sage` (`#6B8F71` — same HSL value, accurate hex).
- `--ring: 226 38% 59%;` → drop. Use `--outlex-primary` (`226 43% 59%` — saturation drift fixed; corporate site was 38%, mvp2 is 43%, canonical is 43%).
- `--background: 40 33% 97%` → drop. Use `--outlex-bg-hsl` (`30 20% 97%` — corporate site annotated `#FAF8F5` but actually rendered `#FAF7F1`; canonical fixes to match mvp2).

After migration the corporate site's index.css is ~10 lines (just the @tailwind directives + import).

---

## Acceptance criteria for Phase 0d-followup

- [ ] `bash compare-tokens.sh` passes for both consumers
- [ ] `mvp2 npm run build` produces no new lint or type errors
- [ ] `outlex-corporate-website npm run build` produces no errors
- [ ] Visual diff: production build of each consumer side-by-side with current main shows no UI regression
- [ ] One full page on each consumer (mvp2 Home, outlex.ai landing) screenshot-diffed at desktop + mobile
- [ ] Sage CTA color matches `#6B8F71` on both surfaces (was previously drifted to `#7A9E7E` annotation on corporate site)

---

## Why two phases instead of one

Phase 0d (this PR) ships the canonical + symlink + guard with low risk — no production CSS changes, no possible regression. Phase 0d-followup ships the actual token migration with full visual regression testing, on its own PR, reviewable independently.

Per `~/.claude/CLAUDE.md` Engineering Principles ("Naive First, Then Elevate"): the symlink works, we verify it works, THEN we rewire. Don't bundle the import-refactor into the canonical-extraction PR.
