:root{font-family:system-ui,sans-serif;color:#323643;background:#fff;--teacher-size:128px;--teacher-active:128px;--accent:#6c7aa6}
*{box-sizing:border-box}html,body{width:100%;height:100%;margin:0;overflow:hidden;background:#fff}body{height:100dvh}#board{position:fixed;inset:0;width:100%;height:100%;overflow:hidden;touch-action:manipulation}#board text,[data-annotation-layer]{display:none}
#teacher{position:fixed;left:50%;top:50%;width:var(--teacher-size);height:var(--teacher-size);padding:0;border:0;border-radius:16px;background:transparent;color:var(--accent);cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transform:translate(-50%,-50%);transition:width .4s,height .4s,background .45s,border-color .45s,border-radius .45s,box-shadow .3s;z-index:2;will-change:left,top}
#teacher:focus-visible{outline:2px solid #9daada;outline-offset:7px}#teacher:disabled{cursor:default}.teacher-art{width:100%;height:100%;overflow:visible;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}.character{transform-origin:48px 48px;transition:transform .7s cubic-bezier(.2,.75,.2,1);filter:drop-shadow(0 3px 2.5px rgba(40,50,85,.18))}.sleep-shadow{fill:#3a4668;stroke:none;opacity:.14;transform-origin:47px 86px;transition:opacity .5s,transform .5s}.sleep-eyes{opacity:0;transition:opacity .2s}.eyes{transition:opacity .15s}.teacher-art{transition:transform .08s}
#teacher[data-state=idle] .character{transform:translateY(16px) rotate(80deg)}#teacher[data-state=idle]:hover .character{transform:translateY(13px) rotate(76deg)}#teacher[data-state=idle] .chalk-body{transform-origin:48px 48px;animation:sleep-breath 4s ease-in-out infinite}#teacher[data-state=idle] .sleep-shadow{opacity:.22;transform:translateY(-6px);animation:sleep-shadow 4s ease-in-out infinite}#teacher[data-state=idle] .eyes{opacity:0}#teacher[data-state=idle] .sleep-eyes{opacity:1}#teacher[data-state=idle] .smile{opacity:0}#teacher[data-state=idle] .mouth{opacity:.65;transform:scale(.6)}
#teacher[data-waking=true] .character{animation:wake-up 1.1s cubic-bezier(.2,.65,.25,1) both}#teacher[data-waking=true] .eyes{animation:wake-eyes 1.1s both}#teacher[data-waking=true] .sleep-eyes{animation:wake-lids 1.1s both}#teacher[data-waking=true] .chalk-body{animation:none}
.chalk-body{transform-origin:43px 80px;transition:transform .32s}.chalk-outline{fill:url(#chalk-shade);stroke:#5b6a94;stroke-width:1.9}.chalk-edge{stroke:#b7c2dc;stroke-width:1.2}.face{color:#2f3b5c;transition:transform .22s}.eye-white{fill:#fff;stroke:currentColor;stroke-width:1.05}.pupil{fill:currentColor;stroke:none}.eye-white,.pupil{transform-box:fill-box;transform-origin:center;animation:blink 6.7s infinite}.pupils{transform:translate(var(--gaze-x,0px),var(--gaze-y,.4px));transition:transform .28s}.blush{fill:#e2907a;stroke:none;opacity:0;transition:opacity .35s}.doodle{opacity:0;stroke:#8f9ab8;stroke-width:1.3}.brows{stroke-width:1.6;opacity:0;transition:opacity .2s}.brow-left,.brow-right{transform-box:fill-box;transform-origin:center;transition:transform .25s}.smile{stroke-width:1.8}.mouth{fill:currentColor;stroke:none;opacity:0;transform-origin:48px 54px;transform:scale(var(--mouth-w,1),var(--mouth,.2))}.listening-lines{opacity:0;stroke:#a9b4d3;stroke-width:1.3;transition:opacity .25s}
#teacher[data-state=listening] .chalk-body{animation:attentive 3.6s ease-in-out infinite}#teacher[data-state=listening] .face{transform:translate(calc(var(--gaze-x,0px) * .3),calc(var(--gaze-y,0px) * .3))}#teacher[data-hearing=true] .listening-lines{opacity:.8}#teacher[data-hearing=true] .eyes{transform:translateY(-1px)}
#teacher[data-state=thinking] .chalk-body,#teacher[data-state=connecting] .chalk-body{animation:ponder 2.6s ease-in-out infinite}#teacher[data-state=thinking] .face,#teacher[data-state=connecting] .face{transform:translate(2px,-4px)}#teacher[data-state=thinking] .brows,#teacher[data-state=connecting] .brows{opacity:1}#teacher[data-state=thinking] .brow-left,#teacher[data-state=connecting] .brow-left{transform:rotate(-18deg) translateY(-1px)}#teacher[data-state=thinking] .smile,#teacher[data-state=connecting] .smile{transform:translate(2px,0) scaleX(.93)}
#teacher[data-state=drawing] .chalk-body{transform:rotate(13deg)}#teacher[data-state=drawing] .face{transform:translate(-2px,3px)}#teacher[data-state=drawing] .brows{opacity:1}#teacher[data-state=drawing] .brow-left{transform:rotate(12deg)}#teacher[data-state=drawing] .brow-right{transform:rotate(-12deg)}
#teacher[data-state=speaking] .chalk-body{animation:explain 1.9s ease-in-out infinite}#teacher[data-speaking=true] .smile{opacity:0}#teacher[data-speaking=true] .mouth{opacity:1}#teacher[data-pointing=true] .chalk-body{transform:rotate(-12deg)}
#teacher[data-state=error] .brows,#teacher[data-state=blocked] .brows{opacity:1}#teacher[data-state=error] .brow-left,#teacher[data-state=blocked] .brow-left{transform:rotate(-20deg) translateY(-2px)}#teacher[data-state=error] .brow-right,#teacher[data-state=blocked] .brow-right{transform:rotate(20deg) translateY(-2px)}#teacher[data-state=error] .smile,#teacher[data-state=blocked] .smile{transform:scaleY(-1) translateY(1px)}#teacher[data-state=error] .chalk-body,#teacher[data-state=blocked] .chalk-body{transform:rotate(-8deg)}#teacher[data-state=closing] .chalk-body{transform:rotate(12deg) scale(.9)}#teacher[data-state=closing] .eyes{transform:scaleY(.25)}
.pointing-arm{opacity:0;pointer-events:none;transition:opacity .16s}.pointing-hand,.resting-hand{fill:#fcfcff}.finger-fold{stroke-width:1}.arm{stroke-width:2.2}#teacher[data-pointing=true] .pointing-arm{opacity:1}#teacher[data-pointing=true] .chalk-body{animation:none;transform:none}#teacher[data-pointing=true][data-arm-side=left] .resting-arm{opacity:0}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
@keyframes blink{0%,42%,46%,100%{transform:scaleY(1)}44%{transform:scaleY(.08)}}@keyframes attentive{0%,100%{transform:rotate(-3deg)}50%{transform:rotate(2deg) translateY(-2px)}}@keyframes ponder{0%,100%{transform:rotate(-7deg)}45%,65%{transform:rotate(5deg) translateY(-3px)}}@keyframes explain{0%,100%{transform:rotate(0)}50%{transform:rotate(-3deg) translateY(-2px)}}
@keyframes sleep-breath{0%,100%{transform:scale(1,.97)}50%{transform:scale(1.025,1.02)}}@keyframes sleep-shadow{0%,100%{transform:scaleX(.94);opacity:.7}50%{transform:scaleX(1);opacity:1}}@keyframes wake-up{0%{transform:translateY(16px) rotate(80deg)}30%{transform:translateY(17px) rotate(85deg) scale(.97)}65%{transform:translateY(-7px) rotate(-10deg)}83%{transform:translateY(2px) rotate(4deg)}100%{transform:translateY(0) rotate(0)}}@keyframes wake-eyes{0%,35%{opacity:0}48%{opacity:1}58%{opacity:0}72%,100%{opacity:1}}@keyframes wake-lids{0%,35%{opacity:1}48%{opacity:0}58%{opacity:1}72%,100%{opacity:0}}
/* Brows follow the voice while speaking; moods shape the face for a whole beat. */
.brows{transform:translateY(calc(-1 * var(--brow-lift,0px)))}#teacher[data-speaking=true] .brows{opacity:1}
#teacher[data-state=listening][data-hearing=true] .face{animation:nod 1.15s ease-in-out infinite}#teacher[data-state=listening][data-hearing=true] .brows{opacity:1}#teacher[data-state=listening][data-hearing=true] .brow-left,#teacher[data-state=listening][data-hearing=true] .brow-right{transform:translateY(-1.5px)}
#teacher[data-state=drawing] .character{transform:translate(4px,1px)}#teacher[data-state=speaking][data-pointing=false] .character{transform:translateX(2px)}
#teacher[data-mood]:not([data-state=error]):not([data-state=blocked]) .brows{opacity:1}
#teacher[data-mood=curious] .brow-left{transform:rotate(-10deg) translateY(-1.5px)}#teacher[data-mood=curious] .brow-right{transform:translateY(-2px)}#teacher[data-mood=curious] .eyes{transform:scale(1.06,1.14)}#teacher[data-mood=curious] .face{transform:translate(1px,-1px)}
#teacher[data-mood=delighted] .brow-left,#teacher[data-mood=delighted] .brow-right{transform:translateY(-2.2px)}#teacher[data-mood=delighted] .smile{transform:scale(1.3,1.5)}#teacher[data-mood=delighted] .eyes{transform:scaleY(.8)}#teacher[data-mood=delighted] .character{transform:translateY(-1px)}#teacher[data-mood=delighted] .blush{opacity:.8}
#teacher[data-mood=thoughtful] .brow-left{transform:rotate(-14deg) translateY(-1px)}#teacher[data-mood=thoughtful] .brow-right{transform:rotate(4deg)}#teacher[data-mood=thoughtful] .smile{transform:translate(1px,0) scaleX(.85)}#teacher[data-mood=thoughtful] .face{transform:translate(2px,-2px)}#teacher[data-mood=thoughtful] .eyes{transform:scaleY(.72)}
#teacher[data-mood=reassuring] .brow-left{transform:rotate(9deg) translateY(-1px)}#teacher[data-mood=reassuring] .brow-right{transform:rotate(-9deg) translateY(-1px)}#teacher[data-mood=reassuring] .smile{transform:scaleX(1.15)}#teacher[data-mood=reassuring] .face{transform:translateY(1px)}#teacher[data-mood=reassuring] .eyes{transform:scaleY(.92)}
#teacher[data-mood=playful] .brow-right{transform:rotate(-18deg) translateY(-2.5px)}#teacher[data-mood=playful] .brow-left{transform:translateY(.5px)}#teacher[data-mood=playful] .smile{transform:translate(2px,0) scale(1.15,1.2)}#teacher[data-mood=playful] .character{transform:rotate(-5deg)}#teacher[data-mood=playful] .eyes{transform:scaleY(.95)}
.smile,.eyes{transform-box:fill-box;transform-origin:center;transition:transform .3s}
/* Reactions: brief flourishes on top of state and mood. */
#teacher[data-reaction=proud] .character{animation:proud-bounce .9s cubic-bezier(.3,.8,.3,1)}#teacher[data-reaction=proud] .smile{transform:scale(1.35,1.6)}#teacher[data-reaction=proud] .eyes{transform:scaleY(.7)}#teacher[data-reaction=proud] .brow-left,#teacher[data-reaction=proud] .brow-right{transform:translateY(-2.5px)}
#teacher[data-reaction=startled] .character{animation:startle .6s cubic-bezier(.2,.8,.3,1)}#teacher[data-reaction=startled] .eyes{transform:scale(1.25,1.3);animation:none}#teacher[data-reaction=startled] .brows{opacity:1}#teacher[data-reaction=startled] .brow-left,#teacher[data-reaction=startled] .brow-right{transform:translateY(-3px)}#teacher[data-reaction=startled] .smile{transform:scale(.6,1.6)}
#teacher[data-state=error] .character,#teacher[data-state=blocked] .character{animation:shrug .8s ease-out}
/* Gestures: a presenting sweep, a double tap, a chin tap while thinking, a lean while listening; and idle life. */
#teacher[data-gesture=sweep] .pointing-arm{opacity:1;transform-origin:63px 55px;animation:sweep 1.3s ease-in-out}#teacher[data-gesture=sweep][data-pointing=false] .chalk-body{animation:none;transform:rotate(-4deg)}
#teacher[data-gesture=tap] .pointing-arm{animation:tap .7s ease-in-out}
#teacher[data-state=thinking] .resting-arm{transform-origin:32px 55px;animation:chin-tap 2.6s ease-in-out infinite}
#teacher[data-hearing=true] .character{transform:translate(-2px,1px) scale(1.04)}
#teacher[data-gesture=fidget] .character{animation:fidget .9s ease-in-out}
#teacher[data-gesture=doodle] .doodle{animation:doodle 2.6s ease-in-out}#teacher[data-gesture=doodle] .resting-arm{transform-origin:32px 55px;animation:scribble 2.6s ease-in-out}
#teacher[data-gesture=yawn] .mouth{opacity:1;transform:scale(1.25,2.8);transition:transform .5s}#teacher[data-gesture=yawn] .smile{opacity:0}#teacher[data-gesture=yawn] .eyes{transform:scaleY(.15)}#teacher[data-gesture=yawn] .brow-left,#teacher[data-gesture=yawn] .brow-right{transform:translateY(-2px)}#teacher[data-gesture=yawn] .brows{opacity:1}
@keyframes sweep{0%{transform:rotate(18deg)}45%{transform:rotate(-26deg)}75%{transform:rotate(-20deg)}100%{transform:rotate(18deg)}}
@keyframes tap{0%,100%{transform:translate(0,0)}25%{transform:translate(3px,1px)}50%{transform:translate(0,0)}75%{transform:translate(3px,1px)}}
@keyframes chin-tap{0%,100%{transform:rotate(0)}30%,60%{transform:rotate(-38deg) translate(6px,-2px)}45%{transform:rotate(-34deg) translate(6px,-1px)}}
@keyframes fidget{0%,100%{transform:rotate(0)}30%{transform:rotate(-3deg) translateY(1px)}60%{transform:rotate(2.5deg)}}
@keyframes doodle{0%{opacity:0;stroke-dasharray:40;stroke-dashoffset:40}20%{opacity:1}55%{stroke-dashoffset:0;opacity:1}85%{opacity:.5}100%{opacity:0;stroke-dashoffset:0}}
@keyframes scribble{0%,100%{transform:rotate(0)}15%{transform:rotate(-22deg) translate(4px,4px)}30%{transform:rotate(-18deg) translate(4px,5px)}45%{transform:rotate(-24deg) translate(5px,4px)}60%{transform:rotate(-16deg) translate(4px,5px)}80%{transform:rotate(-10deg)}}
@keyframes nod{0%,100%{transform:translate(calc(var(--gaze-x,0px) * .3),calc(var(--gaze-y,0px) * .3))}50%{transform:translate(calc(var(--gaze-x,0px) * .3),calc(var(--gaze-y,0px) * .3 + 1.6px))}}
@keyframes proud-bounce{0%{transform:translateY(0)}30%{transform:translateY(-6px) scale(1.04,.98)}55%{transform:translateY(1px) scale(.99,1.02)}75%{transform:translateY(-2px)}100%{transform:translateY(0)}}
@keyframes startle{0%{transform:translate(0,0)}25%{transform:translate(-3px,-4px) rotate(-4deg)}60%{transform:translate(1px,0) rotate(2deg)}100%{transform:translate(0,0)}}
@keyframes shrug{0%{transform:translateY(0)}35%{transform:translateY(-3px) rotate(-3deg)}70%{transform:translateY(0) rotate(2deg)}100%{transform:none}}
@media(max-width:600px){:root{--teacher-size:92px;--teacher-active:92px}}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}#teacher{will-change:auto}}
