Move the Project Thing deck out of the applet; the applet URL redirects to /Thing

The deck's styles move to static/thing/deck.css scoped under .thing-deck,
with guards against base.scss rules that reach into article content. Its
script moves to static/thing/deck.js with the root set to the deck element.
The applet becomes a redirect stub; the post's embed and its 85vh rule go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-02 14:46:23 +02:00
commit 48d7dc9df6
5 changed files with 409 additions and 688 deletions

View file

@ -13,13 +13,3 @@ socialDeck: "Thing renders things."
# Project Thing
The Thing Transformation Office has prepared a board deck on the rename of Eve to Thing. Scroll to realise synergies.
<div class="gamecult-embed-frame">
<iframe
src="/static/applets/project-thing/index.html"
title="Project Thing board deck"
loading="lazy"
></iframe>
</div>
If the embedded version gives you trouble, <a href="/static/applets/project-thing/index.html" data-router-ignore>open the deck directly</a>.

View file

@ -2,680 +2,11 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
<title>Project Thing</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400&family=IBM+Plex+Mono:wght@400;500&display=swap">
<style>
/* Layout: a consulting board deck unrolled into one scroll. Nothing pins the page; every exhibit scrolls naturally while its contents animate in place or in a sticky background layer */
:root{
color-scheme:dark;
--paper:#07111a; --ink:#eef5ff; --ink-2:#b7c7d9; --ink-3:#63758a; --rule:#16212c; --tint:#16212c; --tint-2:rgba(89,183,255,.14);
--accent:#ff8a2a; --accent-ink:#07111a;
--inv:#03070d; --inv-ink:#eef5ff; --inv-2:#b7c7d9; --inv-accent:#59b7ff;
--display:'Montserrat', sans-serif;
--body:'Ubuntu', sans-serif;
--mono:'IBM Plex Mono', ui-monospace, 'Courier New', monospace;
}
*{box-sizing:border-box}
body{margin:0;background:radial-gradient(circle at 78% 14%,rgba(255,138,42,.18),transparent 18%),radial-gradient(circle at 18% 10%,rgba(109,96,255,.16),transparent 24%),radial-gradient(circle at 52% 0%,rgba(89,183,255,.14),transparent 28%),linear-gradient(180deg,#03070d 0%,#07111a 44%,#09141f 100%);color:var(--ink-2);font-family:var(--body);font-weight:300;font-size:18px;line-height:1.55;overflow-x:hidden}
h1,h2,h3{margin:0;text-wrap:balance}
p{margin:0}
.wrap{width:100%;max-width:1160px;margin-inline:auto;padding-inline:clamp(16px,4vw,48px)}
.eyebrow{font-family:var(--mono);font-size:13px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
.src{font-family:var(--mono);font-size:12.5px;color:var(--ink-3);margin-top:28px;max-width:80ch}
.xhead{display:flex;flex-direction:column;gap:14px;padding-bottom:22px;border-bottom:2px solid var(--ink);margin-bottom:clamp(28px,4vh,48px)}
.xhead h2{font-family:var(--display);font-weight:200;color:var(--ink);font-size:clamp(24px,3.1vw,42px);line-height:1.22;max-width:30ch}
.sec{position:relative;overflow-x:clip;padding-block:clamp(88px,14vh,170px)}
b,strong{font-weight:500}
/* reveals: visible at rest, scrubbed by --r */
[data-reveal]{--r:1;opacity:calc(.25 + .75*var(--r));transform:translateY(calc((1 - var(--r))*60px))}
[data-reveal="left"]{transform:translateX(calc((1 - var(--r))*-90px))}
[data-reveal="right"]{transform:translateX(calc((1 - var(--r))*90px))}
[data-reveal="pop"]{transform:scale(calc(.82 + .18*var(--r))) rotate(calc((1 - var(--r))*-4deg))}
/* HUD */
.hud-bar{position:fixed;left:0;right:0;top:env(safe-area-inset-top,0px);height:3px;z-index:50;pointer-events:none}
.hud-bar i{display:block;height:100%;background:var(--accent);transform-origin:left;transform:scaleX(var(--prog,0))}
.hud-pill{position:fixed;right:clamp(12px,2vw,24px);bottom:calc(14px + env(safe-area-inset-bottom,0px));z-index:50;display:flex;gap:14px;font-family:var(--mono);font-size:12px;background:var(--ink);color:var(--paper);padding:8px 14px;border-radius:999px;pointer-events:none;font-variant-numeric:tabular-nums;box-shadow:0 6px 24px rgba(0,0,0,.45)}
.hud-pill b{color:var(--paper);font-weight:500}
/* HERO: one screen */
.stage{position:relative;height:100vh;height:calc(100svh - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px));overflow:hidden;display:flex;flex-direction:column;justify-content:center;background:var(--inv);color:var(--inv-ink)}
.hero-bg{position:absolute;inset:0;background:radial-gradient(ellipse at 50% 55%, var(--accent), transparent 60%);opacity:.3;animation:pulse 3.2s ease-in-out 2s infinite}
@keyframes pulse{50%{filter:brightness(1.35)}}
.rays{position:absolute;left:50%;top:55%;width:220vmax;height:220vmax;margin:-110vmax 0 0 -110vmax;background:repeating-conic-gradient(from 0deg, var(--inv-accent) 0deg 4deg, transparent 4deg 15deg);-webkit-mask-image:radial-gradient(circle, #000 6%, transparent 42%);mask-image:radial-gradient(circle, #000 6%, transparent 42%);opacity:0;animation:rayin .9s ease-out 2s forwards, spin 70s linear 2s infinite}
@keyframes rayin{to{opacity:.16}}
@keyframes spin{to{transform:rotate(360deg)}}
#burst{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:3}
.flash{position:absolute;inset:0;background:var(--inv-ink);opacity:0;pointer-events:none;z-index:4;animation:flash .7s ease-out 2s both}
@keyframes flash{0%{opacity:0}8%{opacity:.92}100%{opacity:0}}
.hero-in{position:relative;z-index:2;display:flex;flex-direction:column;gap:clamp(12px,2.2vh,24px)}
.hero-in.shake{animation:shake .32s cubic-bezier(.36,.07,.19,.97)}
.hero-in.shake-big{animation:shakebig .7s cubic-bezier(.36,.07,.19,.97)}
@keyframes shake{20%{transform:translate(-6px,4px)}40%{transform:translate(7px,-5px)}60%{transform:translate(-4px,-3px)}80%{transform:translate(3px,4px)}}
@keyframes shakebig{10%{transform:translate(-18px,10px) rotate(-.6deg)}25%{transform:translate(16px,-14px) rotate(.5deg)}40%{transform:translate(-12px,-8px)}55%{transform:translate(10px,10px) rotate(-.3deg)}70%{transform:translate(-6px,4px)}85%{transform:translate(3px,-3px)}}
.fade{display:block}
.in{animation:rise .6s cubic-bezier(.2,.8,.2,1) var(--d,0s) both}
@keyframes rise{from{opacity:0;transform:translateY(18px)}}
.hero .eyebrow{color:var(--inv-accent)}
.was{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 16px;font-family:var(--display);font-weight:300;font-size:clamp(22px,3vw,34px);color:var(--inv-2)}
.strike{position:relative;text-decoration:none}
.strike::after{content:"";position:absolute;left:-4%;right:-4%;top:52%;height:4px;background:var(--inv-accent);transform-origin:left;animation:strike .45s cubic-bezier(.7,0,.3,1) .65s both}
@keyframes strike{from{transform:scaleX(0)}}
.was span{font-family:var(--mono);font-size:12.5px;letter-spacing:.06em;text-transform:uppercase}
.hero h1{font-family:var(--display);font-weight:200;line-height:.9;display:flex;flex-direction:column}
.proj{display:block;font-style:normal;font-weight:100;font-size:clamp(30px,5vw,64px);color:var(--inv-2)}
.letters{font-size:clamp(96px,22vw,300px);letter-spacing:-.02em;white-space:nowrap;font-weight:100}
.l{display:inline-block}
.li{display:inline-block;animation:slam .42s cubic-bezier(.6,0,1,.5) var(--d) both}
@keyframes slam{0%{opacity:0;transform:scale(7) translateY(-12%);filter:blur(14px)}60%{opacity:1}100%{opacity:1;transform:none;filter:none}}
.hero-sub{font-size:clamp(18px,2vw,24px);line-height:1.45;max-width:46ch;color:var(--inv-2)}
.cue{font-family:var(--mono);font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--inv-accent);display:flex;gap:10px;align-items:center}
.cue::after{content:"↓";animation:bob 1.6s ease-in-out infinite}
@keyframes bob{50%{transform:translateY(6px)}}
.ring{position:absolute;width:40px;height:40px;margin:-20px 0 0 -20px;border:3px solid var(--inv-accent);border-radius:50%;pointer-events:none;z-index:1;animation:ring .7s ease-out forwards}
.ring.big{border-width:8px;border-color:var(--inv-ink);animation:ringbig 1.2s cubic-bezier(.1,.7,.3,1) forwards}
@keyframes ring{from{transform:scale(.3);opacity:1}to{transform:scale(12);opacity:0}}
@keyframes ringbig{from{transform:scale(.3);opacity:1}to{transform:scale(70);opacity:0}}
.ticker-w{position:absolute;left:-4vw;right:-4vw;bottom:56px;z-index:2;transform:rotate(-2deg)}
.ticker{background:var(--accent);color:var(--accent-ink);overflow:hidden;white-space:nowrap;font-family:var(--mono);font-weight:500;font-size:14px;letter-spacing:.12em;text-transform:uppercase;padding-block:10px;animation-name:tkin;animation-duration:.6s}
@keyframes tkin{from{transform:translateY(160%) skewY(4deg);opacity:0}}
.tk{display:inline-block;animation:marquee 38s linear infinite}
.tk span{padding-inline:22px}
@keyframes marquee{to{transform:translateX(-50%)}}
.conf{position:absolute;left:0;right:0;bottom:16px;z-index:2;text-align:center;font-family:var(--mono);font-size:12px;color:var(--ink-3);padding-inline:16px}
/* SUMMARY */
.scr{display:flex;flex-direction:column}
.scr-row{display:grid;grid-template-columns:220px minmax(0,1fr);gap:16px 40px;padding-block:26px;border-bottom:1px solid var(--rule)}
.scr-row:last-child{border-bottom:0}
.scr-k{font-family:var(--mono);font-size:13px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);padding-top:6px}
.scr-row p:last-child{font-size:clamp(19px,2vw,24px);line-height:1.5;max-width:58ch}
.scr-row.res{background:var(--tint);padding-inline:24px;border-radius:4px}
/* STATS */
.stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.stat{background:var(--tint);padding:clamp(24px,3vw,40px);border-radius:4px;display:flex;flex-direction:column;gap:10px}
.num{font-family:var(--display);font-weight:200;font-size:clamp(84px,10vw,140px);line-height:1;color:var(--ink);font-variant-numeric:tabular-nums}
.stat p:last-child{color:var(--ink-2);font-size:17px;max-width:28ch}
.sowhat{margin-top:32px;font-size:clamp(19px,2vw,24px);max-width:60ch}
/* QUADRANT */
.matrix{--p:1;position:relative;width:100%;height:clamp(300px,56vh,560px);background:linear-gradient(var(--rule),var(--rule)) 50% 0/1px 100% no-repeat,linear-gradient(var(--rule),var(--rule)) 0 50%/100% 1px no-repeat}
.axis{position:absolute;background:var(--ink)}
.axis.x{left:0;right:0;bottom:0;height:2px;transform-origin:left;transform:scaleX(min(1,calc(var(--p)*5)))}
.axis.y{left:0;top:0;bottom:0;width:2px;transform-origin:bottom;transform:scaleY(min(1,calc(var(--p)*5)))}
.ax{position:absolute;font-family:var(--mono);font-size:12.5px;color:var(--ink-3);letter-spacing:.04em}
.ax-y{left:12px;top:6px}
.ax-x{right:4px;bottom:10px}
.chip{--k:1;position:absolute;left:calc(50% + (var(--fx) - 50%)*var(--k));top:calc(50% + (var(--fy) - 50%)*var(--k));transform:translate(-50%,-50%) rotate(calc((1 - var(--k))*24deg)) scale(calc(.7 + .3*var(--k)));background:var(--paper);border:2px solid var(--ink);padding:12px 18px;border-radius:4px;display:flex;flex-direction:column;gap:2px;width:min(38%,300px);box-shadow:0 8px 30px rgba(0,0,0,.45)}
.chip strong{font-family:var(--display);font-weight:300;font-size:clamp(17px,2vw,24px)}
.chip span{font-size:15px;color:var(--ink-2);line-height:1.35}
.chip.hot{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);transform:translate(-50%,-50%) rotate(calc((1 - var(--k))*-30deg)) scale(calc(.5 + .65*var(--k)));z-index:2}
.chip.hot span{color:var(--accent-ink)}
.stamp{--k:1;position:absolute;left:84%;top:8%;z-index:3;font-family:var(--mono);font-weight:500;font-size:clamp(13px,1.6vw,18px);letter-spacing:.2em;text-transform:uppercase;color:var(--accent);border:3px solid var(--accent);padding:6px 12px;background:var(--paper);opacity:var(--k);transform:translate(-50%,-50%) rotate(-12deg) scale(calc(3.4 - 2.4*var(--k)))}
/* ETYMOLOGY */
.etym{background:var(--tint);overflow:hidden}
.bigthorn{position:absolute;right:-6vw;top:50%;font-family:var(--display);font-size:90vh;line-height:1;color:var(--ink);opacity:.06;transform:translate(calc(var(--p,0)*-40vw),-50%);pointer-events:none}
.viewport{overflow-x:auto;padding-block:8px}
.etym.scrub .viewport{overflow:visible}
.track{display:flex;gap:20px;align-items:stretch;transform:translateX(calc(var(--p,0)*var(--shift,0px)*-1));will-change:transform;width:max-content}
.ecard{flex:0 0 min(78vw,400px);background:var(--paper);border-radius:4px;padding:clamp(24px,3vw,40px);display:flex;flex-direction:column;gap:12px;border:1px solid var(--rule)}
.ecard .w{font-family:var(--display);font-weight:200;color:var(--ink);font-size:clamp(64px,8vw,112px);line-height:1}
.ecard p:last-child{color:var(--ink-2);font-size:18px}
.earrow{align-self:center;font-family:var(--display);font-weight:300;font-size:56px;color:var(--accent)}
.ecard.impl{flex-basis:min(86vw,560px);background:var(--inv);color:var(--inv-ink);border-color:var(--inv);justify-content:center}
.ecard.impl .eyebrow{color:var(--inv-accent)}
.ecard.impl p:last-child{color:var(--inv-ink);font-size:clamp(19px,2vw,23px);line-height:1.5}
/* DIVINITY */
.div-grid{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:48px;align-items:start}
.tbl{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:17px;min-width:560px}
th{text-align:left;font-family:var(--mono);font-size:12.5px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);padding:10px 12px;border-bottom:2px solid var(--ink)}
td{padding:14px 12px;border-bottom:1px solid var(--rule);vertical-align:top}
tr.lit td{background:var(--accent);color:var(--accent-ink);font-weight:500}
tr.strike td{position:relative;color:var(--ink-2)}
tr.strike td::after{content:"";position:absolute;left:0;right:0;top:50%;height:2px;background:var(--accent);transform-origin:left;transform:scaleX(var(--strike,1))}
.meter{position:sticky;top:22vh;display:flex;flex-direction:column;gap:14px;border-top:2px solid var(--ink);padding-top:18px}
.div-big{font-family:var(--display);font-weight:200;color:var(--ink);font-size:clamp(64px,7vw,96px);line-height:1;font-variant-numeric:tabular-nums}
.gauge{height:14px;background:var(--tint);border-radius:999px;overflow:hidden}
.gauge div{height:100%;width:100%;background:var(--accent);transform-origin:left;transform:scaleX(var(--fill,.357))}
.meter-note{font-family:var(--mono);font-size:12.5px;color:var(--ink-3)}
/* TAM: sticky background, foreground scrolls over it */
.tam{position:relative}
.tam-bg,.st-bg{position:absolute;inset:0;pointer-events:none}
.bg-in{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden}
.tam-fg{position:relative;z-index:1}
.orbit{position:absolute;left:50%;top:50%;border-radius:50%;transform:translate(-50%,-50%) scale(var(--c,1));display:flex;justify-content:center;will-change:transform}
.o1{width:70vmin;height:70vmin;background:var(--tint)}
.o2{width:48vmin;height:48vmin;background:var(--tint-2)}
.o3{width:22vmin;height:22vmin;background:var(--accent);color:var(--accent-ink);align-items:center}
.orbit p{font-family:var(--mono);font-size:clamp(11px,1.3vw,14px);letter-spacing:.08em;text-transform:uppercase;text-align:center;line-height:1.4}
.o1 p{margin-top:5%}
.o2 p{margin-top:7%}
.o3 p{opacity:calc(1 - var(--g,0)*5)}
.orbit p b{display:block;font-family:var(--display);text-transform:none;letter-spacing:0;font-size:clamp(14px,1.8vw,20px)}
.tam-head{padding-top:clamp(72px,12vh,140px)}
.tam-head .xhead{border-bottom:0;margin:0}
.tam-cap{min-height:78vh;display:flex;align-items:center;justify-content:center;padding-inline:16px}
.caption{font-family:var(--display);font-weight:200;font-size:clamp(24px,3.6vw,46px);text-align:center;text-wrap:balance;background:var(--paper);color:var(--ink);padding:18px 30px;border-radius:4px;box-shadow:0 12px 40px rgba(0,0,0,.45);max-width:22ch}
.pen{position:absolute;left:50%;bottom:calc(64px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);font-family:var(--mono);font-size:13px;background:var(--ink);color:var(--paper);padding:8px 16px;border-radius:999px;opacity:min(1,calc(var(--g,0)*8));font-variant-numeric:tabular-nums;white-space:nowrap}
.tam-final{min-height:115vh;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:20px;text-align:center;color:var(--accent-ink);opacity:var(--fo,1);padding-inline:16px}
.tam-final h3{font-family:var(--display);font-weight:200;font-size:clamp(34px,6vw,84px);line-height:1.1;max-width:16ch}
.tam-final p{font-family:var(--mono);font-size:14px;letter-spacing:.14em;text-transform:uppercase}
/* TAXONOMY */
.tax{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:48px;align-items:start}
.tiers{display:flex;flex-direction:column;gap:14px}
.tier{display:grid;grid-template-columns:150px minmax(0,1fr);gap:20px;align-items:center;padding:22px;border-radius:4px;background:var(--tint)}
.tier h3{font-family:var(--display);font-weight:300;color:var(--ink);font-size:clamp(24px,2.4vw,30px)}
.tier.t1{background:var(--inv);color:var(--inv-ink)}
.tier.t1 p{color:var(--inv-2)}
.tier p{color:var(--ink-2)}
.rename{min-width:0}
.rename td{font-family:var(--mono);font-size:16px}
.mx{display:inline-grid;overflow:hidden;vertical-align:bottom;justify-items:end}
.mx.l{justify-items:start}
.mx>span{grid-area:1/1}
.mx .o{transform:translateY(calc(var(--f,1)*-110%));opacity:calc(1 - var(--f,1))}
.mx .n{transform:translateY(calc((1 - var(--f,1))*110%));opacity:var(--f,1);color:var(--accent);font-weight:500}
.status .o{color:var(--ink-2)}
/* WATERFALL */
.wfhead{display:flex;justify-content:space-between;align-items:end;gap:24px;flex-wrap:wrap}
.tpsbig{font-family:var(--display);font-weight:200;font-size:clamp(48px,7vw,92px);line-height:1;color:var(--accent);font-variant-numeric:tabular-nums}
.tpsbig small{font-family:var(--mono);font-size:13px;letter-spacing:.12em;color:var(--ink-2);font-weight:400;margin-left:8px}
.wf{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));height:clamp(200px,38vh,420px);border-bottom:2px solid var(--ink);margin-top:20px}
.col{--k:1;position:relative}
.bar{position:absolute;left:16%;right:16%;bottom:calc(var(--base)*20%);height:calc(var(--k)*var(--u,1)*20%);background:var(--accent)}
.col.total .bar{background:var(--ink)}
.col.zero .bar{height:3px;background:var(--ink-2)}
.v{position:absolute;left:0;right:0;text-align:center;bottom:calc((var(--base) + var(--k)*var(--u,1))*20% + 8px);font-family:var(--mono);font-weight:500;font-size:clamp(13px,1.6vw,18px);opacity:min(1,calc(var(--k)*3))}
.wfl{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:8px;margin-top:12px}
.wfl p{font-size:clamp(12px,1.35vw,15px);line-height:1.35;color:var(--ink-2);text-align:center}
.wfl p:last-child{color:var(--ink);font-weight:500}
.example{margin-top:22px;font-size:clamp(17px,1.9vw,22px)}
.t{background:transparent;color:inherit;padding:0 3px;border-radius:3px}
.t.on{background:var(--accent);color:var(--accent-ink)}
/* RISKS */
.risks td:nth-child(2),.risks td:nth-child(3){font-family:var(--mono);font-size:15px}
.upside{display:inline-block;font-family:var(--mono);font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent);border:2px solid var(--accent);padding:3px 8px;margin-left:10px;transform:rotate(-8deg) scale(calc(2.6 - 1.6*var(--r,1)));opacity:var(--r,1)}
/* STATEMENT: sticky canvas behind, text scrolls over */
.statement{position:relative;background:var(--inv);color:var(--inv-ink)}
#things{position:absolute;inset:0;width:100%;height:100%}
.scrim{position:absolute;inset:0;background:radial-gradient(ellipse 75% 55% at 35% 50%, var(--inv) 15%, transparent 75%);opacity:.75}
.st-count{position:absolute;left:clamp(16px,4vw,48px);bottom:calc(24px + env(safe-area-inset-bottom,0px));font-family:var(--mono);font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--inv-accent);font-variant-numeric:tabular-nums}
.st-fg{position:relative;z-index:1;display:flex;flex-direction:column;gap:24px;padding-block:65vh 75vh}
.st-fg .eyebrow{color:var(--inv-accent)}
.st-fg h2{font-family:var(--display);font-weight:200;font-size:clamp(64px,12vw,176px);line-height:1.02;text-shadow:0 2px 40px var(--inv),0 0 12px var(--inv)}
.st-fg p{font-size:clamp(18px,2vw,24px);color:var(--inv-2);max-width:44ch;text-shadow:0 0 12px var(--inv)}
/* ROADMAP */
.waves{position:relative;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;padding-top:30px}
.waves::before{content:"";position:absolute;left:0;right:0;top:8px;height:3px;background:var(--accent);transform-origin:left;transform:scaleX(var(--r,1))}
.wave{position:relative;background:var(--tint);padding:clamp(24px,3vw,36px);border-radius:4px;display:flex;flex-direction:column;gap:12px}
.wave::before{content:"";position:absolute;left:clamp(24px,3vw,36px);top:-29px;width:16px;height:16px;border-radius:50%;background:var(--paper);border:3px solid var(--accent)}
.wave h3{font-family:var(--display);font-weight:300;color:var(--ink);font-size:clamp(22px,2.2vw,28px)}
.wave ul{margin:0;padding-left:20px;color:var(--ink-2);display:flex;flex-direction:column;gap:8px}
.close{background:var(--inv);color:var(--inv-ink);padding-block:clamp(96px,16vh,180px)}
.close h2{font-family:var(--display);font-weight:200;font-size:clamp(44px,8vw,112px);line-height:1.05}
.close h2 i{font-style:normal;font-weight:100;color:var(--inv-accent)}
.close p{font-family:var(--mono);font-size:12.5px;color:var(--inv-2);margin-top:40px;max-width:70ch}
@media (max-width:760px){
.scr-row{grid-template-columns:1fr;gap:6px}
.stats,.waves,.tax,.div-grid{grid-template-columns:1fr}
.meter{position:static;order:-1}
.chip span{display:none}
.chip{width:auto;padding:8px 12px}
.stamp{left:72%;top:6%}
.tier{grid-template-columns:1fr;gap:6px}
.wfl p{font-size:11.5px}
.hud-pill{font-size:10.5px;gap:8px;padding:5px 10px;top:calc(10px + env(safe-area-inset-top,0px));bottom:auto;right:10px;opacity:.92}
.pen{bottom:calc(28px + env(safe-area-inset-bottom,0px))}
.ticker{font-size:12px}
}
/* reduced motion: everything in its finished, readable state */
.rm .stage{height:auto;min-height:88vh;padding-block:96px 160px}
.rm .in,.rm .li,.rm .strike::after,.rm .ticker,.rm .tk,.rm .flash,.rm .hero-bg,.rm .cue::after{animation:none!important}
.rm .rays{animation:none;opacity:.12}
.rm .flash{opacity:0}
</style>
<meta http-equiv="refresh" content="0; url=/Thing">
<link rel="canonical" href="https://gamecult.org/Thing">
</head>
<body>
<div class="hud-bar" aria-hidden="true"><i></i></div>
<div class="hud-pill" aria-hidden="true"><span>Synergy realised <b class="syn">0%</b></span><span>Live TPS <b class="tps">0</b></span></div>
<!-- HERO -->
<section class="hero">
<div class="stage">
<div class="hero-bg" aria-hidden="true"></div>
<div class="rays" aria-hidden="true"></div>
<div class="wrap hero-in">
<div class="fade"><p class="eyebrow in" style="--d:.1s">Thing Transformation Office · Board discussion document · October 2026</p></div>
<div class="fade"><p class="was in" style="--d:.3s"><span class="strike">Project Eve</span><span>Deprecated: based on a copyrighted character</span></p></div>
<h1 aria-label="Project THING"><span class="fade" aria-hidden="true"><span class="proj in" style="--d:.85s">Project</span></span><span class="letters" aria-hidden="true"><span class="l"><span class="li" style="--d:1s">T</span></span><span class="l"><span class="li" style="--d:1.13s">H</span></span><span class="l"><span class="li" style="--d:1.26s">I</span></span><span class="l"><span class="li" style="--d:1.39s">N</span></span><span class="l"><span class="li" style="--d:1.52s">G</span></span></span></h1>
<div class="fade"><p class="hero-sub in" style="--d:2.25s">Reframing the semantic surface value chain through an etymologically grounded, deity-light naming architecture</p></div>
<div class="fade"><p class="cue in" style="--d:2.5s">Scroll to realise synergies</p></div>
</div>
<div class="fade ticker-w" aria-hidden="true"><div class="ticker in" style="--d:2.1s"><div class="tk"><span>Breaking: Eve deprecated</span><span>◆</span><span>Thing announced</span><span>◆</span><span>Analysts confirm it is a thing</span><span>◆</span><span>Persona divinity down 28.6%</span><span>◆</span><span>TPS up from 0 to 4</span><span>◆</span><span>Your thing can now talk to Thing</span><span>◆</span><span>Full penetration expected</span><span>◆</span><span>Breaking: Eve deprecated</span><span>◆</span><span>Thing announced</span><span>◆</span><span>Analysts confirm it is a thing</span><span>◆</span><span>Persona divinity down 28.6%</span><span>◆</span><span>TPS up from 0 to 4</span><span>◆</span><span>Your thing can now talk to Thing</span><span>◆</span><span>Full penetration expected</span><span>◆</span></div></div></div>
<div class="fade"><p class="conf">Confidential and proprietary. Unauthorised use will be referred to Thing.</p></div>
<canvas id="burst" aria-hidden="true"></canvas>
<div class="flash" aria-hidden="true"></div>
</div>
</section>
<!-- SUMMARY -->
<section class="sec">
<div class="wrap">
<header class="xhead">
<p class="eyebrow">Executive summary</p>
<h2>Renaming Eve to Thing removes IP exposure and unlocks a deity-light Nordic naming moat</h2>
</header>
<div class="scr">
<div class="scr-row" data-reveal="left"><p class="scr-k">Situation</p><p>Eve owns the portable semantic interface contract and a seven-repo renderer family. Users love her. Lawyers have questions.</p></div>
<div class="scr-row" data-reveal="left" data-delay="1"><p class="scr-k">Complication</p><p>Eve is based on a copyrighted character. The obvious Nordic alternative, Freyja, would add yet another god to an already god-saturated portfolio.</p></div>
<div class="scr-row res" data-reveal="left" data-delay="2"><p class="scr-k">Resolution</p><p>Rename to <b>Thing</b>, from Old Norse <i>þing</i>, the assembly. Everything can have a Thing. Your thing can talk to Thing. Thing renders things.</p></div>
</div>
<p class="src">Source: GameCult team analysis</p>
</div>
</section>
<!-- EXHIBIT 1 -->
<section class="sec" style="padding-top:0">
<div class="wrap">
<header class="xhead">
<p class="eyebrow">Exhibit 1 · Current state</p>
<h2>Eve's name carries IP exposure across eight repositories and sits outside the Nordic portfolio</h2>
</header>
<div class="stats">
<div class="stat" data-reveal="pop"><p class="num" data-count="1">1</p><p>copyrighted character underpinning the current brand</p></div>
<div class="stat" data-reveal="pop" data-delay="1"><p class="num" data-count="8">8</p><p>repositories carrying the name, from Eve to AetheriaEve</p></div>
<div class="stat" data-reveal="pop" data-delay="2"><p class="num" data-count="0" data-spin>0</p><p>gods involved, a strength the recommended option preserves</p></div>
</div>
<p class="sowhat"><b>So what:</b> the rename is unavoidable. The only open question is how Norse it should be.</p>
<p class="src">Source: GameCult Projects directory; GameCult legal instinct</p>
</div>
</section>
<!-- EXHIBIT 2 -->
<section class="sec" style="padding-top:0">
<div class="wrap">
<header class="xhead">
<p class="eyebrow">Exhibit 2 · Options assessment</p>
<h2>Of the four options assessed, only Thing sits in the upper-right quadrant</h2>
</header>
<div class="matrix">
<div class="axis y"></div><div class="axis x"></div>
<p class="ax ax-y">↑ Deity fatigue mitigation</p>
<p class="ax ax-x">Etymological rigour →</p>
<div class="chip" data-start="0.05" style="--fx:25%;--fy:75%"><strong class="cn">Eve</strong><span>Status quo. Copyrighted. Not Norse.</span></div>
<div class="chip" data-start="0.2" style="--fx:75%;--fy:75%"><strong class="cn">Freyja</strong><span>Impeccable lineage. Yet another god.</span></div>
<div class="chip" data-start="0.35" style="--fx:25%;--fy:25%"><strong class="cn">CultUI</strong><span>Implies Libby owns it. Says "UI".</span></div>
<div class="chip hot" data-start="0.55" style="--fx:72%;--fy:28%"><strong class="cn">Thing</strong><span>An institution, not a god. Funny in every sentence.</span></div>
<div class="stamp" data-start="0.8">Recommended</div>
</div>
<p class="src">Axes selected after the recommendation was finalised, in line with industry best practice.</p>
</div>
</section>
<!-- EXHIBIT 3 -->
<section class="sec etym">
<div class="bigthorn" aria-hidden="true">þ</div>
<div class="wrap" style="position:relative">
<header class="xhead">
<p class="eyebrow">Exhibit 3 · Due diligence</p>
<h2>Thing's etymology has been independently verified by anyone who owns a dictionary</h2>
</header>
<div class="viewport">
<div class="track">
<div class="ecard"><p class="eyebrow">Proto-Germanic</p><p class="w">*þingą</p><p>An appointed time; a meeting</p></div>
<div class="earrow" aria-hidden="true">→</div>
<div class="ecard"><p class="eyebrow">Old Norse</p><p class="w">þing</p><p>The assembly where free people met and accepted rulings</p></div>
<div class="earrow" aria-hidden="true">→</div>
<div class="ecard"><p class="eyebrow">Old English</p><p class="w">þing</p><p>The assembly, then the matter brought before it</p></div>
<div class="earrow" aria-hidden="true">→</div>
<div class="ecard"><p class="eyebrow">Modern English</p><p class="w">thing</p><p>Anything at all, which is the point</p></div>
<div class="earrow" aria-hidden="true">→</div>
<div class="ecard impl"><p class="eyebrow">Implication</p><p>A þing is where parties meet one shared state and submit matters for acceptance. Eve already does this. We are not renaming the product. We are confessing it.</p></div>
</div>
</div>
<p class="src">Source: any etymological dictionary; cf. Althing (Iceland, est. 930), Storting, Folketing</p>
</div>
</section>
<!-- EXHIBIT 4 -->
<section class="sec" data-divinity>
<div class="wrap">
<header class="xhead">
<p class="eyebrow">Exhibit 4 · Portfolio fit</p>
<h2>Thing becomes the portfolio's first institution, materially reducing average Persona divinity</h2>
</header>
<div class="div-grid">
<div class="tbl">
<table>
<tr><th>Persona</th><th>Mythic referent</th><th>Divine?</th><th>Assessment</th></tr>
<tr data-reveal="left"><td>Odin</td><td>The all-father</td><td>Yes</td><td>Already watching</td></tr>
<tr data-reveal="left"><td>Heimdall</td><td>Watchman of the gods</td><td>Yes</td><td>Difficult to bribe</td></tr>
<tr data-reveal="left"><td>Mimir</td><td>Severed oracular head</td><td>Debatable</td><td>Reports to Odin</td></tr>
<tr data-reveal="left"><td>Ymir</td><td>Primordial giant</td><td>No (worse)</td><td>Body became the world</td></tr>
<tr data-reveal="left"><td>Bifrost</td><td>Rainbow bridge</td><td>No</td><td>Infrastructure</td></tr>
<tr data-reveal="left"><td>Fensalir</td><td>Frigg's hall</td><td>No</td><td>Real estate</td></tr>
<tr data-reveal="left" class="thingrow"><td>Thing</td><td>The assembly</td><td>No</td><td>Where everyone meets</td></tr>
<tr data-reveal="left" class="strike"><td>Freyja</td><td>Goddess</td><td>Yes</td><td>Declined: fatigue</td></tr>
</table>
</div>
<aside class="meter">
<p class="eyebrow">Average Persona divinity</p>
<p class="div-big"><span class="div-n">35.7</span>%</p>
<div class="gauge"><div></div></div>
<p class="meter-note">Freyja scenario 50.0% → Thing scenario 35.7%</p>
</aside>
</div>
<p class="src">Method: Yes = 1, Debatable = 0.5, No = 0, averaged over seven Personas including the new name. Ymir scores 0 despite being worse. Sources: Poetic Edda; Prose Edda; GameCult Projects directory.</p>
</div>
</section>
<!-- EXHIBIT 5 -->
<section class="tam" data-tam>
<div class="tam-bg" aria-hidden="true"><div class="bg-in">
<div class="orbit o1"><p>TAM<b>All things</b></p></div>
<div class="orbit o2"><p>SAM<b>Things with a Thing</b></p></div>
<div class="orbit o3"><p>SOM<b>Talking to Thing</b></p></div>
<p class="pen">Market penetration: <span class="pen-n">0</span>%</p>
</div></div>
<div class="tam-fg">
<div class="wrap tam-head"><header class="xhead">
<p class="eyebrow">Exhibit 5 · Vision and market sizing</p>
<h2>Thing is the future of all things</h2>
</header></div>
<div class="tam-cap"><p class="caption">Everything can have a Thing.</p></div>
<div class="tam-cap"><p class="caption">Your thing can talk to Thing.</p></div>
<div class="tam-cap"><p class="caption">Thing is the future of all things.</p></div>
<div class="tam-final"><p>Long-term ambition</p><h3>Full penetration of the addressable thing market</h3><p>Penetration: 100%</p></div>
</div>
</section>
<!-- EXHIBIT 6 -->
<section class="sec">
<div class="wrap">
<header class="xhead">
<p class="eyebrow">Exhibit 6 · Nomenclature architecture</p>
<h2>A three-tier Thing taxonomy drives MECE clarity across the Thing portfolio</h2>
</header>
<div class="tax">
<div class="tiers">
<div class="tier t1" data-reveal="left"><h3>Thing</h3><p>The contract and renderer family. Capitalised, singular, load-bearing.</p></div>
<div class="tier" data-reveal="left" data-delay="1"><h3>a Thing</h3><p>One provider's surface. Everything can have one. "Open the Stonks Thing."</p></div>
<div class="tier" data-reveal="left" data-delay="2"><h3>a thing</h3><p>Everything else. Can talk to Thing. Out of internal comms by Q3.</p></div>
</div>
<div class="tbl rename">
<table style="min-width:0">
<tr><th>Repository</th><th>Status</th></tr>
<tr data-reveal><td><span class="mx"><span class="o">Eve</span><span class="n">Thing</span></span></td><td class="status"><span class="mx l"><span class="o">Pending</span><span class="n">Thing-ified</span></span></td></tr>
<tr data-reveal><td><span class="mx"><span class="o">Eve</span><span class="n">Thing</span></span>Unity</td><td class="status"><span class="mx l"><span class="o">Pending</span><span class="n">Thing-ified</span></span></td></tr>
<tr data-reveal><td><span class="mx"><span class="o">Eve</span><span class="n">Thing</span></span>Flutter</td><td class="status"><span class="mx l"><span class="o">Pending</span><span class="n">Thing-ified</span></span></td></tr>
<tr data-reveal><td><span class="mx"><span class="o">Eve</span><span class="n">Thing</span></span>Electron</td><td class="status"><span class="mx l"><span class="o">Pending</span><span class="n">Thing-ified</span></span></td></tr>
<tr data-reveal><td><span class="mx"><span class="o">Eve</span><span class="n">Thing</span></span>Tui</td><td class="status"><span class="mx l"><span class="o">Pending</span><span class="n">Thing-ified</span></span></td></tr>
<tr data-reveal><td><span class="mx"><span class="o">Eve</span><span class="n">Thing</span></span>Plugins</td><td class="status"><span class="mx l"><span class="o">Pending</span><span class="n">Thing-ified</span></span></td></tr>
<tr data-reveal><td><span class="mx"><span class="o">Eve</span><span class="n">Thing</span></span>Conformance</td><td class="status"><span class="mx l"><span class="o">Pending</span><span class="n">Thing-ified</span></span></td></tr>
<tr data-reveal><td>Aetheria<span class="mx l"><span class="o">Eve</span><span class="n">Thing</span></span></td><td class="status"><span class="mx l"><span class="o">Archived</span><span class="n">Thing-ified posthumously</span></span></td></tr>
</table>
</div>
</div>
<p class="src">Source: GameCult GitHub organisation; Thing Transformation Office style guide (draft)</p>
</div>
</section>
<!-- EXHIBIT 7 -->
<section class="sec" style="padding-top:0" data-wf>
<div class="wrap">
<header class="xhead">
<p class="eyebrow">Exhibit 7 · Value bridge</p>
<div class="wfhead">
<h2>Things per Sentence (TPS) rises from zero to four, driven primarily by surface-level synergies</h2>
<p class="tpsbig"><span class="tps-n">4</span><small>TPS</small></p>
</div>
</header>
<div class="wf">
<div class="col zero" style="--base:0;--u:0"><div class="bar"></div><span class="v">0</span></div>
<div class="col" style="--base:0"><div class="bar" data-i="0"></div><span class="v">+1</span></div>
<div class="col" style="--base:1"><div class="bar" data-i="1"></div><span class="v">+1</span></div>
<div class="col" style="--base:2"><div class="bar" data-i="2"></div><span class="v">+1</span></div>
<div class="col" style="--base:3"><div class="bar" data-i="3"></div><span class="v">+1</span></div>
<div class="col total" style="--base:0;--u:4"><div class="bar" data-i="4"></div><span class="v">4</span></div>
</div>
<div class="wfl">
<p>Baseline: "Eve renders surfaces"</p>
<p>Contract renamed Thing</p>
<p>Surfaces become Things</p>
<p>Renderers become ThingFlutter et al.</p>
<p>Your thing talks to Thing</p>
<p>Post-rebrand TPS</p>
</div>
<p class="example"><b>Worked example:</b> "The <mark class="t on" data-i="1">Thing</mark> team ships <mark class="t on" data-i="2">Things</mark> to <mark class="t on" data-i="3">ThingFlutter</mark>, which is a <mark class="t on" data-i="4">thing</mark>."</p>
<p class="src">Source: GameCult team analysis; reading this exhibit aloud. Baseline assumes "surface" is not a thing.</p>
</div>
</section>
<!-- EXHIBIT 8 -->
<section class="sec" style="padding-top:0">
<div class="wrap">
<header class="xhead">
<p class="eyebrow">Exhibit 8 · Risk register</p>
<h2>All material risks are manageable, and one has been reclassified as an upside</h2>
</header>
<div class="tbl risks">
<table>
<tr><th>Risk</th><th>Likelihood</th><th>Impact</th><th>Mitigation</th></tr>
<tr data-reveal="right"><td>Searchability approaches zero</td><td>Certain</td><td>Low</td><td>Users arrive via GameCult tooling</td></tr>
<tr data-reveal="right"><td>Marvel adjacency</td><td>Medium</td><td>Medium</td><td>Portrait to contain no orange rock</td></tr>
<tr data-reveal="right"><td>Addams Family adjacency</td><td>Medium</td><td>High</td><td>Persona must have at least one arm</td></tr>
<tr data-reveal="right"><td>Dr. Seuss adjacency</td><td>High</td><td>Medium</td><td>Things named by provider, never ordinal</td></tr>
<tr data-reveal="right"><td>Overlap with Bifrost</td><td>Low</td><td>Medium</td><td>Thing presents; Bifrost governs</td></tr>
<tr data-reveal="right"><td>Laughter during standups</td><td>Certain</td><td>Upside</td><td>Reclassified as a morale initiative <span class="upside">Upside</span></td></tr>
</table>
</div>
<p class="src">Source: Steering committee risk workshop. Not legal advice, though it is good advice.</p>
</div>
</section>
<!-- STATEMENT -->
<section class="statement" data-statement>
<div class="st-bg" aria-hidden="true"><div class="bg-in">
<canvas id="things"></canvas>
<div class="scrim"></div>
<p class="st-count">Things rendered: <span class="things-n">0</span></p>
</div></div>
<div class="wrap st-fg">
<p class="eyebrow">Key insight</p>
<h2>Thing renders things.</h2>
<p>Read aloud in every steering committee to date. It has not become less funny.</p>
</div>
</section>
<!-- ROADMAP -->
<section class="sec">
<div class="wrap">
<header class="xhead">
<p class="eyebrow">Next steps</p>
<h2>A three-wave programme takes Thing from rename to category-defining Thing</h2>
</header>
<div class="waves" data-reveal-line>
<div class="wave" data-reveal><p class="eyebrow">Wave 1 · Weeks 1–2</p><h3>Rename the Thing</h3><ul><li>Rename eight repositories, Eve to Thing</li><li>Redirect old names so nothing breaks</li><li>Update the Projects page and Persona card</li></ul></div>
<div class="wave" data-reveal data-delay="1"><p class="eyebrow">Wave 2 · Weeks 3–6</p><h3>Embody the Thing</h3><ul><li>Commission a Persona portrait (arms: confirmed)</li><li>Retire the site's "Eve projection" wording for Huginn</li><li>Give every thing its own Thing</li></ul></div>
<div class="wave" data-reveal data-delay="2"><p class="eyebrow">Wave 3 · Ongoing</p><h3>Become the Thing</h3><ul><li>Ship Thing 2.0: more Things, fewer things</li><li>Let your thing talk to Thing</li><li>Next steering committee: held at a þing</li></ul></div>
</div>
<p class="src">Source: Thing Transformation Office. Timeline indicative; Thing is eternal.</p>
</div>
</section>
<section class="close">
<div class="wrap">
<h2>Thing 2.0.<br><i>More Things, fewer things.</i></h2>
<p>Prepared by the Thing Transformation Office for GameCult · October 2026 · Confidential and proprietary. Unauthorised use will be referred to Thing.</p>
</div>
</section>
<script>
(function(){
var root=document.documentElement;
var reduce=window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if(reduce) root.classList.add('rm');
function clamp(v,a,b){a=a===undefined?0:a;b=b===undefined?1:b;return v<a?a:v>b?b:v;}
function $(s,c){return (c||document).querySelector(s);}
function $$(s,c){return Array.prototype.slice.call((c||document).querySelectorAll(s));}
function tok(n,f){return getComputedStyle(root).getPropertyValue(n).trim()||f;}
var heroStage=$('.hero .stage'), heroIn=$('.hero-in');
var reveals=$$('[data-reveal]');
var etym=$('.etym'); if(!reduce) etym.classList.add('scrub');
var matrix=$('.matrix'), wfSec=$('[data-wf]'), tam=$('[data-tam]'), statement=$('[data-statement]');
/* ---------- hero intro: slams, shakes, rings, burst ---------- */
var bc=$('#burst'), bx=bc.getContext('2d'), parts=[], bursting=false;
function sizeBurst(){var r=bc.getBoundingClientRect(),d=Math.min(2,window.devicePixelRatio||1);bc.width=Math.max(1,r.width*d);bc.height=Math.max(1,r.height*d);bx.setTransform(d,0,0,d,0,0);}
function shake(big){heroIn.classList.remove('shake','shake-big');void heroIn.offsetWidth;heroIn.classList.add(big?'shake-big':'shake');}
function ring(el,big){
var s=heroStage.getBoundingClientRect(),r=el.getBoundingClientRect(),d=document.createElement('div');
d.className='ring'+(big?' big':'');d.style.left=(r.left+r.width/2-s.left)+'px';d.style.top=(r.top+r.height/2-s.top)+'px';
heroStage.appendChild(d);setTimeout(function(){d.remove();},1300);
}
function burst(el){
sizeBurst();
var s=heroStage.getBoundingClientRect(),r=el.getBoundingClientRect(),cx=r.left+r.width/2-s.left,cy=r.top+r.height/2-s.top;
var cols=[tok('--accent','#ff8a2a'),tok('--inv-accent','#59b7ff'),tok('--inv-ink','#eef5ff')];
var words=['thing','Thing','things','THING','synergy','þing'];
for(var i=0;i<170;i++){
var a=Math.random()*Math.PI*2,v=6+Math.random()*22,w=Math.random()<.22;
parts.push({x:cx,y:cy,vx:Math.cos(a)*v,vy:Math.sin(a)*v-6,r:Math.random()*6,vr:(Math.random()-.5)*.5,s:w?14+Math.random()*20:4+Math.random()*9,c:cols[i%3],w:w?words[i%words.length]:null,life:1});
}
if(!bursting){bursting=true;requestAnimationFrame(stepBurst);}
}
function stepBurst(){
var w=bc.clientWidth,h=bc.clientHeight;bx.clearRect(0,0,w,h);
parts=parts.filter(function(p){return p.life>0;});
parts.forEach(function(p){
p.x+=p.vx;p.y+=p.vy;p.vy+=.55;p.vx*=.985;p.r+=p.vr;p.life-=.011;
bx.save();bx.globalAlpha=Math.max(0,p.life);bx.translate(p.x,p.y);bx.rotate(p.r);bx.fillStyle=p.c;
if(p.w){bx.font='200 '+Math.round(p.s)+'px "Montserrat", sans-serif';bx.textAlign='center';bx.fillText(p.w,0,0);}
else bx.fillRect(-p.s/2,-p.s/4,p.s,p.s/2);
bx.restore();
});
if(parts.length) requestAnimationFrame(stepBurst); else {bursting=false;bx.clearRect(0,0,w,h);}
}
if(!reduce){
var lis=$$('.li');
lis.forEach(function(el){
var t=(parseFloat(el.style.getPropertyValue('--d'))+0.42)*1000;
setTimeout(function(){shake(false);ring(el,false);},t);
});
setTimeout(function(){var mid=lis[2];shake(true);ring(mid,true);setTimeout(function(){ring(mid,true);},140);burst(mid);},2000);
}
/* ---------- statement canvas ---------- */
var cv=$('#things'), ctx=cv.getContext('2d'), MAX=900, lastN=-1, thingsN=0, items=[];
var seed=930; function rnd(){seed=(seed*1664525+1013904223)%4294967296;return seed/4294967296;}
var tw=['things','things','things','things','Thing','things.','THING','thing'];
// random albedo: each word sits somewhere between darker-than-ground and the light tone, skewed dark, so normal alpha blending keeps the ground's brightness
for(var i=0;i<MAX;i++){items.push({x:rnd(),y:rnd(),s:12+Math.pow(rnd(),2.2)*54,r:(rnd()-.5)*.9,a:.18+rnd()*.42,l:Math.pow(rnd(),2.2),acc:rnd()<.08,w:tw[Math.floor(rnd()*tw.length)],it:rnd()<.3});}
function rgb(hex){hex=hex.replace('#','');if(hex.length===3)hex=hex.replace(/./g,'$&$&');var n=parseInt(hex,16);return [n>>16&255,n>>8&255,n&255];}
function sizeCanvas(){var r=cv.getBoundingClientRect(),d=Math.min(2,window.devicePixelRatio||1);cv.width=Math.max(1,r.width*d);cv.height=Math.max(1,r.height*d);ctx.setTransform(d,0,0,d,0,0);lastN=-1;}
function drawThings(p){
var N=Math.floor(Math.pow(p,1.3)*MAX); thingsN=N;
if(N===lastN) return; lastN=N;
var w=cv.clientWidth,h=cv.clientHeight; ctx.clearRect(0,0,w,h);
var lt=rgb(tok('--inv-2','#b7c7d9')),gd=rgb(tok('--inv','#03070d')),ac=tok('--inv-accent','#59b7ff');
var dk=gd.map(function(c){return Math.round(c*.25);});
ctx.globalCompositeOperation='source-over'; ctx.textAlign='center'; ctx.textBaseline='middle';
for(var i=0;i<N;i++){var t=items[i];ctx.globalAlpha=t.a;
ctx.fillStyle=t.acc?ac:'rgb('+dk.map(function(c,j){return Math.round(c+(lt[j]-c)*t.l);}).join(',')+')';ctx.save();ctx.translate(t.x*w,t.y*h);ctx.rotate(t.r);ctx.font=(t.it?'100 ':'200 ')+Math.round(t.s)+'px "Montserrat", sans-serif';ctx.fillText(t.w,0,0);ctx.restore();}
ctx.globalAlpha=1; $('.things-n').textContent=N.toLocaleString();
}
var div=$('[data-divinity]'), thingRow=$('.thingrow'), divTable=$('table',div);
var counters=$$('[data-count]');
var tpsEls=$$('h1,h2,h3,p,td,th,li,strong.cn').filter(function(el){return !el.closest('.hud-pill');}).map(function(el){return [el,(el.textContent.match(/thing/gi)||[]).length];}).filter(function(x){return x[1]>0;});
function flowP(el,vh,a,b){var r=el.getBoundingClientRect();return clamp((vh*a-r.top)/(vh*b));}
function rev(el,vh){if(reduce)return 1;var r=el.getBoundingClientRect(),d=parseFloat(el.dataset.delay||0);return clamp((vh-r.top-d*vh*0.06)/(vh*0.5));}
var ticking=false;
function frame(){
ticking=false;
var vh=window.innerHeight;
// quadrant
var qp=reduce?1:flowP(matrix,vh,0.95,0.6);
matrix.style.setProperty('--p',qp.toFixed(4));
$$('.chip,.stamp',matrix).forEach(function(c){c.style.setProperty('--k',clamp((qp-parseFloat(c.dataset.start))/0.2).toFixed(4));});
// etymology: sideways pan while the section scrolls up
var vp=$('.viewport',etym),track=$('.track',etym);
var ep=reduce?0:flowP(vp,vh,1,0.85);
etym.style.setProperty('--p',ep.toFixed(4));
etym.style.setProperty('--shift',reduce?'0px':Math.max(0,track.scrollWidth-vp.clientWidth)+'px');
// TAM: circles grow as the section enters; SOM floods as the finale rises
var tr0=tam.getBoundingClientRect(),q=reduce?1:clamp((vh-tr0.top)/vh);
var fin=$('.tam-final',tam),g=reduce?0:clamp((vh-fin.getBoundingClientRect().top)/(vh*0.85));
$$('.orbit',tam).forEach(function(c,i){var k=clamp((q-0.15-i*0.2)/0.3);c.style.setProperty('--c',(i===2?k*(1+g*g*16):k).toFixed(4));});
tam.style.setProperty('--g',g.toFixed(4));
fin.style.setProperty('--fo',reduce?0:clamp((g-0.55)/0.3).toFixed(3));
$('.pen-n',tam).textContent=Math.round(g*100);
// waterfall
var wp=reduce?1:flowP($('.wf',wfSec),vh,0.95,0.55),sum=0;
$$('.bar[data-i]',wfSec).forEach(function(b){var i=+b.dataset.i,k=clamp((wp-0.02-i*0.17)/0.14);b.parentElement.style.setProperty('--k',k.toFixed(4));if(i<4)sum+=k;});
var n=Math.round(sum);$('.tps-n',wfSec).textContent=n;
$$('.t',wfSec).forEach(function(w){w.classList.toggle('on',n>=+w.dataset.i);});
// statement: things pile up behind the scrolling text
var sr=statement.getBoundingClientRect();
drawThings(reduce?0.45:clamp((vh-sr.top)/sr.height));
// reveals and counters
reveals.forEach(function(el){
var r=rev(el,vh);el.style.setProperty('--r',r.toFixed(4));
if(el.tagName==='TR')el.style.setProperty('--f',clamp((r-0.45)*2.5).toFixed(4));
});
var line=$('[data-reveal-line]');line.style.setProperty('--r',rev(line,vh).toFixed(4));
counters.forEach(function(el){
var r=rev(el.parentElement,vh),to=+el.dataset.count;
el.textContent=el.hasAttribute('data-spin')?(r<1?String(Math.floor(r*97)%10):'0'):String(Math.round(r*to));
});
var dt=divTable.getBoundingClientRect(),tp=reduce?1:clamp((vh*0.55-dt.top)/dt.height);
var v=50-(50-35.7)*clamp((tp-0.55)/0.3);
div.style.setProperty('--fill',(v/100).toFixed(4));
div.style.setProperty('--strike',clamp((tp-0.8)/0.15).toFixed(4));
$('.div-n',div).textContent=v.toFixed(1);
thingRow.classList.toggle('lit',tp>0.6);
// HUD
var max=root.scrollHeight-vh,prog=max>0?clamp(window.scrollY/max):1;
root.style.setProperty('--prog',prog.toFixed(4));
$('.syn').textContent=Math.round(prog*100)+'%';
var tps=0;
tpsEls.forEach(function(x){var b=x[0].getBoundingClientRect();if(b.bottom>0&&b.top<vh&&b.width>0)tps+=x[1];});
if(sr.top<vh&&sr.bottom>0)tps+=thingsN;
$('.tps').textContent=tps.toLocaleString();
}
function req(){if(!ticking){ticking=true;requestAnimationFrame(frame);}}
window.addEventListener('scroll',req,{passive:true});
window.addEventListener('resize',function(){sizeCanvas();sizeBurst();req();});
sizeCanvas();sizeBurst();frame();
if(document.fonts&&document.fonts.ready)document.fonts.ready.then(function(){lastN=-1;frame();});
})();
</script>
</body></html>
<p>Project Thing now lives at <a href="/Thing">gamecult.org/Thing</a>.</p>
</body>
</html>

