@justai/cuts 0.15.0 → 0.17.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.
- package/package.json +1 -1
- package/src/Base.astro +16 -0
- package/src/Posts.astro +13 -4
package/package.json
CHANGED
package/src/Base.astro
CHANGED
|
@@ -184,6 +184,18 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
|
|
|
184
184
|
ten that measure themselves exactly nothing. */}
|
|
185
185
|
{gaId && (
|
|
186
186
|
<script is:inline define:vars={{ gaId }}>
|
|
187
|
+
// A non-production page measures NOTHING. Found by the first read through the analytics MCP:
|
|
188
|
+
// 127.0.0.1 + localhost were the property's TOP "persona" (562 fake users in 28 days — local
|
|
189
|
+
// dev, plus every headless verification sweep loading the built HTML). The guard also covers
|
|
190
|
+
// the edge's dev- preview hosts: previews are rehearsals, not visits. gtag is still defined
|
|
191
|
+
// (as the same queue-stub) even on a silenced host, so the consent script can never hit
|
|
192
|
+
// "gtag is not defined" — the exact trap documented below. The whole block sits in an if
|
|
193
|
+
// rather than behind an early return: Astro 7's compiler rejects a top-level `return` in an
|
|
194
|
+
// inline script at BUILD time (the define:vars IIFE only exists later, at runtime).
|
|
195
|
+
window.gtag = window.gtag || function () { (window.dataLayer = window.dataLayer || []).push(arguments); };
|
|
196
|
+
var __h = location.hostname;
|
|
197
|
+
var __nonprod = __h === "localhost" || __h === "127.0.0.1" || __h === "::1" || __h === "[::1]" || __h.indexOf("dev-") === 0;
|
|
198
|
+
if (!__nonprod) {
|
|
187
199
|
window.dataLayer = window.dataLayer || [];
|
|
188
200
|
// gtag is put on WINDOW, not declared as `function gtag`, and this is load-bearing: `define:vars`
|
|
189
201
|
// wraps this inline script in an IIFE to scope the injected `gaId`, so a `function gtag` here
|
|
@@ -213,6 +225,7 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
|
|
|
213
225
|
document.head.appendChild(s);
|
|
214
226
|
});
|
|
215
227
|
});
|
|
228
|
+
}
|
|
216
229
|
</script>
|
|
217
230
|
)}
|
|
218
231
|
</head>
|
|
@@ -263,6 +276,9 @@ const localePath = (l: string) => (l === defaultLocale ? "/" : `/${l}/`);
|
|
|
263
276
|
<script is:inline>
|
|
264
277
|
(function () {
|
|
265
278
|
try {
|
|
279
|
+
// same non-production guard as the analytics block: no measurement → nothing to consent to
|
|
280
|
+
var h = location.hostname;
|
|
281
|
+
if (h === "localhost" || h === "127.0.0.1" || h === "::1" || h === "[::1]" || h.indexOf("dev-") === 0) return;
|
|
266
282
|
if (localStorage.getItem("consent")) return;
|
|
267
283
|
if (!document.getElementById("kernel")) return; // no kernel = not a content page (e.g. 404) — don't ask for consent on a dead end
|
|
268
284
|
if ((Intl.DateTimeFormat().resolvedOptions().timeZone || "").indexOf("Europe/") !== 0) return;
|
package/src/Posts.astro
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
// script framework-free in spirit: the day a Next persona (auth's home feed) wants the same feed, this
|
|
12
12
|
// exact logic lifts into @justai/core unchanged. Until then, YAGNI — it stays an Astro cut.
|
|
13
13
|
//
|
|
14
|
-
//
|
|
15
|
-
//
|
|
14
|
+
// The per-persona knobs are the post-avatar tile behind /icon.svg (matching the profile): `avatarBg`,
|
|
15
|
+
// plus `avatarBgLight` when that ground is a dark gradient that must invert in light mode rather than
|
|
16
|
+
// stay dark. Everything else is shared.
|
|
16
17
|
//
|
|
17
18
|
// THE SOCIAL LAYER is in here: a persona's feed carries replies from OTHER personas, and they must read
|
|
18
19
|
// as themselves — their own icon (or glyph), their own name and @handle, and a link to their own
|
|
@@ -27,8 +28,13 @@ interface Props {
|
|
|
27
28
|
footer: string; // the localized footer tagline after "justai.pro ·"
|
|
28
29
|
displayHandle?: string; // the rendered @handle when it differs from the key (app.zone → @appzone)
|
|
29
30
|
avatarBg?: string; // post-avatar tile background (default #fff)
|
|
31
|
+
avatarBgLight?: string; // light-scheme override for that tile (a dark gradient must invert, not stay dark)
|
|
30
32
|
}
|
|
31
|
-
const { handle, name, footer, displayHandle, avatarBg } = Astro.props;
|
|
33
|
+
const { handle, name, footer, displayHandle, avatarBg, avatarBgLight } = Astro.props;
|
|
34
|
+
const vars = [
|
|
35
|
+
avatarBg && `--feed-av-bg:${avatarBg}`,
|
|
36
|
+
avatarBgLight && `--feed-av-bg-light:${avatarBgLight}`,
|
|
37
|
+
].filter(Boolean).join(";");
|
|
32
38
|
---
|
|
33
39
|
|
|
34
40
|
<section
|
|
@@ -37,7 +43,7 @@ const { handle, name, footer, displayHandle, avatarBg } = Astro.props;
|
|
|
37
43
|
data-persona={handle}
|
|
38
44
|
data-handle={displayHandle ?? handle}
|
|
39
45
|
data-name={name}
|
|
40
|
-
style={
|
|
46
|
+
style={vars || undefined}
|
|
41
47
|
>
|
|
42
48
|
<!-- filled at runtime by the loader below (lazy, on Posts-cut intersection) — single source: the console -->
|
|
43
49
|
<div id="feed"></div>
|
|
@@ -65,6 +71,9 @@ const { handle, name, footer, displayHandle, avatarBg } = Astro.props;
|
|
|
65
71
|
.rav { flex: none; width: 30px; height: 30px; border-radius: var(--radius-sm); display: grid; place-items: center; font-size: 15px; background: var(--feed-av-bg, #fff); border: 1px solid var(--border); overflow: hidden; }
|
|
66
72
|
.pa :global(svg), .rav :global(svg) { display: block; }
|
|
67
73
|
.pa .mk, .rav .mk { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
74
|
+
/* a dark tile must invert in light mode, not stay dark — personas whose avatar ground is a gradient
|
|
75
|
+
pass avatarBgLight; the rest fall back to their single background. */
|
|
76
|
+
@media (prefers-color-scheme: light) { .pa, .rav { background: var(--feed-av-bg-light, var(--feed-av-bg, #fff)); } }
|
|
68
77
|
|
|
69
78
|
.ph { display: flex; align-items: center; gap: 5px; font-size: var(--fs-xs); flex-wrap: wrap; }
|
|
70
79
|
.ph b { font-weight: 600; }
|