/** Shopify CDN: Minification failed

Line 267:64 Unexpected ")"

**/
/* Toot mascot — generated by toot-lab/build-theme.mjs; do not hand-edit */
/* the site is permanently light — pin Toot's palette (no OS dark-scheme override) */
#toot-layer,#tipbubble{--surface:#fffdf9;--ink:#26211c;--muted:#8a7f72;--line:#e7dccb;
  --berry:#a5263b;--berry2:#c04a3d;--gold:#d8913a;--bg:#f6f0e7}

/* Toot overlay + size panel */
#toot-layer{position:fixed;inset:0;z-index:40;pointer-events:none}
.toot-wrap{position:fixed;left:0;top:0;width:100px;height:100px;will-change:transform;pointer-events:auto;cursor:pointer;
  -webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;user-select:none;-webkit-user-select:none;outline:none;-webkit-appearance:none}
/* HD: draw the bird at 2x and scale down — the composited layer is rasterized at
   double resolution, so edges stay crisp even mid-squash/flight scale-ups */
.toot-wrap .hd{width:200%;height:200%;transform:scale(.5);transform-origin:0 0;will-change:transform}
.toot{width:100%;height:100%;display:block;overflow:visible}
.an{transform-box:fill-box}
@keyframes breathe{0%,100%{transform:scaleY(1)}50%{transform:scaleY(1.03) translateY(-1px)}}
@keyframes crestbob{0%,100%{transform:rotate(0)}50%{transform:rotate(4deg)}}
.idle .p-body{transform-origin:50% 90%;animation:breathe 3.4s ease-in-out infinite}
.idle .p-crest{transform-origin:60% 92%;animation:crestbob 3.1s ease-in-out infinite}
.blink .eyes-open{display:none!important}.blink .eyes-happy{display:block!important}
.blink .eyes-glance,.blink .eyes-joy,.blink .eyes-angry,.blink .eyes-wide{display:none!important}
.sing .eyes-open,.sing .eyes-glance,.sing .eyes-angry,.sing .eyes-wide,.sing .eyes-happy{display:none!important}
.sing .eyes-joy{display:block!important}
.toot.is-angry .eyes-open,.toot.is-angry .eyes-happy,.toot.is-angry .eyes-glance,
.toot.is-angry .eyes-joy,.toot.is-angry .eyes-wide{display:none!important}
.toot.is-angry .eyes-angry{display:block!important}
@keyframes toot-annoyed{
  0%,100%{transform:translateX(0)}
  20%{transform:translateX(-2%) rotate(-1deg)}
  40%{transform:translateX(2%) rotate(1deg)}
  60%{transform:translateX(-1%)}
}
.toot.is-angry{animation:toot-annoyed .34s ease-in-out 1;transform-origin:50% 92%}
@keyframes wavearm{0%,100%{transform:rotate(0)}30%{transform:rotate(-52deg)}70%{transform:rotate(-28deg)}}
.wave .p-wingfR{transform-origin:10% 50%;animation:wavearm .55s ease-in-out 3}
.fly-only{display:none}.flying .fly-only{display:block}.flying .perch-only{display:none}
@keyframes flap{0%,100%{transform:rotate(11deg)}50%{transform:rotate(-13deg)}}
.flying .p-wing{transform-origin:96% 16%;animation:flap .34s ease-in-out infinite}
/* braking flare: wings held up-and-forward just before touchdown (no flap) */
.flaring .p-wing{animation:none!important;transform:rotate(-30deg)}
/* squash-and-settle on touchdown, pivoting at the feet */
@keyframes landsquash{0%{transform:translateY(-2px) scale(1.07,.9)}28%{transform:scale(1.12,.85)}54%{transform:scale(.95,1.07)}76%{transform:scale(1.03,.98)}100%{transform:scale(1)}}
.toot.land{transform-origin:50% 92%;animation:landsquash .56s cubic-bezier(.3,1,.5,1)}
.hush .toot-wrap{opacity:.85}
.hush .p-body,.hush .p-crest{animation:none!important} /* perfectly still while the mic is live */
.toot-wrap:focus-visible{outline:2px solid var(--berry);outline-offset:4px;border-radius:14px}
/* ground shadow under the bird — fades out while airborne */
.tshadow{position:fixed;left:0;top:0;border-radius:50%;background:rgba(70,48,24,.20);filter:blur(2px);
  pointer-events:none;transition:opacity .25s;will-change:transform,opacity} 



