Skip to content

chore: add DESIGN.md design-identity spec with generated token block and drift check#768

Merged
QuintonJason merged 3 commits into
mainfrom
chore/design-md-spec
Jul 13, 2026
Merged

chore: add DESIGN.md design-identity spec with generated token block and drift check#768
QuintonJason merged 3 commits into
mainfrom
chore/design-md-spec

Conversation

@QuintonJason

@QuintonJason QuintonJason commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a DESIGN.md at the repo root following the google-labs-code/design.md convention — a single machine-readable + human-readable file that lets coding agents reproduce Pine's visual identity with precision (exact token values plus the rationale behind them).

The file has two layers:

  1. tokens: AUTOGEN block — raw values pulled verbatim from the source of truth (@kajabi-ui/styles core.json/semantic.json + _motion.scss): full color palette, 8px spacing scale, radius/shadow ramps, typography scale, semantic z-index, motion, and intent colors. Never hand-edited.
  2. Curated semantic layer + prose — semantic color roles, typography guidance, and token mappings for all ~35 pds-* components, plus the standard design.md sections (Overview → Do's and Don'ts).

To keep the generated block honest, this PR also adds:

  • scripts/generate-design-md.mjs — zero-dependency generator. Default mode rewrites the AUTOGEN block from upstream tokens; --check mode (CI) exits non-zero on drift.
  • npm run design.tokens script.
  • A CI drift step in the test-lint composite action (runs on every PR).
  • A pre-push lefthook command for fast local feedback.

Component token mappings were verified against each component's compiled CSS, which corrected several inferences (e.g. Pine's primary button is dark grey-900, not purple — purple is the accent variant).

No new dependencies. No runtime/component code changes.

Fixes #(n/a)

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How Has This Been Tested?

  • tested manually
  • other: ran npm run design.tokens (generates block), --check (passes), a negative drift test (correctly fails + restores), and npm run lint.all (0 errors)

Test Configuration:

  • OS: macOS
  • Node: 22.x

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing tests pass locally with my changes
  • Design has QA'ed and approved this PR

Note

Low Risk
Documentation and dev/CI tooling only; no production component or auth paths touched.

Overview
Introduces root DESIGN.md (google-labs-code/design.md style) as Pine’s machine- and human-readable design identity for agents: an AUTOGEN tokens: block synced from @kajabi-ui/styles + _motion.scss, plus hand-maintained semantic roles, pds-* component token mappings, and prose (overview through do’s/don’ts).

Adds scripts/generate-design-md.mjs and npm run design.tokens to rewrite that block or --check for drift. CI (test-lint composite action) and lefthook pre-push run the check so committed tokens stay aligned with upstream bumps.

No new dependencies or component/runtime code changes.

Reviewed by Cursor Bugbot for commit 9f928d9. Bugbot is set up for automated code reviews on this repo. Configure here.

@QuintonJason QuintonJason requested a review from a team as a code owner June 22, 2026 18:39
@netlify

netlify Bot commented Jun 22, 2026

Copy link
Copy Markdown

Deploy Preview for pine-design-system ready!

Name Link
🔨 Latest commit 9f928d9
🔍 Latest deploy log https://app.netlify.com/projects/pine-design-system/deploys/6a54e2dea266cf0008dcc6ad
😎 Deploy Preview https://deploy-preview-768--pine-design-system.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@QuintonJason QuintonJason requested a review from pixelflips June 30, 2026 19:08

@pixelflips pixelflips left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review — two non-blocking nits left inline on scripts/generate-design-md.mjs. Neither blocks merge.

🤖 Generated with Claude Code

Comment thread scripts/generate-design-md.mjs Outdated
// typography
const fs = Object.fromEntries(
Object.entries(core['font-size'])
.map(([k, v]) => [k, v.value])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This font_size map is the only numeric scale that doesn't normalize its keys — palette, spacing, line_height, and box_shadow all map [norm(k), …], but this one maps the raw key [k, v.value].

Two consequences in the generated block:

  1. Ordering — the token JSON has zero-padded keys 057/071/085. JS hoists canonical integer-string keys ahead of leading-zero string keys, so the three smallest sizes land at the end of the scale (the .sort() is a no-op for them). You can see it in the committed output at DESIGN.md L51: … 285: 40px, 057: 8px, 071: 10px, 085: 12px.
  2. Lossy key — a YAML parser reads bare 057 as the integer 57, a different identifier than the source token name.

Applying norm(k) like the sibling maps fixes both:

.map(([k, v]) => [norm(k), v.value])

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9f928d9font_size now uses norm(k) like the sibling scales, so keys sort correctly (57/71/85 first) and stay YAML-safe integers.

Comment thread scripts/generate-design-md.mjs Outdated
const next = md.replace(re, block);

if (process.argv.includes('--check')) {
if (next !== md) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--check compares the regenerated block against the on-disk file with strict !==, but block is always joined with \n (L156: lines.join('\n')). On a CRLF checkout (Windows + core.autocrlf=true, or an editor that normalizes endings), the content outside the AUTOGEN markers keeps its \r\n, so next !== md is true even when the token data is identical — a spurious "token block is stale" failure in CI and the pre-push hook, with no real drift to fix.

Consider normalizing line endings before comparing (or comparing only the extracted marker block) so the check is line-ending agnostic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9f928d9--check now normalizes CRLF→LF on both sides before comparing, so Windows/autocrlf checkouts won't false-fail on identical token data.

@QuintonJason QuintonJason requested a review from pixelflips July 13, 2026 13:02
@QuintonJason QuintonJason self-assigned this Jul 13, 2026
@QuintonJason QuintonJason merged commit 91427ad into main Jul 13, 2026
21 checks passed
@QuintonJason QuintonJason deleted the chore/design-md-spec branch July 13, 2026 18:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants