# Agent guide — `@colorpalette/core`

Brand color systems for AI / agency agents. **Deterministic**, **auditable**, **no DOM**.

| | |
|--|--|
| Contract | [`api-types.md`](./api-types.md) (`contractVersion: 1.0.0`) |
| Package | [`packages/core`](../packages/core) |
| Primer | [Brand Color Suggestion API for AI Agents.md](./Brand%20Color%20Suggestion%20API%20for%20AI%20Agents.md) |
| Fixtures | [`packages/core/fixtures`](../packages/core/fixtures) |
| MCP (optional) | [`packages/mcp`](../packages/mcp) |

**Do not** import `js/studio-bridge.js` or `@colorpalette/browser` from agent runtimes unless the host explicitly needs URL/image extract or file download.

---

## Install / import

This repo is static ESM (no publish required):

```js
import {
  suggestFromSeed,
  suggestFromPreset,
  suggestFromExtractedColors,
  suggestCombinations,
  listPresets,
  exportDesignTokens,
  auditPalette,
  buildBrandScale,
  suggestHarmony,
} from "../packages/core/index.js";
```

---

## Intent APIs

| Call | Use when |
|------|----------|
| `suggestBrand(brief)` | Full pipeline from a `BrandBrief` |
| `suggestFromSeed(hex, opts?)` | Known brand seed |
| `suggestFromPreset(id, opts?)` | Catalogue recipe |
| `suggestFromExtractedColors(colors[], opts?)` | Host already scraped URL/image colors |
| `listPresets({ mode?, industry?, pack?, q? })` | Browse recipes |
| `buildBrandScale` / `buildNeutrals` / `suggestHarmony` | Scale / Harmony only |
| `buildContrastMatrix(system \| scales, opts?)` | Brand×neutral/theme WCAG (+ APCA) grid |
| `buildRoleScales(seed, roles?, opts?)` | Secondary / tertiary / status ramps |
| `suggestCombinations(seed, opts?)` | Ranked color-theory recipes (`strategy`, ΔE, scores) |
| `rankedHarmonyStrategies(industry)` | Industry → strategy order (catalogue) |
| `patchStop` / `rescaleFromStop` / `applyStopPatch` | Per-stop edit & ramp rebuild |
| `formatColor` / `enrichStop` | Notation projections |
| `exportDesignTokens(system, { format, notation? })` | css · tailwind · tokens.json · agent.json · scale.json · harmony.json |
| `auditPalette(system)` | WCAG or APCA pairs + neon APCA + gradient scrim |
| `APCA_TARGETS` | Preferred \|Lc\| body/large/ui when `target: 'APCA'` |
| `classifyMode({ industry, keywords })` | Mode hint without generating |

### Minimal seed → tokens

```js
const system = suggestFromSeed("#FF7800", {
  variantCount: 3,
  target: "AA",
  theme: "light",
});

// Ranked harmony variants on system.variants[]
console.log(system.variants.map((v) => v.harmony.strategy));
// Thin recipes (same ranking) on system.combinations[]
console.log(system.combinations.map((c) => `${c.strategy} ΔE=${c.separation}`));

const combos = suggestCombinations("#FF7800", { count: 4, industry: "saas" });

const agentJson = exportDesignTokens(system, {
  format: "agent.json",
  notations: ["hex", "hsl", "oklch", "rgb"],
});

const css = exportDesignTokens(system, {
  format: "css",
  notation: "oklch",
  theme: "light",
});
```

Industry biases which strategies are generated first (`catalogue/harmony-weights.v1.json`). Explicit `harmony` / `strategy` still pins first.

### Preset (neon / hybrid)

```js
const presets = listPresets({ mode: "neon", industry: "crypto" });
const system = suggestFromPreset(presets[0].id, { variantCount: 3 });
// system.mode === 'neon' → system.neon (60-30-10)
// hybrid presets → system.gradients[] with scrim
```

### Extracted colors (host did the fetch)

```js
// Browser host: extractColorsFromUrl → colors[]
const system = suggestFromExtractedColors(["#0F62FE", "#161616", "#F4F4F4"], {
  source: "website",
  variantCount: 3,
});
```

### Industry gate

```js
suggestFromSeed("#00CAFF", { preferMode: "neon", industry: "law" });
// → mode 'solid' + warning (unless forceNeon: true)
```

---

## Response shape (always)

Every `BrandSystem` includes:

- `version` — `1.0.0`
- `mode` — `solid` \| `neon` \| `gradient` \| `hybrid`
- `seed`, `brandScale`, `neutrals`, `status`, `harmony`, `themes`
- `audit` — scores + pair findings
- `warnings[]`, `provenance` — algorithms + params (citable)
- `variants[]` when `variantCount > 1`
- `combinations[]` — ranked recipes (`strategy`, `separation`, `auditScore`, `rankScore`, `colors`) mirroring variants
- `neon?` / `gradients?` when mode requires them

---

## MCP tools (optional adapter)

Thin wrappers in `packages/mcp` — same core functions, JSON-serializable args/results:

| Tool | Maps to |
|------|---------|
| `suggest_brand` | `suggestBrand` / `suggestFromSeed` |
| `suggest_combinations` | `suggestCombinations` |
| `list_presets` | `listPresets` |
| `audit_palette` | `auditPalette` on a prior system or seed |
| `export_tokens` | `exportDesignTokens` |

Discovery envelope: [`docs/oasf/`](./oasf/) (OASF record + skills/domains).

See [`packages/mcp/README.md`](../packages/mcp/README.md).

---

## CI fixtures

```bash
npm run test:core          # smoke
npm run test:fixtures      # golden snapshots
npm run fixtures:update    # regenerate goldens (intentional changes only)
```

Fixtures assert stable fields: seed, mode, strategies, neon accent, gradient style, audit score band — not float noise in every OKLCH channel.
