markilo 0.4.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/README.md +132 -79
  2. package/THIRD_PARTY_NOTICES.md +26 -12
  3. package/package.json +15 -1
  4. package/plugin/.claude-plugin/icon.png +0 -0
  5. package/plugin/.claude-plugin/plugin.json +1 -1
  6. package/plugin/THIRD_PARTY_NOTICES.md +26 -12
  7. package/plugin/agents/concept-designer.md +111 -76
  8. package/plugin/agents/design-critic.md +32 -68
  9. package/plugin/dist/markilo.mjs +271 -178
  10. package/plugin/fonts/alegreya-sans/OFL.txt +93 -0
  11. package/plugin/fonts/alegreya-sans/alegreya-sans-latin-400-normal.woff +0 -0
  12. package/plugin/fonts/alegreya-sans/alegreya-sans-latin-500-normal.woff +0 -0
  13. package/plugin/fonts/alegreya-sans/alegreya-sans-latin-700-normal.woff +0 -0
  14. package/plugin/fonts/alegreya-sans/alegreya-sans-latin-800-normal.woff +0 -0
  15. package/plugin/fonts/alegreya-sans/alegreya-sans-latin-ext-400-normal.woff +0 -0
  16. package/plugin/fonts/alegreya-sans/alegreya-sans-latin-ext-500-normal.woff +0 -0
  17. package/plugin/fonts/alegreya-sans/alegreya-sans-latin-ext-700-normal.woff +0 -0
  18. package/plugin/fonts/alegreya-sans/alegreya-sans-latin-ext-800-normal.woff +0 -0
  19. package/plugin/fonts/archivo/OFL.txt +93 -0
  20. package/plugin/fonts/archivo/archivo-latin-400-normal.woff +0 -0
  21. package/plugin/fonts/archivo/archivo-latin-500-normal.woff +0 -0
  22. package/plugin/fonts/archivo/archivo-latin-600-normal.woff +0 -0
  23. package/plugin/fonts/archivo/archivo-latin-700-normal.woff +0 -0
  24. package/plugin/fonts/archivo/archivo-latin-800-normal.woff +0 -0
  25. package/plugin/fonts/archivo/archivo-latin-900-normal.woff +0 -0
  26. package/plugin/fonts/archivo/archivo-latin-ext-400-normal.woff +0 -0
  27. package/plugin/fonts/archivo/archivo-latin-ext-500-normal.woff +0 -0
  28. package/plugin/fonts/archivo/archivo-latin-ext-600-normal.woff +0 -0
  29. package/plugin/fonts/archivo/archivo-latin-ext-700-normal.woff +0 -0
  30. package/plugin/fonts/archivo/archivo-latin-ext-800-normal.woff +0 -0
  31. package/plugin/fonts/archivo/archivo-latin-ext-900-normal.woff +0 -0
  32. package/plugin/fonts/atkinson-hyperlegible-next/OFL.txt +93 -0
  33. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-400-normal.woff +0 -0
  34. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-500-normal.woff +0 -0
  35. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-600-normal.woff +0 -0
  36. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-700-normal.woff +0 -0
  37. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-800-normal.woff +0 -0
  38. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-ext-400-normal.woff +0 -0
  39. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-ext-500-normal.woff +0 -0
  40. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-ext-600-normal.woff +0 -0
  41. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-ext-700-normal.woff +0 -0
  42. package/plugin/fonts/atkinson-hyperlegible-next/atkinson-hyperlegible-next-latin-ext-800-normal.woff +0 -0
  43. package/plugin/fonts/bricolage-grotesque/OFL.txt +93 -0
  44. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-400-normal.woff +0 -0
  45. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-500-normal.woff +0 -0
  46. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-600-normal.woff +0 -0
  47. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-700-normal.woff +0 -0
  48. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-800-normal.woff +0 -0
  49. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-ext-400-normal.woff +0 -0
  50. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-ext-500-normal.woff +0 -0
  51. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-ext-600-normal.woff +0 -0
  52. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-ext-700-normal.woff +0 -0
  53. package/plugin/fonts/bricolage-grotesque/bricolage-grotesque-latin-ext-800-normal.woff +0 -0
  54. package/plugin/fonts/dm-serif-display/OFL.txt +93 -0
  55. package/plugin/fonts/dm-serif-display/dm-serif-display-latin-400-normal.woff +0 -0
  56. package/plugin/fonts/dm-serif-display/dm-serif-display-latin-ext-400-normal.woff +0 -0
  57. package/plugin/fonts/familjen-grotesk/OFL.txt +93 -0
  58. package/plugin/fonts/familjen-grotesk/familjen-grotesk-latin-400-normal.woff +0 -0
  59. package/plugin/fonts/familjen-grotesk/familjen-grotesk-latin-500-normal.woff +0 -0
  60. package/plugin/fonts/familjen-grotesk/familjen-grotesk-latin-600-normal.woff +0 -0
  61. package/plugin/fonts/familjen-grotesk/familjen-grotesk-latin-700-normal.woff +0 -0
  62. package/plugin/fonts/familjen-grotesk/familjen-grotesk-latin-ext-400-normal.woff +0 -0
  63. package/plugin/fonts/familjen-grotesk/familjen-grotesk-latin-ext-500-normal.woff +0 -0
  64. package/plugin/fonts/familjen-grotesk/familjen-grotesk-latin-ext-600-normal.woff +0 -0
  65. package/plugin/fonts/familjen-grotesk/familjen-grotesk-latin-ext-700-normal.woff +0 -0
  66. package/plugin/fonts/fonts.json +628 -0
  67. package/plugin/fonts/instrument-serif/OFL.txt +93 -0
  68. package/plugin/fonts/instrument-serif/instrument-serif-latin-400-normal.woff +0 -0
  69. package/plugin/fonts/instrument-serif/instrument-serif-latin-ext-400-normal.woff +0 -0
  70. package/plugin/fonts/newsreader/OFL.txt +93 -0
  71. package/plugin/fonts/newsreader/newsreader-latin-400-normal.woff +0 -0
  72. package/plugin/fonts/newsreader/newsreader-latin-500-normal.woff +0 -0
  73. package/plugin/fonts/newsreader/newsreader-latin-600-normal.woff +0 -0
  74. package/plugin/fonts/newsreader/newsreader-latin-700-normal.woff +0 -0
  75. package/plugin/fonts/newsreader/newsreader-latin-800-normal.woff +0 -0
  76. package/plugin/fonts/newsreader/newsreader-latin-ext-400-normal.woff +0 -0
  77. package/plugin/fonts/newsreader/newsreader-latin-ext-500-normal.woff +0 -0
  78. package/plugin/fonts/newsreader/newsreader-latin-ext-600-normal.woff +0 -0
  79. package/plugin/fonts/newsreader/newsreader-latin-ext-700-normal.woff +0 -0
  80. package/plugin/fonts/newsreader/newsreader-latin-ext-800-normal.woff +0 -0
  81. package/plugin/fonts/schibsted-grotesk/OFL.txt +93 -0
  82. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-400-normal.woff +0 -0
  83. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-500-normal.woff +0 -0
  84. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-600-normal.woff +0 -0
  85. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-700-normal.woff +0 -0
  86. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-800-normal.woff +0 -0
  87. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-900-normal.woff +0 -0
  88. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-ext-400-normal.woff +0 -0
  89. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-ext-500-normal.woff +0 -0
  90. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-ext-600-normal.woff +0 -0
  91. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-ext-700-normal.woff +0 -0
  92. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-ext-800-normal.woff +0 -0
  93. package/plugin/fonts/schibsted-grotesk/schibsted-grotesk-latin-ext-900-normal.woff +0 -0
  94. package/plugin/fonts/space-mono/OFL.txt +93 -0
  95. package/plugin/fonts/space-mono/space-mono-latin-400-normal.woff +0 -0
  96. package/plugin/fonts/space-mono/space-mono-latin-700-normal.woff +0 -0
  97. package/plugin/fonts/space-mono/space-mono-latin-ext-400-normal.woff +0 -0
  98. package/plugin/fonts/space-mono/space-mono-latin-ext-700-normal.woff +0 -0
  99. package/plugin/fonts/syne/OFL.txt +93 -0
  100. package/plugin/fonts/syne/syne-latin-400-normal.woff +0 -0
  101. package/plugin/fonts/syne/syne-latin-500-normal.woff +0 -0
  102. package/plugin/fonts/syne/syne-latin-600-normal.woff +0 -0
  103. package/plugin/fonts/syne/syne-latin-700-normal.woff +0 -0
  104. package/plugin/fonts/syne/syne-latin-800-normal.woff +0 -0
  105. package/plugin/fonts/syne/syne-latin-ext-400-normal.woff +0 -0
  106. package/plugin/fonts/syne/syne-latin-ext-500-normal.woff +0 -0
  107. package/plugin/fonts/syne/syne-latin-ext-600-normal.woff +0 -0
  108. package/plugin/fonts/syne/syne-latin-ext-700-normal.woff +0 -0
  109. package/plugin/fonts/syne/syne-latin-ext-800-normal.woff +0 -0
  110. package/plugin/fonts/unbounded/OFL.txt +93 -0
  111. package/plugin/fonts/unbounded/unbounded-latin-400-normal.woff +0 -0
  112. package/plugin/fonts/unbounded/unbounded-latin-500-normal.woff +0 -0
  113. package/plugin/fonts/unbounded/unbounded-latin-600-normal.woff +0 -0
  114. package/plugin/fonts/unbounded/unbounded-latin-700-normal.woff +0 -0
  115. package/plugin/fonts/unbounded/unbounded-latin-800-normal.woff +0 -0
  116. package/plugin/fonts/unbounded/unbounded-latin-900-normal.woff +0 -0
  117. package/plugin/fonts/unbounded/unbounded-latin-ext-400-normal.woff +0 -0
  118. package/plugin/fonts/unbounded/unbounded-latin-ext-500-normal.woff +0 -0
  119. package/plugin/fonts/unbounded/unbounded-latin-ext-600-normal.woff +0 -0
  120. package/plugin/fonts/unbounded/unbounded-latin-ext-700-normal.woff +0 -0
  121. package/plugin/fonts/unbounded/unbounded-latin-ext-800-normal.woff +0 -0
  122. package/plugin/fonts/unbounded/unbounded-latin-ext-900-normal.woff +0 -0
  123. package/plugin/fonts/young-serif/OFL.txt +93 -0
  124. package/plugin/fonts/young-serif/young-serif-latin-400-normal.woff +0 -0
  125. package/plugin/fonts/young-serif/young-serif-latin-ext-400-normal.woff +0 -0
  126. package/plugin/fonts/zilla-slab/OFL.txt +93 -0
  127. package/plugin/fonts/zilla-slab/zilla-slab-latin-400-normal.woff +0 -0
  128. package/plugin/fonts/zilla-slab/zilla-slab-latin-500-normal.woff +0 -0
  129. package/plugin/fonts/zilla-slab/zilla-slab-latin-600-normal.woff +0 -0
  130. package/plugin/fonts/zilla-slab/zilla-slab-latin-700-normal.woff +0 -0
  131. package/plugin/fonts/zilla-slab/zilla-slab-latin-ext-400-normal.woff +0 -0
  132. package/plugin/fonts/zilla-slab/zilla-slab-latin-ext-500-normal.woff +0 -0
  133. package/plugin/fonts/zilla-slab/zilla-slab-latin-ext-600-normal.woff +0 -0
  134. package/plugin/fonts/zilla-slab/zilla-slab-latin-ext-700-normal.woff +0 -0
  135. package/plugin/skills/concepts/SKILL.md +18 -23
  136. package/plugin/skills/design/SKILL.md +125 -94
  137. package/plugin/skills/design/references/cli.md +58 -55
  138. package/plugin/skills/design/references/construction.md +47 -40
  139. package/plugin/skills/design/references/design-principles.md +163 -126
  140. package/plugin/skills/design/references/svg-authoring.md +11 -8
  141. package/plugin/skills/design/references/workflow.md +19 -20
  142. package/plugin/skills/export/SKILL.md +6 -3
  143. package/plugin/skills/gallery/SKILL.md +10 -7
  144. package/plugin/skills/refine/SKILL.md +18 -13
  145. package/plugin/skills/research/SKILL.md +3 -2
