|
| 1 | +{ |
| 2 | + "$schema": "http://json-schema.org/draft-07/schema#", |
| 3 | + "title": ".impeccable/brand.json", |
| 4 | + "description": "Per-project opt-in. Absent by default: with no brand.json, ui-engineer and component-registry behave normally and ui-gate falls back to its default type scale. Present, it is read by ui-gate/rules/tokens.sh (TOK-TYPE-SCALE) and by impeccable. A skill that fires on whether something deserves to be beautiful will fire wrongly and constantly; a file in the repo is a decision somebody made.", |
| 5 | + "type": "object", |
| 6 | + "required": ["mode", "type"], |
| 7 | + "properties": { |
| 8 | + "mode": { |
| 9 | + "enum": ["pixel", "plate", "editorial", "custom"], |
| 10 | + "description": "Which measured mode this surface targets. See reference/modes/. Not a style preference: the modes contradict each other on base unit, grain and radius policy, and averaging them resolves each contradiction toward the stock default." |
| 11 | + }, |
| 12 | + "type": { |
| 13 | + "type": "object", |
| 14 | + "required": ["scale"], |
| 15 | + "properties": { |
| 16 | + "scale": { |
| 17 | + "type": "array", "items": {"type": "number"}, "minItems": 3, |
| 18 | + "description": "Font sizes in px. TOK-TYPE-SCALE fails any font-size not on this list. Measured references have no modular ratio: pixel has a 2.31x hole, plate runs two regimes, editorial uses 19 bespoke clamps. State the sizes, not a ratio." |
| 19 | + }, |
| 20 | + "tracking": { |
| 21 | + "type": "array", |
| 22 | + "description": "Tracking as a monotonic function of size, in em. Every reference locks this in em so it survives fluid resize untouched.", |
| 23 | + "items": { |
| 24 | + "type": "object", |
| 25 | + "required": ["minPx", "em"], |
| 26 | + "properties": { |
| 27 | + "minPx": {"type": "number"}, |
| 28 | + "em": {"type": "number", "description": "Negative on display, 0 mid-band, positive on small uppercase. Crossover sits at 15-20px in all three references."} |
| 29 | + } |
| 30 | + } |
| 31 | + }, |
| 32 | + "leading": { |
| 33 | + "type": "object", |
| 34 | + "description": "Line-height inverts with size in every reference. No exceptions found.", |
| 35 | + "properties": { |
| 36 | + "display": {"type": "number", "description": "0.88-0.95 measured"}, |
| 37 | + "mid": {"type": "number", "description": "1.35-1.5 measured"}, |
| 38 | + "body": {"type": "number", "description": "1.5-1.75 measured"} |
| 39 | + } |
| 40 | + }, |
| 41 | + "measureCh": {"type": "number", "description": "Max prose line length. 32.6-62 measured; all under 60 except plate's prose at 62. Machine output is exempt and runs long on purpose."} |
| 42 | + } |
| 43 | + }, |
| 44 | + "color": { |
| 45 | + "type": "object", |
| 46 | + "properties": { |
| 47 | + "ground": {"type": "string", "description": "Never pure black. Measured: #050505, #09090b, #060708."}, |
| 48 | + "ink": {"type": "string", "description": "Never pure white on dark. Measured: #f7f4ec (4.3% warm), #ecebf2 (cool)."}, |
| 49 | + "accent": {"type": "string", "description": "One hue, or none. pixel has no type accent and reserves #ffffff for a single line."}, |
| 50 | + "hairline": {"type": "string", "description": "Ink at low alpha. plate's most-used value is rgba(236,235,242,0.08) at 1033 occurrences; it has no solid grey borders at all."} |
| 51 | + } |
| 52 | + }, |
| 53 | + "spacing": { |
| 54 | + "type": "object", |
| 55 | + "properties": { |
| 56 | + "baseUnit": {"type": "number", "enum": [2, 4, 8], "description": "plate is 2 (85.8% of values), pixel and editorial are 4. Not 8 in any reference."}, |
| 57 | + "ratio": { |
| 58 | + "type": "array", "items": {"type": "number"}, |
| 59 | + "description": "Tight groups inside enormous silence. Measured: editorial 7:1, plate 1:1.5:3:5:16, pixel 24:1. The ratio is the signature, not any single value." |
| 60 | + } |
| 61 | + } |
| 62 | + }, |
| 63 | + "motion": { |
| 64 | + "type": "object", |
| 65 | + "properties": { |
| 66 | + "hoverMs": {"type": "number", "description": "130-200 in all references."}, |
| 67 | + "entranceMs": {"type": "number", "description": "420-760 in all references."}, |
| 68 | + "staggerMs": {"type": "number", "description": "45 (editorial), 75-80 (plate)."}, |
| 69 | + "easing": {"type": "object", "properties": { |
| 70 | + "micro": {"type": "string", "description": "cubic-bezier(.4,0,.2,1)"}, |
| 71 | + "entrance": {"type": "string", "description": "cubic-bezier(.16,1,.3,1) or cubic-bezier(0,0,.2,1)"} |
| 72 | + }} |
| 73 | + }, |
| 74 | + "description": "Two bands and a hole: nothing between 300 and 420ms in any reference." |
| 75 | + }, |
| 76 | + "radius": { |
| 77 | + "type": "array", "items": {"type": "number"}, |
| 78 | + "description": "editorial is binary: 0 or 9999, nothing between, 551 elements against 14. plate runs 8/12/28. Declare the set; anything off it is drift." |
| 79 | + }, |
| 80 | + "texture": { |
| 81 | + "type": "object", |
| 82 | + "description": "Optional. editorial ships none at all and still reads expensive, so absence is a valid choice rather than an omission.", |
| 83 | + "properties": { |
| 84 | + "grain": {"type": "object", "properties": { |
| 85 | + "baseFrequency": {"type": "number", "description": "0.85 (plate), 1.15 (pixel)"}, |
| 86 | + "numOctaves": {"type": "number"}, |
| 87 | + "opacity": {"type": "number", "description": "0.06 overlay (plate), 0.52 screen (pixel)"}, |
| 88 | + "blendMode": {"type": "string"} |
| 89 | + }} |
| 90 | + } |
| 91 | + } |
| 92 | + } |
| 93 | +} |
0 commit comments