/* Talking Hamster (talking_hamster) — оформление игрушки. Категория fun.
   Тёплая кремовая карточка, посреди неё пухлый золотистый хомяк. Всё живое рисует CSS по трём
   переменным, которые правит JS: --mouth (раскрытие рта 0..1), --cheek (надувание щёк 0..1),
   --level (что слышит микрофон 0..1). Каркас — Bootstrap, кастом (персонаж, кнопки голосов) —
   это и есть сама игрушка (см. .tool_conventions/fun.md), поверх токенов сайта.
   Префикс .thm. Сайтовые шапку/меню/H1 не трогаем (см. _common.md «Подложка инструмента»). */

.thm-wrap {
    /* мех и мордочка */
    --th-fur:       #e9a959;
    --th-fur-hi:    #f6c886;
    --th-fur-deep:  #cd8636;
    --th-cream:     #f8e2be;
    --th-cream-hi:  #fff6e6;
    --th-ear-in:    #e79aa2;
    --th-nose:      #d9737f;
    --th-eye:       #3a2b20;
    --th-mouth:     #a84a58;
    --th-tongue:    #ef8b99;
    --th-paw:       #f0c08d;

    /* карточка */
    --th-bg-1:      #fff6e8;
    --th-bg-2:      #ffe2bd;
    --th-card:      #fffaf2;
    --th-line:      #e8d3b4;
    --th-text:      #5a4632;
    --th-muted:     #9a866c;
    --th-accent:    #f0872f;
    --th-accent-hi: #ffa958;
    --th-danger:    #c8503f;
    --th-radius:    22px;

    max-width: 600px;
    margin-inline: auto;
}

.thm {
    --mouth: 0;   /* 0..1 — раскрытие рта (громкость того, что хомяк ГОВОРИТ) */
    --cheek: 0;   /* 0..1 — надувание защёчных мешков (громкость того, что он СЛЫШИТ) */
    --level: 0;   /* 0..1 — уровень с микрофона для индикатора-дуги */

    position: relative;
    width: 100%;
    color: var(--th-text);
    font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    background: radial-gradient(120% 100% at 50% 0%, var(--th-bg-1), var(--th-bg-2));
    border: 1px solid var(--th-line);
    border-radius: var(--th-radius);
    box-shadow: 0 10px 30px rgba(122, 79, 26, .16);
    padding: 1.1rem 1.15rem 1.15rem;
    overflow: hidden;
}

/* ── Сцена с персонажем ──────────────────────────────────────────────────── */

.thm__scene {
    position: relative;
    background:
        radial-gradient(80% 60% at 50% 88%, rgba(255, 213, 156, .75), transparent 70%),
        var(--th-card);
    border: 1px solid var(--th-line);
    border-radius: 18px;
    padding: .6rem .6rem .2rem;
}

.thm__hamster {
    display: block;
    width: 100%;
    max-width: 320px;
    height: auto;
    margin-inline: auto;
    overflow: visible;
}

/* Облачко-подсказка над хомяком */
.thm__bubble {
    position: relative;
    z-index: 2;
    width: max-content;
    max-width: 92%;
    margin: .1rem auto .2rem;
    padding: .42rem .85rem;
    background: #fff;
    border: 2px solid var(--th-line);
    border-radius: 999px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--th-text);
    box-shadow: 0 3px 0 rgba(122, 79, 26, .08);
    transition: transform .18s ease;
}
.thm__bubble::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -9px;
    width: 14px;
    height: 14px;
    background: #fff;
    border-right: 2px solid var(--th-line);
    border-bottom: 2px solid var(--th-line);
    transform: translateX(-50%) rotate(45deg);
}
.thm[data-state="talking"] .thm__bubble { transform: scale(1.06); }

/* ── Персонаж: тело, дыхание, подскок ────────────────────────────────────── */

.thm-shadow { fill: rgba(150, 104, 44, .18); }

.thm-body {
    transform-box: fill-box;
    transform-origin: center bottom;
    animation: thm-breathe var(--th-breath, 3.2s) ease-in-out infinite;
}
@keyframes thm-breathe {
    0%, 100% { transform: scale(1, 1); }
    50%      { transform: scale(1.015, 1.025); }
}
/* Слушает — замер и чуть подался вперёд */
.thm[data-state="hearing"] .thm-body { animation-duration: calc(var(--th-breath, 3.2s) * .55); }
/* Говорит — подпрыгивает в такт (амплитуда — из голоса, --th-bounce) */
.thm[data-state="talking"] .thm-body {
    animation: thm-hop calc(.34s / var(--th-bounce, 1)) ease-in-out infinite;
}
@keyframes thm-hop {
    0%, 100% { transform: translateY(0)                                   scale(1, 1); }
    35%      { transform: translateY(calc(var(--th-bounce, 1) * -9px))    scale(.985, 1.03); }
    70%      { transform: translateY(calc(var(--th-bounce, 1) * 1.5px))   scale(1.03, .97); }
}

