Project Thing deck as a site applet, re-skinned to the brand with two fact fixes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2af33995d9
commit
eec97d1c7d
1 changed files with 689 additions and 0 deletions
689
site/quartz/static/applets/project-thing/index.html
Normal file
689
site/quartz/static/applets/project-thing/index.html
Normal file
|
|
@ -0,0 +1,689 @@
|
|||
<!doctype html>
|
||||
<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. Only the hero pins; every exhibit after it 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;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: the one pinned scene */
|
||||
.hero{position:relative;height:260vh}
|
||||
.stage{position:sticky;top:env(safe-area-inset-top,0px);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:calc(.3 + var(--p)*.5);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{opacity:max(0,calc(1 - var(--p)*3));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;transform:translate(calc(var(--p)*var(--dx,0px)),calc(var(--p)*var(--dy,0px))) rotate(calc(var(--p)*var(--rot,0deg)));will-change:transform}
|
||||
.l.zoom{transform:scale(calc(1 + var(--p)*var(--p)*90));opacity:clamp(0,calc((1 - var(--p))*7),1)}
|
||||
.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 .hero{height:auto}
|
||||
.rm .stage{position:relative;top:0;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>
|
||||
</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" style="--p:0">
|
||||
<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" style="--dx:-60vw;--dy:-45vh;--rot:-70deg"><span class="li" style="--d:1s">T</span></span><span class="l" style="--dx:-30vw;--dy:60vh;--rot:45deg"><span class="li" style="--d:1.13s">H</span></span><span class="l zoom"><span class="li" style="--d:1.26s">I</span></span><span class="l" style="--dx:35vw;--dy:-60vh;--rot:60deg"><span class="li" style="--d:1.39s">N</span></span><span class="l" style="--dx:65vw;--dy:45vh;--rot:-40deg"><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 hero=$('.hero'), 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;
|
||||
|
||||
// hero: the only pinned scene
|
||||
var hp=0;
|
||||
if(!reduce){var hr=hero.getBoundingClientRect(),tot=hr.height-heroStage.offsetHeight;hp=tot>0?clamp(-hr.top/tot):0;}
|
||||
hero.style.setProperty('--p',hp.toFixed(4));
|
||||
|
||||
// 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>
|
||||
Loading…
Reference in a new issue