<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><meta name="theme-color" content="#f4e8c8"><title>slap the boss</title>
<style>
:root{--paper:#f4e8c8;--ink:#171514;--red:#e53935;--yellow:#ffd84d}*{box-sizing:border-box}body{margin:0;background:var(--paper);color:var(--ink);font-family:Impact,'Arial Black',system-ui,sans-serif;text-transform:uppercase;background-image:radial-gradient(#17151422 1px,transparent 1.3px);background-size:8px 8px;min-height:100dvh}.wrap{width:min(100%,560px);min-height:100dvh;margin:auto;padding:14px 16px 10px;display:flex;flex-direction:column}.mast{display:flex;justify-content:space-between;align-items:center;border-bottom:4px solid;padding-bottom:7px;font-size:13px;letter-spacing:1px}.logo{font-size:16px}.screen{display:none;flex:1}.screen.active{display:flex;flex-direction:column}.intro{justify-content:center;text-align:center;gap:18px}.title{font-size:clamp(50px,15vw,86px);line-height:.82;margin:0;text-shadow:4px 4px 0 var(--red);-webkit-text-stroke:1px var(--ink)}.joke{font:900 16px system-ui;text-transform:none;margin:3px auto;max-width:330px}.btn{border:4px solid var(--ink);box-shadow:5px 5px var(--ink);background:var(--yellow);color:var(--ink);font:1000 23px Impact,'Arial Black',sans-serif;text-transform:uppercase;padding:15px 18px;min-height:60px;cursor:pointer;touch-action:manipulation}.btn:active{transform:translate(3px,3px);box-shadow:2px 2px var(--ink)}.btn.red{background:var(--red);color:white}.upload{font:900 13px system-ui;text-transform:none}.upload input{display:block;margin:10px auto;max-width:100%;font:700 13px system-ui}.tiny{font:700 12px system-ui;text-transform:none}.game{gap:8px;padding-top:9px}.hud{display:grid;grid-template-columns:1fr auto;gap:5px 10px;align-items:center;font-size:14px}.meter{height:19px;border:3px solid;background:white;grid-column:1/-1}.fill{height:100%;width:0;background:var(--red);transition:width .25s}.scene{position:relative;border:4px solid;box-shadow:4px 4px var(--ink);height:clamp(270px,45vh,410px);overflow:hidden;background:#d9e6df;background-image:radial-gradient(#17151420 1px,transparent 1px);background-size:7px 7px}.wall{height:61%;position:relative;background:#f4e8c8;border-bottom:9px solid var(--ink)}.window{position:absolute;left:8%;top:12%;width:27%;height:39%;background:#b5dceb;border:4px solid}.poster{position:absolute;right:9%;top:12%;font-size:14px;text-align:center;border:3px solid;padding:4px;background:var(--yellow);transform:rotate(4deg)}.desk{position:absolute;bottom:0;left:0;width:100%;height:28%;background:#9e6138;border-top:8px solid var(--ink)}.desk:after{content:'';position:absolute;left:8%;right:8%;top:17px;height:100%;border-left:8px solid var(--ink);border-right:8px solid var(--ink)}.boss{position:absolute;left:50%;top:22%;transform:translateX(-50%);width:135px;height:173px;z-index:2;transition:transform .2s}.head{position:absolute;left:25px;top:0;width:85px;height:92px;border:5px solid var(--ink);border-radius:46% 46% 42% 42%;background:#f0b987;z-index:2}.hair{position:absolute;left:24px;top:-6px;width:86px;height:31px;background:var(--ink);border-radius:50% 48% 15% 10%;z-index:3}.eye{position:absolute;top:35px;left:23px;width:11px;height:13px;background:var(--ink);border-radius:50%}.eye.r{left:55px}.nose{position:absolute;top:47px;left:42px;width:15px;height:12px;border-right:4px solid var(--ink);border-bottom:3px solid var(--ink);transform:rotate(15deg)}.mouth{position:absolute;left:33px;top:68px;width:30px;height:8px;border-bottom:4px solid var(--ink);border-radius:50%}.bodyboss{position:absolute;top:82px;left:10px;width:116px;height:86px;background:#344d68;border:5px solid var(--ink);border-radius:32px 32px 12px 12px}.tie{position:absolute;left:50px;top:89px;width:25px;height:65px;background:var(--red);clip-path:polygon(50% 0,100% 12%,70% 100%,50% 84%,30% 100%,0 12%);border:2px solid var(--ink)}.bubble{position:absolute;z-index:5;top:5%;left:4%;width:63%;min-height:66px;background:white;border:4px solid;padding:8px 10px;font:1000 14px/1.1 system-ui;text-transform:none;box-shadow:3px 3px var(--ink)}.bubble:after{content:'';position:absolute;right:8%;bottom:-14px;width:20px;height:20px;background:white;border-right:4px solid;border-bottom:4px solid;transform:rotate(45deg)}.dialogue{position:absolute;z-index:8;left:4%;right:4%;bottom:30%;text-align:center;font:1000 13px system-ui;text-transform:none;text-shadow:1px 1px var(--paper)}.player{position:absolute;z-index:3;left:5%;bottom:8%;width:74px;height:74px;border:5px solid;border-radius:50%;background:#ffd84d;display:grid;place-items:center;overflow:hidden;font-size:26px}.player img{width:100%;height:100%;object-fit:cover}.buttons{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:5px}.buttons .btn{font-size:23px;padding:12px 6px}.status{font:900 12px system-ui;text-transform:none;text-align:center;min-height:18px}.slap-hand{position:absolute;z-index:10;left:-80px;top:51%;font:1000 38px Impact;display:none;background:var(--yellow);border:4px solid;padding:3px 8px;transform:rotate(-15deg)}.burst{position:absolute;z-index:9;display:none;left:51%;top:37%;color:var(--red);font:1000 35px Impact;text-shadow:2px 2px white,-2px -2px white;transform:rotate(-12deg)}.print{position:absolute;z-index:6;display:none;left:55%;top:25%;width:38px;height:34px;background:var(--red);opacity:.88;border-radius:50% 44% 40% 45%;box-shadow:10px 0 var(--red),-9px -10px var(--red),0 -15px var(--red);transform:rotate(-15deg)}.hit .boss{animation:bonk .55s ease}.hit .slap-hand{display:block;animation:swing .55s ease forwards}.hit .burst,.hit .print{display:block;animation:pop .7s ease}.accepting .boss{animation:nod .5s ease}.accepting .dialogue{color:#135c31}@keyframes swing{0%{left:-80px;top:65%}55%{left:48%;top:40%;transform:rotate(-25deg) scale(1.2)}100%{left:108%;top:52%}}@keyframes bonk{30%{transform:translateX(-50%) rotate(18deg)}55%{transform:translateX(-44%) rotate(-14deg) scale(1.07)}100%{transform:translateX(-50%) rotate(0)}}@keyframes pop{0%,100%{opacity:0;transform:scale(.2) rotate(-12deg)}30%,70%{opacity:1;transform:scale(1.15) rotate(-12deg)}}@keyframes nod{50%{transform:translateX(-50%) translateY(8px)}}.over{justify-content:center;text-align:center;gap:12px}.over h2{font-size:40px;line-height:.95;margin:0}.score{font-size:24px}.footer{font:700 10px system-ui;text-transform:none;text-align:center;padding-top:8px}
</style></head><body><div class="wrap"><header class="mast"><span>office casualties weekly</span><span>issue no. 09</span></header>
<section class="screen intro active" id="start"><h1 class="title">slap<br>the boss</h1><p class="joke">one weird trick HR definitely doesn't want you to try.</p><button class="btn red" id="startBtn">start the shift</button><label class="upload">optional: use my face<input id="photo" type="file" accept="image/*"></label><div class="tiny">your photo stays on this device.</div></section>
<section class="screen game" id="game"><div class="hud"><span>stress <b id="stressNum">0%</b></span><span>best <b id="best">0</b> score <b id="score">0</b></span><div class="meter"><div class="fill" id="fill"></div></div></div><div class="scene" id="scene"><div class="wall"><div class="window"></div><div class="poster">Q3<br>SYNERGY</div></div><div class="desk"></div><div class="bubble" id="order">loading your unreasonable request...</div><div class="boss" id="boss"><div class="hair"></div><div class="head"><i class="eye"></i><i class="eye r"></i><i class="nose"></i><i class="mouth"></i></div><div class="bodyboss"></div><div class="tie"></div></div><div class="player" id="player">K</div><div class="dialogue" id="dialogue">the meeting could have been an email.</div><div class="slap-hand">WHAP!</div><div class="burst">POW!</div><div class="print"></div></div><div class="buttons"><button class="btn" id="accept">accept</button><button class="btn red" id="slap">slap</button></div><div class="status" id="status">choose wisely. ish.</div></section>
<section class="screen over" id="over"><h2 id="endTitle">you burned out.<br>he promoted himself.</h2><div class="score" id="finalScore"></div><div class="tiny" id="bestLine"></div><button class="btn red" id="restart">another day at the office</button></section><footer class="footer">made with tomo</footer></div>
<script>
(()=>{const orders=['Kishan, can you make the logo bigger but also smaller?','quick one: can you work this weekend, unpaid?','where were you at 9:04?','can you just make it pop?','please circle back to the thing we never discussed.','let’s take this offline, then schedule a meeting about it.','can you do the impossible by lunch?','could you synergize the deliverables into a paradigm?','tiny change: rebuild the entire thing.'];let stress=0,score=0,round=0,streak=0,best=+(localStorage.getItem('stbBest')||0),timer=null,ended=false,face=null;const $=x=>document.getElementById(x);$('best').textContent=best;function show(id){document.querySelectorAll('.screen').forEach(s=>s.classList.remove('active'));$(id).classList.add('active')}function order(){if(ended)return;round++;$('order').textContent=orders[(round-1)%orders.length];$('dialogue').textContent='the meeting could have been an email.';let delay=Math.max(2300,5600-round*130);timer=setTimeout(()=>{if(!ended){stress+=7;update();if(stress>=100)finish(false);else order()}},delay)}function update(){$('stressNum').textContent=stress+'%';$('fill').style.width=Math.min(stress,100)+'%';$('score').textContent=score;$('best').textContent=best}function start(){clearTimeout(timer);stress=0;score=0;round=0;streak=0;ended=false;update();if(face){$('player').innerHTML='';$('player').appendChild(face.cloneNode())}else $('player').textContent='K';show('game');order()}function act(kind){if(ended)return;clearTimeout(timer);if(kind==='accept'){streak=0;stress+=19;score+=10;$('dialogue').textContent='yes boss. absolutely boss. love this.';$('scene').classList.add('accepting');setTimeout(()=>$('scene').classList.remove('accepting'),550);update();if(stress>=100){finish(false);return}}else{streak++;stress=Math.max(0,stress-34);let combo=streak>1?streak:1;score+=20*combo;$('dialogue').textContent=combo>1?'combo x'+combo+'! that was a performance review.':'that was a stakeholder alignment.';$('scene').classList.remove('hit');void $('scene').offsetWidth;$('scene').classList.add('hit');setTimeout(()=>$('scene').classList.remove('hit'),750);if(streak>=3){update();finish(true);return}update()}$('status').textContent='order '+round+' survived. next one incoming...';let delay=Math.max(1300,4200-round*115);timer=setTimeout(order,delay)}function finish(fired){ended=true;clearTimeout(timer);if(score>best){best=score;localStorage.setItem('stbBest',best)}$('endTitle').innerHTML=fired?'hr would like a word.<br>you’re fired.':'you burned out.<br>he promoted himself.';$('finalScore').textContent='score: '+score+' | orders: '+round+' | slaps: '+Math.floor(score/20);$('bestLine').textContent='best score: '+best;show('over')}$('startBtn').onclick=start;$('restart').onclick=start;$('accept').onclick=()=>act('accept');$('slap').onclick=()=>act('slap');$('photo').addEventListener('change',e=>{const file=e.target.files&&e.target.files[0];if(!file)return;const img=new Image();img.onload=()=>{const c=document.createElement('canvas'),ctx=c.getContext('2d',{willReadFrequently:true}),n=128;c.width=n;c.height=n;ctx.drawImage(img,0,0,n,n);let im=ctx.getImageData(0,0,n,n),d=im.data;for(let i=0;i<d.length;i+=4){let r=d[i],g=d[i+1],b=d[i+2],gray=.299*r+.587*g+.114*b,sat=1.25; r=gray+(r-gray)*sat;g=gray+(g-gray)*sat;b=gray+(b-gray)*sat;d[i]=Math.round(Math.max(0,Math.min(255,Math.round(r/51)*51)));d[i+1]=Math.round(Math.max(0,Math.min(255,Math.round(g/51)*51)));d[i+2]=Math.round(Math.max(0,Math.min(255,Math.round(b/51)*51)))}ctx.putImageData(im,0,0);const src=ctx.getImageData(0,0,n,n),out=ctx.createImageData(n,n);for(let y=1;y<n-1;y++)for(let x=1;x<n-1;x++){let p=(y*n+x)*4, lum=(q)=>.299*src.data[q]+.587*src.data[q+1]+.114*src.data[q+2],gx=0,gy=0;for(let j=-1;j<=1;j++)for(let k=-1;k<=1;k++){let l=lum(((y+j)*n+x+k)*4);gx+=k*l;gy+=j*l}let edge=Math.hypot(gx,gy)>160;for(let z=0;z<3;z++)out.data[p+z]=edge?23:src.data[p+z];out.data[p+3]=255}ctx.putImageData(out,0,0);face=new Image();face.src=c.toDataURL('image/png');$('player').innerHTML='';$('player').appendChild(face.cloneNode())};img.src=URL.createObjectURL(file)});})();
</script>
</body>
</html>