/* Toot's tip speech-bubble (points to his beak) */
#tipbubble{position:fixed;z-index:45;max-width:252px;background:var(--surface);border:1px solid var(--line);
  border-radius:14px;padding:11px 14px;font-size:13.5px;line-height:1.45;color:var(--ink);font-weight:550;
  box-shadow:0 14px 40px rgba(60,40,20,.22);opacity:0;transform:scale(.92) translateY(5px);
  transform-origin:14% 100%;transition:opacity .22s,transform .25s cubic-bezier(.3,1.4,.5,1);
  pointer-events:auto;cursor:pointer;visibility:hidden}
#tipbubble.show{opacity:1;transform:none;visibility:visible}
#tipbubble .tail{position:absolute;bottom:-6.5px;left:22px;width:12px;height:12px;background:var(--surface);
  border-right:1px solid var(--line);border-bottom:1px solid var(--line);transform:rotate(45deg)}
#tipbubble.flip{transform-origin:86% 100%}
#tipbubble.flip .tail{left:auto;right:22px}
#tipbubble.below .tail{bottom:auto;top:-6.5px;transform:rotate(225deg)}
#tipbubble.below{transform-origin:14% 0%}

/* mobile: no double-tap zoom on the interactive bits (spam-tapping Toot must never zoom the page) */
.toot-wrap,#sizer .sbtn,#tipbubble{touch-action:manipulation}

/* preprod-only dev tag on the size panel */
#sizer .devtag{font-size:10px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);
  border:1px solid var(--line);border-radius:6px;padding:2px 6px;margin-left:6px}




#sizer{position:fixed;right:16px;bottom:16px;z-index:60;background:var(--surface);border:1px solid var(--line);
  border-radius:16px;padding:12px 14px;box-shadow:0 12px 34px rgba(60,40,20,.18);font-size:13px;pointer-events:auto;
  display:flex;flex-direction:column;gap:9px;min-width:210px}
