# ICP-Aligned E2E Test Projects Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Build 4 test projects (TestimonialWall, MetricsPanel, AuthorBioCard, FeatureComparisonTable) that each exercise the full CMS-aiChemist pipeline end-to-end, targeting Digital Agency, SaaS Product, Content Publisher, and Enterprise Design System ICP segments.

**Architecture:** Each project follows the same pipeline: DTCG tokens → build.py → CSS custom properties → React component in packages/ui → Next.js route in apps/web → catalog/stats sync → CSA artifact → brain push. Projects execute sequentially (1→2→3→4), accumulating tokens and components.

**Tech Stack:** TypeScript/React (components), Python (token build), Next.js 15 App Router (routes), CSS custom properties (styling), ADW/CSA skills (pipeline integration), brain scripts (NotebookLM sync)

---

## File Map

### New Files (per project)

| Project | Component | Route Page | Route Showcase | Route CSS |
|---------|-----------|------------|----------------|-----------|
| 1 | `packages/ui/src/components/TestimonialWall.tsx` | `apps/web/src/app/testimonials/page.tsx` | `apps/web/src/app/testimonials/TestimonialShowcase.tsx` | `apps/web/src/app/testimonials/testimonials.css` |
| 2 | `packages/ui/src/components/MetricsPanel.tsx` | `apps/web/src/app/metrics/page.tsx` | `apps/web/src/app/metrics/MetricsShowcase.tsx` | `apps/web/src/app/metrics/metrics.css` |
| 3 | `packages/ui/src/components/AuthorBioCard.tsx` | `apps/web/src/app/authors/page.tsx` | `apps/web/src/app/authors/AuthorsShowcase.tsx` | `apps/web/src/app/authors/authors.css` |
| 4 | `packages/ui/src/components/FeatureComparisonTable.tsx` | `apps/web/src/app/compare/page.tsx` | `apps/web/src/app/compare/CompareShowcase.tsx` | `apps/web/src/app/compare/compare.css` |

### Modified Files (cumulative — each project updates all of these)

| File | What changes |
|------|-------------|
| `packages/tokens/src/tokens.json` | Add new `components.*` DTCG group |
| `packages/ui/src/styles.css` | Append component CSS |
| `packages/ui/src/index.ts` | Add barrel exports |
| `apps/web/src/app/layout.tsx` | Add nav link |
| `apps/web/src/app/page.tsx` | Update token count, component count, component list |
| `apps/web/src/app/dashboard/ProjectDashboard.tsx` | Sync mock data counts |
| `apps/web/src/app/design-system/DesignSystem.tsx` | Add component to catalog, update usage tab |

### ADW Spec Files (one per project)

- `specs/adw-feat-4-testimonial-wall.md`
- `specs/adw-feat-5-metrics-panel.md`
- `specs/adw-feat-6-author-bio-card.md`
- `specs/adw-feat-7-feature-comparison-table.md`

---

## Task 1: Project 1 — TestimonialWall Tokens

**Files:**
- Modify: `packages/tokens/src/tokens.json` (add `components.testimonial` group after `pricingCard`)

- [ ] **Step 1: Add testimonial tokens to DTCG JSON**

Open `packages/tokens/src/tokens.json`. Inside the `"components"` object, after the `"pricingCard"` block (line 182), add:

```json
    "testimonial": {
      "background": { "$value": "{color.background.card}", "$type": "color" },
      "backgroundHover": { "$value": "{color.background.elevated}", "$type": "color" },
      "borderRadius": { "$value": "{borderRadius.lg}", "$type": "dimension" },
      "padding": { "$value": "{spacing.6}", "$type": "dimension" },
      "border": { "$value": "{color.border.default}", "$type": "color" },
      "avatarBorder": { "$value": "{color.primary.base}", "$type": "color" },
      "avatarSize": { "$value": "48px", "$type": "dimension" },
      "quoteColor": { "$value": "{color.text.secondary}", "$type": "color" },
      "nameColor": { "$value": "{color.text.primary}", "$type": "color" },
      "roleColor": { "$value": "{color.text.muted}", "$type": "color" },
      "starColor": { "$value": "{color.accent.gold}", "$type": "color" },
      "starEmpty": { "$value": "{color.text.muted}", "$type": "color" }
    }
```

That's 12 tokens.

- [ ] **Step 2: Run token build and verify count**

Run: `python3 packages/tokens/build.py`

Expected: Output reports 133 tokens (121 + 12 testimonial). Check `packages/tokens/output/tokens.css` contains `--components-testimonial-*` variables.

- [ ] **Step 3: Commit tokens**

```bash
git add packages/tokens/src/tokens.json
git commit -m "feat(tokens): add 12 testimonial component tokens for TestimonialWall"
```

---

## Task 2: Project 1 — TestimonialWall Component

**Files:**
- Create: `packages/ui/src/components/TestimonialWall.tsx`
- Modify: `packages/ui/src/styles.css` (append testimonial CSS)
- Modify: `packages/ui/src/index.ts` (add exports)

- [ ] **Step 1: Create TestimonialWall component**

Create `packages/ui/src/components/TestimonialWall.tsx`:

```tsx
"use client";

import type { HTMLAttributes } from "react";

export interface Testimonial {
  name: string;
  role: string;
  avatarUrl?: string;
  quote: string;
  rating: number; // 1-5
}

export interface TestimonialWallProps extends HTMLAttributes<HTMLDivElement> {
  testimonials: Testimonial[];
}

function StarRating({ rating }: { rating: number }) {
  return (
    <div className="ac-testimonial__stars" aria-label={`${rating} out of 5 stars`}>
      {Array.from({ length: 5 }, (_, i) => (
        <span
          key={i}
          className={`ac-testimonial__star${i < rating ? " ac-testimonial__star--filled" : ""}`}
          aria-hidden="true"
        >
          {"\u2605"}
        </span>
      ))}
    </div>
  );
}

export function TestimonialWall({
  testimonials,
  className = "",
  ...props
}: TestimonialWallProps) {
  const classes = ["ac-testimonial-wall", className].filter(Boolean).join(" ");

  return (
    <div className={classes} {...props}>
      {testimonials.map((t) => (
        <div key={`${t.name}-${t.role}`} className="ac-testimonial">
          <div className="ac-testimonial__header">
            {t.avatarUrl ? (
              <img
                src={t.avatarUrl}
                alt={t.name}
                className="ac-testimonial__avatar"
              />
            ) : (
              <div className="ac-testimonial__avatar ac-testimonial__avatar--placeholder">
                {t.name.charAt(0).toUpperCase()}
              </div>
            )}
            <div className="ac-testimonial__meta">
              <p className="ac-testimonial__name">{t.name}</p>
              <p className="ac-testimonial__role">{t.role}</p>
            </div>
          </div>
          <blockquote className="ac-testimonial__quote">
            &ldquo;{t.quote}&rdquo;
          </blockquote>
          <StarRating rating={t.rating} />
        </div>
      ))}
    </div>
  );
}
```

- [ ] **Step 2: Add TestimonialWall CSS to styles.css**

Append to `packages/ui/src/styles.css`:

