Spaces:
Running
Running
fix: creature no longer screen-shakes at neutral mood (tantrum FSM tuned for the real engine)
58182e8 verified | <html lang="en"><head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>clanker · a deterministic emotional creature</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Press+Start+2P&family=VT323&display=swap" rel="stylesheet"> | |
| <link rel="stylesheet" href="/static/styles.css?v=22"> | |
| <script src="/static/app.js?v=22" defer></script> | |
| </head> | |
| <body> | |
| <div id="root" style="position:relative;min-height:100vh;width:100%;background:var(--bg,#211710);color:var(--ink,#f4e8d6);font-family:var(--fbody,'JetBrains Mono',monospace);padding:18px;display:flex;flex-direction:column;gap:16px;overflow-x:hidden;"> | |
| <!-- ===== HEADER ===== --> | |
| <header style="display:flex;align-items:center;gap:14px;flex-wrap:wrap;"> | |
| <div style="display:flex;align-items:center;gap:11px;"> | |
| <div style="width:34px;height:34px;border-radius:11px;background:var(--accent,#ffd21e);display:flex;align-items:center;justify-content:center;box-shadow:0 4px 14px rgba(255,200,60,.35);"> | |
| <svg width="22" height="22" viewBox="0 0 24 24"><circle cx="12" cy="12" r="11" fill="#26190d"></circle><circle cx="8.5" cy="11" r="1.7" fill="#ffd21e"></circle><circle cx="15.5" cy="11" r="1.7" fill="#ffd21e"></circle><path d="M7.5 15 Q12 19 16.5 15" stroke="#ffd21e" stroke-width="1.8" fill="none" stroke-linecap="round"></path></svg> | |
| </div> | |
| <div> | |
| <div id="creatureName" style="font-family:var(--fhead,'Fredoka',sans-serif);font-weight:700;font-size:20px;letter-spacing:.3px;line-height:1;">Huggy</div> | |
| <div style="font-size:11px;color:var(--dim,#a9967c);margin-top:3px;letter-spacing:.4px;">a deterministic emotional creature · powered by VADUGWI</div> | |
| </div> | |
| </div> | |
| <div data-tip="VADUGWI: 7 deterministic dimensions (0–255, 128 neutral). 4,563-word vocabulary, 66 chess-like structural patterns, proximity fields (0.9× decay/word), phase system & Force Flow. Fully explainable. The live Space calls the real clanker engine + clanker-soul on the backend." style="cursor:help;font-size:10.5px;color:var(--dim,#a9967c);border:1px solid var(--line,rgba(255,210,140,.16));border-radius:999px;padding:5px 11px;display:flex;align-items:center;gap:6px;"> | |
| <span style="width:7px;height:7px;border-radius:50%;background:#5fd08a;box-shadow:0 0 8px #5fd08a;"></span>7D engine · how it works | |
| </div> | |
| <div style="flex:1;"></div> | |
| <button id="soundBtn" title="toggle babble sound" style="cursor:pointer;border:1px solid var(--line,rgba(255,210,140,.16));background:var(--panel2,#1a120b);color:var(--ink,#f4e8d6);border-radius:11px;width:38px;height:34px;font-size:15px;">🔊</button> | |
| </header> | |
| <!-- ===== GRID ===== --> | |
| <div style="display:flex;gap:16px;flex-wrap:wrap;align-items:stretch;flex:1;"> | |
| <!-- LEFT: VADUGWI live --> | |
| <section style="flex:1 1 300px;max-width:360px;min-width:268px;background:var(--panel,#2c2016);border:1px solid var(--line,rgba(255,210,140,.16));border-radius:var(--rad,18px);padding:16px;display:flex;flex-direction:column;gap:13px;"> | |
| <div style="display:flex;align-items:baseline;justify-content:space-between;"> | |
| <div style="font-family:var(--fhead,'Fredoka',sans-serif);font-weight:700;font-size:14px;letter-spacing:1.5px;">VADUGWI</div> | |
| <div style="font-size:9.5px;color:var(--accent,#ffd21e);letter-spacing:2px;display:flex;align-items:center;gap:5px;"><span style="width:6px;height:6px;border-radius:50%;background:var(--accent,#ffd21e);animation:floaty 1.6s ease-in-out infinite;"></span>LIVE</div> | |
| </div> | |
| <div style="font-size:11px;color:var(--dim,#a9967c);line-height:1.5;">this message read as<br><span id="readPhrase" style="color:var(--ink,#f4e8d6);font-size:13px;font-weight:600;">waiting…</span></div> | |
| <!-- meters (JS fills 7 rows) --> | |
| <div id="meters"></div> | |
| <!-- needs --> | |
| <div style="border-top:1px solid var(--line,rgba(255,210,140,.16));padding-top:11px;display:flex;flex-direction:column;gap:8px;"> | |
| <div data-tip="Tamagotchi-style needs decay over time. Feed, water, play with and pet it to keep them up — neglect pulls its mood down." style="cursor:help;font-size:11px;letter-spacing:1.5px;color:var(--dim,#a9967c);font-weight:600;">NEEDS</div> | |
| <div id="needs"></div> | |
| </div> | |
| <!-- soul / mood distance --> | |
| <div data-tip="Three timescales (clanker-soul): the Conversational score → Mood (minutes–hours, blends & cushions) → Soul (the persistent baseline mood drifts back toward). Heavy events during a wound can breach straight into Soul." style="cursor:help;border-top:1px solid var(--line,rgba(255,210,140,.16));padding-top:11px;display:flex;align-items:center;justify-content:space-between;font-size:11px;color:var(--dim,#a9967c);"> | |
| <span>mood ⟶ soul drift</span> | |
| <span id="soulDistance" style="color:var(--ink,#f4e8d6);font-weight:600;">Δ 0</span> | |
| </div> | |
| </section> | |
| <!-- CENTER: room --> | |
| <section style="flex:3 1 460px;min-width:320px;display:flex;flex-direction:column;gap:13px;"> | |
| <div id="stage" style="position:relative;width:100%;aspect-ratio:4/3;border-radius:var(--rad,18px);overflow:hidden;border:1px solid var(--line,rgba(255,210,140,.16));background:var(--wall2,#e9bd72);box-shadow:inset 0 0 80px rgba(40,20,0,.25);touch-action:none;user-select:none;"> | |
| <!-- room scene --> | |
| <svg viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice" style="position:absolute;inset:0;width:100%;height:100%;"> | |
| <defs> | |
| <linearGradient id="wallg" x1="0" y1="0" x2="0" y2="1"> | |
| <stop offset="0%" stop-color="var(--wall1,#ffe8b0)"></stop><stop offset="100%" stop-color="var(--wall2,#e9bd72)"></stop> | |
| </linearGradient> | |
| <linearGradient id="skyg" x1="0" y1="0" x2="0" y2="1"> | |
| <stop offset="0%" stop-color="var(--sky1,#bfe3ff)"></stop><stop offset="100%" stop-color="var(--sky2,#ffd98a)"></stop> | |
| </linearGradient> | |
| <radialGradient id="sung" cx="50%" cy="50%" r="50%"><stop offset="0%" stop-color="#fff4c2"></stop><stop offset="100%" stop-color="#ffcf5e"></stop></radialGradient> | |
| <radialGradient id="lightg" cx="50%" cy="14%" r="62%"><stop offset="0%" stop-color="rgba(255,244,200,.34)"></stop><stop offset="100%" stop-color="rgba(255,244,200,0)"></stop></radialGradient> | |
| <radialGradient id="vigg" cx="50%" cy="52%" r="72%"><stop offset="52%" stop-color="rgba(40,20,0,0)"></stop><stop offset="100%" stop-color="rgba(30,15,0,.34)"></stop></radialGradient> | |
| </defs> | |
| <rect x="0" y="0" width="400" height="196" fill="url(#wallg)"></rect> | |
| <rect x="0" y="196" width="400" height="104" fill="var(--floor,#c9a06a)"></rect> | |
| <rect x="0" y="193" width="400" height="4" fill="rgba(90,55,18,.32)"></rect> | |
| <!-- window, centered + aligned --> | |
| <g> | |
| <rect x="150" y="26" width="100" height="84" rx="7" fill="#fff" opacity=".5"></rect> | |
| <rect x="155" y="31" width="90" height="74" rx="4" fill="url(#skyg)"></rect> | |
| <circle cx="225" cy="52" r="13" fill="url(#sung)"></circle> | |
| <path d="M170 96 q12 -16 24 -4 q10 -14 24 -2 l0 12 -48 0 z" fill="#fff" opacity=".5"></path> | |
| <rect x="197" y="31" width="6" height="74" fill="#fff" opacity=".55"></rect> | |
| <rect x="155" y="64" width="90" height="6" fill="#fff" opacity=".55"></rect> | |
| <rect x="146" y="108" width="108" height="7" rx="3" fill="#caa46a"></rect> | |
| </g> | |
| <!-- shelf right --> | |
| <g> | |
| <rect x="300" y="60" width="86" height="7" rx="2" fill="#a9763f"></rect> | |
| <rect x="310" y="40" width="9" height="20" rx="2" fill="#cf6a5a"></rect> | |
| <rect x="321" y="36" width="9" height="24" rx="2" fill="#6aa6cf"></rect> | |
| <rect x="332" y="43" width="9" height="17" rx="2" fill="#7dbf72"></rect> | |
| <circle cx="360" cy="52" r="8" fill="#d8975a"></circle><rect x="356" y="50" width="8" height="10" fill="#b97e44"></rect> | |
| </g> | |
| <!-- plant lower-left --> | |
| <g> | |
| <path d="M30 196 q-16 -34 -6 -56 q8 12 6 30 q10 -22 24 -28 q-6 18 -18 34 q14 -10 26 -8 q-12 14 -28 24z" fill="#5a9a52"></path> | |
| <path d="M30 196 l-12 0 6 -26 12 0 z" fill="#bf6a4a"></path> | |
| </g> | |
| <!-- rug --> | |
| <ellipse cx="200" cy="252" rx="118" ry="26" fill="#d9544e" opacity=".22"></ellipse> | |
| <ellipse cx="200" cy="252" rx="92" ry="19" fill="#e8a23a" opacity=".22"></ellipse> | |
| <rect x="0" y="0" width="400" height="300" fill="url(#lightg)" pointer-events="none"></rect> | |
| <rect x="0" y="0" width="400" height="300" fill="url(#vigg)" pointer-events="none"></rect> | |
| </svg> | |
| <!-- aura --> | |
| <div id="aura" style="position:absolute;left:50%;top:54%;width:42%;height:42%;border-radius:50%;background:radial-gradient(circle,hsl(48 70% 60% / .55),transparent 68%);transform:translate(-50%,-50%);mix-blend-mode:screen;pointer-events:none;animation:auraPulse 3.4s ease-in-out infinite;filter:blur(4px);"></div> | |
| <!-- creature --> | |
| <svg id="creature" viewBox="0 0 200 240" style="position:absolute;left:50%;bottom:13%;width:30%;transform:translateX(-50%);overflow:visible;cursor:pointer;z-index:4;"> | |
| <ellipse id="shadow" cx="100" cy="224" rx="62" ry="11" fill="rgba(0,0,0,.28)"></ellipse> | |
| <g id="blob"> | |
| <circle id="body" cx="100" cy="120" r="78" fill="var(--accent,#ffd21e)" stroke="var(--cstroke-col,transparent)" stroke-width="var(--cstroke,0)"></circle> | |
| <circle id="emoteGlow" cx="100" cy="122" r="70" fill="hsl(48 80% 55%)" opacity="0" pointer-events="none"></circle> | |
| <ellipse cx="78" cy="84" rx="18" ry="11" fill="#fff" opacity=".26" transform="rotate(-16 78 84)"></ellipse> | |
| <ellipse id="cheekL" cx="62" cy="138" rx="14" ry="9" fill="#ff9bb0" opacity=".35"></ellipse> | |
| <ellipse id="cheekR" cx="138" cy="138" rx="14" ry="9" fill="#ff9bb0" opacity=".35"></ellipse> | |
| <g id="armL"><path d="M52 150 Q34 152 24 138" stroke="var(--accent,#ffd21e)" stroke-width="15" stroke-linecap="round" fill="none"></path><ellipse cx="22" cy="136" rx="15" ry="13" fill="var(--accent,#ffd21e)"></ellipse></g> | |
| <g id="armR"><path d="M148 150 Q166 152 176 138" stroke="var(--accent,#ffd21e)" stroke-width="15" stroke-linecap="round" fill="none"></path><ellipse cx="178" cy="136" rx="15" ry="13" fill="var(--accent,#ffd21e)"></ellipse></g> | |
| <line id="browL" x1="62" y1="96" x2="86" y2="96" stroke="#2a1a0c" stroke-width="5" stroke-linecap="round"></line> | |
| <line id="browR" x1="114" y1="96" x2="138" y2="96" stroke="#2a1a0c" stroke-width="5" stroke-linecap="round"></line> | |
| <ellipse id="eyeL" cx="74" cy="112" rx="9" ry="11" fill="#2a1a0c"></ellipse> | |
| <ellipse id="eyeR" cx="126" cy="112" rx="9" ry="11" fill="#2a1a0c"></ellipse> | |
| <circle id="glintL" cx="77" cy="108" r="3" fill="#fff"></circle> | |
| <circle id="glintR" cx="129" cy="108" r="3" fill="#fff"></circle> | |
| <path id="mouth" d="M82 150 Q100 166 118 150" stroke="#2a1a0c" stroke-width="5" fill="none" stroke-linecap="round"></path> | |
| <path id="tearL" d="M70 124 q-4 6 0 9 q4 -3 0 -9Z" fill="#7ec8f5" opacity="0"></path> | |
| <path id="tearR" d="M130 124 q-4 6 0 9 q4 -3 0 -9Z" fill="#7ec8f5" opacity="0"></path> | |
| </g> | |
| <circle id="steamL" cx="44" cy="64" r="6" fill="#cfd8e0" opacity="0"></circle> | |
| <circle id="steamR" cx="156" cy="64" r="6" fill="#cfd8e0" opacity="0"></circle> | |
| <g id="hearts" opacity="0"><path d="M100 44 c-5 -8 -16 -2 -10 6 l10 10 10 -10 c6 -8 -5 -14 -10 -6Z" fill="#ff7aa8"></path></g> | |
| <text id="zzz" x="150" y="60" font-size="26" fill="#cfe0ff" opacity="0" font-family="Fredoka,sans-serif">z</text> | |
| </svg> | |
| <!-- items (toys — draggable; JS fills) --> | |
| <div id="items"></div> | |
| <!-- feeding stations (fixed — click to fill) --> | |
| <div id="foodBowl" data-tip="Click to fill the food bowl. Huggy walks over and eats on his own when there's food and he's hungry." style="position:absolute;left:14%;bottom:5%;width:10%;cursor:pointer;z-index:3;filter:drop-shadow(0 4px 5px rgba(0,0,0,.3));"> | |
| <div id="foodFill" style="width:100%;"></div> | |
| </div> | |
| <div id="waterBowl" data-tip="Click to fill the water bowl. Huggy drinks automatically when thirsty." style="position:absolute;left:25%;bottom:4%;width:10%;cursor:pointer;z-index:3;filter:drop-shadow(0 4px 5px rgba(0,0,0,.3));"> | |
| <div id="waterFill" style="width:100%;"></div> | |
| </div> | |
| <!-- mood chip --> | |
| <div style="position:absolute;top:12px;right:12px;background:var(--panel,#2c2016);border:1px solid var(--line,rgba(255,210,140,.16));border-radius:999px;padding:7px 14px;font-size:13px;font-weight:600;font-family:var(--fhead,'Fredoka',sans-serif);display:flex;align-items:center;gap:8px;z-index:6;"> | |
| <span id="moodDot" style="width:9px;height:9px;border-radius:50%;background:hsl(48 70% 55%);box-shadow:0 0 9px hsl(48 70% 55%);"></span><span id="moodWord">calm</span> | |
| </div> | |
| <!-- remembers-you hint (welcome back / known device) --> | |
| <div id="remembersHint" style="display:none;position:absolute;top:12px;left:12px;background:var(--panel,#2c2016);border:1px solid var(--line,rgba(255,210,140,.16));border-radius:999px;padding:6px 12px;font-size:11px;font-weight:600;font-family:var(--fhead,'Fredoka',sans-serif);color:var(--ink,#f4e8d6);z-index:6;">it remembers you 🤍</div> | |
| <!-- emoticon bubble --> | |
| <div id="bubble" style="position:absolute;left:50%;top:18%;transform:translate(-50%,-50%);background:#fff;color:#2a1a0c;border-radius:14px;padding:7px 13px;font-family:var(--fbody,monospace);font-size:17px;font-weight:600;opacity:0;pointer-events:none;z-index:7;box-shadow:0 6px 18px rgba(0,0,0,.25);">·_·</div> | |
| <!-- simlish --> | |
| <div id="simlish" style="position:absolute;left:50%;top:30%;transform:translate(-50%,-50%);color:#fff;font-family:var(--fhead,'Fredoka',sans-serif);font-size:15px;font-weight:600;opacity:0;pointer-events:none;z-index:7;text-shadow:0 2px 6px rgba(20,12,4,.8);white-space:nowrap;"></div> | |
| <!-- hint --> | |
| <div style="position:absolute;bottom:10px;left:50%;transform:translateX(-50%);background:rgba(26,18,11,.66);backdrop-filter:blur(3px);border-radius:999px;padding:6px 14px;font-size:10.5px;color:#f4e8d6;z-index:6;white-space:nowrap;">drag a toy onto <span class="cn">Huggy</span> — he plays with it, then sets it down · click the bowls to fill them · tap <span class="cn">Huggy</span> to pet</div> | |
| </div> | |
| <!-- dock --> | |
| <div style="display:flex;flex-direction:column;gap:9px;"> | |
| <div style="display:flex;gap:9px;align-items:center;background:var(--panel,#2c2016);border:1px solid var(--line,rgba(255,210,140,.16));border-radius:14px;padding:7px 7px 7px 15px;"> | |
| <input id="msg" placeholder="say something to Huggy…" autocomplete="off" style="flex:1;background:none;border:none;outline:none;color:var(--ink,#f4e8d6);font-family:var(--fbody,monospace);font-size:14px;"> | |
| <button id="send" style="cursor:pointer;border:none;background:var(--accent,#ffd21e);color:#1a120b;border-radius:10px;padding:9px 18px;font-family:var(--fhead,'Fredoka',sans-serif);font-weight:700;font-size:13px;">send</button> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- RIGHT: detection + diary --> | |
| <section style="flex:1 1 300px;max-width:368px;min-width:268px;display:flex;flex-direction:column;gap:16px;"> | |
| <div style="background:var(--panel,#2c2016);border:1px solid var(--line,rgba(255,210,140,.16));border-radius:var(--rad,18px);padding:16px;display:flex;flex-direction:column;gap:12px;"> | |
| <div style="font-family:var(--fhead,'Fredoka',sans-serif);font-weight:700;font-size:14px;letter-spacing:.5px;">what it detected</div> | |
| <div style="display:flex;flex-direction:column;gap:6px;"> | |
| <div style="font-size:10px;letter-spacing:1.5px;color:var(--dim,#a9967c);">WORDS · roles</div> | |
| <div id="traceWords" style="display:flex;flex-wrap:wrap;gap:5px;min-height:24px;"> | |
| <span style="font-size:11px;color:var(--dim,#a9967c);">talk to it and the structural read shows up here.</span> | |
| </div> | |
| </div> | |
| <div style="display:flex;flex-direction:column;gap:6px;"> | |
| <div style="font-size:10px;letter-spacing:1.5px;color:var(--dim,#a9967c);">STRUCTURES · <span id="structCount">0</span> of 66 patterns</div> | |
| <div id="traceStructs" style="display:flex;flex-wrap:wrap;gap:5px;min-height:18px;"> | |
| <span style="font-size:11px;color:var(--dim,#a9967c);">— none in this message</span> | |
| </div> | |
| </div> | |
| <div style="display:flex;flex-direction:column;gap:6px;"> | |
| <div style="font-size:10px;letter-spacing:1.5px;color:var(--dim,#a9967c);">TOP CONTRIBUTORS</div> | |
| <div id="traceContribs"></div> | |
| </div> | |
| <!-- why --> | |
| <div data-tip="Every output is explainable — this is the single biggest reason the read landed where it did." style="cursor:help;background:var(--panel2,#1a120b);border-radius:10px;padding:9px 11px;font-size:11px;line-height:1.5;color:var(--ink,#f4e8d6);"> | |
| <span style="color:var(--accent,#ffd21e);font-weight:700;">why:</span> <span id="whyText">say something, give it a toy, or pet it — every read is explainable.</span> | |
| </div> | |
| <!-- crisis gradient --> | |
| <div id="crisisWrap" data-tip="Continuous 0–1 concern gradient informed by the CARE / TCI framework. Tuned for 0% false-positive on safe text, dark humour and metaphor. A screening signal, not a diagnosis." style="cursor:help;display:flex;flex-direction:column;gap:5px;"> | |
| <div style="display:flex;justify-content:space-between;font-size:10px;letter-spacing:1.5px;color:var(--dim,#a9967c);"><span>CRISIS GRADIENT</span><span id="crisisLabel" style="color:#5fd08a;font-weight:600;">calm</span></div> | |
| <div style="height:8px;border-radius:5px;background:var(--panel2,#1a120b);overflow:hidden;"> | |
| <div id="crisisBar" style="height:100%;width:0%;background:#5fd08a;border-radius:5px;transition:width .5s ease,background .5s ease;"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- diary --> | |
| <div style="background:var(--panel,#2c2016);border:1px solid var(--line,rgba(255,210,140,.16));border-radius:var(--rad,18px);padding:16px;display:flex;flex-direction:column;gap:10px;flex:1;min-height:150px;"> | |
| <div style="font-family:var(--fhead,'Fredoka',sans-serif);font-weight:700;font-size:14px;">diary</div> | |
| <div id="diary" style="display:flex;flex-direction:column;gap:8px;overflow-y:auto;max-height:230px;"> | |
| <span style="font-size:11px;color:var(--dim,#a9967c);">moments you share will be remembered here.</span> | |
| </div> | |
| </div> | |
| </section> | |
| </div> | |
| <div style="font-size:10px;color:var(--dim,#a9967c);text-align:center;opacity:.8;">the production Space calls the real clanker engine + clanker-soul on the backend · every read is deterministic and explainable</div> | |
| <!-- floating tooltip --> | |
| <div id="tooltip" style="position:fixed;left:0px;top:0px;max-width:248px;background:#120c06;color:#f4e8d6;border:1px solid rgba(255,210,140,.28);border-radius:10px;padding:9px 12px;font-size:11px;line-height:1.5;font-family:var(--fbody,monospace);pointer-events:none;opacity:0;transform:translateY(-50%);transition:opacity .12s;z-index:90;box-shadow:0 10px 30px rgba(0,0,0,.45);"></div> | |
| </div> | |
| </body></html> | |