/*
 * Говорящий портрет вместо сферы голосового режима (hermes-voice-portrait.js).
 * Персонаж сидит в круглом медальоне: снизу бюст обрезан кругом, голова выходит за его верх.
 * Кольцо медальона берёт цвета фаз прежней сферы, ореол за ним дышит голосом агента.
 * Слои персонажа: body дышит (и подпрыгивает), pose принимает позу фазы и сна (плавно) и держит руку взмаха,
 * face покачивается, look чуть поворачивается к курсору, head слушает, раздумывает и занимает себя в тишине,
 * talk — разовые действия. Эффекты у головы (сердечки, искорки…) — отдельный слой поверх всего, без маски.
 * У каждого слоя своё свойство transform, поэтому анимации и переходы друг другу не мешают.
 */

.hermes-dashboard .voice-mode__orb--portrait {
    width: clamp(15rem, 50vh, 27rem);
}

/* Громкость пишется на круг голоса 20 раз в секунду, а в CSS её никто не читает: ненаследуемая переменная
   не пересчитывает стиль всего портрета при каждой записи. */
@property --voice-level {
    syntax: "<number>";
    inherits: false;
    initial-value: 0;
}

@property --voice-assistant-level {
    syntax: "<number>";
    inherits: false;
    initial-value: 0;
}

/* Медальон: круг радиуса --medal-r с центром на высоте --medal-y (коробка квадратная, проценты одинаковы по обеим осям).
   Низ круга выше нижнего края бюста с запасом на прыжок «готово» (−5 %). */
.voice-portrait {
    --medal-r: 37%;
    --medal-y: 54%;
    position: absolute;
    inset: 0;
    /* «z» сна растут с портретом (cqw). */
    container-type: size;
    /* По персонажу кликают и гладят: без выделения, подсветки касания и зума двойным тапом; ведение пальцем по
       голове — поглаживание, а не прокрутка (иначе браузер отменит касание). */
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    touch-action: none;
}

.voice-portrait__halo,
.voice-portrait__disc,
.voice-portrait__rings,
.voice-portrait__arc {
    position: absolute;
    left: calc(50% - var(--medal-r));
    top: calc(var(--medal-y) - var(--medal-r));
    width: calc(2 * var(--medal-r));
    height: calc(2 * var(--medal-r));
    border-radius: 50%;
    pointer-events: none;
}

/* Ореол — голос агента: цвет речи в любой фазе, --halo (0–10) пишет hermes-voice-portrait.js по громкости.
   Без перехода и на своём слое: каждый переход стоил главному потоку лишних кадров, а смена слоя — только
   композитору. Плавность даёт огибающая в JS. */
.voice-portrait__halo {
    --halo: 0;
    background: radial-gradient(closest-side, rgb(var(--voice-orb-speak) / 0.5) 72%, rgb(var(--voice-orb-speak) / 0.14) 86%, transparent);
    opacity: calc(0.45 + 0.05 * var(--halo));
    transform: scale(calc(1.1 + 0.008 * var(--halo)));
    will-change: opacity, transform;
}

.voice-portrait__disc {
    background:
        radial-gradient(circle at 50% 28%, rgb(var(--hermes-accent-rgb) / 0.3), rgb(var(--hermes-accent-rgb) / 0.1) 60%, rgb(var(--hermes-accent-rgb) / 0.05)),
        #1b1a22;
}

/* Кольцо фазы — пять колец цветов прежней сферы друг над другом, видно одно. Смена фазы — смена прозрачности,
   её ведёт композитор; переход box-shadow главный поток рисовал бы каждый кадр. Новое кольцо проявляется сразу,
   прежнее гаснет с задержкой — без провала яркости посередине. */
.voice-portrait__rings {
    transition: opacity 420ms ease;
}

.voice-portrait__ring {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    box-shadow: 0 0 0 0.125rem rgb(var(--tone) / 0.7);
    opacity: 0;
    transition: opacity 300ms ease 250ms;
}

