/* ═══ Аиҭагаҩ · стиль приложения ═══
   Токены v0.2 платформы + флаговый зелёный акцент продукта
   (значения совпадают с packages/tokens/accents/translate.css). */

:root{
  --paper:#EFF8FC; --card:#FFFFFF; --paper-warm:#FFFBEA;
  --ink:#243B4A; --ink-soft:#5B7283; --line:#E7EDF1;
  --sun:#FFD500; --sun-deep:#F4B800; --sun-dark:#D99B00; --sun-ink:#4D3800;
  --sky:#6FD2F4; --sky-pale:#CFF1FC; --grass:#62D435;
  --green:#2E8E12; --green-deep:#20670B; --green-tint:#E9FBDF;
  --hand:#E8402E; --hand-tint:#FEEFED;
  --shadow-card:0 6px 0 rgba(36,59,74,.10);
  --font-display:"PT Sans","Noto Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-body:"PT Sans","Noto Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-lit:"PT Serif","Noto Serif",Georgia,"Times New Roman",serif;
  --r:18px; --r-lg:26px; --r-md:18px; --r-sm:12px; --r-pill:999px;
  --accent:#0E9E4F; --accent-deep:#0B7A3C; --accent-tint:#E3F6EB; --accent-ink:#FFFFFF;
  color-scheme:light;   /* native controls (the select's popup) follow the app theme */
}
@media (prefers-color-scheme: dark){
  :root{
    color-scheme:dark;
    --paper:#0F1D2A; --card:#182B3B; --paper-warm:#20303E;
    --ink:#E8F1F8; --ink-soft:#9FB4C4; --line:#2C4256;
    --sun:#FFD500; --sun-deep:#C79E00; --sun-dark:#8F7100; --sun-ink:#4D3800;
    --sky:#1B4965; --sky-pale:#14293C; --grass:#62D435;
    --green:#7BE048; --green-deep:#3FAE1E; --green-tint:#1C3312;
    --hand:#FF6B5A; --hand-tint:#3A1D18;
    --shadow-card:0 6px 0 rgba(0,0,0,.35);
    --accent:#37C77E; --accent-deep:#0E9E4F; --accent-tint:#10301F; --accent-ink:#05160D;
  }
}
/* explicit theme choice — must beat the media query in BOTH directions */
:root[data-theme="dark"]{
  color-scheme:dark;
  --paper:#0F1D2A; --card:#182B3B; --paper-warm:#20303E;
  --ink:#E8F1F8; --ink-soft:#9FB4C4; --line:#2C4256;
  --sun:#FFD500; --sun-deep:#C79E00; --sun-dark:#8F7100; --sun-ink:#4D3800;
  --sky:#1B4965; --sky-pale:#14293C; --grass:#62D435;
  --green:#7BE048; --green-deep:#3FAE1E; --green-tint:#1C3312;
  --hand:#FF6B5A; --hand-tint:#3A1D18;
  --shadow-card:0 6px 0 rgba(0,0,0,.35);
  --accent:#37C77E; --accent-deep:#0E9E4F; --accent-tint:#10301F; --accent-ink:#05160D;
}
:root[data-theme="light"]{
  color-scheme:light;
  --paper:#EFF8FC; --card:#FFFFFF; --paper-warm:#FFFBEA;
  --ink:#243B4A; --ink-soft:#5B7283; --line:#E7EDF1;
  --sun:#FFD500; --sun-deep:#F4B800; --sun-dark:#D99B00; --sun-ink:#4D3800;
  --sky:#6FD2F4; --sky-pale:#CFF1FC; --grass:#62D435;
  --green:#2E8E12; --green-deep:#20670B; --green-tint:#E9FBDF;
  --hand:#E8402E; --hand-tint:#FEEFED;
  --shadow-card:0 6px 0 rgba(36,59,74,.10);
  --accent:#0E9E4F; --accent-deep:#0B7A3C; --accent-tint:#E3F6EB; --accent-ink:#FFFFFF;
}

*{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent}
html,body{height:100%}
html{touch-action:manipulation; -webkit-text-size-adjust:100%}
body{
  background:var(--paper); color:var(--ink);
  font-family:var(--font-body); font-size:1.0625rem; line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow:hidden; overscroll-behavior:none;
}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}
[hidden]{display:none!important}