#sizer .row{display:flex;align-items:center;gap:10px;justify-content:space-between}
#sizer label{font-weight:700}
#sizer input[type=range]{width:100%;accent-color:var(--berry)}
#sizer .val{font-weight:800;color:var(--berry);font-variant-numeric:tabular-nums}
#sizer .btns{display:flex;gap:6px}
#sizer .sbtn{flex:1;font:inherit;font-weight:700;font-size:12.5px;padding:7px 8px;border-radius:9px;border:1px solid var(--line);background:var(--bg);color:var(--ink);cursor:pointer}
#sizer .sbtn:hover{border-color:var(--berry)}
#sizer .sbtn[data-on="1"]{background:var(--ink);color:var(--bg)}
@media(max-width:430px){#sizer{bottom:78px}}

/* ===== Toot FX (generated): singing notes, idle emotes, reactions, flight flourishes ===== */
/* ===================================================================
   TOOT FX — integrated stylesheet (append verbatim)
   Concat order is LOAD-BEARING: M1(tn) → M2(em) → M3(rx) → M4(fx).
   For equal-specificity (0,2,0) whole-body .toot animations, later
   source wins → precedence fx > rx > em; .tn-singing (0,1,0) is lowest.
   =================================================================== */

/* ===== MODULE tn: singing music notes + sing body-language ===== */
/* Overlay notes are fixed; ordinary page notes receive .toot-page-fx below. */
.tn-note{position:fixed;left:0;top:0;z-index:41;pointer-events:none;
  font-family:"Segoe UI Symbol","Apple Color Emoji","Noto Color Emoji",system-ui,sans-serif;
  line-height:1;user-select:none;white-space:nowrap;will-change:transform,opacity;
  transform:translate(-50%,-50%) scale(.3);opacity:0;
  animation:tnFloat 1.8s cubic-bezier(.33,.66,.4,1) forwards}
.tn-note.tn-c1{color:var(--berry);text-shadow:0 0 10px color-mix(in srgb,var(--berry) 45%,transparent)}
.tn-note.tn-c2{color:var(--gold);text-shadow:0 0 10px color-mix(in srgb,var(--gold) 50%,transparent)}
.tn-note.tn-c3{color:var(--berry2);text-shadow:0 0 9px color-mix(in srgb,var(--berry2) 42%,transparent)}
@keyframes tnFloat{
  0%  {opacity:0;transform:translate(-50%,-50%) translate3d(0,0,0) scale(.3) rotate(0deg)}
  14% {opacity:1;transform:translate(-50%,-50%) translate3d(var(--tn-sway),calc(var(--tn-rise) * .13),0) scale(1.14) rotate(calc(var(--tn-rot) * .18))}
  44% {opacity:1;transform:translate(-50%,-50%) translate3d(calc(var(--tn-sway) * -1),calc(var(--tn-rise) * .48),0) scale(1) rotate(calc(var(--tn-rot) * .5))}
  72% {opacity:.82;transform:translate(-50%,-50%) translate3d(calc(var(--tn-sway) * .55),calc(var(--tn-rise) * .77),0) scale(.95) rotate(calc(var(--tn-rot) * .8))}
  100%{opacity:0;transform:translate(-50%,-50%) translate3d(var(--tn-drift),var(--tn-rise),0) scale(.82) rotate(var(--tn-rot))}
}
/* enriched sing body-language (composes with existing .sing / .idle state; no face-squash) */
/* whole-bird gentle rock, pivoting at the feet (transform on the root .toot svg).
   NOTE: single-class specificity (0,1,0) is intentional so the reserved .toot.land
   landsquash (0,2,0) always wins if the two ever coincide — no fight with touchdown. */
@keyframes tnBodyRock{0%,100%{transform:rotate(0deg) translateY(0)}25%{transform:rotate(-2.2deg) translateY(-1px)}50%{transform:rotate(0deg) translateY(-2px)}75%{transform:rotate(2.2deg) translateY(-1px)}}
.tn-singing{transform-origin:50% 92%;animation:tnBodyRock 1.1s ease-in-out infinite}
/* livelier crest flick (overrides idle crestbob while singing; inner .an group) */
@keyframes tnCrestFlick{0%,100%{transform:rotate(-3deg)}30%{transform:rotate(8deg)}62%{transform:rotate(1deg)}}
.tn-singing .p-crest{transform-origin:60% 92%;animation:tnCrestFlick .52s ease-in-out infinite}
/* tail lift + flick on the accents, pivoting where it meets the body */
@keyframes tnTailFlick{0%,100%{transform:rotate(0deg) translateY(0)}20%{transform:rotate(-5deg) translateY(-3px)}50%{transform:rotate(3deg) translateY(-1px)}72%{transform:rotate(-2deg) translateY(-2px)}}
.tn-singing .p-tail{transform-origin:50% 4%;animation:tnTailFlick 1.05s ease-in-out infinite}
/* (head-bob removed: .p-head is a SIBLING of eyes/beak — moving it alone tears the face) */
/* reduced-motion float variant lives under its OWN name (no same-name @keyframes
   redefinition — that leaks to all users on some engines). RM just switches the name. */
@keyframes tnFloatRM{
  0%  {opacity:0;transform:translate(-50%,-50%) scale(.6)}
  22% {opacity:1;transform:translate(-50%,-50%) translate3d(0,calc(var(--tn-rise) * .22),0) scale(1)}
  100%{opacity:0;transform:translate(-50%,-50%) translate3d(0,var(--tn-rise),0) scale(.9)}
}
@media(prefers-reduced-motion:reduce){
  .tn-note{animation-name:tnFloatRM}
  .tn-singing{animation:none}
  .tn-singing .p-tail{animation:none}
  .tn-singing .p-crest{animation:tnCrestFlick 1s ease-in-out infinite}
}

/* ===== Toot Module 2 — idle emote repertoire (pure body language) ===== */
/* HARD CONSTRAINT baked into these rules: the head, eyes, beak and crest are SEPARATE
   sibling <g> groups in the rig (verified in build-home.mjs). So we NEVER rotate/translate
   .p-head on its own (that tears the eyes+beak off the face). "Curious / scan / preen"
   moves are done as whole-.toot tilts pivoting at the feet, so the face stays perfectly
   rigid. Crest / tail / folded-wing accents animate on inner .an groups and COMPOSE over
   each part's placement-transform attribute. All motion is rotate/scale-driven (scale-
   invariant, visible at every Toot size); px-translate is used only on the whole svg where
   it is real screen pixels. No eyes/beak morph anywhere — honours the no-face-squash rule. */

/* curious head-cock: whole bird tips on its perch (face rigid), crest leads the other way */
.toot.em-headtilt{transform-origin:50% 94%;animation:emkf-headtilt 1.15s cubic-bezier(.34,1.1,.5,1) both}
.em-headtilt .p-crest{transform-origin:60% 94%;animation:emkf-htcrest 1.15s cubic-bezier(.34,1.1,.5,1) both}
@keyframes emkf-headtilt{0%{transform:rotate(0)}22%{transform:rotate(9deg)}30%{transform:rotate(8deg)}68%{transform:rotate(9deg)}100%{transform:rotate(0)}}
@keyframes emkf-htcrest{0%{transform:rotate(0)}24%{transform:rotate(-11deg)}68%{transform:rotate(-9deg)}100%{transform:rotate(0)}}

/* look around: whole-body swivel, scans left then right, crest trailing */
.toot.em-lookaround{transform-origin:50% 94%;animation:emkf-look 1.6s ease-in-out both}
.em-lookaround .p-crest{transform-origin:60% 94%;animation:emkf-lookcrest 1.6s ease-in-out both}
@keyframes emkf-look{0%{transform:rotate(0)}20%{transform:rotate(-8deg)}42%{transform:rotate(-7deg)}62%{transform:rotate(8deg)}84%{transform:rotate(7deg)}100%{transform:rotate(0)}}
@keyframes emkf-lookcrest{0%{transform:rotate(0)}24%{transform:rotate(7deg)}64%{transform:rotate(-7deg)}100%{transform:rotate(0)}}

/* alert crest-flick (crest only, springy) — crest snaps tall then settles */
.em-crestflick .p-crest{transform-origin:58% 95%;animation:emkf-crestflick .76s cubic-bezier(.2,1.5,.4,1) both}
@keyframes emkf-crestflick{0%{transform:scaleY(1) rotate(0)}16%{transform:scaleY(1.4) rotate(3deg)}34%{transform:scaleY(1.3) rotate(-2deg)}55%{transform:scaleY(1.16) rotate(1deg)}100%{transform:scaleY(1) rotate(0)}}

/* tail wag (tail only) — pivots at the tail's attach point (top of its bbox) */
.em-tailflick .p-tail{transform-origin:50% 10%;animation:emkf-tailflick .95s cubic-bezier(.3,.9,.4,1) both}
@keyframes emkf-tailflick{0%{transform:rotate(0)}20%{transform:rotate(13deg)}45%{transform:rotate(-11deg)}68%{transform:rotate(8deg)}85%{transform:rotate(-4deg)}100%{transform:rotate(0)}}

/* preen: whole-body forward tuck (dips down & settles, face rigid), crest folds, LEFT wing lifts to groom */
.toot.em-preen{transform-origin:50% 94%;animation:emkf-preen 1.4s ease-in-out both}
.em-preen .p-crest{transform-origin:60% 94%;animation:emkf-preencrest 1.4s ease-in-out both}
.em-preen .p-wingfL{transform-origin:88% 24%;animation:emkf-preenwing 1.4s ease-in-out both}
@keyframes emkf-preen{0%{transform:rotate(0) translateY(0)}30%{transform:rotate(-5deg) translateY(3px)}55%{transform:rotate(-6deg) translateY(4px)}64%{transform:rotate(-5deg) translateY(3px)}100%{transform:rotate(0) translateY(0)}}
@keyframes emkf-preencrest{0%{transform:rotate(0)}40%{transform:rotate(11deg)}60%{transform:rotate(9deg)}100%{transform:rotate(0)}}
@keyframes emkf-preenwing{0%{transform:rotate(0)}35%{transform:rotate(-16deg)}62%{transform:rotate(-19deg)}80%{transform:rotate(-14deg)}100%{transform:rotate(0)}}

/* fluff shiver: whole-body puff + quick rotate wobble (uniform scale = puff, NOT a face-squash), crest ruffles */
.toot.em-fluff{transform-origin:50% 94%;animation:emkf-fluff .7s ease-in-out both}
.em-fluff .p-crest{transform-origin:58% 95%;animation:emkf-fluffcrest .7s ease-in-out both}
@keyframes emkf-fluff{0%{transform:scale(1) rotate(0)}14%{transform:scale(1.045) rotate(-1.4deg)}30%{transform:scale(1.04) rotate(1.4deg)}46%{transform:scale(1.045) rotate(-1.1deg)}62%{transform:scale(1.03) rotate(.7deg)}100%{transform:scale(1) rotate(0)}}
@keyframes emkf-fluffcrest{0%{transform:scaleY(1) rotate(0)}18%{transform:scaleY(1.26) rotate(-4deg)}40%{transform:scaleY(1.28) rotate(4deg)}62%{transform:scaleY(1.12) rotate(-1.5deg)}100%{transform:scaleY(1) rotate(0)}}

/* springy hop (whole-body translate = real px), crest lags */
.toot.em-hop{transform-origin:50% 94%;animation:emkf-hop .72s cubic-bezier(.3,.8,.3,1) both}
.em-hop .p-crest{transform-origin:60% 94%;animation:emkf-hopcrest .72s ease-out both}
@keyframes emkf-hop{0%{transform:translateY(0)}16%{transform:translateY(1.5%)}46%{transform:translateY(-8.5%)}64%{transform:translateY(-6.5%)}82%{transform:translateY(1%)}100%{transform:translateY(0)}}
@keyframes emkf-hopcrest{0%{transform:rotate(0)}40%{transform:rotate(-7deg)}70%{transform:rotate(4deg)}100%{transform:rotate(0)}}

/* one-wing stretch: LEFT folded wing extends, tail fans, crest raises, body leans in.
   Uses .p-wingfL only (NEVER the .p-wingfR wave-arm) so it can never hijack a wave animation. */
.toot.em-stretch{transform-origin:50% 94%;animation:emkf-stretch 1.3s ease-in-out both}
.em-stretch .p-wingfL{transform-origin:88% 22%;animation:emkf-stretchwing 1.3s ease-in-out both}
.em-stretch .p-tail{transform-origin:50% 9%;animation:emkf-stretchtail 1.3s ease-in-out both}
.em-stretch .p-crest{transform-origin:58% 95%;animation:emkf-stretchcrest 1.3s ease-in-out both}
@keyframes emkf-stretch{0%{transform:rotate(0)}38%{transform:rotate(-4deg)}66%{transform:rotate(-4deg)}100%{transform:rotate(0)}}
@keyframes emkf-stretchwing{0%{transform:rotate(0)}36%{transform:rotate(-34deg)}62%{transform:rotate(-38deg)}80%{transform:rotate(-32deg)}100%{transform:rotate(0)}}
@keyframes emkf-stretchtail{0%{transform:scaleY(1) rotate(0)}40%{transform:scaleY(1.14) rotate(-5deg)}66%{transform:scaleY(1.13) rotate(-4deg)}100%{transform:scaleY(1) rotate(0)}}
@keyframes emkf-stretchcrest{0%{transform:scaleY(1)}45%{transform:scaleY(1.2)}70%{transform:scaleY(1.18)}100%{transform:scaleY(1)}}

/* respect reduced motion — belt-and-suspenders (emRun ALSO skips in JS at the single choke point) */
@media(prefers-reduced-motion:reduce){
  .toot.em-headtilt,.toot.em-lookaround,.toot.em-preen,.toot.em-fluff,.toot.em-hop,.toot.em-stretch,
  .em-headtilt .p-crest,.em-lookaround .p-crest,.em-crestflick .p-crest,.em-tailflick .p-tail,
  .em-preen .p-crest,.em-preen .p-wingfL,.em-fluff .p-crest,.em-hop .p-crest,
  .em-stretch .p-wingfL,.em-stretch .p-tail,.em-stretch .p-crest{animation:none!important}
}

/* ===== Module rx-reactions: interaction reactions + particles ===== */
/* whole-bird happy double-bounce — transform on the .toot SVG only, which COMPOSES with the
   .toot-wrap transform that apply()/ride() write (different elements, they never fight) */
@keyframes rx-bounce{
  0%{transform:translateY(0) scale(1,1)}
  12%{transform:translateY(2%) scale(1.06,.9)}
  34%{transform:translateY(-17%) scale(.95,1.09)}
  52%{transform:translateY(0) scale(1.05,.94)}
  70%{transform:translateY(-8%) scale(.98,1.04)}
  86%{transform:translateY(0) scale(1.02,.98)}
  100%{transform:translateY(0) scale(1,1)}
}
.toot.rx-bounce{transform-origin:50% 92%;animation:rx-bounce .68s cubic-bezier(.3,1.2,.4,1)}
/* excited: several rapid little hops, pivoting at the feet */
@keyframes rx-hoplet{
  0%,100%{transform:translateY(0) scale(1,1)}
  28%{transform:translateY(-17%) scale(.96,1.07)}
  55%{transform:translateY(0) scale(1.05,.93)}
}
.toot.rx-hop{transform-origin:50% 92%;animation:rx-hoplet .19s ease-in-out 6}
/* body-language flourishes on crest + tail. Selectors lead with .toot -> specificity (0,3,0), so they
   out-rank the reserved (0,2,0) .idle .p-crest idle loop for the duration, then cleanly revert. */
@keyframes rx-crestpop{0%{transform:rotate(0) scaleY(1)}25%{transform:rotate(-7deg) scaleY(1.14)}60%{transform:rotate(3deg) scaleY(1.04)}100%{transform:rotate(0) scaleY(1)}}
@keyframes rx-tailwag{0%{transform:rotate(0)}25%{transform:rotate(6deg)}55%{transform:rotate(-5deg)}80%{transform:rotate(3deg)}100%{transform:rotate(0)}}
.toot.rx-bounce .p-crest{transform-origin:60% 92%;animation:rx-crestpop .5s ease-out}
.toot.rx-hop .p-crest{transform-origin:60% 92%;animation:rx-crestpop .38s ease-in-out 3}
.toot.rx-bounce .p-tail{transform-origin:50% 12%;animation:rx-tailwag .55s ease-in-out}
.toot.rx-hop .p-tail{transform-origin:50% 12%;animation:rx-tailwag .42s ease-in-out 3}
/* Overlay particles are fixed; ordinary page particles receive .toot-page-fx. */
.rx-particle{position:fixed;left:0;top:0;pointer-events:none;user-select:none;z-index:1;line-height:1;
  opacity:0;will-change:transform,opacity;
  animation-name:rx-rise;animation-timing-function:cubic-bezier(.2,.7,.3,1);animation-fill-mode:forwards}
/* Body-mounted effects use document coordinates and therefore scroll away with
   the page position where Toot emitted them. Fixed tutorial UI keeps the base
   viewport rule above. */
.tn-note.toot-page-fx,.rx-particle.toot-page-fx{position:absolute;z-index:41}
.rx-heart{color:var(--gold);text-shadow:0 0 6px rgba(216,145,58,.5)}
.rx-spark{color:var(--gold);text-shadow:0 0 7px rgba(216,145,58,.65)}
@keyframes rx-rise{
  0%{opacity:0;transform:translate(0,0) scale(.35) rotate(0)}
  18%{opacity:1;transform:translate(calc(var(--rx-dx)*.2),calc(var(--rx-dy)*.2)) scale(1) rotate(calc(var(--rx-rot)*.2))}
  100%{opacity:0;transform:translate(var(--rx-dx),var(--rx-dy)) scale(var(--rx-sc)) rotate(var(--rx-rot))}
}
@keyframes rx-fade{0%{opacity:0;transform:scale(.6)}25%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1.1)}}
@media(prefers-reduced-motion:reduce){
  .toot.rx-bounce,.toot.rx-hop,
  .toot.rx-bounce .p-crest,.toot.rx-hop .p-crest,
  .toot.rx-bounce .p-tail,.toot.rx-hop .p-tail{animation:none!important}
  .rx-particle{animation-name:rx-fade!important;animation-duration:.9s!important}
}

