# Install the Brand Kit in Your Project

The MagicBlocks brand kit is published as a private npm family on **GitHub Packages**, scoped to `@magicblocksai`. This doc covers the one-time setup any consumer (the Spark CRM, the sales website, the 10DLC Wingman, future products) needs to install the packages.

The kit is **twenty-six chapters across five buckets** (Foundations, Building Blocks, Marketing, Operator, Embed) on the live demo site at [brand.magicblocks.ai/components/](https://brand.magicblocks.ai/components/), with 257 typed React components shipped via `@magicblocksai/ui`.

## What you get

| Package | What it ships | Use this when… |
|---|---|---|
| `@magicblocksai/css` | Drop-in CSS — every brand token + every component class (`.btn`, `.card`, `.input`, `.modal`, `.topnav`, `.table`, `.tag`, `.cmdk-overlay`, …). One file. | Static sites, vanilla JS, Astro, 11ty, Hugo, Next.js, anything. **Always start here.** |
| `@magicblocksai/ui` | Typed React components (257 in the barrel) — `Button`, `Modal`, `Drawer`, `Tabs`, `Toast`, `Card`, `DataTable`, `Kanban`, `EmailThread`, `Sage` drawer, the embeddable chat widget, the agent-builder query toolkit, the explainability trace timeline, etc. | React apps (Next.js, Vite + React, Remix). |
| `@magicblocksai/brand` | Pure JSON — brand tokens, asset registry, voice notes, content + HTML templates. Zero runtime deps. | AI agents, static-site builders, anywhere you want machine-readable brand data. |

Current published versions are shown live at [brand.magicblocks.ai/install](https://brand.magicblocks.ai/install).

`@magicblocksai/ui` and `@magicblocksai/css` ship lockstep — whenever shared CSS classes change, the pair bumps together so the version a consumer reaches for stays consistent.

## One-Time Setup — Auth Token

You need a **fine-grained personal access token (PAT)** with `read:packages` scope on the `MagicBlocksAI` GitHub org.

1. Go to https://github.com/settings/personal-access-tokens
2. **Generate new token** → choose **Fine-grained**
3. **Resource owner**: `MagicBlocksAI`
4. **Permissions** → **Repository permissions** → leave default
5. **Permissions** → **Account permissions** → set **Packages** to **Read-only** — this is the one that matters; without it the install 404s
6. Generate. Copy the token. Save it as `GITHUB_TOKEN` in your shell env / `.env` / CI secrets.

(For CI, use the built-in `secrets.GITHUB_TOKEN` — no PAT needed.)

## Per-Project Setup — `.npmrc`

In the **consumer repo's root**, create a `.npmrc`:

```ini
# Tells npm/pnpm to resolve @magicblocksai/* from GitHub Packages.
@magicblocksai:registry=https://npm.pkg.github.com

# Auth — reads from your shell env. Make sure GITHUB_TOKEN is exported.
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
```

**Monorepo / pnpm workspace:** put this at the **repo root** (the workspace root) — not inside a sub-package such as `apps/web/`. pnpm reads the workspace-root `.npmrc`, so a file at the root authenticates `pnpm install` whether it runs from the repo root **or** from any package inside it. A `.npmrc` placed only in a sub-folder works when you install from that folder, but fails — with an auth error on a cold cache — when the install runs from the root.

Then install:

```bash
npm install @magicblocksai/css
# Or, for a React project:
npm install @magicblocksai/ui @magicblocksai/css
# Or, if you want the brand JSON too:
npm install @magicblocksai/brand
```

## Use It

### Vanilla JS / Static Site / Astro / 11ty / Hugo

```html
<!-- Drop the CSS into your head once. Every kit class becomes available. -->
<link rel="stylesheet" href="/node_modules/@magicblocksai/css/dist/magicblocks.css">

<!-- Or via your bundler (Vite, Astro, etc.): -->
<script>import "@magicblocksai/css";</script>
```

Now markup like this works:

```html
<button class="btn btn-primary">Book a demo</button>
<input class="input" type="email" placeholder="you@company.com">
<div class="card">…</div>
```

### React (Next.js, Vite + React, Remix)

```tsx
// app/layout.tsx (Next.js) or src/main.tsx (Vite)
import "@magicblocksai/css";
import { Button, Modal, Toast } from "@magicblocksai/ui";

export default function Page() {
  return <Button variant="primary">Book a demo</Button>;
}
```

### Per-Surface Bundles (Optional, for CSS-Budget-Sensitive Projects)

The package exposes four focused bundles alongside the default monolith. Each surface bundle ships only the component CSS for that surface; `core` contains the shared primitives used across all of them.

| Consumer | Import |
|---|---|
| Everything (default) | `@magicblocksai/css` |
| Marketing site | `@magicblocksai/css/tokens` + `/core` + `/marketing` |
| Product app | `@magicblocksai/css/tokens` + `/core` + `/operator` |
| Widget embed | `@magicblocksai/css/tokens` + `/core` + `/embed` |

The `core` bundle is always imported after `tokens` — it contains the component primitives (buttons, forms, cards, overlays, navigation, data display) that all surfaces share. The surface bundles (`marketing`, `operator`, `embed`) layer on the CSS unique to that surface.

The monolith default (`@magicblocksai/css`) is byte-identical to importing all surfaces together and is the right choice when CSS budget is not a concern. Switch to the per-surface recipe only when you need to reduce the CSS shipped to a specific surface.

```js
// Marketing site — imports only tokens + core + marketing CSS
import "@magicblocksai/css/tokens";
import "@magicblocksai/css/core";
import "@magicblocksai/css/marketing";
```

### Tailwind Setup (Optional, for React Projects)

The kit ships theme bridges for **both** Tailwind v3 and v4. Pick the one that matches your app.

#### Tailwind v4 (CSS-First Config — Recommended for New Apps)

In your app's CSS entry (e.g. `app/globals.css` for Next.js, or `src/index.css` for Vite):

```css
@import "tailwindcss";
@import "@magicblocksai/css";
@import "@magicblocksai/ui/theme.css";
```

That's it — no `tailwind.config.{js,ts}` file needed. The `theme.css` declares an `@theme` block mapping every brand token to a Tailwind utility namespace, plus a `@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *))` rule so `dark:` utilities flip on `body[data-theme="dark"]` (matching the kit's strategy).

> **Z-index + duration utilities**: Tailwind v4 has no first-class theme key for these. Use arbitrary values: `z-[var(--z-modal)]`, `duration-[var(--dur-2)]`. The custom properties are declared in `@magicblocksai/css`.

> **`@import` ordering matters (Vite + Tailwind v4)**: any `@import url(…)` for webfonts must come **first**, before `@import "tailwindcss"`. Vite warns when `@import` rules follow non-`@import` declarations. If you're adding Google Fonts via `@import` inside this same CSS file, put that line at the very top of the file. (Reported by the 10DLC Wingman team, v1.39.0 — Wingman W-009.)

#### Tailwind v3 (JS Preset — Legacy)

```js
// tailwind.config.js
module.exports = {
  presets: [require("@magicblocksai/ui/tailwind.preset")],
  content: ["./app/**/*.{ts,tsx}", "./node_modules/@magicblocksai/ui/dist/**/*.js"],
};
```

Either path bridges every brand token (`text-accent`, `bg-paper`, `gap-s-3`, `rounded-lg`, `shadow-sh-2`, `font-display`) into Tailwind's utility classes.

## Versioning & Upgrades

- All three packages follow semver and ship from the canonical brand-kit repo at `MagicBlocksAI/brand-kit`.
- Tags `css-vX.Y.Z`, `ui-vX.Y.Z`, `brand-vX.Y.Z` trigger publishing via the repo's GitHub Actions workflows.
- `@magicblocksai/ui` + `@magicblocksai/css` follow a **lockstep policy** — whenever shared CSS classes change, both bump together so the pair version stays consistent. See the [changelog](https://brand.magicblocks.ai/changelog) for the latest published pair.
- `@magicblocksai/brand` versions independently (JSON schema). See the [changelog](https://brand.magicblocks.ai/changelog) for the current version.
- To upgrade in your project: `pnpm update @magicblocksai/css @magicblocksai/ui` (or `npm update`).
- Token / class additions ride in minor bumps. Breaking changes only on majors.

## Troubleshooting

- **`404 Not Found` on install** — your `.npmrc` doesn't have the `@magicblocksai:registry=…` line, OR your `GITHUB_TOKEN` env var isn't exported, OR your PAT doesn't have `read:packages` scope on `MagicBlocksAI`.
- **`401 Unauthorized`** — your token expired or doesn't have access to the org's packages. Check at https://github.com/orgs/MagicBlocksAI/packages.
- **`Cannot find module '@magicblocksai/css'` in code** — install ran but the import path is wrong. Try `import "@magicblocksai/css/magicblocks.css"` or use the file path: `import "@magicblocksai/css/dist/magicblocks.css"`.
- **CI install fails** — use the built-in `${{ secrets.GITHUB_TOKEN }}` in your GitHub Actions workflow:
  ```yaml
  - run: echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> ~/.npmrc
  - run: npm install
  ```

## Where to Learn What's Available

- **Live demos** (26 chapters across 5 buckets): https://brand.magicblocks.ai/components/
- **Component catalogue (JSON)**: https://brand.magicblocks.ai/api/components.json
- **Per-component spec**: https://brand.magicblocks.ai/api/components/{Name}.json
- **Asset registry**: https://brand.magicblocks.ai/api/assets.json
- **Brand tokens**: https://brand.magicblocks.ai/api/brand.json
- **Voice + tone**: https://brand.magicblocks.ai/api/voice.json
- **Search across everything**: open any page and press **⌘K**

### CSS Variables — Single Source of Truth

Every CSS custom property the kit declares (colours, typography, spacing, radius, motion, shadows, z-index, surface tokens — about 200 of them) is listed at:

> **https://brand.magicblocks.ai/tokens#variables** — filterable; click any row to copy the variable name with the leading `--`.

If you're about to introduce a local CSS value in a consumer codebase, check the variables list first — the kit usually already has the right token. The same data is also available as JSON via `/api/brand.json` for AI agents and tooling.

---

Maintained at `git@github.com:MagicBlocksAI/brand-kit.git`. File issues there.