View file

@ -0,0 +1,256 @@
/* Layout: a consulting board deck unrolled into one scroll. Nothing pins the page; every exhibit scrolls naturally while its contents animate in place or in a sticky background layer */
.thing-deck{
color-scheme:dark;
--paper:#07111a; --ink:#eef5ff; --ink-2:#b7c7d9; --ink-3:#63758a; --rule:#16212c; --tint:#16212c; --tint-2:rgba(89,183,255,.14);
--accent:#ff8a2a; --accent-ink:#07111a;
--inv:#03070d; --inv-ink:#eef5ff; --inv-2:#b7c7d9; --inv-accent:#59b7ff;
--display:'Montserrat', sans-serif;
--body:'Ubuntu', sans-serif;
--mono:'IBM Plex Mono', ui-monospace, 'Courier New', monospace;
}
.thing-deck *{box-sizing:border-box}
.thing-deck{margin:0;color:var(--ink-2);font-family:var(--body);font-weight:300;font-size:18px;line-height:1.55}
.thing-deck h1,.thing-deck h2,.thing-deck h3{margin:0;text-wrap:balance}
.thing-deck p{margin:0}
.thing-deck .wrap{width:100%;max-width:1160px;margin-inline:auto;padding-inline:clamp(16px,4vw,48px)}
.thing-deck .eyebrow{font-family:var(--mono);font-size:13px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--accent)}
.thing-deck .src{font-family:var(--mono);font-size:12.5px;color:var(--ink-3);margin-top:28px;max-width:80ch}
.thing-deck .xhead{display:flex;flex-direction:column;gap:14px;padding-bottom:22px;border-bottom:2px solid var(--ink);margin-bottom:clamp(28px,4vh,48px)}
.thing-deck .xhead h2{font-family:var(--display);font-weight:200;color:var(--ink);font-size:clamp(24px,3.1vw,42px);line-height:1.22;max-width:30ch}
.thing-deck .sec{position:relative;overflow-x:clip;padding-block:clamp(88px,14vh,170px)}
.thing-deck b,.thing-deck strong{font-weight:500}
/* reveals: visible at rest, scrubbed by --r */
.thing-deck [data-reveal]{--r:1;opacity:calc(.25 + .75*var(--r));transform:translateY(calc((1 - var(--r))*60px))}
.thing-deck [data-reveal="left"]{transform:translateX(calc((1 - var(--r))*-90px))}
.thing-deck [data-reveal="right"]{transform:translateX(calc((1 - var(--r))*90px))}
.thing-deck [data-reveal="pop"]{transform:scale(calc(.82 + .18*var(--r))) rotate(calc((1 - var(--r))*-4deg))}
/* HUD */
.thing-deck .hud-bar{position:fixed;left:0;right:0;top:env(safe-area-inset-top,0px);height:3px;z-index:50;pointer-events:none}
.thing-deck .hud-bar i{display:block;height:100%;background:var(--accent);transform-origin:left;transform:scaleX(var(--prog,0))}
.thing-deck .hud-pill{position:fixed;right:clamp(12px,2vw,24px);bottom:calc(14px + env(safe-area-inset-bottom,0px));z-index:50;display:flex;gap:14px;font-family:var(--mono);font-size:12px;background:var(--ink);color:var(--paper);padding:8px 14px;border-radius:999px;pointer-events:none;font-variant-numeric:tabular-nums;box-shadow:0 6px 24px rgba(0,0,0,.45)}
.thing-deck .hud-pill b{color:var(--paper);font-weight:500}
/* HERO: one screen */
.thing-deck .stage{position:relative;height:100vh;height:calc(100svh - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px));overflow:hidden;display:flex;flex-direction:column;justify-content:center;background:var(--inv);color:var(--inv-ink)}
.thing-deck .hero-bg{position:absolute;inset:0;background:radial-gradient(ellipse at 50% 55%, var(--accent), transparent 60%);opacity:.3;animation:pulse 3.2s ease-in-out 2s infinite}
@keyframes pulse{50%{filter:brightness(1.35)}}
.thing-deck .rays{position:absolute;left:50%;top:55%;width:220vmax;height:220vmax;margin:-110vmax 0 0 -110vmax;background:repeating-conic-gradient(from 0deg, var(--inv-accent) 0deg 4deg, transparent 4deg 15deg);-webkit-mask-image:radial-gradient(circle, #000 6%, transparent 42%);mask-image:radial-gradient(circle, #000 6%, transparent 42%);opacity:0;animation:rayin .9s ease-out 2s forwards, spin 70s linear 2s infinite}
@keyframes rayin{to{opacity:.16}}
@keyframes spin{to{transform:rotate(360deg)}}
.thing-deck #burst{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:3}
.thing-deck .flash{position:absolute;inset:0;background:var(--inv-ink);opacity:0;pointer-events:none;z-index:4;animation:flash .7s ease-out 2s both}
@keyframes flash{0%{opacity:0}8%{opacity:.92}100%{opacity:0}}
.thing-deck .hero-in{position:relative;z-index:2;display:flex;flex-direction:column;gap:clamp(12px,2.2vh,24px)}
.thing-deck .hero-in.shake{animation:shake .32s cubic-bezier(.36,.07,.19,.97)}
.thing-deck .hero-in.shake-big{animation:shakebig .7s cubic-bezier(.36,.07,.19,.97)}
@keyframes shake{20%{transform:translate(-6px,4px)}40%{transform:translate(7px,-5px)}60%{transform:translate(-4px,-3px)}80%{transform:translate(3px,4px)}}
@keyframes shakebig{10%{transform:translate(-18px,10px) rotate(-.6deg)}25%{transform:translate(16px,-14px) rotate(.5deg)}40%{transform:translate(-12px,-8px)}55%{transform:translate(10px,10px) rotate(-.3deg)}70%{transform:translate(-6px,4px)}85%{transform:translate(3px,-3px)}}
.thing-deck .fade{display:block}
.thing-deck .in{animation:rise .6s cubic-bezier(.2,.8,.2,1) var(--d,0s) both}
@keyframes rise{from{opacity:0;transform:translateY(18px)}}
.thing-deck .hero .eyebrow{color:var(--inv-accent)}
.thing-deck .was{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 16px;font-family:var(--display);font-weight:300;font-size:clamp(22px,3vw,34px);color:var(--inv-2)}
.thing-deck .strike{position:relative;text-decoration:none}
.thing-deck .strike::after{content:"";position:absolute;left:-4%;right:-4%;top:52%;height:4px;background:var(--inv-accent);transform-origin:left;animation:strike .45s cubic-bezier(.7,0,.3,1) .65s both}
@keyframes strike{from{transform:scaleX(0)}}
.thing-deck .was span{font-family:var(--mono);font-size:12.5px;letter-spacing:.06em;text-transform:uppercase}
.thing-deck .hero h1{font-family:var(--display);font-weight:200;line-height:.9;display:flex;flex-direction:column}
.thing-deck .proj{display:block;font-style:normal;font-weight:100;font-size:clamp(30px,5vw,64px);color:var(--inv-2)}
.thing-deck .letters{font-size:clamp(96px,22vw,300px);letter-spacing:-.02em;white-space:nowrap;font-weight:100}
.thing-deck .l{display:inline-block}
.thing-deck .li{display:inline-block;animation:slam .42s cubic-bezier(.6,0,1,.5) var(--d) both}
@keyframes slam{0%{opacity:0;transform:scale(7) translateY(-12%);filter:blur(14px)}60%{opacity:1}100%{opacity:1;transform:none;filter:none}}
.thing-deck .hero-sub{font-size:clamp(18px,2vw,24px);line-height:1.45;max-width:46ch;color:var(--inv-2)}
.thing-deck .cue{font-family:var(--mono);font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--inv-accent);display:flex;gap:10px;align-items:center}
.thing-deck .cue::after{content:"↓";animation:bob 1.6s ease-in-out infinite}
@keyframes bob{50%{transform:translateY(6px)}}
.thing-deck .ring{position:absolute;width:40px;height:40px;margin:-20px 0 0 -20px;border:3px solid var(--inv-accent);border-radius:50%;pointer-events:none;z-index:1;animation:ring .7s ease-out forwards}
.thing-deck .ring.big{border-width:8px;border-color:var(--inv-ink);animation:ringbig 1.2s cubic-bezier(.1,.7,.3,1) forwards}
@keyframes ring{from{transform:scale(.3);opacity:1}to{transform:scale(12);opacity:0}}
@keyframes ringbig{from{transform:scale(.3);opacity:1}to{transform:scale(70);opacity:0}}
.thing-deck .ticker-w{position:absolute;left:-4vw;right:-4vw;bottom:56px;z-index:2;transform:rotate(-2deg)}
.thing-deck .ticker{background:var(--accent);color:var(--accent-ink);overflow:hidden;white-space:nowrap;font-family:var(--mono);font-weight:500;font-size:14px;letter-spacing:.12em;text-transform:uppercase;padding-block:10px;animation-name:tkin;animation-duration:.6s}
@keyframes tkin{from{transform:translateY(160%) skewY(4deg);opacity:0}}
.thing-deck .tk{display:inline-block;animation:marquee 38s linear infinite}
.thing-deck .tk span{padding-inline:22px}
@keyframes marquee{to{transform:translateX(-50%)}}
.thing-deck .conf{position:absolute;left:0;right:0;bottom:16px;z-index:2;text-align:center;font-family:var(--mono);font-size:12px;color:var(--ink-3);padding-inline:16px}
/* SUMMARY */
.thing-deck .scr{display:flex;flex-direction:column}
.thing-deck .scr-row{display:grid;grid-template-columns:220px minmax(0,1fr);gap:16px 40px;padding-block:26px;border-bottom:1px solid var(--rule)}
.thing-deck .scr-row:last-child{border-bottom:0}
.thing-deck .scr-k{font-family:var(--mono);font-size:13px;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);padding-top:6px}
.thing-deck .scr-row p:last-child{font-size:clamp(19px,2vw,24px);line-height:1.5;max-width:58ch}
.thing-deck .scr-row.res{background:var(--tint);padding-inline:24px;border-radius:4px}
/* STATS */
.thing-deck .stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.thing-deck .stat{background:var(--tint);padding:clamp(24px,3vw,40px);border-radius:4px;display:flex;flex-direction:column;gap:10px}
.thing-deck .num{font-family:var(--display);font-weight:200;font-size:clamp(84px,10vw,140px);line-height:1;color:var(--ink);font-variant-numeric:tabular-nums}
.thing-deck .stat p:last-child{color:var(--ink-2);font-size:17px;max-width:28ch}
.thing-deck .sowhat{margin-top:32px;font-size:clamp(19px,2vw,24px);max-width:60ch}
/* QUADRANT */
.thing-deck .matrix{--p:1;position:relative;width:100%;height:clamp(300px,56vh,560px);background:linear-gradient(var(--rule),var(--rule)) 50% 0/1px 100% no-repeat,linear-gradient(var(--rule),var(--rule)) 0 50%/100% 1px no-repeat}
.thing-deck .axis{position:absolute;background:var(--ink)}
.thing-deck .axis.x{left:0;right:0;bottom:0;height:2px;transform-origin:left;transform:scaleX(min(1,calc(var(--p)*5)))}
.thing-deck .axis.y{left:0;top:0;bottom:0;width:2px;transform-origin:bottom;transform:scaleY(min(1,calc(var(--p)*5)))}
.thing-deck .ax{position:absolute;font-family:var(--mono);font-size:12.5px;color:var(--ink-3);letter-spacing:.04em}
.thing-deck .ax-y{left:12px;top:6px}
.thing-deck .ax-x{right:4px;bottom:10px}
.thing-deck .chip{--k:1;position:absolute;left:calc(50% + (var(--fx) - 50%)*var(--k));top:calc(50% + (var(--fy) - 50%)*var(--k));transform:translate(-50%,-50%) rotate(calc((1 - var(--k))*24deg)) scale(calc(.7 + .3*var(--k)));background:var(--paper);border:2px solid var(--ink);padding:12px 18px;border-radius:4px;display:flex;flex-direction:column;gap:2px;width:min(38%,300px);box-shadow:0 8px 30px rgba(0,0,0,.45)}
.thing-deck .chip strong{font-family:var(--display);font-weight:300;font-size:clamp(17px,2vw,24px)}
.thing-deck .chip span{font-size:15px;color:var(--ink-2);line-height:1.35}
.thing-deck .chip.hot{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);transform:translate(-50%,-50%) rotate(calc((1 - var(--k))*-30deg)) scale(calc(.5 + .65*var(--k)));z-index:2}
.thing-deck .chip.hot span{color:var(--accent-ink)}
.thing-deck .stamp{--k:1;position:absolute;left:84%;top:8%;z-index:3;font-family:var(--mono);font-weight:500;font-size:clamp(13px,1.6vw,18px);letter-spacing:.2em;text-transform:uppercase;color:var(--accent);border:3px solid var(--accent);padding:6px 12px;background:var(--paper);opacity:var(--k);transform:translate(-50%,-50%) rotate(-12deg) scale(calc(3.4 - 2.4*var(--k)))}
/* ETYMOLOGY */
.thing-deck .etym{background:var(--tint);overflow:hidden}
.thing-deck .bigthorn{position:absolute;right:-6vw;top:50%;font-family:var(--display);font-size:90vh;line-height:1;color:var(--ink);opacity:.06;transform:translate(calc(var(--p,0)*-40vw),-50%);pointer-events:none}
.thing-deck .viewport{overflow-x:auto;padding-block:8px}
.thing-deck .etym.scrub .viewport{overflow:visible}
.thing-deck .track{display:flex;gap:20px;align-items:stretch;transform:translateX(calc(var(--p,0)*var(--shift,0px)*-1));will-change:transform;width:max-content}
.thing-deck .ecard{flex:0 0 min(78vw,400px);background:var(--paper);border-radius:4px;padding:clamp(24px,3vw,40px);display:flex;flex-direction:column;gap:12px;border:1px solid var(--rule)}
.thing-deck .ecard .w{font-family:var(--display);font-weight:200;color:var(--ink);font-size:clamp(64px,8vw,112px);line-height:1}
.thing-deck .ecard p:last-child{color:var(--ink-2);font-size:18px}
.thing-deck .earrow{align-self:center;font-family:var(--display);font-weight:300;font-size:56px;color:var(--accent)}
.thing-deck .ecard.impl{flex-basis:min(86vw,560px);background:var(--inv);color:var(--inv-ink);border-color:var(--inv);justify-content:center}
.thing-deck .ecard.impl .eyebrow{color:var(--inv-accent)}
.thing-deck .ecard.impl p:last-child{color:var(--inv-ink);font-size:clamp(19px,2vw,23px);line-height:1.5}
/* DIVINITY */
.thing-deck .div-grid{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:48px;align-items:start}
.thing-deck .tbl{overflow-x:auto}
.thing-deck table{width:100%;border-collapse:collapse;font-size:17px;min-width:560px}
.thing-deck th{text-align:left;font-family:var(--mono);font-size:12.5px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2);padding:10px 12px;border-bottom:2px solid var(--ink)}
.thing-deck td{padding:14px 12px;border-bottom:1px solid var(--rule);vertical-align:top}
.thing-deck tr.lit td{background:var(--accent);color:var(--accent-ink);font-weight:500}
.thing-deck tr.strike td{position:relative;color:var(--ink-2)}
.thing-deck tr.strike td::after{content:"";position:absolute;left:0;right:0;top:50%;height:2px;background:var(--accent);transform-origin:left;transform:scaleX(var(--strike,1))}
.thing-deck .meter{position:sticky;top:22vh;display:flex;flex-direction:column;gap:14px;border-top:2px solid var(--ink);padding-top:18px}
.thing-deck .div-big{font-family:var(--display);font-weight:200;color:var(--ink);font-size:clamp(64px,7vw,96px);line-height:1;font-variant-numeric:tabular-nums}
.thing-deck .gauge{height:14px;background:var(--tint);border-radius:999px;overflow:hidden}
.thing-deck .gauge div{height:100%;width:100%;background:var(--accent);transform-origin:left;transform:scaleX(var(--fill,.357))}
.thing-deck .meter-note{font-family:var(--mono);font-size:12.5px;color:var(--ink-3)}
/* TAM: sticky background, foreground scrolls over it */
.thing-deck .tam{position:relative}
.thing-deck .tam-bg,.thing-deck .st-bg{position:absolute;inset:0;pointer-events:none}
.thing-deck .bg-in{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden}
.thing-deck .tam-fg{position:relative;z-index:1}
.thing-deck .orbit{position:absolute;left:50%;top:50%;border-radius:50%;transform:translate(-50%,-50%) scale(var(--c,1));display:flex;justify-content:center;will-change:transform}
.thing-deck .o1{width:70vmin;height:70vmin;background:var(--tint)}
.thing-deck .o2{width:48vmin;height:48vmin;background:var(--tint-2)}
.thing-deck .o3{width:22vmin;height:22vmin;background:var(--accent);color:var(--accent-ink);align-items:center}
.thing-deck .orbit p{font-family:var(--mono);font-size:clamp(11px,1.3vw,14px);letter-spacing:.08em;text-transform:uppercase;text-align:center;line-height:1.4}
.thing-deck .o1 p{margin-top:5%}
.thing-deck .o2 p{margin-top:7%}
.thing-deck .o3 p{opacity:calc(1 - var(--g,0)*5)}
.thing-deck .orbit p b{display:block;font-family:var(--display);text-transform:none;letter-spacing:0;font-size:clamp(14px,1.8vw,20px)}
.thing-deck .tam-head{padding-top:clamp(72px,12vh,140px)}
.thing-deck .tam-head .xhead{border-bottom:0;margin:0}
.thing-deck .tam-cap{min-height:78vh;display:flex;align-items:center;justify-content:center;padding-inline:16px}
.thing-deck .caption{font-family:var(--display);font-weight:200;font-size:clamp(24px,3.6vw,46px);text-align:center;text-wrap:balance;background:var(--paper);color:var(--ink);padding:18px 30px;border-radius:4px;box-shadow:0 12px 40px rgba(0,0,0,.45);max-width:22ch}
.thing-deck .pen{position:absolute;left:50%;bottom:calc(64px + env(safe-area-inset-bottom,0px));transform:translateX(-50%);font-family:var(--mono);font-size:13px;background:var(--ink);color:var(--paper);padding:8px 16px;border-radius:999px;opacity:min(1,calc(var(--g,0)*8));font-variant-numeric:tabular-nums;white-space:nowrap}
.thing-deck .tam-final{min-height:115vh;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:20px;text-align:center;color:var(--accent-ink);opacity:var(--fo,1);padding-inline:16px}
.thing-deck .tam-final h3{font-family:var(--display);font-weight:200;font-size:clamp(34px,6vw,84px);line-height:1.1;max-width:16ch}
.thing-deck .tam-final p{font-family:var(--mono);font-size:14px;letter-spacing:.14em;text-transform:uppercase}
/* TAXONOMY */
.thing-deck .tax{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:48px;align-items:start}
.thing-deck .tiers{display:flex;flex-direction:column;gap:14px}
.thing-deck .tier{display:grid;grid-template-columns:150px minmax(0,1fr);gap:20px;align-items:center;padding:22px;border-radius:4px;background:var(--tint)}
.thing-deck .tier h3{font-family:var(--display);font-weight:300;color:var(--ink);font-size:clamp(24px,2.4vw,30px)}
.thing-deck .tier.t1{background:var(--inv);color:var(--inv-ink)}
.thing-deck .tier.t1 p{color:var(--inv-2)}
.thing-deck .tier p{color:var(--ink-2)}
.thing-deck .rename{min-width:0}
.thing-deck .rename td{font-family:var(--mono);font-size:16px}
.thing-deck .mx{display:inline-grid;overflow:hidden;vertical-align:bottom;justify-items:end}
.thing-deck .mx.l{justify-items:start}
.thing-deck .mx>span{grid-area:1/1}
.thing-deck .mx .o{transform:translateY(calc(var(--f,1)*-110%));opacity:calc(1 - var(--f,1))}
.thing-deck .mx .n{transform:translateY(calc((1 - var(--f,1))*110%));opacity:var(--f,1);color:var(--accent);font-weight:500}
.thing-deck .status .o{color:var(--ink-2)}
/* WATERFALL */
.thing-deck .wfhead{display:flex;justify-content:space-between;align-items:end;gap:24px;flex-wrap:wrap}
.thing-deck .tpsbig{font-family:var(--display);font-weight:200;font-size:clamp(48px,7vw,92px);line-height:1;color:var(--accent);font-variant-numeric:tabular-nums}
.thing-deck .tpsbig small{font-family:var(--mono);font-size:13px;letter-spacing:.12em;color:var(--ink-2);font-weight:400;margin-left:8px}
.thing-deck .wf{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));height:clamp(200px,38vh,420px);border-bottom:2px solid var(--ink);margin-top:20px}
.thing-deck .col{--k:1;position:relative}
.thing-deck .bar{position:absolute;left:16%;right:16%;bottom:calc(var(--base)*20%);height:calc(var(--k)*var(--u,1)*20%);background:var(--accent)}
.thing-deck .col.total .bar{background:var(--ink)}
.thing-deck .col.zero .bar{height:3px;background:var(--ink-2)}
.thing-deck .v{position:absolute;left:0;right:0;text-align:center;bottom:calc((var(--base) + var(--k)*var(--u,1))*20% + 8px);font-family:var(--mono);font-weight:500;font-size:clamp(13px,1.6vw,18px);opacity:min(1,calc(var(--k)*3))}
.thing-deck .wfl{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:8px;margin-top:12px}
.thing-deck .wfl p{font-size:clamp(12px,1.35vw,15px);line-height:1.35;color:var(--ink-2);text-align:center}
.thing-deck .wfl p:last-child{color:var(--ink);font-weight:500}
.thing-deck .example{margin-top:22px;font-size:clamp(17px,1.9vw,22px)}
.thing-deck .t{background:transparent;color:inherit;padding:0 3px;border-radius:3px}
.thing-deck .t.on{background:var(--accent);color:var(--accent-ink)}
/* RISKS */
.thing-deck .risks td:nth-child(2),.thing-deck .risks td:nth-child(3){font-family:var(--mono);font-size:15px}
.thing-deck .upside{display:inline-block;font-family:var(--mono);font-size:12.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent);border:2px solid var(--accent);padding:3px 8px;margin-left:10px;transform:rotate(-8deg) scale(calc(2.6 - 1.6*var(--r,1)));opacity:var(--r,1)}
/* STATEMENT: sticky canvas behind, text scrolls over */
.thing-deck .statement{position:relative;background:var(--inv);color:var(--inv-ink)}
.thing-deck #things{position:absolute;inset:0;width:100%;height:100%}
.thing-deck .scrim{position:absolute;inset:0;background:radial-gradient(ellipse 75% 55% at 35% 50%, var(--inv) 15%, transparent 75%);opacity:.75}
.thing-deck .st-count{position:absolute;left:clamp(16px,4vw,48px);bottom:calc(24px + env(safe-area-inset-bottom,0px));font-family:var(--mono);font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--inv-accent);font-variant-numeric:tabular-nums}
.thing-deck .st-fg{position:relative;z-index:1;display:flex;flex-direction:column;gap:24px;padding-block:65vh 75vh}
.thing-deck .st-fg .eyebrow{color:var(--inv-accent)}
.thing-deck .st-fg h2{font-family:var(--display);font-weight:200;font-size:clamp(64px,12vw,176px);line-height:1.02;text-shadow:0 2px 40px var(--inv),0 0 12px var(--inv)}
.thing-deck .st-fg p{font-size:clamp(18px,2vw,24px);color:var(--inv-2);max-width:44ch;text-shadow:0 0 12px var(--inv)}
/* ROADMAP */
.thing-deck .waves{position:relative;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;padding-top:30px}
.thing-deck .waves::before{content:"";position:absolute;left:0;right:0;top:8px;height:3px;background:var(--accent);transform-origin:left;transform:scaleX(var(--r,1))}
.thing-deck .wave{position:relative;background:var(--tint);padding:clamp(24px,3vw,36px);border-radius:4px;display:flex;flex-direction:column;gap:12px}
.thing-deck .wave::before{content:"";position:absolute;left:clamp(24px,3vw,36px);top:-29px;width:16px;height:16px;border-radius:50%;background:var(--paper);border:3px solid var(--accent)}
.thing-deck .wave h3{font-family:var(--display);font-weight:300;color:var(--ink);font-size:clamp(22px,2.2vw,28px)}
.thing-deck .wave ul{margin:0;padding-left:20px;color:var(--ink-2);display:flex;flex-direction:column;gap:8px}
.thing-deck .close{background:var(--inv);color:var(--inv-ink);padding-block:clamp(96px,16vh,180px)}
.thing-deck .close h2{font-family:var(--display);font-weight:200;font-size:clamp(44px,8vw,112px);line-height:1.05}
.thing-deck .close h2 i{font-style:normal;font-weight:100;color:var(--inv-accent)}
.thing-deck .close p{font-family:var(--mono);font-size:12.5px;color:var(--inv-2);margin-top:40px;max-width:70ch}
@media (max-width:760px){
.thing-deck .scr-row{grid-template-columns:1fr;gap:6px}
.thing-deck .stats,.thing-deck .waves,.thing-deck .tax,.thing-deck .div-grid{grid-template-columns:1fr}
.thing-deck .meter{position:static;order:-1}
.thing-deck .chip span{display:none}
.thing-deck .chip{width:auto;padding:8px 12px}
.thing-deck .stamp{left:72%;top:6%}
.thing-deck .tier{grid-template-columns:1fr;gap:6px}
.thing-deck .wfl p{font-size:11.5px}
.thing-deck .hud-pill{font-size:10.5px;gap:8px;padding:5px 10px;top:calc(10px + env(safe-area-inset-top,0px));bottom:auto;right:10px;opacity:.92}
.thing-deck .pen{bottom:calc(28px + env(safe-area-inset-bottom,0px))}
.thing-deck .ticker{font-size:12px}
}
/* reduced motion: everything in its finished, readable state */
.thing-deck.rm .stage{height:auto;min-height:88vh;padding-block:96px 160px}
.thing-deck.rm .in,.thing-deck.rm .li,.thing-deck.rm .strike::after,.thing-deck.rm .ticker,.thing-deck.rm .tk,.thing-deck.rm .flash,.thing-deck.rm .hero-bg,.thing-deck.rm .cue::after{animation:none!important}
.thing-deck.rm .rays{animation:none;opacity:.12}
.thing-deck.rm .flash{opacity:0}
/* reach-in guards: site rules that would otherwise show through into the deck */
.thing-deck a{color:inherit;font-weight:inherit;text-decoration:inherit}
.thing-deck strong,.thing-deck b{font-weight:500}
.thing-deck h1,.thing-deck h2,.thing-deck h3{margin:0;color:inherit}
.thing-deck p,.thing-deck li,.thing-deck tbody{margin:0;line-height:inherit}
.thing-deck p,.thing-deck ul,.thing-deck li,.thing-deck tr,.thing-deck td{color:inherit}
.thing-deck table{border-collapse:collapse}
.thing-deck tr{border:0}
.thing-deck th{padding:10px 12px;border-bottom:2px solid var(--ink)}
.thing-deck td{padding:14px 12px;border-bottom:1px solid var(--rule)}
.thing-deck tr.lit td{background:var(--accent)}
.thing-deck .wave ul{margin:0;padding-left:20px;list-style:disc}
.thing-deck .external-icon{display:none}