@@ -24,72 +24,75 @@ Brief fields: `oneLiner`, `mode` (new/refresh/redesign/evaluate), `product{type,
24
24
 
25
25
  ## Research
26
26
 
27
- | Command | Purpose |
28
- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
29
- | `research site <url> --brand s --allow-network [--pages 8] [--download-assets] [--allow-private]` | Multi-page read: robots, sitemap, brand pages, JSON-LD, colors/fonts, logo candidates; access gaps recorded. |
30
- | `research competitors --brand s --allow-network [--url U --name N]… [--pages 3]` | Competitor findings + logos/icons collected as reference marks. |
31
- | `research app "<name | id | url>" --brand s --allow-network [--store ios\|android] [--competitor] [--as-reference]` | App Store (iTunes Search API) / Google Play listing. |
32
- | `research monorepo <repo> [--register --groups products,apps --parent p --lock a,b --scan]` | Find sites/apps/packages; register brandable ones with `codePaths`; scan each. |
33
- | `research repo [<path>] --brand s [--full]` | Local scan: package.json, README, logos, icon sets, design-system docs, manifests, CSS colors, fonts. Summary by default (full scan cached). Skips secret-like files. |
34
- | `profile understanding --brand s` | What the product does, for whom, where and at what price — with sources, stated vs inferred, and what is unknown. |
35
- | `profile tidy --brand s` | Rewrite the profile without absolute local paths (before committing a workspace). |
36
- | `profile show --brand s [--full] [--topic t]` | Brand Intelligence Profile summary. |
37
- | `profile add-source --brand s --type url\|search\|registry\|file\|user --ref R [--notes N]` | Log a source with date. Returns its id (S1…). |
38
- | `profile add-finding --brand s --topic T --status observed\|inferred\|verified\|user-provided --statement "…" --source S1,S2 [--confidence low\|medium\|high]` | Record a finding. observed/verified need sources. |
39
- | `profile add-gap --brand s --text "…"` | Record an unknown. |
40
- | `answers --brand s [--question Q --answer A]` | Questions already asked; record new ones. |
41
- | `reference remove --brand s --id ID[,ID]` | Remove wrong or duplicate reference marks. |
42
- | `reference dedupe --brand s [--apply]` | Find (and remove) files that add no evidence: near-identical files of one brand, one artwork under two names. |
43
- | `reference list --brand s` | References grouped by brand, with source quality (official, store, catalog, unverified). |
44
- | `similarity calibrate (--brand s \| <folder>)` | Measure how well copies are caught and different marks kept apart on real logos. |
45
- | `reference add --brand s --file F --name "Brand" --source URL [--category direct\|indirect\|category]` | Add a reference mark (SVG/PNG/JPG) for similarity checks. |
27
+ | Command | Purpose |
28
+ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
29
+ | `research site <url> --brand s --allow-network [--pages 8] [--download-assets] [--allow-private]` | Multi-page read: robots, sitemap, brand pages, JSON-LD, colors/fonts, logo candidates; access gaps recorded. |
30
+ | `research competitors --brand s --allow-network [--url U --name N]… [--pages 3]` | Competitor findings + logos/icons collected as reference marks. |
31
+ | `research app "<name | id | url>" --brand s --allow-network [--store ios\|android] [--competitor] [--as-reference]` | App Store (iTunes Search API) / Google Play listing. |
32
+ | `research monorepo <repo> [--register --groups products,apps --parent p --lock a,b --scan]` | Find sites/apps/packages; register brandable ones with `codePaths`; scan each. |
33
+ | `research repo [<path>] --brand s [--full]` | Local scan: package.json, README, logos, icon sets, design-system docs, manifests, CSS colors, fonts. Summary by default (full scan cached). Skips secret-like files. |
34
+ | `profile understanding --brand s` | What the product does, for whom, where and at what price — with sources, stated vs inferred, and what is unknown. |
35
+ | `profile tidy --brand s` | Rewrite the profile without absolute local paths (before committing a workspace). |
36
+ | `profile show --brand s [--full] [--topic t]` | Brand Intelligence Profile summary. |
37
+ | `profile add-source --brand s --type url\|search\|registry\|file\|user --ref R [--notes N]` | Log a source with date. Returns its id (S1…). |
38
+ | `profile add-finding --brand s --topic T --status observed\|inferred\|verified\|user-provided --statement "…" --source S1,S2 [--confidence low\|medium\|high]` | Record a finding. observed/verified need sources. |
39
+ | `profile add-gap --brand s --text "…"` | Record an unknown. |
40
+ | `answers --brand s [--question Q --answer A]` | Questions already asked; record new ones. |
41
+ | `reference remove --brand s --id ID[,ID]` | Remove wrong or duplicate reference marks. |
42
+ | `reference dedupe --brand s [--apply]` | Find (and remove) files that add no evidence: near-identical files of one brand, one artwork under two names. |
43
+ | `reference list --brand s` | References grouped by brand, with source quality (official, store, catalog, unverified). |
44
+ | `similarity calibrate (--brand s \| <folder>)` | Measure how well copies are caught and different marks kept apart on real logos. |
45
+ | `reference add --brand s --file F --name "Brand" --source URL [--category direct\|indirect\|category\|form-family\|inspiration\|dislike\|existing] [--notes "…"]` | Add a reference mark or image. Competitor categories feed similarity and the context sheet; `inspiration`, `dislike` and `existing` are the user's own references (logos, screenshots, mood boards, sketches) — read for characteristics, compared for originality, never shown as competitors. |
46
46
 
47
47
  Topics: product, audience, market, competitor, visual-identity, typography, color, naming, trend, culture, trademark, platform.
48
48
 
49
49
  ## Design
50
50
 
51
- | Command | Purpose |
52
- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
53
- | `concept new --brand s --id ID --title T --direction D --rationale R --semantics a,b --primary '#hex' [--secondary --accent --ink --paper] [--font id --weight n]` | Create `concepts/ID/`; then write `symbol.svg` there. |
54
- | `concept list --brand s` | Concepts with status, files, palette and `gate` (`passed`, `failed`, `not-reviewed`) with the critic average. |
55
- | `concept show --brand s --concept ID` | One concept with its files, palette, typography, critique and `gate`. |
56
- | `wordmarks --brand s --concept ID [--fonts a,b] [--weights 500,700] [--tracking -20,0,20] \| --pick wN` | The name in several faces next to the symbol on `review/wordmarks.png`, measured; `--pick` commits one as `wordmark.svg` with its typography. |
57
- | `sketches --brand s --concept ID` | Build `sketches/*.json` in the concept palette into `sketches/board.png` for the critic's sketch review; says which are `ready` (with `fix` lines). Specs with `members` also get `sketches/family.png`. |
58
- | `construct spec.json -o out.svg [--guides c.png] [--set k=v,…]` | Build a mark from a construction spec (see construction.md). |
59
- | `construct spec.json --brand s --concept ID [--vary [--max 24]] [--set k=v,…] [--member name] [--role small]` | Into the concept: `symbol.svg`, `construction.json`, `review/construction.png`; `--vary` ranks variants in `sketches/variants/`. |
60
- | `wordmark --text T --font id --weight n -o out.svg [--tracking=-10] [--case lower] [--color '#hex'] [--locale tr]` | Outlined wordmark with real kerning. Negative tracking needs `=`. |
61
- | `lockup --symbol a.svg --wordmark b.svg --layout horizontal\|stacked -o out.svg` | Cap-height aligned lockup. |
62
- | `concept update --brand s --concept ID [--wordmark wordmark.svg] [--status shortlisted\|rejected] [--judgment memorability=8:"reason"] [--present yes\|no:"reason"] [--blind distinctiveness=n,memorability=n,brand-fit=n,craft=n,versatility=n] [--reads-as "a; b; c"] [--sketch-pick s3\|none --sketch-notes "…"]` | Update files/status/judgment. Criteria: brand-fit, semantic-relevance, distinctiveness, memorability, simplicity, balance, craft, typography, color, cultural-fit, timelessness, premium-perception, versatility. Prints the `gate` (blind scores when recorded). |
63
- | `color compare #a #b [#c…]` | ΔE00 and WCAG contrast between colors (e.g. an accent vs a well-known brand color). |
64
- | `palette '#primary' [--secondary '#…'] [--accent '#…']` | OKLCH scales, neutrals, semantic colors, WCAG pairs. |
65
- | `fonts` | Bundled OFL fonts (inter, manrope, space-grotesk, sora, dm-sans, outfit, plus-jakarta-sans, fraunces, ibm-plex-serif, jetbrains-mono). |
51
+ | Command | Purpose |
52
+ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
53
+ | `concept new --brand s --id ID --title T --direction D --rationale R --semantics a,b --primary '#hex' [--secondary --accent --ink --paper] [--font id --weight n] [--lead wordmark] [--round n [--directed "<user's words>"]]` | Create `concepts/ID/`. `--round`: the exploration round (at most 3 proposals per round; a round beyond 2 needs the user's direction). Then write `symbol.svg` (the compact icon) and `wordmark.svg`. |
54
+ | `concept list --brand s` | Concepts with status, files, palette and `gate` (`passed`, `failed`, `not-reviewed`) with the critic average. |
55
+ | `concept show --brand s --concept ID` | One concept with its files, palette, typography, critique and `gate`. |
56
+ | `wordmarks --brand s --concept ID [--fonts a,b] [--weights 500,700] [--tracking -20,0,20] \| --pick wN` | The name in several faces next to the symbol on `review/wordmarks.png`, measured; `--pick` commits one as `wordmark.svg` with its typography. |
57
+ | `sketches --brand s --concept ID` | Optional: build `sketches/*.json` construction specs onto `sketches/board.png` and say which are not `ready` (with `fix` lines). Specs with `members` also get `sketches/family.png`. |
58
+ | `construct spec.json -o out.svg [--guides c.png] [--set k=v,…]` | Build a mark from a construction spec (see construction.md). |
59
+ | `construct spec.json --brand s --concept ID [--vary [--max 24]] [--set k=v,…] [--member name] [--role small]` | Into the concept: `symbol.svg`, `construction.json`, `review/construction.png`; `--vary` ranks variants in `sketches/variants/`. |
60
+ | `wordmark --text T --font id --weight n -o out.svg [--tracking=-10] [--case lower] [--color '#hex'] [--locale tr]` | Outlined wordmark with real kerning. Negative tracking needs `=`. |
61
+ | `lockup --symbol a.svg --wordmark b.svg --layout horizontal\|stacked -o out.svg` | Cap-height aligned lockup. |
62
+ | `ideas --brand s [--add "<hook>" --means "<why>" --source …]` | Optional idea log (kept for compatibility; the default workflow does not need it). |
63
+ | `proposals --brand s [--round n \| --concepts a,b,c]` | Render a round for the user's decision: `concepts/<id>/review/proposal.png` per concept (the identity on its paper and reversed, the icon as app tile, avatar, 32 and 16 px, the idea) and `proposals/round-<n>.png` side by side; `missing` lists what a proposal still lacks (word, icon, strengths/weaknesses). |
64
+ | `concept update --brand s --concept ID [--idea "<sentence>" --strengths "a; b" --weaknesses "a; b"] [--wordmark wordmark.svg] [--status shortlisted\|rejected] [--judgment memorability=8:"reason"] [--present yes\|no:"reason"] [--blind distinctiveness=n,memorability=n,brand-fit=n,craft=n,versatility=n] [--reviewer <model>] [--reads-as "a; b; c"] [--sketch-pick s3\|none --sketch-notes "…"] [--look <five scores> --look-present yes\|no:"reason"]` | Update files/status/judgment; `--look` records a fresh critic's second look when the gate says `second-look`. Criteria: brand-fit, semantic-relevance, distinctiveness, memorability, simplicity, balance, craft, typography, color, cultural-fit, timelessness, premium-perception, versatility. Prints the `gate` (blind scores when recorded) with `next` (`present`, `fix` once, `reject`, `second-look`), the `reviewer` and whether the gate was calibrated on it. |
65
+ | `color compare #a #b [#c…]` | ΔE00 and WCAG contrast between colors (e.g. an accent vs a well-known brand color). |
66
+ | `palette '#primary' [--secondary '#…'] [--accent '#…']` | OKLCH scales, neutrals, semantic colors, WCAG pairs. |
67
+ | `fonts` | Bundled OFL fonts (inter, manrope, space-grotesk, sora, dm-sans, outfit, plus-jakarta-sans, fraunces, ibm-plex-serif, jetbrains-mono). |
66
68
 
67
69
  ## Verify
68
70
 
69
- | Command | Purpose |
70
- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
71
- | `verify --brand s --concept ID` | All checks; writes reports + `concepts/ID/review/symbol-sheet.png`. **Read the PNG.** |
72
- | `diversity --brand s` | Pairwise similarity of active concepts. |
73
- | `originality --brand s --concept ID [--names a,b]` | Originality & Similarity Report only. |
74
- | `score file.svg [--role symbol\|wordmark\|lockup]` / `analyze file` / `compare a b` | Standalone measurements. |
75
- | `svg lint file.svg [--master]` | Master-file rules. |
76
- | `name check "Name" --against a,b,c` / `name trademark "Name" --describe "…"` | Name confusion and registry pre-screen plan. |
77
- | `render file.svg -o out.png [--sheet]` | PNG or review contact sheet. |
71
+ | Command | Purpose |
72
+ | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
73
+ | `verify --brand s --concept ID` | All checks; writes reports + `concepts/ID/review/symbol-sheet.png` (and `wordmark-sheet.png`). **Read the PNGs.** |
74
+ | `diversity --brand s` | Pairwise similarity of active concepts. |
75
+ | `originality --brand s --concept ID [--names a,b]` | Originality & Similarity Report only. |
76
+ | `score file.svg [--role symbol\|wordmark\|lockup]` / `analyze file` / `compare a b` | Standalone measurements. |
77
+ | `svg lint file.svg [--master]` | Master-file rules. |
78
+ | `name check "Name" --against a,b,c` / `name trademark "Name" --describe "…"` | Name confusion and registry pre-screen plan. |
79
+ | `render file.svg -o out.png [--sheet]` | PNG or review contact sheet. |
78
80
 
79
81
  ## Deliver
80
82
 
81
- | Command | Purpose |
82
- | ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
83
- | `finalize --brand s --concept ID [--tagline T] [--note "usage rule"]... [--accept-risk] [--user-choice "why"] [--force]` | Freeze masters, build lockups (horizontal/stacked/compact), write `final/brand.json`. Refuses a concept that failed the critic gate unless `--user-choice`. |
84
- | `lock --brand s --primary '#hex' [--symbol f] [--wordmark f] [--lockup f]` | Register an existing identity to preserve byte-for-byte. |
85
- | `deliverables --brand s [--set g,…] [--add g,…] [--remove g,…]` | Which groups this brand needs; suggests from product type and platforms. |
86
- | `export --brand s [--only logos,web,ios,macos,android,windows,social,marketing,tokens,guidelines] [--all] [--clean]` | Chosen groups (deliverables) + `asset-manifest.json`. |
87
- | `gallery [--brand s] [--serve [--port N]]` | `brand/gallery/index.html`; `--serve` serves it on 127.0.0.1 (token, read-only, stops when idle) so "Send to Claude" saves decisions. |
88
- | `feedback [--brand s] [--import file] [--apply]` | Decisions from the gallery: keep/refine/drop, tags, notes, pinned spots, preferred concept, ready-to-act requests; `--apply` sets concept status. |
89
- | `install-assets --brand s --framework auto\|next\|laravel\|flutter\|static [--project <dir>] [--apply] [--force]` | Files where the framework expects them (plan unless `--apply`; replaced files backed up). Without `--framework`: `--group web --into public`. |
90
- | `agent-setup --target codex\|cursor\|generic [--apply]` | Instruction file so another coding agent can run Markilo's workflow with this CLI. |
91
- | `shortcut install\|uninstall\|status [--yes]` | Optional personal `/markilo` skill. |
92
- | `doctor` | Environment check. |
83
+ | Command | Purpose |
84
+ | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
85
+ | `finalize --brand s --concept ID --user-choice "<the user's words>" [--tagline T] [--note "usage rule"]... [--accept-risk] [--force]` | Freeze masters, build lockups (horizontal, stacked, compact) and `brand.json`. Needs the user's choice (a critic's pass alone never finalizes) and an originality verdict of `no-conflicts-found` unless `--accept-risk`. |
86
+ | `lock --brand s --primary '#hex' [--symbol f] [--wordmark f] [--lockup f]` | Register an existing identity to preserve byte-for-byte. |
87
+ | `deliverables --brand s [--set g,…] [--add g,…] [--remove g,…]` | Which groups this brand needs; suggests from product type and platforms. |
88
+ | `export --brand s [--only logos,web,ios,macos,android,windows,social,marketing,tokens,guidelines] [--all] [--clean]` | Chosen groups (deliverables) + `asset-manifest.json`. |
89
+ | `gallery [--brand s] [--serve [--port N]]` | `brand/gallery/index.html`; `--serve` serves it on 127.0.0.1 (token, read-only, stops when idle) so "Send to your agent" saves decisions. |
90
+ | `feedback [--brand s] [--import file] [--apply]` | Decisions from the gallery: select / change / drop, combine, reject a whole round (with a note), tags, notes, pinned spots, the preferred concept, and ready-to-act `requests`. `--apply` marks selected concepts shortlisted and dropped or round-rejected ones rejected. |
91
+ | `cost --brand s [--phase understand\|explore\|refine\|verify\|export (--tokens n \| --usd x) [--minutes m] [--rate r] [--note t]] [--budget usd]` | Cost per creative phase against a budget (default $12). Tokens are estimated at $0.60 per million (measured on Markilo 1.0 runs; a lower bound — the orchestrating session is not counted) unless `--usd` records a measured cost. `status: over` means stop paid work and ask; `warn` at 80 %. |
92
+ | `install-assets --brand s --framework auto\|next\|laravel\|flutter\|static [--project <dir>] [--apply [--expect <planId>]] [--force]` | Files where the framework expects them (plan unless `--apply`; one transaction, replaced files backed up; `--expect` refuses a stale plan). Without `--framework`: `--group web --into public`. `install-assets --undo [--apply]` reverses the last installation. |
93
+ | `agent-setup --target codex\|cursor\|vscode\|generic [--model critic=<id>]... [--apply]` | The workflow for another coding agent, and the researcher, designer and critic as its sub-agents (`.codex/agents`, `.cursor/agents`, `.github/agents`) on the models named with `--model`. Dry run unless `--apply`. |
94
+ | `shortcut install\|uninstall\|status [--yes]` | Optional personal `/markilo` skill. |
95
+ | `doctor` | Environment check. |
93
96
 
94
97
  Error codes: USAGE, NOT_FOUND, EXISTS, UNSAFE_PATH, INVALID_INPUT, INVALID_SVG, NETWORK_DISABLED, NETWORK,
95
98
  ROBOTS_DISALLOWED, LOCKED, NO_WORKSPACE, INTERNAL.
@@ -1,10 +1,10 @@
1
- # Building marks with construction specs
1
+ # Construction specs — an optional drawing tool
2
2
 
3
- Do not hand-type path coordinates for a symbol. Describe how the mark is **built** — primitives, cuts, gaps,
4
- offsets, repeats, real letterforms — in a JSON construction spec, and let `markilo construct` turn it into exact,
5
- filled, optimized SVG. A spec is how a designer thinks ("a 300-unit ring, cut open at 2 o'clock, with a bar
6
- crossing it and a 32-unit gap where they meet"). Every measurement is a named parameter, so one spec gives many
7
- measured variants.
3
+ `markilo construct` turns a JSON description of how a mark is built — primitives, real letterforms, your own paths,
4
+ booleans, gaps, repeats — into exact, filled, optimized SVG. Use it when it helps: to join or cut real letters, to
5
+ outline a stroked skeleton into a custom letter, to keep measurements consistent, or to try measured variants. It is
6
+ not required. Freeform SVG paths written by hand are equally valid (`svg-authoring.md`), and the best work often mixes
7
+ both: a drawn contour, merged with a letter, cleaned up by a boolean.
8
8
 
9
9
  ```
10
10
  markilo construct <spec.json> -o <out.svg> [--guides <construction.png>] # build one
@@ -58,7 +58,7 @@ With `--brand/--concept`, palette roles come from the concept, the result is wri
58
58
  | `ring` | `c`, `r` (outer), `width` |
59
59
  | `arc` | `c`, `r` (centre line), `from`, `to`, `width`, `cap` `butt`/`round`/`square` — a stroked arc as a filled shape |
60
60
  | `sector` | `c`, `r`, `from`, `to`, `inner` (0 = pie slice) |
61
- | `polygon` | `points` |
61
+ | `polygon` | `points`; `smooth: true` draws one curved, filled outline through them (`tension`, and `sharp: [i…]` keeps those points as corners — the tip of a drop, the point of a leaf) |
62
62
  | `regular` | `c`, `r`, `sides`, `rotate` |
63
63
  | `star` | `c`, `r`, `inner`, `points`, `rotate` |
64
64
  | `line` | `points`, `width`, `cap`, `join`, `smooth` (curve through the points), `closed` |
@@ -79,28 +79,20 @@ With `--brand/--concept`, palette roles come from the concept, the result is wri
79
79
  Every shape also takes `round` (fillet all corners with this radius), `grow` (offset), `scale`, `rotate`, `flip`
80
80
  (`x`/`y`), `move` `[dx, dy]` and `origin` (default: the shape's centre). Order: grow, round, scale, flip, rotate, move.
81
81
 
82
- ## Process
83
-
84
- 1. **Write the idea sentence first** (design-principles.md). Then pick the _move_ that makes it ownable (below).
85
- Write it as what the eye catches, then what it means: _"one stem shared by two arches — research and verification
86
- meet in an m"_. The first half must be visible at 32 px; a story without a visible hook ("a safe crossing from work
87
- to payment") is not a sketch yet.
88
- 2. **Sketch wide**: 3–5 specs (`sketches/s1.json …`), each a different move, not a nudge, each with an `"idea"`
89
- sentence in that form. `markilo sketches --brand <slug> --concept <id>` builds them all onto `sketches/board.png` for the
90
- critic's sketch review. Build each with
91
- `construct sN.json -o sN.svg --brand <slug> --concept <id>` (with `-o` the concept's palette is used and nothing
92
- in the concept changes), compare with `markilo render s1.svg s2.svg … --compare --paper <paper> -o
93
- compare.png`, `Read` it. Keep one; say why the others lost.
94
- 3. **Tune by measurement**: put the uncertain measurements (stroke weight, gap, cut angle, overlap) in `vary`, run
95
- `--vary`, `Read` `variants.png`. The score is a guide, not the judge: pick by eye among the top rows. A red
96
- label names the first failing check; `variants.json` has every check's message.
97
- 4. **Commit**: `construct … --brand --concept --set …` → `symbol.svg`, `construction.json`, `construction.png`.
98
- 5. **Verify** (`markilo verify`) and look at the 16 px, dark and one-color rows. Fix in the spec, not the SVG.
99
- 6. For wordmarks, start from `markilo wordmark`; for a custom letter (a cut, a ligature, a terminal that carries
100
- the idea) build that letter as a `glyph` with booleans and compose it with `lockup`, or build the whole word
101
- with `glyph` and `"role": "wordmark"` (its recipe is saved as `construction-wordmark.json`). `construct` prints
102
- each letter's box, baseline, cap and x-height (`glyphs`), so cuts can be aimed at a stem or a bar by expression
103
- rather than by reading path data. Judge wordmarks with `markilo render wordmark.svg -o wm.png --width 1200`.
82
+ ## Using it well
83
+
84
+ - **Custom letters as skeletons.** Draw a letter's centre line as a `path` with `width` (and `cap`/`join`); Béziers
85
+ (`C`) give it a drawn quality. The same `width` across letters gives a consistent stroke; `union` with real glyphs
86
+ where you keep the font's letters. This is the quickest route to lettering no font has.
87
+ - **Real letters, edited.** A `glyph` gives the font's outline; `subtract` a shape to cut a terminal or open a
88
+ counter, `union` a drawn stroke to make a ligature between neighbours. `construct` prints each glyph's box, baseline,
89
+ cap and x-height (`glyphs`), so edits are aimed by expression, not guessed.
90
+ - **Words.** Build the whole word in one spec with `"role": "wordmark"` (the recipe is saved as
91
+ `construction-wordmark.json` and the wordmark keeps its type metrics for lockups).
92
+ - **Variants.** Put an uncertain measurement (stroke, gap, angle) in `params` + `vary` and run `--vary`; choose by eye
93
+ among the top rows of `variants.png`.
94
+ - **Look.** Render (`markilo render out.svg -o out.png --width 1200`) and `Read` it after every change. A spec is only
95
+ as good as the drawing it produces.
104
96
 
105
97
  ## A worked example
106
98
 
@@ -148,9 +140,9 @@ a letter, and a strict independent judge rated it 5.8/10 (the knockout where the
148
140
  One move (overlap), one unit system, one accent on the idea, every gap ≥ 80 units. Its weakness is the idea's
149
141
  first reading — a letter m — which is why most directions should not start from the name's initial.
150
142
 
151
- ## Moves that make a mark ownable
143
+ ## Moves that can make a mark ownable
152
144
 
153
- Each is a construction technique, not a shape to copy. Combine at most two.
145
+ Techniques, not recipes — use one when it serves the idea.
154
146
 
155
147
  - **Letter carries the metaphor**: a `glyph` whose counter, terminal or stem becomes the object — `subtract` the
156
148
  metaphor from the letter, or `union` a part of it in. Only when the object is the first reading; an initial with a
@@ -162,6 +154,10 @@ Each is a construction technique, not a shape to copy. Combine at most two.
162
154
  - **Cut and shift**: `subtract` a thin band (`rect` rotated) through a solid, then `move` one side — motion,
163
155
  precision, a "slice" of something.
164
156
  - **Truncation**: `intersect` a form with a frame so it is cropped by the edge — tension, scale beyond the frame.
157
+ - **One silhouette**: the object as a single filled outline — a `polygon` with `smooth: true` through 6–12 points,
158
+ sharp only where the object has a point — instead of a stack of circles, bars and triangles. An object assembled
159
+ from separate primitives reads as a pictogram (a plumb bob built from a ring, a bar, a trapezoid and a triangle read
160
+ as a download arrow); one drawn outline with a particular proportion reads as a drawing.
165
161
  - **Single gesture**: one `line` with `smooth: true`, consistent `width`, round caps, that draws the idea in one
166
162
  movement. Avoid the generic swoosh; the path must describe something specific.
167
163
  - **Modular system**: one unit (`defs`) repeated with `repeat` along a grid, where the arrangement itself is the
@@ -188,10 +184,22 @@ product with `construct <spec> --brand <product> --concept <id> --member <name>`
188
184
 
189
185
  ## Wordmarks
190
186
 
191
- Carry the symbol's idea into the wordmark **once**: one or two letters that share the symbol's move (a cut, a corner,
192
- a terminal), on top of a calm, well-spaced typeface. Rebuilding every letter from the idea makes the word busy and
193
- harder to read, and it reads as a display face rather than a brand. Every letter must still be readable on its own:
194
- check `e`, `a`, `w`, `m` and other complex forms at 1200 px and at 64 px wide.
187
+ See "Wordmark first" in `design-principles.md` for what to aim for. With construct:
188
+
189
+ 1. Compare faces quickly: `markilo wordmarks --brand <slug> --concept <id> --fonts a,b,c --weights 500,700
190
+ [--tracking -20,0,20]` (`review/wordmarks.png`).
191
+ 2. Build the word in one spec with `glyph` and `"role": "wordmark"`, then apply the treatment across it: a ligature
192
+ from a `union` of two neighbours and a drawn stroke, terminals cut at one angle by a repeated `subtract`, `round` to
193
+ soften every corner, `grow` for weight, custom letters drawn as skeleton paths. Aim by the printed `glyphs` boxes.
194
+ 3. Derive the icon from the same drawing: the same spec keeping only some letters (`"letters": [i]`), fitted to the
195
+ square, with `construct … --role symbol`; then redraw it until it stands on its own.
196
+ 4. `markilo verify` writes `review/wordmark-sheet.png` (12–64 px on light, dark, black and white): the word must stay
197
+ readable at 12 px.
198
+
199
+ `construct` and `sketches` measure every changed letter against the font's own alphabet: a letter that now looks more
200
+ like another letter ("o" cut open on the right reads as "c") is flagged; a letter that lost its counter or two letters
201
+ merged into one shape is a note to weigh. A separate element dropped into a word reads as punctuation — a hyphen
202
+ between letters, an accent over one, a full stop after the word — so attach it to a letter or put it inside a counter.
195
203
 
196
204
  ## Craft checklist
197
205
 
@@ -213,9 +221,8 @@ check `e`, `a`, `w`, `m` and other complex forms at 1200 px and at 64 px wide.
213
221
  - Before you commit, describe the mark in one sentence without naming a shape ("a ring and a bar" is a shape; "a
214
222
  door left ajar" is an idea). If you can only name shapes, go back to step 1.
215
223
 
216
- ## Patterns the critic scores low
224
+ ## Patterns that read as generic
217
225
 
218
- Circle + bar, plain rings, a single letter in a stock font in a rounded square, generic arrows/checkmarks/sparkles,
219
- radial petals, interlocking circles, gradient blobs, swooshes, abstract "network" dots, and shapes that are already
220
- UI icons (paperclip/hairpin = attachment, power symbol, refresh arrows, padlock, cloud). Clean execution does not
221
- rescue a generic idea.
226
+ Circle + bar, plain rings, a single letter in a stock font in a rounded square, generic arrows, check marks and
227
+ sparkles, radial petals, interlocking circles, gradient blobs, swooshes, "network" dots, and shapes that are already UI
228
+ icons (paperclip, power symbol, refresh arrows, padlock, cloud). Clean execution does not rescue a generic idea.