# @prioritytaxrelief-development/design-kit

The PTR Design Kit as **one installable package**. Everything is generated from **`tokens.json`** + **`tokens.dark.json`** — the canonical DaisyUI v5 `"PTR"` theme export from Figma (light mode + the dark-mode flip). No consumer ever hand-edits a token value.

## Use it (jsDelivr — no install, no auth)

The repo is public; jsDelivr serves every tagged file. Pin a tag and link the layers you need:

```html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/PriorityTaxRelief-Development/design-kit@v0.2.0/package/theme.css">
```

Pattern: `https://cdn.jsdelivr.net/gh/PriorityTaxRelief-Development/design-kit@v<version>/package/<file>` — append `.min` before `.css` for jsDelivr's auto-minified variant. **Always pin a `v*` tag**; never `@latest` or a branch ref (branch content caches ~12 h and drifts). Build-time consumers that want `theme.plugin.css` vendor that one file from the tagged URL — a `@plugin` block must be processed by the Tailwind build and can't load from a CDN.

## What you import

| Entry | Use it when |
| --- | --- |
| `theme.plugin.css` | Tailwind v4 + DaisyUI builds that want the theme registered at build time. **Build-time only — vendor the file from the tagged jsDelivr URL**, then `@import` it in `input.css`. Ships as `name: "ptr"`. The Phase-2 app swap uses the runtime files below instead. |
| `theme.css` | **The default path.** No build step — link the tag-pinned jsDelivr URL (after any compiled CSS) and any DaisyUI-shaped component CSS reads the PTR variables at runtime (`:root` / `[data-theme="ptr"]`). |
| `theme-dark.css` | The branded dark theme (audit #12, promoted from the Services site July 16 2026): a selector-gated flip of neutral surface/text/border tokens + `--surface-1/2` under `[data-theme="dark"]` / `[data-theme="ptr-dark"]`. Load after `theme.css` + `brand.css`; inert until the attribute is set. Generated by `build.mjs` from `tokens.dark.json` (O5, July 16 2026). |
| `brand.css` | The PTR extension layer: brand palette (+ the #8 orange-usage rule), 8 case-status colors, type scale as `.ptr-*` classes (incl. `.ptr-eyebrow` quiet/`--loud` and the weight-800 `.ptr-title`, O1), web-copy mid sizes (`--fs-title/--fs-lead-web/--fs-intro/--fs-body-lg`, O2), layout tokens (`--site-max/--gutter/--header-h`), surfaces (`--surface-1/2`), spacing, shadows, motion tokens. **Tokens + classes only — no bare-element styles**, safe to load app-wide next to `theme.css`. |
| `marketing.css` | The marketing/web vocabulary (Services-site rebuild contract, ingested July 15 2026, reconciled D1–D5 + O1–O5, packaged July 17 2026): header/nav, hero, section bands, service cards, accordions, lead form, footer, component-level dark rules. Vocabulary only — load `theme.css` (+ `theme-dark.css`) + `brand.css` first. |
| `pages.css` | Marketing page blocks (About, Careers, Tax News, Article, Thank You). Load after `marketing.css`. |
| `tokens.json` + `tokens.dark.json` | The source of truth: light mode + the dark-mode flip (the dark file lists only the variables that change; everything else keeps its PTR value). Figma sync targets; the only inputs to `build.mjs`. Since O5 (July 16 2026) they also carry the brand palette, surfaces and layout groups. |
| `CHANGELOG.md` | What changed in each tag — read before bumping a pin. |
| `assets/*` | Logo lockups (flag / horizontal / stacked / wordmark / symbol in black + white, flag also in orange), the **official vector masters** from `ptr_logo` in `assets/logo-kit/svg/` (Horz / Icon / Stacked / Stacked-Mixed, tiny-ps SVG), and `textures/grain.jpg` — a compressed variant of the grain texture (the ~8 MB master stays in the design-system repo, not the package). High-res PNG exports, favicon set, BIMI mark and social covers are deliberately **not** packaged — download them from the brand page (`index.html#downloads`) or the `ptr_logo` repo. |

**In since v0.2 (July 17 2026):** `product.css` — the shared product layer (status pills reading the `--case-{group}-bg/-fg` pairs, empty state, filter bar, toast; tokens only). Load after `theme.css` + `brand.css`. **Deliberately not yet in:** the prebuilt CDN drop-in bundle for HubSpot/Ads (Phase 3).

## The anti-drift build

`npm run build` (→ `node build.mjs`) regenerates from `tokens.json` + `tokens.dark.json`:

- `theme.css` — runtime variables
- `theme.plugin.css` — the `@plugin "daisyui/theme"` block
- `theme-dark.css` — the dark flip, from `tokens.dark.json`
- the `@generated:*` blocks inside `brand.css` (brand palette, case-status colors, `--color-base-400`, font stacks, layout, surfaces)

CI runs `build.mjs --check` on every `v*` tag, so a stale generated file **fails the release**. In the design-system repo, the root `ptr-theme.css` simply `@import`s `package/theme.css` — there is no second copy of any token anywhere.

**Token change flow:** edit variables in the Figma "PTR" theme → re-export `tokens.json` (dark-mode values → `tokens.dark.json`) → `npm run build` → review the diff in a small PR → version bump → publish.

## Releasing (tags → jsDelivr)

There is no registry publish — **the tag is the release**. Push a `v*` tag to the public [design-kit](https://github.com/PriorityTaxRelief-Development/design-kit) repo and jsDelivr serves the tagged files immediately at `…/design-kit@v<version>/package/<file>`. CI (`.github/workflows/publish.yml`) guards each tag: it runs `npm run check` (stale generated CSS fails the release) and verifies the tag matches `package.json`'s version.

```sh
cd package
npm run check                 # verify nothing is stale
# add the release's entries to CHANGELOG.md under the new version heading
npm version patch             # value tweak · minor = new token/class · major = rename/removal
git push --follow-tags        # the tag IS the release — jsDelivr picks it up
```

Note: `npm version` creates the tag as `v0.2.1` only when run at the repo root; from `package/` it still creates the commit + tag — confirm the tag name matches `v<version>` before pushing.