```css
/* Testimonial Wall */
.ac-testimonial-wall {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--spacing-6);
  width: 100%;
}

.ac-testimonial {
  background: var(--components-testimonial-background);
  border-radius: var(--components-testimonial-borderRadius);
  padding: var(--components-testimonial-padding);
  border: 1px solid var(--components-testimonial-border);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-4);
  transition: background-color 0.15s ease;
}

.ac-testimonial:hover {
  background: var(--components-testimonial-backgroundHover);
}

.ac-testimonial__header {
  display: flex;
  align-items: center;
  gap: var(--spacing-3);
}

.ac-testimonial__avatar {
  width: var(--components-testimonial-avatarSize);
  height: var(--components-testimonial-avatarSize);
  border-radius: var(--borderRadius-full);
  border: 2px solid var(--components-testimonial-avatarBorder);
  object-fit: cover;
}

.ac-testimonial__avatar--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-background-elevated);
  color: var(--color-primary-base);
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-xl);
  font-weight: var(--typography-fontWeight-semibold);
}

.ac-testimonial__meta {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.ac-testimonial__name {
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-sm);
  font-weight: var(--typography-fontWeight-semibold);
  color: var(--components-testimonial-nameColor);
  margin: 0;
}

.ac-testimonial__role {
  font-size: var(--typography-fontSize-xs);
  color: var(--components-testimonial-roleColor);
  margin: 0;
}

.ac-testimonial__quote {
  font-size: var(--typography-fontSize-sm);
  color: var(--components-testimonial-quoteColor);
  line-height: var(--typography-lineHeight-relaxed);
  margin: 0;
  font-style: italic;
}

.ac-testimonial__stars {
  display: flex;
  gap: 2px;
}

.ac-testimonial__star {
  font-size: var(--typography-fontSize-sm);
  color: var(--components-testimonial-starEmpty);
}

.ac-testimonial__star--filled {
  color: var(--components-testimonial-starColor);
}
```

- [ ] **Step 3: Add barrel exports**

Add to `packages/ui/src/index.ts`:

```typescript
export { TestimonialWall } from "./components/TestimonialWall";
export type { TestimonialWallProps, Testimonial } from "./components/TestimonialWall";
```

- [ ] **Step 4: Commit component**

```bash
git add packages/ui/src/components/TestimonialWall.tsx packages/ui/src/styles.css packages/ui/src/index.ts
git commit -m "feat(ui): add TestimonialWall component with 12 token-driven styles"
```

---

## Task 3: Project 1 — TestimonialWall Route

**Files:**
- Create: `apps/web/src/app/testimonials/page.tsx`
- Create: `apps/web/src/app/testimonials/TestimonialShowcase.tsx`
- Create: `apps/web/src/app/testimonials/testimonials.css`

- [ ] **Step 1: Create route page**

Create `apps/web/src/app/testimonials/page.tsx`:

```tsx
import type { Metadata } from "next";
import "./testimonials.css";
import TestimonialShowcase from "./TestimonialShowcase";

export const metadata: Metadata = {
  title: "Testimonials | CMS-aiChemist",
  description:
    "Client social proof module — TestimonialWall component from the shared UI library",
};

export default function TestimonialsPage() {
  return <TestimonialShowcase />;
}
```

- [ ] **Step 2: Create showcase component**

Create `apps/web/src/app/testimonials/TestimonialShowcase.tsx`:

```tsx
"use client";

import { TestimonialWall, Alert } from "../../../../../packages/ui/src";
import type { Testimonial } from "../../../../../packages/ui/src";

const testimonials: Testimonial[] = [
  {
    name: "Sarah Chen",
    role: "VP Engineering, TechScale",
    quote:
      "The token pipeline eliminated design drift across our 3 product surfaces. What used to take a week of manual CSS updates now happens in one build.",
    rating: 5,
  },
  {
    name: "Marcus Williams",
    role: "Creative Director, BrandForge Agency",
    quote:
      "We manage 12 client brands through one orchestration system. The agentic workflow cut our delivery time by 60%.",
    rating: 5,
  },
  {
    name: "Elena Rodriguez",
    role: "Head of Product, DataPulse",
    quote:
      "The shared component library ensures our marketing site and app dashboard always look consistent. Our design team loves the Penpot integration.",
    rating: 4,
  },
  {
    name: "James Park",
    role: "CTO, ContentFlow Media",
    quote:
      "EmDash + Astro gave us the editorial CMS we needed without the bloat. The AI-assisted content workflows are a game changer for our publishing team.",
    rating: 5,
  },
  {
    name: "Aisha Patel",
    role: "Design Systems Lead, Enterprise Corp",
    quote:
      "WCAG compliance built into every component from day one. The DTCG token format means our design decisions are portable and auditable.",
    rating: 4,
  },
  {
    name: "David Nguyen",
    role: "Frontend Architect, ScaleUp Inc",
    quote:
      "The ADW pipeline turns a GitHub issue into a deployed feature with CSA artifacts. It's the most efficient development workflow I've used.",
    rating: 5,
  },
];

export default function TestimonialShowcase() {
  return (
    <section className="testimonials-page">
      <a href="/" className="testimonials-back-link">
        &larr; Home
      </a>

      <header className="testimonials-header">
        <p className="testimonials-label">Social Proof</p>
        <h1 className="testimonials-title">What Our Clients Say</h1>
        <p className="testimonials-subtitle">
          Teams across agencies, SaaS companies, publishers, and enterprises
          trust aiChemist for their design system orchestration.
        </p>
      </header>

      <TestimonialWall testimonials={testimonials} />

      <div className="testimonials-info">
        <Alert variant="info">
          This is a demo of the shared <strong>TestimonialWall</strong>{" "}
          component from packages/ui. All styling is driven by 12 dedicated
          testimonial tokens in the DTCG pipeline.
        </Alert>
      </div>
    </section>
  );
}
```

- [ ] **Step 3: Create route CSS**

Create `apps/web/src/app/testimonials/testimonials.css`:

```css
.testimonials-page {
  padding: var(--spacing-8) var(--spacing-6);
  max-width: 1100px;
  margin: 0 auto;
}

.testimonials-back-link {
  display: inline-block;
  color: var(--color-text-muted);
  font-size: var(--typography-fontSize-sm);
  text-decoration: none;
  margin-bottom: var(--spacing-6);
  transition: color 0.15s ease;
}

.testimonials-back-link:hover {
  color: var(--color-text-primary);
}

.testimonials-header {
  text-align: center;
  margin-bottom: var(--spacing-12);
}

.testimonials-label {
  font-size: var(--typography-fontSize-sm);
  font-weight: var(--typography-fontWeight-semibold);
  color: var(--color-primary-base);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 0 0 var(--spacing-2) 0;
}

.testimonials-title {
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-5xl);
  font-weight: var(--typography-fontWeight-bold);
  color: var(--color-text-primary);
  margin: 0 0 var(--spacing-4) 0;
  line-height: var(--typography-lineHeight-tight);
}

.testimonials-subtitle {
  font-size: var(--typography-fontSize-lg);
  color: var(--color-text-secondary);
  max-width: 600px;
  margin: 0 auto;
  line-height: var(--typography-lineHeight-normal);
}

.testimonials-info {
  margin-top: var(--spacing-10);
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 768px) {
  .testimonials-page {
    padding: var(--spacing-6) var(--spacing-4);
  }

  .testimonials-title {
    font-size: var(--typography-fontSize-3xl);
  }
}
```

- [ ] **Step 4: Commit route**

```bash
git add apps/web/src/app/testimonials/
git commit -m "feat(web): add /testimonials route with TestimonialWall showcase"
```

---

## Task 4: Project 1 — TestimonialWall Integration (nav, stats, catalog)

**Files:**
- Modify: `apps/web/src/app/layout.tsx` (add nav link)
- Modify: `apps/web/src/app/page.tsx` (update stats: 133 tokens, 6 components, add TestimonialWall to component list)
- Modify: `apps/web/src/app/dashboard/ProjectDashboard.tsx` (sync counts)
- Modify: `apps/web/src/app/design-system/DesignSystem.tsx` (add TestimonialWall to catalog + usage tab)

- [ ] **Step 1: Add nav link in layout.tsx**

In `apps/web/src/app/layout.tsx`, after the Pricing nav link (line 37), add:

```tsx
              <a href="/testimonials" className="demo-header__link">
                Testimonials
              </a>
```

- [ ] **Step 2: Update landing page stats in page.tsx**

In `apps/web/src/app/page.tsx`:
- Line 8: Change `121 design tokens` → `133 design tokens`
- Line 97: Change component list to `Button, Card, Tabs, Alert, PricingTable, TestimonialWall`
- Line 127: Change `<span className="demo-feature__stat">121</span>` → `133`
- Line 137: Change `<span className="demo-feature__stat">5</span>` → `6`
- Line 135: Update component list text to include `TestimonialWall`
- Line 220: Change `<p className="demo-stat__number">121</p>` → `133`
- Line 224: Change `<p className="demo-stat__number">5</p>` → `6`

