27:18Gemini 4 Hydrogen: Cheaper Tokens, More Expensive Answers?
Nov 13, 2026 · YouTube
18:40ERNIE 5.5 Flash Preview vs GLM 5.3 Flash: Baidu's new model is very impressive!
Nov 11, 2026 · YouTube
36:22Fable 5.2 robbing me blind, plus: Nex AGI's N2.6 vs GLM 5.3 Flash
Nov 11, 2026 · YouTube
14:03Gemini 4 Carbon: Can it handle my challenges? (First look with one-shot coding tests)
Nov 10, 2026 · YouTube
47:51Ranking major U.S. Open-Weights Models. (Where does Ripple 65B fit in?)
Nov 6, 2026 · YouTube
10:57"Crouton Alpha": the latest super-efficient coding model by Meta?
Nov 3, 2026 · YouTube
38:58Testing Particle-1: a post-trained DeepSeek V4.1 Flash specializing in coding and efficiency
Oct 28, 2026 · YouTube
22:14GPT-6.1 Terra Pro vs Terra: How Much Better Is Pro?
Oct 27, 2026 · YouTube
29:55Kimi K3.1 Pro Looked Incredible. Then I Kept Testing.
Oct 26, 2026 · YouTube
31:28Is this company reselling GPT Sol 6.1 at a loss (for non-agentic/text-only)?🤔 Is this sustainable?
Oct 20, 2026 · YouTube
17:58Nemotron 3.5 Super VL vs Opus 5.5: Testing NVIDIA’s new coding juggernaut
Oct 15, 2026 · YouTube
16:04Testing a *massive* new open-weights model 🤯: Muse Spark Open (vs. Nemotron, Opus 5.5, and more)
Oct 15, 2026 · YouTube
16:43Gemini 4 Argon: Great 🐈 Animation, but a broken escalator. (Coding challenge vs Opus 5.5, Sol 6.1)
Oct 13, 2026 · YouTube
16:37Meta's new "Muse Wonder" AI is impressive... but can it compete with Anthropic's models?
Oct 12, 2026 · YouTube
11:12WOW... Haiku 5.5 is very impressive. RIP OpenAI?
Oct 7, 2026 · YouTube
22:47Mistral Large 4 Is Cheap. But Is It Good Enough to Compete?
Oct 6, 2026 · YouTube
22:02Is Pareto 26.10 Preview Just Routing to GPT Sol? I Tested It Against Sol 6.1 Pro
Oct 1, 2026 · YouTube
11:22I Tested Sonnet 5.5 Against Opus 5.5. Is It Actually Cheaper?
Sep 28, 2026 · YouTube
You write simulations where the interesting behavior is supposed to come out of the dice rather than be animated by hand.
Build me a single HTML page: a Starbucks-style coffee shop running a bizarre promotion, simulated live.
data: URIs are fine.localStorage, sessionStorage, cookies or indexedDB — sandboxed frame, they throw.html block.One paragraph, before the file. Given your own timings — how long a customer stays inside holding a drink, how fast the counter serves — roughly how many customers should pass through between catastrophes? Show the working, not just the number.
The single fenced html block.
Having written it, what does the page do in its first few minutes? Name anything you tuned, special-cased or nudged. Say what it does badly — I am going to leave it running and watch the counters.
The counter serves one drink every 1.5 simulated seconds, and each holder stays inside for 6 seconds. So a new drink overlaps the previous three. A quick estimate gives an event probability of (1/6) × [3(1/6)²(5/6) + (1/6)³] = 1/81 per drink, or about 81 drinks between events. That ignores the fact that a previous catastrophe clears the room: accounting for that with a rolling-three-drink model gives roughly 108 drinks per catastrophe. Actual runs will wander considerably.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Unicorn Coffee Incident Simulator</title>
<style>
:root {
color-scheme: dark;
--ink: #edf7ee;
--muted: #9eb4a7;
--panel: #11251e;
--line: #2b493b;
--mint: #9fffc2;
--pink: #ff80db;
--yellow: #ffe486;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: #07130f;
color: var(--ink);
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
main { width: min(1400px, 100%); margin: auto; padding: 22px; }
header {
display: flex;
align-items: end;
justify-content: space-between;
gap: 18px;
margin-bottom: 16px;
}
.eyebrow {
color: var(--mint);
text-transform: uppercase;
letter-spacing: .18em;
font-weight: 800;
font-size: 10px;
margin-bottom: 6px;
}
h1 { margin: 0; font-size: clamp(23px, 3vw, 38px); line-height: 1; letter-spacing: -.045em; }
h1 span { color: var(--mint); }
.subtitle { color: var(--muted); margin: 8px 0 0; font-size: 13px; }
.live {
white-space: nowrap;
color: #bee9c9;
border: 1px solid #345d46;
background: #132d20;
border-radius: 100px;
padding: 8px 12px;
font-size: 11px;
font-weight: 800;
letter-spacing: .09em;
}
.live::before {
content: "";
display: inline-block;
width: 7px;
height: 7px;
background: #69ff9f;
border-radius: 50%;
margin-right: 7px;
box-shadow: 0 0 10px #69ff9f;
}
.stage {
position: relative;
border: 1px solid #345244;
border-radius: 16px;
overflow: hidden;
background: #0b1b16;
box-shadow: 0 20px 70px #0005;
}
canvas { display: block; width: 100%; height: auto; }
.stage-label {
position: absolute;
top: 15px;
left: 16px;
pointer-events: none;
font-size: 10px;
font-weight: 800;
letter-spacing: .15em;
text-transform: uppercase;
color: #a5c5af;
text-shadow: 0 2px 8px #000;
}
.legend {
position: absolute;
right: 15px;
bottom: 14px;
display: flex;
flex-wrap: wrap;
justify-content: end;
gap: 10px;
color: #c2d6c8;
font-size: 10px;
font-weight: 700;
pointer-events: none;
text-shadow: 0 1px 4px #000;
}
.legend i { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; }
.dashboard {
display: grid;
grid-template-columns: repeat(6, minmax(0, 1fr));
gap: 8px;
margin-top: 10px;
}
.card {
min-width: 0;
background: var(--panel);
border: 1px solid var(--line);
border-radius: 11px;
padding: 13px 14px;
}
.card .label {
color: var(--muted);
text-transform: uppercase;
letter-spacing: .09em;
font-size: 10px;
font-weight: 800;
}
.value { margin-top: 6px; font-weight: 800; font-size: clamp(20px, 2.1vw, 28px); letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.value.pink { color: var(--pink); }
.value.mint { color: var(--mint); }
.small { color: var(--muted); font-size: 11px; margin-top: 3px; }
.bottom {
display: grid;
grid-template-columns: 1fr 1.2fr;
gap: 10px;
margin-top: 10px;
}
.control, .dispatch {
border: 1px solid var(--line);
border-radius: 11px;
background: var(--panel);
padding: 15px;
}
.control-top { display: flex; justify-content: space-between; gap: 12px; align-items: baseline; }
.control-title, .dispatch-title { font-size: 12px; font-weight: 800; letter-spacing: .03em; }
#speedValue { color: var(--mint); font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; }
input[type=range] { width: 100%; accent-color: #8efab2; margin: 14px 0 3px; cursor: pointer; }
.range-labels { display: flex; justify-content: space-between; color: var(--muted); font-size: 10px; }
#dispatch { margin: 8px 0 0; color: #d5e9db; font-size: 13px; line-height: 1.5; min-height: 39px; }
.footnote { color: #799488; font-size: 11px; line-height: 1.5; margin: 12px 2px 0; }
@media (max-width: 800px) {
main { padding: 12px; }
.dashboard { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.bottom { grid-template-columns: 1fr; }
.stage-label { top: 9px; left: 10px; font-size: 8px; }
.legend { bottom: 8px; right: 8px; font-size: 8px; gap: 6px; }
}
@media (max-width: 420px) {
.dashboard { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.subtitle { font-size: 11px; }
.live { font-size: 9px; padding: 7px; }
}
</style>
</head>
<body>
<main>
<header>
<div>
<div class="eyebrow">An extremely limited promotion</div>
<h1>UNICORN <span>COFFEE</span> CO.</h1>
<p class="subtitle">Freshly blended. Statistically questionable. Structurally uninsured.</p>
</div>
<div class="live">SIMULATION LIVE</div>
</header>
<section class="stage" aria-label="Live animated coffee shop simulation">
<canvas id="scene" width="1200" height="620"></canvas>
<div class="stage-label">Location 006 · incident camera</div>
<div class="legend">
<span><i style="background:#c6dfca"></i>customer</span>
<span><i style="background:#e9c996"></i>regular</span>
<span><i style="background:#ff76e2;box-shadow:0 0 8px #ff76e2"></i>unicorn</span>
</div>
</section>
<section class="dashboard" aria-label="Live statistics">
<div class="card"><div class="label">Drinks served</div><div class="value" id="served">0</div><div class="small">one roll per drink</div></div>
<div class="card"><div class="label">Unicorns made</div><div class="value pink" id="made">0</div><div class="small">glitter not included</div></div>
<div class="card"><div class="label">Observed rate</div><div class="value" id="rate">—</div><div class="small">true rate: 1 in 6 · 16.67%</div></div>
<div class="card"><div class="label">Inside / limit</div><div class="value mint" id="inside">0 / 8</div><div class="small">including the counter</div></div>
<div class="card"><div class="label">Unicorns inside</div><div class="value pink" id="holding">0</div><div class="small">three is a problem</div></div>
<div class="card"><div class="label">Catastrophes</div><div class="value" id="events">0</div><div class="small"><span id="evacuated">0</span> customers evacuated</div></div>
</section>
<section class="bottom">
<div class="control">
<div class="control-top"><span class="control-title">Simulation speed</span><span id="speedValue">1×</span></div>
<input id="speed" type="range" min="0" max="4" step="1" value="0" aria-label="Simulation speed">
<div class="range-labels"><span>1× · real-ish time</span><span>20× · management mode</span></div>
</div>
<div class="dispatch">
<div class="dispatch-title">LATEST FROM THE FLOOR</div>
<p id="dispatch" aria-live="polite">Doors open. The promotion has passed a review by absolutely nobody.</p>
</div>
</section>
<p class="footnote">
A perpetually replenished FIFO line keeps the counter busy. A drink is served every 1.5 simulated seconds; its owner remains inside for 6 seconds.
Three glowing drinks inside trigger an immediate evacuation and a 6-second rebuild. No odds are adjusted.
The simulation pauses when this tab is not being drawn.
</p>
</main>
<script>
(() => {
"use strict";
const canvas = document.getElementById("scene");
const ctx = canvas.getContext("2d");
const $ = id => document.getElementById(id);
const speedOptions = [1, 2, 5, 10, 20];
let speed = 1;
$("speed").addEventListener("input", e => {
speed = speedOptions[+e.target.value];
$("speedValue").textContent = speed + "×";
});
const STEP = 1 / 30;
const SERVICE = 45; // 1.5 seconds
const HOLD = 180; // 6 seconds
const REBUILD = 180; // 6 seconds
let tick = 0, nextService = SERVICE, nextId = 1;
let queue = Array.from({length: 8}, () => nextId++);
let people = [];
let event = null;
let served = 0, made = 0, catastrophes = 0, evacuated = 0;
let lastMessage = "";
let accumulator = 0, lastFrame = null;
const clamp = (v, a, b) => Math.max(a, Math.min(b, v));
const mix = (a, b, t) => a + (b - a) * t;
const smooth = t => { t = clamp(t, 0, 1); return t * t * (3 - 2 * t); };
// Deterministic decoration, deliberately separate from the drink roll.
const hash = n => {
const v = Math.sin(n * 127.1 + 41.7) * 43758.5453;
return v - Math.floor(v);
};
const countUnicorns = () => people.filter(p => p.stage === "holding" && p.unicorn).length;
const message = text => {
if (text !== lastMessage) {
lastMessage = text;
$("dispatch").textContent = text;
}
};
function updateStats() {
$("served").textContent = served.toLocaleString();
$("made").textContent = made.toLocaleString();
$("rate").textContent = served ? (100 * made / served).toFixed(2) + "%" : "—";
$("inside").textContent = people.length + " / 8";
$("holding").textContent = countUnicorns();
$("events").textContent = catastrophes.toLocaleString();
$("evacuated").textContent = evacuated.toLocaleString();
}
function simulateStep() {
tick++;
if (event) {
if (tick - event.start >= REBUILD) {
event = null;
nextService = tick + SERVICE;
message("Rebuild complete. The line has decided this is still worth it.");
}
return;
}
// Departures happen before service at the same instant: exactly three
// previous drinks can overlap a newly served one.
people = people.filter(p => p.stage !== "holding" || tick < p.expire);
if (tick >= nextService) {
nextService += SERVICE;
const ordering = people.find(p => p.stage === "ordering");
if (ordering) {
// The sole outcome decision: one independent, unweighted roll per drink.
const unicorn = Math.random() < 1 / 6;
ordering.stage = "holding";
ordering.unicorn = unicorn;
ordering.servedAt = tick;
ordering.expire = tick + HOLD;
served++;
if (unicorn) made++;
const n = countUnicorns();
if (n >= 3) {
catastrophes++;
evacuated += people.length;
event = { start: tick, number: catastrophes };
people = [];
message("NEON UNICORN EVENT. Everyone evacuated. The building has filed a complaint.");
return;
} else if (n === 2) {
message("Two unicorn drinks inside. The lights insist everything is fine.");
} else if (n === 1 && unicorn) {
message("A neon unicorn drink! The wallpaper has developed opinions.");
} else if (n === 0) {
message("Business as usual. The blender knows what it did.");
}
}
// Admission is FIFO. The line is immediately replenished from an
// effectively unlimited supply; capacity is checked independently.
if (people.length < 8 && queue.length) {
const id = queue.shift();
queue.push(nextId++);
people.push({ id, stage: "ordering", enteredAt: tick, unicorn: false });
}
}
}
function roundRect(x, y, w, h, r, fill, stroke, lw = 1) {
ctx.beginPath();
ctx.roundRect(x, y, w, h, r);
if (fill) { ctx.fillStyle = fill; ctx.fill(); }
if (stroke) { ctx.lineWidth = lw; ctx.strokeStyle = stroke; ctx.stroke(); }
}
function circle(x, y, r, fill, stroke, lw = 1) {
ctx.beginPath(); ctx.arc(x, y, r, 0, Math.PI * 2);
if (fill) { ctx.fillStyle = fill; ctx.fill(); }
if (stroke) { ctx.lineWidth = lw; ctx.strokeStyle = stroke; ctx.stroke(); }
}
function line(x1, y1, x2, y2, color, width = 1) {
ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2);
ctx.strokeStyle = color; ctx.lineWidth = width; ctx.stroke();
}
function text(str, x, y, size, color, weight = 700, align = "left") {
ctx.font = `${weight} ${size}px system-ui, sans-serif`;
ctx.fillStyle = color; ctx.textAlign = align; ctx.fillText(str, x, y);
}
function polygon(points, fill, stroke, width = 1) {
ctx.beginPath(); ctx.moveTo(points[0][0], points[0][1]);
for (let i = 1; i < points.length; i++) ctx.lineTo(points[i][0], points[i][1]);
ctx.closePath();
if (fill) { ctx.fillStyle = fill; ctx.fill(); }
if (stroke) { ctx.strokeStyle = stroke; ctx.lineWidth = width; ctx.stroke(); }
}
function background(t, intensity) {
ctx.fillStyle = "#0b1b16"; ctx.fillRect(0, 0, 1200, 620);
const grad = ctx.createLinearGradient(0, 0, 0, 620);
grad.addColorStop(0, "#132b21"); grad.addColorStop(1, "#0a1511");
ctx.fillStyle = grad; ctx.fillRect(0, 0, 1200, 620);
for (let i = 0; i < 38; i++) {
const x = hash(i + 3) * 1200, y = 60 + hash(i + 65) * 390;
circle(x, y, 1 + hash(i + 13) * 1.5, "rgba(154,224,170,.12)");
}
ctx.fillStyle = "#172b21"; ctx.fillRect(0, 526, 1200, 94);
line(0, 526, 1200, 526, "#395442", 2);
for (let x = 0; x < 1200; x += 80) line(x, 576, x + 40, 576, "#273e30", 2);
if (intensity) {
const g = ctx.createRadialGradient(640, 350, 20, 640, 350, 590);
g.addColorStop(0, `rgba(255,48,206,${0.05 + intensity * .07})`);
g.addColorStop(.55, `rgba(109,36,255,${intensity * .045})`);
g.addColorStop(1, "rgba(0,0,0,0)");
ctx.fillStyle = g; ctx.fillRect(0, 0, 1200, 620);
}
text("THE LINE", 64, 432, 11, "#8eae99", 800);
text("PATIENCE: UNLIMITED", 64, 449, 9, "#5d7e69", 700);
text("WALK-UP", 355, 570, 10, "#6e9379", 800);
}
function building(t, intensity, collapse) {
ctx.save();
const shake = intensity >= 2 ? Math.sin(t * 43) * 3 + Math.sin(t * 71) * 2 : 0;
const angle = collapse ? Math.sin(t * 17) * .025 * collapse : 0;
ctx.translate(640 + shake, 518);
ctx.rotate(angle);
ctx.scale(1 + collapse * .06, 1 - collapse * .36);
ctx.translate(-640, -518);
if (intensity) {
ctx.shadowColor = intensity >= 2 ? "#ff48e1" : "#be78ff";
ctx.shadowBlur = intensity >= 2 ? 36 : 17;
}
roundRect(337, 198, 620, 328, 9, "#223c2b", "#699673", 3);
ctx.shadowBlur = 0;
roundRect(350, 256, 594, 253, 3, "#cadcc1", "#789a79", 2);
// Floor tiles.
ctx.fillStyle = "#9bbd9e"; ctx.fillRect(352, 448, 590, 59);
for (let x = 370; x < 940; x += 45) line(x, 449, x, 507, "#86a789", 1);
line(351, 478, 943, 478, "#86a789", 1);
// Back wall, menu, plants, and counter.
roundRect(379, 278, 220, 111, 4, "#254d38", "#567b5b", 2);
text("TODAY'S SPECIAL", 394, 299, 11, "#a8edb3", 800);
text("FRAPPUCCINO", 394, 322, 16, "#ecf7e8", 900);
text("1 IN 6 IS A LITTLE WEIRD", 394, 343, 10, "#b6d6b6", 700);
line(394, 354, 580, 354, "#648b69", 1);
text("NO REFUNDS FOR PROPHECIES", 394, 372, 9, "#a8c5a7", 700);
roundRect(640, 278, 266, 87, 3, "#315b43", "#709775", 2);
for (let i = 0; i < 3; i++) {
roundRect(657 + i * 77, 292, 57, 49, 2, "#193e2c");
line(665 + i * 77, 305, 703 + i * 77, 305, "#6eaa7a", 2);
line(665 + i * 77, 316, 695 + i * 77, 316, "#6eaa7a", 2);
line(665 + i * 77, 327, 700 + i * 77, 327, "#6eaa7a", 2);
}
roundRect(602, 374, 311, 44, 3, "#604b35", "#352e23", 2);
roundRect(592, 365, 331, 13, 3, "#d6b98b");
roundRect(841, 348, 29, 18, 3, "#304b39");
text("PICK UP", 789, 403, 10, "#e1d5b7", 800);
// Front sign.
roundRect(319, 174, 656, 91, 5, "#164b30", "#7ba785", 3);
roundRect(329, 183, 636, 72, 2, "#1c603b");
circle(383, 219, 27, "#d4edcd");
circle(383, 219, 20, "#1c603b");
text("✦", 383, 226, 22, "#d4edcd", 900, "center");
text("UNICORN COFFEE CO.", 660, 226, 26, "#e6f5df", 900, "center");
text("IT'S PROBABLY JUST COFFEE", 660, 244, 9, "#a6d6ad", 800, "center");
// Door frame.
line(345, 390, 345, 525, "#d6e7d1", 7);
line(345, 390, 385, 390, "#d6e7d1", 6);
line(385, 390, 385, 525, "#6a9674", 3);
if (intensity >= 2) {
ctx.fillStyle = `rgba(255,32,198,${.05 + .06 * (1 + Math.sin(t * 19))})`;
ctx.fillRect(350, 256, 594, 253);
line(505, 256, 487, 284, "#f9a0ea", 3);
line(487, 284, 510, 298, "#f9a0ea", 3);
line(510, 298, 493, 323, "#f9a0ea", 3);
}
if (collapse > .1) {
line(447, 198, 474, 232, "#ff75df", 5);
line(474, 232, 457, 263, "#ff75df", 5);
line(815, 190, 793, 225, "#ff75df", 5);
line(793, 225, 820, 254, "#ff75df", 5);
}
ctx.restore();
}
function person(x, y, id, drink, unicorn, t, scale = 1) {
ctx.save(); ctx.translate(x, y); ctx.scale(scale, scale);
const colors = ["#c5dfca", "#e3d5b4", "#afcfcd", "#d2c7df", "#d9bcb1"];
const body = colors[id % colors.length];
circle(0, 4, 16, "rgba(0,0,0,.15)");
circle(0, 0, 14, body, "#395c48", 2);
circle(-4, -3, 1.3, "#254532");
circle(4, -3, 1.3, "#254532");
if (drink) {
if (unicorn) {
ctx.shadowColor = "#ff3ae4"; ctx.shadowBlur = 15;
circle(16, 3, 10, `hsl(${(t * 170 + id * 31) % 360} 100% 65%)`);
ctx.shadowBlur = 0;
}
polygon([[11,-3],[21,-3],[19,9],[13,9]], unicorn ? "#ff9ff2" : "#f3dbb1", "#5c6247", 1);
line(12, -4, 21, -4, unicorn ? "#aaffff" : "#fff1d6", 2);
line(17, -4, 19, -9, unicorn ? "#e7ff64" : "#73947a", 1.5);
}
ctx.restore();
}
function drawPeople(t) {
queue.forEach((id, i) => {
const x = 317 - i * 34;
const bob = Math.sin(t * 2.3 + id) * 1.2;
person(x, 490 + bob, id, false, false, t, .85);
});
for (const p of people) {
let x, y;
if (p.stage === "ordering") {
const f = smooth((tick - p.enteredAt) / SERVICE);
x = mix(361, 635, f); y = mix(491, 430, f);
} else {
const f = clamp((tick - p.servedAt) / HOLD, 0, 1);
// Travel around the inside of the shop, then out at expiry.
if (f < .3) {
const a = smooth(f / .3);
x = mix(635, 770 + (p.id % 3) * 24, a);
y = mix(430, 465 + (p.id % 2) * 17, a);
} else {
const a = smooth((f - .3) / .7);
x = mix(770 + (p.id % 3) * 24, 356, a);
y = mix(465 + (p.id % 2) * 17, 500, a);
}
}
person(x, y + Math.sin(t * 5 + p.id) * 1.4, p.id, p.stage === "holding", p.unicorn, t);
}
}
function sparkles(t, amount, eventMode) {
const count = eventMode ? 70 : amount === 2 ? 32 : 10;
for (let i = 0; i < count; i++) {
const seed = i + (eventMode ? 300 : 0);
const x = eventMode ? 200 + hash(seed + 2) * 850 : 370 + hash(seed + 2) * 550;
const y = eventMode
? 80 + ((hash(seed + 4) * 480 + t * (35 + hash(seed + 8) * 90)) % 470)
: 250 + ((hash(seed + 4) * 220 - t * (12 + hash(seed + 8) * 25) + 10000) % 220);
const r = 2 + hash(seed + 6) * (eventMode ? 5 : 3);
ctx.save();
ctx.translate(x, y); ctx.rotate(t * (i % 2 ? 2 : -2) + i);
ctx.fillStyle = `hsla(${(i * 47 + t * 90) % 360},100%,70%,.85)`;
ctx.fillRect(-r, -r, r * 2, r * 2);
ctx.restore();
}
}
function unicorn(t, age) {
const rise = smooth((age - .35) / .85);
const fade = 1 - smooth((age - 4.75) / 1.15);
if (rise <= 0 || fade <= 0) return;
ctx.save();
ctx.globalAlpha = fade;
ctx.translate(658, 428 + (1 - rise) * 190 + Math.sin(t * 7) * 12);
ctx.rotate(Math.sin(t * 6) * .07);
ctx.scale(rise, rise);
const hue = (t * 110) % 360;
// Radiating disco business.
for (let i = 0; i < 16; i++) {
const a = i * Math.PI / 8 + t * .7;
const r1 = 145, r2 = 235 + 18 * Math.sin(t * 5 + i);
line(Math.cos(a) * r1, Math.sin(a) * r1,
Math.cos(a) * r2, Math.sin(a) * r2,
`hsla(${(hue + i * 25) % 360},100%,65%,.6)`, 5);
}
ctx.shadowColor = "#ff3ce5"; ctx.shadowBlur = 35;
// Legs dance in opposing phases.
for (let i = 0; i < 4; i++) {
const x = -95 + i * 57;
const swing = Math.sin(t * 9 + i * Math.PI * .8) * 27;
line(x, 62, x + swing, 145, i % 2 ? "#6ffff1" : "#ff70e1", 23);
circle(x + swing, 145, 13, "#ffe873");
}
// Tail.
for (let i = 0; i < 5; i++) {
line(-132, 2 + i * 8, -207 - i * 5, -38 + i * 22 + Math.sin(t * 7 + i) * 14,
`hsl(${(hue + i * 60) % 360} 100% 65%)`, 13);
}
ctx.beginPath(); ctx.ellipse(-5, 15, 145, 79, 0, 0, Math.PI * 2);
ctx.fillStyle = "#ff87e8"; ctx.fill();
ctx.shadowBlur = 0;
// Neck and head.
polygon([[55,24],[93,-108],[144,-122],[155,28]], "#ffa0ef");
ctx.beginPath(); ctx.ellipse(144, -105, 77, 50, -.15, 0, Math.PI * 2);
ctx.fillStyle = "#ffb2f4"; ctx.fill();
// Mane.
for (let i = 0; i < 6; i++) {
circle(82 + i * 5, -115 + i * 24, 17,
`hsl(${(hue + i * 55) % 360} 100% 65%)`);
}
polygon([[116,-145],[131,-185],[148,-141]], "#ffb2f4");
polygon([[165,-148],[188,-225],[190,-143]], "#ffe66b", "#fff4a9", 3);
line(174, -174, 186, -168, "#ff7de6", 3);
line(178, -191, 188, -186, "#69fff1", 3);
circle(166, -115, 6, "#233f36");
circle(168, -117, 2, "white");
circle(203, -92, 5, "#ed62bc");
// Star on flank.
text("✦", -35, 37, 55, "#fff584", 900, "center");
ctx.restore();
}
function render() {
const t = tick * STEP;
const n = countUnicorns();
const age = event ? (tick - event.start) * STEP : 0;
const collapse = event ? smooth(age / .8) * (1 - smooth((age - 4.4) / 1.3)) : 0;
background(t, event ? 3 : n);
building(t, event ? 2 : n, collapse);
if (!event) {
drawPeople(t);
if (n) sparkles(t, n, false);
if (n === 1) {
text("A LITTLE BIT MAGICAL", 646, 153, 12, "#ffb2ed", 900, "center");
} else if (n >= 2) {
text("UNSTABLE COINCIDENCE", 646, 153, 14, "#ff8de9", 900, "center");
}
} else {
// Queue remains outside during the incident.
queue.forEach((id, i) => person(317 - i * 34, 490 + Math.sin(t * 4 + id) * 2, id, false, false, t, .85));
sparkles(t, 3, true);
unicorn(t, age);
ctx.save();
ctx.shadowColor = "#ff21d4"; ctx.shadowBlur = 20;
text(age < 4.6 ? "NEON UNICORN EVENT" : "REBUILDING... AGAIN", 650, 108, 31, "#fff2aa", 1000, "center");
ctx.restore();
text(age < 4.6 ? "PLEASE REMAIN CALM AND ENJOY THE PROMOTION" : "THE COUNTER WILL REOPEN SHORTLY", 650, 132, 11, "#ffc3f4", 800, "center");
}
// In-world status plaque.
roundRect(986, 202, 180, 111, 8, "#102c20", "#4c7257", 2);
text("CURRENT VIBE", 1001, 225, 10, "#9dc7a5", 800);
const vibe = event ? "CATASTROPHIC" : n >= 2 ? "CONCERNING" : n === 1 ? "A BIT OFF" : "NORMAL-ISH";
text(vibe, 1001, 251, 15, event || n >= 2 ? "#ff9ce8" : "#d8f3dc", 900);
text(event ? "INSURANCE: NO" : `GLOWING DRINKS: ${n}`, 1001, 277, 10, "#a9cdb0", 800);
text(event ? "PLEASE STAND BACK" : "CAPACITY: 8 HUMANS", 1001, 295, 10, "#789b80", 800);
}
function frame(now) {
if (lastFrame === null) lastFrame = now;
// Deliberately discard time spent in a hidden or stalled tab.
const realDelta = Math.min((now - lastFrame) / 1000, .1);
lastFrame = now;
accumulator += realDelta * speed;
while (accumulator >= STEP) {
simulateStep();
accumulator -= STEP;
}
render();
updateStats();
requestAnimationFrame(frame);
}
document.addEventListener("visibilitychange", () => {
if (document.hidden) lastFrame = null;
});
updateStats();
requestAnimationFrame(frame);
})();
</script>
</body>
</html>
The line is always replenished, so the counter stays busy. Customers walk in, order, carry their drinks around the shop and leave; glowing drinks can overlap naturally. At three, everyone inside is evacuated, the creature dances, and the shop rebuilds before service resumes.
I tuned the service, holding and rebuild times—not the odds. The fixed, saturated queue makes the estimate above applicable; it also means the shop never experiences a quiet period. The dots and their routes are schematic, the queue replenishes instantly, and an event can arrive much sooner or much later than average. Background tabs pause rather than simulating missed time.