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.
@@ -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. Would this look different from a generic template if the accent colour were removed? (A-01 → A-10)
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.
@@ -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** — wrap the barrel, nothing else changes
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
- @import "./jig/theme.css";
462
+ --color-ink: var(--color-text-strong);
463
+ --color-paper: var(--color-bg-base);
398
464
  }
399
465
  ```
400
- Yields `bg-surface`, `rounded-surface`, `p-card`, `text-body` as utilities.
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": "judgment",
88
- "severity": "note",
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": "judgment",
112
- "severity": "note",
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": "judgment",
118
- "severity": "note",
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",
@@ -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