/* One transparent sprite sheet: green, yellow, orange, red (left to right).
   Animate the inner art only, never Leaflet's positioned marker element. */
.map-character {
    display: block;
    position: relative;
    width: 48px;
    height: 82px;
    transform-origin: 50% 96%;
    transition: transform .2s ease, filter .2s ease;
    filter: drop-shadow(0 2px 2px #25304155);
}
.map-character::before {
    content: '';
    position: absolute;
    bottom: 2px;
    left: 8px;
    width: 32px;
    height: 9px;
    border-radius: 50%;
    background: var(--c, #299d59);
    opacity: .28;
}
.character-art { position: absolute; inset: 0; transform-origin: 50% 96%; animation: character-arrive .55s cubic-bezier(.2,.8,.3,1) both; }
.map-character-sprite, .map-character-base {
    display: block;
    width: 100%;
    height: 100%;
    background-image: url('../images/map-characters/patients-v1.png?v=2');
    background-repeat: no-repeat;
    background-size: 400% 100%;
    background-position: var(--sprite-x, 0%) 0;
    position: absolute;
    inset: 0;
}
/* Keep the pedestal fixed; only the upper illustration breathes and shifts weight. */
.map-character-base { clip-path: inset(77% 0 0); }
.map-character-sprite {
    clip-path: inset(0 0 23%);
    transform-origin: 50% 77%;
    animation: character-breathe 5.6s ease-in-out infinite;
}
.map-character[data-risk="yellow"] { --sprite-x: 33.333333%; }
.map-character[data-risk="orange"] { --sprite-x: 66.666667%; }
.map-character[data-risk="red"] { --sprite-x: 100%; }
.map-character[data-risk="yellow"] .map-character-sprite { animation-name: character-seated; animation-delay: -1.4s; }
.map-character[data-risk="orange"] .map-character-sprite { animation-delay: -2.8s; }
.map-character[data-risk="red"] .map-character-sprite { animation-name: character-weight-shift; animation-delay: -4.2s; }
.character-ripple { position: absolute; bottom: 1px; left: 4px; width: 40px; height: 13px; border: 2px solid var(--c); border-radius: 50%; opacity: 0; pointer-events: none; }
.map-character.is-tapped .character-ripple { animation: character-tap-ring .65s ease-out; }
.map-character.is-tapped .character-art { animation: character-nod .45s ease-in-out; }
.patient-character { position: relative; width: 48px; height: 82px; cursor: pointer; }
.character-initial {
    position: absolute;
    top: 5px;
    right: -2px;
    min-width: 19px;
    height: 19px;
    padding: 0 3px;
    display: grid;
    place-items: center;
    border: 2px solid white;
    border-radius: 50%;
    background: var(--c);
    color: white;
    font: 700 10px var(--font-display);
    box-shadow: 0 1px 4px #0003;
}
.patient-character[data-risk="yellow"] .character-initial { color: #2a2000; }
.vm.has-character > .map-character { position: absolute; left: -17px; top: -72px; }
.vm.has-character > .vm-dot { opacity: 0; }
.vm.has-character > .vm-count { left: 22px; top: -70px; z-index: 1; }
.vm.has-character > .vm-name { margin-left: 9px; }
.patient-character:hover .map-character,
.character-icon:focus-visible .map-character,
.vm:hover > .map-character,
.vm.is-selected > .map-character,
.vm-icon:focus-visible .map-character {
    transform: scale(1.12);
    filter: drop-shadow(0 3px 3px #25304177);
}
.patient-character:active .map-character, .vm:active > .map-character { transform: scale(.96); }
.character-icon:focus-visible, .vm-icon:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; }
@keyframes character-breathe {
    0%, 100% { transform: scaleY(1) rotate(-.6deg); }
    45% { transform: scaleY(1.018) rotate(.6deg); }
}
@keyframes character-seated {
    0%, 100% { transform: rotate(-.7deg); }
    50% { transform: rotate(.7deg) scaleY(1.012); }
}
@keyframes character-weight-shift {
    0%, 100% { transform: rotate(-1deg); }
    40%, 60% { transform: rotate(1deg) scaleY(1.012); }
}
@keyframes character-arrive {
    from { opacity: 0; transform: translateY(-8px) scale(.85); }
    70% { opacity: 1; transform: translateY(0) scale(1.035); }
    to { opacity: 1; transform: none; }
}
@keyframes character-nod {
    0%, 100% { transform: scale(1); }
    40% { transform: scale(.97, .94); }
    75% { transform: scale(1.025); }
}
@keyframes character-tap-ring {
    from { opacity: .65; transform: scale(.65); }
    to { opacity: 0; transform: scale(1.8); }
}
.characters-moving .map-character-sprite,
.characters-background .map-character-sprite { animation-play-state: paused; }
.characters-paused .map-character-sprite,
.characters-paused .character-art,
.characters-paused .character-ripple { animation: none !important; }
.characters-paused .map-character { transition: none; }
@media (hover: hover) {
    .patient-character:hover .map-character-sprite,
    .vm:hover .map-character-sprite { animation-play-state: paused; }
}
@media (prefers-reduced-motion: reduce) {
    .map-character-sprite, .character-art, .character-ripple { animation: none !important; }
    .map-character { transition: none !important; }
}

/* Scale inside Leaflet's position transform, preserving the location tip. */
.patient-character, .character-cluster { transform: scale(var(--map-character-scale, 1)); transform-origin: 50% 96%; }
.character-cluster-icon { background: none; border: 0; }
.character-cluster { position: relative; width: 54px; height: 82px; cursor: pointer; }
.character-cluster::before { content: ''; position: absolute; left: -1px; bottom: 3px; width: 52px; height: 18px; border: 3px solid var(--c); border-radius: 50%; background: #ffffffb8; box-shadow: 0 2px 5px #0003; }
.character-cluster-count { position: absolute; top: 2px; right: -3px; min-width: 25px; height: 25px; padding: 0 4px; display: grid; place-items: center; border: 2px solid white; border-radius: 20px; background: var(--c); color: white; font: 700 12px var(--font-display); }
.character-cluster[data-risk="yellow"] .character-cluster-count { color: #2a2000; }
.character-cluster-icon:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; }
.character-focused .map-character::before { opacity: .8; outline: 3px solid white; box-shadow: 0 0 0 5px var(--c); }
.character-focused .character-ripple { animation: character-tap-ring 1.2s ease-out 5; }
.character-focused .character-initial { outline: 3px solid var(--brand); }
.character-picker { display: flex; align-items: center; gap: 18px; padding: 10px 14px; border: 1px solid var(--border, #e0d9e4); border-radius: 14px; }
.character-preview { display: block; flex: 0 0 48px; }
.character-picker .select { flex: 1; min-width: 0; }
/* Atlas rows: risk colors; columns: hand/head animation frames. */
.has-frames { --atlas-row: 0%; width: 62px; margin-left: -7px; }
.has-frames[data-risk="yellow"] { --atlas-row: 33.333333%; }
.has-frames[data-risk="orange"] { --atlas-row: 66.666667%; }
.has-frames[data-risk="red"] { --atlas-row: 100%; }
.has-frames .map-character-base { display: none; }
.map-character.has-frames .map-character-sprite { clip-path: none; background-image: var(--atlas-image); background-size: 400% 400%; background-position: 0% var(--atlas-row); animation: character-frames 8s step-end var(--frame-delay, 0s) infinite; transform: none; }
.map-character[data-variant="man"] { --atlas-image: url('../images/map-characters/man-v1.png?v=2'); }
.map-character[data-variant="woman"] { --atlas-image: url('../images/map-characters/woman-v1.png?v=2'); }
.map-character[data-variant="elder"] { --atlas-image: url('../images/map-characters/elder-v1.png?v=2'); }
.map-character[data-variant="short-hair"] { --atlas-image: url('../images/map-characters/short-hair-v1.png?v=2'); }
@keyframes character-frames {
    0%, 65%, 100% { background-position: 0% var(--atlas-row); }
    70% { background-position: 33.333333% var(--atlas-row); }
    77% { background-position: 66.666667% var(--atlas-row); }
    85% { background-position: 100% var(--atlas-row); }
    92% { background-position: 0% var(--atlas-row); }
}
.characters-moving .has-frames .map-character-sprite,
.characters-background .has-frames .map-character-sprite { animation-play-state: paused; }
@media (hover: hover) {
    .patient-character:hover .has-frames .map-character-sprite { animation-play-state: running; }
}
@media (prefers-reduced-motion: reduce) {
    .character-focused .character-ripple { animation: none !important; }
}