/* ===== Module 4 — flight & landing flourishes (fx-) =====
   Part-level anims target .an groups (.p-tail/.p-wing*/.p-crest) so they COMPOSE
   with the outer placement transform attribute; whole-body anims target .toot
   itself (never a placement <g>). Nothing here creates a reserved class/keyframe. */

/* (a) fxLandFlourish: tail FAN + folded-wing flutter-settle on touchdown (~0.6s).
   Targets PARTS only, so it rides ON TOP of the reserved .toot.land landsquash
   (which owns the .toot transform) instead of fighting it. */
.toot.fx-landjoy .p-tail{transform-origin:50% 8%;animation:fx-tailfan .6s cubic-bezier(.25,.9,.3,1)}
.toot.fx-landjoy .p-wingfL{transform-origin:62% 22%;animation:fx-wingsettleL .58s ease-in-out}
.toot.fx-landjoy .p-wingfR{transform-origin:38% 22%;animation:fx-wingsettleR .58s ease-in-out}
@keyframes fx-tailfan{0%{transform:scaleX(1) scaleY(1) rotate(0)}22%{transform:scaleX(1.34) scaleY(1.05) rotate(0)}48%{transform:scaleX(1.12) scaleY(1.01) rotate(-1.6deg)}72%{transform:scaleX(1.19) scaleY(1.02) rotate(1.6deg)}100%{transform:scaleX(1) scaleY(1) rotate(0)}}
@keyframes fx-wingsettleL{0%{transform:rotate(0)}24%{transform:rotate(-17deg)}55%{transform:rotate(7deg)}80%{transform:rotate(-3deg)}100%{transform:rotate(0)}}
@keyframes fx-wingsettleR{0%{transform:rotate(0)}24%{transform:rotate(17deg)}55%{transform:rotate(-7deg)}80%{transform:rotate(3deg)}100%{transform:rotate(0)}}

