Commit Graph

60 Commits

Author SHA1 Message Date
Manav Arya Singh db17011449 chore(release): bump to 13.0.0 across package + plugin manifests 2026-06-25 12:00:09 +04:00
Manav Arya Singh ee68490eb7 docs: document fidelity + gallery, bump to 12.24.0
README quick-start, a dedicated 'Measured clone fidelity' section, the plugin
command table, and the full CLI reference now cover /fidelity and /gallery.
CHANGELOG 12.24.0 entry. Version bumped in lockstep across package.json,
plugin.json, marketplace.json (manifests describe the two new commands); the
version-sync test now guards fidelity + gallery too.
2026-06-22 22:33:52 +04:00
dependabot[bot] a0f95f2b61 chore(deps): bump commander from 12.1.0 to 15.0.0 (#155)
Bumps [commander](https://github.com/tj/commander.js) from 12.1.0 to 15.0.0.
- [Release notes](https://github.com/tj/commander.js/releases)
- [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tj/commander.js/compare/v12.1.0...v15.0.0)

---
updated-dependencies:
- dependency-name: commander
  dependency-version: 15.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 14:02:23 +04:00
dependabot[bot] 7714d36bc1 chore(deps): bump ora from 8.2.0 to 9.4.0 (#154)
Bumps [ora](https://github.com/sindresorhus/ora) from 8.2.0 to 9.4.0.
- [Release notes](https://github.com/sindresorhus/ora/releases)
- [Commits](https://github.com/sindresorhus/ora/compare/v8.2.0...v9.4.0)

---
updated-dependencies:
- dependency-name: ora
  dependency-version: 9.4.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 13:59:42 +04:00
dependabot[bot] af9e86807a chore(deps): bump playwright in the minor-and-patch group (#153)
Bumps the minor-and-patch group with 1 update: [playwright](https://github.com/microsoft/playwright).


Updates `playwright` from 1.59.1 to 1.61.0
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](https://github.com/microsoft/playwright/compare/v1.59.1...v1.61.0)

---
updated-dependencies:
- dependency-name: playwright
  dependency-version: 1.61.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-18 09:55:28 +00:00
Manav Arya Singh 3a81b3561b chore: release 12.23.0 — whole-site design system + plugin fixes
Bump all manifests to 12.23.0 (in sync) and document the new 'site'
command, OKLab clustering, coverage map, consistency grade, and the
plugin command/version fixes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:35:59 +04:00
Manav Arya Singh 78fdf58add chore(plugin): add version-sync guard script + test
scripts/check-plugin-version.mjs fails loud when plugin.json or
marketplace.json drift from package.json; wired as 'npm run check-plugin'
and enforced by tests/plugin-version.test.js (also asserts every new
command has a backing file and is described). Prevents the drift recurring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:35:28 +04:00
Manav Arya Singh 1a68d4458d docs: Motion Lang v3 — v12.22.0, README + CHANGELOG (--motion-runtime)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 23:55:57 +04:00
Manav Arya Singh a51e406c01 feat(studio): craft pass — intentional specimen + harmonised colors (v12.21.0)
The preview felt random. This rebuilds it as a deliberate design-system
specimen instead of a scatter of placeholder components.

- Composed preview: masthead, a centered hero using the site's own strongest
  heading + top CTA verbs, labeled Color and Type foundations, then Buttons /
  Inputs / Status / In-context cards / Metrics — each under a clear section
  eyebrow, on a consistent vertical rhythm. The rebuilt-Page tab reuses the
  same crafted components. Honest product copy, no lorem.
- Harmonised deriveTokens: guarantee a legible surface/text pair, filter greys
  out of accent selection (no neutral promoted to brand), deepen a near-
  invisible accent to read on the surface, hold secondary text above a
  legibility floor. Keep white-on-warm-accent convention for accent foreground.
- Calmer chrome: quieter hairlines, consistent 30px rounded controls, pill
  tabs, segmented light/dark — the frame recedes so the system is the focus.

Shared studio engine, so the CLI and website /studio get it identically.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 13:34:00 +04:00
Manav Arya Singh c652df1b96 feat(studio): one-click generated dark mode (v12.20.0)
Add a Light/Dark toggle that generates a dark variant from the extracted
light tokens: surface → near-black tinted toward the brand hue, text →
near-white, muted/border/card recomputed; the brand accent is preserved
(lightened only if it would vanish on dark). Type/shape/spacing/motion carry
over. Contrast grading recomputes live, inspector edits layer on top of
either theme, and the theme is encoded in the shareable URL.

Pure shared deriveDark() in src/studio-tokens.js keeps the CLI and website
studios in lock-step. New unit tests cover the dark derivation and control.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 03:42:56 +04:00
Manav Arya Singh 8a2c425f4f feat(studio): living design-system editor + /studio on the website (v12.19.0)
Turn `designlang studio` from a read-only viewer into an interactive
playground, and ship the same experience on the website.

CLI (`designlang studio`):
- Inspector (color/type/shape/spacing/motion) writes a small `--p-*` CSS
  variable set; a tabbed live preview — component wall + a page rebuilt from
  the extraction's reading order — restyles instantly off those variables.
- Live WCAG contrast grading per color, paper/white/dark backdrops, an edit
  counter, and smooth token-driven transitions.
- Export edited system as DTCG tokens / CSS variables / Tailwind theme
  (zero-dep client downloads); share via URL (edits encoded as hash deltas).

Website (`/studio`):
- Paste any URL → extract → embed the identical editable studio in a framed
  viewport. Shareable via `?url=`; shares the free 2/day demo budget.
- New POST /api/studio reuses the same `studioHtml` engine server-side.

Internals:
- Token derivation extracted to a pure, dep-free module (src/studio-tokens.js)
  shared by the CLI and the website route, keeping both surfaces in lock-step.
- New unit tests: derivation, WCAG contrast math, rendered studio document.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 02:49:47 +04:00
Manav Arya Singh f9e0c4770a feat(verify): fidelity loop — rebuild from tokens, pixel-diff vs live (v12.18.0) (#139)
`designlang verify <url>` closes the extract→prove loop. For each detected
component (button+card in v1) it rebuilds a clone styled ONLY by the extracted
tokens (each visual property snapped to nearest token, colours in CIE-Lab ΔE),
renders it, and pixel-diffs against the live component → 0-100 fidelity score +
per-token-family attribution + a verify.html triptych (original | rebuilt |
loss heatmap) + verify.json. `--min` gates CI.

Honest by construction: missing component → n/a (excluded, no silent 100);
property with no token → unmapped (counted as loss, surfaced in attribution);
size mismatch letterboxed, never stretched.

New isolated modules under src/verify/ (tokens/restyle/render/diff/index) +
formatters/verify.js + verify CLI command. Adds pixelmatch+pngjs. 13 unit tests,
full suite green (438). Live smoke vs github.com: button 89/100.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 17:50:42 +04:00
Manav Arya Singh 95eae1702d feat(motionlang): add GSAP and Web Animations API emitters (v12.17.0) (#138)
Two new framework targets for the extracted motion language:

- motion-gsap.js: registers extracted cubic-bezier curves as named GSAP
  CustomEases, emits gsap.from() reveal helpers + a ScrollTrigger batch
  reveal when the page uses scroll/view-timeline.
- motion-waapi.js: zero-dependency Web Animations API preset. WAAPI takes
  cubic-bezier easing strings verbatim, so curves reproduce exactly (no
  spring approximation); helpers honour prefers-reduced-motion.

Wired into the CLI emit list (`<host>-motion.gsap.js`, `-motion.waapi.js`),
the /api/motion exports, and the motionlang analyzer export cards. Adds 8
emitter tests (425 -> all green). Also ignores .npmrc.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 17:13:29 +04:00
Manav Arya Singh 619d44ad21 v12.16.0 — motionlang CSS + Tailwind emitters; fix website brand-book PDF
motionlang:
- New formatter src/formatters/motion-css.js — <host>-motion.css with
  --duration-*/--ease-* custom properties, reusable + reconstructed
  @keyframes, .mo-* utility classes, and a prefers-reduced-motion guard.
- New formatter src/formatters/motion-tailwind.js — <host>-motion.tailwind.js
  require-able theme.extend (transitionDuration, transitionTimingFunction
  incl. a spring curve from detected overshoot beziers, keyframes, animation).
- Wired both through api.js (RENDERERS + ext map) and the bin files array as
  the motion-css and motion-tailwind renderer ids.
- 13 new tests; full suite 414 pass.

website PDF fix ("downloaded PDF won't open"):
- extract route awaits the Blob cache write before the stream closes, so the
  serverless instance can't freeze mid-write and leave /api/pdf/<hash> with
  no cached design (was a fire-and-forget write returning 404 JSON).
- ShareExtractionButton fetches + validates content-type is application/pdf
  before saving, surfacing an error instead of writing a broken file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 22:46:52 +04:00
Manav Arya Singh 82b20dbe5a v12.15.0 — motionlang: Motion Lab + Framer Motion emitters 2026-05-21 16:27:03 +04:00
Manav Arya Singh 2c50abc5b0 v12.14.0 — real PDFs everywhere + one-shot agent prompt 2026-05-18 01:23:23 +04:00
Manav Arya Singh daae95095a v12.13.0 — six new emitters + public programmatic API 2026-05-17 02:23:25 +04:00
Manav Arya Singh 7d793db8b3 feat: public programmatic API at 'designlang/api' (#117)
Adds a stable surface other packages, scripts and AI agents can
import without touching internal modules.

New file: src/api.js
- extract(url, opts)  — run the full extraction pipeline, returns design
- render(id, design)  — render a single emitter by id
- renderAll(design)   — return a { filename: contents } map
- RENDERERS           — frozen map of every emitter id → renderer fn
- Re-exports: extractDesignLanguage, compressPalette, diffDesigns,
  formatDiffMarkdown

19 renderer ids exposed (every web/native/agent emitter).

package.json gains an exports map:
  'designlang'         — index.js
  'designlang/api'     — the new public API
  'designlang/mcp'     — the existing MCP server entry

Usage:
  import { extract, render } from 'designlang/api';
  const design = await extract('https://stripe.com', { palette: 8 });
  const tailwind = render('tailwind-v4', design);
2026-05-17 02:21:25 +04:00
Manav Arya Singh 00844c5f85 v12.12.0 — website launch
Bumps the package to v12.12.0 alongside the full website rewrite.
The CLI itself is unchanged from v12.11.0 — this version is published
mainly so the (previously broken) README image URLs propagate to the
npm package page.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 02:41:20 +04:00
Manav Arya Singh f403f8c536 v12.11.0: brand --pdf
Adds native PDF brand-guide output to the brand command:
  --pdf, --paper a4|letter|tabloid, --landscape,
  --no-print-background, --attach-tokens

PDF features: per-chapter page breaks, running footer with page
numbers, selectable text, embedded fonts, optional DTCG-tokens
JSON attached as a file inside the PDF (paperclip in Acrobat).

One new dep: pdf-lib (lazy-imported, only used when --attach-tokens
is passed).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 01:25:11 +04:00
Manav Arya Singh 706422ed09 feat(v12.10.1): stats accepts multiple URLs
$ npx designlang stats stripe.com vercel.com linear.app

Each URL is extracted in parallel; the pretty path prints each block
with a divider between them, the --as-json path emits an array.

Backwards compatible: a single URL still emits a bare object in
JSON mode, identical pretty output, and uses the exact same flag
surface. Per-URL failures use Promise.allSettled — one bad URL
doesn't kill the batch; the process exits non-zero only when at
least one site failed.

398/398 tests still pass.
2026-05-14 23:31:43 +04:00
Manav Arya Singh be37b82526 feat(v12.10): designlang stats + low-confidence note in grade card
Two tight quality-of-life additions on top of the v12.9 extraction pass.

stats command

  $ npx designlang stats stripe.com

    Grade        B · 87/100
    Primary      #533afd ×899 59% conf
    Fonts        sohne-var
    Type scale   14 sizes
    Spacing      base 2px · 13 steps
    Shape        5 radii · 6 shadows
    Colours      31 tokens
    WCAG         79%
    Stack        next · unknown
    Material     skeuomorphic
    Tone         neutral
    Intent       landing

  One-screen summary, no files written. Use -j / --as-json for
  machine-readable output (CI, scripting).

  (--json is already a global program flag for the main extract
  command's raw-JSON-to-stdout mode, so the subcommand flag is
  --as-json to avoid the clash. Both --as-json and -j shortcuts work.)

Low-confidence note in grade.html

  v12.9 added primary.confidence (0-1) on the colours payload but no
  surface used it. v12.10 renders an amber callout above the
  dimensions grid in the grade report card when confidence < 0.5:

    "Primary detection was low-confidence (32%). The brand colour
     may be a soft pick — review the palette below."

  Soft inline note, not an error. Stays hidden on the common high-
  confidence path. Dark-mode aware.

Tests
  - 2 new tests cover the present + absent paths of the confidence
    note.
  - 398/398 total.

No breaking changes, no new dependencies.
2026-05-13 23:36:13 +04:00
Manav Arya Singh 95a18d7211 feat(v12.9): extraction quality pass — fix the core MVP
Eight features rode on top of the same extractor. This release fixes
four real defects in that extractor — visible across every downstream
output (grade, battle, remix, pack, theme-swap, brand, pair).

Fixed

  1. clusterColors() representative bug. Before, the first-encountered
     colour seeded each cluster, so a sparsely-used pale shade could
     become the canonical hex of a cluster that mostly held a vivid
     brand colour. The brand-book primary slot was reading lavender
     for Stripe instead of #533afd. Now: representative is the
     most-counted member.

  2. detectScale() missed common production base units. Before, only
     [2, 4, 6, 8] were tried, so Bootstrap-style base-5 and base-7/10/12
     sites returned base:null. Now: [2, 4, 5, 6, 7, 8, 10, 12, 16] with
     a small bonus for 4 and 8 to keep results stable for production
     defaults.

  3. Typography noise. Generic CSS stacks (sans-serif, monospace,
     system-ui, inherit, -apple-system, ...) and icon fonts (Material
     Icons, Font Awesome, Lucide, Tabler, ...) polluted the families
     list. Brand books had icon fonts documented as the body family.
     Now: an explicit filter at the source.

Added

  4. primary.confidence (0–1) on design.colors.primary. Computed from
     the brand-score gap between rank 1 and rank 2. Runaway leader →
     1.0; near-tie → 0.3. Downstream consumers can surface uncertainty
     warnings on low-confidence extractions.

  5. asList(v) helper exported from src/utils.js. Coerces anything-
     shaped input (array / object / comma-string / scalar) into a clean
     string array. Consolidates ad-hoc per-formatter defenses.

Verified live on stripe.com

  Before: primary slot showed a washed-out lavender; multiple icon
  fonts polluted families; spacing base often null.

  After: primary #533afd (count 899, confidence 0.59), families
  ['sohne-var'], spacing base correctly detected.

No new dependencies, no schema breaks, no public-API changes.
396/396 tests pass (6 new).
2026-05-12 13:31:28 +04:00
Manav Arya Singh 03a2e7524a feat(v12.8): designlang pair — fuse two designs into a single hybrid identity
`designlang pair <urlA> <urlB>` extracts both sites in parallel, then
mixes their design systems along seven configurable axes (colours,
typography, spacing, shape, motion, voice, components). Default split
is "visuals from A, voice + type + components from B" — i.e. the most
distinctive crossover.

  $ npx designlang pair stripe.com linear.app

  stripe.com × linear.app
    A  Colours      · stripe.com
    B  Typography   · linear.app
    A  Spacing      · stripe.com
    A  Shape        · stripe.com
    A  Motion       · stripe.com
    B  Voice        · linear.app
    B  Components   · linear.app

  ✓ stripe-com-x-linear-app.pair.html
  ✓ stripe-com-x-linear-app.pair.md
  ✓ stripe-com-x-linear-app.pair.json

How it works

  - src/fuse.js — fuseDesigns(a, b, opts) deep-clones both inputs,
    picks each axis from the requested source, synthesises a
    pair-specific meta URL ("pair://<a>-x-<b>"), and strips score /
    cssHealth (those measurements belong to the source extractions,
    not the fusion).
  - Default axes calibrated for the most interesting crossover:
    colour/spacing/shape/motion from A, typography/voice/components
    from B. Override any axis with --<axis>-from a|b.
  - Layout follows colour (mixing primary from one site with neutrals
    from another tends to muddy the brand). Material language and
    imagery style track the colour pick. Variables follow colour.
  - Components carry their detected library label (componentLibrary)
    along with the anatomy.

Pair card formatter

  - src/formatters/pair.js — editorial three-card hero (A · B · Fused),
    per-axis source matrix, and a fused specimen using the *real*
    headline from whichever site contributed the voice axis.
  - --brand flag also emits a full brand-guidelines book of the fused
    identity (re-uses formatBrandBook on the fused design).

Plugin

  - /pair is the 8th slash command (commands/pair.md).
  - .claude-plugin/plugin.json + marketplace.json bumped to 12.8.0
    with an eight-command description.

Tests (12 new, 390/390 total)

  - Default split, per-axis overrides, score-stripping, meta synthesis
  - Source-design immutability, missing-input errors
  - HTML rendering, voice carry-through to specimen, XSS escaping
  - Markdown axis source table

Verified live: Stripe × Linear fuses Stripe's purple palette with
Linear's Inter Variable typography and Linear's actual top heading
("The product development system for teams and agents") as the
specimen quote.

Why

  battle (v12.2) answers "which is better"; pair answers "what would
  the intersection look like". Same parallel extraction, opposite
  operation. Pure logic, no LLM, no new dependencies.
2026-05-10 21:11:57 +04:00
Manav Arya Singh a935a1ae41 fix(v12.7.1): brand-book visual polish — extracted brand color leads, real text everywhere
The v12.7.0 brand book had a real-data deficit:
  - Cover used a generic grade-coloured accent (not the brand's actual primary).
  - Every section opened with a philosophical lede ("the felt pace of an
    interface", "form follows feeling", "quiet authority of restraint").
  - Components chapter was a metadata table, not a real mock.
  - Type specimen reused the same recycled aphorisms across files.

This pass replaces all of that with the extracted values themselves.

Cover

  Full-bleed band of the brand's actual primary (auto-detected via the
  most-saturated brand-classified colour; falls back through secondary,
  accent, most-used). The hex prints inside the band. Host name lives
  below the band in massive serif.

Section ledes

  Replaced philosophy with one-line data summaries.
  "1 primary · 1 secondary · 1 accent · 27 neutrals · 88 total" beats
  "Brand colours carry meaning. Neutrals carry structure."

Type specimen

  Now uses real headlines extracted from design.voice.sampleHeadings.
  Falls back to a single neutral pangram only when those are absent.
  Recycled aphorisms removed entirely.

Colour chapter

  Primary at full-width hero (aspect 2.6:1), secondary + accent
  half-width pair, neutrals flush horizontal strip, full palette grid.
  Hex labels render *inside* the swatch in auto-contrast text.

Components chapter

  Renders an actual primary + secondary button using extracted brand
  colour + radius, plus a card mock using extracted surface + text
  + accent for the link. Metadata moved below the mock.

Accessibility chapter

  Failing pairs render as actual stacked colour blocks ("Aa" in
  foreground on the failing background, ratio inline). Big WCAG score
  on top.

Tokens chapter

  Code blocks now have a header bar with language + target filename.

"How to use"

  Trimmed from 6 rules of thumb to 4 punchier ones. Dropped the
  "rule of thumb" framing.

Layout

  Section padding moved into the wrap (no gutter around the hero
  band). TOC sits on tinted sub-paper background. Chapter headers
  thinner with a bottom rule.

Same 13 chapters, same public API, no breaking changes.

378/378 tests pass (one assertion updated for the lowercase
"Brand guidelines" cover label).
2026-05-09 23:37:39 +04:00
Manav Arya Singh b249fb8f2e feat(v12.7): designlang brand — full editorial brand-guidelines book
`designlang brand <url>` produces a self-contained, print-ready HTML
"brand guidelines book" — a hand-off-ready document for designers and
recipients, distinct from `pack` (developer files) and `grade` (audit).

  $ npx designlang brand stripe.com

  Brand book · 54 tokens · 3 fonts · grade B · https://stripe.com
  ✓ stripe-com.brand.html
  ✓ stripe-com.brand.md
  ✓ stripe-com.brand.json

Layout — 13 chapters

  Cover           Big serif headline, 4 stat callouts (intent, grade,
                  score, token count)
  Contents        Two-column TOC with smooth-scroll anchors
  01 About        Page intent · material language · imagery style ·
                  component library · stack · voice tone
  02 Logo         Extracted SVG on canvas + dimensions/aspect/format
  03 Colour       Brand swatches w/ HEX/RGB/HSL/usage, neutrals grid,
                  full palette, A11y callout
  04 Typography   Display + body families, scale table w/ Aa samples,
                  large specimen lines in extracted family
  05 Spacing      Base unit + visual rhythm bars
  06 Shape        Border radii visualised, shadow elevation cards
  07 Iconography  Library detection + captured icons grid
  08 Motion       Feel + durations (animated dots) + easings list
  09 Components   Detected anatomy w/ slots, variants, sizes
  10 Voice        Tone, pronoun posture, heading case, CTA verbs, quotes
  11 Accessibility WCAG score, failing pairs table, remediation list
  12 Tokens       Drop-in CSS-var + Tailwind extend snippets
  13 How to use   Six rules of thumb for derivative work

Internals

  - src/formatters/brand-book.js — formatBrandBook + formatBrandBookMarkdown
  - bin/design-extract.js — `brand` command (--format html|md|json|all,
    --open). Defaults to deep-interact extraction since the book wants
    motion, voice, anatomy, accessibility surfaces.
  - asList() coercer for the component-anatomy fields, which arrive as
    arrays / objects / strings depending on the cluster (the bug that
    broke the first integration).
  - Editorial CSS: Instrument Serif display + Inter body + JetBrains Mono
    code, generous whitespace, dark-mode toggle, print stylesheet with
    page-breaks at chapter boundaries.

Plugin

  - /brand is the 7th slash command (commands/brand.md)
  - .claude-plugin/plugin.json + marketplace.json bumped to 12.7.0 with
    a seven-command description.

Tests

  - 7 new tests cover chapter coverage, host/colour/font rendering,
    XSS escaping, sparse-design fallback, mixed-shape anatomy.
  - 378/378 passing.

Verified live on stripe.com — 54 tokens, 3 fonts, grade B, all 13
chapters rendering correctly.
2026-05-09 23:25:52 +04:00
Manav Arya Singh 765139b992 feat(v12.6): designlang theme-swap — recolour around a new brand primary
Closes #57.

`designlang theme-swap <url> --primary <hex>` takes the existing
extraction and rotates the brand palette around a new primary while
preserving everything else: type scale, spacing rhythm, neutrals,
motion, component anatomy.

  $ npx designlang theme-swap stripe.com --primary "#ff4800"

  #533afd → #ff4800 · 91 colours · https://stripe.com
  Hue shift: 118.5° · neutrals preserved · type/spacing/motion untouched

  ✓ stripe-com-themeswap-ff4800.themeswap.html
  ✓ stripe-com-themeswap-ff4800.themeswap.md
  ✓ stripe-com-themeswap-ff4800.themeswap.json
  ✓ stripe-com-themeswap-ff4800.themeswap.tokens.json

How it works

  - Detects the source primary (extractor classification + usage-count
    fallback). Override with --from <hex>.
  - Computes hue delta in OKLCH → applies to every coloured token.
    Neutrals (chroma < 0.04) are explicitly preserved so body text,
    surfaces, and rule lines stay readable.
  - The user's --primary hex lands verbatim on the primary slot
    (no rounding through chroma).
  - Out-of-gamut targets get chroma-clamped via the existing
    oklchToHex helper.

The recoloured design is fed through every existing emitter (DTCG,
Tailwind, shadcn, Figma vars, CSS vars) so the swap propagates for
free — no new emitter code.

Internals

  - src/recolor.js — recolorDesign(design, opts)
  - src/formatters/theme-swap.js — formatThemeSwap (HTML preview),
    formatThemeSwapMarkdown
  - src/utils/color-gamut.js — adds srgbToOklab, srgbToOklch,
    hexToOklch, oklchToHex with chroma fallback
  - bin/design-extract.js — `theme-swap` command with --primary,
    --from, --format, --open

Plugin

  - Adds /theme-swap slash command (commands/theme-swap.md)
  - Bumps .claude-plugin/plugin.json + marketplace.json to 12.6.0
    with a six-command description.

Tests

  - 10 new tests covering primary-pinning, neutral preservation,
    hue rotation, error paths, --from override, HTML/markdown shapes,
    and XSS escaping.
  - 367/367 total, all passing.

Verified live on stripe.com (Stripe purple → orange, 91 colours,
118.5° rotation), JSON outputs parse cleanly, HTML preview renders
side-by-side palettes + mockup comparison correctly.
2026-05-08 12:57:09 +04:00
Manav Arya Singh 0b76ab8b3f feat(v12.5): Claude Code plugin — five slash commands
Drop designlang straight into any Claude Code session as a plugin:

  /plugin install Manavarya09/design-extract

Every CLI verb becomes a slash command:

  /extract <url>                 — full extraction (DTCG, Tailwind, Figma)
  /grade <url> [--badge]         — shareable HTML report card + SVG badge
  /battle <urlA> <urlB>          — head-to-head graded battle card
  /remix <url> --as <vocab>      — restyle in 6 vocabularies
  /pack <url>                    — bundle every output into one directory

What changed:

- New commands/ directory with five slash-command manifests
  (description + argument-hint frontmatter, prompt body wraps CLI and
  surfaces a tight summary).
- Refreshed .claude-plugin/plugin.json (was stale at v1.0.0):
  name → designlang, description rewritten to cover all v12 surfaces,
  added "commands": "./commands/" pointer, expanded keywords.
- Refreshed .claude-plugin/marketplace.json with the same updates plus
  marketplace tags.
- New README section "Claude Code plugin" with install + slash command
  table. Existing "Agent skill" section retained for Cursor/Codex/40+
  other agents via the skills ecosystem.

No CLI behavior change. The slash commands are pure wrappers around
existing `npx designlang …` calls.

357/357 tests pass.
2026-05-06 00:07:47 +04:00
Manav Arya Singh 8ae995db70 feat(v12.4): designlang pack — one polished design-system bundle
Closes #59.

`designlang pack <url>` runs the full extraction once and writes every
emitter output into a single, signed, layered directory. One artifact a
designer or dev can clone, drop into a project, or zip up and send to a
client.

Layout:

  <host>-design-system/
  ├── README.md           bespoke, references source + grade + at-a-glance
  ├── LICENSE.txt         provenance + usage guidance
  ├── tokens/             DTCG + Tailwind + CSS vars + Figma vars + motion + theme.js
  ├── components/         typed React stubs (anatomy.tsx)
  ├── storybook/          runnable Storybook project
  ├── starter/            minimal HTML starter wired to tokens/variables.css
  ├── prompts/            v0 / Lovable / Cursor / Claude Artifacts + named recipes/*.md
  └── extras/             voice.json + prompt-pack.md rollup

Pure composition — zero new deps, zero new analysis. Reuses formatDtcg,
formatTokens, formatTailwind, formatCssVars, formatFigma, formatMotionTokens,
formatReactTheme, formatAnatomyStubs, formatStorybook, buildPromptPack,
generateClone (opt-in via --with-clone).

Internals:
- `toText()` normaliser handles the inconsistent return shapes across
  formatters (some return objects, some return JSON strings already).
- Recipes now write as `<name>.md` files, not array indices.
- 7 new tests cover directory shape, valid JSON token outputs, README
  content, starter wiring, recipe filenames, and a regression test for
  the double-stringify bug.

357/357 tests pass.

Verified live on stripe.com: 40 files, 232KB, all token JSON parses
cleanly.
2026-05-05 23:59:43 +04:00
Manav Arya Singh b62560309e feat(v12.3): designlang remix — restyle any site in another vocabulary
A genuinely new product surface. Take an extracted page-shape (sections,
voice, page-intent, anatomy) and re-render it under one of six opinionated
design vocabularies. Same content, different language.

  $ designlang remix stripe.com --as cyberpunk
  $ designlang remix stripe.com --all   # all 6 vocabularies, one extract

Six vocabularies:
  brutalist  — hard edges, mono type, single screaming accent
  swiss      — Helvetica, grids, restraint (post-Bauhaus default)
  art-deco   — gold on ink, geometric ornament, vertical type
  cyberpunk  — neon on midnight, scanlines, chromatic-aberration headings
  soft-ui    — cushioned shapes, low contrast, Vision-OS-adjacent
  editorial  — broadsheet serifs, generous whitespace, ink on paper

Each vocabulary is a self-contained tokens + font-stack + signature CSS
file in src/vocabularies/. The formatter (src/formatters/remix.js) maps
every section role (hero, feature-grid, pricing-table, stats, testimonial,
faq, logo-wall, steps, cta) to vocabulary-styled markup, using the host's
own copy (headings, ledes, CTA verbs from voice).

Hero deduplication: real-world section walkers — especially on SPA
marketing pages — often emit a hero wrapper + an inner hero with the
same h1. Remix dedupes by heading and excludes section-claimed headings
from the voice pool, so heading-less sections (cta bands, logo walls)
don't re-render an already-claimed heading.

14 new tests (350 total, all passing). Cover registry shape, per-vocab
token validity, dedup semantics, no-cross-claim heading pool, XSS
escaping, missing-input errors.

Why: Grade (v12.1) is the audit. Battle (v12.2) is the comparison.
Remix is the transformation. No competitor (Dembrandt, Superposition,
html.to.design, Builder Visual Copilot) ships site-shape-preserving
vocabulary swap.

Website: bumps v12.2 → v12.3 across home/features/gallery/spec/permalink,
adds /features#remix section, swaps Battle CTA chip to Remix.
2026-05-05 00:17:33 +04:00
Manav Arya Singh 100cea608a feat(v12.2): designlang battle + design-score badges
Two ships on top of the v12.1 Grade flywheel.

`designlang battle <urlA> <urlB>` — head-to-head graded card, parallel
extraction, dimension-by-dimension bar table with verdict + win/tie/loss
tally. Self-contained HTML, also emits .battle.md and .battle.json.

Design-score SVG badges:
- `designlang grade --badge` writes *-badge.svg locally
- New formatter src/formatters/badge.js — shields.io style, color by
  letter grade, accessible (aria-label, role=img), Verdana-width math so
  it renders identically across GitHub / npm / arbitrary markdown
- Live endpoint at website/app/api/badge/[host]/route.js — reuses the
  same blob cache /api/extract writes to, edge-cached 6h with 24h SWR
  for friendly behavior under GitHub's image proxy
- Friendly URL rewrites: /badge/<host> and /badge/<host>.svg → /api/badge/<host>

Why both: Grade is the artifact, Battle is the viral content layer
("Stripe vs Vercel — guess who lost"), Badge is the permanent
distribution layer (every README adoption is a backlink to a live
grade page).

13 new tests (336 total, all passing). Cover battle markup, score
comparison thresholds, SVG escaping, grade-color mapping, missing-score
handling.

Website: bumps v12.1 → v12.2 across home/gallery/spec/features/permalink,
adds /features#battle section, swaps Grade CTA chip to Battle.
2026-05-02 23:29:36 +04:00
Manav Arya Singh 5aac5e707d feat(v12.1): designlang grade — shareable HTML Design Report Card
Adds `designlang grade <url>` — a self-contained, editorial-style HTML
audit page (plus JSON + Markdown variants). Big serif letter grade,
eight scored dimensions with arc gauges, evidence pulled from the
audited site itself (palette swatches, type specimen, spacing rhythm),
and a strengths / what-to-fix ledger. Paper/ink theme with a dark
toggle, print-ready, OG meta for shareable links.

Why this exists: html.to.design, Locofy, Builder, Polypane all ship
extraction or layout cloning. None of them grade the design system
itself in a form you can post on Twitter or send to a client.

- src/formatters/grade.js — new formatHTML + formatMarkdown formatters
- bin/design-extract.js — `grade` subcommand with --format / --open
- 6 new tests covering shape, escaping, scale-shape regression
- README — trimmed 649 → 241 lines, restructured around outputs/moats
- website — adds /features#grade section, bumps v12 → v12.1 throughout
2026-04-29 13:25:27 +04:00
Manav Arya Singh e72f402971 v12.0.0 · v12 — chat · permalinks · gallery · spec 2026-04-26 21:55:36 +04:00
Manav Arya Singh 3aba1d251f v11.3.0 · chat REPL + permalinks + gallery + spec 2026-04-26 21:55:14 +04:00
Manav Arya Singh 2e74348acd v11.2.0 · DESIGN.md emitter + vs/design-extractor page 2026-04-25 21:05:59 +04:00
Manav Arya Singh a9b745a751 v11.1.0 · storybook emitter + motion replay (#9 #10) 2026-04-24 23:48:21 +04:00
Manav Arya Singh 6732d2768a v11.0.2 · --ignore-widgets (#15) 2026-04-24 23:40:31 +04:00
Manav Arya Singh 34ba9a5b27 v11.0.1 · shadow stringification + HSL NaN fixes (#42 #45) 2026-04-24 23:35:46 +04:00
Manav Arya Singh 419e8f19ed feat(v11): clone · ci · studio — three commands that end three paid categories
- clone v2: driven by sectionRoles + voice + materialLanguage. Emits a
  working Next.js repo that mirrors the target's actual section order,
  CTA verbs, and material treatment — not a generic palette demo.
- ci: one-shot PR-comment markdown (score + drift + optional visual-diff).
  Works in any CI. Writes GITHUB_STEP_SUMMARY automatically. Exits
  non-zero on configured drift threshold.
- studio: zero-dep local web studio over the latest extraction.
  localhost:4837. Clickable swatches, voice/DNA/motion, /raw endpoint.
- website: new V11 showcase below hero ("Stop shipping tokens. Start
  shipping the outcome."). v10 demoted to editorial supporting strip,
  v9 rewritten to numbered rows — kill the uniform-card-grid slop.
2026-04-24 23:28:54 +04:00
Manav Arya Singh 25db0fa7cb feat(v10.5): form & state capture — the states LLMs always botch
- form-states.js surfaces:
  - forms (input count + style families)
  - modal/dialog/sheet containers
  - skeleton + spinner loading indicators
  - empty-state + error-state placeholders
  - toast library detection (Sonner, react-hot-toast, react-toastify,
    Radix Toast, Chakra Toast, Notistack)
- New output: *-form-states.json
- Closes the v10.x minor-release series started in v10.1 — all v11
  deferred items now shipped as minors.
- 317/317 tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:15:06 +04:00
Manav Arya Singh 161403511d feat(v10.4): icon system + background patterns + stack intel
- icon-system.js fingerprints the icon library from stroke/fill
  dominance, stroke width, grid size, and rounded-caps presence.
  Recognises Lucide, Heroicons (outline+solid), Phosphor, Tabler,
  Feather, Remix, Material.
- background-patterns.js classifies noise/dot-grid/line-grid/
  gradient-mesh/svg-pattern/plain from background-image values.
- stack-intel.js extends stack-fingerprint with 12 CMS, 13 analytics,
  and 7 experimentation platform detectors.
- Bin now reads its version from package.json — no more drift.
- New outputs: *-icon-system.json, *-stack-intel.json.
- background-patterns merged into *-visual-dna.json.
- 313/313 tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:13:13 +04:00
Manav Arya Singh 33e5cd1620 feat(v10.3): perf (core web vitals + bundle) + SEO + structured data
- perf.js: fresh Playwright context measures LCP/CLS/INP via
  PerformanceObserver, categorises network responses into
  js/css/font/image/document/other bytes, counts third-party requests
  against a known-host list, synthesises an interaction so INP
  reports. Returns grade buckets per vital.
- seo.js: pure extractor for OG, Twitter, canonical, manifest,
  theme-color, viewport, favicons, and inline JSON-LD blocks.
- Crawler captures favicons + manifest link + JSON-LD script text.
- New flag --perf, auto-on with --full.
- New outputs: *-seo.json, *-perf.json.
- 307/307 tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:09:54 +04:00
Manav Arya Singh bd354e2971 feat(v10.2): dark-mode pairing + responsive screenshots
- dark-mode-pair.js joins light+dark passes into semantic role pairs
  (primary/secondary/accent/background/text), pairs CSS variables
  that actually differ, and emits a drop-in Tailwind darkMode config
  plus an audit of tokens missing from either pass
- responsive-screenshots.js captures full-page PNGs at mobile/tablet/
  desktop/wide × (light,dark) with a JSON index
- New flag --responsive-shots, auto-on with --full
- New outputs: *-dark-mode.json, *-responsive.json
- CLI version test now reads from package.json so future minor
  releases don't need to update the test
- 303/303 tests passing

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:06:18 +04:00
Manav Arya Singh c878d09ce0 feat(v10.1): cluster-aware retina component screenshots
Replaces the v9 hardcoded-selector screenshot pass with a cluster-
aware, retina (2×), multi-variant pipeline.

- New src/extractors/component-screenshots.js groups candidates by
  kind + variantHint + sizeHint and captures up to three reps per
  group. Falls back to the v9 hardcoded list when nothing clusters
  (auth / docs pages).
- Dedicated Playwright context at deviceScaleFactor: 2 for crisp crops
- New *-screenshots.json index maps every crop to cluster/bounds
- Markdown gains a Component Screenshots section
- No new CLI flags — --screenshots / --full still opt into capture
- 299/299 tests passing

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:01:27 +04:00
Manav Arya Singh bcfe9f84ce feat(v10): the Intent release — semantic layer for LLM agents
Six new extractors (page-intent, section-roles, component-library,
material-language, imagery-style, logo), a multi-page crawl
orchestrator with cross-page consistency, an optional --smart LLM
fallback, and a ready-to-paste prompt pack for v0 / Lovable / Cursor /
Claude Artifacts.

v9 captured *how* a site looks. v10 captures *what it is* — the
semantic signal an LLM needs to rebuild a site faithfully.

- page-intent.js: landing/pricing/docs/blog/product/about/dashboard/auth/legal
- section-roles.js: hero/feature-grid/logo-wall/stats/testimonial/
  pricing-table/faq/steps/comparison/bento/cta/footer + slot copy +
  reading order
- component-library.js: shadcn/Radix/MUI/Chakra/Mantine/AntD/HeroUI/
  Vuetify/Bootstrap/Tailwind detection with evidence + alternates
- material-language.js: glass/neumorph/flat/brutalist/soft-ui/
  material-you/skeuo from shadow + geometry + saturation
- imagery-style.js: photo/3d/iso/flat-illustration/mesh/icon-only/
  screenshot + dominant aspect + image-radius profile
- logo.js: SVG/PNG extraction + sampled clearspace
- multipage.js: auto-discovers canonical pages from nav, runs full
  pipeline per page, emits Jaccard consistency
- classifiers/smart.js: opt-in LLM refinement via OPENAI_API_KEY or
  ANTHROPIC_API_KEY, zero-dep fetch
- formatters/prompt-pack.js: v0.txt, lovable.txt, cursor.md,
  claude-artifacts.md, per-component recipe cards

New CLI flags: --smart, --pages <n>, --no-prompts.
New output files: *-intent.json, *-visual-dna.json, *-library.json,
*-logo.{svg,png,json}, *-multipage.json, *-prompts/.
Extended markdown: 6 new sections.
297/297 tests passing.

Website: v10 capabilities section, version stamps bumped to v10,
and a fix for the Specimens IntersectionObserver that was hijacking
--accent on page load before the specimens strip was ever in view.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 05:39:15 +04:00
Manav Arya Singh 13af4d8d8a feat(v9): motion · anatomy · voice — and lint/drift/visual-diff
Six new capabilities that push designlang past "extract the paint" into
"extract the feel, the anatomy, and the voice":

- motion language: easing-family classification, spring detection via
  cubic-bezier geometry, duration bucketing (instant/xs/sm/md/lg/xl/xxl),
  scroll-linked animation capture (animation-timeline / view-timeline /
  scroll-timeline), keyframe kind classification, and a one-word `feel`
  fingerprint. emits *-motion-tokens.json.
- component anatomy v2: variant × size × state matrices, slot inference
  (icon/label/badge/heading/media/footer), typed React stubs.
  emits *-anatomy.tsx.
- brand voice: tone (friendly/formal/technical/playful/neutral), pronoun
  posture (we→you / you-only / we-only / third-person), heading style,
  top CTA verbs, microcopy patterns. emits *-voice.json.
- designlang lint <file>: audit local DTCG / flat / css-vars token files
  for color sprawl, scale variance, contrast. non-zero exit on errors.
- designlang drift <url> --tokens <file>: verdict + ratio between local
  tokens and live site. --fail-on <level> for CI gating.
- designlang visual-diff <a> <b>: single-file HTML report with embedded
  screenshots, file-size deltas, changed-color-tokens table.

Crawler extended to capture animation-timeline + candidate text/slots/
variantHint/sizeHint/disabled. Markdown output gains Motion Language,
Component Anatomy, and Brand Voice sections. Website adds §00 v9 block.

All 282 tests pass (21 new in tests/v9-features.test.js).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 00:55:53 +04:00
Manavarya09 48b92c794b feat(v8): credibility + distribution release
Reliability fixes that restore trust on real sites:

- colors.js: brand-color detection rewritten — ranks chromatic clusters by
  interactiveBg x100 + saturation x2 + log(usage), requires HSL sat >25 or
  an interactive-bg hit. Linear primary: #d0d6e0 (gray) -> #e4f222 (lime).
  Stripe: #533afd. Verified on 5 ground-truth sites.
- accessibility.js + crawler.js: crawler now emits hasText per element
  (direct text-node child with visible chars); WCAG extractor filters
  decorative glyph spans, transparent overlays, non-text containers.
  Linear: 25% (171 failing pairs) -> 83% (1 failing pair).
- scoring.js: rubric recalibrated against Stripe/Linear/Vercel/GitHub/Apple.
  Loosened color/shadow/radii/type-scale thresholds; softened spacing
  no-base penalty when tokenization is present; cssHealth now weighted in
  the overall. Linear 47->76, Stripe 81->88, Apple 83->86.

New CLI flags:

- --selector <css>: scope extraction to a DOM subtree. Stripe: 2409 -> 112
  elements when scoped to footer. Falls back to full doc if invalid.
- --system-chrome: channel: 'chrome' in Playwright launch; skips the
  bundled Chromium download.
- --json: full extraction to stdout (already partial in v7, now first-class
  and documented).

New distribution surfaces (each publishes to its own registry):

- vscode-extension/: Extract-from-URL + inject-into-workspace commands.
- raycast-extension/: Extract, Score, Copy-CLI commands.
- figma-plugin/: URL or paste-JSON -> Figma Variables with multi-mode.
- github-action/: "Design regression guard" runs designlang on PRs, diffs
  tokens vs baseline, comments the delta, optional fail-on-change.
- smithery.yaml + smithery.dockerfile + docs/MCP-REGISTRY.md: MCP registry
  submission checklist.
- chrome-extension/PRIVACY.md + STORE_LISTING.md: Chrome/Firefox/Edge
  store listing prep (extension code already existed in v7.1).
- docs/LAUNCH.md: PH + Show HN + Twitter copy + day-of checklist.
- docs/demo.tape: VHS tape for the animated README hero.

README updated: hero references demo.gif with PNG fallback, adds "Install
everywhere" table for the new surfaces, documents the three new flags.
.npmignore excludes every companion-surface directory so the npm tarball
stays 109KB / 73 files.

All 275 tests pass.
2026-04-20 03:14:04 +04:00
Manav Arya Singh 866317dc13 chore(release): v7.2.0 (#37)
Bundles Tier 1 and Tier 2 extraction work:
- Modern CSS surfacing (#33)
- Wide-gamut color + CSS source attribution (#34)
- Auto-interact pass (#35)
- Multi-page token reconciliation (#36)
2026-04-19 03:38:32 +04:00
Manav Arya Singh aab2b0b72a feat(v7.1): --cookie-file, --insecure, --user-agent, Chrome extension (#30)
* docs: v7.1 spec — designer toolkit

* feat(v7.1): cookie-file loader + --insecure + --user-agent + Chrome extension

Ships three community-requested features in one release.

## Cookie handling
- `--cookie-file <path>` loads cookies from JSON array, Playwright storageState, or Netscape cookies.txt.
- `src/utils-cookies.js` with 8 unit tests covering all three formats plus merge-with-CLI behavior.

## Network / auth
- `--insecure` sets `ignoreHTTPSErrors: true` on the Playwright context and adds the matching Chromium flags.
- `--user-agent <ua>` overrides the browser UA.

## Chrome extension (chrome-extension/)
- Manifest v3 popup with activeTab permission only.
- Handoff button opens the hosted extractor with the current URL prefilled (via `?url=`).
- Copy-CLI button drops `npx designlang <url>` into the clipboard.
- Four PNG icons rendered from the existing favicon SVG.
- Install-in-dev-mode instructions in chrome-extension/README.md.

## Website
- HeroExtractor now honours `?url=` query param (Chrome extension handoff, deep links). Prefill is mount-only and URL-validated.

## Contributing
- CONTRIBUTING.md adds a 'Good first issues' list and a 'Credits' section. Bumped to v7.1.0.
2026-04-19 02:47:58 +04:00
Manav Arya Singh f0a5c9623a v7.0 part 3: release — README, CHANGELOG, version 7.0.0 (#20)
* docs(readme): v7 features — MCP, platforms, agent rules, health, remediation, regions

* docs: CHANGELOG for v7.0

* chore(release): v7.0.0
2026-04-18 14:57:30 +04:00