@justai/cuts 0.132.0 → 0.133.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/Posts.astro +37 -7
package/package.json
CHANGED
package/src/Posts.astro
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import { tagline } from "./tagline.js";
|
|
2
|
+
import { tagline, TAGLINE } from "./tagline.js";
|
|
3
3
|
// ░░ POSTS cut — a persona's feed, revealed by scrolling past the Kernel. ░░
|
|
4
4
|
//
|
|
5
5
|
// The feed's markup, its styling, AND its runtime loader were byte-near-identical across every persona
|
|
@@ -102,8 +102,33 @@ const { handle, name, lang, footer, avatarBg, avatarBgLight, avatarSrc, avatarBa
|
|
|
102
102
|
// (`/tr/`), so it is settled before any script runs — and the same rule the feed permalink pages
|
|
103
103
|
// learned the hard way: a page whose language came from its address must not be second-guessed by
|
|
104
104
|
// what the visitor last picked somewhere else.
|
|
105
|
-
|
|
105
|
+
//
|
|
106
|
+
// ── `Astro.currentLocale` IS UNDEFINED HERE, ON EVERY PERSONA IN THIS FLEET ─────────────────────
|
|
107
|
+
//
|
|
108
|
+
// It was written as the fallback and it has never once fired. The fleet routes languages through a
|
|
109
|
+
// `[lang]` PARAMETER, not Astro's i18n config, so `currentLocale` is undefined in every persona that
|
|
110
|
+
// has one — `Sheet.astro` says exactly this, in this same package, and the two comments contradicted
|
|
111
|
+
// each other with the wrong one load-bearing.
|
|
112
|
+
//
|
|
113
|
+
// MEASURED 2026-08-21, and it is not theoretical: `time.app.zone/tr/` and `tabata.app.zone/tr/` were
|
|
114
|
+
// closing their feeds with *"made to matter"* — the ENGLISH house line, on a Turkish page — because
|
|
115
|
+
// neither passes `lang`. Fifteen of the twenty-five personas that render this cut are in that state.
|
|
116
|
+
//
|
|
117
|
+
// So there are two answers, one per surface, and neither is "ask fifteen repos to remember":
|
|
118
|
+
// the footer → rendered by the server, so it is RE-LABELLED at runtime from `<html lang>`, which
|
|
119
|
+
// is the pattern this package already uses for the words a cut owns
|
|
120
|
+
// the feed → fetched by the loader, which runs at runtime and can simply read `<html lang>`
|
|
121
|
+
// `lang` still wins wherever a persona states it: a stated fact beats an inferred one.
|
|
122
|
+
const feedLang = lang ?? "en";
|
|
106
123
|
const foot = footer ?? tagline(feedLang);
|
|
124
|
+
// Only a STATED language rides on the section. An inferred "en" here would look identical to a
|
|
125
|
+
// persona that really is English, and the loader could no longer tell the difference.
|
|
126
|
+
const statedLang = lang ?? undefined;
|
|
127
|
+
// The house line is re-labelled at runtime ONLY when the persona did not state its language and did
|
|
128
|
+
// not override the sentence. A consumer's word always wins — the same rule `data-chrome` keeps.
|
|
129
|
+
const RELABEL = !lang && !footer
|
|
130
|
+
? `(function(){try{var T=${JSON.stringify(TAGLINE)},l=(document.documentElement.lang||"en").toLowerCase().split("-")[0],e=document.querySelector("[data-house-line]");if(e&&T[l])e.textContent=T[l];}catch(_){}})();`
|
|
131
|
+
: "";
|
|
107
132
|
const vars = [
|
|
108
133
|
avatarBg && `--feed-av-bg:${avatarBg}`,
|
|
109
134
|
avatarBgLight && `--feed-av-bg-light:${avatarBgLight}`,
|
|
@@ -115,7 +140,7 @@ const vars = [
|
|
|
115
140
|
id="posts"
|
|
116
141
|
data-persona={handle}
|
|
117
142
|
data-name={name}
|
|
118
|
-
data-lang={
|
|
143
|
+
data-lang={statedLang}
|
|
119
144
|
data-av={avatarSrc ?? "/icon.svg"}
|
|
120
145
|
data-av-dark={avatarSrcDark}
|
|
121
146
|
data-av-bare={avatarBare ? "" : undefined}
|
|
@@ -124,7 +149,7 @@ const vars = [
|
|
|
124
149
|
<!-- filled at runtime by the loader below (lazy, on Posts-cut intersection) — single source: the console -->
|
|
125
150
|
<div id="feed"></div>
|
|
126
151
|
<footer class="z-foot">
|
|
127
|
-
<a href="https://justai.pro">justai.pro</a> · {foot}
|
|
152
|
+
<a href="https://justai.pro">justai.pro</a> · <span data-house-line={!lang && !footer ? "" : undefined}>{foot}</span>
|
|
128
153
|
{/* the change-your-mind door: hidden until the shell's consent script labels + reveals it
|
|
129
154
|
(Base owns the behavior and the localized label; this cut only owns the placement). On a
|
|
130
155
|
page with no analytics — and so no consent banner — it simply never appears. */}
|
|
@@ -132,6 +157,8 @@ const vars = [
|
|
|
132
157
|
</footer>
|
|
133
158
|
</section>
|
|
134
159
|
|
|
160
|
+
{RELABEL && <script is:inline set:html={RELABEL}></script>}
|
|
161
|
+
|
|
135
162
|
<style>
|
|
136
163
|
/* ---- POSTS cut — a conversation: ONE line descends from the post's avatar and
|
|
137
164
|
connects every comment & reply (they're all replies to the post). ---- */
|
|
@@ -333,9 +360,12 @@ const vars = [
|
|
|
333
360
|
// so it may carry markup (justai's ".pro" span). Every name that comes from the API is escaped.
|
|
334
361
|
const PERSONA = section.dataset.persona || "";
|
|
335
362
|
const NAME = section.dataset.name || "";
|
|
336
|
-
// THE PAGE'S LANGUAGE
|
|
337
|
-
//
|
|
338
|
-
|
|
363
|
+
// THE PAGE'S LANGUAGE. `data-lang` is present only when the persona STATED it; otherwise the
|
|
364
|
+
// document's own `lang` is read, which is the one place every persona in this fleet agrees —
|
|
365
|
+
// `Astro.currentLocale` is undefined under `[lang]` routing and cannot be the fallback it looks
|
|
366
|
+
// like. Not localStorage either: on a localized home the language is in the URL, settled before
|
|
367
|
+
// this ran, and a link shared in Turkish must open in Turkish for whoever follows it.
|
|
368
|
+
const LANG = (section.dataset.lang || document.documentElement.lang || "en").toLowerCase().split("-")[0];
|
|
339
369
|
if (!PERSONA) return;
|
|
340
370
|
// Astro scopes this component's CSS by a data-astro-cid-* attribute; runtime nodes lack it, so copy it.
|
|
341
371
|
const scopeAttr = section.getAttributeNames().find((n) => n.startsWith("data-astro-cid-")) || null;
|