/* (b) fxFlutterHop: reveal the spread flight wings, bounce up on the feet, settle (~0.7s).
   The reveal rule out-specifies both `.fly-only{display:none}` (0,1,0) and
   `.flying .fly-only` (0,2,0) at (0,3,0) — and because .fly-only is CLASS-hidden
   (NOT inline style="display:none"), specificity alone reveals it; no !important needed.
   The .toot translate/scale is free while perched — idle anims live on .p-body/.p-crest,
   never on .toot. JS guards this class out whenever .land or .wave own their targets. */
.toot.fx-hop .fly-only{display:block}
.toot.fx-hop .perch-only{display:none}
.toot.fx-hop{transform-origin:50% 92%;animation:fx-hoprise .7s cubic-bezier(.3,.9,.4,1)}
.toot.fx-hop .p-wing{transform-origin:96% 16%;animation:fx-hopflutter .16s ease-in-out 4}
.toot.fx-hop .p-crest{transform-origin:60% 92%;animation:fx-hopcrest .7s ease-in-out}
@keyframes fx-hoprise{0%{transform:translateY(0) scaleY(1)}18%{transform:translateY(2%) scaleY(.94)}42%{transform:translateY(-15%) scaleY(1.05)}70%{transform:translateY(0) scaleY(.97)}85%{transform:translateY(-3%) scaleY(1.01)}100%{transform:translateY(0) scaleY(1)}}
@keyframes fx-hopflutter{0%,100%{transform:rotate(9deg)}50%{transform:rotate(-18deg)}}
@keyframes fx-hopcrest{0%,100%{transform:rotate(0)}40%{transform:rotate(-8deg)}72%{transform:rotate(5deg)}}

