/* Roxy, the HR for I.T support dog: the character rig from Docs/Roxy/roxy-character-demo.html. */
/* ---------------------------------------------------------------
   ROXY RIG
   Everything below styles the SVG template cloned by Roxy.mount().
   Pose = CSS custom properties set per [data-state]; one-shot
   motion = keyframes that read those same properties, so a twitch
   or wag starts from wherever the pose left the part.
   --------------------------------------------------------------- */
.roxy{
  display:block;width:100%;height:100%;overflow:hidden;
  --head-r:0deg; --head-y:0px; --look-r:0deg; --look-x:0px; --look-y:0px;
  --ear-l:0deg; --ear-r:0deg;
  --lid:.14; --lid-lo:0;
  --brow-l-y:0px; --brow-l-r:0deg; --brow-r-y:0px; --brow-r-r:0deg;
  --paw-l:translate(0px,90px); --paw-r:translate(0px,90px);
  --tail-r:0deg;
  --spring:cubic-bezier(.34,1.45,.64,1);
}
.roxy .fur-black{fill:#1b1b1f}
.roxy .fur-patch{fill:#232329}
.roxy .fur-white{fill:#f7f5f0}
.roxy .fur-shade{fill:#dcd7cd}
.roxy .pink{fill:#d8949c}
.roxy .collar{stroke:#2f6bff}
/* outlines: dark ink on light shapes, soft rim on dark shapes; paint-order keeps the stroke outside the fill */
.roxy .ink{stroke:#15151a;stroke-width:2.4;stroke-linejoin:round;paint-order:stroke fill}
.roxy .ink-thin{stroke:#15151a;stroke-width:1.4;stroke-linejoin:round;paint-order:stroke fill}
.roxy .fur-strands{fill:none;stroke-linecap:round;pointer-events:none}
.roxy .rim{stroke:#5a5a66;stroke-width:2.4;stroke-linejoin:round;paint-order:stroke fill}

.roxy .body-anim{transform-origin:160px 340px}
.roxy .head{transform:translate(0,var(--head-y)) rotate(calc(var(--head-r) + var(--look-r)));transform-origin:160px 238px;transition:transform .5s var(--spring)}
.roxy .head-anim{transform-origin:160px 238px}
.roxy .ear-l{transform:rotate(var(--ear-l));transform-origin:118px 112px;transition:transform .45s var(--spring)}
.roxy .ear-r{transform:rotate(var(--ear-r));transform-origin:118px 112px;transition:transform .45s var(--spring)}
.roxy .pupils{transform:translate(var(--look-x),var(--look-y));transition:transform .22s ease-out}
.roxy .lid{transform:scaleY(var(--lid));transform-origin:0 -13px;transition:transform .09s ease-out}
.roxy .lid-lo{transform:scaleY(var(--lid-lo));transform-origin:0 13px;transition:transform .12s ease-out}
.roxy .brow-l{transform:translate(0,var(--brow-l-y)) rotate(var(--brow-l-r));transform-origin:137px 124px;transition:transform .35s var(--spring)}
.roxy .brow-r{transform:translate(0,var(--brow-r-y)) rotate(var(--brow-r-r));transform-origin:137px 124px;transition:transform .35s var(--spring)}
.roxy .paw-l{transform:var(--paw-l);transform-origin:84px 330px;transition:transform .55s var(--spring)}
.roxy .paw-r{transform:var(--paw-r);transform-origin:84px 330px;transition:transform .55s var(--spring)}
.roxy .tail{transform:rotate(var(--tail-r));transform-origin:246px 324px;transition:transform .5s var(--spring)}
.roxy .happy-arc,.roxy .mouth-smile,.roxy .mouth-o,.roxy .mark,.roxy .zzz,.roxy .dots{opacity:0;transition:opacity .2s}
.roxy .mark{transform:scale(.4);transform-origin:240px 100px}
.roxy .mouth-open{transform:scaleY(0);transform-origin:160px 237px;transition:transform .07s ease-out}
.roxy .mouth-closed{transition:opacity .07s}

/* mouth visemes (set by Roxy.say) */
.roxy[data-mouth="s"] .mouth-open{transform:scaleY(.35)}
.roxy[data-mouth="m"] .mouth-open{transform:scaleY(.65)}
.roxy[data-mouth="l"] .mouth-open{transform:scaleY(1)}
.roxy[data-mouth="o"] .mouth-o{opacity:1}
.roxy:not([data-mouth="closed"]) .mouth-closed{opacity:0}

/* blink + ear twitch (classes toggled by JS) */
.roxy.blink{--lid:1}
.roxy .ear-l.twitch{animation:twitch-l .42s ease-in-out}
.roxy .ear-r.twitch{animation:twitch-l .42s ease-in-out}
@keyframes twitch-l{0%{transform:rotate(var(--ear-l))}35%{transform:rotate(calc(var(--ear-l) - 16deg))}65%{transform:rotate(calc(var(--ear-l) + 6deg))}100%{transform:rotate(var(--ear-l))}}

/* continuous idle life */
.roxy .body-anim{animation:breathe 3.4s ease-in-out infinite}
.roxy .tail{animation:sway 2.8s ease-in-out infinite}
@keyframes breathe{0%,100%{transform:scale(1,1)}50%{transform:scale(1.008,1.022)}}
@keyframes sway{0%,100%{transform:rotate(calc(var(--tail-r) - 5deg))}50%{transform:rotate(calc(var(--tail-r) + 5deg))}}
@keyframes wag{0%{transform:rotate(calc(var(--tail-r) - 24deg))}100%{transform:rotate(calc(var(--tail-r) + 24deg))}}
@keyframes nod{0%,100%{transform:translateY(0) rotate(0)}45%{transform:translateY(2.5px) rotate(1.2deg)}}
@keyframes bob{0%,100%{transform:translateY(0) rotate(0)}30%{transform:translateY(-1.5px) rotate(-1deg)}70%{transform:translateY(1px) rotate(1deg)}}
@keyframes bounce{0%,100%{transform:translateY(0)}40%{transform:translateY(-7px)}}
@keyframes hop{0%{transform:translateY(0)}35%{transform:translateY(-14px)}60%{transform:translateY(0)}75%{transform:translateY(-4px)}100%{transform:translateY(0)}}
@keyframes wave{0%{transform:var(--paw-l) rotate(-12deg)}100%{transform:var(--paw-l) rotate(14deg)}}
@keyframes pop{0%{opacity:0;transform:scale(.4)}60%{opacity:1;transform:scale(1.15)}100%{opacity:1;transform:scale(1)}}
@keyframes drift{0%{opacity:0;transform:translate(0,6px)}25%{opacity:1}100%{opacity:0;transform:translate(10px,-26px)}}
@keyframes dot{0%,100%{opacity:.25}50%{opacity:1}}
@keyframes tongue{0%,100%{transform:scaleY(1)}50%{transform:scaleY(1.08)}}
@keyframes paws-up{0%{transform:var(--paw-l) translateY(0)}100%{transform:var(--paw-l) translateY(-8px)}}
@keyframes paws-up-r{0%{transform:var(--paw-r) translateY(0)}100%{transform:var(--paw-r) translateY(-8px)}}

/* ----- states ----- */
.roxy[data-state="listening"]{--head-r:9deg;--ear-l:14deg;--ear-r:14deg;--lid:.08;--brow-l-y:-2px;--brow-r-y:-2px}
.roxy[data-state="listening"] .head-anim{animation:nod 2.4s ease-in-out infinite}

.roxy[data-state="thinking"]{--head-r:-7deg;--head-y:-2px;--look-x:3.5px;--look-y:-3.5px;--ear-l:10deg;--ear-r:-30deg;--brow-l-y:-3px;--brow-r-y:1px;--brow-r-r:-8deg;--paw-l:translate(56px,-26px);--lid:.3}
.roxy[data-state="thinking"] .dots{opacity:1}
.roxy[data-state="thinking"] .dots circle{animation:dot 1.4s ease-in-out infinite}
.roxy[data-state="thinking"] .dots circle:nth-child(2){animation-delay:.25s}
.roxy[data-state="thinking"] .dots circle:nth-child(3){animation-delay:.5s}
.roxy[data-state="thinking"] .tail{animation-duration:4.5s}

.roxy[data-state="talking"]{--head-r:2deg;--brow-l-y:-1.5px;--brow-r-y:-1.5px;--ear-l:8deg;--ear-r:8deg}
.roxy[data-state="talking"] .head-anim{animation:bob 1.1s ease-in-out infinite}
.roxy[data-state="talking"] .tail{animation:wag .6s ease-in-out infinite alternate}

.roxy[data-state="happy"],.roxy[data-state="celebrate"]{--lid:1;--ear-l:6deg;--ear-r:6deg;--head-r:-4deg;--brow-l-y:-3px;--brow-r-y:-3px}
.roxy[data-state="happy"] .happy-arc,.roxy[data-state="celebrate"] .happy-arc{opacity:1}
.roxy[data-state="happy"] .mouth-smile,.roxy[data-state="celebrate"] .mouth-smile{opacity:1}
.roxy[data-state="happy"] .mouth-closed,.roxy[data-state="celebrate"] .mouth-closed{opacity:0}
.roxy[data-state="happy"] .tongue-out,.roxy[data-state="celebrate"] .tongue-out{animation:tongue .5s ease-in-out infinite;transform-origin:160px 242px}
.roxy[data-state="happy"] .tail,.roxy[data-state="celebrate"] .tail{animation:wag .26s ease-in-out infinite alternate}
.roxy[data-state="happy"] .body-anim{animation:bounce .55s ease-in-out infinite}

.roxy[data-state="confused"]{--head-r:15deg;--ear-l:16deg;--ear-r:-36deg;--brow-l-y:-4px;--brow-l-r:-10deg;--brow-r-y:2px;--brow-r-r:12deg;--look-x:-2px;--look-y:-1px;--lid:.2}
.roxy[data-state="confused"] .mouth-o{opacity:1}
.roxy[data-state="confused"] .mouth-closed{opacity:0}
.roxy[data-state="confused"] .mark-q{animation:pop .5s var(--spring) forwards}
.roxy[data-state="confused"] .tail{animation:none}

.roxy[data-state="sorry"]{--head-y:9px;--ear-l:-34deg;--ear-r:-34deg;--brow-l-y:-1px;--brow-l-r:-16deg;--brow-r-y:-1px;--brow-r-r:-16deg;--look-y:3px;--lid:.38;--tail-r:-28deg}
.roxy[data-state="sorry"] .tail{animation:none}
.roxy[data-state="sorry"] .mouth-closed{opacity:0}
.roxy[data-state="sorry"] .mouth-flat{opacity:1}
.roxy .mouth-flat{opacity:0;transition:opacity .2s}

.roxy[data-state="alert"]{--ear-l:20deg;--ear-r:20deg;--lid:0;--head-y:-5px;--brow-l-y:-4px;--brow-r-y:-4px;--tail-r:12deg}
.roxy[data-state="alert"] .body-anim{animation:hop .6s ease-out 1}
.roxy[data-state="alert"] .mark-ex{animation:pop .4s var(--spring) forwards}
.roxy[data-state="alert"] .mouth-o{opacity:1}
.roxy[data-state="alert"] .mouth-closed{opacity:0}

.roxy[data-state="sleeping"]{--lid:1;--head-r:8deg;--head-y:12px;--ear-l:-18deg;--ear-r:-18deg;--tail-r:-22deg;--brow-l-y:2px;--brow-r-y:2px}
.roxy[data-state="sleeping"] .body-anim{animation-duration:5.2s}
.roxy[data-state="sleeping"] .tail{animation:none}
.roxy[data-state="sleeping"] .zzz{opacity:1}
.roxy[data-state="sleeping"] .zzz text{animation:drift 3s ease-out infinite}
.roxy[data-state="sleeping"] .zzz text:nth-child(2){animation-delay:1s}
.roxy[data-state="sleeping"] .zzz text:nth-child(3){animation-delay:2s}

.roxy[data-state="greet"]{--head-r:-8deg;--paw-l:translate(-2px,-74px);--lid:.22;--ear-l:10deg;--ear-r:10deg;--brow-l-y:-3px;--brow-r-y:-3px}
.roxy[data-state="greet"] .paw-l{animation:wave .32s ease-in-out infinite alternate}
.roxy[data-state="greet"] .tail{animation:wag .3s ease-in-out infinite alternate}
.roxy[data-state="greet"] .mouth-smile{opacity:1}
.roxy[data-state="greet"] .mouth-closed{opacity:0}

.roxy[data-state="celebrate"]{--paw-l:translate(6px,-92px);--paw-r:translate(6px,-92px);--head-r:0deg;--head-y:-4px}
.roxy[data-state="celebrate"] .paw-l{animation:paws-up .28s ease-in-out infinite alternate}
.roxy[data-state="celebrate"] .paw-r{animation:paws-up-r .28s ease-in-out infinite alternate-reverse}
.roxy[data-state="celebrate"] .body-anim{animation:hop .7s ease-out infinite}

.roxy[data-state="static"] *{animation:none !important}

@media (prefers-reduced-motion: reduce){
  .roxy .body-anim,.roxy .tail,.roxy .head-anim,.roxy .paw-l,.roxy .paw-r,.roxy .tongue-out,.roxy .zzz text,.roxy .dots circle{animation:none !important}
  .roxy .head,.roxy .ear-l,.roxy .ear-r,.roxy .brow-l,.roxy .brow-r,.roxy .paw-l,.roxy .paw-r,.roxy .tail{transition-duration:.01s}
  .roxy .mark{opacity:1;transform:none;animation:none !important}
  .roxy:not([data-state="confused"]) .mark-q,.roxy:not([data-state="alert"]) .mark-ex{opacity:0}
}
