/* Otto scenes (js/otto_scenes.js). All loops divide 4s so they can be exported as seamless GIFs. */
.osc{position:relative;width:100%;aspect-ratio:4/3;overflow:hidden;border-radius:20px;isolation:isolate;background:#14103a}
.osc>svg,.osc>.ot{position:absolute}
.osc .osb,.osc .osk,.osc .osf{left:0;top:0;width:100%;height:100%;overflow:visible}
.osc .osb{z-index:0}.osc .osk{z-index:1}.osc>.ot{z-index:2}.osc .osf{z-index:3}
.osc.bleed{overflow:visible;background:none;border-radius:0}
.osc.bleed .osb{position:fixed;inset:0;width:100%;height:100%}
.osc .ot .otto{width:100%}
.osc text{pointer-events:none}
/* shared animation bits */
.osc .tw{animation:osTw 2s ease-in-out infinite}.osc .tw2{animation-duration:4s}
@keyframes osTw{0%,100%{opacity:.25}50%{opacity:1}}
.osc .glow{animation:osGlow 4s ease-in-out infinite;transform-origin:center;transform-box:fill-box}
@keyframes osGlow{0%,100%{opacity:.75;transform:scale(1)}50%{opacity:1;transform:scale(1.06)}}
.osc .rise{animation:osRise 4s linear infinite;opacity:0}
.osc .r2{animation-delay:-1s}.osc .r3{animation-delay:-2s}.osc .r4{animation-delay:-3s}
@keyframes osRise{0%{transform:translate(0,6px) scale(.5);opacity:0}12%{opacity:1}100%{transform:translate(var(--dx,6px),-64px) scale(1.15) rotate(12deg);opacity:0}}
.osc .r2{--dx:-10px}.osc .r3{--dx:14px}.osc .r4{--dx:-4px}
.osc .otto .bob{animation-duration:4s}.osc .otto .tail{animation-duration:2s}.osc .otto .eye{animation-duration:4s}
/* ── Otto poses used by scenes: lots of full-body movement, every loop divides 4s ── */
.osc .otto .all{transform-origin:110px 250px}
.osc .otto .bob{animation:osBreath 2s ease-in-out infinite}
@keyframes osBreath{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
.osc .otto .tail{animation:osWag 1s ease-in-out infinite alternate}
@keyframes osWag{from{transform:rotate(-10deg)}to{transform:rotate(16deg)}}
.osc .otto .head{transform-origin:110px 150px}
.osc .otto .ftL{animation:osFootA 1s ease-in-out infinite alternate}.osc .otto .ftR{animation:osFootB 1s ease-in-out infinite alternate}
@keyframes osFootA{from{transform:translateY(0)}to{transform:translateY(-4px)}}@keyframes osFootB{from{transform:translateY(-4px)}to{transform:translateY(0)}}
/* read: sways side to side, head tilts, eyes follow the lines, arms ease the book up and down */
.otto[data-mood=read] .all{animation:osSway 4s ease-in-out infinite}
@keyframes osSway{0%,100%{transform:rotate(-2.2deg) translateY(0)}25%{transform:rotate(0) translateY(-3px)}50%{transform:rotate(2.2deg) translateY(0)}75%{transform:rotate(0) translateY(-3px)}}
.otto[data-mood=read] .armL{animation:osRdL 2s ease-in-out infinite alternate}.otto[data-mood=read] .armR{animation:osRdR 2s ease-in-out infinite alternate}
@keyframes osRdL{from{transform:rotate(-50deg)}to{transform:rotate(-60deg)}}@keyframes osRdR{from{transform:rotate(50deg)}to{transform:rotate(60deg)}}
.otto[data-mood=read] .eyes{animation:osLook 1s ease-in-out infinite alternate}
.otto[data-mood=read] .head{animation:osHeadR 2s ease-in-out infinite alternate}
@keyframes osLook{from{transform:translate(-4px,5px)}to{transform:translate(4px,5px)}}
@keyframes osHeadR{from{transform:rotate(-5deg) translateY(1px)}to{transform:rotate(5deg) translateY(-2px)}}
.otto[data-mood=read] .brow{animation:osBrow 2s ease-in-out infinite alternate}
@keyframes osBrow{from{transform:translateY(0)}to{transform:translateY(-3px)}}
/* board: leans in and writes, whole body bounces with the marker, eyes follow the pen */
.otto[data-mood=board] .all{animation:osLean 2s ease-in-out infinite alternate}
@keyframes osLean{from{transform:translateX(-2px) rotate(-1deg)}to{transform:translateX(7px) rotate(3deg)}}
.otto[data-mood=board] .bob{animation:osWBob .5s ease-in-out infinite alternate}
@keyframes osWBob{from{transform:translateY(0)}to{transform:translateY(-3px)}}
.otto[data-mood=board] .armR{animation:osWrite .5s ease-in-out infinite alternate}
.otto[data-mood=board] .armL{animation:osHip 2s ease-in-out infinite alternate}
@keyframes osWrite{from{transform:rotate(-127deg)}to{transform:rotate(-141deg)}}
@keyframes osHip{from{transform:rotate(14deg)}to{transform:rotate(34deg)}}
.otto[data-mood=board] .head{animation:osHeadB 1s ease-in-out infinite alternate}
@keyframes osHeadB{from{transform:rotate(2deg)}to{transform:rotate(9deg) translateX(3px)}}
.otto[data-mood=board] .eyes{animation:osEyesB 2s ease-in-out infinite alternate}
@keyframes osEyesB{from{transform:translate(4px,-3px)}to{transform:translate(7px,3px)}}
.otto[data-mood=board] .m-smile{display:none}.otto[data-mood=board] .m-flat{display:block}
/* holo: dancing while he taps and swipes */
.otto[data-mood=holo] .all{animation:osDance 1s ease-in-out infinite alternate}
@keyframes osDance{from{transform:translateY(0) rotate(-3deg)}to{transform:translateY(-9px) rotate(3deg)}}
.otto[data-mood=holo] .armR{animation:osTap .5s ease-in-out infinite alternate}
.otto[data-mood=holo] .armL{animation:osSwipe 2s ease-in-out infinite alternate}
@keyframes osTap{from{transform:rotate(-138deg)}to{transform:rotate(-124deg)}}
@keyframes osSwipe{from{transform:rotate(100deg)}to{transform:rotate(150deg)}}
.otto[data-mood=holo] .head{animation:osHeadD 1s ease-in-out infinite alternate}
@keyframes osHeadD{from{transform:rotate(-6deg)}to{transform:rotate(6deg)}}
.otto[data-mood=holo] .eyes{animation:osEyesH 2s ease-in-out infinite alternate}
@keyframes osEyesH{from{transform:translate(3px,-3px)}to{transform:translate(7px,2px)}}
.otto[data-mood=holo] .tail{animation-duration:.5s}
/* rocket: bouncing around in the cockpit and looking out the window */
.otto[data-mood=rocket] .all{animation:osJit .5s ease-in-out infinite alternate}
@keyframes osJit{from{transform:translate(-4px,2px) rotate(-3deg)}to{transform:translate(4px,-3px) rotate(3deg)}}
.otto[data-mood=rocket] .head{animation:osHeadK 2s ease-in-out infinite alternate}
@keyframes osHeadK{from{transform:rotate(-8deg)}to{transform:rotate(8deg) translateY(-3px)}}
.otto[data-mood=rocket] .eyes{animation:osEyesK 2s ease-in-out infinite alternate}
@keyframes osEyesK{from{transform:translate(-2px,-3px)}to{transform:translate(8px,2px)}}
/* lab: excited bouncing, flask shaking, free arm swinging */
.otto[data-mood=lab] .all{animation:osBounce .5s ease-in-out infinite alternate}
@keyframes osBounce{from{transform:translateY(0) rotate(-2deg)}to{transform:translateY(-8px) rotate(2deg)}}
.otto[data-mood=lab] .armR{animation:osShake .5s ease-in-out infinite alternate}
.otto[data-mood=lab] .armL{animation:osSwL 1s ease-in-out infinite alternate}
@keyframes osShake{from{transform:rotate(-92deg)}to{transform:rotate(-112deg)}}
@keyframes osSwL{from{transform:rotate(10deg)}to{transform:rotate(60deg)}}
.otto[data-mood=lab] .head{animation:osHeadL .5s ease-in-out infinite alternate}
@keyframes osHeadL{from{transform:rotate(-5deg)}to{transform:rotate(5deg)}}
.otto[data-mood=lab] .eyes{animation:osEyesL 1s ease-in-out infinite alternate}
@keyframes osEyesL{from{transform:translate(3px,-2px)}to{transform:translate(7px,2px)}}
.otto[data-mood=lab] .brow{transform:translateY(-4px)}
.otto[data-mood=lab] .tail{animation-duration:.5s}
/* laptop: nodding to the music, typing, glancing around */
.otto[data-mood=laptop] .all{animation:osBeat .5s ease-in-out infinite alternate}
@keyframes osBeat{from{transform:translateY(0)}to{transform:translateY(-4px)}}
.otto[data-mood=laptop] .armL{animation:osType .25s ease-in-out infinite alternate}
.otto[data-mood=laptop] .armR{animation:osTypeR .25s ease-in-out .125s infinite alternate}
@keyframes osType{from{transform:rotate(-34deg)}to{transform:rotate(-46deg)}}@keyframes osTypeR{from{transform:rotate(34deg)}to{transform:rotate(46deg)}}
.otto[data-mood=laptop] .head{animation:osHeadN 1s ease-in-out infinite alternate}
@keyframes osHeadN{from{transform:rotate(-5deg) translateY(0)}to{transform:rotate(5deg) translateY(3px)}}
.otto[data-mood=laptop] .eyes{animation:osEyesN 2s ease-in-out infinite alternate}
@keyframes osEyesN{from{transform:translate(-4px,4px)}to{transform:translate(4px,4px)}}
/* trophy: victory dance */
.otto[data-mood=trophy] .all{animation:osJump 1s ease-in-out infinite}
@keyframes osJump{0%,100%{transform:translateY(0) rotate(-3deg)}50%{transform:translateY(-14px) rotate(3deg)}}
.otto[data-mood=trophy] .bob{animation:none}
.otto[data-mood=trophy] .armL{animation:osTroL .5s ease-in-out infinite alternate}.otto[data-mood=trophy] .armR{animation:osTroR .5s ease-in-out infinite alternate}
@keyframes osTroL{from{transform:rotate(-48deg)}to{transform:rotate(-62deg)}}@keyframes osTroR{from{transform:rotate(48deg)}to{transform:rotate(62deg)}}
.otto[data-mood=trophy] .head{animation:osHeadT 1s ease-in-out infinite alternate}
@keyframes osHeadT{from{transform:rotate(-7deg)}to{transform:rotate(7deg)}}
.otto[data-mood=trophy] .brow{transform:translateY(-3px)}.otto[data-mood=trophy] .tail{animation-duration:.5s}
.otto[data-mood=holo] .m-smile,.otto[data-mood=lab] .m-smile,.otto[data-mood=trophy] .m-smile,.otto[data-mood=rocket] .m-smile{display:none}
.otto[data-mood=holo] .m-open,.otto[data-mood=lab] .m-open,.otto[data-mood=trophy] .m-open,.otto[data-mood=rocket] .m-open{display:block}
.osc[data-scene=trophy] .rays{animation:osSpin 4s linear infinite}
@keyframes osSpin{to{transform:rotate(45deg)}}
.osc .cf{animation:osFall 4s linear infinite}
@keyframes osFall{0%{transform:translateY(0) rotate(0)}100%{transform:translateY(350px) rotate(360deg)}}
.osc .shn{animation:osShine 2s ease-in-out infinite}
@keyframes osShine{0%,100%{opacity:.3}50%{opacity:1}}
/* read */
.osc .pgf{transform-origin:220px 247px;animation:osFlip 4s ease-in-out infinite}
@keyframes osFlip{0%,22%{transform:scaleX(1);opacity:1}38%{transform:scaleX(-1);opacity:1}40%,100%{transform:scaleX(-1);opacity:0}}
.osc .lant{animation:osSwing 4s ease-in-out infinite;transform-origin:220px 30px}
@keyframes osSwing{0%,100%{transform:rotate(-2deg)}50%{transform:rotate(2deg)}}
/* board */
.osc .scr{stroke-dasharray:100;animation:osScr 4s linear infinite}
@keyframes osScr{0%{stroke-dashoffset:100}45%,100%{stroke-dashoffset:0}}
.osc .chk{stroke-dasharray:60;animation:osChk 4s ease-out infinite}
@keyframes osChk{0%,50%{stroke-dashoffset:60}60%,100%{stroke-dashoffset:0}}
.osc .pop1{transform-origin:396px 76px;transform-box:view-box;animation:osPop 4s ease-out infinite}
@keyframes osPop{0%,56%{transform:scale(0)}66%{transform:scale(1.4)}74%,100%{transform:scale(1)}}
.osc .clk{transform-origin:64px 156px;transform-box:view-box;animation:osSpin 4s linear infinite}
/* holo */
.osc .hp{animation:osFloat 4s ease-in-out infinite}.osc .hp2{animation:osFloat 4s ease-in-out -2s infinite}
@keyframes osFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
.osc .scan{animation:osScan 2s linear infinite}
@keyframes osScan{0%{transform:translateY(0);opacity:0}15%{opacity:.4}100%{transform:translateY(172px);opacity:0}}
.osc .ring{stroke-dasharray:100;transform-origin:370px 133px;transform:rotate(-90deg);animation:osRing 4s ease-in-out infinite}
@keyframes osRing{0%,100%{stroke-dashoffset:75}50%{stroke-dashoffset:18}}
.osc .bar{animation:osBar 2s ease-in-out infinite;transform-box:fill-box;transform-origin:bottom}
.osc .b2{animation-delay:-.7s}.osc .b3{animation-delay:-1.3s}
@keyframes osBar{0%,100%{transform:scaleY(.8)}50%{transform:scaleY(3.4)}}
.osc .chip{animation:osChip 4s ease-in-out infinite}.osc .c2{animation-delay:-1s}.osc .c3{animation-delay:-2s}
@keyframes osChip{0%,100%{opacity:.7}50%{opacity:1}}
.osc .wave{stroke-dasharray:140;animation:osWave 2s linear infinite}
@keyframes osWave{to{stroke-dashoffset:-140}}
.osc .rip circle{transform-origin:262px 206px;transform-box:view-box;animation:osRip .5s ease-out infinite}
.osc .rip2 circle{animation-delay:.25s}
@keyframes osRip{0%{transform:scale(.4);opacity:1}100%{transform:scale(3.6);opacity:0}}
.osc .shine{animation:osShine 2s ease-in-out infinite}
/* rocket */
.osc .sc1{animation:osStarL 4s linear infinite}
@keyframes osStarL{to{transform:translateX(-440px)}}
.osc .plt{animation:osPlt 4s linear infinite}
@keyframes osPlt{from{transform:translate(520px,70px)}to{transform:translate(-140px,40px)}}
.osc .rkw{animation:osRk .5s ease-in-out infinite alternate}
@keyframes osRk{from{transform:translateY(-1.5px)}to{transform:translateY(2px)}}
.osc .spd{animation:osSpd .5s linear infinite}
@keyframes osSpd{from{transform:translateX(30px);opacity:.1}to{transform:translateX(-40px);opacity:.7}}
.osc .flm{animation:osFlm .25s ease-in-out infinite alternate;transform-origin:150px 168px;transform-box:view-box}
@keyframes osFlm{from{transform:scale(1,.9)}to{transform:scale(1.18,1.1)}}
/* lab */
.osc .bb{animation:osBub 1s linear infinite}.osc .bb2{animation-delay:-.5s}
@keyframes osBub{0%{transform:translateY(6px);opacity:0}30%{opacity:1}100%{transform:translateY(-14px);opacity:0}}
.osc .ekg{stroke-dasharray:140;animation:osWave 2s linear infinite}
.osc .flow{animation:osFlow 1s linear infinite}
@keyframes osFlow{to{stroke-dashoffset:-15}}
.osc .dial{transform-origin:356px 140px;transform-box:view-box;animation:osSpin 4s linear infinite}
.osc .lvl{transform-origin:342px 171px;transform-box:view-box;animation:osLvl 4s ease-in-out infinite}
@keyframes osLvl{0%,100%{transform:scaleX(.25)}50%{transform:scaleX(1)}}
/* laptop */
.osc .steam{animation:osSteam 2s ease-in-out infinite}
@keyframes osSteam{0%,100%{opacity:.15;transform:translateY(2px)}50%{opacity:.5;transform:translateY(-4px)}}
.osc .o3fx{display:none!important}
/* flame: Otto holds the streak flame (home streak card). Fire layers flicker at different speeds. */
.otto[data-mood=flame] .armR{animation:osTorch 2s ease-in-out infinite alternate}
@keyframes osTorch{from{transform:rotate(-133deg)}to{transform:rotate(-147deg)}}
.otto[data-mood=flame] .armL{animation:osFlL 2s ease-in-out infinite alternate}
@keyframes osFlL{from{transform:rotate(14deg)}to{transform:rotate(26deg)}}
.otto[data-mood=flame] .all{animation:osProud 2s ease-in-out infinite alternate}
@keyframes osProud{from{transform:rotate(-1.5deg) translateY(0)}to{transform:rotate(1.5deg) translateY(-3px)}}
.otto[data-mood=flame] .head{animation:osHeadF 2s ease-in-out infinite alternate}
@keyframes osHeadF{from{transform:rotate(1deg)}to{transform:rotate(-5deg)}}
.otto[data-mood=flame] .eyes{transform:translate(5px,-3px)}
.otto[data-mood=flame] .tail{animation-duration:.5s}
.osc .fl{transform-box:fill-box;transform-origin:50% 100%}
.osc .flm-on{transform-box:fill-box;transform-origin:50% 100%;transform:scale(var(--fs,1.2))}
.osc .fl1{animation:osF1 1s ease-in-out infinite alternate}
.osc .fl2{animation:osF2 .5s ease-in-out infinite alternate}
.osc .fl3{animation:osF3 .5s ease-in-out infinite alternate}
.osc .lk1{animation:osLk 1s ease-in-out infinite alternate}.osc .lk2{animation:osLk 2s ease-in-out infinite alternate-reverse}
@keyframes osF1{from{transform:scale(1,1) skewX(-3deg)}to{transform:scale(.93,1.08) skewX(4deg)}}
@keyframes osF2{from{transform:scale(1.04,.96) skewX(3deg)}to{transform:scale(.92,1.06) skewX(-4deg)}}
@keyframes osF3{from{transform:scale(.95,1) skewX(-2deg)}to{transform:scale(1.06,1.1) skewX(3deg)}}
@keyframes osLk{from{transform:scale(.8,.75) translateY(2px);opacity:.5}to{transform:scale(1.1,1.2);opacity:1}}
.osc .emb{animation:osEmber 4s linear infinite;opacity:0}
@keyframes osEmber{0%{transform:translate(0,0) scale(1);opacity:0}10%{opacity:1}100%{transform:translate(var(--dx,10px),-110px) scale(.2);opacity:0}}
.osc .flm-off{display:none}.osc .coal{animation:osGlow 2s ease-in-out infinite}.osc .smk{animation:osSteam 2s ease-in-out infinite}
.sflm.off .osc .flm-on,.sflm.off .osc .flm-glow,.sflm.off .osc .embs{display:none}.sflm.off .osc .flm-off{display:block}.sflm.off .osc .bgl{opacity:.2;animation:none}

/* well done / try again scenes */
.osc .fwk{animation:osFwk 3.4s ease-out infinite;opacity:0}
@keyframes osFwk{0%{transform:scale(.1);opacity:0}12%{opacity:1}45%{transform:scale(1.15);opacity:1}70%,100%{transform:scale(1.35);opacity:0}}
.osc .bln{animation:osBln 8s linear infinite}
@keyframes osBln{0%{transform:translateY(40px)}100%{transform:translateY(-380px)}}
.osc .sunr{animation:osSunr 5s ease-in-out infinite alternate}
@keyframes osSunr{from{transform:translateY(14px)}to{transform:translateY(-4px)}}
.osc .sunspin{animation:osRot 24s linear infinite}
.osc .rtr{animation:osRot 4.5s cubic-bezier(.5,0,.3,1) infinite}
@keyframes osRot{to{transform:rotate(360deg)}}

.osc .rbt{animation:osBtn 1.6s ease-in-out infinite}
@keyframes osBtn{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
.osc .rpl{animation:osRpl 1.6s ease-out infinite}
@keyframes osRpl{0%{transform:scale(.92);opacity:.9}100%{transform:scale(1.35);opacity:0}}
.osc .cld{animation:osCld 14s linear infinite}
@keyframes osCld{from{transform:translateX(-30px)}to{transform:translateX(40px)}}
.osc .rlb{paint-order:stroke;stroke:#9a5a00;stroke-width:4px;stroke-linejoin:round}

/* dive: floating weightlessly, one paw waves, the other holds the torch */
.otto[data-mood=dive] .all{animation:os2Float 3.4s ease-in-out infinite}
@keyframes os2Float{0%,100%{transform:translateY(0) rotate(-2.5deg)}50%{transform:translateY(-12px) rotate(2.5deg)}}
.otto[data-mood=dive] .bob{animation:none}
.otto[data-mood=dive] .armL{animation:os2DvL 1.1s ease-in-out infinite alternate}
@keyframes os2DvL{from{transform:rotate(126deg)}to{transform:rotate(160deg)}}
.otto[data-mood=dive] .armR{transform:rotate(-104deg);animation:os2DvR 2.6s ease-in-out infinite alternate}
@keyframes os2DvR{from{transform:rotate(-98deg)}to{transform:rotate(-118deg)}}
.otto[data-mood=dive] .head{animation:osHeadL 2.4s ease-in-out infinite alternate}
.otto[data-mood=dive] .tail{animation-duration:1.3s}
.otto[data-mood=dive] .m-smile{display:none}.otto[data-mood=dive] .m-open{display:block}
.osc .rayw{transform-origin:50% 0;transform-box:fill-box;animation:os2Ray 7s ease-in-out infinite alternate}
@keyframes os2Ray{from{transform:rotate(-4deg);opacity:.06}to{transform:rotate(5deg);opacity:.16}}
.osc .bkh{animation:os2Up 9s linear infinite}
@keyframes os2Up{0%{transform:translateY(40px);opacity:0}15%{opacity:.6}100%{transform:translateY(-260px);opacity:0}}
.osc .swd{animation:os2Sway 3s ease-in-out infinite alternate}
@keyframes os2Sway{from{transform:skewX(-9deg)}to{transform:skewX(9deg)}}
.osc .fsh{animation:os2Fish 15s linear infinite}.osc .f2{animation-duration:21s;animation-delay:-8s}.osc .f3{animation-duration:18s;animation-delay:-3s}
.osc .fsh{transform:translate(-80px,var(--y))}
@keyframes os2Fish{from{transform:translate(-80px,var(--y))}50%{transform:translate(260px,calc(var(--y) + 14px))}to{transform:translate(540px,var(--y))}}
.osc .jly{animation:os2Jelly 3s ease-in-out infinite}
@keyframes os2Jelly{0%,100%{transform:translateY(0) scale(1,1)}50%{transform:translateY(-14px) scale(1.06,.92)}}
.osc .lbub{animation:os2Bub 4.2s ease-in infinite;opacity:0}
.osc .lb2{animation-delay:-1s}.osc .lb3{animation-delay:-2.1s}.osc .lb4{animation-delay:-3.2s}
@keyframes os2Bub{0%{transform:translate(0,0) scale(.4);opacity:0}12%{opacity:1}60%{transform:translate(14px,-62px) scale(1)}100%{transform:translate(-8px,-130px) scale(1.15);opacity:0}}

/* bee: spelling it out — paw on the mic, other paw pointing at the letters, antennae bobbing */
.otto[data-mood=bee] .all{animation:os2Hop .8s ease-in-out infinite alternate}
@keyframes os2Hop{from{transform:translateY(0) rotate(-2deg)}to{transform:translateY(-7px) rotate(2deg)}}
.otto[data-mood=bee] .bob{animation:none}
.otto[data-mood=bee] .armR{transform:rotate(112deg);animation:os2MicR .4s ease-in-out infinite alternate}
@keyframes os2MicR{from{transform:rotate(109deg)}to{transform:rotate(115deg)}}
.otto[data-mood=bee] .armL{animation:os2PtL 1s ease-in-out infinite alternate}
@keyframes os2PtL{from{transform:rotate(138deg)}to{transform:rotate(170deg)}}
.otto[data-mood=bee] .head{animation:osHeadT 1.2s ease-in-out infinite alternate}
.otto[data-mood=bee] .m-smile{display:none}.otto[data-mood=bee] .m-open{display:block}
.otto[data-mood=bee] .tail{animation-duration:.45s}
.osc .ant{transform-origin:50% 100%;transform-box:fill-box;animation:os2Ant .6s ease-in-out infinite alternate}.osc .a2{animation-delay:-.3s}
@keyframes os2Ant{from{transform:rotate(-9deg)}to{transform:rotate(9deg)}}
.osc .tl{animation:os2Tile 5s ease-in-out infinite}
@keyframes os2Tile{0%,22%,100%{transform:translateY(0) scale(1);filter:none}5%,14%{transform:translateY(-9px) scale(1.2);filter:drop-shadow(0 0 7px #fff3b0) brightness(1.15)}}
.osc .spt{transform-origin:50% 0;transform-box:fill-box;animation:os2Spot 5s ease-in-out infinite alternate}.osc .sp2{animation-delay:-2.5s}
@keyframes os2Spot{from{transform:rotate(-5deg)}to{transform:rotate(5deg)}}
.osc .beef{animation:os2Bee 11s ease-in-out infinite}
@keyframes os2Bee{0%{transform:translate(52px,200px)}16%{transform:translate(120px,150px)}34%{transform:translate(260px,138px)}52%{transform:translate(388px,150px)}66%{transform:translate(372px,226px)}82%{transform:translate(230px,64px)}100%{transform:translate(52px,200px)}}
.osc .beeb{animation:os2BeeB .5s ease-in-out infinite alternate}
@keyframes os2BeeB{from{transform:translateY(-3px) rotate(-6deg)}to{transform:translateY(3px) rotate(6deg)}}
.osc .wng{transform-box:fill-box;transform-origin:50% 100%;animation:os2Wing .08s linear infinite alternate}
@keyframes os2Wing{from{transform:rotate(-22deg) scaleY(1)}to{transform:rotate(-22deg) scaleY(.45)}}
.osc .w2{animation-delay:-.04s}

/* type: pecking at the keys, head bobbing along the line */
.otto[data-mood=type] .all{animation:os2Sway2 2s ease-in-out infinite alternate}
@keyframes os2Sway2{from{transform:translateX(-1px) rotate(-1deg)}to{transform:translateX(3px) rotate(2deg)}}
.otto[data-mood=type] .armR{animation:os2TyR .22s ease-in-out infinite alternate}
@keyframes os2TyR{from{transform:rotate(4deg) translateY(-4px)}to{transform:rotate(1deg) translateY(2px)}}
.otto[data-mood=type] .armL{animation:os2TyL .22s ease-in-out .11s infinite alternate}
@keyframes os2TyL{from{transform:rotate(-4deg) translateY(-4px)}to{transform:rotate(-1deg) translateY(2px)}}
.otto[data-mood=type] .head{animation:osHeadN 1.2s ease-in-out infinite alternate}
.otto[data-mood=type] .eyes{animation:osEyesH 1.6s ease-in-out infinite alternate}
.otto[data-mood=type] .m-smile{display:block}
.osc .wd{opacity:0;animation:os2Word 8s ease-out infinite}
@keyframes os2Word{0%{opacity:0;transform:translateY(5px)}6%,86%{opacity:1;transform:translateY(0)}94%,100%{opacity:0}}
.osc .ln{stroke-dasharray:80;stroke-dashoffset:80;animation:os2Line 8s ease-out infinite}
@keyframes os2Line{0%{stroke-dashoffset:80;opacity:1}16%{stroke-dashoffset:0;opacity:1}86%{stroke-dashoffset:0;opacity:1}94%,100%{opacity:0;stroke-dashoffset:0}}
.osc .tyw{animation:os2Ty 1.1s ease-in-out infinite alternate}
@keyframes os2Ty{from{transform:translateY(0)}to{transform:translateY(1.4px)}}
.osc .pap{animation:os2Pap 8s ease-in-out infinite}
@keyframes os2Pap{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}

/* pirate: spyglass up, swaying with the ship */
.otto[data-mood=pirate] .all{animation:os2Roll 3.6s ease-in-out infinite alternate}
@keyframes os2Roll{from{transform:rotate(-3deg) translateY(0)}to{transform:rotate(3deg) translateY(-4px)}}
.otto[data-mood=pirate] .bob{animation:none}
.otto[data-mood=pirate] .armR{transform:rotate(-132deg);animation:os2SpyR 2.8s ease-in-out infinite alternate}
@keyframes os2SpyR{from{transform:rotate(-124deg)}to{transform:rotate(-140deg)}}
.otto[data-mood=pirate] .armL{transform:rotate(22deg);animation:os2HipL 3.6s ease-in-out infinite alternate}
@keyframes os2HipL{from{transform:rotate(18deg)}to{transform:rotate(30deg)}}
.otto[data-mood=pirate] .head{animation:osHeadL 2.8s ease-in-out infinite alternate}
.otto[data-mood=pirate] .eyes{animation:osEyesL 2.8s ease-in-out infinite alternate}
.otto[data-mood=pirate] .m-smile{display:none}.otto[data-mood=pirate] .m-open{display:block}
.osc .shp{animation:os2Ship 3.6s ease-in-out infinite alternate;transform-box:view-box;transform-origin:250px 300px}
@keyframes os2Ship{from{transform:rotate(-1.6deg)}to{transform:rotate(1.6deg)}}
.osc .wv1{animation:os2Wv 5s ease-in-out infinite alternate}.osc .wv2{animation:os2Wv 3.4s ease-in-out infinite alternate-reverse}.osc .wv3{animation:os2Wv 4.2s ease-in-out infinite alternate}
@keyframes os2Wv{from{transform:translateX(-30px)}to{transform:translateX(0)}}
.osc .gl{animation:os2Gull 9s linear infinite}.osc .g2{animation-duration:12s;animation-delay:-4s}.osc .g3{animation-duration:10s;animation-delay:-7s}
@keyframes os2Gull{0%{transform:translate(-30px,var(--gy,80px))}100%{transform:translate(480px,calc(var(--gy,80px) - 24px))}}
.osc .g1{--gy:70px}.osc .g2{--gy:110px}.osc .g3{--gy:124px}
.osc .glw{transform-box:fill-box;transform-origin:50% 100%;animation:os2Flap .5s ease-in-out infinite alternate}
@keyframes os2Flap{from{transform:scale(1,1)}to{transform:scale(1,-.7)}}
.osc .flg{animation:os2Flag 1.2s ease-in-out infinite alternate;transform-box:view-box}
@keyframes os2Flag{from{transform:skewY(-5deg)}to{transform:skewY(6deg)}}
.osc .spk{animation:os2Spk 9s ease-in-out infinite}
@keyframes os2Spk{0%{opacity:0;transform:translateY(8px) scale(.8)}4%,30%{opacity:1;transform:none}36%,100%{opacity:0}}
.osc .spk{transform-box:fill-box;transform-origin:50% 100%}


/* exam + practice scenes */
.otto[data-mood=exam] .all{animation:os3Focus 3s ease-in-out infinite alternate}
@keyframes os3Focus{from{transform:translateX(0) rotate(0)}to{transform:translateX(2px) rotate(1.4deg)}}
.otto[data-mood=exam] .bob{animation:none}
.otto[data-mood=exam] .armR{transform:rotate(-50deg);animation:os3Write .5s ease-in-out infinite alternate}
@keyframes os3Write{from{transform:rotate(-46deg)}to{transform:rotate(-58deg)}}
.otto[data-mood=exam] .armL{transform:rotate(-26deg);animation:os3Hold 3s ease-in-out infinite alternate}
@keyframes os3Hold{from{transform:rotate(-26deg)}to{transform:rotate(-30deg)}}
.otto[data-mood=exam] .head{animation:osHeadN 1.4s ease-in-out infinite alternate}
.otto[data-mood=exam] .eyes{animation:osEyesH 1.8s ease-in-out infinite alternate}
.osc .sh{animation:os3Tick 10s steps(10) infinite}
.osc .mh{animation:os3Tick 90s linear infinite}
.osc .hh{animation:os3Tick 1080s linear infinite}
@keyframes os3Tick{to{transform:rotate(360deg)}}
.osc .tring{animation:os3Ring 24s linear infinite}
@keyframes os3Ring{from{stroke-dashoffset:0}to{stroke-dashoffset:352}}
.osc .swt{animation:os3Sweat 3.2s ease-in infinite;opacity:0}
@keyframes os3Sweat{0%,30%{opacity:0;transform:translateY(-4px)}40%{opacity:.9}100%{opacity:0;transform:translateY(16px)}}

.otto[data-mood=practice] .all{animation:os3Lean 2.4s ease-in-out infinite alternate}
@keyframes os3Lean{from{transform:rotate(-1deg)}to{transform:rotate(2.5deg) translateX(3px)}}
.otto[data-mood=practice] .bob{animation:none}
.otto[data-mood=practice] .armR{transform:rotate(-76deg);animation:os3Lens 2.6s ease-in-out infinite alternate}
@keyframes os3Lens{from{transform:rotate(-64deg)}to{transform:rotate(-92deg)}}
.otto[data-mood=practice] .armL{transform:rotate(14deg)}
.otto[data-mood=practice] .head{animation:osHeadN 1.6s ease-in-out infinite alternate}
.otto[data-mood=practice] .eyes{animation:osEyesH 2s ease-in-out infinite alternate}
.otto[data-mood=practice] .m-smile{display:block}
.osc .tkc{stroke-dasharray:30;stroke-dashoffset:30;animation:os3Tk 7.8s ease-out infinite}
@keyframes os3Tk{0%{stroke-dashoffset:30;opacity:1}8%,86%{stroke-dashoffset:0;opacity:1}94%,100%{opacity:0;stroke-dashoffset:0}}
.osc .scs{transform-box:fill-box;transform-origin:center;animation:os3Star 1.4s ease-in-out infinite alternate}
@keyframes os3Star{from{transform:scale(1) rotate(-8deg)}to{transform:scale(1.25) rotate(10deg)}}

/* topics + arcade hub scenes (4s loops) */
.osc .tpc{animation:tpPop 4s ease-in-out infinite;transform-box:fill-box;transform-origin:left center;opacity:0}
@keyframes tpPop{0%{transform:translateX(26px);opacity:0}12%{transform:translateX(0);opacity:1}88%{transform:translateX(0);opacity:1}100%{transform:translateX(26px);opacity:0}}
.osc .tpk{stroke-dasharray:26;stroke-dashoffset:26;animation:tpTick 4s ease-in-out infinite}
@keyframes tpTick{0%,30%{stroke-dashoffset:26}45%,90%{stroke-dashoffset:0}100%{stroke-dashoffset:26}}
.osc .tpf{transform-box:fill-box;transform-origin:left center;animation:tpFill 4s ease-in-out infinite}
@keyframes tpFill{0%{transform:scaleX(.04)}85%,100%{transform:scaleX(1)}}
.osc .tpb{animation:tpBob 2s ease-in-out infinite;transform-box:fill-box;transform-origin:center}
@keyframes tpBob{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-8px) rotate(4deg)}}
.osc .arst{transform-box:fill-box;transform-origin:center bottom;animation:arStick .5s ease-in-out infinite alternate}
@keyframes arStick{from{transform:rotate(-16deg)}to{transform:rotate(16deg)}}
.osc .arb{animation:arBtn 1s steps(1) infinite}
@keyframes arBtn{0%{opacity:1}50%{opacity:.4}}
.osc .art{transform-box:fill-box;transform-origin:center bottom;animation:arTile 2s ease-in-out infinite}
@keyframes arTile{0%,100%{transform:translateY(0)}50%{transform:translateY(-9px)}}
.osc .arc{animation:arFall 2s linear infinite}
@keyframes arFall{0%{transform:translateY(0);opacity:0}15%{opacity:1}85%{opacity:1}100%{transform:translateY(40px);opacity:0}}
.osc .arsc{opacity:0;animation:arScore 4s steps(1) infinite}
@keyframes arScore{0%{opacity:1}25%,100%{opacity:0}}

/* held props: soft shadow so they sit in Otto's paw instead of looking pasted on */
.osc .hold{filter:drop-shadow(1px 2.5px 1.6px rgba(8,4,28,.5))}
.osc .tsw{animation:tsSway 3.2s ease-in-out infinite alternate;transform-box:view-box}
@keyframes tsSway{from{transform:rotate(-2.2deg)}to{transform:rotate(2.2deg)}}

/* typing: keys press down in turn */
.osc .ky0{animation:kyP .44s ease-in-out infinite alternate}.osc .ky1{animation:kyP .44s ease-in-out .11s infinite alternate}.osc .ky2{animation:kyP .44s ease-in-out .22s infinite alternate}.osc .ky3{animation:kyP .44s ease-in-out .33s infinite alternate}
@keyframes kyP{from{transform:translateY(0)}to{transform:translateY(1.6px)}}