- [ ] **Step 3: Sync dashboard mock data**

In `apps/web/src/app/dashboard/ProjectDashboard.tsx`:
- p1 (Token Pipeline): `tokenCount: 121` → `tokenCount: 133`
- p2 (Shared UI Kit): `componentCount: 5` → `componentCount: 6`
- p5 (Dashboard Pilot): `tokenCount: 121` → `133`, `componentCount: 5` → `6`
- p7 (Astro Surface): `tokenCount: 121` → `133`, `componentCount: 5` → `6`

- [ ] **Step 4: Add TestimonialWall to design system catalog**

In `apps/web/src/app/design-system/DesignSystem.tsx`:

Add `TestimonialWall` to the import (line 3):
```tsx
import { Alert, Button, Card, PricingTable, Tabs, TestimonialWall } from "../../../../../packages/ui/src";
```

After the Pricing Table `<Card>` block (around line 417), add:

```tsx
        <Card title="Testimonial Wall">
          <div className="ds-component-group">
            <h4 className="ds-component-group__label">Social Proof Grid</h4>
            <TestimonialWall
              testimonials={[
                {
                  name: "Jane Smith",
                  role: "CTO, Example Corp",
                  quote: "This platform transformed our design workflow.",
                  rating: 5,
                },
                {
                  name: "John Doe",
                  role: "Design Lead, Agency X",
                  quote: "Token-driven components saved us weeks of work.",
                  rating: 4,
                },
              ]}
            />
          </div>
        </Card>
```

Update the Usage tab text (line 154) to:
```
Import from packages/ui/src — Button, Card, Tabs, Alert, PricingTable, and TestimonialWall. Each accepts typed props and renders token-driven styles via CSS custom properties.
```

- [ ] **Step 5: Build and verify**

Run: `cd apps/web && npx next build`

Expected: Build succeeds with 0 errors. All 7 routes generate (/, /dashboard, /design-system, /kaleido-life, /pricing, /testimonials).

- [ ] **Step 6: Commit integration**

```bash
git add apps/web/src/app/layout.tsx apps/web/src/app/page.tsx apps/web/src/app/dashboard/ProjectDashboard.tsx apps/web/src/app/design-system/DesignSystem.tsx
git commit -m "feat(web): integrate TestimonialWall — nav, stats (133 tokens/6 components), catalog"
```

---

## Task 5: Project 2 — MetricsPanel Tokens

**Files:**
- Modify: `packages/tokens/src/tokens.json` (add `components.metricsPanel` group)

- [ ] **Step 1: Add metrics panel tokens**

In `packages/tokens/src/tokens.json`, inside `"components"`, after the `"testimonial"` block, add:

```json
    "metricsPanel": {
      "background": { "$value": "{color.background.card}", "$type": "color" },
      "borderRadius": { "$value": "{borderRadius.lg}", "$type": "dimension" },
      "padding": { "$value": "{spacing.6}", "$type": "dimension" },
      "border": { "$value": "{color.border.default}", "$type": "color" },
      "valueColor": { "$value": "{color.text.primary}", "$type": "color" },
      "labelColor": { "$value": "{color.text.secondary}", "$type": "color" },
      "trendUp": { "$value": "{color.status.success}", "$type": "color" },
      "trendDown": { "$value": "{color.status.error}", "$type": "color" },
      "trendFlat": { "$value": "{color.text.muted}", "$type": "color" },
      "statusGood": { "$value": "{color.status.success}", "$type": "color" },
      "statusWarning": { "$value": "{color.status.warning}", "$type": "color" },
      "statusCritical": { "$value": "{color.status.error}", "$type": "color" }
    }
```

That's 12 tokens.

- [ ] **Step 2: Run token build and verify**

Run: `python3 packages/tokens/build.py`

Expected: 145 tokens (133 + 12 metricsPanel). Verify `--components-metricsPanel-*` in output.

- [ ] **Step 3: Commit**

```bash
git add packages/tokens/src/tokens.json
git commit -m "feat(tokens): add 12 metricsPanel component tokens for MetricsPanel"
```

---

## Task 6: Project 2 — MetricsPanel Component

**Files:**
- Create: `packages/ui/src/components/MetricsPanel.tsx`
- Modify: `packages/ui/src/styles.css`
- Modify: `packages/ui/src/index.ts`

- [ ] **Step 1: Create MetricsPanel component**

Create `packages/ui/src/components/MetricsPanel.tsx`:

```tsx
"use client";

import type { HTMLAttributes } from "react";

export type TrendDirection = "up" | "down" | "flat";
export type MetricStatus = "good" | "warning" | "critical";

export interface MetricItem {
  label: string;
  value: string;
  trend: TrendDirection;
  trendValue?: string;
  status?: MetricStatus;
}

export interface MetricsPanelProps extends HTMLAttributes<HTMLDivElement> {
  metrics: MetricItem[];
  columns?: 2 | 3 | 4;
}

const trendArrows: Record<TrendDirection, string> = {
  up: "\u2191",
  down: "\u2193",
  flat: "\u2192",
};

export function MetricsPanel({
  metrics,
  columns = 4,
  className = "",
  ...props
}: MetricsPanelProps) {
  const classes = ["ac-metrics-panel", `ac-metrics-panel--cols-${columns}`, className]
    .filter(Boolean)
    .join(" ");

  return (
    <div className={classes} {...props}>
      {metrics.map((m) => (
        <div
          key={m.label}
          className={`ac-metric-card${m.status ? ` ac-metric-card--${m.status}` : ""}`}
        >
          <p className="ac-metric-card__label">{m.label}</p>
          <p className="ac-metric-card__value">{m.value}</p>
          <div className={`ac-metric-card__trend ac-metric-card__trend--${m.trend}`}>
            <span className="ac-metric-card__trend-arrow" aria-hidden="true">
              {trendArrows[m.trend]}
            </span>
            {m.trendValue && (
              <span className="ac-metric-card__trend-value">{m.trendValue}</span>
            )}
          </div>
        </div>
      ))}
    </div>
  );
}
```

- [ ] **Step 2: Add MetricsPanel CSS**

Append to `packages/ui/src/styles.css`:

```css
/* Metrics Panel */
.ac-metrics-panel {
  display: grid;
  gap: var(--spacing-4);
  width: 100%;
}

.ac-metrics-panel--cols-2 { grid-template-columns: repeat(2, 1fr); }
.ac-metrics-panel--cols-3 { grid-template-columns: repeat(3, 1fr); }
.ac-metrics-panel--cols-4 { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }

.ac-metric-card {
  background: var(--components-metricsPanel-background);
  border-radius: var(--components-metricsPanel-borderRadius);
  padding: var(--components-metricsPanel-padding);
  border: 1px solid var(--components-metricsPanel-border);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
}

.ac-metric-card--good { border-left: 3px solid var(--components-metricsPanel-statusGood); }
.ac-metric-card--warning { border-left: 3px solid var(--components-metricsPanel-statusWarning); }
.ac-metric-card--critical { border-left: 3px solid var(--components-metricsPanel-statusCritical); }

.ac-metric-card__label {
  font-size: var(--typography-fontSize-xs);
  font-weight: var(--typography-fontWeight-medium);
  color: var(--components-metricsPanel-labelColor);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 0;
}

.ac-metric-card__value {
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-3xl);
  font-weight: var(--typography-fontWeight-bold);
  color: var(--components-metricsPanel-valueColor);
  margin: 0;
  line-height: var(--typography-lineHeight-tight);
}

.ac-metric-card__trend {
  display: flex;
  align-items: center;
  gap: var(--spacing-1);
  font-size: var(--typography-fontSize-sm);
}

.ac-metric-card__trend--up { color: var(--components-metricsPanel-trendUp); }
.ac-metric-card__trend--down { color: var(--components-metricsPanel-trendDown); }
.ac-metric-card__trend--flat { color: var(--components-metricsPanel-trendFlat); }

.ac-metric-card__trend-arrow {
  font-weight: var(--typography-fontWeight-bold);
}

.ac-metric-card__trend-value {
  font-weight: var(--typography-fontWeight-medium);
}
```

