Swap three monochrome UI stickers for a tumbleweed, a like heart and a 429 gauge

calendar/empty, chat/crickets and confirmed/handshake are out, replaced by
tumbleweed/roll, liked/heart and 429/gauge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 13:01:53 +00:00
co-authored by Claude Opus 5.5
parent c00ba79178
commit 3bc30a41a3
18 changed files with 91 additions and 70 deletions
+33
View File
@@ -0,0 +1,33 @@
// a stressed speed gauge's needle climbs and jitters in the hatched red zone while the dial trembles, steams and flashes alert lines, then drops back and climbs again
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=24,delay=70
const ease=u=>(u=min(1,max(0,u)),u<.5?2*u*u:1-2*(1-u)**2)
const ln=(c,w,f)=>{for(const[l,s]of[[w,'#111'],[w-7,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),f(),c.stroke();c.lineWidth=7;c.strokeStyle='#111'}
const X=128,Y=146,A=PI*5/6,SW=PI*4/3,ang=v=>A+SW*v
export default(c,t,i)=>{
const hot=t>=.4&&t<.72,v=t<.4?.06+.82*(t/.4)**2:hot?.9+(i%2?.05:-.03):.06+.84*(1-ease((t-.72)/.14))
if(hot){
for(const d of[-1,1])for(const a of[-.45,0,.45])ln(c,11,()=>{const b=-PI/2+d*(1.2+a*.4),r=i%2?5:0;c.moveTo(X+cos(b)*(104+r),Y+sin(b)*(104+r));c.lineTo(X+cos(b)*(120+r),Y+sin(b)*(120+r))})
c.translate(i%2?3:-3,i%3-1)
}
c.lineWidth=7;c.beginPath();c.arc(X,Y,92,0,T);c.fill();c.stroke()
c.lineWidth=5;c.beginPath();c.arc(X,Y,80,0,T);c.stroke()
c.save();c.beginPath();c.arc(X,Y,74,ang(.72),ang(1));c.arc(X,Y,54,ang(1),ang(.72),true);c.closePath();c.clip()
c.lineWidth=5;for(let x=40;x<240;x+=11)c.beginPath(),c.moveTo(x,20),c.lineTo(x-60,120),c.stroke()
c.restore();c.lineWidth=5;c.beginPath();c.arc(X,Y,74,ang(.72),ang(1));c.arc(X,Y,54,ang(1),ang(.72),true);c.closePath();c.stroke()
for(let k=0;k<=8;k++){const a=ang(k/8),r=k%2?66:58;c.lineWidth=k%2?4:6;c.beginPath();c.moveTo(X+cos(a)*r,Y+sin(a)*r);c.lineTo(X+cos(a)*74,Y+sin(a)*74);c.stroke()}
const a=ang(v)
c.fillStyle='#111';c.beginPath();c.moveTo(X+cos(a)*68,Y+sin(a)*68);c.lineTo(X+cos(a+PI/2)*8,Y+sin(a+PI/2)*8);c.lineTo(X-cos(a)*14,Y-sin(a)*14);c.lineTo(X+cos(a-PI/2)*8,Y+sin(a-PI/2)*8);c.closePath();c.fill()
c.fillStyle='#fff';c.lineWidth=6;c.beginPath();c.arc(X,Y,12,0,T);c.fill();c.stroke()
c.fillStyle='#111';c.lineWidth=5
if(hot){
for(const d of[-1,1])c.beginPath(),c.moveTo(X+d*24,180),c.lineTo(X+d*14,186),c.lineTo(X+d*24,192),c.stroke()
c.beginPath();for(let k=0;k<=6;k++)c.lineTo(X-15+k*5,206+(k%2?-3:3));c.stroke()
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.moveTo(X+40,170);c.bezierCurveTo(X+34,182,X+36,190,X+42,190);c.bezierCurveTo(X+48,190,X+50,182,X+40,170);c.fill();c.stroke()
}else{
const w=v>.5?8:6
for(const d of[-1,1])c.beginPath(),c.arc(X+d*18,186,w*.75,0,T),c.fill()
c.beginPath();v>.5?c.ellipse(X,204,6,5,0,0,T):c.arc(X,200,8,PI*.15,PI*.85);v>.5?c.fill():c.stroke()
}
if(hot)for(const d of[-1,1])for(const o of[0,.5]){const p=((t-.4)/.32*2+o)%1;c.fillStyle='#fff';c.lineWidth=5;c.beginPath();c.arc(X+d*(56+14*p),Y-74-36*p,6+9*p,0,T);c.fill();c.stroke()}
}
-23
View File
@@ -1,23 +0,0 @@
// tear-off calendar pad, the top page flips up over the binding and away, but every page underneath is blank too
const{sin,cos,PI,min,max}=Math
export const frames=32,delay=55
const ease=u=>(u=min(1,max(0,u)),u<.5?2*u*u:1-2*(1-u)**2)
const X=128,Y=102,W=160,H=124
const flip=(c,a)=>{
const k=cos(a),y=Y+H*k*(k>0?1:.62),w=W/2*(1+.2*sin(a)),y0=k>0?Y-20:Y
c.fillStyle=k>0?'#fff':'#ddd'
c.beginPath();c.moveTo(X-W/2,y0);c.lineTo(X-w,y);c.lineTo(X+w,y);c.lineTo(X+W/2,y0);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff'
}
export default(c,t)=>{
const a=1.5*PI*ease((t*2%1)/.78)
if(a>PI)flip(c,a)
c.beginPath();c.rect(X-W/2+5,Y-10,W-10,H+20);c.fill();c.stroke()
c.beginPath();c.rect(X-W/2,Y-20,W,H+20);c.fill();c.stroke()
if(a<PI/2)flip(c,a)
for(const d of[-1,1])c.beginPath(),c.roundRect(X+d*44-9,34,18,40,9),c.fill(),c.stroke()
c.beginPath();c.roundRect(X-W/2-12,58,W+24,50,14);c.fill();c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(X+d*44,72,6,0,7),c.fill()
c.fillStyle='#fff'
if(a>=PI/2&&a<=PI)flip(c,a)
}
-26
View File
@@ -1,26 +0,0 @@
// an empty speech bubble hangs in awkward silence while a little cricket beside it rubs its wings and chirps
const{sin,cos,PI}=Math,T=2*PI
export const frames=20,delay=70
const ln=(c,w,f)=>{for(const[l,s]of[[w,'#111'],[w-7,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),f(),c.stroke();c.lineWidth=7;c.strokeStyle='#111'}
export default(c,t,i)=>{
const ch=t*2%1<.4,j=ch?(i%2?1:-1):0,b=3*sin(t*T)
c.save();c.translate(92,68+b);c.rotate(.03*sin(t*T))
c.beginPath();c.moveTo(-36,-50);c.arcTo(76,-50,76,50,36);c.arcTo(76,50,-76,50,36);c.lineTo(-12,50);c.lineTo(-50,86);c.lineTo(-38,50);c.arcTo(-76,50,-76,-50,36);c.arcTo(-76,-50,76,-50,36);c.closePath();c.fill();c.stroke()
c.restore()
c.save();c.translate(142,198-(ch&&i%2?2:0));c.scale(1.15,1.15)
if(ch)for(const a of[-1.5,-1.05,-.6])ln(c,10,()=>{const r=j>0?4:0;c.moveTo(46+cos(a)*(42+r),-32+sin(a)*(42+r));c.lineTo(46+cos(a)*(56+r),-32+sin(a)*(56+r))})
for(const o of[0,1])ln(c,9,()=>{c.moveTo(-36-o*8,-22);c.quadraticCurveTo(-30+o*14,-80,10+o*22+5*sin(t*T*2+o*2),-92+o*12)})
for(const[x,y,fx,fy]of[[-22,10,-36,30],[2,14,-6,30]])ln(c,11,()=>{c.moveTo(x,y);c.lineTo(fx,fy);c.lineTo(fx-10,fy)})
c.beginPath();c.ellipse(20,0,46,24,0,0,T);c.fill();c.stroke()
c.save();c.translate(-12,-16);c.rotate(ch?-.32+.1*j:-.06)
c.beginPath();c.moveTo(0,0);c.quadraticCurveTo(40,-24,78,6);c.quadraticCurveTo(40,4,0,0);c.fill();c.stroke()
c.lineWidth=4;c.beginPath();c.moveTo(14,-2);c.quadraticCurveTo(40,-10,62,2);c.stroke()
c.restore()
ln(c,11,()=>{c.moveTo(58,-30);c.lineTo(74,26);c.lineTo(84,26)})
c.save();c.translate(40,-10);c.rotate(-.55);c.beginPath();c.ellipse(0,0,32,13,0,0,T);c.fill();c.stroke();c.restore()
c.beginPath();c.arc(-36,-4,25,0,T);c.fill();c.stroke()
c.fillStyle='#111';c.beginPath();c.arc(-44,-10,7,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(-46,-12,2.5,0,T);c.fill()
c.lineWidth=4;c.beginPath();c.arc(-46,4,7,.2*PI,.8*PI);c.stroke()
c.restore()
}
-21
View File
@@ -1,21 +0,0 @@
// two hands clasped in a handshake, pumping up and down, with little shake lines above and below
const{sin,cos,PI,atan2,hypot}=Math,T=2*PI
export const frames=16,delay=70
export default(c,t)=>{
const D=(f,a=12,b=5)=>{for(const[w,s]of[[a,'#111'],[b,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),f(),c.stroke();c.lineWidth=7;c.strokeStyle='#111'}
const v=sin(2*T*t),cx=128,cy=108+14*v,S=1.35,w=7/S
for(const s of[-1,1])if(s*cos(2*T*t)<-.3)for(const k of[0,1])D(()=>{const y=cy+s*(s<0?56:62)+s*k*14;c.moveTo(cx-24+k*6,y+s*6);c.quadraticCurveTo(cx,y-s*4,cx+24-k*6,y+s*6)},11,4)
for(const d of[-1,1]){
const wx=cx+d*66,wy=cy+12,ex=128+d*88,ey=224,r=atan2(ey-wy,ex-wx),l=hypot(ex-wx,ey-wy)
c.save();c.translate(wx,wy);c.rotate(r)
c.fillStyle=d<0?'#777':'#fff';c.beginPath();c.roundRect(6,-25,l,50,14);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.roundRect(-6,-30,18,60,7);c.fill();c.stroke()
c.restore()
}
c.save();c.translate(cx,cy);c.rotate(.05*v);c.scale(S,S);c.lineWidth=w
c.beginPath();c.roundRect(-14,-22,62,46,20);c.fill();c.stroke()
c.beginPath();c.roundRect(-52,-24,52,46,20);c.fill();c.stroke()
for(const[y,l]of[[16,22],[6,32],[-4,36],[-14,32]])c.beginPath(),c.roundRect(-10,y-6,l,12,6),c.fill(),c.stroke()
c.beginPath();c.roundRect(-40,-31,48,15,7.5);c.fill();c.stroke();c.lineWidth=w*.7;c.beginPath();c.moveTo(-31,-27);c.lineTo(-31,-20);c.stroke()
c.restore()
}
+27
View File
@@ -0,0 +1,27 @@
// a heart outline gets tapped, squashes, then pops big and fills in while a ring of tiny hearts and dots bursts out, settles, and drains back to an outline
const{sin,cos,PI,min,max,exp}=Math,T=2*PI
export const frames=24,delay=60
const ease=u=>(u=min(1,max(0,u)),u<.5?2*u*u:1-2*(1-u)**2)
const hp=(c,s)=>{c.beginPath();c.moveTo(0,-26*s);c.bezierCurveTo(-14*s,-56*s,-62*s,-54*s,-62*s,-16*s);c.bezierCurveTo(-62*s,14*s,-26*s,34*s,0,56*s);c.bezierCurveTo(26*s,34*s,62*s,14*s,62*s,-16*s);c.bezierCurveTo(62*s,-54*s,14*s,-56*s,0,-26*s);c.closePath()}
export default(c,t)=>{
const u=(t-.2)/.34,k=t>.1&&t<.2?sin(PI*(t-.1)/.2):0,full=t>=.2&&t<.96,lv=-58+116*ease((t-.8)/.16)
const s=t<.2?1:u<.2?.88+.42*(u/.2)**.7:1+.3*exp(-6*(u-.2))*cos((u-.2)*T*1.4)
c.translate(128,130);c.scale(.86,.86)
if(u>0&&u<1){
const r=84+38*(1-(1-u)**3),z=1-u*u
for(let j=0;j<12;j++){
const a=j*T/12-PI/2,x=cos(a)*(j%2?r*.85:r),y=sin(a)*(j%2?r*.85:r)
c.save();c.translate(x,y);c.lineWidth=5
if(j%2)c.beginPath(),c.arc(0,0,9*z+2,0,T),c.fill(),c.stroke()
else c.rotate(a+PI/2),hp(c,.3*z+.06),c.fill(),c.stroke()
c.restore()
}
}
if(t>.08&&t<.24){const v=(t-.08)/.16;for(const[w,st]of[[11,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.arc(0,0,8+30*v,0,T),c.stroke()}
c.scale(s*(1+.12*k),s*(1-.16*k));c.translate(0,10*k)
if(full){
c.save();hp(c,1);c.clip();c.fillStyle='#555';c.fillRect(-70,max(-70,lv),140,140);c.restore()
if(lv<-20){c.fillStyle='#fff';c.strokeStyle='#fff';c.lineWidth=9;c.beginPath();c.arc(-30,-18,20,PI*1.05,PI*1.5);c.stroke();c.beginPath();c.arc(-44,8,5,0,T);c.fill()}
}
for(const[w,st]of[[22,'#111'],[9,'#fff']])c.lineWidth=w,c.strokeStyle=st,hp(c,1),c.stroke()
}
+31
View File
@@ -0,0 +1,31 @@
// a big scribbly tumbleweed bounces and spins along empty desert ground in the wind, puffing dust on each landing while pebbles and sand dashes scroll past
const{sin,cos,PI,min}=Math,T=2*PI
export const frames=16,delay=75
let sd=53;const rn=()=>(sd=sd*16807%2147483647)/2147483647
const R=60,S=T*R,W=[]
for(let k=0;k<7;k++){
const rx=R*(.5+rn()*.38),ry=rx*(.4+rn()*.45),a=rn()*T,d=rn()*(R*.96-rx),r0=rn()*T,o=rn()*T,n=.85+rn()*.3,p=[]
for(let j=0;j<=56;j++){const b=o+j/56*T*n,w=1+.07*sin(3*b+k)+.05*sin(13*b+k*3),x=cos(b)*rx*w,y=sin(b)*ry*w;p.push([cos(a)*d+x*cos(r0)-y*sin(r0),sin(a)*d+x*sin(r0)+y*cos(r0)])}
W.push(p)
}
for(let k=0;k<2;k++){const p=[],o=rn()*T;for(let j=0;j<=60;j++){const b=o+j/52*T,r=R*(.9+.06*sin(b*5+k*2)+.03*sin(b*11+k));p.push([cos(b)*r,sin(b)*r])}W.push(p)}
const P=(r,b)=>[cos(b)*R*r,sin(b)*R*r]
for(let k=0;k<3;k++){const b=rn()*T,p=[];for(let j=0;j<=20;j++){const v=j/20*2-1;p.push([cos(b)*v*R*.82-sin(b)*R*.2*sin(v*PI*1.5+k),sin(b)*v*R*.82+cos(b)*R*.2*sin(v*PI*1.5+k)])}W.push(p)}
for(let k=0;k<12;k++){const b=k*T/12+rn()*.3,e=(rn()-.5)*.4;W.push([P(.86,b),P(1.13,b+e)],[P(1.01,b+e*.6),P(1.1,b+e*.6+.17)])}
const ln=(c,w,f)=>{for(const[l,s]of[[w,'#111'],[w-7,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),f(),c.stroke();c.lineWidth=7;c.strokeStyle='#111'}
const scr=(x0,t)=>((x0-S*t)%S+S)%S-48
export default(c,t)=>{
const q=t*2%1,G=226,e=min(q,1-q),sy=e<.08?.9+.1*e/.08:1,x=124+10*sin(T*t),y=G-R-42*4*q*(1-q)
c.save();c.translate(226,G)
for(const[w,s]of[[13,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(-8,-16),c.lineTo(-15,-16),c.lineTo(-15,-27),c.moveTo(8,-22),c.lineTo(15,-22),c.lineTo(15,-33),c.stroke()
c.lineWidth=5;c.strokeStyle='#111';c.beginPath();c.roundRect(-7,-38,14,40,7);c.fill();c.stroke()
c.restore()
ln(c,11,()=>{c.moveTo(14,G);c.lineTo(242,G)})
for(const x0 of[30,150,262])ln(c,10,()=>{const u=scr(x0,t);c.moveTo(u,G+14);c.lineTo(u+18,G+14)})
for(const[x0,r]of[[96,14],[214,10],[318,12]]){const u=scr(x0,t);c.lineWidth=4;c.beginPath();c.ellipse(u,G,r,r*.75,0,PI,0);c.closePath();c.fill();c.stroke()}
for(let k=0;k<3;k++){const p=(t*3+k/3)%1,yy=y-38+k*30,x1=x-R-14-26*p,L=30*(1-p)+8;if(x1-L>8)ln(c,11,()=>{c.moveTo(x1,yy);c.lineTo(x1-L,yy)})}
if(q<.45)for(const d of[-1,1])for(const[o,s0]of[[26,11],[46,7]]){const p=q/.45,u=x+d*(o+14*p)-60*p;c.lineWidth=5;c.beginPath();c.arc(u,G-6-12*p,s0*(1-p)+2,0,T);c.fill();c.stroke()}
c.save();c.translate(x,y+R);c.scale(2-sy,sy);c.translate(0,-R);c.rotate(T*t)
for(const[w,s]of[[11,'#fff'],[4.5,'#111']]){c.lineWidth=w;c.strokeStyle=s;for(const p of W){c.beginPath();for(const[a,b]of p)c.lineTo(a,b);c.stroke()}}
c.restore()
}