/* ── ощущение приложения на касании ──
   Строка 53 убирает только серую вспышку под пальцем; синее выделение оставалось,
   и долгое нажатие на подпись кнопки или на язык в панели подхватывало их как
   текст, с ручками и меню «скопировать». Канон — packages/tokens/tokens.css
   (коммит 3933488); сюда он не попадал, потому что приложение инлайнит токены.
   ИСКЛЮЧЕНИЕ: .stage .text — распознанное и переведённое. Ради него всё и
   затевалось, его копируют руками, поэтому там выделение и вызов меню остаются. */
@media (pointer:coarse){
  body{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
  .stage .text,input,textarea,[contenteditable]{
    -webkit-user-select:text;user-select:text;-webkit-touch-callout:default}
  :focus:not(:focus-visible){outline:none}
}

.app{
  position:fixed;inset:0;margin-inline:auto;max-width:520px;width:100%;height:100%;
  background:var(--card);display:flex;flex-direction:column;
}
@media (min-width:560px){
  .app{border-inline:2.5px solid var(--line)}
}

/* ── шапка ── под статус-баром телефона. Сборка из App Store прижимает WKWebView к
   самому верху экрана и выключает системный отступ — с расчётом, что страница
   отступит сама через env(safe-area-inset-*). Снизу она отступала, сверху — нет:
   часы ложились на логотип, батарея — на чипы (отзыв 3 Sep 2026, Аиҭагаҩ). В
   обычной вкладке и в PWA из Safari inset равен нулю, и ничего не меняется. */
.appbar{display:flex;align-items:center;gap:.55rem;padding:calc(.85rem + env(safe-area-inset-top)) 1.1rem .3rem;flex:none}
.appbar img{width:30px;height:30px;flex:none}
.appbar b{font-family:var(--font-display);font-weight:900;font-size:1.12rem;letter-spacing:.01em}
.appbar b .hi{color:var(--accent)}
@keyframes install-nudge{0%,80%,100%{transform:translateY(0)}86%{transform:translateY(-3px)}92%{transform:translateY(0)}}
/* Кнопки без «объёма» (Нарт, 7 сен 2026): плоские чипы, нажатие — лёгкое сжатие.
   Токены платформы велят жёсткую тень под всем нажимаемым — здесь его решение. */
.chip-theme{flex:none;width:36px;height:36px;border-radius:50%;
  background:var(--paper);color:var(--ink-soft);
  display:flex;align-items:center;justify-content:center}
.chip-theme:active{transform:scale(.94)}
.chip-theme svg{width:19px;height:19px}
/* ── аццакра: у OmniVoice нет параметра скорости речи, а короткую строку он читает
      медленно (замерено 2026-08-10: 9,5 зн/с на 14 знаках против ~16 на абзаце) —
      именно поэтому одно предложение перевода звучит вяло. Единственный рычаг —
      скорость воспроизведения. Не круглая: внутри цифры, а не значок ── */
.chip-speed{flex:none;height:36px;min-width:36px;padding:0 .42rem;border-radius:18px;
  background:var(--paper);color:var(--ink-soft);
  display:flex;align-items:center;justify-content:center;
  font-weight:700;font-size:.74rem;font-variant-numeric:tabular-nums}
.chip-speed:active{transform:scale(.94)}
/* ── ашара: установленное приложение живёт без адресной строки, поэтому
      ссылку на себя оно отдаёт только этой кнопкой ── */
.chip-share{flex:none;width:36px;height:36px;border-radius:50%;
  background:var(--paper);color:var(--ink-soft);
  display:flex;align-items:center;justify-content:center}
.chip-share:active{transform:scale(.94)}
.chip-share svg{width:18px;height:18px}
.chip-share .ok{display:none;color:var(--accent);font-weight:900}
.chip-share[data-copied] svg{display:none}
.chip-share[data-copied] .ok{display:inline}

/* ── амагазинқәа: App Store / Google Play в шапке, только в обычной вкладке браузера
      (см. app.js). Круглые, как соседние чипы, и только значок — Нарт, 3 Sep: без подписи ── */
.chip-store{flex:none;width:36px;height:36px;border-radius:50%;background:var(--paper);color:var(--ink-soft);
  display:inline-flex;align-items:center;justify-content:center;text-decoration:none}
.chip-store:active{transform:scale(.94)}
.chip-store svg{width:18px;height:18px;flex:none}

/* ── шестерёнка и ряд чипов (Нарт, 8 сен 2026): чипы шапки раскрываются в самой
      шапке, слева от неё. Раскрытый ряд берёт auto-margin на себя, шестерёнка — нет,
      иначе два auto-поля делят пустоту пополам. Тесно — прячется имя (класс squeeze). ── */
.chip-gear{margin-left:auto;flex:none;width:36px;height:36px;border-radius:50%;
  background:var(--paper);color:var(--ink-soft);
  display:flex;align-items:center;justify-content:center}
.chip-gear:active{transform:scale(.94)}
.chip-gear svg{width:20px;height:20px;fill:currentColor}
.chip-gear[aria-expanded="true"]{background:var(--accent-tint);color:var(--accent)}
.setrow{display:flex;align-items:center;gap:.4rem;margin-left:auto;flex:none;animation:row-in .14s ease}
.setrow:not([hidden]) + .chip-gear{margin-left:0}
.appbar.squeeze b{display:none}
@keyframes row-in{from{opacity:0;transform:translateX(6px)}to{opacity:1;transform:none}}

/* ── выбор пары языков ── */
/* Подписей над списками нет (Нарт, 7 сен 2026) — ряд стал на строку ниже. */
.langbar{display:flex;align-items:center;gap:.35rem;padding:.05rem 1.1rem 0;flex:none}
/* Половины делят ряд по содержимому: длинное имя (Къэбэрдеибзэ) берёт место у
   короткого, а не режется многоточием. Ужимаются обе, только если не влезают вдвоём. */
.langbar .col{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;align-items:center}
/* Пункты раскрытого списка — по центру, как и выбранное имя (Нарт, 7 сен 2026).
   Держится там, где список рисует браузер (Chrome, десктоп); системные
   пикеры Android/iOS рисуют свой и на это не смотрят. */
/* Имя языка — кнопка без плашки и рамки (Нарт, 7 сен 2026); ширина по своему тексту.
   Сам <select> скрыт и держит состояние (см. app.js, language picker). */
.langbtn{font:inherit;font-weight:400;color:var(--ink);max-width:100%;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis;padding:.28rem .55rem;border-radius:var(--r-sm)}
.langbtn:active{opacity:.7}
/* Оба имени длинные (Azərbaycanca + Къэбэрдеибзэ) и вдвоём не влезают — ряд
   ужимает шрифт на ступень вместо многоточия; ставит app.js по факту переполнения. */
.langbar.tight .langbtn{font-size:.85rem;padding:.3rem .3rem}
/* Без зелёного кольца фокуса на панели языков (Нарт, 7 сен 2026). */
.langbtn:focus-visible,.swap:focus-visible,.reset:focus-visible{outline:none}
/* ── наш список языков ── панель под нажатым именем: цвет карточек, кольцо в цвет
   рамки и мягкая тень, пункты по центру с РАВНЫМИ полями, текущий — заливкой
   акцента. Подложка ловит касание мимо. Не выше экрана: высоту зажимает app.js. */
.langmenu{position:fixed;inset:0;z-index:50}
.langmenu-backdrop{position:absolute;inset:0}
.langmenu-list{position:absolute;top:0;left:0;display:flex;flex-direction:column;gap:2px;
  padding:.35rem;border-radius:var(--r-md);background:var(--paper);color:var(--ink);
  box-shadow:0 0 0 1.5px var(--line),0 12px 32px rgba(0,0,0,.28);
  overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;
  animation:menu-in .14s ease}
.langmenu-list button{font:inherit;font-weight:400;color:var(--ink);white-space:nowrap;
  padding:.42rem 1.1rem;border-radius:var(--r-sm);text-align:center}
.langmenu-list button[aria-selected="true"]{background:var(--accent-tint);color:var(--accent)}
.langmenu-list button:hover,.langmenu-list button:focus-visible{background:var(--card);outline:none}
.langmenu-list button[aria-selected="true"]:hover,.langmenu-list button[aria-selected="true"]:focus-visible{background:var(--accent-tint)}
@keyframes menu-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
/* Без круга под стрелками (Нарт, 8 сен 2026) — голый значок, зона касания та же.
   Стрелка «назад» (сброс полей, 10 сен 2026) — той же формы, у левого края ряда;
   .ghost справа — её пустой двойник, чтобы пара имён не съехала вправо. */
.swap,.reset{
  flex:none;width:44px;height:44px;border-radius:50%;
  display:grid;place-items:center;
  color:var(--accent);
}
.reset{margin-left:-.4rem}
/* Нечего сбрасывать — стрелки нет, но место остаётся: имена не прыгают, когда она
   появляется (visibility и клики, и фокус, и скринридер снимает разом). */
.reset.off{visibility:hidden}
/* Двойник уступает первым: если пара имён с ним не влезает, app.js снимает его
   (.noghost) и лишь потом ужимает шрифт — пара чуть съезжает, но не режется. */
.langbar .ghost{flex:none;width:44px;margin-right:-.4rem}
.langbar.noghost .ghost{display:none}
.reset:active{transform:scale(.94)}
.reset svg{width:22px;height:22px;fill:currentColor}
.swap:active{transform:scale(.94)}
.swap svg{width:22px;height:22px;fill:currentColor}

/* ── лента результата ── */
/* main прокручивает только карточки и уступает место ленте: flex 0 1 — сжимается,
   лента (flex 1 0) растёт в свободное место, но никогда не ужимается меньше
   своего содержимого. Пол в 6rem оставляет хотя бы одну карточку на виду. */
/* main забирает всё свободное место и делит его между карточками поровну, а лента
   и кнопка стоят под ним неподвижно. До 3 сен 2026 было наоборот — росла лента,
   а карточки жили по содержимому и уезжали за край общей прокрутки. Теперь обе
   карточки видны ВСЕГДА, и длинный текст прокручивается внутри своей. */
/* Сверху 3px: кольцо правки/фокуса (2px) выходит за карточку, а main режет всё за
   своим краем — у исходника срезался верх контура (Нарт, 8 сен 2026). */
main{flex:1 1 auto;min-height:6rem;overflow:hidden;padding:3px 1.1rem .15rem;display:flex;flex-direction:column;gap:.9rem}
/* Каждая карточка прокручивается САМА (Нарт, 3 сен 2026: «each their own scroll
   instead of ... single scroll for both»). Поэтому у неё есть верхняя граница
   высоты, и текст внутри — свой блок прокрутки. Ручка внизу задаёт высоту явно,
   и тогда max-height снимается (это делает app.js). main остаётся прокручиваемым
   как внешний запас: две растянутые карточки имеют право не поместиться. */
.stage{border:none;border-radius:var(--r-md);padding:.75rem .95rem 1.15rem;background:var(--paper);
  box-shadow:var(--shadow-card);
  position:relative;flex:1 1 0;display:flex;flex-direction:column;min-height:5.2rem;overflow:hidden}
/* Перевод по умолчанию вдвое выше исходника (Нарт, 8 сен 2026: «extend further the
   target field»); ручки и сохранённые высоты это переигрывают (см. app.js). */
.stage.tgt{background:var(--accent-tint);flex-grow:2}
/* Строки подписи нет (Нарт, 7 сен 2026): кнопка прослушивания стоит в правом верхнем
   углу, а первая строка текста обтекает её — float у ::before держит для неё место,
   поэтому многоточие пустой карточки переехало в ::after. */
.stage .tools{position:absolute;top:.5rem;right:.55rem;z-index:1;display:flex;gap:.3rem}
.stage .text::before{content:"";float:right;width:4.4rem;height:1.6rem}   /* две кнопки */
/* Справа налево (арабский): кнопки уходят в левый угол, текст начинается справа
   (Нарт, 8 сен 2026). dir карточке ставит applyDirs. */
.stage[dir="rtl"] .tools{right:auto;left:.55rem}
.stage .text[dir="rtl"]::before{float:left}
/* min-height:0 — иначе сжатая до предела карточка не даёт тексту ужаться, и он
   вылезает за её край поверх соседней (поймано на 360×640, 3 сен 2026). Пустая
   карточка всё равно занимает строку: её высоту задаёт «…» в :empty::before. */
.stage .text{flex:1 1 auto;min-height:0;font-size:1.15rem;overflow-wrap:anywhere;white-space:pre-wrap;
  overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
.stage .text:empty::after{content:"…";color:var(--ink-soft)}
/* ── правка карточек ── обе правятся на месте (отзыв 3 Sep 2026: одно слово
   распозналось не так, а исправить букву было нельзя — только стереть всё и
   диктовать заново). Рамка — на карточке, а не на абзаце: контур :focus-visible
   вокруг текста внутри карточки читался бы как второй, вложенный блок.
   Подпись карточки с ожидающей правкой — акцентом, в тон большой кнопке. */
.stage .text[contenteditable]{outline:none;caret-color:var(--accent);cursor:text}
/* Кольцо — ТОЛЬКО по фокусу (Нарт, 10 сен 2026): ожидающая правка его больше не
   держит — после набора и тапа мимо кольцо оставалось, и читалось это как «фокус
   не уходит». Что правка ждёт, говорят большая кнопка (значок стрелок) и строка
   над рядом; класс .dirty остаётся у карточки на будущее, но не рисует ничего. */
/* Кольцо ПЕРВЫМ: тени рисуются в порядке списка, первая — сверху, и жёсткая тень
   карточки ложилась на низ кольца — в тёмной теме она чёрная, и низ тускнел
   (Нарт, 8 сен 2026). */
/* Кольцо — по фокусу ТЕКСТА, не :focus-within (Нарт, 9 сен 2026): значки стоят
   внутри карточки, и с :focus-within нажатие на динамик зажигало кольцо правки,
   хотя правку никто не начинал. Значки фокус не берут вовсе (см. app.js). */
.stage:has(.text:focus){box-shadow:0 0 0 2px var(--accent),var(--shadow-card)}
/* Без кольца и плашки (Нарт, 8 сен 2026) — голый значок в углу карточки. */
.iconbtn{
  width:32px;height:32px;border-radius:50%;display:grid;place-items:center;
  color:var(--ink-soft);
}
.iconbtn:active{transform:translateY(2px)}
.iconbtn svg{width:17px;height:17px;fill:currentColor}
.iconbtn.busy{color:var(--accent);animation:iconpulse .8s ease-in-out infinite}
/* «Копировать»: на 1,6 с значок сменяется галочкой, как у «поделиться» в шапке. */
.iconbtn .ok{display:none;color:var(--accent);font-weight:900;font-size:1.05rem;line-height:1}
.iconbtn[data-copied] svg{display:none}
.iconbtn[data-copied] .ok{display:inline}
@keyframes iconpulse{0%,100%{transform:scale(1)}50%{transform:scale(1.18)}}
.stage .subnote{font-size:.8rem;color:var(--ink-soft);margin-top:.3rem}
/* ── ручка размера карточки ── палец, не курсор: 44px по ширине и своя зона
   касания по высоте, touch-action:none, иначе перетаскивание уедет в прокрутку. */
.stage .grip{position:absolute;left:50%;transform:translateX(-50%);bottom:.05rem;
  width:56px;height:16px;display:grid;place-items:center;cursor:ns-resize;
  touch-action:none;-webkit-tap-highlight-color:transparent}
.stage .grip::before{content:"";width:32px;height:3px;border-radius:2px;background:var(--line);
  transition:background .15s,width .15s}
.stage.resizing .grip::before,.stage .grip:active::before{background:var(--accent);width:40px}

/* ── ряд кнопки = конвейер: микрофон · орнамент · кнопка · орнамент · динамик ──
   (Нарт, 7 сен 2026). Лента этапов со стрелками ушла — стрелки были третьим лицом
   самой кнопки, а строка ленты нужна карточкам. Этапы теперь читаются с трёх мест
   ряда: индекс 0 — микрофон, 1 — большая кнопка, 2 — динамик; связки между ними —
   контур орнамента, и они же несут «докуда дошёл прогон». */
.micdock{flex:none;position:relative;display:flex;flex-direction:column;align-items:center;
  gap:.3rem;padding:.55rem 1.1rem .9rem}   /* сверху — воздух между карточкой и кнопкой */
/* Строка статуса: только ошибки, и ПОВЕРХ карточки (Нарт, 8 сен 2026): плашка над
   рядом кнопки, накрывает низ перевода и через несколько секунд гаснет сама — места
   не занимает, карточки не двигает. Отсчёт после отказа — та же плашка, акцентом. */
.stagelabel{position:absolute;left:1.1rem;right:1.1rem;bottom:100%;z-index:2;
  width:max-content;max-width:34ch;margin:0 auto -.15rem;   /* по центру без transform: его бы перебила анимация */
  padding:.5rem .9rem;border-radius:var(--r-md);background:var(--card);
  box-shadow:0 0 0 1.5px var(--line),0 8px 22px rgba(0,0,0,.18);
  font-size:.98rem;line-height:1.35;font-weight:700;color:var(--ink);text-align:center;
  pointer-events:none;animation:toast-in .16s ease}
.stagelabel.bye{opacity:0;transition:opacity .5s}
@keyframes toast-in{from{opacity:0}to{opacity:1}}
.stagebox[data-mode="idle"] .stagelabel{font-weight:400;color:var(--ink-soft)}
.stagebox[data-mode="error"] .stagelabel{color:var(--hand);box-shadow:0 0 0 1.5px var(--hand),0 8px 22px rgba(0,0,0,.18)}
.stagebox[data-mode="pending"] .stagelabel{color:var(--accent)}

/* Края стоят вплотную к орнаменту и кнопке (Нарт, 7 сен 2026). */
.pipe{display:flex;align-items:center;justify-content:center;gap:.2rem;width:100%}
/* Связка: контур «бараньего рога» вокруг ромба (symbol#horn в index.html). Зелёный,
   пока связь живая — включены оба её конца (Нарт, 3 сен 2026; 7 сен: «green when the
   path is active»); к выключенному краю — цвета рамки. Прогон рисуется поверх: пока
   идёт — бегущий пунктир, дошёл — ромб залит. */
.conn{flex:none;width:58px;height:28px;color:var(--accent);transition:color .25s}
.conn path{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;
  vector-effect:non-scaling-stroke;transition:fill .25s}
.conn.off{color:var(--line)}
.conn.done .gem{fill:currentColor}
.stagebox[data-mode="run"] .conn.cur .horn{stroke-dasharray:3 5;animation:march .9s linear infinite}
@keyframes march{to{stroke-dashoffset:-16}}

/* Края ряда — выключаемые этапы (микрофон, динамик): кольцо, как у большой кнопки
   по смыслу, но контурное. Выключенный — перечёркнутый значок и пунктирный контур,
   слов нет намеренно (Нарт, 3 сен 2026). */
.tog{width:46px;height:46px;border-radius:50%;flex:none;position:relative;
  display:grid;place-items:center;padding:0;font:inherit;cursor:pointer;
  background:var(--card);border:2px solid var(--accent);color:var(--accent);
  transition:background .25s,color .25s,border-color .25s,transform .25s,box-shadow .25s;
  -webkit-tap-highlight-color:transparent}
.tog svg{width:22px;height:22px;fill:currentColor}
.tog:active{transform:scale(.94)}
.tog .g-off{display:none}
.tog[aria-pressed="false"]{border-style:dashed;border-color:var(--line);color:var(--ink-soft);opacity:.6}
.tog[aria-pressed="false"] .g-on{display:none}
.tog[aria-pressed="false"] .g-off{display:block}
.tog.done{background:var(--accent-tint)}
.tog.cur{border-width:3px;transform:scale(1.1)}
.stagebox[data-mode="run"] .tog.cur{animation:stagepulse 1s ease-in-out infinite}
.stagebox[data-mode="wait"] .tog.cur{animation:stagepulse 2s ease-in-out infinite}
.stagebox[data-mode="error"] .tog.cur{border-color:var(--hand);color:var(--hand);animation:none;transform:none}
/* правка ждёт: край поднят заливкой, без пульса — ничего ещё не идёт */
.stagebox[data-mode="pending"] .tog.cur{background:var(--accent-tint);transform:none}
@keyframes stagepulse{
  0%,100%{transform:scale(1.1);box-shadow:0 0 0 0 var(--accent-tint)}
  50%    {transform:scale(1.0);box-shadow:0 0 0 7px var(--accent-tint)}
}

/* ── большая кнопка — середина ряда и этап 1 (перевод) ── */
/* Глянец вместо объёма (Нарт, 7 сен 2026): блик сверху, градиент к тёмному низу,
   мягкая тень под кнопкой; нажатие — лёгкое сжатие. */
.micbtn{
  width:84px;height:84px;border-radius:50%;position:relative;flex:none;
  background:
    radial-gradient(ellipse 62% 42% at 50% 22%, rgba(255,255,255,.55), rgba(255,255,255,0) 100%),
    linear-gradient(180deg, var(--accent) 0%, var(--accent-deep) 100%);
  color:var(--accent-ink);
  display:grid;place-items:center;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45), inset 0 -3px 6px rgba(0,0,0,.18),
             0 5px 14px rgba(0,0,0,.22);
  transition:transform .06s;
}
.micbtn:active{transform:scale(.95)}
.micbtn svg{width:38px;height:38px;fill:currentColor}
.micbtn[disabled]{opacity:.55;cursor:default}
.micbtn .stopsq{display:none;width:26px;height:26px;border-radius:6px;background:var(--accent-ink)}
/* Глиф следует ожидающей правке: правленое распознанное ждёт перевода — стрелки,
   правленый перевод ждёт озвучки — динамик; иначе микрофон. */
.micbtn .g-tr,.micbtn .g-sp{display:none}
.micbtn[data-state="translate"] .g-mic,.micbtn[data-state="speak"] .g-mic{display:none}
.micbtn[data-state="translate"] .g-tr,.micbtn[data-state="speak"] .g-sp{display:block}
.micbtn[data-state="rec"] svg{display:none}
.micbtn[data-state="rec"] .stopsq{display:block}
/* Ни расходящегося кольца при записи, ни «дыхания» при переводе (Нарт, 8 сен 2026:
   «remove the glow around the button») — запись видна по квадрату «стоп», ход
   прогона — по краям ряда. Ошибка на шаге перевода — красное кольцо, оно осталось. */
.stagebox[data-mode="error"] .micbtn.cur{
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45),inset 0 -3px 6px rgba(0,0,0,.18),0 5px 14px rgba(0,0,0,.22),0 0 0 3px var(--card),0 0 0 6px var(--hand)}

