shadok-ai 0.9.18 → 0.9.19
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/public/index.html +25 -2
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -3377,12 +3377,35 @@
|
|
|
3377
3377
|
* end down = negative angle) and the ball dips with the effort — shared by the
|
|
3378
3378
|
* favicon and the in-page indicator so both pump the same way. */
|
|
3379
3379
|
function pumpPose(p) { return { lever: 13 - p * 28, bob: +(p * 1.5).toFixed(2) }; }
|
|
3380
|
-
/**
|
|
3380
|
+
/** Blend `t` of `b` into `a`, both 6-digit hex. Every palette colour is written
|
|
3381
|
+
* that way on purpose (see the theme blocks), so this needs no colour parser —
|
|
3382
|
+
* but anything else RETURNS `a` rather than producing `#NaNNaNNaN`, which is
|
|
3383
|
+
* an invalid fill and would take the whole favicon down silently. */
|
|
3384
|
+
const HEX6 = /^#[0-9a-f]{6}$/i;
|
|
3385
|
+
function mixHex(a, b, t) {
|
|
3386
|
+
if (!HEX6.test(a) || !HEX6.test(b)) return a;
|
|
3387
|
+
const ch = (c, i) => parseInt(c.slice(1 + i * 2, 3 + i * 2), 16);
|
|
3388
|
+
const out = [0, 1, 2].map((i) => Math.round(ch(a, i) + (ch(b, i) - ch(a, i)) * t));
|
|
3389
|
+
return "#" + out.map((v) => v.toString(16).padStart(2, "0")).join("");
|
|
3390
|
+
}
|
|
3391
|
+
/** The "working" favicon: the Shadok pumping its lever, on a tile that BREATHES
|
|
3392
|
+
* with the stroke. `phase` rides a cycle.
|
|
3393
|
+
*
|
|
3394
|
+
* The breathing is the part that survives. The pump is line work: the lever
|
|
3395
|
+
* swings 28° about a 5px radius and the body dips 1.5 — roughly 1.2 and 0.75
|
|
3396
|
+
* real pixels at the 16px a tab actually paints, i.e. under the threshold of a
|
|
3397
|
+
* rendered pixel. Idle and mid-stroke were pixel-identical there, so the whole
|
|
3398
|
+
* animation existed only for someone who zoomed in. Moving the GROUND moves
|
|
3399
|
+
* every pixel of the icon at once, which is the only thing that reads at that
|
|
3400
|
+
* size — the same lesson as the waiting glyph. The Shadok keeps pumping on top
|
|
3401
|
+
* for whoever looks closely. */
|
|
3381
3402
|
const PUMP_FRAMES = 12;
|
|
3403
|
+
const BREATHE = 0.26; // how far the ground travels toward the accent, at full stroke
|
|
3382
3404
|
function faviconPumpingSVG(phase) {
|
|
3383
3405
|
const accent = themeColor("--amber", "#f0a848");
|
|
3406
|
+
const base = themeColor("--bg", "#14161d");
|
|
3384
3407
|
const p = (Math.sin((phase / PUMP_FRAMES) * 2 * Math.PI - Math.PI / 2) + 1) / 2; // 0..1..0
|
|
3385
|
-
return faviconWrap(shadokInner(accent, pumpPose(p)));
|
|
3408
|
+
return faviconWrap(shadokInner(accent, pumpPose(p)), mixHex(base, accent, p * BREATHE));
|
|
3386
3409
|
}
|
|
3387
3410
|
/** What each channel is asking for, as the pure module wants it. */
|
|
3388
3411
|
function attentionInput() {
|