#characterContainer{
    position:fixed;
    left:12px;
    bottom:2px;
    width:clamp(120px, 15vw, 190px);
    opacity:0;
    pointer-events:none;
    transition:
        left 1.25s cubic-bezier(.22,1,.36,1),
        bottom 1.25s cubic-bezier(.22,1,.36,1),
        width 1.25s cubic-bezier(.22,1,.36,1),
        opacity .6s ease;
    z-index:1500;

    /* Чтобы nameplate был над собакой */
    display:flex;
    flex-direction:column;
    align-items:flex-start;
}

#characterContainer.is-visible{
    opacity:1;
}

#characterContainer.is-intro-scene{
    left:1.8vw;
    bottom:-1.2vh;
    width:min(43vw, 560px);
    z-index:4500;
}

/* Когда интро закончилось — имя исчезает */
#characterContainer:not(.is-intro-scene) .character-nameplate{
    display:none;
}

/* По умолчанию (маленькая собака) имя не показываем */
.character-nameplate{
    display:none;
}

/* ============================================================
   Плавающий значок над собакой в углу (как "ромб" над персонажами в
   The Sims) + подпись с именем под ней. Показываются ТОЛЬКО в маленьком
   угловом виде — как только собака возвращается в is-intro-scene (сцена
   интро, подтверждения сброса/языка и т.п.), оба прячутся.
   ============================================================ */
/* top:2px, не отрицательный отступ — у картинок собаки (images/dog/*.png)
   довольно много прозрачного "воздуха" над самой головой (в среднем ~14%
   высоты кадра), голова начинается не у самого верха img, а значок должен
   парить именно в этом свободном месте над головой, а не улетать выше
   картинки целиком. */
.character-plumbob{
    display:none;
    position:absolute;
    top:2px;
    left:50%;
    transform:translateX(-50%);
    width:44px;
    height:44px;
    pointer-events:none;
    perspective:220px;
}

#characterContainer:not(.is-intro-scene) .character-plumbob{
    display:block;
}

.character-plumbob img{
    width:100%;
    height:100%;
    object-fit:contain;
    filter:drop-shadow(0 4px 8px rgba(19,5,13,.35));
    animation:plumbobSpinY 2.6s linear infinite;
}

/* Вращение вокруг вертикальной оси (Y) — как настоящий "ромб" в The Sims,
   а не кувырок вперёд-назад (была X-ось). */
@keyframes plumbobSpinY{
    from{ transform:rotateY(0deg); }
    to{ transform:rotateY(360deg); }
}

.character-idle-name{
    display:none;
    align-self:center;
    margin-top:4px;
    font-size:20px;
    font-weight:800;
    letter-spacing:.04em;
    text-transform:uppercase;
    color:#fffdfb;
    text-shadow:0 2px 6px rgba(19,5,13,.5);
    user-select:none;
    pointer-events:none;
    white-space:nowrap;
}

#characterContainer:not(.is-intro-scene) .character-idle-name{
    display:block;
}

/* Имя персонажа — только в интро (большой размер).
   Позиционируется абсолютно внутри контейнера,
   помещается низко, прямо у головы собаки. */
#characterContainer.is-intro-scene{
    position:fixed;   /* остаётся fixed, но relative для absolute-потомка */
}

#characterContainer.is-intro-scene .character-nameplate{
    display:inline-block;
    position:absolute;
    left:50%;
    top:4%;                 /* чуть выше, чтобы имя было ближе к голове */
    transform:translateX(-50%);
    margin:0;
    padding:0;
    font-size:clamp(18px, 2.4vw, 28px);
    font-weight:800;
    letter-spacing:.06em;
    text-transform:uppercase;
    color:#fffdfb;
    /* без рамки и фона — просто текст с лёгкой тенью для читаемости */
    text-shadow:0 2px 6px rgba(19,5,13,.6);
    width:fit-content;
    line-height:1;
    white-space:nowrap;
    user-select:none;
    pointer-events:none;
}

/* Анимация появления имени.
   Важно: сохраняем translateX(-50%) для центрирования. */
#characterContainer.is-intro-scene .character-nameplate{
    animation:
        nameplateAppear .5s cubic-bezier(.22,1,.36,1) .3s both;
}

