Files
pbakaus_impeccable/.impeccable/design.json
T
373039a837 Give DESIGN.md a real type ramp so the design hook stops crying wolf (#390)
* Give DESIGN.md a real type ramp so the design hook stops crying wolf

The design hook fired on nearly every CSS file we touched. The cause was
DESIGN.md's typography block: it declared seven named roles rather than a
scale, and two of those roles used clamp(), which the extractor skipped
outright. That left an allowlist of five sizes standing against the 86
distinct font sizes actually in use, so design-system-font-size flagged
roughly 500 declarations. Editing any .astro page made it worse, because
the companion-stylesheet scan re-reported the whole backlog.

Extractor (cli/engine/design-system.mjs):
- Read a typography.scale map as the enumerated ramp.
- Read both clamp() endpoints as allowed sizes. These stay additive on
  purpose: clamp endpoints alone cannot switch the rule on, because a fully
  fluid system enumerates no discrete ramp and inferring one from its
  endpoints would flag every intermediate size. The existing abstention
  test still passes, and three new tests cover the added behavior.

DESIGN.md:
- Document a 19-step ramp, 8px through 72px at a 16px root.
- Snap the five discrete role sizes onto ramp steps.

This also fixes real drift. DESIGN.md claims to mirror kinpaku-tokens.css
verbatim, but wordmark was 1.15rem in the CSS against 1.3rem documented,
with tracking at 0.42em against 0.15em. Both are re-synced.

Standardization, 64 declarations:
- Six near-identical steps between 13.7px and 15.4px collapse onto 14 and 15.
- .foundation-card-label, .designing-lane-mock-title and
  .designing-iterate-name each existed at two different sizes in two files.
  Now unified.
- The wordmark rendered at four sizes (20.8, 18.4, 17, 16.8px). Now 18px,
  plus one deliberate smaller nav variant.

Exemptions, for designs that are foreign on purpose: the antipattern-example
fixtures, the neo-mirai case-study build, the periodic-table cell
annotations in framework-viz.js (5 to 7px diagram geometry sitting at 2 to
3px offsets), and the .why-slop-* before-state card's Inter and gradient
text.

Verified by computed style across ten rendered pages: every element lands on
a ramp step except clamp() values mid-interpolation, which is what fluid
means. Full test suite and build validators pass.

Generated provider output is deliberately left out; the sync workflow owns it.

Prepared with AI assistance (Claude Code).

Co-Authored-By: Claude <noreply@anthropic.com>

* Validate clamp() endpoints in usage, not just when reading DESIGN.md

Reading clamp endpoints as documented steps without also checking them in
source left an asymmetry: `isAllowedFontSizeRaw` returned true for anything
failing the px/rem literal test, so `clamp(99rem, 1vw, 200rem)` passed. That
is how `.ptable-symbol` at `clamp(1.45rem, 1.8vw, 1.8rem)` stayed invisible
until someone measured computed styles, which is not a check the hook can run.

Fluid values are now judged on their min and max. The viewport term
interpolates between them and is never a fixed step, so it is left alone.
Endpoints that cannot be resolved, such as var() or calc() or em, abstain
rather than guess. Findings name the offending endpoint and use it as the
ignore-value, because the whole clamp string is not actionable on its own.

Turning the check on surfaced 22 fluid declarations that had never been
looked at. Three used hero sizes above the ramp's 72px cap (80, 83.2 and
88px) alongside the display role's documented 89.6px max, so the top of the
ramp was genuinely incomplete. Added the 80 and 88 steps, which gives the
display end consistent 8px increments instead of 48/56/64/72 plus an orphan
at 89.6, and fixes two declarations outright.

The other 20 are snapped by a stated rule: nearest step, ties toward the
smaller step, endpoints already matching a documented fluid role left as-is,
and where nearest-step would make a breakpoint override meet or exceed its
base, the next smaller step so the override still reduces. That last case
applies once, to .designing-page-title.

