/* Codi mascot. One source for the desktop app and the website.
   Usage: <div class="codi" data-state="idle" style="--level:0">…mascot.svg…</div>
   States: idle listening thinking happy confused sleepy error locked. Add .wave to wave. */
.codi {
  --body: #7c5cff; --dark: #4b2fd6; --ink: #1c1440; --accent: #ffd35c;
  --level: 0; --lx: 0; --ly: 0;
  display: block; line-height: 0; user-select: none; -webkit-user-select: none;
}
.codi svg { width: 100%; height: 100%; overflow: visible; }
.codi svg * { transform-box: fill-box; transform-origin: center; }
/* .raw groups carry plain SVG transform attributes (pre-rotated ears), so keep SVG's own origin. */
.codi svg .raw { transform-box: view-box; transform-origin: 0 0; }
.codi .body, .codi .ear, .codi .arm { fill: var(--body); transition: fill .35s; }
.codi .shade { fill: var(--dark); opacity: .28; transition: fill .35s; }
.codi .shine { fill: #fff; opacity: .28; }
.codi .belly { fill: #fff; opacity: .16; }
.codi .shadow { fill: #000; opacity: .16; animation: codi-shadow 3.2s ease-in-out infinite; }
.codi .white { fill: #fff; }
.codi .pupil { fill: var(--ink); transform: translate(calc(var(--lx) * 4.5px), calc(var(--ly) * 4px)); transition: transform .12s ease-out; }
.codi .glint { fill: #fff; }
.codi .cheek { fill: #ff8fb3; opacity: .55; }
.codi .line { fill: none; stroke: var(--ink); stroke-width: 4.5; stroke-linecap: round; stroke-linejoin: round; }
.codi .m-open, .codi .m-grin, .codi .m-o { fill: var(--ink); }
.codi .antenna path { fill: none; stroke: var(--dark); stroke-width: 4; stroke-linecap: round; }
.codi .antenna .tip { fill: var(--accent); }
.codi .antenna { transform-origin: 50% 100%; animation: codi-sway 3.2s ease-in-out infinite; }
.codi .rings circle { fill: none; stroke: var(--body); stroke-width: 3; opacity: 0; }
.codi .fx { opacity: 0; fill: var(--accent); font: 800 34px/1 ui-rounded, "SF Pro Rounded", system-ui, sans-serif; }
.codi .fx-lock path { fill: none; stroke: var(--ink); stroke-width: 5; stroke-linecap: round; }
.codi .fx-lock rect { fill: var(--accent); stroke: var(--ink); stroke-width: 4; }

/* Only one eye set and one mouth are visible at a time. */
.codi .eyes-joy, .codi .eyes-shut, .codi .mouth { opacity: 0; transition: opacity .15s; }
.codi .m-smile { opacity: 1; }

.codi .bob { animation: codi-breathe 3.2s ease-in-out infinite; transform-origin: 50% 100%; }
.codi .eyes-open .eye { animation: codi-blink 4.6s infinite; }
.codi .ear, .codi .arm { transition: transform .3s cubic-bezier(.3, 1.6, .5, 1), fill .35s; }
.codi .ear-l { transform-origin: 80% 90%; } .codi .ear-r { transform-origin: 20% 90%; }
.codi .arm-l { transform-origin: 80% 10%; } .codi .arm-r { transform-origin: 20% 10%; }

/* listening: ears up, mouth and rings follow the voice */
.codi[data-state="listening"] { --body: #12b886; --dark: #087f5b; }
.codi[data-state="listening"] .bob { animation: none; transform: scale(calc(1 + var(--level) * .07)); transition: transform .08s; }
.codi[data-state="listening"] .ear-l { transform: rotate(-18deg) translateY(-5px); }
.codi[data-state="listening"] .ear-r { transform: rotate(18deg) translateY(-5px); }
.codi[data-state="listening"] .m-smile { opacity: 0; }
.codi[data-state="listening"] .m-open { opacity: 1; transform: scaleY(calc(.35 + var(--level) * 1.5)); transition: transform .06s; }
.codi[data-state="listening"] .tip { animation: codi-glow .7s ease-in-out infinite; }
.codi[data-state="listening"] .rings circle { opacity: calc(.12 + var(--level) * .6); transform: scale(calc(.86 + var(--level) * .2)); transition: transform .1s, opacity .1s; }
.codi[data-state="listening"] .rings circle:nth-child(2) { opacity: calc(.06 + var(--level) * .4); }
.codi[data-state="listening"] .rings circle:nth-child(3) { opacity: calc(var(--level) * .25); }

/* thinking: looks up, dots bounce */
.codi[data-state="thinking"] { --body: #f59f00; --dark: #c76b00; }
.codi[data-state="thinking"] .pupil { transform: translate(4px, -6px); }
.codi[data-state="thinking"] .eyes-open .eye { animation: none; }
.codi[data-state="thinking"] .m-smile { opacity: 0; } .codi[data-state="thinking"] .m-flat { opacity: 1; }
.codi[data-state="thinking"] .bob { animation: codi-tilt 1.4s ease-in-out infinite; }
.codi[data-state="thinking"] .fx-dots { opacity: 1; }
.codi[data-state="thinking"] .fx-dots circle { animation: codi-dot .9s ease-in-out infinite; }
.codi[data-state="thinking"] .fx-dots circle:nth-child(2) { animation-delay: .15s; }
.codi[data-state="thinking"] .fx-dots circle:nth-child(3) { animation-delay: .3s; }

/* happy: jump, joy eyes, arms up, sparkles */
.codi[data-state="happy"] .bob { animation: codi-jump .55s cubic-bezier(.3, 1.4, .6, 1) 2; }
.codi[data-state="happy"] .eyes-open, .codi[data-state="happy"] .m-smile { opacity: 0; }
.codi[data-state="happy"] .eyes-joy, .codi[data-state="happy"] .m-grin { opacity: 1; }
.codi[data-state="happy"] .arm-l { transform: rotate(140deg); }
.codi[data-state="happy"] .arm-r { transform: rotate(-140deg); }
.codi[data-state="happy"] .cheek { opacity: .9; }
.codi[data-state="happy"] .fx-spark { opacity: 1; }
.codi[data-state="happy"] .fx-spark path { animation: codi-pop .8s ease-out infinite; }
.codi[data-state="happy"] .fx-spark path:nth-child(2) { animation-delay: .2s; }
.codi[data-state="happy"] .fx-spark path:nth-child(3) { animation-delay: .4s; }

/* confused: head tilt, one small eye, wobbly mouth */
.codi[data-state="confused"] { --body: #9775fa; --dark: #6741d9; }
.codi[data-state="confused"] .bob { animation: none; transform: rotate(-9deg); transition: transform .3s cubic-bezier(.3, 1.6, .5, 1); }
.codi[data-state="confused"] .eye-r { transform: scale(.72); animation: none; }
.codi[data-state="confused"] .ear-r { transform: rotate(40deg) translateY(6px); }
.codi[data-state="confused"] .m-smile { opacity: 0; } .codi[data-state="confused"] .m-wobble { opacity: 1; }
.codi[data-state="confused"] .fx-q { opacity: 1; animation: codi-wiggle .8s ease-in-out infinite; }

/* sleepy: eyes shut, ears droop, zzz */
.codi[data-state="sleepy"] { --body: #8a8fc2; --dark: #5c6196; }
.codi[data-state="sleepy"] .bob { animation-duration: 5s; }
.codi[data-state="sleepy"] .eyes-open, .codi[data-state="sleepy"] .m-smile { opacity: 0; }
.codi[data-state="sleepy"] .eyes-shut, .codi[data-state="sleepy"] .m-o { opacity: 1; }
.codi[data-state="sleepy"] .ear-l { transform: rotate(-38deg) translateY(8px); }
.codi[data-state="sleepy"] .ear-r { transform: rotate(38deg) translateY(8px); }
.codi[data-state="sleepy"] .antenna { animation: none; transform: rotate(38deg); }
.codi[data-state="sleepy"] .fx-zzz { opacity: 1; fill: #c5c9ee; }
.codi[data-state="sleepy"] .fx-zzz text { animation: codi-zzz 2.4s ease-in-out infinite; }
.codi[data-state="sleepy"] .fx-zzz text:nth-child(2) { animation-delay: .5s; }
.codi[data-state="sleepy"] .fx-zzz text:nth-child(3) { animation-delay: 1s; }

/* error: red, shake, frown */
.codi[data-state="error"] { --body: #fa5252; --dark: #c92a2a; }
.codi[data-state="error"] .bob { animation: codi-shake .45s linear 2; }
.codi[data-state="error"] .m-smile { opacity: 0; } .codi[data-state="error"] .m-frown { opacity: 1; }
.codi[data-state="error"] .ear-l { transform: rotate(-30deg) translateY(6px); }
.codi[data-state="error"] .ear-r { transform: rotate(30deg) translateY(6px); }
.codi[data-state="error"] .fx-bang { opacity: 1; fill: #fa5252; animation: codi-wiggle .5s ease-in-out infinite; }

/* locked: grey, padlock (signed out, waitlist, or monthly limit reached) */
.codi[data-state="locked"] { --body: #a3a8bd; --dark: #6c7189; }
.codi[data-state="locked"] .m-smile { opacity: 0; } .codi[data-state="locked"] .m-flat { opacity: 1; }
.codi[data-state="locked"] .cheek { opacity: .2; }
.codi[data-state="locked"] .fx-lock { opacity: 1; }

.codi.wave .arm-r { animation: codi-wave .9s ease-in-out; }

@keyframes codi-breathe { 0%, 100% { transform: translateY(0) scale(1, 1); } 50% { transform: translateY(-4px) scale(1.015, .985); } }
@keyframes codi-shadow { 0%, 100% { transform: scaleX(1); } 50% { transform: scaleX(.9); } }
@keyframes codi-blink { 0%, 94%, 100% { transform: scaleY(1); } 97% { transform: scaleY(.08); } }
@keyframes codi-sway { 0%, 100% { transform: rotate(-5deg); } 50% { transform: rotate(7deg); } }
@keyframes codi-glow { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.5); } }
@keyframes codi-tilt { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }
@keyframes codi-dot { 0%, 100% { transform: translateY(0); opacity: .5; } 40% { transform: translateY(-9px); opacity: 1; } }
@keyframes codi-jump { 0%, 100% { transform: translateY(0) scale(1.06, .92); } 45% { transform: translateY(-20px) scale(.95, 1.07); } }
@keyframes codi-pop { 0% { transform: scale(0) rotate(0); opacity: 0; } 40% { transform: scale(1.2) rotate(40deg); opacity: 1; } 100% { transform: scale(.4) rotate(90deg); opacity: 0; } }
@keyframes codi-wiggle { 0%, 100% { transform: rotate(-12deg); } 50% { transform: rotate(12deg); } }
@keyframes codi-zzz { 0% { transform: translate(-6px, 8px) scale(.6); opacity: 0; } 40% { opacity: 1; } 100% { transform: translate(6px, -12px) scale(1.1); opacity: 0; } }
@keyframes codi-shake { 0%, 100% { transform: translateX(0); } 20%, 60% { transform: translateX(-7px); } 40%, 80% { transform: translateX(7px); } }
@keyframes codi-wave { 0%, 100% { transform: rotate(0); } 20%, 60% { transform: rotate(-150deg); } 40%, 80% { transform: rotate(-115deg); } }

@media (prefers-reduced-motion: reduce) {
  .codi *, .codi { animation: none !important; transition: none !important; }
}