- [ ] **Step 3: Add barrel exports**

Add to `packages/ui/src/index.ts`:

```typescript
export { MetricsPanel } from "./components/MetricsPanel";
export type { MetricsPanelProps, MetricItem, TrendDirection, MetricStatus } from "./components/MetricsPanel";
```

- [ ] **Step 4: Commit**

```bash
git add packages/ui/src/components/MetricsPanel.tsx packages/ui/src/styles.css packages/ui/src/index.ts
git commit -m "feat(ui): add MetricsPanel component with trend indicators and status colors"
```

---

## Task 7: Project 2 — MetricsPanel Route

**Files:**
- Create: `apps/web/src/app/metrics/page.tsx`
- Create: `apps/web/src/app/metrics/MetricsShowcase.tsx`
- Create: `apps/web/src/app/metrics/metrics.css`

- [ ] **Step 1: Create route page**

Create `apps/web/src/app/metrics/page.tsx`:

```tsx
import type { Metadata } from "next";
import "./metrics.css";
import MetricsShowcase from "./MetricsShowcase";

export const metadata: Metadata = {
  title: "Metrics | CMS-aiChemist",
  description:
    "SaaS KPI dashboard widget — MetricsPanel component from the shared UI library",
};

export default function MetricsPage() {
  return <MetricsShowcase />;
}
```

- [ ] **Step 2: Create showcase component**

Create `apps/web/src/app/metrics/MetricsShowcase.tsx`:

```tsx
"use client";

import { MetricsPanel, Alert } from "../../../../../packages/ui/src";
import type { MetricItem } from "../../../../../packages/ui/src";

const productMetrics: MetricItem[] = [
  {
    label: "Monthly Revenue",
    value: "$48.2K",
    trend: "up",
    trendValue: "+12.5%",
    status: "good",
  },
  {
    label: "Active Users",
    value: "2,847",
    trend: "up",
    trendValue: "+8.3%",
    status: "good",
  },
  {
    label: "Churn Rate",
    value: "3.2%",
    trend: "down",
    trendValue: "-0.4%",
    status: "warning",
  },
  {
    label: "Avg Response",
    value: "142ms",
    trend: "flat",
    trendValue: "+2ms",
    status: "good",
  },
];

const platformMetrics: MetricItem[] = [
  {
    label: "Design Tokens",
    value: "145",
    trend: "up",
    trendValue: "+24",
    status: "good",
  },
  {
    label: "Components",
    value: "7",
    trend: "up",
    trendValue: "+2",
    status: "good",
  },
  {
    label: "Build Errors",
    value: "0",
    trend: "flat",
    status: "good",
  },
  {
    label: "CSA Score",
    value: "100",
    trend: "up",
    trendValue: "+7",
    status: "good",
  },
];

export default function MetricsShowcase() {
  return (
    <section className="metrics-page">
      <a href="/" className="metrics-back-link">
        &larr; Home
      </a>

      <header className="metrics-header">
        <p className="metrics-label">KPI Dashboard</p>
        <h1 className="metrics-title">Product Metrics</h1>
        <p className="metrics-subtitle">
          Real-time KPI tracking for SaaS product teams. Trend indicators and
          status thresholds driven by design tokens.
        </p>
      </header>

      <div className="metrics-section">
        <h2 className="metrics-section-title">Business KPIs</h2>
        <MetricsPanel metrics={productMetrics} />
      </div>

      <div className="metrics-section">
        <h2 className="metrics-section-title">Platform Health</h2>
        <MetricsPanel metrics={platformMetrics} />
      </div>

      <div className="metrics-info">
        <Alert variant="info">
          This is a demo of the shared <strong>MetricsPanel</strong> component
          from packages/ui. Trend colors and status indicators are driven by 12
          dedicated metrics tokens in the DTCG pipeline.
        </Alert>
      </div>
    </section>
  );
}
```

- [ ] **Step 3: Create route CSS**

Create `apps/web/src/app/metrics/metrics.css`:

```css
.metrics-page {
  padding: var(--spacing-8) var(--spacing-6);
  max-width: 1100px;
  margin: 0 auto;
}

.metrics-back-link {
  display: inline-block;
  color: var(--color-text-muted);
  font-size: var(--typography-fontSize-sm);
  text-decoration: none;
  margin-bottom: var(--spacing-6);
  transition: color 0.15s ease;
}

.metrics-back-link:hover {
  color: var(--color-text-primary);
}

.metrics-header {
  text-align: center;
  margin-bottom: var(--spacing-12);
}

.metrics-label {
  font-size: var(--typography-fontSize-sm);
  font-weight: var(--typography-fontWeight-semibold);
  color: var(--color-primary-base);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 0 0 var(--spacing-2) 0;
}

.metrics-title {
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-5xl);
  font-weight: var(--typography-fontWeight-bold);
  color: var(--color-text-primary);
  margin: 0 0 var(--spacing-4) 0;
  line-height: var(--typography-lineHeight-tight);
}

.metrics-subtitle {
  font-size: var(--typography-fontSize-lg);
  color: var(--color-text-secondary);
  max-width: 600px;
  margin: 0 auto;
  line-height: var(--typography-lineHeight-normal);
}

.metrics-section {
  margin-bottom: var(--spacing-10);
}

.metrics-section-title {
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-xl);
  font-weight: var(--typography-fontWeight-semibold);
  color: var(--color-text-primary);
  margin: 0 0 var(--spacing-4) 0;
}

.metrics-info {
  margin-top: var(--spacing-10);
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 768px) {
  .metrics-page {
    padding: var(--spacing-6) var(--spacing-4);
  }

  .metrics-title {
    font-size: var(--typography-fontSize-3xl);
  }
}
```

- [ ] **Step 4: Commit route**

```bash
git add apps/web/src/app/metrics/
git commit -m "feat(web): add /metrics route with MetricsPanel showcase"
```

---

## Task 8: Project 2 — MetricsPanel Integration

**Files:**
- Modify: `apps/web/src/app/layout.tsx`
- Modify: `apps/web/src/app/page.tsx`
- Modify: `apps/web/src/app/dashboard/ProjectDashboard.tsx`
- Modify: `apps/web/src/app/design-system/DesignSystem.tsx`

- [ ] **Step 1: Add nav link**

In layout.tsx, after the Testimonials link, add:

```tsx
              <a href="/metrics" className="demo-header__link">
                Metrics
              </a>
```

- [ ] **Step 2: Update landing page stats**

In page.tsx: token count `133` → `145`, component count `6` → `7`, component list add `MetricsPanel`. Stats bar: `133` → `145`, `6` → `7`.

- [ ] **Step 3: Sync dashboard**

In ProjectDashboard.tsx: p1 tokenCount `133` → `145`, p2 componentCount `6` → `7`, p5 tokenCount `133` → `145` componentCount `6` → `7`, p7 tokenCount `133` → `145` componentCount `6` → `7`.

- [ ] **Step 4: Add to catalog**

In DesignSystem.tsx, add `MetricsPanel` to import. After TestimonialWall Card, add:

```tsx
        <Card title="Metrics Panel">
          <div className="ds-component-group">
            <h4 className="ds-component-group__label">KPI Grid</h4>
            <MetricsPanel
              metrics={[
                { label: "Revenue", value: "$48K", trend: "up", trendValue: "+12%", status: "good" },
                { label: "Users", value: "2.8K", trend: "up", trendValue: "+8%", status: "good" },
                { label: "Churn", value: "3.2%", trend: "down", trendValue: "-0.4%", status: "warning" },
              ]}
              columns={3}
            />
          </div>
        </Card>
```

Update Usage tab to include MetricsPanel.

- [ ] **Step 5: Build and verify**

Run: `cd apps/web && npx next build`

Expected: 8 routes all build successfully.

- [ ] **Step 6: Commit**