View file

@ -0,0 +1,148 @@
(function(){
var root=document.querySelector('.thing-deck');
var reduce=window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if(reduce) root.classList.add('rm');
function clamp(v,a,b){a=a===undefined?0:a;b=b===undefined?1:b;return v<a?a:v>b?b:v;}
function $(s,c){return (c||document).querySelector(s);}
function $$(s,c){return Array.prototype.slice.call((c||document).querySelectorAll(s));}
function tok(n,f){return getComputedStyle(root).getPropertyValue(n).trim()||f;}
var heroStage=$('.hero .stage'), heroIn=$('.hero-in');
var reveals=$$('[data-reveal]');
var etym=$('.etym'); if(!reduce) etym.classList.add('scrub');
var matrix=$('.matrix'), wfSec=$('[data-wf]'), tam=$('[data-tam]'), statement=$('[data-statement]');
/* ---------- hero intro: slams, shakes, rings, burst ---------- */
var bc=$('#burst'), bx=bc.getContext('2d'), parts=[], bursting=false;
function sizeBurst(){var r=bc.getBoundingClientRect(),d=Math.min(2,window.devicePixelRatio||1);bc.width=Math.max(1,r.width*d);bc.height=Math.max(1,r.height*d);bx.setTransform(d,0,0,d,0,0);}
function shake(big){heroIn.classList.remove('shake','shake-big');void heroIn.offsetWidth;heroIn.classList.add(big?'shake-big':'shake');}
function ring(el,big){
var s=heroStage.getBoundingClientRect(),r=el.getBoundingClientRect(),d=document.createElement('div');
d.className='ring'+(big?' big':'');d.style.left=(r.left+r.width/2-s.left)+'px';d.style.top=(r.top+r.height/2-s.top)+'px';
heroStage.appendChild(d);setTimeout(function(){d.remove();},1300);
}
function burst(el){
sizeBurst();
var s=heroStage.getBoundingClientRect(),r=el.getBoundingClientRect(),cx=r.left+r.width/2-s.left,cy=r.top+r.height/2-s.top;
var cols=[tok('--accent','#ff8a2a'),tok('--inv-accent','#59b7ff'),tok('--inv-ink','#eef5ff')];
var words=['thing','Thing','things','THING','synergy','þing'];
for(var i=0;i<170;i++){
var a=Math.random()*Math.PI*2,v=6+Math.random()*22,w=Math.random()<.22;
parts.push({x:cx,y:cy,vx:Math.cos(a)*v,vy:Math.sin(a)*v-6,r:Math.random()*6,vr:(Math.random()-.5)*.5,s:w?14+Math.random()*20:4+Math.random()*9,c:cols[i%3],w:w?words[i%words.length]:null,life:1});
}
if(!bursting){bursting=true;requestAnimationFrame(stepBurst);}
}
function stepBurst(){
var w=bc.clientWidth,h=bc.clientHeight;bx.clearRect(0,0,w,h);
parts=parts.filter(function(p){return p.life>0;});
parts.forEach(function(p){
p.x+=p.vx;p.y+=p.vy;p.vy+=.55;p.vx*=.985;p.r+=p.vr;p.life-=.011;
bx.save();bx.globalAlpha=Math.max(0,p.life);bx.translate(p.x,p.y);bx.rotate(p.r);bx.fillStyle=p.c;
if(p.w){bx.font='200 '+Math.round(p.s)+'px "Montserrat", sans-serif';bx.textAlign='center';bx.fillText(p.w,0,0);}
else bx.fillRect(-p.s/2,-p.s/4,p.s,p.s/2);
bx.restore();
});
if(parts.length) requestAnimationFrame(stepBurst); else {bursting=false;bx.clearRect(0,0,w,h);}
}
if(!reduce){
var lis=$$('.li');
lis.forEach(function(el){
var t=(parseFloat(el.style.getPropertyValue('--d'))+0.42)*1000;
setTimeout(function(){shake(false);ring(el,false);},t);
});
setTimeout(function(){var mid=lis[2];shake(true);ring(mid,true);setTimeout(function(){ring(mid,true);},140);burst(mid);},2000);
}
/* ---------- statement canvas ---------- */
var cv=$('#things'), ctx=cv.getContext('2d'), MAX=900, lastN=-1, thingsN=0, items=[];
var seed=930; function rnd(){seed=(seed*1664525+1013904223)%4294967296;return seed/4294967296;}
var tw=['things','things','things','things','Thing','things.','THING','thing'];
// random albedo: each word sits somewhere between darker-than-ground and the light tone, skewed dark, so normal alpha blending keeps the ground's brightness
for(var i=0;i<MAX;i++){items.push({x:rnd(),y:rnd(),s:12+Math.pow(rnd(),2.2)*54,r:(rnd()-.5)*.9,a:.18+rnd()*.42,l:Math.pow(rnd(),2.2),acc:rnd()<.08,w:tw[Math.floor(rnd()*tw.length)],it:rnd()<.3});}
function rgb(hex){hex=hex.replace('#','');if(hex.length===3)hex=hex.replace(/./g,'$&$&');var n=parseInt(hex,16);return [n>>16&255,n>>8&255,n&255];}
function sizeCanvas(){var r=cv.getBoundingClientRect(),d=Math.min(2,window.devicePixelRatio||1);cv.width=Math.max(1,r.width*d);cv.height=Math.max(1,r.height*d);ctx.setTransform(d,0,0,d,0,0);lastN=-1;}
function drawThings(p){
var N=Math.floor(Math.pow(p,1.3)*MAX); thingsN=N;
if(N===lastN) return; lastN=N;
var w=cv.clientWidth,h=cv.clientHeight; ctx.clearRect(0,0,w,h);
var lt=rgb(tok('--inv-2','#b7c7d9')),gd=rgb(tok('--inv','#03070d')),ac=tok('--inv-accent','#59b7ff');
var dk=gd.map(function(c){return Math.round(c*.25);});
ctx.globalCompositeOperation='source-over'; ctx.textAlign='center'; ctx.textBaseline='middle';
for(var i=0;i<N;i++){var t=items[i];ctx.globalAlpha=t.a;
ctx.fillStyle=t.acc?ac:'rgb('+dk.map(function(c,j){return Math.round(c+(lt[j]-c)*t.l);}).join(',')+')';ctx.save();ctx.translate(t.x*w,t.y*h);ctx.rotate(t.r);ctx.font=(t.it?'100 ':'200 ')+Math.round(t.s)+'px "Montserrat", sans-serif';ctx.fillText(t.w,0,0);ctx.restore();}
ctx.globalAlpha=1; $('.things-n').textContent=N.toLocaleString();
}
var div=$('[data-divinity]'), thingRow=$('.thingrow'), divTable=$('table',div);
var counters=$$('[data-count]');
var tpsEls=$$('h1,h2,h3,p,td,th,li,strong.cn').filter(function(el){return !el.closest('.hud-pill');}).map(function(el){return [el,(el.textContent.match(/thing/gi)||[]).length];}).filter(function(x){return x[1]>0;});
function flowP(el,vh,a,b){var r=el.getBoundingClientRect();return clamp((vh*a-r.top)/(vh*b));}
function rev(el,vh){if(reduce)return 1;var r=el.getBoundingClientRect(),d=parseFloat(el.dataset.delay||0);return clamp((vh-r.top-d*vh*0.06)/(vh*0.5));}
var ticking=false;
function frame(){
ticking=false;
var vh=window.innerHeight;
// quadrant
var qp=reduce?1:flowP(matrix,vh,0.95,0.6);
matrix.style.setProperty('--p',qp.toFixed(4));
$$('.chip,.stamp',matrix).forEach(function(c){c.style.setProperty('--k',clamp((qp-parseFloat(c.dataset.start))/0.2).toFixed(4));});
// etymology: sideways pan while the section scrolls up
var vp=$('.viewport',etym),track=$('.track',etym);
var ep=reduce?0:flowP(vp,vh,1,0.85);
etym.style.setProperty('--p',ep.toFixed(4));
etym.style.setProperty('--shift',reduce?'0px':Math.max(0,track.scrollWidth-vp.clientWidth)+'px');
// TAM: circles grow as the section enters; SOM floods as the finale rises
var tr0=tam.getBoundingClientRect(),q=reduce?1:clamp((vh-tr0.top)/vh);
var fin=$('.tam-final',tam),g=reduce?0:clamp((vh-fin.getBoundingClientRect().top)/(vh*0.85));
$$('.orbit',tam).forEach(function(c,i){var k=clamp((q-0.15-i*0.2)/0.3);c.style.setProperty('--c',(i===2?k*(1+g*g*16):k).toFixed(4));});
tam.style.setProperty('--g',g.toFixed(4));
fin.style.setProperty('--fo',reduce?0:clamp((g-0.55)/0.3).toFixed(3));
$('.pen-n',tam).textContent=Math.round(g*100);
// waterfall
var wp=reduce?1:flowP($('.wf',wfSec),vh,0.95,0.55),sum=0;
$$('.bar[data-i]',wfSec).forEach(function(b){var i=+b.dataset.i,k=clamp((wp-0.02-i*0.17)/0.14);b.parentElement.style.setProperty('--k',k.toFixed(4));if(i<4)sum+=k;});
var n=Math.round(sum);$('.tps-n',wfSec).textContent=n;
$$('.t',wfSec).forEach(function(w){w.classList.toggle('on',n>=+w.dataset.i);});
// statement: things pile up behind the scrolling text
var sr=statement.getBoundingClientRect();
drawThings(reduce?0.45:clamp((vh-sr.top)/sr.height));
// reveals and counters
reveals.forEach(function(el){
var r=rev(el,vh);el.style.setProperty('--r',r.toFixed(4));
if(el.tagName==='TR')el.style.setProperty('--f',clamp((r-0.45)*2.5).toFixed(4));
});
var line=$('[data-reveal-line]');line.style.setProperty('--r',rev(line,vh).toFixed(4));
counters.forEach(function(el){
var r=rev(el.parentElement,vh),to=+el.dataset.count;
el.textContent=el.hasAttribute('data-spin')?(r<1?String(Math.floor(r*97)%10):'0'):String(Math.round(r*to));
});
var dt=divTable.getBoundingClientRect(),tp=reduce?1:clamp((vh*0.55-dt.top)/dt.height);
var v=50-(50-35.7)*clamp((tp-0.55)/0.3);
div.style.setProperty('--fill',(v/100).toFixed(4));
div.style.setProperty('--strike',clamp((tp-0.8)/0.15).toFixed(4));
$('.div-n',div).textContent=v.toFixed(1);
thingRow.classList.toggle('lit',tp>0.6);
// HUD
var max=root.scrollHeight-vh,prog=max>0?clamp(window.scrollY/max):1;
root.style.setProperty('--prog',prog.toFixed(4));
$('.syn').textContent=Math.round(prog*100)+'%';
var tps=0;
tpsEls.forEach(function(x){var b=x[0].getBoundingClientRect();if(b.bottom>0&&b.top<vh&&b.width>0)tps+=x[1];});
if(sr.top<vh&&sr.bottom>0)tps+=thingsN;
$('.tps').textContent=tps.toLocaleString();
}
function req(){if(!ticking){ticking=true;requestAnimationFrame(frame);}}
window.addEventListener('scroll',req,{passive:true});
window.addEventListener('resize',function(){sizeCanvas();sizeBurst();req();});
sizeCanvas();sizeBurst();frame();
if(document.fonts&&document.fonts.ready)document.fonts.ready.then(function(){lastN=-1;frame();});
})();

View file

@ -1145,10 +1145,6 @@ article > h6 {
}
}
body[data-slug="Blog/project-thing"] .gamecult-embed-frame iframe {
height: 85vh;
}
body[data-slug="Blog/the-sleeping-colossus-refuses-the-throne"] {
.page > #quartz-body {
grid-template-columns: minmax(0, 1fr);