.voice-portrait__ring[data-tone="listen"] { --tone: var(--voice-orb-listen); }
.voice-portrait__ring[data-tone="hear"] { --tone: var(--voice-orb-hear); }
.voice-portrait__ring[data-tone="work"] { --tone: var(--voice-orb-work); }
.voice-portrait__ring[data-tone="speak"] { --tone: var(--voice-orb-speak); }
.voice-portrait__ring[data-tone="mute"] { --tone: var(--voice-orb-mute); }

.voice-portrait:is([data-phase="connect"], [data-phase="listen"]) .voice-portrait__ring[data-tone="listen"],
.voice-portrait[data-phase="hear"] .voice-portrait__ring[data-tone="hear"],
.voice-portrait[data-phase="work"] .voice-portrait__ring[data-tone="work"],
.voice-portrait[data-phase="speak"] .voice-portrait__ring[data-tone="speak"],
.voice-portrait[data-phase="mute"] .voice-portrait__ring[data-tone="mute"] {
    opacity: 1;
    transition-delay: 0s;
}

.voice-portrait[data-phase="connect"] .voice-portrait__rings,
.voice-portrait[data-phase="connect"] .voice-portrait__halo {
    opacity: 0.35;
}

/* Работает: по кольцу бежит дуга — как и у сферы, без подписи. */
.voice-portrait__arc {
    left: calc(50% - var(--medal-r) - 0.125rem);
    top: calc(var(--medal-y) - var(--medal-r) - 0.125rem);
    width: calc(2 * var(--medal-r) + 0.25rem);
    height: calc(2 * var(--medal-r) + 0.25rem);
    background: conic-gradient(rgb(var(--voice-orb-work) / 0) 0 62%, rgb(var(--voice-orb-work)) 100%);
    -webkit-mask: radial-gradient(closest-side, transparent calc(100% - 0.25rem), #000 calc(100% - 0.25rem));
    mask: radial-gradient(closest-side, transparent calc(100% - 0.25rem), #000 calc(100% - 0.25rem));
    opacity: 0;
    transition: opacity 420ms ease;
}

.voice-portrait[data-phase="work"] .voice-portrait__arc {
    opacity: 1;
    animation: portrait-arc 1.6s linear infinite;
}

/* Ждёт подтверждения: кольцо медленно мерцает — «твой ход». */
.voice-mode[data-agent-state="wait"] .voice-portrait__rings {
    animation: portrait-ring-wait 2.4s ease-in-out infinite;
}

/* Персонаж: ниже середины круга — только то, что внутри круга; выше — всё, голова выходит за кольцо.
   Кольцо и ореол видны сразу, лицо проявляется, когда его части загрузились (is-ready). */
.voice-portrait__frame {
    position: absolute;
    inset: 0;
    opacity: 0;
    transition: opacity 420ms ease;
    -webkit-mask:
        radial-gradient(ellipse var(--medal-r) var(--medal-r) at 50% var(--medal-y), #000 99.4%, transparent 100%),
        linear-gradient(#000 var(--medal-y), transparent var(--medal-y));
    mask:
        radial-gradient(ellipse var(--medal-r) var(--medal-r) at 50% var(--medal-y), #000 99.4%, transparent 100%),
        linear-gradient(#000 var(--medal-y), transparent var(--medal-y));
}

.voice-portrait.is-ready .voice-portrait__frame {
    opacity: 1;
}

/* Рука — только внутри круга: за его пределами она уходит за обод, а не торчит обрывком над линией центра. */
.voice-portrait__frame--hand {
    pointer-events: none;
    -webkit-mask: radial-gradient(ellipse var(--medal-r) var(--medal-r) at 50% var(--medal-y), #000 99.4%, transparent 100%);
    mask: radial-gradient(ellipse var(--medal-r) var(--medal-r) at 50% var(--medal-y), #000 99.4%, transparent 100%);
}

.voice-portrait__body,
.voice-portrait__pose,
.voice-portrait__face,
.voice-portrait__look,
.voice-portrait__head,
.voice-portrait__talk {
    position: absolute;
    inset: 0;
}

/* Курсор: сдвиг и поворот пишет hermes-voice-portrait.js, плавность — переход (глаза догоняют быстрее). */
.voice-portrait__look {
    transform-origin: 50% 82%;
    transition: transform 250ms ease-out;
}

/* Дыхание: грудь и голова чуть поднимаются от нижнего края. */
.voice-portrait__body {
    transform-origin: 50% 100%;
    animation: portrait-breathe 4.2s ease-in-out infinite;
}

/* Поза фазы: голова поворачивается вокруг шеи. */
.voice-portrait__pose {
    transform-origin: 50% 82%;
    transition: transform 650ms cubic-bezier(0.3, 0.7, 0.3, 1), opacity 420ms ease, filter 420ms ease;
}


.voice-portrait[data-phase="listen"] .voice-portrait__pose {
    transform: translateY(0.6%) scale(1.01);
}

.voice-portrait[data-phase="hear"] .voice-portrait__pose {
    transform: translateY(1%) rotate(-2.6deg) scale(1.015);
}

.voice-portrait[data-phase="work"] .voice-portrait__pose {
    transform: translateX(1.2%) rotate(2.2deg);
}

.voice-portrait[data-phase="mute"] .voice-portrait__pose {
    filter: saturate(0.6);
    transform: translateY(1.5%) scale(0.985);
}

.voice-mode[data-agent-state="wait"] .voice-portrait__pose {
    transform: translateY(-0.8%) rotate(-3.4deg) scale(1.02);
}

.voice-mode[data-agent-state="error"] .voice-portrait__pose {
    transform: translateY(2.4%) rotate(1.4deg) scale(0.985);
}

/* Покачивание идёт всегда и при смене фазы не начинается заново; слушая — голова кивает, работая — раздумывает. */
.voice-portrait__face {
    transform-origin: 50% 82%;
    animation: portrait-sway 7.4s ease-in-out infinite;
}

.voice-portrait__head {
    transform-origin: 50% 82%;
    transition: transform 700ms cubic-bezier(0.3, 0.7, 0.3, 1);
}

.voice-portrait[data-phase="hear"] .voice-portrait__head {
    animation: portrait-listen 2.6s ease-in-out infinite;
}

.voice-portrait[data-phase="work"] .voice-portrait__head {
    animation: portrait-ponder 3.8s ease-in-out infinite;
}

/* Жесты от Jev; сила жеста — --gesture (0..1), её ставит hermes-voice-portrait.js перед жестом. */
.voice-portrait__talk {
    --gesture: 1;
    transform-origin: 50% 82%;
}

.voice-portrait__base,
.voice-portrait__layer {
    position: absolute;
    display: block;
    user-select: none;
    pointer-events: none;
}

.voice-portrait__layer[hidden] {
    display: none;
}

.voice-portrait__base {
    inset: 0;
    width: 100%;
    height: 100%;
}

/* Риг (портрет из частей): глаз — рамка с белком, радужкой под обрезкой белком и линией век; брови сдвигаются
   к нейтральному месту при слабом выражении; румянец — прозрачность. Всё — transform и opacity. */
.voice-portrait__eye,
.voice-portrait__eye-whites,
.voice-portrait__eye-clip,
.voice-portrait__eye-lines {
    position: absolute;
    pointer-events: none;
}

.voice-portrait__eye-whites,
.voice-portrait__eye-clip,
.voice-portrait__eye-lines {
    inset: 0;
}

.voice-portrait__eye-clip[hidden] {
    display: none;
}

.voice-portrait__brow {
    transition: transform 160ms ease-out;
}

.voice-portrait__cheeks {
    opacity: 0;
    transition: opacity 400ms ease;
}

/* Разовые действия от Jev (data-action), сила — --gesture. */
.voice-portrait[data-action="nod"] .voice-portrait__talk { animation: portrait-nod 0.7s ease-in-out 1; }
.voice-portrait[data-action="tilt"] .voice-portrait__talk { animation: portrait-tilt 1.1s ease-in-out 1; }
.voice-portrait[data-action="shake"] .voice-portrait__talk { animation: portrait-shake 0.9s ease-in-out 1; }
.voice-portrait[data-action="wave"] .voice-portrait__talk { animation: portrait-tilt 1.8s ease-in-out 1; --gesture: 0.45; }
.voice-portrait[data-action="wink"] .voice-portrait__talk { animation: portrait-wink 0.6s ease-in-out 1; }
.voice-portrait[data-action="fidget"] .voice-portrait__talk { animation: portrait-fidget 0.9s ease-in-out 1; }
.voice-portrait[data-action="flinch"] .voice-portrait__talk { animation: portrait-flinch 0.45s cubic-bezier(0.2, 0.8, 0.3, 1) 1; }
.voice-portrait[data-action="turn"] .voice-portrait__talk { animation: portrait-turn 1.6s cubic-bezier(0.3, 0.7, 0.3, 1) 1; }
.voice-portrait[data-action="lean"] .voice-portrait__talk { animation: portrait-lean 1.1s ease-in-out 1; }

.voice-portrait[data-action="hop"] .voice-portrait__body {
    animation: portrait-hop 0.7s cubic-bezier(0.3, 0.7, 0.3, 1) 2, portrait-breathe 4.2s ease-in-out 1.4s infinite;
}

/* Вздох: вдох, плечи опускаются, дыхание продолжается. */
.voice-portrait[data-action="sigh"] .voice-portrait__body {
    animation: portrait-sigh 1.6s ease-in-out 1, portrait-breathe 4.2s ease-in-out 1.6s infinite;
}

/* Рука взмаха: поднимается из-под края медальона, машет вокруг запястья и уходит. */
.voice-portrait__hand {
    position: absolute;
    display: block;
    user-select: none;
    pointer-events: none;
    opacity: 0;
    transform: translateY(40%) rotate(14deg);
}

.voice-portrait[data-action="wave"] .voice-portrait__hand {
    animation: portrait-wave 1.8s ease-in-out 1;
}

/* Сон — до подключения и после долгой тишины: глаза закрыты (JS), голова опущена, дыхание глубже, над головой «z».
   Пробуждение — голова поднимается с лёгким потягиванием. */
.voice-portrait[data-sleep] .voice-portrait__pose {
    filter: saturate(0.85) brightness(0.94);
    transform: translateY(2.2%) rotate(2.4deg) scale(0.985);
}

.voice-portrait[data-sleep] .voice-portrait__body {
    animation: portrait-sleep-breathe 5.4s ease-in-out infinite;
}

.voice-portrait[data-wake] .voice-portrait__head {
    animation: portrait-wake 0.9s ease-out 1;
}

/* Лёгкий профиль (сенсорный экран, круг-кнопка шторки, «без движения»): без ореола и бегущей дуги — они стоят
   композитору слоёв на каждый кадр. Кадры реже ведёт hermes-voice-portrait.js. */
.voice-portrait[data-lite] .voice-portrait__halo {
    display: none;
}

.voice-portrait[data-lite] .voice-portrait__arc {
    animation: none;
}

/* Сон: бесконечные анимации — на паузе, пока не разбудят («z» продолжают подниматься). */
.voice-portrait[data-sleep] :is(.voice-portrait__body, .voice-portrait__face, .voice-portrait__head, .voice-portrait__arc, .voice-portrait__rings) {
    animation-play-state: paused;
}

.voice-portrait__zzz {
    position: absolute;
    left: 80%;
    top: -2%;
    width: 16%;
    height: 22%;
    pointer-events: none;
    opacity: 0;
    transition: opacity 600ms ease;
}

.voice-portrait[data-sleep] .voice-portrait__zzz {
    opacity: 1;
}

.voice-portrait__zzz span {
    position: absolute;
    left: 0;
    bottom: 0;
    font: 800 clamp(0.75rem, 7cqw, 2rem)/1 system-ui, sans-serif;
    color: rgb(var(--voice-orb-listen));
    text-shadow: 0 0 0.4em rgb(var(--voice-orb-listen) / 0.45);
    opacity: 0;
    animation: portrait-zzz 3.6s ease-in infinite;
}

.voice-portrait__zzz span::before {
    content: "z";
}

/* С листом эффектов «z» — значок персонажа. */
.voice-portrait__zzz--icon span {
    width: 42%;
    background-repeat: no-repeat;
}

.voice-portrait__zzz--icon span::before {
    content: none;
}

.voice-portrait__zzz span:nth-child(2) { animation-delay: 1.2s; }
.voice-portrait__zzz span:nth-child(3) { animation-delay: 2.4s; }

/* Тишина: голова следит за взглядом (глаза — слои из manifest.idle), мурлычет, зевает, клюёт носом. */
.voice-portrait[data-idle="look-left"] .voice-portrait__head { transform: translateX(-1.2%) rotate(-2deg); }
.voice-portrait[data-idle="look-right"] .voice-portrait__head { transform: translateX(1.2%) rotate(2deg); }
.voice-portrait[data-idle="look-up"] .voice-portrait__head { transform: translateY(-0.9%) rotate(-0.6deg) scale(1.01); }
.voice-portrait[data-idle="content"] .voice-portrait__head { animation: portrait-hum 1.8s ease-in-out 1; }
.voice-portrait[data-idle="yawn"] .voice-portrait__head { animation: portrait-yawn 2s ease-in-out 1; }
.voice-portrait[data-idle="drowsy"] .voice-portrait__head { transform: translateY(1.2%) rotate(1.6deg); }

/* Эффекты у головы: значок из листа (фон) или знак шрифта; всплывает и тает, пот стекает, досада пульсирует у виска.
   Сдвиги — в cqw/cqh портрета: проценты transform считались бы от самого значка. */
.voice-portrait__fx {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.voice-portrait__fx-icon {
    position: absolute;
    translate: -50% -50%;
    background-repeat: no-repeat;
    opacity: 0;
    animation: portrait-fx-rise var(--fx-ms, 1.6s) ease-out var(--fx-delay, 0s) 1 both;
}

.voice-portrait__fx-icon[data-motion="pop"] { animation-name: portrait-fx-pop; }
.voice-portrait__fx-icon[data-motion="drip"] { animation-name: portrait-fx-drip; }
.voice-portrait__fx-icon[data-motion="pulse"] { animation-name: portrait-fx-pulse; }

.voice-portrait__fx-icon[data-glyph] {
    aspect-ratio: 1;
    font: 900 8cqw/1 system-ui, sans-serif;
    text-align: center;
    color: rgb(var(--voice-orb-listen));
    text-shadow: 0 0 0.25em rgb(0 0 0 / 0.45);
}

.voice-portrait__fx-icon[data-glyph="heart"],
.voice-portrait__fx-icon[data-glyph="anger"],
.voice-portrait__fx-icon[data-glyph="exclaim"] { color: #ff5a6e; }
.voice-portrait__fx-icon[data-glyph="sparkles"] { color: #ffd34d; }
.voice-portrait__fx-icon[data-glyph="notes"] { color: #a78bfa; }

.voice-mode[data-agent-state="done"] .voice-portrait__body {
    animation: portrait-hop 0.7s cubic-bezier(0.3, 0.7, 0.3, 1) 2, portrait-breathe 4.2s ease-in-out 1.4s infinite;
}

@keyframes portrait-breathe {
    0%, 100% { transform: scale(1, 1); }
    45% { transform: scale(1.006, 1.014); }
}

@keyframes portrait-sway {
    0%, 100% { transform: rotate(0deg) translateX(0); }
    30% { transform: rotate(0.9deg) translateX(0.3%); }
    70% { transform: rotate(-0.8deg) translateX(-0.3%); }
}

@keyframes portrait-listen {
    0%, 100% { transform: rotate(0deg) translateY(0); }
    18% { transform: rotate(0.6deg) translateY(1.1%); }
    32% { transform: rotate(0deg) translateY(0); }
    50% { transform: rotate(-0.4deg) translateY(0.8%); }
    64% { transform: rotate(0deg) translateY(0); }
}

@keyframes portrait-ponder {
    0%, 100% { transform: rotate(0deg); }
    40% { transform: rotate(1.6deg) translateY(-0.4%); }
    75% { transform: rotate(-0.6deg); }
}

@keyframes portrait-nod {
    0%, 100% { transform: translateY(0); }
    40% { transform: translateY(calc(1.8% * var(--gesture))) rotate(calc(0.5deg * var(--gesture))); }
}

@keyframes portrait-tilt {
    0%, 100% { transform: rotate(0deg); }
    35%, 70% { transform: rotate(calc(-5deg * var(--gesture))) translateX(calc(-0.8% * var(--gesture))); }
}

@keyframes portrait-shake {
    0%, 100% { transform: rotate(0deg); }
    20% { transform: rotate(calc(-3.5deg * var(--gesture))); }
    45% { transform: rotate(calc(3deg * var(--gesture))); }
    70% { transform: rotate(calc(-2deg * var(--gesture))); }
}

@keyframes portrait-wave {
    0% { opacity: 0; transform: translateY(40%) rotate(14deg); }
    16% { opacity: 1; transform: translateY(0) rotate(0deg); }
    32% { transform: translateY(0) rotate(-14deg); }
    48% { transform: translateY(0) rotate(10deg); }
    64% { transform: translateY(0) rotate(-12deg); }
    80% { opacity: 1; transform: translateY(0) rotate(4deg); }
    100% { opacity: 0; transform: translateY(40%) rotate(14deg); }
}

@keyframes portrait-sleep-breathe {
    0%, 100% { transform: scale(1, 1); }
    45% { transform: scale(1.01, 1.026); }
}

@keyframes portrait-wake {
    0% { transform: translateY(1%) rotate(1.4deg); }
    55% { transform: translateY(-1.4%) rotate(-0.8deg) scale(1.012); }
    100% { transform: none; }
}

@keyframes portrait-zzz {
    0% { opacity: 0; transform: translate(0, 0) scale(0.6); }
    20% { opacity: 1; }
    100% { opacity: 0; transform: translate(60%, -160%) scale(1.15); }
}

@keyframes portrait-hum {
    0%, 100% { transform: rotate(0deg); }
    30% { transform: rotate(2.6deg) translateY(-0.3%); }
    65% { transform: rotate(-1.8deg) translateY(-0.2%); }
}

@keyframes portrait-yawn {
    0%, 100% { transform: none; }
    35%, 70% { transform: translateY(-1.2%) rotate(-1.4deg) scale(1.012); }
}

@keyframes portrait-wink {
    0%, 100% { transform: none; }
    40%, 70% { transform: rotate(-2deg) translateY(-0.3%); }
}

@keyframes portrait-fidget {
    0%, 100% { transform: none; }
    15% { transform: rotate(2.6deg) translateX(0.6%); }
    35% { transform: rotate(-2.4deg) translateX(-0.6%); }
    55% { transform: rotate(2deg) translateX(0.5%); }
    75% { transform: rotate(-1.4deg) translateX(-0.3%); }
}

/* Вздрогнул: быстрый отскок назад, возврат медленнее. */
@keyframes portrait-flinch {
    0%, 100% { transform: none; }
    22% { transform: translateY(-1.8%) scale(0.97); }
}

/* Отвернулся: отвести, подержать, вернуть. */
@keyframes portrait-turn {
    0%, 100% { transform: none; }
    22%, 72% { transform: translateX(2%) rotate(3.5deg); }
}

/* Подался к собеседнику: ближе и внимательнее, без кивка. */
@keyframes portrait-lean {
    0%, 100% { transform: none; }
    35%, 65% { transform: translateY(0.6%) scale(1.025) rotate(-1deg); }
}

@keyframes portrait-sigh {
    0%, 100% { transform: none; }
    30% { transform: translateY(-0.6%) scale(1.008, 1.02); }
    65% { transform: translateY(1.4%) scale(1, 0.985); }
}

@keyframes portrait-fx-rise {
    0% { opacity: 0; transform: translate(0, 0) scale(0.6) rotate(var(--fx-rot, 0deg)); }
    15% { opacity: 1; transform: translate(calc(var(--fx-dx, 0cqw) * 0.2), -2cqh) scale(1.08) rotate(0deg); }
    70% { opacity: 1; }
    100% { opacity: 0; transform: translate(var(--fx-dx, 0cqw), -12cqh) scale(1) rotate(calc(var(--fx-rot, 0deg) * -1)); }
}

@keyframes portrait-fx-pop {
    0% { opacity: 0; transform: scale(0.4); }
    18% { opacity: 1; transform: translateY(-1.5cqh) scale(1.15); }
    30%, 75% { opacity: 1; transform: translateY(-2cqh) scale(1); }
    100% { opacity: 0; transform: translateY(-4cqh) scale(0.95); }
}

@keyframes portrait-fx-drip {
    0% { opacity: 0; transform: scale(0.6); }
    15% { opacity: 1; transform: scale(1); }
    70% { opacity: 1; }
    100% { opacity: 0; transform: translateY(5cqh) scale(0.9); }
}

@keyframes portrait-fx-pulse {
    0% { opacity: 0; transform: scale(0.5); }
    15% { opacity: 1; transform: scale(1.15); }
    30% { transform: scale(0.95); }
    45% { transform: scale(1.1); }
    60%, 80% { opacity: 1; transform: scale(1); }
    100% { opacity: 0; transform: scale(0.9); }
}

@keyframes portrait-arc {
    to { transform: rotate(1turn); }
}

@keyframes portrait-ring-wait {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.4; }
}

@keyframes portrait-hop {
    0%, 100% { transform: translateY(0) scale(1, 1); }
    18% { transform: translateY(1%) scale(1.02, 0.97); }
    50% { transform: translateY(-5%) scale(0.98, 1.03); }
    80% { transform: translateY(0.6%) scale(1.01, 0.99); }
}

@media (prefers-reduced-motion: reduce) {
    .voice-portrait__zzz span {
        animation: none;
        opacity: 0.8;
    }

    .voice-portrait__zzz span:nth-child(2) { transform: translate(40%, -110%); }
    .voice-portrait__zzz span:nth-child(3) { transform: translate(80%, -220%); }

    /* Эффект стоит на месте и исчезает по таймеру. */
    .voice-portrait__fx-icon {
        animation: none;
        opacity: 1;
    }

    .voice-portrait__look {
        transition: none;
    }
}

/* Границы те же, что у оболочки (hermes-shell.css): колонка складывается на 900 px, шторка — на 600 px. */
@media (max-width: 900px) {
    .hermes-dashboard .voice-mode__orb--portrait {
        width: clamp(11rem, 34vh, 17rem);
    }
}

@media (max-width: 600px) {
    .hermes-dashboard .voice-mode--sheet-collapsed .voice-mode__orb--portrait {
        width: clamp(13rem, 44vh, 20rem);
    }

    .hermes-dashboard .voice-mode--sheet-half .voice-mode__orb--portrait {
        width: 9.5rem;
    }

    .hermes-dashboard .voice-mode--sheet-full .voice-mode__orb--portrait {
        width: 3rem;
    }
}
