/* ── OCTO, THE MASCOT ──────────────────────────────────────────
   Motion for components/octo.js. Every move is a whole pixel on steps(), so
   the sprite stays crisp. --d staggers octopuses that sit side by side. */

.octo { display: block; overflow: visible; image-rendering: pixelated; }
.octo * { transform-box: view-box; }
.octo-wrap { display: inline-flex; line-height: 0; flex-shrink: 0; }

.octo .o-bob    { animation: o-bob 1.2s steps(1) infinite; animation-delay: var(--d); }
.octo .o-shadow { animation: o-shadow 1.2s steps(1) infinite; animation-delay: var(--d); }
.octo .o-legsA  { animation: o-legA .8s steps(1) infinite; animation-delay: var(--d); }
.octo .o-legsB  { opacity: 0; animation: o-legB .8s steps(1) infinite; animation-delay: var(--d); }
.octo .o-blink  { opacity: 0; animation: o-blink 3.6s steps(1) infinite; animation-delay: calc(var(--d) * 2); }

.octo .o-drip     { animation: o-drip 1.6s steps(1) infinite; }
.octo .o-scribble { animation: o-scribble .5s steps(1) infinite; }
.octo .o-sway     { animation: o-sway 1.6s steps(1) infinite; }
.octo .o-pump     { animation: o-pump 1.2s steps(1) infinite; }
.octo .o-thunk    { animation: o-thunk 2s steps(1) infinite; }
.octo .o-twinkle  { animation: o-twinkle 1.4s steps(1) infinite; }
.octo .o-twinkle2 { animation: o-twinkle 1.4s steps(1) infinite; animation-delay: .7s; }

/* Right answer: two quick hops, then a happy bounce. Wrong: a nervous shake. */
.octo--happy .o-bob    { animation: o-hop .9s steps(1) 2, o-bob .6s steps(1) 1.8s infinite; }
.octo--happy .o-legsA,
.octo--happy .o-legsB  { animation-duration: .3s; }
.octo--oops .o-bob     { animation: o-shake .5s steps(1) 2, o-bob 1.6s steps(1) 1s infinite; }

@keyframes o-bob     { 0% { transform: translateY(0); } 50% { transform: translateY(-1px); } }
@keyframes o-shadow  { 0% { transform: scaleX(1); } 50% { transform: translateX(1.5px) scaleX(.9); } }
@keyframes o-legA    { 0% { opacity: 1; } 50% { opacity: 0; } }
@keyframes o-legB    { 0% { opacity: 0; } 50% { opacity: 1; } }
@keyframes o-blink   { 0%, 92% { opacity: 0; } 94% { opacity: 1; } 97% { opacity: 0; } }
@keyframes o-hop     { 0% { transform: translateY(0); } 15% { transform: translateY(-2px); } 30% { transform: translateY(-4px); }
                       45% { transform: translateY(-2px); } 60%, 100% { transform: translateY(0); } }
@keyframes o-shake   { 0% { transform: translateX(0); } 20% { transform: translateX(-1px); } 40% { transform: translateX(1px); }
                       60% { transform: translateX(-1px); } 80% { transform: translateX(0); } }
@keyframes o-drip    { 0% { transform: translateY(0); opacity: 1; } 25% { transform: translateY(1px); } 50% { transform: translateY(2px); }
                       75% { transform: translateY(3px); opacity: .4; } 88% { opacity: 0; } }
@keyframes o-scribble { 0% { transform: translate(0, 0); } 25% { transform: translate(-1px, 1px); } 50% { transform: translate(0, 0); } 75% { transform: translate(1px, 0); } }
@keyframes o-sway    { 0% { transform: translate(0, 0); } 25% { transform: translate(1px, 0); } 50% { transform: translate(1px, 1px); } 75% { transform: translate(0, 1px); } }
@keyframes o-pump    { 0% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
@keyframes o-thunk   { 0%, 80% { transform: translate(0, 0); } 84% { transform: translate(2px, -2px); } 90% { transform: translate(1px, -1px); } 95% { transform: translate(0, 0); } }
@keyframes o-twinkle { 0% { opacity: 1; } 50% { opacity: 0; } }

.octo--still * { animation: none !important; }
.octo--still .o-legsB, .octo--still .o-blink { opacity: 0; }

/* ── Header: next to your rank ── */
.hdr-rank { padding-left: 38px; }
.hdr-rank .octo-wrap {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-58%);
}

/* ── Challenge: sits beside the feedback and reacts to it ── */
.challenge-talk { flex: 1; display: flex; align-items: flex-end; gap: var(--space-md); min-width: 0; }
.challenge-talk .sys-message-box { flex: 1; min-width: 0; }
.challenge-octo { margin-bottom: -2px; }

/* ── Profile ──
   The octopus is a square exactly as tall as your details: its top lines up
   with your name, its bottom with the progress line. */
.profile-avatar:has(.octo-wrap) { width: 136px; height: auto; min-height: 136px; align-self: stretch; border-color: var(--green-dark);
  background: radial-gradient(ellipse at 50% 60%, rgba(63, 199, 183, .12), transparent 70%), var(--bg-primary); }