@keyframes nameplateAppear{
    from{
        opacity:0;
        transform:translateX(-50%) translateY(-8px) scale(.92);
    }
    to{
        opacity:1;
        transform:translateX(-50%) translateY(0) scale(1);
    }
}

.dog-character{
    display:block;
    width:100%;
    height:auto;
    filter:drop-shadow(0 14px 20px rgba(39,12,26,.22));
    transform-origin:center bottom;
    will-change:transform, opacity;

    /* pointer-events:auto НЕ ставим здесь безусловно: во время интро
       большая собака визуально перекрывает иконки чата/уведомлений слева
       (z-index у собаки выше), и если она всегда кликабельна — она
       перехватывает клики, которые должны доходить до этих иконок.
       Кликабельность включаем точечно через .is-highlighted (см. ниже);
       для режима разработчика клики по области собаки ловятся отдельно,
       по координатам, в dialogue.js — без участия pointer-events. */

    /* Плавный переход для смены эмоций */
    transition:opacity .35s ease;
}

.dog-character.is-intro{
    animation:
        dogArrival .7s cubic-bezier(.22,1,.36,1) both,
        dogGreeting 4.8s ease-in-out .7s infinite;
}

.dog-character.is-sleeping{
    animation:
        dogArrival .7s cubic-bezier(.22,1,.36,1) both,
        dogSleep 5s ease-in-out .7s infinite;
}

.dog-character.is-resting{
    /* У картинок собаки заметный прозрачный "воздух" под лапами (~15-20%
       высоты кадра), поэтому в маленьком угловом виде между собакой и
       нижним краем экрана виден лишний пустой отступ. Компенсируем это
       сдвигом самой картинки вниз (в свою же прозрачную часть) — только
       в угловом виде (is-resting), в сцене интро/сна не трогаем. */
    --dog-foot-lift:16%;
    animation:dogBreathe 4.6s ease-in-out infinite;
}

/* Подсветка собаки, когда по ней нужно кликнуть (например, чтобы взять ключ).
   #characterContainer сам по себе pointer-events:none (чтобы не перехватывать
   клики в остальное время) — без явного auto здесь клик по собаке никогда
   бы не долетал до неё, даже подсвеченной. */
.dog-character.is-highlighted{
    pointer-events:auto;
    cursor:pointer;
    animation:dogGlowPulse 1.2s ease-in-out infinite alternate;
}

@keyframes dogGlowPulse{
    from{
        filter:
            drop-shadow(0 14px 20px rgba(39,12,26,.22))
            drop-shadow(0 0 10px rgba(255,255,255,.35));
    }
    to{
        filter:
            drop-shadow(0 14px 20px rgba(39,12,26,.22))
            drop-shadow(0 0 26px rgba(255,255,255,.8));
    }
}

@keyframes dogArrival{
    from{ opacity:0; transform:translateY(24px) scale(.94); }
    to{ opacity:1; transform:translateY(0) scale(1); }
}

/*
 * Анимация сна: очень медленное, едва заметное покачивание,
 * как будто собака дышит во сне.
 */
@keyframes dogSleep{
    0%, 100%{ transform:scale(1) translateY(0); }
    50%{ transform:scale(1.015) translateY(-2px); }
}

/*
 * Эффект дыхания: плавное лёгкое увеличение и уменьшение масштаба.
 * Без поворотов — только мягкое "дыхание" (scale) и небольшое
 * вертикальное движение. Дёшево для GPU (только transform).
 */
@keyframes dogBreathe{
    0%, 100%{ transform:translateY(var(--dog-foot-lift, 0)) scale(1) translateY(0); }
    50%{ transform:translateY(var(--dog-foot-lift, 0)) scale(1.025) translateY(-3px); }
}

@keyframes dogGreeting{
    0%, 100%{ transform:scale(1) translateY(0); }
    50%{ transform:scale(1.03) translateY(-4px); }
}

@media (max-width: 640px){
    #characterContainer{
        left:8px;
        bottom:2px;
        width:clamp(95px, 26vw, 135px);
    }

    #characterContainer.is-intro-scene{
        left:2vw;
        bottom:0;
        width:50vw;
    }

    .character-plumbob{
        top:1px;
        width:30px;
        height:30px;
    }

    .character-idle-name{
        font-size:15px;
    }
}
