studio-engine 0.65.1 → 0.65.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3aa4604073fec8349d92e58a72bfb14d5c87fbaf03081f4bcb3e430a0ec35bf6
4
- data.tar.gz: 3653491831ad04c4cb7aad8f1950297655b42a0582864173c998cbf8ea005a06
3
+ metadata.gz: 7389678882ebbd2bba6a35738f330283a2e5a226e68009a76b83f0c14b0e1351
4
+ data.tar.gz: de1b1a74888a3c2e47cc39da0377323c1b51c04d1aa718de9826fc338aff13a8
5
5
  SHA512:
6
- metadata.gz: 38cd8f8eedcf34cb0cac87d4c7737bb3fd29af673651e4593a1a93f0e91e822e582500e62ffdb7172c6de1d6f8673fe6502da4717376b789ee91f0e9b9ed2fc4
7
- data.tar.gz: 2ac51eaf964ad5ef2d9e026298dd0565466540de68ae68677c77eb2b802f17bc392691d63594794bd537282b2a9d315fc64c01e52800a72a82cc87cf5a1ed329
6
+ metadata.gz: f2c671579063631d50ac0298f2812ccde9a32a4554cc85ecf2b23368a8f51d2027f4eb03ed748c87104b7b68c9150d4fa7accec288d6b1a545ddf6233c755847
7
+ data.tar.gz: f2a53ef58b2bc5959d3a0c420f0cb8619b448caf496b9b437cd70e4f79ca5d8652e482338f2472ad3fd3f4b2609c0e5c47e8f0c7da3ca44d4d7b9e9828cb4f80
data/CHANGELOG.md CHANGED
@@ -119,6 +119,60 @@ The format is [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This pro
119
119
  guard on the read-before-write order.
120
120
 
121
121
 
122
+ ### Fixed
123
+
124
+ - **A toast with buttons could not be dismissed while a modal was open.** The
125
+ layer scale put `--z-banner` (500) above `--z-toast` (400), and `body.modal-open`
126
+ lifts the environment bar stack to that tier at `position: sticky; top: 0`.
127
+ `#toast-container` is fixed at top 0 with `1rem` of padding, so the two land on
128
+ the same pixels: measured in a browser, the bars own y0-47 while the toast's
129
+ Dismiss button runs y28-40 — an 8-14px overlap at every viewport tested.
130
+ `elementFromPoint` at that button returned the **banner**, and a real click left
131
+ the toast on the page. Because the toast manager gives any toast carrying
132
+ buttons `duration: 0`, that X was the toast's **only** exit: it was stuck for
133
+ the rest of the session.
134
+
135
+ **The tiers are reordered** — `--z-banner` 400, `--z-toast-blur` 499, `--z-toast`
136
+ 500 — and that is a semantic decision rather than a nudge around the geometry: a
137
+ toast is transient and demands interaction, a banner is persistent chrome that
138
+ will still be there afterwards. `--z-banner` still clears `--z-modal` (200), so
139
+ the property the lift exists for — DEV MODE and the email chip stay lit and
140
+ clickable over a modal — is unchanged and now has its own spec.
141
+
142
+ **One measured cost.** A banner button's tooltip is a descendant of the bar
143
+ stack, and the modal-open lift makes that stack a stacking context, so the
144
+ tooltip composites at `--z-banner` rather than at its own `--z-tooltip` (600).
145
+ At 1440x900 the tooltip and the toast card never meet; at 390x844 they overlap
146
+ by 260x45px, so a banner tooltip opened with both a modal and a toast up is
147
+ drawn under the toast. Hover/focus-only, purely visual, and recorded beside the
148
+ scale.
149
+
150
+ **Consumers that redefine these tokens in their own `:root` after the engine
151
+ import still win**, as they always have, so an app carrying a local copy of the
152
+ scale keeps the old order (and the bug) until it drops the copy.
153
+
154
+ Two literals moved with the tiers: `#toast-container` and `.toast-page-blur` in
155
+ `layouts/studio/_flash` carry `var(--studio-toast-z, var(--z-toast, …))`
156
+ fallbacks, and a fallback that disagreed with the scale would hand the bug to
157
+ any app rendering the partial without the engine sheet.
158
+
159
+ **The existing test could not have caught this and still cannot on its own.**
160
+ `layer_scale_contract_test` asserted `--z-toast > --z-modal`, which was true the
161
+ entire time the toast was unusable — both tiers cleared the modal, which says
162
+ nothing about which of *them* wins. It now names the banner, and pins the halo
163
+ directly beneath its own toast so no tier can settle between them. The property
164
+ is also asserted where the defect lives, in `e2e/toast_over_banner.spec.js`: a
165
+ hit test and a real mouse click at the Dismiss button, at desktop and phone
166
+ widths, at scroll-top and at an offset. And once more on the artifact a
167
+ consumer is actually served — `test/integration/layer_scale_build_test.rb`
168
+ runs the real Tailwind binary over the engine's entry point and reads the
169
+ tiers out of the COMPILED bundle, where `@import` resolution, layer ordering
170
+ and a shadowing `:root` are all in play and a source read sees none of them. One trap is recorded there — at 390px
171
+ the point under that button is the banner's Email link, so on the broken build a
172
+ click *navigated* and the toast count on the new page was zero; asserting the
173
+ count alone passes over the bug.
174
+
175
+
122
176
  ### Breaking
123
177
 
124
178
  - **The age-gate DOB modal is renamed, and the refusal moved to its own card.**
@@ -63,12 +63,51 @@
63
63
  --z-modal: 200; /* modal backdrop + card — THE app blocker */
64
64
  --z-lightbox: 210; /* a lightbox opened from inside a modal */
65
65
  --z-alert: 300; /* transient overlays that must not be missed */
66
- --z-toast-blur: 399; /* the frosted halo behind the toasts */
67
- --z-toast: 400; /* toasts */
68
- --z-banner: 500; /* environment / DEV MODE reachable mid-modal */
66
+ --z-banner: 400; /* environment / DEV MODE reachable mid-modal */
67
+ --z-toast-blur: 499; /* the frosted halo behind the toasts */
68
+ --z-toast: 500; /* toasts ABOVE the banner; see below */
69
69
  --z-tooltip: 600; /* tooltips on the banner, so they clear it */
70
70
  }