Also narrows the framework-viz.js waiver. The periodic-table cell
annotations now carry two `impeccable-disable-line` comments naming the
reason, instead of a config entry wildcarding the whole file for the rule.
Inline waivers travel with the code and cannot silence future drift
elsewhere in that file.

Verified at 420px, 900px and 1600px across seven pages. The pinned ends are
fully on-ramp; the only off-ramp values at 900px are the vw term
mid-interpolation, which is what fluid means.

Prepared with AI assistance (Claude Code).

Co-Authored-By: Claude <noreply@anthropic.com>

* Address review: wordmark tracking picked the wrong side, stale ramp count

Two review findings, both fair.

Wordmark tracking (greptile, bugbot). This PR moved DESIGN.md's wordmark
letterSpacing from 0.15em to 0.42em on the grounds that DESIGN.md claims to
mirror kinpaku-tokens.css and the token read 0.42em. That was the wrong side
to trust. `--ks-type-wordmark-track` has exactly one consumer,
design-system.css:570, which is the specimen page. Every production lockup
(.ks-wordmark, .kinpaku-chrome .site-header-brand-name, .footer-logo)
hardcodes 0.15em, so 0.15em is what every visitor actually sees and what
DESIGN.md already documented correctly before this PR touched it.

Reverted the doc to 0.15em and moved the token to 0.15em as well, so the
specimen now renders the same lockup as production instead of a wider one
nothing else uses. Verified by computed style: header and specimen both
report 18px with 2.7px tracking. No production visual change.

Stale ramp count (copilot). The sidecar described an "18-step ramp, 8px
through 72px". It went stale twice inside this PR, once when the 8 step was
added and again when 80 and 88 were added for the hero display sizes. It is
21 steps, 8px through 88px.

Prepared with AI assistance (Claude Code).

Co-Authored-By: Claude <noreply@anthropic.com>

* Strip !important from the font-size ignore value

Follow-on from the waiver wiring in the hook branch. The ignoreValue is what a
`hooks ignore-value` waiver has to match, and `font-size: 1.4rem !important`
emitted `1.4rem !important` while a plain declaration emitted `1.4rem`. Once
font-size is a direct-value rule, that means the same size needs two different
waivers depending on whether it carries a priority marker.

font-family already strips the marker before matching, and there is a test for
that. font-size now does the same. The snippet still shows the declaration as
authored.

Prepared with AI assistance (Claude Code).

Co-Authored-By: Claude <noreply@anthropic.com>

* Have the wordmark rules consume their tokens instead of copying the values

Follow-up to the tracking fix, and the residual half of what the reviewers
were pointing at. `.ks-wordmark` and the kinpaku chrome lockup each repeated
`1.125rem` and `0.15em` literally rather than reading
`--ks-type-wordmark-size` and `--ks-type-wordmark-track`. That duplication is
exactly how the token drifted to 0.42em while every production lockup stayed
at 0.15em and nobody noticed, which is the confusion that started this thread.

The values already agree, so this is a no-op visually and is verified as such:
computed styles across the home, design-system, docs and changelog pages all
still report 18px with 2.7px tracking. What changes is that there is now one
place to edit, so the next tracking change cannot silently apply to the
specimen page alone.

Prepared with AI assistance (Claude Code).

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-19 20:39:55 -07:00

424 lines
20 KiB
JSON