/* ── подвал ── */
.foot{flex:none;padding:.4rem 1.1rem calc(.7rem + env(safe-area-inset-bottom));
  font-size:.64rem;line-height:1.3;color:var(--ink-soft);text-align:center;
  border-top:1.5px solid var(--line)}

/* ── iOS install sheet (modal, как в Аԥхьарца) ── */
#modal{position:fixed;inset:0;z-index:70;display:none;align-items:flex-end;justify-content:center;background:rgba(10,16,24,.5)}
@keyframes sheet-up{from{transform:translateY(100%)}to{transform:translateY(0)}}

/* ── app-update toast (как в Аԥхьарца/Аӡыркәи) ── */
#upd-toast{
  position:fixed;left:50%;bottom:calc(14px + env(safe-area-inset-bottom));transform:translateX(-50%);
  z-index:60;display:flex;align-items:center;gap:.7rem;background:var(--accent-deep);color:#fff;
  font-weight:800;font-size:.85rem;border-radius:var(--r-pill);padding:.65rem 1.15rem;white-space:nowrap;
  box-shadow:0 8px 22px rgba(0,0,0,.28);animation:updrise .25s ease;transition:opacity .5s;
}
#upd-toast.bye{opacity:0}
/* готово: две строки — плашка перестаёт быть таблеткой и переносит текст */
#upd-toast.done{white-space:normal;width:max-content;text-align:center;border-radius:1rem;
  max-width:min(20rem,86vw);padding:.7rem 1.15rem}
#upd-toast em{display:block;font-style:normal;font-weight:600;font-size:.8rem;
  opacity:.82;margin-top:.15rem}
@keyframes updrise{from{transform:translate(-50%,10px);opacity:0}to{transform:translate(-50%,0);opacity:1}}
.upd-spin{width:15px;height:15px;border-radius:50%;flex:none;border:2.5px solid rgba(255,255,255,.35);border-top-color:#fff;animation:upd-spin .7s linear infinite}
@keyframes upd-spin{to{transform:rotate(360deg)}}