```bash
git add apps/web/src/app/layout.tsx apps/web/src/app/page.tsx apps/web/src/app/dashboard/ProjectDashboard.tsx apps/web/src/app/design-system/DesignSystem.tsx
git commit -m "feat(web): integrate MetricsPanel — nav, stats (145 tokens/7 components), catalog"
```

---

## Task 9: Project 3 — AuthorBioCard Tokens

**Files:**
- Modify: `packages/tokens/src/tokens.json`

- [ ] **Step 1: Add author bio tokens**

In `packages/tokens/src/tokens.json`, inside `"components"`, after `"metricsPanel"`, add:

```json
    "authorBio": {
      "background": { "$value": "{color.background.card}", "$type": "color" },
      "borderRadius": { "$value": "{borderRadius.lg}", "$type": "dimension" },
      "padding": { "$value": "{spacing.6}", "$type": "dimension" },
      "border": { "$value": "{color.border.default}", "$type": "color" },
      "avatarSize": { "$value": "64px", "$type": "dimension" },
      "avatarBorder": { "$value": "{color.primary.base}", "$type": "color" },
      "nameColor": { "$value": "{color.text.primary}", "$type": "color" },
      "roleColor": { "$value": "{color.primary.base}", "$type": "color" },
      "bioColor": { "$value": "{color.text.secondary}", "$type": "color" },
      "socialColor": { "$value": "{color.text.muted}", "$type": "color" },
      "socialHover": { "$value": "{color.primary.base}", "$type": "color" },
      "badgeBackground": { "$value": "{color.background.elevated}", "$type": "color" },
      "badgeText": { "$value": "{color.primary.base}", "$type": "color" }
    }
```

That's 13 tokens.

- [ ] **Step 2: Build and verify**

Run: `python3 packages/tokens/build.py`

Expected: 158 tokens (145 + 13).

- [ ] **Step 3: Commit**

```bash
git add packages/tokens/src/tokens.json
git commit -m "feat(tokens): add 13 authorBio component tokens for AuthorBioCard"
```

---

## Task 10: Project 3 — AuthorBioCard Component

**Files:**
- Create: `packages/ui/src/components/AuthorBioCard.tsx`
- Modify: `packages/ui/src/styles.css`
- Modify: `packages/ui/src/index.ts`

- [ ] **Step 1: Create AuthorBioCard component**

Create `packages/ui/src/components/AuthorBioCard.tsx`:

```tsx
"use client";

import type { HTMLAttributes } from "react";

export interface SocialLink {
  platform: string;
  url: string;
  label?: string;
}

export interface AuthorProfile {
  name: string;
  role: string;
  avatarUrl?: string;
  bio: string;
  articleCount?: number;
  socialLinks?: SocialLink[];
}

export interface AuthorBioCardProps extends HTMLAttributes<HTMLDivElement> {
  author: AuthorProfile;
  layout?: "vertical" | "horizontal";
}

const platformIcons: Record<string, string> = {
  twitter: "\u{1D54F}",
  linkedin: "in",
  github: "\u{2B22}",
  website: "\u{1F310}",
};

export function AuthorBioCard({
  author,
  layout = "vertical",
  className = "",
  ...props
}: AuthorBioCardProps) {
  const classes = ["ac-author-bio", `ac-author-bio--${layout}`, className]
    .filter(Boolean)
    .join(" ");

  return (
    <div className={classes} {...props}>
      <div className="ac-author-bio__visual">
        {author.avatarUrl ? (
          <img
            src={author.avatarUrl}
            alt={author.name}
            className="ac-author-bio__avatar"
          />
        ) : (
          <div className="ac-author-bio__avatar ac-author-bio__avatar--placeholder">
            {author.name.charAt(0).toUpperCase()}
          </div>
        )}
        {author.articleCount !== undefined && (
          <span className="ac-author-bio__badge">
            {author.articleCount} article{author.articleCount !== 1 ? "s" : ""}
          </span>
        )}
      </div>

      <div className="ac-author-bio__content">
        <h3 className="ac-author-bio__name">{author.name}</h3>
        <p className="ac-author-bio__role">{author.role}</p>
        <p className="ac-author-bio__bio">{author.bio}</p>

        {author.socialLinks && author.socialLinks.length > 0 && (
          <div className="ac-author-bio__social">
            {author.socialLinks.map((link) => (
              <a
                key={link.platform}
                href={link.url}
                className="ac-author-bio__social-link"
                title={link.label || link.platform}
                target="_blank"
                rel="noopener noreferrer"
              >
                {platformIcons[link.platform] || link.platform}
              </a>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
```

- [ ] **Step 2: Add AuthorBioCard CSS**

Append to `packages/ui/src/styles.css`:

```css
/* Author Bio Card */
.ac-author-bio {
  background: var(--components-authorBio-background);
  border-radius: var(--components-authorBio-borderRadius);
  padding: var(--components-authorBio-padding);
  border: 1px solid var(--components-authorBio-border);
}

.ac-author-bio--vertical {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--spacing-4);
}

.ac-author-bio--horizontal {
  display: flex;
  align-items: flex-start;
  gap: var(--spacing-6);
}

.ac-author-bio__visual {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-2);
  flex-shrink: 0;
}

.ac-author-bio__avatar {
  width: var(--components-authorBio-avatarSize);
  height: var(--components-authorBio-avatarSize);
  border-radius: var(--borderRadius-full);
  border: 2px solid var(--components-authorBio-avatarBorder);
  object-fit: cover;
}

.ac-author-bio__avatar--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-background-elevated);
  color: var(--color-primary-base);
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-2xl);
  font-weight: var(--typography-fontWeight-semibold);
}

.ac-author-bio__badge {
  font-size: var(--typography-fontSize-xs);
  font-weight: var(--typography-fontWeight-medium);
  color: var(--components-authorBio-badgeText);
  background: var(--components-authorBio-badgeBackground);
  padding: var(--spacing-1) var(--spacing-3);
  border-radius: var(--borderRadius-full);
  white-space: nowrap;
}

.ac-author-bio__content {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-2);
}

.ac-author-bio__name {
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-lg);
  font-weight: var(--typography-fontWeight-semibold);
  color: var(--components-authorBio-nameColor);
  margin: 0;
}

.ac-author-bio__role {
  font-size: var(--typography-fontSize-sm);
  font-weight: var(--typography-fontWeight-medium);
  color: var(--components-authorBio-roleColor);
  margin: 0;
}

.ac-author-bio__bio {
  font-size: var(--typography-fontSize-sm);
  color: var(--components-authorBio-bioColor);
  line-height: var(--typography-lineHeight-relaxed);
  margin: 0;
}

.ac-author-bio__social {
  display: flex;
  gap: var(--spacing-3);
  margin-top: var(--spacing-2);
}

.ac-author-bio--vertical .ac-author-bio__social {
  justify-content: center;
}

.ac-author-bio__social-link {
  font-size: var(--typography-fontSize-sm);
  color: var(--components-authorBio-socialColor);
  text-decoration: none;
  transition: color 0.15s ease;
}

.ac-author-bio__social-link:hover {
  color: var(--components-authorBio-socialHover);
}
```

- [ ] **Step 3: Add barrel exports**

Add to `packages/ui/src/index.ts`:

```typescript
export { AuthorBioCard } from "./components/AuthorBioCard";
export type { AuthorBioCardProps, AuthorProfile, SocialLink } from "./components/AuthorBioCard";
```

- [ ] **Step 4: Commit**

```bash
git add packages/ui/src/components/AuthorBioCard.tsx packages/ui/src/styles.css packages/ui/src/index.ts
git commit -m "feat(ui): add AuthorBioCard component with vertical/horizontal layouts"
```

---

## Task 11: Project 3 — AuthorBioCard Route

**Files:**
- Create: `apps/web/src/app/authors/page.tsx`
- Create: `apps/web/src/app/authors/AuthorsShowcase.tsx`
- Create: `apps/web/src/app/authors/authors.css`

- [ ] **Step 1: Create route page**

Create `apps/web/src/app/authors/page.tsx`:

```tsx
import type { Metadata } from "next";
import "./authors.css";
import AuthorsShowcase from "./AuthorsShowcase";

export const metadata: Metadata = {
  title: "Authors | CMS-aiChemist",
  description:
    "Editorial author profiles — AuthorBioCard component from the shared UI library",
};

export default function AuthorsPage() {
  return <AuthorsShowcase />;
}
```

- [ ] **Step 2: Create showcase component**

Create `apps/web/src/app/authors/AuthorsShowcase.tsx`:

```tsx
"use client";

import { AuthorBioCard, Alert } from "../../../../../packages/ui/src";
import type { AuthorProfile } from "../../../../../packages/ui/src";

const authors: AuthorProfile[] = [
  {
    name: "Alexandra Torres",
    role: "Senior Editor",
    bio: "Alexandra covers enterprise technology and digital transformation. She has 15 years of experience in tech journalism and previously led editorial at TechReview.",
    articleCount: 142,
    socialLinks: [
      { platform: "twitter", url: "#", label: "Twitter" },
      { platform: "linkedin", url: "#", label: "LinkedIn" },
    ],
  },
  {
    name: "Michael Chang",
    role: "Staff Writer, Design Systems",
    bio: "Michael specializes in design systems, component architecture, and the intersection of design and engineering. He maintains the Design Tokens Community Group blog.",
    articleCount: 87,
    socialLinks: [
      { platform: "twitter", url: "#", label: "Twitter" },
      { platform: "github", url: "#", label: "GitHub" },
      { platform: "website", url: "#", label: "Personal site" },
    ],
  },
  {
    name: "Priya Sharma",
    role: "Contributing Editor, AI & Automation",
    bio: "Priya writes about AI-powered development workflows, agentic systems, and the future of content operations. She consults for Fortune 500 companies on AI adoption.",
    articleCount: 63,
    socialLinks: [
      { platform: "linkedin", url: "#", label: "LinkedIn" },
      { platform: "website", url: "#", label: "Blog" },
    ],
  },
  {
    name: "Robert Kim",
    role: "Technical Reviewer",
    bio: "Robert ensures technical accuracy across all published content. A former principal engineer at AWS, he brings deep infrastructure and DevOps expertise to every review.",
    articleCount: 31,
    socialLinks: [
      { platform: "github", url: "#", label: "GitHub" },
    ],
  },
];

export default function AuthorsShowcase() {
  return (
    <section className="authors-page">
      <a href="/" className="authors-back-link">
        &larr; Home
      </a>

      <header className="authors-header">
        <p className="authors-label">Editorial Team</p>
        <h1 className="authors-title">Our Authors</h1>
        <p className="authors-subtitle">
          Meet the experts behind the content. Each profile is rendered with the
          AuthorBioCard component, consuming tokens from the DTCG pipeline.
        </p>
      </header>

      <div className="authors-grid">
        {authors.map((author) => (
          <AuthorBioCard key={author.name} author={author} />
        ))}
      </div>

      <div className="authors-info">
        <Alert variant="info">
          This is a demo of the shared <strong>AuthorBioCard</strong> component
          from packages/ui. All styling is driven by 13 dedicated author bio
          tokens in the DTCG pipeline.
        </Alert>
      </div>
    </section>
  );
}
```

- [ ] **Step 3: Create route CSS**

Create `apps/web/src/app/authors/authors.css`:

```css
.authors-page {
  padding: var(--spacing-8) var(--spacing-6);
  max-width: 1100px;
  margin: 0 auto;
}

.authors-back-link {
  display: inline-block;
  color: var(--color-text-muted);
  font-size: var(--typography-fontSize-sm);
  text-decoration: none;
  margin-bottom: var(--spacing-6);
  transition: color 0.15s ease;
}

.authors-back-link:hover {
  color: var(--color-text-primary);
}

.authors-header {
  text-align: center;
  margin-bottom: var(--spacing-12);
}

.authors-label {
  font-size: var(--typography-fontSize-sm);
  font-weight: var(--typography-fontWeight-semibold);
  color: var(--color-primary-base);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 0 0 var(--spacing-2) 0;
}

.authors-title {
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-5xl);
  font-weight: var(--typography-fontWeight-bold);
  color: var(--color-text-primary);
  margin: 0 0 var(--spacing-4) 0;
  line-height: var(--typography-lineHeight-tight);
}

.authors-subtitle {
  font-size: var(--typography-fontSize-lg);
  color: var(--color-text-secondary);
  max-width: 600px;
  margin: 0 auto;
  line-height: var(--typography-lineHeight-normal);
}

.authors-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--spacing-6);
}

.authors-info {
  margin-top: var(--spacing-10);
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 768px) {
  .authors-page {
    padding: var(--spacing-6) var(--spacing-4);
  }

  .authors-title {
    font-size: var(--typography-fontSize-3xl);
  }
}
```

- [ ] **Step 4: Commit**

```bash
git add apps/web/src/app/authors/
git commit -m "feat(web): add /authors route with AuthorBioCard showcase"
```

---

## Task 12: Project 3 — AuthorBioCard Integration

**Files:**
- Modify: `apps/web/src/app/layout.tsx`
- Modify: `apps/web/src/app/page.tsx`
- Modify: `apps/web/src/app/dashboard/ProjectDashboard.tsx`
- Modify: `apps/web/src/app/design-system/DesignSystem.tsx`

- [ ] **Step 1: Add nav link, update stats, sync dashboard, add to catalog**

Same pattern as Tasks 4 and 8:
- Nav: add `Authors` link after Metrics
- Stats: tokens `145` → `158`, components `7` → `8`, component list add `AuthorBioCard`
- Dashboard: sync p1 tokenCount to `158`, p2 componentCount to `8`, p5/p7 to match
- Catalog: import AuthorBioCard, add card with 2-author demo, update Usage tab

Catalog card to add:

```tsx
        <Card title="Author Bio Card">
          <div className="ds-component-group">
            <h4 className="ds-component-group__label">Vertical Layout</h4>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(250px, 1fr))", gap: "var(--spacing-4)" }}>
              <AuthorBioCard
                author={{
                  name: "Jane Writer",
                  role: "Senior Editor",
                  bio: "Covers enterprise technology and design systems.",
                  articleCount: 42,
                  socialLinks: [{ platform: "twitter", url: "#" }],
                }}
              />
              <AuthorBioCard
                author={{
                  name: "Alex Dev",
                  role: "Staff Engineer",
                  bio: "Specializes in component architecture and tokens.",
                  articleCount: 28,
                  socialLinks: [{ platform: "github", url: "#" }],
                }}
              />
            </div>
          </div>
        </Card>
```

- [ ] **Step 2: Build and verify**

Run: `cd apps/web && npx next build`

Expected: 9 routes all build successfully.

- [ ] **Step 3: Commit**

```bash
git add apps/web/src/app/layout.tsx apps/web/src/app/page.tsx apps/web/src/app/dashboard/ProjectDashboard.tsx apps/web/src/app/design-system/DesignSystem.tsx
git commit -m "feat(web): integrate AuthorBioCard — nav, stats (158 tokens/8 components), catalog"
```

---

## Task 13: Project 4 — FeatureComparisonTable Tokens

**Files:**
- Modify: `packages/tokens/src/tokens.json`

- [ ] **Step 1: Add comparison table tokens**

In `packages/tokens/src/tokens.json`, inside `"components"`, after `"authorBio"`, add:

```json
    "comparisonTable": {
      "background": { "$value": "{color.background.card}", "$type": "color" },
      "headerBackground": { "$value": "{color.background.elevated}", "$type": "color" },
      "borderRadius": { "$value": "{borderRadius.lg}", "$type": "dimension" },
      "border": { "$value": "{color.border.default}", "$type": "color" },
      "rowStripe": { "$value": "rgba(167, 139, 250, 0.04)", "$type": "color" },
      "headerText": { "$value": "{color.text.primary}", "$type": "color" },
      "cellText": { "$value": "{color.text.secondary}", "$type": "color" },
      "checkColor": { "$value": "{color.status.success}", "$type": "color" },
      "crossColor": { "$value": "{color.status.error}", "$type": "color" },
      "partialColor": { "$value": "{color.status.warning}", "$type": "color" },
      "featureLabelColor": { "$value": "{color.text.primary}", "$type": "color" },
      "tooltipBackground": { "$value": "{color.background.elevated}", "$type": "color" },
      "tooltipText": { "$value": "{color.text.primary}", "$type": "color" }
    }
```

