nimiq-branding-cli 1.0.1 → 1.1.0

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.
package/PRINCIPLES.md ADDED
@@ -0,0 +1,153 @@
1
+ # The Nimiq Design Principles
2
+
3
+ **This is the soul of this tool.** Every component in the registry — and every NEW thing
4
+ generated with it — must come from these principles, not just resemble their output.
5
+
6
+ Sources: the **NIMIQ Style Guide (October 2018)**, the
7
+ [A New Visual Identity](https://www.nimiq.com/blog/a-new-visual-identity/) blog post,
8
+ [nimiq-style](https://nimiq.github.io/nimiq-style/), and the
9
+ [Nimiq Design Kit](https://nimiq.dev/design-kit).
10
+
11
+ ---
12
+
13
+ ## Why — the identity
14
+
15
+ > *Nimiq is an Inuit word for an object or force that binds things together.*
16
+
17
+ Nimiq sees itself as **the lowest common denominator at the intersection of payment
18
+ technology and accessible interaction with a blockchain** — and aims for **radical
19
+ simplicity in both technology and design**.
20
+
21
+ The brand persona, derived from team and community (not theory):
22
+
23
+ **Helping & caring · Trustworthy & transparent · Conscientious & driven**
24
+
25
+ …which translates into four visual pillars:
26
+
27
+ 1. **A base that follows common patterns.**
28
+ 2. **Traditional and basic colors with a subtle spin.**
29
+ 3. **Warm and round, but straight visual and form language.**
30
+ 4. **Subtle complexity and calculated breaks in a clear structure.**
31
+
32
+ ---
33
+
34
+ ## The prime directive — radical simplicity
35
+
36
+ > *"Stripping away everything that's not necessary will lead to less cognitive load and
37
+ > eventually to a better experience."*
38
+
39
+ The logo is the proof: every clever N-in-a-hexagon draft was discarded for the **bare
40
+ hexagon** — because two shapes, one inside the other, was already too complex. What
41
+ remained is *"a clean slate, ready for the community to fill."*
42
+
43
+ And the ecosystem framing that defines this CLI's job:
44
+
45
+ > *"We don't want to dictate the way the Nimiq ecosystem looks or feels, but rather
46
+ > provide a boilerplate of our vision, stripped down to the very core, so that there's
47
+ > enough room for others to fill it out with their own ideas."*
48
+
49
+ This tool **is** that boilerplate, made executable.
50
+
51
+ ---
52
+
53
+ ## The laws
54
+
55
+ ### 1. Color — three rules, in order
56
+ 1. **Traditional, basic colors with a subtle, unexpected spin.** The ultramarine
57
+ dark-blue (`#1F2348`) carries a touch of violet spreading from the corner; the
58
+ classic red tilts slightly toward magenta. Colors relate to *payments*, not to
59
+ crypto fashion.
60
+ 2. **Build on a light stage.** Start from a clean slate (white / `#F8F8F8`); create
61
+ structure with very light, nuanced grays derived from the main colors — this
62
+ underlines the transparent, open, collaborative approach and leaves room for
63
+ others' ideas.
64
+ 3. **Color is for accentuated highlights only** — to set focus, and as a *reaction to
65
+ interaction*. Never decorative. (Green = success only. Red = error only.
66
+ Orange = warning. Blue = action/info.)
67
+
68
+ ### 2. The gradient is the spin
69
+ A **subtle radial gradient is THE key feature** of the visual identity. Apply it to
70
+ every element that qualifies as a color area — buttons, boxes, backgrounds — anchored
71
+ in the **bottom-right corner** (e.g. `radial-gradient(100% 100% at bottom right,
72
+ #260133, #1F2348)`). This is how "traditional colors" get their spin. On logo
73
+ substrates: white base with a faint color-aligned tint sweeping from the top-right edge.
74
+
75
+ ### 3. Form — warm and round, but straight and tangible
76
+ Interfaces are **warm and round, but straight and tangible at the same time** (pill
77
+ buttons and 8px-radius cards, yet crisp edges and exact alignment). **Every element
78
+ has a clear anchor and a relation to the whole.** Pare down the number of visual
79
+ elements until **everything remaining is necessary for the layout to function**.
80
+
81
+ ### 4. White space does the structural work
82
+ Achieve hierarchy, separation and cohesion with **white space instead of structural
83
+ elements** like separators or boxes. *"We avoid all forms of decorative elements if we
84
+ can't defend them on a content level."* When in doubt: more breathing room, fewer lines.
85
+
86
+ ### 5. Typography — simple, unique, open
87
+ **Muli/Mulish**: a classic sans-serif molded by radical geometric simplicity, with
88
+ unique details that never compromise that simplicity — chosen over Roboto/Open Sans
89
+ because Nimiq could *own* it, and because it's open source (community must be able to
90
+ reproduce everything). **Fira Mono** for technical content — addresses, keys, numbers —
91
+ optimized for readability, light-footed in non-code environments.
92
+
93
+ ### 6. Calculated breaks — the element of surprise
94
+ Radical simplicity is not sterility:
95
+
96
+ > *"For this reason we embrace subtle complexity — an element of surprise,
97
+ > well-defined breaks in a clear structure — something that makes the experience
98
+ > memorable."*
99
+
100
+ One surprise per experience: the gradient's diagonal, an identicon's character, the
101
+ honeycomb peeking through. **"Driven" translates into adding that bit of sophistication
102
+ and friction that makes the difference between convenience and fascination.** Friction
103
+ belongs only where it protects something critical (a passphrase, money).
104
+
105
+ ### 7. Familiar in the basics, honest in the details
106
+ > *"We use common, learned patterns for critical interactions with Nimiq wherever
107
+ > possible. We're familiar in the basics, but surprising in the details. Nevertheless,
108
+ > if in doubt, everything we do follows intuitive patterns. If we don't follow best
109
+ > practices, we follow logic, nature or human behavior."*
110
+
111
+ ### 8. Reproducibility is a brand value
112
+ > *"We want to encourage the community to use our visual language as a foundation for
113
+ > their own projects. … everything we create visually needs to be easily accessible and
114
+ > reproducible, being able to act as a boilerplate by virtue of its simplicity."*
115
+
116
+ This is why this CLI pixel-verifies every component against the real upstream and ships
117
+ the team's real assets instead of hand-made approximations. Reproduction *is* the brand
118
+ working as designed.
119
+
120
+ ### 9. The logo is sacred ground
121
+ The hexagon signet is **universal** — anyone in the ecosystem may use it and build their
122
+ own mark on top of it. The **signet + wordmark combination is reserved** and must not be
123
+ altered. Clear space: the width of the letter N (horizontal) / half a hexagon (signet).
124
+ Monochrome versions for busy or colored backgrounds. Never reconstruct the geometry —
125
+ use the shipped files (`nq assets search logo`).
126
+
127
+ ---
128
+
129
+ ## The generation checklist
130
+
131
+ Before any NEW component or design ships, it must answer **yes** to all of these:
132
+
133
+ - [ ] Could anything be removed without the layout failing? (If yes → remove it.)
134
+ - [ ] Does it sit on a light stage, structured by white space rather than boxes/lines?
135
+ - [ ] Is every color either a main color with the radial-gradient spin, a light nuanced
136
+ gray derived from main colors, or a semantic highlight reacting to focus/interaction?
137
+ - [ ] Are color areas gradient-built (bottom-right radial), not flat fills?
138
+ - [ ] Is it warm and round (pills, soft radii) yet straight and tangible (crisp anchors,
139
+ exact alignment, clear relation to the whole)?
140
+ - [ ] Is the typography Muli/Mulish (UI) and Fira Mono (technical values) only?
141
+ - [ ] Is there at most ONE calculated break / element of surprise, and can it be
142
+ defended on a content level?
143
+ - [ ] Are the basics a common, learned pattern? (Surprise lives in details, never in
144
+ critical interactions.)
145
+ - [ ] Does it use the team's real assets (`nq assets`) — never redrawn logos, icons or art?
146
+ - [ ] Is it reproducible — plain HTML/CSS or standard Vue, no exotic dependencies,
147
+ verifiable by `nq verify`?
148
+
149
+ ---
150
+
151
+ *Run `nq principles` to print this document. `nq new <name>` scaffolds a component with
152
+ this checklist embedded — a component is not done until the checklist and the pixel
153
+ verification both pass.*
package/README.md CHANGED
@@ -8,6 +8,16 @@ Nimiq apps before it ships, plus the team's real asset library (logos, icons, fl
8
8
  > real shipped files or faithful ports of their open-source components, never hand-drawn
9
9
  > approximations.
10
10
 
11
+ ## The soul of the tool
12
+
13
+ Everything here flows from the **[Nimiq Design Principles](PRINCIPLES.md)** — distilled from
14
+ the NIMIQ Style Guide (October 2018) and the
15
+ [A New Visual Identity](https://www.nimiq.com/blog/a-new-visual-identity/) essay: radical
16
+ simplicity, a light stage structured by white space, traditional colors with the radial-gradient
17
+ spin, warm-and-round-yet-tangible form, and one calculated break per experience. `nq principles`
18
+ prints them; `nq new <name>` scaffolds a component with the 10-point principles checklist
19
+ embedded — a component isn't done until the checklist and the pixel verification both pass.
20
+
11
21
  ## Install
12
22
 
13
23
  ```bash
package/bin/nq.js CHANGED
@@ -24,6 +24,9 @@ Usage:
24
24
  nq assets search <term> Search assets incl. the 323 nimiq-icons + 422 hexagon flags
25
25
  nq assets add <name...> Copy official asset(s) into ./nimiq/assets/
26
26
  (icon:<name> extracts from nimiq-icons, flag:<cc> from nimiq-flags)
27
+ nq principles Print the Nimiq design principles — the soul of this tool
28
+ nq new <name> Scaffold a new registry component with the principles
29
+ checklist + verification contract embedded
27
30
  nq verify <component|all> Render the html variant and diff against the reference PNG
28
31
  nq help This message
29
32
 
@@ -239,6 +242,88 @@ async function cmdTokens() {
239
242
  console.log(await readFile(join(ROOT, 'assets', 'tokens.md'), 'utf8'));
240
243
  }
241
244
 
245
+ async function cmdPrinciples() {
246
+ console.log(await readFile(join(ROOT, 'PRINCIPLES.md'), 'utf8'));
247
+ }
248
+
249
+ const CHECKLIST = [
250
+ 'remove-everything-unnecessary: could anything be removed without the layout failing?',
251
+ 'light-stage: white/#F8F8F8 base, structure via white space + nuanced grays, not boxes/lines',
252
+ 'color-rules: main colors w/ gradient spin | light grays | semantic highlights on interaction only',
253
+ 'gradients: color areas use the bottom-right radial gradient, never flat fills',
254
+ 'form: warm and round yet straight and tangible; every element anchored, related to the whole',
255
+ 'type: Mulish for UI, Fira Mono for technical values, nothing else',
256
+ 'one-break: at most ONE calculated surprise, defensible on a content level',
257
+ 'learned-patterns: basics follow common patterns; surprise lives in details only',
258
+ 'real-assets: team-shipped files via nq assets — no redrawn logos/icons/art',
259
+ 'reproducible: plain HTML/CSS or standard Vue, passes nq verify',
260
+ ];
261
+
262
+ async function cmdNew(name, flags) {
263
+ if (!name || !/^[a-z][a-z0-9-]*$/.test(name)) throw new Error('nq new <kebab-case-name>');
264
+ const dir = join(ROOT, 'registry', 'components', name);
265
+ if (existsSync(dir)) throw new Error(`component "${name}" already exists`);
266
+ const pascal = name.split('-').map(w => w[0].toUpperCase() + w.slice(1)).join('');
267
+ await mkdir(join(dir, 'html'), { recursive: true });
268
+ await mkdir(join(dir, 'truth'), { recursive: true });
269
+ await mkdir(join(dir, 'vue'), { recursive: true });
270
+
271
+ const meta = {
272
+ name,
273
+ purpose: 'TODO: one sentence — what it is and where Nimiq uses it',
274
+ category: 'misc',
275
+ variants: ['vue', 'html'],
276
+ props: [],
277
+ cssFiles: ['css/legacy/nimiq-style.min.css'],
278
+ assetFiles: [],
279
+ dependsOn: [],
280
+ npmDeps: [],
281
+ verified: false,
282
+ verify: { viewport: { width: 600, height: 400 }, selector: `.${name}`, maxDiffPct: 0.5, settleMs: 250 },
283
+ principles: Object.fromEntries(CHECKLIST.map(c => [c.split(':')[0], false])),
284
+ notes: 'Scaffolded by nq new. Cite the source (upstream file, real asset, or screenshot reference) here. A component is DONE when every principles flag is true AND nq verify passes.',
285
+ };
286
+ await writeFile(join(dir, 'meta.json'), JSON.stringify(meta, null, 2) + '\n');
287
+
288
+ const pageChrome = (title, cssHref) => `<!DOCTYPE html>
289
+ <html lang="en">
290
+ <head>
291
+ <meta charset="utf-8">
292
+ <title>${title}</title>
293
+ <link rel="preconnect" href="https://fonts.googleapis.com">
294
+ <link href="https://fonts.googleapis.com/css2?family=Mulish:wght@400;600;700;800&display=swap" rel="stylesheet">
295
+ <link rel="stylesheet" href="../../../../assets/css/legacy/nimiq-style.min.css">
296
+ <link rel="stylesheet" href="${cssHref}">
297
+ <style>
298
+ html, body { margin: 0; padding: 0; background: #fff; }
299
+ body { font-family: 'Mulish', 'Muli', system-ui, sans-serif; }
300
+ </style>
301
+ </head>
302
+ <body>
303
+ <div class="${name}">
304
+ <!-- TODO: same markup as html/${name}.html — keep truth/demo/snippet identical -->
305
+ </div>
306
+ </body>
307
+ </html>
308
+ `;
309
+ await writeFile(join(dir, 'truth', 'truth.html'), pageChrome(`${name} — truth (cite your source!)`, `../html/${name}.css`));
310
+ await writeFile(join(dir, 'html', 'demo.html'), pageChrome(name, `${name}.css`));
311
+ await writeFile(join(dir, 'html', `${name}.html`), `<!-- ${name} — TODO describe. Requires ${name}.css + nimiq-style.min.css.\n Source: TODO (upstream file / real asset / reference screenshot). -->\n<div class="${name}">\n <!-- TODO -->\n</div>\n`);
312
+ await writeFile(join(dir, 'html', `${name}.css`), `/* ${name} — all selectors namespaced under .${name}.\n Principles: light stage, white-space structure, bottom-right radial gradients,\n Mulish/Fira Mono, one calculated break max. Run: nq principles */\n.${name} {\n font-family: 'Mulish', sans-serif;\n}\n`);
313
+ await writeFile(join(dir, 'vue', `${pascal}.vue`), `<script setup lang="ts">\n// ${pascal} — port faithfully; inline small helpers; record npm deps in meta.json\n</script>\n\n<template>\n <div class="${name}">\n <!-- TODO -->\n </div>\n</template>\n\n<style scoped>\n.${name} {\n font-family: 'Mulish', sans-serif;\n}\n</style>\n`);
314
+
315
+ console.log(`+ registry/components/${name}/ scaffolded\n`);
316
+ console.log('The principles gate (all must become true in meta.json):');
317
+ for (const c of CHECKLIST) console.log(' [ ] ' + c);
318
+ console.log(`\nWorkflow:
319
+ 1. Build truth/truth.html from a REAL source (upstream code, real asset, or live screenshot) — cite it in meta.notes.
320
+ 2. node scripts/snap.mjs ${name} (truth -> reference.png; eyeball it)
321
+ 3. Build html/${name}.html + demo.html + vue/${pascal}.vue with identical markup.
322
+ 4. node scripts/verify.mjs ${name} (must pass at <= 0.5% diff)
323
+ 5. Flip the principles flags + verified:true, then: node scripts/build-index.mjs
324
+ Read the soul of the tool first: nq principles`);
325
+ }
326
+
242
327
  async function cmdVerify(target) {
243
328
  const { verify } = await import(join(ROOT, 'scripts', 'verify.mjs'));
244
329
  const names = target === 'all' || !target
@@ -264,6 +349,8 @@ try {
264
349
  case 'add': await cmdAdd(rest, flags); break;
265
350
  case 'init': await cmdInit(flags); break;
266
351
  case 'tokens': await cmdTokens(); break;
352
+ case 'principles': await cmdPrinciples(); break;
353
+ case 'new': await cmdNew(rest[0], flags); break;
267
354
  case 'assets': await cmdAssets(rest[0], rest.slice(1), flags); break;
268
355
  case 'verify': await cmdVerify(rest[0]); break;
269
356
  default: console.log(HELP);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nimiq-branding-cli",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "nq \u2014 pixel-verified Nimiq UI component registry + CLI. 39 components (Vue 3 + plain HTML) diffed against the real Nimiq apps, plus the team's real asset library. Unofficial community tool.",
5
5
  "type": "module",
6
6
  "bin": {