@justai/cuts 0.3.1 → 0.3.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.
- package/package.json +2 -2
- package/src/Base.astro +20 -11
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@justai/cuts",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "A persona's named parts
|
|
3
|
+
"version": "0.3.2",
|
|
4
|
+
"description": "A persona's named parts — the page shell that holds them, and the cuts themselves.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
package/src/Base.astro
CHANGED
|
@@ -61,19 +61,28 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
|
|
|
61
61
|
<meta charset="utf-8" />
|
|
62
62
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
63
63
|
<link rel="preconnect" href="https://api.justai.pro" crossorigin />
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
{/* justai auth: capture the SSO token here, synchronously, BEFORE anything else can touch the
|
|
65
|
+
hash. Its position in the head is LOAD-BEARING, not stylistic, because two later scripts
|
|
66
|
+
would otherwise take the token: the scroll-spy rewrites the hash to #kernel and CLOBBERS
|
|
67
|
+
#auth_token before the deferred sdk.js can read it; and the language picker copies the
|
|
68
|
+
current hash onto the next locale's URL (LangPicker), which would PROPAGATE the raw token
|
|
69
|
+
into a new page and into history. Capturing first defeats both. Move this and sign-in breaks
|
|
70
|
+
silently — no error, the visitor simply lands back signed out. */}
|
|
68
71
|
<script is:inline>(function(){try{var h=location.hash||"";var m=h.match(/(?:^#|&)auth_token=([^&]+)/);if(m){localStorage.setItem("justai_token",decodeURIComponent(m[1]))}else if(/(?:^#|&)auth_signout=1\b/.test(h)){localStorage.removeItem("justai_token")}else{return}history.replaceState(null,"",location.pathname+location.search)}catch(e){}})();</script>
|
|
69
72
|
<script is:inline>document.documentElement.classList.add("js")</script>
|
|
73
|
+
{/* Reveal only after a page marks itself ready — gated behind .js so the page is always visible
|
|
74
|
+
if JS is off, and no scroll flash before we position at the Kernel. This style is a TRAP as
|
|
75
|
+
much as a feature, and the warning must stay beside it: ANY page using this layout without a
|
|
76
|
+
kernel script that sets body.ready stays invisible FOREVER. The 404 is the page that keeps
|
|
77
|
+
falling into this — it carries its own inline body.classList.add("ready") for exactly this
|
|
78
|
+
reason. Nothing errors; the page is simply never shown. */}
|
|
70
79
|
<style is:inline>html.js body{opacity:0}html.js body.ready{opacity:1}</style>
|
|
71
|
-
|
|
80
|
+
{/* The locale list is INJECTED, never typed. It used to be a literal array here — a second
|
|
72
81
|
declaration beside src/i18n/index.ts, kept in agreement by hand, in the one place where
|
|
73
82
|
being wrong is invisible: a locale missing from this list simply never auto-routes, and
|
|
74
83
|
nothing anywhere goes red. The same shape in astro.config had already drifted (twelve
|
|
75
84
|
listed while /it/ was live), which is why this one is wired to the real list instead of
|
|
76
|
-
being checked against it.
|
|
85
|
+
being checked against it. */}
|
|
77
86
|
<script is:inline define:vars={{ supported: locales, def: defaultLocale }}>
|
|
78
87
|
// Auto-route to the visitor's language: a saved choice wins; otherwise the browser
|
|
79
88
|
// language on first visit. Only on the default (en) root — explicit /xx/ links are
|
|
@@ -130,7 +139,7 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
|
|
|
130
139
|
rel="icon"
|
|
131
140
|
href={favicon}
|
|
132
141
|
/>
|
|
133
|
-
|
|
142
|
+
{/* PWA: Workbox service worker (precache + offline) + installable manifest */}
|
|
134
143
|
<link rel="manifest" href="/manifest.webmanifest" />
|
|
135
144
|
<link rel="apple-touch-icon" href="/icon-192.png" />
|
|
136
145
|
{import.meta.env.DEV ? (
|
|
@@ -153,14 +162,14 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
|
|
|
153
162
|
if ("serviceWorker" in navigator) addEventListener("load", () => navigator.serviceWorker.register("/sw.js"));
|
|
154
163
|
</script>
|
|
155
164
|
)}
|
|
156
|
-
|
|
165
|
+
{/* Google Analytics 4 — anonymous (ad signals + personalization OFF), lazy-loaded after idle.
|
|
157
166
|
analytics_storage granted: direct user counting (cookieless modeling needs high traffic to
|
|
158
167
|
surface, so it shows nothing at low/launch volume).
|
|
159
168
|
|
|
160
169
|
gaId comes through define:vars because this script runs in the BROWSER. An is:inline block
|
|
161
170
|
has no access to component scope, so a bare `gaId` here would be undefined at runtime and
|
|
162
171
|
every persona would report to a property that does not exist — silently, with no failed
|
|
163
|
-
request and no console error, which is the only kind of analytics bug nobody finds.
|
|
172
|
+
request and no console error, which is the only kind of analytics bug nobody finds. */}
|
|
164
173
|
<script is:inline define:vars={{ gaId }}>
|
|
165
174
|
window.dataLayer = window.dataLayer || [];
|
|
166
175
|
function gtag() { dataLayer.push(arguments); }
|
|
@@ -190,8 +199,8 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
|
|
|
190
199
|
</head>
|
|
191
200
|
<body>
|
|
192
201
|
<slot />
|
|
193
|
-
|
|
194
|
-
Consent Mode region default already denies analytics for the EEA/UK until "Allow".
|
|
202
|
+
{/* Consent banner — shown only to European-timezone visitors with no stored choice. The
|
|
203
|
+
Consent Mode region default already denies analytics for the EEA/UK until "Allow". */}
|
|
195
204
|
<div id="cc" class="cc" role="dialog" aria-label={t.chromePrivacy}>
|
|
196
205
|
<div class="cc-card">
|
|
197
206
|
<p class="cc-text">{t.consentText}</p>
|