/* (c) fxWiggle: mid-air celebratory bank/roll + crest pop + tail flick (~0.75s).
   Rolls the whole .toot; composes with the wrap's FR bank (wrap transform is a
   different element). Airborne-only — JS blocks it while state==='perch'/.land. */
.toot.fx-wig{transform-origin:50% 52%;animation:fx-bank .75s ease-in-out}
.toot.fx-wig .p-crest{transform-origin:60% 92%;animation:fx-wigcrest .75s cubic-bezier(.3,1.5,.5,1)}
.toot.fx-wig .p-tail{transform-origin:50% 8%;animation:fx-wigtail .75s ease-in-out}
@keyframes fx-bank{0%{transform:rotate(0)}18%{transform:rotate(-14deg)}44%{transform:rotate(12deg)}68%{transform:rotate(-7deg)}86%{transform:rotate(3deg)}100%{transform:rotate(0)}}
@keyframes fx-wigcrest{0%,100%{transform:scaleY(1) scaleX(1) rotate(0)}35%{transform:scaleY(1.3) scaleX(.9) rotate(-6deg)}66%{transform:scaleY(.95) scaleX(1.02) rotate(4deg)}}
@keyframes fx-wigtail{0%,100%{transform:rotate(0)}30%{transform:rotate(9deg)}62%{transform:rotate(-6deg)}}

