jig-ui 0.7.1 → 0.8.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/CHANGELOG.md +762 -0
- package/README.md +107 -23
- package/dist/index.js +298 -14
- package/package.json +3 -2
- package/rules/00-anti-patterns.md +24 -14
- package/rules/02-tokens.md +78 -3
- package/rules.index.json +12 -9
- package/templates/SKILL.md.tmpl +24 -1
|
@@ -24,6 +24,7 @@ These are the strongest defaults in a model's training data and the fastest way
|
|
|
24
24
|
### A-01 Purple and violet as the unspecified default
|
|
25
25
|
❌ A violet or indigo fill, or a violet→pink gradient, chosen because no colour was specified
|
|
26
26
|
✅ Use `--color-brand` from the brand file. The unbranded default resolves it to near-black, which ships a coherent monochrome UI and makes the missing decision visible. Then ask.
|
|
27
|
+
**Being asked to propose a colour does not discharge this.** A proposal is a question with a suggested answer, not a decision — so suggest one freely when asked, but ship the unbranded default alongside it and leave the brand file unchanged until a human confirms. Two agents given the same brief split on exactly this point, one deferring and one treating its own proposal as the answer, and both cited the same conflict-resolution clause to get there. The task can ask you for a recommendation; it cannot make you the one who decided.
|
|
27
28
|
|
|
28
29
|
### A-02 Gradient text on headings
|
|
29
30
|
❌ `background-clip: text` with a gradient fill and transparent text colour
|
|
@@ -90,6 +91,7 @@ In `operator`, `--radius-surface` also selects `sm`, so cards, buttons and input
|
|
|
90
91
|
### B-11 Unbounded line length
|
|
91
92
|
❌ Paragraphs spanning the full width of a wide viewport
|
|
92
93
|
✅ Cap at `--measure-prose` (68ch editorial, 60ch product, 72ch operator). Applies to any run of prose in any mode.
|
|
94
|
+
**And do not let a layout choice push it far under.** The readable band is 40–80 characters (`02-tokens.md`); the cap is the only half stated here, so a column can be halved indefinitely and still satisfy this rule while reading worse at every step. A narrow viewport that cannot reach 40 is a constraint and fine. Splitting a capped column into two side-by-side panels, and rendering prose at 41 characters in a mode whose own measure selects 68, is a choice — and it is choosing density over legibility, which is the trade `M-01` says editorial does not make.
|
|
93
95
|
|
|
94
96
|
### B-12 Centred or justified body text
|
|
95
97
|
❌ A centred paragraph of four lines. Justified text of any length.
|
|
@@ -503,7 +505,28 @@ Load `05-copy.md` whenever writing or reviewing a user-facing string.
|
|
|
503
505
|
|
|
504
506
|
Run this against what you produced. Any "no" is a defect to fix, not a note to mention.
|
|
505
507
|
|
|
506
|
-
1.
|
|
508
|
+
1. **The generic-AI tells, named rather than gestured at.** This used to read
|
|
509
|
+
"would this look different from a generic template if the accent colour were
|
|
510
|
+
removed?", which an agent that has just produced a generic template answers
|
|
511
|
+
yes to — and its `A-01 → A-10` range silently excluded `A-58`, `A-59`, `A-60`
|
|
512
|
+
and `A-67`. Check each:
|
|
513
|
+
- Was the accent colour **chosen**, or did it appear because none was
|
|
514
|
+
specified? (`A-01`)
|
|
515
|
+
- Any gradient text, decorative blobs, glassmorphism or neumorphism?
|
|
516
|
+
(`A-02`, `A-03`, `A-04`)
|
|
517
|
+
- Emoji standing in for icons — including ones marked `aria-hidden`?
|
|
518
|
+
(`A-05`)
|
|
519
|
+
- Three things in a three-column icon-and-heading grid because there were
|
|
520
|
+
three of them? (`A-06`)
|
|
521
|
+
- One radius on every element regardless of its size; shadow doing all the
|
|
522
|
+
depth work? (`A-07`, `A-08`)
|
|
523
|
+
- Marketing voice in an application, or placeholder content still in place?
|
|
524
|
+
(`A-09`, `A-10`)
|
|
525
|
+
- Decoration that mimics a functional signal — colour picked for variety, an
|
|
526
|
+
icon that looks pressable and is not? (`A-58`)
|
|
527
|
+
- Every list item restating the context they share? (`A-59`)
|
|
528
|
+
- Icons at equal weight competing with the text they support? (`A-60`)
|
|
529
|
+
- A border, card or panel around every group on the page? (`A-67`)
|
|
507
530
|
2. Is every run of prose measure-capped and left-aligned? (B-11, B-12)
|
|
508
531
|
3. Does any text or placeholder fall below 4.5:1? (C-19)
|
|
509
532
|
4. Is every spacing value a `--spacing-*` token, and does `--spacing-heading-before` exceed `--spacing-heading-after`? (D-23, D-24)
|
|
@@ -523,16 +546,3 @@ Run this against what you produced. Any "no" is a defect to fix, not a note to m
|
|
|
523
546
|
9. Does the primary action still work with JavaScript disabled? (F-41)
|
|
524
547
|
10. Is there a `prefers-reduced-motion` path? (G-43)
|
|
525
548
|
11. Did you reuse existing components and tokens rather than adding new ones? (H-45, H-47)
|
|
526
|
-
|
|
527
|
-
---
|
|
528
|
-
|
|
529
|
-
## Notes for the author (not for the agent)
|
|
530
|
-
|
|
531
|
-
Rules carrying a deliberate house position rather than a general best practice — these are where your taste is recorded, and they should be defended or changed consciously:
|
|
532
|
-
|
|
533
|
-
- **C-18** — off-white over pure white. Already evidenced in your site's `#fafaf7`, now the anchor of the default neutral ramp.
|
|
534
|
-
- **A-07, A-08** — bordered, low-radius, low-shadow surfaces. This is a stance, not a consensus.
|
|
535
|
-
- **F-41, G-42** — resilience and restraint weighted above visual richness. Connects directly to your writing on JS-dependent form fields.
|
|
536
|
-
- **D-24** — heading space asymmetry. Universal advice, but stating a ratio makes it enforceable.
|
|
537
|
-
|
|
538
|
-
Candidates deferred to mode profiles because they are not universal: information density, table row height, use of colour fills for status, page-section rhythm, hero presence, illustration and imagery policy, animation budget.
|
package/rules/02-tokens.md
CHANGED
|
@@ -390,14 +390,89 @@ In dark, elevated surfaces get **lighter**, not shadowed. Border-led elevation s
|
|
|
390
390
|
}
|
|
391
391
|
```
|
|
392
392
|
|
|
393
|
-
**Tailwind v4** —
|
|
393
|
+
**Tailwind v4** — the barrel is imported flat, exactly as anywhere else
|
|
394
|
+
|
|
395
|
+
```css
|
|
396
|
+
@import "tailwindcss";
|
|
397
|
+
@import "./jig/theme.css";
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
That is all that is required, and it is what `init` writes. Every token is
|
|
401
|
+
readable as `var(--color-text-strong)` in any stylesheet or component.
|
|
402
|
+
|
|
403
|
+
**Do not nest the import inside `@theme`.** Earlier versions of this file told
|
|
404
|
+
you to, and Tailwind rejects it outright:
|
|
405
|
+
|
|
406
|
+
```
|
|
407
|
+
@theme blocks must only contain custom properties or @keyframes.
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
`@theme` takes declarations, not an `@import`, and Jig's tokens cannot move into
|
|
411
|
+
one regardless: `@theme` requires them top-level and unnested, while Jig's live
|
|
412
|
+
in `:root` and are redeclared under `[data-theme="dark"]` and a
|
|
413
|
+
`prefers-color-scheme` query. That structure is what makes dark mode work.
|
|
414
|
+
|
|
415
|
+
### Optional: Tailwind utility classes
|
|
416
|
+
|
|
417
|
+
The flat import gives you the tokens. It does **not** give you `p-card` or
|
|
418
|
+
`rounded-surface` as classes — Tailwind only generates utilities for names
|
|
419
|
+
declared in `@theme`. If you want them, add one alias block:
|
|
420
|
+
|
|
421
|
+
```css
|
|
422
|
+
/* jig/utilities.css — one per project, not one per mode */
|
|
423
|
+
@theme inline {
|
|
424
|
+
--color-text-strong: var(--color-text-strong);
|
|
425
|
+
--color-bg-base: var(--color-bg-base);
|
|
426
|
+
--spacing-card: var(--spacing-card);
|
|
427
|
+
--radius-surface: var(--radius-surface);
|
|
428
|
+
/* …every token you want as a utility */
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
394
432
|
```css
|
|
433
|
+
/* your root stylesheet */
|
|
395
434
|
@import "tailwindcss";
|
|
435
|
+
@import "./jig/utilities.css";
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Then `<article class="bg-bg-base p-card rounded-surface">` works, and the value
|
|
439
|
+
still comes from whichever mode barrel that route loaded — so one set of
|
|
440
|
+
utilities serves every mode, with no `dark:` variants and nothing per-mode.
|
|
441
|
+
|
|
442
|
+
**`@theme` and `@theme inline` behave identically here.** Both generate the
|
|
443
|
+
utilities; both also emit a self-referential declaration you will see in the
|
|
444
|
+
compiled CSS:
|
|
445
|
+
|
|
446
|
+
```css
|
|
447
|
+
@layer theme { :root, :host { --radius-surface: var(--radius-surface) } } /* Tailwind's */
|
|
448
|
+
:root { --radius-surface: var(--radius-md) } /* Jig's */
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**This is not a bug and must not be "fixed".** Tailwind's copy is inside
|
|
452
|
+
`@layer theme`; Jig's is unlayered. Unlayered declarations beat layered ones in
|
|
453
|
+
the cascade regardless of source order, so Jig's value always wins. Removing
|
|
454
|
+
either one breaks something: drop the alias and the utility stops existing, drop
|
|
455
|
+
Jig's and the token has no value.
|
|
456
|
+
|
|
457
|
+
**The alternative, if the duplicate bothers you:** alias to *different* names,
|
|
458
|
+
the way a project with its own semantic layer would.
|
|
459
|
+
|
|
460
|
+
```css
|
|
396
461
|
@theme {
|
|
397
|
-
|
|
462
|
+
--color-ink: var(--color-text-strong);
|
|
463
|
+
--color-paper: var(--color-bg-base);
|
|
398
464
|
}
|
|
399
465
|
```
|
|
400
|
-
|
|
466
|
+
|
|
467
|
+
Utilities become `text-ink`, `bg-paper`. No self-reference, no duplicate
|
|
468
|
+
declaration, and the names read as yours rather than as Jig's. The cost is a
|
|
469
|
+
mapping to maintain. Both arrangements are correct; this is a naming preference,
|
|
470
|
+
not a correctness one.
|
|
471
|
+
|
|
472
|
+
**A missing alias fails silently.** A class whose token is not in the block
|
|
473
|
+
renders onto the element and matches no rule — no error, no warning, no style.
|
|
474
|
+
Generate the block rather than hand-maintaining it, and regenerate it when the
|
|
475
|
+
token layer changes.
|
|
401
476
|
|
|
402
477
|
**In a monorepo, add `@source` for every workspace package that uses these
|
|
403
478
|
utilities.** Tailwind v4's content detection does not cross package boundaries:
|
package/rules.index.json
CHANGED
|
@@ -84,9 +84,10 @@
|
|
|
84
84
|
},
|
|
85
85
|
{
|
|
86
86
|
"id": "A-05",
|
|
87
|
-
"bucket": "
|
|
88
|
-
"severity": "
|
|
89
|
-
"since": "0.1.0"
|
|
87
|
+
"bucket": "mechanical",
|
|
88
|
+
"severity": "warning",
|
|
89
|
+
"since": "0.1.0",
|
|
90
|
+
"detector": "emoji-icon"
|
|
90
91
|
},
|
|
91
92
|
{
|
|
92
93
|
"id": "A-06",
|
|
@@ -108,15 +109,17 @@
|
|
|
108
109
|
},
|
|
109
110
|
{
|
|
110
111
|
"id": "A-09",
|
|
111
|
-
"bucket": "
|
|
112
|
-
"severity": "
|
|
113
|
-
"since": "0.1.0"
|
|
112
|
+
"bucket": "mechanical",
|
|
113
|
+
"severity": "warning",
|
|
114
|
+
"since": "0.1.0",
|
|
115
|
+
"detector": "marketing-voice"
|
|
114
116
|
},
|
|
115
117
|
{
|
|
116
118
|
"id": "A-10",
|
|
117
|
-
"bucket": "
|
|
118
|
-
"severity": "
|
|
119
|
-
"since": "0.1.0"
|
|
119
|
+
"bucket": "mechanical",
|
|
120
|
+
"severity": "warning",
|
|
121
|
+
"since": "0.1.0",
|
|
122
|
+
"detector": "placeholder-content"
|
|
120
123
|
},
|
|
121
124
|
{
|
|
122
125
|
"id": "B-11",
|
package/templates/SKILL.md.tmpl
CHANGED
|
@@ -23,6 +23,29 @@ cite the number when you follow or deliberately break one.
|
|
|
23
23
|
|
|
24
24
|
Load `{{rules_path}}/04-principles.md` only when two rules conflict.
|
|
25
25
|
|
|
26
|
+
## If the project uses Tailwind v4
|
|
27
|
+
|
|
28
|
+
Jig needs nothing from Tailwind and Tailwind needs nothing from Jig: the flat
|
|
29
|
+
`@import` of the token barrel is enough, and every token is readable as
|
|
30
|
+
`var(--color-text-strong)` from any component. Build that way unless the user
|
|
31
|
+
tells you otherwise.
|
|
32
|
+
|
|
33
|
+
Tailwind can additionally generate utility classes (`p-card`, `rounded-surface`)
|
|
34
|
+
from Jig's tokens, but only if the project declares an alias block. **That is
|
|
35
|
+
the user's decision, not yours.** It changes how every component in the codebase
|
|
36
|
+
is written, and both arrangements are correct — so when you find Tailwind v4 in
|
|
37
|
+
a project without one:
|
|
38
|
+
|
|
39
|
+
1. Say you found it, and that the token layer works today without any change.
|
|
40
|
+
2. Show them the two arrangements from "Optional: Tailwind utility classes" in
|
|
41
|
+
`{{rules_path}}/02-tokens.md` — self-referential aliases keeping Jig's names,
|
|
42
|
+
or aliases to names of their own.
|
|
43
|
+
3. Ask which they want, and **wait**. Do not pick one and proceed.
|
|
44
|
+
|
|
45
|
+
Never write `@import "tailwindcss"` into a project that does not already have
|
|
46
|
+
it. Jig is framework-agnostic by design, and a token layer that drags in a CSS
|
|
47
|
+
framework has stopped being one.
|
|
48
|
+
|
|
26
49
|
## Commands
|
|
27
50
|
|
|
28
51
|
{{available_commands}}
|
|
@@ -55,7 +78,7 @@ changed since, do not re-run it.
|
|
|
55
78
|
Before you finish a task that generated or modified UI, emit this line:
|
|
56
79
|
|
|
57
80
|
```text
|
|
58
|
-
JIG_CHECK: version=<version> mode=<mode> mechanical=<pass|fail|skipped>:<n> judgment=<ran|skipped>
|
|
81
|
+
JIG_CHECK: version=<version> mode=<mode> mechanical=<pass|fail|skipped>:<n> judgment=<ran|skipped> files=<n> styled=<n>
|
|
59
82
|
```
|
|
60
83
|
|
|
61
84
|
`jig check` emits this same line for the half it can do, with
|