@justai/cuts 0.129.4 → 0.129.6

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 +1 -1
  2. package/src/Toolbar.astro +38 -16
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justai/cuts",
3
- "version": "0.129.4",
3
+ "version": "0.129.6",
4
4
  "description": "A persona's named parts \u2014 the page shell that holds them, and the cuts themselves.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
package/src/Toolbar.astro CHANGED
@@ -457,12 +457,21 @@ import AuthMount from "./AuthMount.astro";
457
457
  * Opacity and pointer-events here; the INERT that takes them out of the tab order is set in the
458
458
  * script, because CSS cannot. The transition matters more than it looks: chrome that snaps away
459
459
  * reads as breaking, chrome that withdraws reads as dimming the house lights. */
460
- :global(html[data-stage="playing"]) .tb-nav-group,
461
- :global(html[data-stage="playing"]) .tb-right,
462
- :global(html[data-stage="playing"]) .tb-title {
463
- opacity: 0.16; pointer-events: none;
464
- transition: opacity 0.4s var(--ease-out);
465
- }
460
+ /* ── IN THE DARK, NOT DISABLED — how this row goes quiet while a game plays ─────────────────
461
+ * queries: toolbar looks disabled · faded but clickable · toolbar during a game · theater
462
+ *
463
+ * Three versions of quieting, each struck by the founder. Fading the elements was the last one:
464
+ * *"neden disable mis gibi gozukuyor ama tiklanabiliyor? tiklanabiliyorsa disable gibi
465
+ * gozukmemeli."* Right - reduced opacity IS the visual language of disabled, and nothing
466
+ * clickable may speak it.
467
+ *
468
+ * The answer was in the theater metaphor the whole time: in a dark cinema the seats are not
469
+ * disabled, they are in the dark. So the elements keep their full strength and the ROW STEPS
470
+ * UNDER THE ROOM'S DIM - below the .pr-room layer the stage protocol hangs over the page - and
471
+ * darkens with everything else in one coherent light change. The dim takes no pointer events,
472
+ * so every control underneath works exactly as it looks like it should: like chrome in a dark
473
+ * room, waiting. */
474
+ :global(html[data-stage="playing"]) .tb-slot { z-index: 20; }
466
475
  /* icon-only section nav — current cut highlighted */
467
476
  .tb-nav {
468
477
  display: grid; place-items: center; width: 38px; height: 36px;
@@ -628,16 +637,29 @@ import AuthMount from "./AuthMount.astro";
628
637
  // Both or neither — see the props above. When both are set the strip names the SECTIONS; core's
629
638
  // default, which names the persona and its handle, is left entirely alone otherwise. Nothing here
630
639
  // reproduces that default, which is the point: `.pname` and `.handle` stay core's business.
631
- // ── the stage: the row's whole part is to withdraw and come back ──────────────────────────
632
- // queries: toolbar during a game · the nav is unreachable while playing
633
- // The nav fades by CSS; inert is what CSS cannot do — out of the tab order and the accessibility
634
- // tree, so a keyboard or a screen reader is not walking chrome the player left. The game draws
635
- // its own pause and fullscreen — see the markup comment above for the decision.
636
- document.addEventListener("justai:stage", (e: any) => {
637
- const playing = e?.detail?.mode === "playing";
638
- document.querySelector(".tb-nav-group")?.toggleAttribute("inert", playing);
639
- document.querySelector(".tb-right")?.toggleAttribute("inert", playing);
640
- });
640
+ // ── the stage: the row stays LIVE, and using it pauses the game ───────────────────────────
641
+ // queries: toolbar during a game · tapping posts while playing · auto pause · data-stage-silent
642
+ //
643
+ // The row went inert for one version and the founder unlocked it: every control stays enabled,
644
+ // and touching ANY of them while a game is playing asks the game to pause first — so a player who
645
+ // reaches for the posts mid-flight gets a paused gull and the feed, in one tap. The event is not
646
+ // blocked: the action proceeds naturally while the pause lands beside it (a locked page still
647
+ // scrolls programmatically, so even the hash navigation works before the unlock).
648
+ //
649
+ // Declarative seam, as asked: an element that must NOT pause the game opts out by carrying
650
+ // `data-stage-silent` — on itself or any ancestor. Everything else pauses by default, because a
651
+ // rule with a default and an opt-out survives a fleet; a per-element opt-in is the third copy
652
+ // that forgets.
653
+ document.querySelector(".toolbar")?.addEventListener(
654
+ "click",
655
+ (e) => {
656
+ if (document.documentElement.dataset.stage !== "playing") return;
657
+ const hit = (e.target as Element | null)?.closest?.("a, button, select, [role=button]");
658
+ if (!hit || hit.closest("[data-stage-silent]")) return;
659
+ document.dispatchEvent(new CustomEvent("justai:pause-request"));
660
+ },
661
+ true,
662
+ );
641
663
 
642
664
  const bar = document.querySelector(".toolbar") as HTMLElement | null;
643
665
  const kt = bar?.dataset.kernelTitle;