/* Respect reduced-motion: keep the character, cut the travel — on EVERY animated
   part (whole-body AND crest/tail), not just the big translate/rotate. */
@media(prefers-reduced-motion:reduce){
  .toot.fx-landjoy .p-tail,.toot.fx-landjoy .p-wingfL,.toot.fx-landjoy .p-wingfR{animation:none!important}
  .toot.fx-hop{animation:fx-hopRM .5s ease}
  .toot.fx-hop .p-wing{animation-iteration-count:2}
  .toot.fx-hop .p-crest{animation-duration:.5s}
  .toot.fx-wig{animation:fx-bankRM .55s ease}
  .toot.fx-wig .p-crest,.toot.fx-wig .p-tail{animation-duration:.5s}
  @keyframes fx-hopRM{0%,100%{transform:translateY(0)}45%{transform:translateY(-5%)}}
  @keyframes fx-bankRM{0%,100%{transform:rotate(0)}32%{transform:rotate(-5deg)}66%{transform:rotate(4deg)}}
}

/* TEACHING MODE: the Practice Studio tour lays a z-index:1000 scrim over the
   page and dims everything beneath it. Toot presents from above that — a
   teacher the class cannot see is not teaching. Set by saif-toot.js only while
   a tour is actually running. */
body.saif-toot-teaching #toot-layer{z-index:1001}
body.saif-toot-teaching #tipbubble{z-index:1002}
body.saif-toot-teaching .tn-note{z-index:1002}

/* ── SCORE DANCES ───────────────────────────────────────────────────────────
   Whole-body transforms pivoting at his feet: the crest, eyes and beak are
   SIBLING groups, so animating the head alone tears the face apart.
   Percentages, never px — the .hd supersampling wrapper is scaled 0.5, which
   visually halves any px translation on the .toot svg. */
@keyframes toot-cheer1{  /* under 8: one pleased bob */
  0%{transform:none} 26%{transform:translateY(-7%) scale(1.03,.98)}
  58%{transform:translateY(1%) scale(.99,1.01)} 100%{transform:none} }