{
"schemaVersion": 2,
"generatedAt": "2026-07-19T18:55:00.000Z",
"title": "Design System: Impeccable",
"extensions": {
"colorMeta": {
"kinpaku-gold": {
"role": "primary",
"displayName": "Kinpaku Gold",
"canonical": "oklch(84% 0.19 80.46)",
"description": "Primary accent. CTAs, wordmark, active state, live picker borders, key rules.",
"tonalRamp": [
"oklch(22% 0.04 78)",
"oklch(34% 0.06 78)",
"oklch(48% 0.08 78)",
"oklch(61% 0.085 78)",
"oklch(72% 0.105 82)",
"oklch(78% 0.12 82)",
"oklch(84% 0.075 84)",
"oklch(89% 0.055 84)",
"oklch(95% 0.04 84)",
"oklch(98% 0.04 84)",
"oklch(94% 0.07 82)",
"oklch(98% 0.035 84)"
]
},
"verdigris-patina": {
"role": "secondary",
"displayName": "Verdigris Patina",
"canonical": "oklch(70% 0.12 188)",
"description": "Secondary accent. Improved states, live indicators, focus rings, contrast against gold.",
"tonalRamp": [
"oklch(22% 0.04 188)",
"oklch(49% 0.08 188)",
"oklch(58% 0.085 185)",
"oklch(70% 0.105 190)",
"oklch(71% 0.082 184)",
"oklch(76% 0.088 190)",
"oklch(82% 0.07 188)"
]
},
"lacquer-black": {
"role": "neutral",
"displayName": "Lacquer Black",
"canonical": "oklch(7% 0.006 95)",
"description": "Default page ground. Warm mineral black, never pure #000.",
"tonalRamp": [
"oklch(4% 0.004 95)",
"oklch(7% 0.006 95)",
"oklch(11% 0.006 95)",
"oklch(15% 0.008 95)",
"oklch(19% 0.008 95)",
"oklch(22% 0.008 95)",
"oklch(34% 0.014 82)",
"oklch(58% 0.012 95)"
]
},
"neutral-text": {
"role": "neutral",
"displayName": "Neutral Text Ramp",
"canonical": "oklch(88% 0 0)",
"description": "Neutral white/gray text and utility stops shared by dark docs, live overlay, and light-mode chrome.",
"tonalRamp": [
"oklch(100% 0 0)",
"oklch(99% 0 0)",
"oklch(98.5% 0 0)",
"oklch(98% 0 0)",
"oklch(96% 0 0)",
"oklch(94% 0 0)",
"oklch(91% 0 0)",
"oklch(88% 0 0)",
"oklch(85% 0 0)",
"oklch(80% 0 0)",
"oklch(75% 0 0)",
"oklch(72% 0 0)",
"oklch(65% 0 0)",
"oklch(62% 0 0)",
"oklch(58% 0 0)",
"oklch(55% 0 0)",
"oklch(45% 0 0)",
"oklch(42% 0 0)",
"oklch(40% 0 0)",
"oklch(35% 0 0)",
"oklch(34% 0 0)",
"oklch(30% 0 0)",
"oklch(25% 0 0)",
"oklch(24% 0 0)",
"oklch(22% 0 0)"
]
},
"light-paper": {
"role": "neutral",
"displayName": "Light Mode Paper",
"canonical": "oklch(97% 0.012 95)",
"description": "Light theme surfaces, ink, and rules from site/styles/kinpaku-tokens.css.",
"tonalRamp": [
"oklch(99% 0.008 95)",
"oklch(97.5% 0.004 95)",
"oklch(97% 0.012 95)",
"oklch(96% 0.012 95)",
"oklch(94% 0.014 95)",
"oklch(92% 0.014 95)",
"oklch(91% 0.012 95)",
"oklch(88% 0.014 95)",
"oklch(72% 0.02 95)",
"oklch(65% 0.01 95)",
"oklch(55% 0.012 95)",
"oklch(45% 0.015 95)",
"oklch(30% 0.02 95)",
"oklch(25% 0.02 95)",
"oklch(25% 0.018 95)",
"oklch(18% 0.02 95)"
]
},
"command-category": {
"role": "data-viz",
"displayName": "Command Category Colors",
"canonical": "oklch(86% 0.075 82)",
"description": "Homepage proof modules use a constrained category palette for command groups, not generic decoration.",
"tonalRamp": [
"oklch(86% 0.075 82)",
"oklch(76% 0.088 190)",
"oklch(89% 0.055 84)",
"oklch(84% 0.055 84)",
"oklch(88% 0.047 84)",
"oklch(61% 0.085 78)",
"oklch(70% 0.096 72)",
"oklch(82% 0.095 76)",
"oklch(58% 0.085 185)",
"oklch(71% 0.082 184)",
"oklch(58% 0.028 82)",
"oklch(71% 0.028 82)"
]
},
"terminal-chrome": {
"role": "utility",
"displayName": "Terminal Chrome",
"canonical": "#ff5f56",
"description": "Conventional faux terminal traffic-light dots.",
"tonalRamp": [
"#ff5f56",
"#ffbd2e",
"#27c93f"
]
},
"vermilion-warning": {
"role": "state",
"displayName": "Vermilion Warning",
"canonical": "oklch(58% 0.15 35)",
"description": "Errors, anti-pattern warnings, live picker exit hover.",
"tonalRamp": [
"oklch(52% 0.16 35)",
"oklch(46% 0.13 35)",
"oklch(42% 0.13 35)",
"oklch(22% 0.04 35)",
"oklch(58% 0.15 35)"
]
},
"positive-success": {
"role": "state",
"displayName": "Positive Success",
"canonical": "oklch(45% 0.18 145)",
"description": "Success and accepted states: confirmation rows, diff additions, and positive status badges.",
"tonalRamp": [
"oklch(40% 0.10 145)",
"oklch(45% 0.18 145)",
"oklch(58% 0.12 145)",
"oklch(75% 0.12 145)",
"oklch(95% 0.05 145)",
"oklch(96% 0.04 145)"
]
}
},
"typographyMeta": {
"scale": {
"displayName": "Type Ramp",
"purpose": "The enumerated 21-step ramp at a 16px root, 8px through 88px. Roles below pick from it; display and headline are fluid and interpolate between clamp endpoints."
},
"wordmark": {
"displayName": "Wordmark",
"purpose": "IMPECCABLE lockup only. Alumni Sans at weight 400."
},
"display": {
"displayName": "Display",
"purpose": "Hero h1. Alumni Sans, weight 100."
},
"headline": {
"displayName": "Headline",
"purpose": "Section h2. Alumni Sans at weight 300, heavier than display."
},
"title": {
"displayName": "Title",
"purpose": "Panel and card headings (h3). Albert Sans."
},
"body": {
"displayName": "Body",
"purpose": "Long copy. Albert Sans, line-height 1.8, max 65\u201375ch."
},
"eyebrow": {
"displayName": "Eyebrow",
"purpose": "Short mono labels above titles. Uppercase, tracked."
},
"mono": {
"displayName": "Mono Label",
"purpose": "Command names, audit lines, table headers."
}
},
"shadows": [
{
"name": "Panel Setback",
"value": "0 24px 70px oklch(2% 0.004 95 / 0.42)",
"purpose": "Large framed modules only."
},
{
"name": "CTA Lift",
"value": "0 18px 48px oklch(2% 0.004 95 / 0.4)",
"purpose": "Primary button hover lift on large CTAs."
},
{
"name": "Patina Glow",
"value": "0 0 22px oklch(70% 0.105 190 / 0.24)",
"purpose": "Tiny live indicators only."
},
{
"name": "Picker Halo",
"value": "0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28)",
"purpose": "Live mode global and contextual picker bars."
}
],
"motion": [
{
"name": "ks-ease",
"value": "cubic-bezier(0.2, 0.8, 0.2, 1)",
"purpose": "Default kit easing for color, border, and transform transitions."
}
],
"breakpoints": [
{
"name": "md",
"value": "980px"
},
{
"name": "lg",
"value": "1080px"
}
],
"roundedMeta": {
"code": {
"value": "3px",
"purpose": "Inline code, terminal chips, tiny badges."
},
"controlSm": {
"value": "5px",
"purpose": "Compact icon and chip controls."
},
"controlMd": {
"value": "7px",
"purpose": "Live overlay buttons and segmented controls."
},
"xl": {
"value": "10px",
"purpose": "Picker bars, compact frames, and small visual shells."
},
"panel": {
"value": "12px",
"purpose": "Larger panels and demo canvases."
},
"overlay": {
"value": "14px",
"purpose": "Detached overlay panels."
},
"visualFrame": {
"value": "16px",
"purpose": "Large illustrative frames only."
},
"pill": {
"value": "999px",
"purpose": "Tags, toggles, and circular controls."
}
}
},
"components": [
{
"name": "Primary Button",
"kind": "button",
"refersTo": "button-primary",
"description": "Filled kinpaku CTA on lacquer. Both .ks-button and .ks-button-primary required.",
"html": "<button type=\"button\" class=\"ds-btn-primary\">Get started</button>",
"css": ".ds-btn-primary { display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 0 28px; font-family: \"Albert Sans\", \"Avenir Next\", \"Helvetica Neue\", Arial, system-ui, sans-serif; font-size: 0.96rem; font-weight: 500; line-height: 1; color: oklch(4% 0.004 95); background: oklch(84% 0.19 80.46); border: 1px solid oklch(84% 0.19 80.46); border-radius: 2px; cursor: pointer; transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1), background-color 180ms cubic-bezier(0.2, 0.8, 0.2, 1), border-color 180ms cubic-bezier(0.2, 0.8, 0.2, 1); } .ds-btn-primary:hover { background: oklch(86% 0.07 84); border-color: oklch(86% 0.07 84); transform: translateY(-1px); } .ds-btn-primary:active { transform: translateY(0); background: oklch(77% 0.13 82); border-color: oklch(77% 0.13 82); } .ds-btn-primary:focus-visible { outline: 2px solid oklch(70% 0.12 188); outline-offset: 3px; }"
},
{
"name": "Secondary Button",
"kind": "button",
"refersTo": "button-secondary",
"description": "Outlined kinpaku on transparent lacquer.",
"html": "<button type=\"button\" class=\"ds-btn-secondary\">See the rules</button>",
"css": ".ds-btn-secondary { display: inline-flex; align-items: center; justify-content: center; min-height: 52px; padding: 0 28px; font-family: \"Albert Sans\", \"Avenir Next\", \"Helvetica Neue\", Arial, system-ui, sans-serif; font-size: 0.96rem; font-weight: 500; color: oklch(84% 0.19 80.46); background: transparent; border: 1px solid oklch(84% 0.19 80.46); border-radius: 2px; cursor: pointer; transition: transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1), background-color 180ms cubic-bezier(0.2, 0.8, 0.2, 1); } .ds-btn-secondary:hover { background: oklch(77% 0.14 82 / 0.08); transform: translateY(-1px); } .ds-btn-secondary:focus-visible { outline: 2px solid oklch(70% 0.12 188); outline-offset: 3px; }"
},
{
"name": "Text Input",
"kind": "input",
"refersTo": "input-text",
"description": "Raised lacquer field with gold hairline border, patina focus.",
"html": "<input type=\"text\" class=\"ds-input-text\" placeholder=\"Search commands\">",
"css": ".ds-input-text { width: 100%; min-height: 46px; padding: 0 14px; font-family: \"Albert Sans\", \"Avenir Next\", \"Helvetica Neue\", Arial, system-ui, sans-serif; font-size: 0.92rem; color: oklch(84% 0.035 82); background: oklch(11% 0.006 95); border: 1px solid oklch(58% 0.065 82 / 0.32); border-radius: 2px; outline: none; transition: border-color 180ms cubic-bezier(0.2, 0.8, 0.2, 1); } .ds-input-text::placeholder { color: oklch(63% 0.024 82); } .ds-input-text:focus { border-color: oklch(70% 0.12 188); }"
},
{
"name": "Site Navigation",
"kind": "nav",
"refersTo": "nav-link",
"description": "Dark header nav. Champagne at rest, kinpaku on hover/active.",
"html": "<nav class=\"ds-nav\"><a href=\"/\" class=\"ds-nav-link ds-nav-active\">Home</a><a href=\"/docs\" class=\"ds-nav-link\">Docs</a></nav>",
"css": ".ds-nav { display: flex; gap: clamp(22px, 3vw, 48px); font-family: \"Albert Sans\", \"Avenir Next\", \"Helvetica Neue\", Arial, system-ui, sans-serif; font-size: 0.95rem; } .ds-nav-link { color: oklch(84% 0.035 82); text-decoration: none; transition: color 180ms cubic-bezier(0.2, 0.8, 0.2, 1); } .ds-nav-link:hover { color: oklch(84% 0.19 80.46); } .ds-nav-active { color: oklch(84% 0.19 80.46); }"
},
{
"name": "Bento Tile",
"kind": "card",
"refersTo": "card",
"description": "Flat lacquer tile inside the 12-column bento grid. No nested cards.",
"html": "<article class=\"ds-bento-tile\"><span class=\"ds-bento-num\">01</span><h3 class=\"ds-bento-title\">Respects your design system.</h3><p class=\"ds-bento-body\">Inherits tokens and conventions instead of overwriting them.</p></article>",
"css": ".ds-bento-tile { display: flex; flex-direction: column; gap: 14px; padding: 48px; background: oklch(7% 0.006 95); border: 0; border-radius: 0; font-family: \"Albert Sans\", \"Avenir Next\", \"Helvetica Neue\", Arial, system-ui, sans-serif; } .ds-bento-num { font-family: \"SFMono-Regular\", \"Roboto Mono\", Consolas, monospace; font-size: 0.62rem; letter-spacing: 0.28em; text-transform: uppercase; color: oklch(84% 0.19 80.46); } .ds-bento-title { margin: 0; font-size: 1.18rem; font-weight: 500; color: oklch(84% 0.035 82); } .ds-bento-body { margin: 0; font-size: 1.02rem; line-height: 1.8; color: oklch(81% 0.03 82); max-width: 65ch; }"
},
{
"name": "Live Picker Bar",
"kind": "custom",
"refersTo": "live-picker-bar",
"description": "Global live mode bar. Lacquer-deep fill, kinpaku border, carved-tile mark.",
"html": "<div class=\"ds-live-bar\"><span class=\"ds-live-mark\" aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"18\" height=\"18\"><path d=\"M5 2.5 L13.5 2.5 L5.5 21.5 L5 21.5 Q2.5 21.5 2.5 19 L2.5 5 Q2.5 2.5 5 2.5 Z\"/><path d=\"M16.5 2.5 L19 2.5 Q21.5 2.5 21.5 5 L21.5 19 Q21.5 21.5 19 21.5 L8.5 21.5 Z\"/></svg></span><button type=\"button\" class=\"ds-live-toggle is-active\">Pick</button><button type=\"button\" class=\"ds-live-toggle\">Detect</button></div>",
"css": ".ds-live-bar { display: inline-flex; align-items: center; gap: 2px; padding: 4px 5px; background: oklch(4% 0.004 95); border: 1.5px solid oklch(84% 0.19 80.46); border-radius: 10px; box-shadow: 0 0 0 1px oklch(78% 0.12 82 / 0.18), 0 10px 28px oklch(0% 0 0 / 0.28); font-family: system-ui, -apple-system, sans-serif; font-size: 12px; color: oklch(84% 0.035 82); } .ds-live-mark { display: inline-flex; align-items: center; padding: 0 12px 0 14px; color: oklch(84% 0.19 80.46); } .ds-live-toggle { padding: 6px 8px; border: none; border-radius: 7px; background: transparent; color: oklch(63% 0.024 82); font-family: inherit; font-size: 11.5px; font-weight: 500; cursor: pointer; transition: background 0.15s ease, color 0.15s ease; } .ds-live-toggle:hover { color: oklch(84% 0.035 82); } .ds-live-toggle.is-active { background: oklch(78% 0.12 82 / 0.18); color: oklch(84% 0.19 80.46); } .ds-live-toggle:focus-visible { outline: none; box-shadow: 0 0 0 2px oklch(84% 0.19 80.46 / 0.18), 0 0 0 3px oklch(84% 0.19 80.46); }"
}
],
"narrative": {
"northStar": "Neo Kinpaku",
"overview": "Impeccable is a dark lacquer interface marked by Japanese gold leaf and precise technical geometry. The brand should feel like a crafted object: black urushi, irregular kinpaku seams, quiet measurement marks, circuit traces, and controlled verdigris oxidation. It is refined, technical, and physical. This direction replaces the old warm-paper editorial system.",
"keyCharacteristics": [
"Dark mineral and lacquer surfaces, never pure black.",
"Kinpaku gold as the primary accent, with true leaf texture where an element carries brand weight.",
"Verdigris patina as the secondary accent for state, contrast, and improved signals.",
"A geometric sans voice with a widely tracked wordmark, not a serif editorial voice.",
"Thin calibration lines, circuit geometry, and gold seams used as functional structure.",
"Small radii, restrained borders, and almost no decorative shadow."
],
"rules": [
{
"name": "The Gold Carries Brand Rule",
"section": "colors",
"body": "Kinpaku gold is the primary brand signal. If a single accent must represent Impeccable, use gold, not magenta or cyan."
},
{
"name": "The Patina Has Meaning Rule",
"section": "colors",
"body": "Verdigris is secondary. It marks improvement, live state, or contrast against gold. Do not use it as a generic decoration field."
},
{
"name": "The Texture Budget Rule",
"section": "colors",
"body": "Leaf and patina textures are for brand-bearing moments: hero seams, CTA fills, dividers, major swatches, and select system modules. Generic cards stay mostly flat."
},
{
"name": "The OKLCH-Only Rule",
"section": "colors",
"body": "New colors are declared in OKLCH. Hex appears only inside third-party examples or imported assets."
},
{
"name": "The Weight-Inversion Rule",
"section": "typography",
"body": "Section h2s read heavier (300) than the hero h1 (100). This is deliberate: the hero is elegant and thin so the page can breathe; section anchors carry more weight to ground each block."
},
{
"name": "The Two-Face Rule",
"section": "typography",
"body": "Display sizes use Alumni Sans \u2014 thin (100) for the h1, heavier (300) for h2s. Anything sized below 1.2rem uses Albert Sans. The thin display cut reads too light at small sizes, so it never carries body or UI text."
},
{
"name": "The Tracked Labels Are Short Rule",
"section": "typography",
"body": "Tracked uppercase labels are for short system markers. Do not write full sentences in tracked caps."
},
{
"name": "The Dark Type Needs Air Rule",
"section": "typography",
"body": "Body text on lacquer uses line-height 1.65 to 1.8 and a max width of 65 to 75ch."
},
{
"name": "The Hairline First Rule",
"section": "elevation",
"body": "Use 1px gold hairlines before adding shadow."
},
{
"name": "The No Glass Rule",
"section": "elevation",
"body": "Translucency can exist in overlays, but decorative blur/glass panels are not part of this system."
},
{
"name": "The Picker Is Brand Rule",
"section": "components",
"body": "Live mode UI is Impeccable product chrome, not host-page chrome. It always ships the full kinpaku border, lacquer-deep fill, and carved-tile mark."
}
],
"dos": [
"Do use kinpaku gold as the primary brand color.",
"Do use verdigris patina for secondary state and contrast.",
"Do keep surfaces dark, warm, and mineral.",
"Do use real texture assets for gold leaf and oxidation when the element is brand-bearing.",
"Do use circuit/calibration geometry as structure, especially around product proof.",
"Do keep cards compact, flat, and sharply bounded.",
"Do preserve utility: demos, sliders, audit tables, command examples, docs, and pricing must remain understandable.",
"Do keep live mode picker bars on lacquer-deep with kinpaku gold borders, regardless of host page theme."
],
"donts": [
"Do not use editorial magenta as a brand accent.",
"Do not use italic serif display typography.",
"Do not use purple gradients, neon cyan fields, glassmorphism, or generic AI-tool glow.",
"Do not put gold texture under long text.",
"Do not use beige, paper, or cream as the page ground.",
"Do not add decorative calibration marks that do not align with real content.",
"Do not use wide rounded cards or nested cards.",
"Do not use pure black or pure white.",
"Do not let the visual system hide the product proof.",
"Do not theme-adapt live mode picker chrome to match arbitrary host pages. The picker is always neo-kinpaku."
]
}
}