.profile-avatar .octo-wrap { line-height: 0; }
.profile-info { display: flex; flex-direction: column; justify-content: space-between; min-height: 136px; min-width: 0; flex: 1; max-width: 460px; }
.profile-name { line-height: .9; }
.profile-email { font-family: var(--font-mono); font-size: 12px; color: var(--green-dim); overflow-wrap: anywhere; margin-top: 6px; }
.profile-standing { display: flex; align-items: baseline; gap: 14px; margin-top: auto; padding-top: 10px; flex-wrap: wrap; }
.profile-xp-big { line-height: 1; }
.profile-rank { font-family: var(--font-display); font-size: 20px; line-height: 1; letter-spacing: 1px; color: var(--amber); }
.profile-next { margin-top: 10px; }
.profile-next .progress-bar-track { margin-bottom: 6px; }
.profile-next-label { font-family: var(--font-mono); font-size: 11px; line-height: 1; letter-spacing: 1px; color: var(--green-dim); }
@media (min-width: 1280px) {
  .profile-avatar:has(.octo-wrap) { width: 160px; min-height: 160px; }
  .profile-avatar .octo { width: 116px; height: 101px; }
  .profile-info { min-height: 160px; }
  .profile-rank { font-size: 24px; }
}
@media (max-width: 768px) {
  .profile-top { gap: var(--space-md); padding: var(--space-md); }
  .profile-avatar:has(.octo-wrap) { width: 104px; min-height: 96px; }
  .profile-avatar .octo { width: 76px; height: 66px; }
  .profile-info { min-height: 96px; }
  .profile-stats { grid-template-columns: repeat(2, 1fr); }
  .profile-stat { border-left: 0; border-top: 1px solid var(--green-dark); padding: var(--space-md); }
  .profile-stat:nth-child(-n+2) { border-top: 0; }
  .profile-stat:nth-child(even) { border-left: 1px solid var(--green-dark); }
  .profile-stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
.badge-card .badge-octo { display: flex; justify-content: center; margin-bottom: var(--space-sm); }

/* ── Rank up ── */
.rankup {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center; padding: 16px;
  background: rgba(4, 7, 10, .82);
  animation: rankup-in .2s ease both;
}
.rankup.is-leaving { animation: rankup-out .18s ease both; }
.rankup-box {
  width: min(420px, 100%); text-align: center; padding: 28px 24px 24px;
  background: radial-gradient(ellipse at 50% 42%, rgba(63, 199, 183, .16), transparent 62%), var(--bg-card, #0C1116);
  border: 1px solid var(--amber); box-shadow: var(--glow-amber);
}
.rankup-kicker { font-family: var(--font-mono); font-size: 12px; letter-spacing: .3em; color: var(--amber); }
.rankup-stage { position: relative; width: 180px; height: 156px; margin: 18px auto 8px; }
.rankup-stage > div { position: absolute; inset: 0; }
.rankup-old  { animation: rankup-old 1.1s steps(1) both; }
.rankup-new  { opacity: 0; animation: rankup-new 1.1s steps(1) both; }
.rankup-puff g { opacity: 0; transform-box: fill-box; transform-origin: center; }
.rankup-puff .p0 { animation: rankup-puff 1.4s steps(1) both; }
.rankup-puff .p1 { animation: rankup-puff 1.4s steps(1) .05s both; }
.rankup-puff .p2 { animation: rankup-puff 1.4s steps(1) .1s both; }
.rankup-puff .p3 { animation: rankup-puff 1.4s steps(1) .15s both; }
.rankup-name {
  font-family: var(--font-display); font-size: 44px; letter-spacing: 3px; color: var(--white-em);
  animation: rankup-name 1.4s steps(1) both;
}
.rankup-look { font-family: var(--font-mono); font-size: 13px; line-height: 1.6; color: var(--green-dim); margin: 6px 0 18px; }

@keyframes rankup-in   { from { opacity: 0; } }
@keyframes rankup-out  { to { opacity: 0; } }
@keyframes rankup-old  { 0% { opacity: 1; transform: translateX(0); } 20% { transform: translateX(-6px); } 30% { transform: translateX(6px); }
                         40% { transform: translateX(-6px); } 50% { transform: translateX(6px); } 60% { transform: translateX(0); } 70%, 100% { opacity: 0; } }
@keyframes rankup-new  { 0%, 72% { opacity: 0; } 76%, 100% { opacity: 1; } }
@keyframes rankup-puff { 0%, 58% { opacity: 0; transform: scale(.6); } 62% { opacity: 1; transform: scale(.9); } 72% { opacity: 1; transform: scale(1.15); }
                         84% { opacity: .5; transform: scale(1.3); } 92%, 100% { opacity: 0; } }
@keyframes rankup-name { 0%, 76% { opacity: 0; } 80%, 100% { opacity: 1; } }

/* Phone: octopus, rank name and the bar. The XP numbers pushed the octopus
   into the logo; they are on the profile, one tap away. */
@media (max-width: 768px) {
  .hdr-rank-xp { display: none; }
}
@media (max-width: 767px) {
  .hdr-rank { padding-left: 32px; }
  .hdr-rank .octo-wrap svg { width: 28px; height: 24px; }
  .challenge-octo svg { width: 48px; height: 42px; }
}

@media (prefers-reduced-motion: reduce) {
  .octo *, .rankup-stage * { animation: none !important; }
  .octo .o-legsB, .octo .o-blink { opacity: 0; }
  .rankup-old, .rankup-puff { display: none; }
  .rankup-new, .rankup-name { opacity: 1; }
}