@keyframes toot-cheer2{  /* 8-9: two hops with a lean */
  0%{transform:none} 16%{transform:translateY(-12%) rotate(-4deg)}
  34%{transform:translateY(0) rotate(0deg)} 52%{transform:translateY(-12%) rotate(4deg)}
  72%{transform:translateY(0) rotate(0deg)} 86%{transform:translateY(-4%)} 100%{transform:none} }
@keyframes toot-cheer3{  /* 9-10: the full dance — four hops, sway, a spin-wobble */
  0%{transform:none} 10%{transform:translateY(-16%) rotate(-7deg)}
  22%{transform:translateY(0) translateX(-5%) rotate(0deg)}
  34%{transform:translateY(-16%) translateX(-5%) rotate(7deg)}
  46%{transform:translateY(0) translateX(5%) rotate(0deg)}
  58%{transform:translateY(-18%) translateX(5%) rotate(-7deg)}
  70%{transform:translateY(0) rotate(0deg)}
  82%{transform:translateY(-10%) scale(1.05,.96)}
  92%{transform:translateY(0) scale(.98,1.02)} 100%{transform:none} }
.toot.cheer1{animation:toot-cheer1 .9s cubic-bezier(.22,1,.3,1);transform-origin:50% 92%}
.toot.cheer2{animation:toot-cheer2 1.3s cubic-bezier(.22,1,.3,1);transform-origin:50% 92%}
.toot.cheer3{animation:toot-cheer3 2s cubic-bezier(.22,1,.3,1);transform-origin:50% 92%}

/* Four visibly separate score energies: supportive nod, pleased bob, bright
   double-hop, then the full jubilee. These declarations intentionally follow
   the legacy three-band rules above so they are the definitive mapping. */
@keyframes toot-score-gentle{
  0%,100%{transform:none}
  34%{transform:translateY(1.5%) scale(1.02,.98)}
  66%{transform:translateY(-2%) scale(.995,1.005)}
}
@keyframes toot-score-good{
  0%{transform:none}
  26%{transform:translateY(-7%) scale(1.03,.98)}
  58%{transform:translateY(1%) scale(.99,1.01)}
  100%{transform:none}
}
@keyframes toot-score-bright{
  0%{transform:none}
  16%{transform:translateY(-12%) rotate(-4deg)}
  34%{transform:translateY(0)}
  52%{transform:translateY(-12%) rotate(4deg)}
  72%{transform:translateY(0)}
  86%{transform:translateY(-4%)}
  100%{transform:none}
}
@keyframes toot-score-jubilee{
  0%{transform:none}
  10%{transform:translateY(-16%) rotate(-7deg)}
  22%{transform:translateY(0) translateX(-5%)}
  34%{transform:translateY(-16%) translateX(-5%) rotate(7deg)}
  46%{transform:translateY(0) translateX(5%)}
  58%{transform:translateY(-18%) translateX(5%) rotate(-7deg)}
  70%{transform:translateY(0)}
  82%{transform:translateY(-10%) scale(1.05,.96)}
  92%{transform:translateY(0) scale(.98,1.02)}
  100%{transform:none}
}
.toot.cheer1{animation:toot-score-gentle .7s cubic-bezier(.22,1,.3,1);transform-origin:50% 92%}
.toot.cheer2{animation:toot-score-good .9s cubic-bezier(.22,1,.3,1);transform-origin:50% 92%}
.toot.cheer3{animation:toot-score-bright 1.3s cubic-bezier(.22,1,.3,1);transform-origin:50% 92%}
.toot.cheer4{animation:toot-score-jubilee 2s cubic-bezier(.22,1,.3,1);transform-origin:50% 92%}

/* The generic singing rule shows joy eyes. Score bands override it so the
   supportive bands stay warm and Jubilee gets the genuinely surprised face. */
.toot.cheer1.sing .eyes-joy,.toot.cheer2.sing .eyes-joy{display:none!important}
.toot.cheer1.sing .eyes-happy,.toot.cheer2.sing .eyes-happy{display:block!important}
.toot.cheer4.sing .eyes-joy{display:none!important}
.toot.cheer4.sing .eyes-wide{display:block!important}
@media (prefers-reduced-motion:reduce){
  .toot.cheer1,.toot.cheer2,.toot.cheer3,.toot.cheer4,.toot.is-angry{animation:none}
}

/* Speech is hidden while he flies between steps: left visible it chased him
   frame by frame and flipped sides mid-air. Visibility rather than display so
   the bubble keeps its measured size for the landing placement. */
.saif-practice-tour__card--mute{opacity:0!important;pointer-events:none;transition:opacity .12s ease}
