shadok-ai 0.8.21 → 0.8.22
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 +51 -46
package/package.json
CHANGED
package/public/index.html
CHANGED
|
@@ -1019,17 +1019,15 @@
|
|
|
1019
1019
|
/* The pumping Shadok: `color` feeds its `currentColor` fill so it follows the
|
|
1020
1020
|
palette. The body bobs and the arm swings — the pump — on the same beat. */
|
|
1021
1021
|
#thinking .tw-shadok { display: inline-flex; color: var(--amber); }
|
|
1022
|
-
#thinking .tw-shadok svg { width:
|
|
1023
|
-
/*
|
|
1024
|
-
cross-browser trap on SVG
|
|
1025
|
-
|
|
1026
|
-
#thinking .tw-shadok .sh-
|
|
1027
|
-
|
|
1028
|
-
@keyframes tw-pump { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(1.5px); } }
|
|
1029
|
-
@keyframes tw-arm { 0%, 100% { transform: rotate(-10deg); } 50% { transform: rotate(28deg); } }
|
|
1022
|
+
#thinking .tw-shadok svg { width: 22px; height: 22px; overflow: visible; }
|
|
1023
|
+
/* The whole Shadok (body + arm + handle) bobs with translate — no
|
|
1024
|
+
transform-origin, which is a cross-browser trap on SVG — while the pump rod
|
|
1025
|
+
and legs stay planted, so the handle strokes up and down the rod. */
|
|
1026
|
+
#thinking .tw-shadok .sh-bob { animation: tw-bob 0.62s ease-in-out infinite; }
|
|
1027
|
+
@keyframes tw-bob { 0%, 100% { transform: translateY(-1.6px); } 50% { transform: translateY(1.9px); } }
|
|
1030
1028
|
@media (prefers-reduced-motion: reduce) {
|
|
1031
1029
|
#thinking .tw-text { animation: none; color: var(--phosphor); -webkit-text-fill-color: currentColor; }
|
|
1032
|
-
#thinking .tw-shadok .sh-
|
|
1030
|
+
#thinking .tw-shadok .sh-bob { animation: none; }
|
|
1033
1031
|
}
|
|
1034
1032
|
|
|
1035
1033
|
/* Composer */
|
|
@@ -3168,33 +3166,46 @@
|
|
|
3168
3166
|
return v || fallback;
|
|
3169
3167
|
}
|
|
3170
3168
|
/** The Shadok itself — the cockpit's mascot, which famously PUMPS. One drawing
|
|
3171
|
-
* serves every use
|
|
3172
|
-
*
|
|
3173
|
-
*
|
|
3174
|
-
*
|
|
3175
|
-
*
|
|
3176
|
-
*
|
|
3177
|
-
|
|
3169
|
+
* serves every use. `bob` poses one frame of the pump (the favicon animates by
|
|
3170
|
+
* re-generating with new values); `anim` instead tags the bobbing group so CSS
|
|
3171
|
+
* drives it (the DOM indicator only — CSS animation inside a favicon data URI
|
|
3172
|
+
* is unreliable). `pump` gives it a hand-pump — a FIXED rod the Shadok works up
|
|
3173
|
+
* and down; that steady reference is what makes the bob read at favicon size, a
|
|
3174
|
+
* bob with nothing to measure against looked static. `sym` overlays a bold "!"
|
|
3175
|
+
* / "?" ON the Shadok, outlined in the ground colour so the accent-on-accent
|
|
3176
|
+
* "?" still reads. Legs (and, while pumping, the rod) stay planted; everything
|
|
3177
|
+
* else bobs. The body sits left when pumping, to seat the rod on its right. */
|
|
3178
|
+
function shadokInner(fill, { bob = 0, pump = false, anim = false, sym = null, symColor } = {}) {
|
|
3178
3179
|
const base = themeColor("--bg", "#14161d");
|
|
3179
|
-
const
|
|
3180
|
-
const
|
|
3181
|
-
const
|
|
3182
|
-
|
|
3180
|
+
const cx = pump ? 13 : 15;
|
|
3181
|
+
const bobCls = anim ? ' class="sh-bob"' : "";
|
|
3182
|
+
const bobTf = anim ? "" : ` transform="translate(0 ${bob})"`;
|
|
3183
|
+
// The fore-limb: a resting stub, or — pumping — an arm gripping a handle bar.
|
|
3184
|
+
// Both live INSIDE the bobbing group, so the handle strokes down the rod.
|
|
3185
|
+
const arm = pump
|
|
3186
|
+
? `<rect x="${cx + 6.2}" y="12.6" width="6" height="1.7" rx="0.85"/>` +
|
|
3187
|
+
`<rect x="${cx + 5.8}" y="13.6" width="1.9" height="6" rx="0.95" transform="rotate(12 ${cx + 6.7} 13.6)"/>`
|
|
3188
|
+
: `<g transform="rotate(6 ${cx + 4.6} 15.6)"><rect x="${cx + 3.6}" y="15" width="2.1" height="8.4" rx="1.05"/></g>`;
|
|
3189
|
+
const rod = pump ? `<rect x="${cx + 9.6}" y="16.5" width="1.5" height="12.7" rx="0.6" fill="${fill}"/>` : "";
|
|
3190
|
+
const glyph = sym
|
|
3191
|
+
? `<text x="${cx}" y="20.4" font-family="monospace" font-size="16" font-weight="800" fill="${symColor || fill}" stroke="${base}" stroke-width="2.6" paint-order="stroke" text-anchor="middle">${sym}</text>`
|
|
3192
|
+
: "";
|
|
3183
3193
|
return (
|
|
3184
|
-
|
|
3194
|
+
rod +
|
|
3185
3195
|
// legs + feet (planted, not part of the bob)
|
|
3186
3196
|
`<g fill="${fill}">` +
|
|
3187
|
-
`<rect x="
|
|
3188
|
-
`<rect x="
|
|
3197
|
+
`<rect x="${cx - 3.6}" y="21" width="1.7" height="9" rx="0.85"/><rect x="${cx + 2.4}" y="21" width="1.7" height="9" rx="0.85"/>` +
|
|
3198
|
+
`<rect x="${cx - 5.8}" y="28.7" width="4.6" height="1.7" rx="0.85"/><rect x="${cx + 1.4}" y="28.7" width="4.6" height="1.7" rx="0.85"/>` +
|
|
3199
|
+
`</g>` +
|
|
3200
|
+
// body + arm(/handle) + long neck + head + beak + eye — all bob together
|
|
3201
|
+
`<g${bobCls} fill="${fill}"${bobTf}>` +
|
|
3202
|
+
`<ellipse cx="${cx}" cy="16.8" rx="7.4" ry="7.6"/>` +
|
|
3203
|
+
arm +
|
|
3204
|
+
`<path d="M${cx - 0.4} 10 C ${cx - 0.4} 6.6, ${cx + 1.6} 4.8, ${cx + 3.9} 4.8" stroke="${fill}" stroke-width="3" fill="none" stroke-linecap="round"/>` +
|
|
3205
|
+
`<circle cx="${cx + 4.5}" cy="4.7" r="3"/><path d="M${cx + 7.1} 3.5 L${cx + 11.4} 5 L${cx + 7.1} 6.5 Z"/>` +
|
|
3206
|
+
`<circle cx="${cx + 5.2}" cy="4.2" r="0.95" fill="${base}"/>` +
|
|
3189
3207
|
`</g>` +
|
|
3190
|
-
|
|
3191
|
-
`<g${bodyCls} fill="${fill}"${bodyTf}>` +
|
|
3192
|
-
`<ellipse cx="15" cy="16.8" rx="7.4" ry="7.6"/>` +
|
|
3193
|
-
`<g${armCls}${armTf}><rect x="18.6" y="15" width="2.1" height="8.4" rx="1.05"/></g>` +
|
|
3194
|
-
`<path d="M14.6 10 C 14.6 6.6, 16.6 4.8, 18.9 4.8" stroke="${fill}" stroke-width="3" fill="none" stroke-linecap="round"/>` +
|
|
3195
|
-
`<circle cx="19.5" cy="4.7" r="3"/><path d="M22.1 3.5 L26.4 5 L22.1 6.5 Z"/>` +
|
|
3196
|
-
`<circle cx="20.2" cy="4.2" r="0.95" fill="${base}"/>` +
|
|
3197
|
-
`</g></g>`
|
|
3208
|
+
glyph
|
|
3198
3209
|
);
|
|
3199
3210
|
}
|
|
3200
3211
|
function faviconWrap(inner) {
|
|
@@ -3207,27 +3218,21 @@
|
|
|
3207
3218
|
)
|
|
3208
3219
|
);
|
|
3209
3220
|
}
|
|
3210
|
-
/** The favicon: an accent Shadok on the dark ground. A waiting state
|
|
3211
|
-
* bold "!" (something to answer) or "?" (something to read) in its
|
|
3212
|
-
*
|
|
3213
|
-
* asked to distinguish the two. No symbol → the idle Shadok. */
|
|
3221
|
+
/** The favicon: an accent Shadok on the dark ground. A waiting state stamps a
|
|
3222
|
+
* bold "!" (something to answer) or "?" (something to read) OVER it, in its
|
|
3223
|
+
* colour. No symbol → the idle Shadok. */
|
|
3214
3224
|
function faviconSVG(symbol, symColor) {
|
|
3215
3225
|
const accent = themeColor("--amber", "#f0a848");
|
|
3216
|
-
|
|
3217
|
-
const sym = symbol
|
|
3218
|
-
? `<text x="25.8" y="13" font-family="monospace" font-size="15" font-weight="800" fill="${symColor || accent}" text-anchor="middle">${symbol}</text>`
|
|
3219
|
-
: "";
|
|
3220
|
-
return faviconWrap(shadok + sym);
|
|
3226
|
+
return faviconWrap(shadokInner(accent, symbol ? { sym: symbol, symColor } : {}));
|
|
3221
3227
|
}
|
|
3222
|
-
/** The "working" favicon: the Shadok pumping. `phase` (0..PUMP_FRAMES-1) rides
|
|
3223
|
-
*
|
|
3228
|
+
/** The "working" favicon: the Shadok pumping. `phase` (0..PUMP_FRAMES-1) rides a
|
|
3229
|
+
* cycle; the whole Shadok heaves up and down against the fixed rod. */
|
|
3224
3230
|
const PUMP_FRAMES = 8;
|
|
3225
3231
|
function faviconPumpingSVG(phase) {
|
|
3226
3232
|
const accent = themeColor("--amber", "#f0a848");
|
|
3227
3233
|
const p = (Math.sin((phase / PUMP_FRAMES) * 2 * Math.PI - Math.PI / 2) + 1) / 2; // 0..1..0
|
|
3228
|
-
const bob = +(p *
|
|
3229
|
-
|
|
3230
|
-
return faviconWrap(shadokInner(accent, { bob, armRot }));
|
|
3234
|
+
const bob = +(-2 + p * 4.2).toFixed(2); // -2 (up) .. +2.2 (down): a big, visible stroke
|
|
3235
|
+
return faviconWrap(shadokInner(accent, { bob, pump: true }));
|
|
3231
3236
|
}
|
|
3232
3237
|
/** What each channel is asking for, as the pure module wants it. */
|
|
3233
3238
|
function attentionInput() {
|
|
@@ -3299,7 +3304,7 @@
|
|
|
3299
3304
|
const twShadok = document.querySelector("#thinking .tw-shadok");
|
|
3300
3305
|
if (twShadok)
|
|
3301
3306
|
twShadok.innerHTML =
|
|
3302
|
-
`<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">${shadokInner("currentColor", { anim: true })}</svg>`;
|
|
3307
|
+
`<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">${shadokInner("currentColor", { pump: true, anim: true })}</svg>`;
|
|
3303
3308
|
}
|
|
3304
3309
|
// Coming back must stop the blink at once, not at the next tick. Both signals
|
|
3305
3310
|
// matter: switching tabs fires visibilitychange, switching application only
|