That's 13 tokens.

- [ ] **Step 2: Build and verify**

Run: `python3 packages/tokens/build.py`

Expected: 171 tokens (158 + 13).

- [ ] **Step 3: Commit**

```bash
git add packages/tokens/src/tokens.json
git commit -m "feat(tokens): add 13 comparisonTable component tokens for FeatureComparisonTable"
```

---

## Task 14: Project 4 — FeatureComparisonTable Component

**Files:**
- Create: `packages/ui/src/components/FeatureComparisonTable.tsx`
- Modify: `packages/ui/src/styles.css`
- Modify: `packages/ui/src/index.ts`

- [ ] **Step 1: Create FeatureComparisonTable component**

Create `packages/ui/src/components/FeatureComparisonTable.tsx`:

```tsx
"use client";

import type { HTMLAttributes } from "react";

export type FeatureSupport = "yes" | "no" | "partial";

export interface ComparisonFeature {
  name: string;
  tooltip?: string;
  values: FeatureSupport[];
}

export interface ComparisonColumn {
  name: string;
  highlighted?: boolean;
}

export interface FeatureComparisonTableProps extends HTMLAttributes<HTMLDivElement> {
  columns: ComparisonColumn[];
  features: ComparisonFeature[];
}

const supportIcons: Record<FeatureSupport, { symbol: string; label: string; className: string }> = {
  yes: { symbol: "\u2713", label: "Included", className: "ac-comparison__icon--check" },
  no: { symbol: "\u2717", label: "Not included", className: "ac-comparison__icon--cross" },
  partial: { symbol: "\u25D0", label: "Partial support", className: "ac-comparison__icon--partial" },
};

export function FeatureComparisonTable({
  columns,
  features,
  className = "",
  ...props
}: FeatureComparisonTableProps) {
  const classes = ["ac-comparison-table", className].filter(Boolean).join(" ");

  return (
    <div className={classes} {...props}>
      <div className="ac-comparison__wrapper" role="region" aria-label="Feature comparison" tabIndex={0}>
        <table className="ac-comparison" role="table">
          <thead>
            <tr>
              <th scope="col" className="ac-comparison__feature-header">Feature</th>
              {columns.map((col) => (
                <th
                  key={col.name}
                  scope="col"
                  className={`ac-comparison__col-header${col.highlighted ? " ac-comparison__col-header--highlighted" : ""}`}
                >
                  {col.name}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {features.map((feature, rowIndex) => (
              <tr
                key={feature.name}
                className={rowIndex % 2 === 1 ? "ac-comparison__row--stripe" : ""}
              >
                <td className="ac-comparison__feature-cell">
                  {feature.name}
                  {feature.tooltip && (
                    <span
                      className="ac-comparison__tooltip-trigger"
                      title={feature.tooltip}
                      aria-label={feature.tooltip}
                    >
                      ?
                    </span>
                  )}
                </td>
                {feature.values.map((val, colIndex) => {
                  const icon = supportIcons[val];
                  return (
                    <td
                      key={columns[colIndex].name}
                      className="ac-comparison__value-cell"
                      aria-label={`${columns[colIndex].name}: ${icon.label}`}
                    >
                      <span className={`ac-comparison__icon ${icon.className}`} aria-hidden="true">
                        {icon.symbol}
                      </span>
                    </td>
                  );
                })}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}
```

- [ ] **Step 2: Add FeatureComparisonTable CSS**

Append to `packages/ui/src/styles.css`:

```css
/* Feature Comparison Table */
.ac-comparison-table {
  background: var(--components-comparisonTable-background);
  border-radius: var(--components-comparisonTable-borderRadius);
  border: 1px solid var(--components-comparisonTable-border);
  overflow: hidden;
}

.ac-comparison__wrapper {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.ac-comparison {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--typography-fontFamily-body);
  font-size: var(--typography-fontSize-sm);
}

.ac-comparison__feature-header,
.ac-comparison__col-header {
  background: var(--components-comparisonTable-headerBackground);
  padding: var(--spacing-4);
  font-weight: var(--typography-fontWeight-semibold);
  color: var(--components-comparisonTable-headerText);
  text-align: center;
  border-bottom: 1px solid var(--components-comparisonTable-border);
}

.ac-comparison__feature-header {
  text-align: left;
  min-width: 200px;
}

.ac-comparison__col-header--highlighted {
  color: var(--color-primary-base);
  position: relative;
}

.ac-comparison__col-header--highlighted::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--color-primary-base);
}

.ac-comparison__row--stripe td {
  background: var(--components-comparisonTable-rowStripe);
}

.ac-comparison__feature-cell {
  padding: var(--spacing-3) var(--spacing-4);
  color: var(--components-comparisonTable-featureLabelColor);
  font-weight: var(--typography-fontWeight-medium);
  border-bottom: 1px solid var(--components-comparisonTable-border);
  display: flex;
  align-items: center;
  gap: var(--spacing-2);
}

.ac-comparison__tooltip-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: var(--borderRadius-full);
  background: var(--components-comparisonTable-tooltipBackground);
  color: var(--components-comparisonTable-tooltipText);
  font-size: 10px;
  font-weight: var(--typography-fontWeight-bold);
  cursor: help;
  flex-shrink: 0;
}

.ac-comparison__value-cell {
  padding: var(--spacing-3) var(--spacing-4);
  text-align: center;
  border-bottom: 1px solid var(--components-comparisonTable-border);
}

.ac-comparison__icon {
  font-size: var(--typography-fontSize-base);
}

.ac-comparison__icon--check { color: var(--components-comparisonTable-checkColor); }
.ac-comparison__icon--cross { color: var(--components-comparisonTable-crossColor); }
.ac-comparison__icon--partial { color: var(--components-comparisonTable-partialColor); }
```

- [ ] **Step 3: Add barrel exports**

Add to `packages/ui/src/index.ts`:

```typescript
export { FeatureComparisonTable } from "./components/FeatureComparisonTable";
export type {
  FeatureComparisonTableProps,
  ComparisonFeature,
  ComparisonColumn,
  FeatureSupport,
} from "./components/FeatureComparisonTable";
```

- [ ] **Step 4: Commit**

```bash
git add packages/ui/src/components/FeatureComparisonTable.tsx packages/ui/src/styles.css packages/ui/src/index.ts
git commit -m "feat(ui): add accessible FeatureComparisonTable with ARIA and semantic HTML"
```

---

## Task 15: Project 4 — FeatureComparisonTable Route

**Files:**
- Create: `apps/web/src/app/compare/page.tsx`
- Create: `apps/web/src/app/compare/CompareShowcase.tsx`
- Create: `apps/web/src/app/compare/compare.css`

- [ ] **Step 1: Create route page**

Create `apps/web/src/app/compare/page.tsx`:

```tsx
import type { Metadata } from "next";
import "./compare.css";
import CompareShowcase from "./CompareShowcase";

export const metadata: Metadata = {
  title: "Compare | CMS-aiChemist",
  description:
    "Feature comparison table — FeatureComparisonTable component from the shared UI library",
};

export default function ComparePage() {
  return <CompareShowcase />;
}
```

- [ ] **Step 2: Create showcase component**

Create `apps/web/src/app/compare/CompareShowcase.tsx`:

```tsx
"use client";

import { FeatureComparisonTable, Alert } from "../../../../../packages/ui/src";
import type { ComparisonColumn, ComparisonFeature } from "../../../../../packages/ui/src";

const columns: ComparisonColumn[] = [
  { name: "Starter" },
  { name: "Pro", highlighted: true },
  { name: "Enterprise" },
];

const features: ComparisonFeature[] = [
  {
    name: "Design Systems",
    tooltip: "Number of concurrent design system projects",
    values: ["partial", "yes", "yes"],
  },
  {
    name: "Design Tokens",
    tooltip: "DTCG-format token pipeline with CSS output",
    values: ["partial", "yes", "yes"],
  },
  {
    name: "Shared Components",
    values: ["yes", "yes", "yes"],
  },
  {
    name: "Penpot Integration",
    tooltip: "MCP-based Penpot design-to-code workflow",
    values: ["no", "yes", "yes"],
  },
  {
    name: "ADW Pipeline",
    tooltip: "Agentic Development Workflow — issue to implementation",
    values: ["no", "yes", "yes"],
  },
  {
    name: "CSA Artifacts",
    tooltip: "Communication & Stakeholder Artifact generation",
    values: ["no", "yes", "yes"],
  },
  {
    name: "Multi-Surface Deploy",
    tooltip: "Deploy to both Next.js and Astro surfaces",
    values: ["no", "partial", "yes"],
  },
  {
    name: "NotebookLM Brain",
    tooltip: "AI brain integration for orchestration memory",
    values: ["no", "no", "yes"],
  },
  {
    name: "SSO / SAML",
    values: ["no", "no", "yes"],
  },
  {
    name: "SLA Guarantee",
    values: ["no", "no", "yes"],
  },
  {
    name: "Dedicated Support",
    values: ["no", "no", "yes"],
  },
  {
    name: "White-Label",
    tooltip: "Custom branding on all generated surfaces",
    values: ["no", "no", "yes"],
  },
];

export default function CompareShowcase() {
  return (
    <section className="compare-page">
      <a href="/" className="compare-back-link">
        &larr; Home
      </a>

      <header className="compare-header">
        <p className="compare-label">Plan Comparison</p>
        <h1 className="compare-title">Compare Features</h1>
        <p className="compare-subtitle">
          See which features are included in each plan. The comparison table
          uses semantic HTML and ARIA attributes for full accessibility.
        </p>
      </header>

      <FeatureComparisonTable columns={columns} features={features} />

      <div className="compare-info">
        <Alert variant="info">
          This is a demo of the shared <strong>FeatureComparisonTable</strong>{" "}
          component from packages/ui. It uses semantic{" "}
          <code>&lt;table&gt;</code> markup with ARIA roles for screen reader
          support. All colors are driven by 13 dedicated tokens.
        </Alert>
      </div>
    </section>
  );
}
```

- [ ] **Step 3: Create route CSS**

Create `apps/web/src/app/compare/compare.css`:

```css
.compare-page {
  padding: var(--spacing-8) var(--spacing-6);
  max-width: 1100px;
  margin: 0 auto;
}

.compare-back-link {
  display: inline-block;
  color: var(--color-text-muted);
  font-size: var(--typography-fontSize-sm);
  text-decoration: none;
  margin-bottom: var(--spacing-6);
  transition: color 0.15s ease;
}

.compare-back-link:hover {
  color: var(--color-text-primary);
}

.compare-header {
  text-align: center;
  margin-bottom: var(--spacing-12);
}

.compare-label {
  font-size: var(--typography-fontSize-sm);
  font-weight: var(--typography-fontWeight-semibold);
  color: var(--color-primary-base);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 0 0 var(--spacing-2) 0;
}

.compare-title {
  font-family: var(--typography-fontFamily-heading);
  font-size: var(--typography-fontSize-5xl);
  font-weight: var(--typography-fontWeight-bold);
  color: var(--color-text-primary);
  margin: 0 0 var(--spacing-4) 0;
  line-height: var(--typography-lineHeight-tight);
}

.compare-subtitle {
  font-size: var(--typography-fontSize-lg);
  color: var(--color-text-secondary);
  max-width: 600px;
  margin: 0 auto;
  line-height: var(--typography-lineHeight-normal);
}

.compare-info {
  margin-top: var(--spacing-10);
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 768px) {
  .compare-page {
    padding: var(--spacing-6) var(--spacing-4);
  }

  .compare-title {
    font-size: var(--typography-fontSize-3xl);
  }
}
```

- [ ] **Step 4: Commit**

```bash
git add apps/web/src/app/compare/
git commit -m "feat(web): add /compare route with accessible FeatureComparisonTable showcase"
```

---

## Task 16: Project 4 — FeatureComparisonTable Integration

**Files:**
- Modify: `apps/web/src/app/layout.tsx`
- Modify: `apps/web/src/app/page.tsx`
- Modify: `apps/web/src/app/dashboard/ProjectDashboard.tsx`
- Modify: `apps/web/src/app/design-system/DesignSystem.tsx`

- [ ] **Step 1: Add nav, stats, dashboard, catalog**

Same pattern:
- Nav: add `Compare` link after Authors
- Stats: tokens `158` → `171`, components `8` → `9`, add `FeatureComparisonTable`
- Dashboard: sync all counts to 171/9
- Catalog: import FeatureComparisonTable, add card:

```tsx
        <Card title="Feature Comparison Table">
          <div className="ds-component-group">
            <h4 className="ds-component-group__label">Accessible Data Table</h4>
            <FeatureComparisonTable
              columns={[
                { name: "Basic" },
                { name: "Pro", highlighted: true },
              ]}
              features={[
                { name: "Tokens", values: ["partial", "yes"] },
                { name: "Components", values: ["yes", "yes"] },
                { name: "ADW Pipeline", values: ["no", "yes"] },
              ]}
            />
          </div>
        </Card>
```

Update Usage tab to include all 9 components.

- [ ] **Step 2: Build and verify**

Run: `cd apps/web && npx next build`

Expected: 10 routes all build successfully.

- [ ] **Step 3: Commit**

```bash
git add apps/web/src/app/layout.tsx apps/web/src/app/page.tsx apps/web/src/app/dashboard/ProjectDashboard.tsx apps/web/src/app/design-system/DesignSystem.tsx
git commit -m "feat(web): integrate FeatureComparisonTable — nav, stats (171 tokens/9 components), catalog"
```

---

## Task 17: Final Build Verification & Brain Push

**Files:** No new files

- [ ] **Step 1: Full build verification**

Run: `cd apps/web && npx next build`

Verify all 10 routes build: `/`, `/dashboard`, `/design-system`, `/kaleido-life`, `/pricing`, `/testimonials`, `/metrics`, `/authors`, `/compare`.

- [ ] **Step 2: Token count verification**

Run: `python3 packages/tokens/build.py`

Expected: 171 tokens.

- [ ] **Step 3: Component count verification**

Run: `ls packages/ui/src/components/`

Expected: 9 files — Button.tsx, Card.tsx, Tabs.tsx, Alert.tsx, PricingTable.tsx, TestimonialWall.tsx, MetricsPanel.tsx, AuthorBioCard.tsx, FeatureComparisonTable.tsx

- [ ] **Step 4: Grep verification**

```bash
grep -c '"$value"' packages/tokens/src/tokens.json
# Expected: 171

grep -c 'export {' packages/ui/src/index.ts
# Expected: 9

grep -c 'demo-header__link' apps/web/src/app/layout.tsx
# Expected: 9 (Platform, Dashboard, Design System, Kaleido-Life, Pricing, Testimonials, Metrics, Authors, Compare)
```

- [ ] **Step 5: Push milestone to brain**

```bash
bash ops/brain/brain-push.sh "ICP E2E Test Projects — All 4 Complete" \
  "Completed 4 ICP-aligned E2E test projects exercising the full pipeline:
  1. TestimonialWall (Digital Agency) — 12 tokens, social proof grid
  2. MetricsPanel (SaaS Product) — 12 tokens, KPI dashboard with trends
  3. AuthorBioCard (Content Publisher) — 13 tokens, editorial profiles
  4. FeatureComparisonTable (Enterprise) — 13 tokens, accessible data table

  Final counts: 171 DTCG tokens, 9 shared components, 10 Next.js routes.
  All builds pass. Design system catalog updated with all components."
```

- [ ] **Step 6: Commit verification results**

```bash
git add -A
git commit -m "chore: mark ICP E2E test projects complete — 171 tokens, 9 components, 10 routes"
```