71
71
 
72
+ /* WHY THE TOAST OUTRANKS THE BANNER, and why it did not used to.
73
+
74
+ The first cut of this scale put --z-banner (500) over --z-toast (400) on the
75
+ reasoning that the environment bars must stay reachable mid-modal. They must
76
+ — but so must a toast, and the two claims collided the moment BOTH were true
77
+ at once, because they occupy the same corner of the viewport.
78
+
79
+ THE DEFECT, MEASURED on mcritchie-studio at 1440x900 and 390x844, dark and
80
+ light, scrollY 0 and 900. #toast-container is fixed at top 0 with 1rem of
81
+ padding, so a toast card sits at roughly y16-92. With a modal open, the rule
82
+ below lifts the bar stack to sticky top 0 at --z-banner, so it owns y0-47 —
83
+ overlapping the toast's top edge, which is where the Dismiss button lives.
84
+ `document.elementFromPoint` at that button returned the BANNER div, and a
85
+ real click left the toast count at 1. With no modal open it returned the
86
+ button's own SVG and the count dropped to 0.
87
+
88
+ That is not a cosmetic overlap. A toast carrying action buttons is given
89
+ `duration: 0` by the toast manager (layouts/studio/_flash), so it never
90
+ auto-dismisses — the Dismiss button is its ONLY exit, and under a lifted
91
+ banner the toast is stuck on the page for the rest of the session.
92
+
93
+ SO THE ORDER IS A SEMANTIC DECISION, not a workaround for the geometry: a
94
+ TOAST IS TRANSIENT AND DEMANDS INTERACTION; a BANNER IS PERSISTENT CHROME
95
+ that will still be there afterwards. The thing asking to be dealt with wins.
96
+ Two alternatives were considered and rejected — lowering the modal-open lift
97
+ below the toast (narrower blast radius, but leaves the scale saying something
98
+ nobody believes) and offsetting #toast-container while modal-open (treats the
99
+ symptom; the toast goes back under the banner the day either one grows).
100
+
101
+ WHAT THIS COSTS, MEASURED RATHER THAN ASSUMED. --z-tooltip (600) still clears
102
+ both tiers, but a banner button's tooltip is a DESCENDANT of the bar stack —
103
+ and while a modal is open the rule below gives that stack a z-index, which
104
+ makes it a stacking context and clamps every descendant inside it. So the
105
+ tooltip now composites at --z-banner rather than at 600. At 1440x900 the two
106
+ never meet (tooltip x1083-1343, toast card x496-944); at 390x844 they overlap
107
+ by 260x45px, so a banner tooltip opened with a modal AND a toast up is drawn
108
+ under the toast card. It is hover/focus-only, purely visual (the tooltip is
109
+ pointer-events:none), and it is the accepted cost of this ordering. */
110
+
72
111
  /* The environment / impersonation bars stay in NORMAL FLOW at rest
73
112
  (banners/_stack records why: pinning them in the RESTING state needs one
74
113
  pinned sibling to measure the other, and the measured version visibly
@@ -110,7 +149,7 @@ body.modal-open .studio-bar-stack,
110
149
  body.modal-open .studio-app-banner {
111
150
  position: sticky;
112
151
  top: 0;
113
- z-index: var(--z-banner, 500);
152
+ z-index: var(--z-banner, 400);
114
153
  }
115
154
 
116
155
  /* -- Surfaces -------------------------------------------------------------- */
