@justai/cuts 0.93.0 → 0.95.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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/Toolbar.astro +35 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justai/cuts",
3
- "version": "0.93.0",
3
+ "version": "0.95.0",
4
4
  "description": "A persona's named parts — the page shell that holds them, and the cuts themselves.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -37,7 +37,7 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@justai/core": "^0.18.0",
40
+ "@justai/core": "^0.20.0",
41
41
  "@justai/ui": "^0",
42
42
  "@justai/atrium": "^0.1.9"
43
43
  }
package/src/Toolbar.astro CHANGED
@@ -207,7 +207,7 @@ import AuthMount from "./AuthMount.astro";
207
207
  sees, rather than a duplicate face, which is a defect nobody reports. */}
208
208
  {Astro.slots.has("profileIcon")
209
209
  ? <slot name="profileIcon" />
210
- : (!parent && <img src={avatar} alt="" width="19" height="19" loading="lazy" decoding="async" />)}
210
+ : (!parent && <img src={avatar} alt="" width="20" height="20" loading="lazy" decoding="async" />)}
211
211
  </a>
212
212
  {/* THE KERNEL IS ALWAYS THE BOLT. The founder's rule, and it is the shell's to draw rather
213
213
  than the persona's to remember.
@@ -346,16 +346,23 @@ import AuthMount from "./AuthMount.astro";
346
346
  misses. Same ink hook as everywhere the accent stops being paint. */
347
347
  .tb-nav.active { color: var(--accent-text, var(--accent)); }
348
348
 
349
- /* A MARK IS NOT DIMMED, AND THE PROFILE CUT DOES NOT NEED IT TO BE.
350
- It shipped dimmed at rest for one version, on the reasoning that a mark cannot take `currentColor`
351
- and so needed opacity to say "you are here". Both halves of that were true and the conclusion was
352
- still wrong, because the state was already being said, louder: `titleFor` in @justai/core returns an
353
- empty string for `profile`, so the title strip CLOSES on this cut and opens — 26px of layout, naming
354
- where you are — the moment you leave it. Against that, tinting an icon adds nothing.
355
- And the two are not the same kind of thing. The three stroke icons are generic glyphs whose colour IS
356
- a UI state; a mark is an identity. A faded logo does not read as "not current", it reads as disabled.
357
- So the mark stays itself. Press feedback is not lost: `.tb-nav:active`'s scale applies to it like any
358
- other item. `.tb-mark` remains, because the sizing rule below still needs to know an image is here. */
349
+ /* queries: should the persona mark be coloured · the mark is always accent · two icons look active
350
+ THE MARK IS A CUT ICON LIKE THE OTHER TWO — the founder's rule, 2026-08-03: the ACTIVE cut wears
351
+ the accent and no passive one does, the persona's own mark included.
352
+
353
+ This comment used to argue the opposite: *"the three stroke icons are generic glyphs whose colour
354
+ IS a UI state; a mark is an identity… a faded logo reads as disabled."* Kept, because it is a true
355
+ premise ageing into a wrong conclusion. It was true while the mark arrived as an `<img>`, which
356
+ cannot take `currentColor` — dimming was then the only way to say "not here", and a dimmed logo
357
+ does read as disabled. The premise expired when `toolbarMark` began deriving an inline SVG: an
358
+ inline mark can be INK, and ink is not dimming. `toolbarMark` neutralises its paint, so the two
359
+ rules below reach it exactly as they reach the bolt and the bubble.
360
+
361
+ A mark that keeps its colours while another cut is current is a second voice on the one channel
362
+ the accent has — measured, several passive marks were more coloured than the active icon. A
363
+ persona that wants its own gradient WHILE CURRENT re-points to it from its own CSS; the `<defs>`
364
+ survive the derivation for that. `.tb-mark` remains, because the sizing rule below still needs to
365
+ know a mark is here. */
359
366
  /* The shell sizes the mark and says NOTHING about `display`, deliberately. Two files arrive for the two
360
367
  themes — an SVG's internal `prefers-color-scheme` does not survive <img>, measured — and the persona
361
368
  hides one with a media query. A `display: block` here would be two classes deep against the persona's
@@ -472,6 +479,23 @@ import AuthMount from "./AuthMount.astro";
472
479
  // consumers each remembering a line is O(N), and the third one always forgets.
473
480
  if (document.getElementById("navParent")) adoptMark({ id: "navParent" });
474
481
 
482
+ // queries: the persona mark is an image · the golden rule does not apply · currentColor img ·
483
+ // the mark keeps its colours when I did not pass profileIcon
484
+ //
485
+ // THE FALLBACK HAS TO OBEY THE RULE TOO. A persona that passes `profileIcon` hands over a mark
486
+ // derived at build time — ink, ground-less, sized. A persona that passes nothing gets the `<img>`
487
+ // above, and an image obeys nothing: it cannot take `currentColor`, so it wears its own colours
488
+ // while another cut is current, which is exactly what the accent must never do.
489
+ //
490
+ // It is the child persona's problem in a different costume — a mark known only as a URL — so it
491
+ // takes the child's answer: fetch it and derive it here. Same function, same three edits, and the
492
+ // row's own `.tb-nav` / `.tb-nav.active` rules reach it afterwards like any glyph.
493
+ //
494
+ // The build-time path stays the better one and stays the default advice: it costs no request and
495
+ // no frame of the wrong picture. This is the floor under a persona that has not got there yet.
496
+ const ownMark = document.querySelector("#navProfile img");
497
+ if (ownMark) adoptMark({ id: "navProfile" });
498
+
475
499
  // Both or neither — see the props above. When both are set the strip names the SECTIONS; core's
476
500
  // default, which names the persona and its handle, is left entirely alone otherwise. Nothing here
477
501
  // reproduces that default, which is the point: `.pname` and `.handle` stay core's business.