/* mascot.css — Milestone 17 introduced "Volt"; Milestone 18, Phase C adds the rest of the crew
   (Pip, Mossy, Ember, Nimbus, Coco) plus size variants, a speech bubble, a peeker positioning
   modifier, and staggered idle micro-life so multiple mascots on one page never move in lockstep.
   Built entirely from hand-authored inline SVG primitives (rect/polygon), no raster assets.
   Colors come from assets/css/style.css's :root tokens (one triplet per character) so recoloring
   the brand palette recolors the whole crew for free.

   Every character shares the same 4-state contract: components/mascot.php's render_mascot() and
   assets/js/wizard-create.js only ever swap the mascot--{idle|building|celebrating|error} class —
   everything else here is free to change without touching any calling code. */

.mascot {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Size variants — the SVG's viewBox (0 0 120 140) never changes; only the rendered box does. */
.mascot--sm { width: 64px; height: 75px; }
.mascot--md { width: 120px; height: 140px; }
.mascot--lg { width: 180px; height: 210px; }

.mascot__figure {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: visible;
}

/* Group everything except the ground shadow so state animations (bob/shake/celebrate) and state
   filters (brightness/saturate/hue-rotate) move and recolor the whole creature as one unit. */
.mascot__body-group {
    transform-box: fill-box;
    transform-origin: center;
}

.mascot__shadow {
    fill: rgba(58, 46, 31, 0.18);
}

/* Shared eye styling + blink micro-life — every character's eyes carry .mascot__eye, even when
   they also carry a character-specific class (e.g. Ember's glow). --mascot-blink-delay is a
   per-instance random negative delay set inline by render_mascot(), so mascots never blink in
   sync with each other. */
.mascot__eye {
    fill: #2B2118;
    transform-box: fill-box;
    transform-origin: center;
    animation: mascot-blink 5s ease-in-out infinite;
    animation-delay: var(--mascot-blink-delay, 0s);
}
.mascot__eye-highlight { fill: #ffffff; }

@keyframes mascot-blink {
    0%, 94%, 100% { transform: scaleY(1); }
    97% { transform: scaleY(0.12); }
}

/* --- Volt (grass-block creature) — light-top/mid-front/dark-side per cube face, dirt-toned legs,
   matching Minecraft's own grass-block-on-dirt convention. Fallback values on every var() here and
   below mean a character still renders correctly even on a page that doesn't load style.css's
   :root (e.g. pages/404.php, deliberately standalone — see its own header comment). --- */
.mascot--char-volt .mascot__face-front { fill: var(--mascot-mid, #58C445); }
.mascot--char-volt .mascot__face-top { fill: var(--mascot-light, #7AD965); }
.mascot--char-volt .mascot__face-side { fill: var(--mascot-dark, #3D8A2C); }
.mascot--char-volt .mascot__ear { fill: var(--mascot-mid, #58C445); }
.mascot--char-volt .mascot__leg-front { fill: var(--mascot-dirt, #A9754A); }
.mascot--char-volt .mascot__leg-light { fill: var(--mascot-dirt-light, #C4936A); }
.mascot--char-volt .mascot__leg-dark { fill: var(--mascot-dirt-dark, #7A5433); }
.mascot--char-volt .mascot__spark { fill: var(--highlight, #FFD43B); }

/* --- Pip (bee) --- */
.pip__leg { fill: var(--pip-dark, #D99A0A); }
.pip__abdomen { fill: var(--pip-mid, #FFC627); }
.pip__stripe { fill: var(--pip-stripe, #2B2118); }
.pip__thorax { fill: var(--pip-light, #FFE066); }
.pip__head { fill: var(--pip-stripe, #2B2118); }
.pip__wing { fill: var(--pip-wing, rgba(210, 235, 250, 0.65)); }
.pip__antenna { fill: var(--pip-stripe, #2B2118); }
.pip__antenna-tip { fill: var(--pip-stripe, #2B2118); }

/* --- Mossy (slime cube) --- */
.mossy__face-front { fill: var(--mossy-mid, #6FCB5C); opacity: 0.92; }
.mossy__face-top { fill: var(--mossy-light, #A6E896); opacity: 0.92; }
.mossy__face-side { fill: var(--mossy-dark, #4A9A3B); opacity: 0.92; }
.mossy__shine { fill: var(--mossy-light, #A6E896); opacity: 0.7; }
.mossy__mouth { fill: var(--mossy-dark, #4A9A3B); }

/* --- Ember (magma cube) — glowing cracks pulse gently, independent of the state animation. --- */
.ember__face-front { fill: var(--ember-dark, #7A2210); }
.ember__face-top { fill: var(--ember-mid, #D94F2B); }
.ember__face-side { fill: #4A150A; }
.ember__crack {
    fill: var(--ember-glow, #FFD43B);
    animation: ember-glow-pulse 1.8s ease-in-out infinite;
}
.ember__eye { fill: var(--ember-glow, #FFD43B); }
@keyframes ember-glow-pulse {
    0%, 100% { opacity: 0.75; }
    50% { opacity: 1; }
}

/* --- Nimbus (cloud) — no legs, floats. --- */
.nimbus__puff { fill: var(--nimbus-mid, #E9F2FA); }
.nimbus__puff-shade { fill: var(--nimbus-dark, #C3D4E3); }
.nimbus__smile { fill: var(--nimbus-dark, #C3D4E3); }

/* --- Coco (chicken) --- */
.coco__leg { fill: var(--coco-beak, #FFB627); }
.coco__body-front { fill: var(--coco-mid, #F5EBD6); }
.coco__body-top { fill: var(--coco-light, #FFFDF5); }
.coco__body-side { fill: var(--coco-dark, #D9C9A3); }
.coco__wing { fill: var(--coco-dark, #D9C9A3); }
.coco__head-front { fill: var(--coco-light, #FFFDF5); }
.coco__head-top { fill: #ffffff; }
.coco__comb { fill: var(--coco-comb, #E8544B); }
.coco__beak { fill: var(--coco-beak, #FFB627); }

/* --- State: idle (default) — --mascot-bob-delay staggers multiple mascots on one page. --- */
.mascot--idle .mascot__body-group {
    animation: mascot-bob 3.5s ease-in-out infinite;
    animation-delay: var(--mascot-bob-delay, 0s);
}

/* --- State: building --- */
.mascot--building .mascot__body-group {
    animation: mascot-pulse 0.9s steps(4) infinite;
}

/* --- State: celebrating --- */
.mascot--celebrating .mascot__body-group {
    animation: mascot-celebrate 0.5s steps(2) infinite;
    filter: brightness(1.15) saturate(1.3);
}

/* --- State: error/concern --- */
.mascot--error .mascot__body-group {
    animation: mascot-shake 2.4s ease-in-out infinite;
    filter: saturate(0.5) sepia(0.4) hue-rotate(-30deg);
}

@keyframes mascot-bob {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-6px); }
}

@keyframes mascot-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.05); }
}

@keyframes mascot-celebrate {
    0%, 100% { transform: translateY(0) scale(1); }
    50% { transform: translateY(-10px) scale(1.06); }
}

@keyframes mascot-shake {
    0%, 92%, 100% { transform: translateX(0); }
    94% { transform: translateX(-3px); }
    96% { transform: translateX(3px); }
    98% { transform: translateX(-2px); }
}

/* --- Peeker: positions a mascot poking over the corner of whatever `position:relative` ancestor
   it's placed in. The caller sets the actual corner (top/right/bottom/left) via render_mascot()'s
   $style param — this just supplies the positioning mode + a sensible default. --- */
.mascot--peeker {
    position: absolute;
    bottom: -16px;
    right: 8px;
    z-index: 2;
    pointer-events: none;
}

/* --- Speech bubble --- */
.mascot-speech {
    position: relative;
    display: inline-block;
    background: var(--bg-card, #FFFDF7);
    border: 3px solid var(--text-main, #3A2E1F);
    border-radius: 4px;
    padding: 8px 14px;
    font-family: var(--font-terminal, monospace);
    font-size: 1.15rem;
    line-height: 1.3;
    color: var(--text-main, #3A2E1F);
    max-width: 240px;
    /* Milestone 21: field-tip hover text (wizard-create.js's FIELD_TIPS) runs up to ~5-6 wrapped
       lines, vs. 1 line for the default message. Without a floor here, swapping text on hover
       changes this box's height, which (since the modal is `modal-dialog-centered`) re-centers
       the whole modal — moving the just-hovered field out from under the cursor, firing
       mouseleave, reverting the text, shrinking the box, re-centering back, and re-entering the
       hover zone again. Confirmed live: this produced a fast, continuous shake of the entire
       Deploy Server modal. A fixed floor stops the box from ever changing size on hover, which
       breaks the loop at its source rather than working around the event handling. */
    min-height: 10rem;
}
.mascot-speech::after {
    content: '';
    position: absolute;
    bottom: -9px;
    left: 22px;
    width: 12px;
    height: 12px;
    background: var(--bg-card, #FFFDF7);
    border-right: 3px solid var(--text-main, #3A2E1F);
    border-bottom: 3px solid var(--text-main, #3A2E1F);
    transform: rotate(45deg);
}

@media (prefers-reduced-motion: reduce) {
    .mascot--idle .mascot__body-group,
    .mascot--building .mascot__body-group,
    .mascot--celebrating .mascot__body-group,
    .mascot--error .mascot__body-group,
    .mascot__eye,
    .ember__crack {
        animation: none;
    }
}