@@ -17,8 +17,18 @@
17
17
  bare 60/55 that sat below every app navbar. A toast is the one thing that
18
18
  must surface over an open modal, so --z-toast is above --z-modal and an app
19
19
  that never overrides gets that for free. Apps that DO override should set
20
- the tier (--z-toast) instead, and drop the per-component name. */
21
- #toast-container { z-index: var(--studio-toast-z, var(--z-toast, 400)); }
20
+ the tier (--z-toast) instead, and drop the per-component name.
21
+
22
+ ABOVE THE BANNER TOO, and the fallbacks below have to say so. A toast and
23
+ the environment bars share the top of the viewport, and with a modal open
24
+ engine.css lifts those bars to --z-banner at top 0 — which used to sit at
25
+ 500, over the toast's 400, so the toast's Dismiss button was covered and a
26
+ click landed on the banner. A toast carrying buttons is given duration 0 by
27
+ the manager below, so that button is its only exit: covered, the toast was
28
+ stuck forever. The tiers were reordered (engine.css carries the argument);
29
+ these literals are what an app gets when the engine sheet is absent, so
30
+ they must carry the SAME order or that app keeps the bug. */
31
+ #toast-container { z-index: var(--studio-toast-z, var(--z-toast, 500)); }
22
32
  .toast-shadow-all {
23
33
  box-shadow: 0 0 30px rgba(0,0,0,0.4), 0 0 10px rgba(0,0,0,0.2);
24
34
  }
@@ -65,7 +75,7 @@
65
75
  mask-image: radial-gradient(ellipse 70% 80% at 50% 0%, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0) 100%);
66
76
  -webkit-mask-image: radial-gradient(ellipse 70% 80% at 50% 0%, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 40%, rgba(0,0,0,0) 100%);
67
77
  pointer-events: none;
68
- z-index: var(--studio-toast-blur-z, var(--z-toast-blur, 399));
78
+ z-index: var(--studio-toast-blur-z, var(--z-toast-blur, 499));
69
79
  transition: opacity 0.5s ease;
70
80
  background: rgba(255, 255, 255, 0.15);
71
81
  }
@@ -1,3 +1,3 @@
1
1
  module Studio
2
- VERSION = "0.65.1"
2
+ VERSION = "0.65.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: studio-engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.65.1
4
+ version: 0.65.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex McRitchie