.thm-fur    { fill: url(#thm-fur-grad); }
.thm-belly  { fill: url(#thm-belly-grad); }
.thm-muzzle { fill: url(#thm-belly-grad); }

/* Уши: подрагивают в покое, встают торчком, когда слушает */
.thm-ear__outer { fill: var(--th-fur-deep); }
.thm-ear__inner { fill: var(--th-ear-in); }
.thm-ear {
    transform-box: fill-box;
    transform-origin: center bottom;
    transition: transform .25s ease;
}
.thm-ear--l { animation: thm-twitch-l var(--th-twitch, 5s) ease-in-out infinite; }
.thm-ear--r { animation: thm-twitch-r var(--th-twitch, 5s) ease-in-out infinite; }
@keyframes thm-twitch-l {
    0%, 88%, 100% { transform: rotate(0deg); }
    92%           { transform: rotate(-9deg); }
    96%           { transform: rotate(3deg); }
}
@keyframes thm-twitch-r {
    0%, 90%, 100% { transform: rotate(0deg); }
    94%           { transform: rotate(9deg); }
    98%           { transform: rotate(-3deg); }
}
.thm[data-state="hearing"] .thm-ear--l,
.thm[data-state="listening"] .thm-ear--l { transform: rotate(-11deg) scale(1.06); }
.thm[data-state="hearing"] .thm-ear--r,
.thm[data-state="listening"] .thm-ear--r { transform: rotate(11deg) scale(1.06); }

/* Защёчные мешки: раздуваются от того, что хомяк слышит */
.thm-cheek {
    fill: url(#thm-cheek-grad);
    transform-box: fill-box;
    transform-origin: center;
    transform: scale(calc(1 + var(--cheek) * .3));
}
.thm-cheek--l { transform: translate(calc(var(--cheek) * -5px), calc(var(--cheek) * 3px)) scale(calc(1 + var(--cheek) * .26)); }
.thm-cheek--r { transform: translate(calc(var(--cheek) *  5px), calc(var(--cheek) * 3px)) scale(calc(1 + var(--cheek) * .26)); }

/* Глаза + моргание (веко цвета меха опускается сверху) */
.thm-eye__ball  { fill: var(--th-eye); }
.thm-eye__spark { fill: #fff; }
.thm-eye__glint { fill: rgba(255, 255, 255, .5); }
.thm-eye__lid {
    fill: var(--th-fur);
    transform-box: fill-box;
    transform-origin: center top;
    transform: scaleY(0);
}
.thm.is-blink .thm-eye__lid { transform: scaleY(1); }
/* Слушает — глаза шире (веко точно убрано, зрачок крупнее) */
.thm[data-state="hearing"] .thm-eye__ball { transform: none; }

.thm-whiskers {
    fill: none;
    stroke: rgba(120, 84, 40, .5);
    stroke-width: 2.4;
    stroke-linecap: round;
}
.thm-nose        { fill: var(--th-nose); }
.thm-nose__shine { fill: rgba(255, 255, 255, .55); }
.thm-blush       { fill: rgba(231, 138, 146, .38); }
.thm-philtrum    { stroke: rgba(120, 84, 40, .45); stroke-width: 2.2; stroke-linecap: round; fill: none; }
.thm-teeth       { fill: #fffdf6; stroke: rgba(120, 84, 40, .35); stroke-width: 1.4; stroke-linejoin: round; }
.thm-smile       { fill: none; stroke: var(--th-mouth); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }

/* Пасть: закрыта — схлопнута в линию губы и спрятана за резцами; раскрывается по громкости голоса */
.thm-mouth {
    transform-box: fill-box;
    transform-origin: center top;
    transform: scaleY(calc(.05 + var(--mouth) * .95));
}
.thm-mouth__hole   { fill: var(--th-mouth); }
.thm-mouth__tongue { fill: var(--th-tongue); }

.thm-paw { fill: var(--th-paw); }
/* Лапки чуть разводятся, когда хомяк набивает щёки */
.thm-paw--hand {
    transform-box: fill-box;
    transform-origin: center;
    transition: transform .2s ease;
}
.thm[data-state="hearing"] #thm-hand-l { transform: translate(-4px, -3px) rotate(-12deg); }
.thm[data-state="hearing"] #thm-hand-r { transform: translate( 4px, -3px) rotate( 12deg); }

/* ── Индикатор «что слышит микрофон» ─────────────────────────────────────── */

.thm__level {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: 5px;
    height: 22px;
    margin: -.2rem 0 .35rem;
    opacity: 0;
    transition: opacity .2s ease;
}
.thm[data-state="listening"] .thm__level,
.thm[data-state="hearing"]   .thm__level { opacity: 1; }

.thm__level-bar {
    width: 7px;
    height: 7px;
    border-radius: 4px;
    background: var(--th-line);
    transition: height .07s linear, background-color .07s linear;
}
/* Полоски загораются по очереди: n-я — когда уровень перевалил за n/7 */
.thm__level-bar:nth-child(1) { height: calc(7px + min(var(--level) * 7, 1) * 13px); }
.thm__level-bar:nth-child(2) { height: calc(7px + clamp(0, (var(--level) * 7 - 1), 1) * 13px); }
.thm__level-bar:nth-child(3) { height: calc(7px + clamp(0, (var(--level) * 7 - 2), 1) * 13px); }
.thm__level-bar:nth-child(4) { height: calc(7px + clamp(0, (var(--level) * 7 - 3), 1) * 13px); }
.thm__level-bar:nth-child(5) { height: calc(7px + clamp(0, (var(--level) * 7 - 4), 1) * 13px); }
.thm__level-bar:nth-child(6) { height: calc(7px + clamp(0, (var(--level) * 7 - 5), 1) * 13px); }
.thm__level-bar:nth-child(7) { height: calc(7px + clamp(0, (var(--level) * 7 - 6), 1) * 13px); }
.thm[data-state="hearing"] .thm__level-bar { background: var(--th-accent); }

/* ── Ошибка ──────────────────────────────────────────────────────────────── */

.thm__error {
    margin: .7rem 0 0;
    padding: .6rem .8rem;
    background: #fdece9;
    border: 1px solid #f0c3bb;
    border-radius: 12px;
    color: var(--th-danger);
    font-size: .93rem;
    text-align: center;
}
.thm__error[hidden] { display: none; }

/* ── Главная кнопка ──────────────────────────────────────────────────────── */

.thm__main {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .3rem;
    margin-top: .85rem;
}

.thm__talk {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-width: 15rem;
    padding: .72rem 1.5rem;
    font-size: 1.08rem;
    font-weight: 700;
    color: #fff;
    background: linear-gradient(180deg, var(--th-accent-hi), var(--th-accent));
    border: 0;
    border-radius: 999px;
    box-shadow: 0 4px 0 #c96a1c, 0 8px 18px rgba(201, 106, 28, .3);
    cursor: pointer;
    transition: transform .1s ease, box-shadow .1s ease, background-color .2s ease;
}
.thm__talk:hover  { filter: brightness(1.04); }
.thm__talk:active { transform: translateY(3px); box-shadow: 0 1px 0 #c96a1c, 0 3px 10px rgba(201, 106, 28, .3); }
.thm__talk .bi    { font-size: 1.2rem; }

/* Слух включён — кнопка становится «стоп» и мягко пульсирует */
.thm[data-state="listening"] .thm__talk,
.thm[data-state="hearing"]   .thm__talk,
.thm[data-state="talking"]   .thm__talk {
    background: linear-gradient(180deg, #7fc98a, #4da55f);
    box-shadow: 0 4px 0 #3c8a4c, 0 8px 18px rgba(60, 138, 76, .3);
}
.thm[data-state="listening"] .thm__talk { animation: thm-pulse 2s ease-in-out infinite; }
@keyframes thm-pulse {
    0%, 100% { box-shadow: 0 4px 0 #3c8a4c, 0 8px 18px rgba(60, 138, 76, .3); }
    50%      { box-shadow: 0 4px 0 #3c8a4c, 0 8px 26px rgba(60, 138, 76, .55); }
}

.thm__hint {
    font-size: .88rem;
    color: var(--th-muted);
    text-align: center;
}

/* ── Голоса ──────────────────────────────────────────────────────────────── */

.thm__voices {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: .5rem;
    margin-top: .9rem;
}

.thm__voice {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .18rem;
    width: 5.1rem;
    padding: .45rem .3rem .4rem;
    background: var(--th-card);
    border: 2px solid var(--th-line);
    border-radius: 16px;
    color: var(--th-text);
    font-size: .8rem;
    font-weight: 600;
    line-height: 1.1;
    cursor: pointer;
    transition: transform .12s ease, border-color .15s ease, background-color .15s ease;
}
.thm__voice:hover { transform: translateY(-2px); border-color: var(--th-accent-hi); }
.thm__voice[aria-pressed="true"] {
    border-color: var(--th-accent);
    background: #fff2e0;
    box-shadow: 0 3px 0 rgba(201, 106, 28, .18);
}
.thm__voice-ic {
    display: block;
    width: 44px;
    height: 44px;
    pointer-events: none;
}
.thm__voice-name {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* ── Нижняя панель ───────────────────────────────────────────────────────── */

.thm__bar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: .45rem;
    margin-top: .9rem;
    padding-top: .8rem;
    border-top: 1px dashed var(--th-line);
}

.thm__info,
.thm__again,
.thm__save {
    display: inline-flex;
    align-items: center;
    gap: .38rem;
    padding: .42rem .8rem;
    background: var(--th-card);
    border: 1px solid var(--th-line);
    border-radius: 999px;
    color: var(--th-text);
    font-size: .9rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease, opacity .15s ease;
}
.thm__info  { padding: .42rem .55rem; font-size: 1.05rem; }
.thm__info:hover,
.thm__again:not(:disabled):hover,
.thm__save:not(:disabled):hover { border-color: var(--th-accent); color: var(--th-accent); }

.thm__again:disabled,
.thm__save:disabled { opacity: .45; cursor: default; }

/* Кнопка сохранения: на широком экране подпись целиком, на узком — короткая версия.
   Обе лежат в разметке, выбор — медиазапросом (тексты в локализации, а не в CSS). */
.thm__save-short { display: none; }
/* Пока кодируется MP3 — кнопка занята; иконка крутится, ширина не прыгает */
.thm__save.is-working .bi { animation: thm-spin .9s linear infinite; }
@keyframes thm-spin { to { transform: rotate(360deg); } }

/* Ни браузерного outline, ни синего bootstrap-ring на кнопках игрушки (глобальное правило сайта,
   см. CLAUDE.md «Без bootstrap/браузерного обрамления поля при нажатии»). Клавиатурный фокус при этом
   не теряется — он свой, тёплый, на токене инструмента. */
.thm button:focus { outline: none; }
.thm__voice:focus-visible,
.thm__info:focus-visible,
.thm__again:focus-visible,
.thm__save:focus-visible {
    outline: none;
    border-color: var(--th-accent);
    box-shadow: 0 0 0 3px rgba(240, 135, 47, .3);
}
.thm__talk:focus-visible {
    outline: none;
    box-shadow: 0 4px 0 #c96a1c, 0 8px 18px rgba(201, 106, 28, .3), 0 0 0 4px rgba(240, 135, 47, .35);
}
.thm[data-state="listening"] .thm__talk:focus-visible,
.thm[data-state="hearing"]   .thm__talk:focus-visible,
.thm[data-state="talking"]   .thm__talk:focus-visible {
    box-shadow: 0 4px 0 #3c8a4c, 0 8px 18px rgba(60, 138, 76, .3), 0 0 0 4px rgba(77, 165, 95, .4);
}

/* Всплывающая подсказка ⓘ — отдельный элемент, position:fixed, позицию считает JS
   (см. _common.md «Всплывающие подсказки — отдельный элемент, прижатый к окну») */
.thm-tip {
    position: fixed;
    z-index: 1080;
    max-width: 17rem;
    padding: .5rem .7rem;
    background: #3a2b20;
    color: #fff6e6;
    font-size: .86rem;
    line-height: 1.35;
    border-radius: 10px;
    box-shadow: 0 6px 18px rgba(58, 43, 32, .3);
    pointer-events: none;
    opacity: 0;
    transition: opacity .12s ease;
}
.thm-tip.is-open { opacity: 1; }

/* ── Мобайл ──────────────────────────────────────────────────────────────── */

@media (max-width: 480px) {
    .thm { padding: .8rem .7rem .9rem; }
    .thm__hamster { max-width: 260px; }
    .thm__bubble { font-size: .93rem; padding: .36rem .7rem; }
    .thm__talk { min-width: 0; width: 100%; font-size: 1rem; padding: .7rem 1rem; }
    /* Ряд голосов делит всю ширину поровну: имя обязано влезать в строку целиком,
       обрезать его многоточием нельзя (см. _common.md «Мобайл — отдельная компоновка») */
    .thm__voices { flex-wrap: nowrap; gap: .4rem; }
    .thm__voice { flex: 1 1 0; width: auto; min-width: 0; font-size: .74rem; padding: .42rem .2rem .38rem; }
    .thm__voice-ic { width: 38px; height: 38px; }
    .thm__bar { gap: .35rem; }
    .thm__info, .thm__again, .thm__save { font-size: .84rem; padding: .4rem .65rem; }
    .thm__save-full  { display: none; }
    .thm__save-short { display: inline; }
}

@media (max-width: 360px) {
    .thm__voices { gap: .3rem; }
    .thm__voice { font-size: .7rem; padding: .4rem .12rem .34rem; }
}

/* ── Уважение к тем, кому движение мешает ────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    .thm-body,
    .thm-ear--l,
    .thm-ear--r,
    .thm[data-state="talking"] .thm-body,
    .thm[data-state="listening"] .thm__talk { animation: none !important; }
    .thm__bubble,
    .thm-cheek,
    .thm-ear,
    .thm-paw--hand { transition: none; }
}
