/* 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}
