/* Оскар: вид главного экрана (шаг D1, 27.09.2026). Задание на вид: /DESIGN.md.
   Идея: одна живая сфера в центре (как значок: тёмный шар с неоновым кольцом), крупные субтитры, внизу кнопки как
   в звонилке. Тёмная тема на фирменном #061439, светлая на #F3F5FB. Движения на пружинах Material 3 Expressive,
   анимируются только transform и opacity. Цвета: переменные ниже; «Авто / Светлая / Тёмная»: theme.js (data-theme). */

/* значки (маски из SVG, цвет берут из currentColor) */
:root {
  --i-mic: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Crect x=%229%22 y=%223%22 width=%226%22 height=%2212%22 rx=%223%22/%3E%3Cpath d=%22M19 11a7 7 0 0 1-14 0%22/%3E%3Cpath d=%22M12 18v3%22/%3E%3C/svg%3E");
  --i-micoff: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M15 10.5V6a3 3 0 0 0-5.8-1%22/%3E%3Cpath d=%22M9 9v3a3 3 0 0 0 4.9 2.3%22/%3E%3Cpath d=%22M19 11a7 7 0 0 1-1.1 3.8%22/%3E%3Cpath d=%22M16.5 16.8A7 7 0 0 1 5 11%22/%3E%3Cpath d=%22M12 18v3%22/%3E%3Cpath d=%22M3.5 3.5l17 17%22/%3E%3C/svg%3E");
  --i-end: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22black%22%3E%3Cpath d=%22M2.6 13.6c5.2-4.8 13.6-4.8 18.8 0 .7.6.7 1.6.1 2.3l-1.6 1.7c-.5.6-1.4.7-2.1.3l-2.3-1.4c-.5-.3-.8-.9-.7-1.5l.2-1.4a11.8 11.8 0 0 0-6 0l.2 1.4c.1.6-.2 1.2-.7 1.5l-2.3 1.4c-.7.4-1.6.3-2.1-.3l-1.6-1.7c-.6-.7-.6-1.7.1-2.3z%22/%3E%3C/svg%3E");
  --i-close: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M6 6l12 12M18 6 6 18%22/%3E%3C/svg%3E");
  --i-eye: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7S2 12 2 12z%22/%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%223%22/%3E%3C/svg%3E");
  --i-camera: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M3 8.5A2 2 0 0 1 5 6.5h2.4L9 4.5h6l1.6 2H19a2 2 0 0 1 2 2V18a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z%22/%3E%3Ccircle cx=%2212%22 cy=%2213%22 r=%223.6%22/%3E%3C/svg%3E");
  --i-camoff: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M3.5 3.5l17 17%22/%3E%3Cpath d=%22M9 4.5h6l1.6 2H19a2 2 0 0 1 2 2v8.3%22/%3E%3Cpath d=%22M18 20H5a2 2 0 0 1-2-2V8.5a2 2 0 0 1 2-2h.5%22/%3E%3Cpath d=%22M9.6 10.7a3.6 3.6 0 0 0 4.9 5%22/%3E%3C/svg%3E");
  --i-read: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M4 8V5.5A1.5 1.5 0 0 1 5.5 4H8M16 4h2.5A1.5 1.5 0 0 1 20 5.5V8M20 16v2.5a1.5 1.5 0 0 1-1.5 1.5H16M8 20H5.5A1.5 1.5 0 0 1 4 18.5V16%22/%3E%3Cpath d=%22M8 9.5h8M8 12.5h8M8 15.5h5%22/%3E%3C/svg%3E");
  --i-speaker: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M11 5 6.5 9H3v6h3.5L11 19z%22/%3E%3Cpath d=%22M15.5 8.8a4.5 4.5 0 0 1 0 6.4%22/%3E%3Cpath d=%22M18.4 5.9a8.6 8.6 0 0 1 0 12.2%22/%3E%3C/svg%3E");
  --i-earpiece: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M8.6 3.8 6 4.1c-1.2.2-2 1.2-2 2.4.2 7.3 6.2 13.3 13.5 13.5 1.2 0 2.2-.8 2.4-2l.3-2.6a1.2 1.2 0 0 0-.8-1.3l-3.2-1.1a1.2 1.2 0 0 0-1.3.3l-1.4 1.5a10.3 10.3 0 0 1-5.1-5.1L9.9 8.3c.4-.3.5-.8.3-1.3L9.1 3.8a1.2 1.2 0 0 0-.5-.1z%22/%3E%3C/svg%3E");
  --i-headphones: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M4 17v-5a8 8 0 0 1 16 0v5%22/%3E%3Cpath d=%22M20 18a2 2 0 0 1-2 2h-1.5v-6H20zM4 18a2 2 0 0 0 2 2h1.5v-6H4z%22/%3E%3C/svg%3E");
  --i-sound: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M11 5 6.5 9H3v6h3.5L11 19z%22/%3E%3Cpath d=%22M16 9l5 6M21 9l-5 6%22/%3E%3C/svg%3E");
  --i-install: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M12 4v11%22/%3E%3Cpath d=%22M7.5 10.5 12 15l4.5-4.5%22/%3E%3Cpath d=%22M5 19.5h14%22/%3E%3C/svg%3E");
  --i-chev: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M6 9l6 6 6-6%22/%3E%3C/svg%3E");
  --i-wave: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M4 10v4M8 7v10M12 4v16M16 7v10M20 10v4%22/%3E%3C/svg%3E");
}

:root {
  --bg: #F3F5FB;
  --bg-2: #E7ECFA;
  --spot: #D9E3FF;
  --panel: #FFFFFF;
  --surface: rgba(255, 255, 255, .78);
  --surface-2: #EEF2FC;
  --surface-hi: #FFFFFF;
  --text: #0B1433;
  --muted: #4A5578;
  --line: rgba(11, 20, 51, .10);
  --line-2: rgba(11, 20, 51, .16);
  --accent: #2F55E0;
  --accent-2: #5B7BFF;
  --accent-ink: #FFFFFF;
  --grad-a: #3360F0;
  --grad-b: #6E50F2;
  --red-a: #D63447;
  --red-b: #C92A3F;
  --live: #E0344A;
  --live-2: #FF5A6E;
  --me: #E3EAFF;
  --ai: #FFFFFF;
  --agent: #FFF1D6;
  --warn: #8A5200;
  --err: #B42335;
  --me-label: #4A5578;
  --ok: #157A4B;
  --shadow: 0 1px 2px rgba(11, 20, 51, .06), 0 8px 24px rgba(11, 20, 51, .10);
  --shadow-lg: 0 2px 6px rgba(11, 20, 51, .08), 0 18px 48px rgba(11, 20, 51, .16);
  --glow-listen: #1FB6FF;
  --glow-think: #7B5CFF;
  --glow-speak: #FF4FB8;
  --glow-spare: #FF9F1C;
  --edge: rgba(123, 92, 255, .30);
  --aura-a: rgba(91, 123, 255, .22);
  --aura-b: rgba(255, 79, 184, .10);
  --focus: #2F55E0;
  color-scheme: light;

  --font: "Google Sans Flex", "Google Sans Text", "Google Sans", "Roboto Flex", Roboto, system-ui, -apple-system, "Segoe UI", sans-serif;
  /* пружины Material 3 Expressive (жёсткость и затухание: 800/0.6, 380/0.8), эффекты без отскока (1600/1.0) */
  --spring-fast: linear(0, 0.119, 0.335, 0.568, 0.772, 0.925, 1.023, 1.074, 1.09, 1.083, 1.066, 1.044, 1.025, 1.01, 1, 0.994, 0.992, 0.992, 0.994, 0.995, 0.997, 0.999, 1);
  --spring: linear(0, 0.077, 0.223, 0.388, 0.544, 0.679, 0.786, 0.867, 0.925, 0.964, 0.988, 1.003, 1.01, 1.013, 1.013, 1.011, 1.009, 1.007, 1.005, 1.004, 1.002, 1.001, 1);
  --effect: linear(0, 0.116, 0.285, 0.451, 0.591, 0.702, 0.786, 0.848, 0.892, 0.924, 0.947, 0.963, 0.976, 0.983, 0.988, 0.992, 0.996, 1);
  --t-fast: 400ms;
  --t-mid: 480ms;
  --t-fx: 280ms;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #061439; --bg-2: #030A1F; --spot: #0F2A78; --panel: #0C1C4C;
    --surface: rgba(20, 38, 96, .62); --surface-2: rgba(255, 255, 255, .06); --surface-hi: #13286A;
    --text: #EEF2FF; --muted: #A9B4D6; --line: rgba(255, 255, 255, .10); --line-2: rgba(255, 255, 255, .18);
    --accent: #7C9CFF; --accent-2: #9DB4FF; --accent-ink: #061439; --grad-a: #3360F0; --grad-b: #6E50F2;
    --live: #F0445A; --live-2: #FF6B7D; --me: #1A2F73; --ai: #0C1C4C; --agent: #3A2D12; --warn: #FFC56B; --err: #FF8A8A;
    --me-label: #A9B4D6; --ok: #4ADE9B;
    --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 10px 30px rgba(0, 0, 0, .35);
    --shadow-lg: 0 2px 8px rgba(0, 0, 0, .35), 0 24px 60px rgba(0, 0, 0, .5);
    --glow-listen: #35D6FF; --glow-think: #9B7BFF; --glow-speak: #FF4FB8; --glow-spare: #FFB547;
    --edge: rgba(155, 123, 255, .42); --aura-a: rgba(63, 123, 255, .34); --aura-b: rgba(255, 79, 184, .12);
    --focus: #9DB4FF;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #061439; --bg-2: #030A1F; --spot: #0F2A78; --panel: #0C1C4C;
  --surface: rgba(20, 38, 96, .62); --surface-2: rgba(255, 255, 255, .06); --surface-hi: #13286A;
  --text: #EEF2FF; --muted: #A9B4D6; --line: rgba(255, 255, 255, .10); --line-2: rgba(255, 255, 255, .18);
  --accent: #7C9CFF; --accent-2: #9DB4FF; --accent-ink: #061439; --grad-a: #3360F0; --grad-b: #6E50F2;
  --live: #F0445A; --live-2: #FF6B7D; --me: #1A2F73; --ai: #0C1C4C; --agent: #3A2D12; --warn: #FFC56B; --err: #FF8A8A;
  --me-label: #A9B4D6; --ok: #4ADE9B;
  --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 10px 30px rgba(0, 0, 0, .35);
  --shadow-lg: 0 2px 8px rgba(0, 0, 0, .35), 0 24px 60px rgba(0, 0, 0, .5);
  --glow-listen: #35D6FF; --glow-think: #9B7BFF; --glow-speak: #FF4FB8; --glow-spare: #FFB547;
  --edge: rgba(155, 123, 255, .42); --aura-a: rgba(63, 123, 255, .34); --aura-b: rgba(255, 79, 184, .12);
  --focus: #9DB4FF;
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { background: var(--bg); }
body {
  background: radial-gradient(130% 75% at 50% 36%, var(--spot) 0%, var(--bg) 52%, var(--bg-2) 100%) fixed, var(--bg);
  color: var(--text);
  font: 16px/1.45 var(--font);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  min-height: 100vh;
  min-height: 100dvh;
  overflow: hidden;
}
[hidden] { display: none !important; }
button, select, input { font: inherit; color: inherit; }
button { -webkit-user-select: none; user-select: none; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }

/* ── фон: мягкое пятно за сферой и свечение снизу (как у Gemini Live), двигает orb.js ── */
.aura { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.aura-a, .aura-b, .edge { position: absolute; display: block; will-change: transform, opacity; }
.aura-a {
  left: 50%; top: 40%; width: 150vmin; height: 150vmin; margin: -75vmin 0 0 -75vmin; border-radius: 50%;
  background: radial-gradient(closest-side, var(--aura-a), transparent 72%);
  opacity: .8; transition: opacity var(--t-mid) var(--effect);
}
.aura-b {
  left: 50%; top: 44%; width: 110vmin; height: 110vmin; margin: -55vmin 0 0 -55vmin; border-radius: 50%;
  background: radial-gradient(closest-side, var(--aura-b), transparent 70%);
  opacity: 0; transition: opacity var(--t-mid) var(--effect);
}
.edge {
  left: -10%; right: -10%; bottom: 0; height: 42vh;
  background: radial-gradient(60% 100% at 50% 100%, var(--edge), transparent 75%);
  opacity: 0; transition: opacity var(--t-mid) var(--effect);
}
body.o-thinking .edge, body.o-connecting .edge { opacity: .55; }
body.o-speaking .aura-b { opacity: 1; }
/* пока говорит, свечение ведёт orb.js каждый кадр: без перехода (иначе переход перезапускался бы каждый кадр) */
body.o-speaking .edge { transition: none; }
body.tr .edge, body.tr .aura-b { opacity: 0; }

.wrap {
  position: relative; z-index: 1;
  max-width: 560px;
  margin: 0 auto;
  padding: max(8px, env(safe-area-inset-top)) 16px max(12px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
}

/* ── переключатель «Помощник / Переводчик»: таблетка с бегущей подложкой ── */
.top { order: 1; display: flex; flex-direction: column; gap: 8px; align-items: center; margin-top: 4px; }
.seg {
  position: relative; display: grid; grid-template-columns: 1fr 1fr; width: min(100%, 320px);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 999px; padding: 4px;
}
.seg-ind {
  position: absolute; top: 4px; bottom: 4px; left: 4px; width: calc(50% - 4px); border-radius: 999px;
  background: linear-gradient(135deg, var(--grad-a), var(--grad-b));
  box-shadow: 0 4px 14px rgba(63, 111, 255, .35);
  transition: transform var(--t-fast) var(--spring-fast);
}
body.tr .seg-ind { transform: translateX(100%); }
.segb {
  position: relative; z-index: 1; border: 0; background: transparent; border-radius: 999px; padding: 8px 4px;
  font-size: 15px; font-weight: 650; letter-spacing: .1px; color: var(--muted); cursor: pointer; min-height: 44px;
  transition: color var(--t-fx) var(--effect);
}
.segb.on { color: #FFFFFF; }
.segb[aria-disabled="true"] { cursor: default; }
.segb[aria-disabled="true"]:not(.on) { opacity: .55; }
.langrow {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%;
  background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 8px 12px; color: var(--muted);
}
.langrow span { white-space: nowrap; }
.langrow select { background: transparent; border: 0; font-weight: 600; color: var(--text); padding: 8px 4px; min-height: 44px; }

/* ── приглашение (вход по ссылке) ── */
.invite { order: 2; text-align: center; margin: auto 0; padding: 24px 8px; }
.invite h1 { margin: 22px 0 8px; font-size: 32px; font-weight: 700; letter-spacing: -.3px; }
.invite p { margin: 8px auto; max-width: 30ch; text-wrap: balance; }
.invite .err { margin: 0 auto 14px; }
.invite-orb { position: relative; width: 132px; height: 132px; margin: 0 auto; }
.invite-orb .orb-ring, .invite-orb .orb-core { position: absolute; border-radius: 50%; }
.muted { color: var(--muted); font-size: 14px; }

/* ── главный экран: сцена раскладывается прямо в колонку страницы ── */
.stage { display: contents; }
.hud { order: 3; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; align-items: center; padding-top: 10px; }
.hudtxt { display: flex; flex-direction: column; align-items: center; gap: 6px; min-height: 58px; text-align: center; }
.status {
  margin: 0; font-size: 22px; font-weight: 650; letter-spacing: -.2px; line-height: 1.25; min-height: 1.25em;
  text-wrap: balance; transition: color var(--t-fx) var(--effect);
}
.chips { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.chips:empty { display: none; }
.englbl, .badge {
  margin: 0; padding: 3px 10px; border-radius: 999px; font-size: 12.5px; font-weight: 700; letter-spacing: .2px; line-height: 1.5;
  background: var(--surface-2); color: var(--muted); border: 1px solid var(--line);
}
.englbl.fast { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.englbl.spare { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.badge.test { color: var(--err); border-color: color-mix(in srgb, var(--err) 40%, transparent); font-weight: 650; max-width: 100%; }
.badge.eng { color: var(--warn); }
.badge.wait { background: transparent; border: 0; padding: 0; font-weight: 600; color: var(--muted); font-size: 14px; }

/* ── сфера Оскара ── */
.orbbox {
  flex: 1 1 auto; min-height: 120px; width: 100%; display: grid; place-items: center;
  container-type: size; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.orb {
  --os: min(70cqw, 86cqh, 320px);
  position: relative; width: var(--os); height: var(--os); border-radius: 50%;
  will-change: transform; transform: translateZ(0);
}
.orb > span, .orb > canvas, .orb-spin > span { position: absolute; display: block; border-radius: 50%; pointer-events: none; }
.orb-glow {
  inset: -34%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--glow, var(--grad-a)) 55%, transparent) 0%,
    color-mix(in srgb, var(--glow, var(--grad-a)) 18%, transparent) 55%, transparent 100%);
  opacity: .55; will-change: transform, opacity;
  transition: background var(--t-mid) var(--effect);
}
.orb-spin { inset: 0; animation: orbspin 18s linear infinite; }
.orb-ring {
  inset: 0;
  background: conic-gradient(from 200deg, #35D6FF, #3F7BFF, #7A5CFF, #FF4FB8, #FFB23F, #FFE45C, #35D6FF);
  -webkit-mask: radial-gradient(closest-side, transparent 86%, #000 88.5%, #000 97%, transparent 100%);
  mask: radial-gradient(closest-side, transparent 86%, #000 88.5%, #000 97%, transparent 100%);
  opacity: .9; transition: opacity var(--t-mid) var(--effect);
  will-change: transform;
}
.orb-ring.warm {
  background: conic-gradient(from 20deg, #FF4FB8, #FF7A59, #FFB23F, #FFE45C, #FF4FB8, #B45CFF, #FF4FB8);
  opacity: 0;
}
.orb-arc {
  inset: -2px;
  background: conic-gradient(from 0deg, transparent 0deg, transparent 250deg, rgba(255, 255, 255, .0) 262deg, #FFFFFF 350deg, transparent 360deg);
  -webkit-mask: radial-gradient(closest-side, transparent 84%, #000 88%, #000 98%, transparent 100%);
  mask: radial-gradient(closest-side, transparent 84%, #000 88%, #000 98%, transparent 100%);
  opacity: 0; transition: opacity var(--t-fx) var(--effect); will-change: transform, opacity;
}
.orb-core {
  inset: 7.5%;
  background:
    radial-gradient(circle at 34% 26%, rgba(120, 170, 255, .38) 0%, rgba(120, 170, 255, 0) 38%),
    radial-gradient(circle at 50% 62%, #0B2263 0%, #071848 48%, #050F33 78%, #030A22 100%);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06), inset 0 -10px 30px rgba(53, 214, 255, .10), 0 18px 40px rgba(3, 10, 34, .45);
}
.orb-wave { left: 20%; top: 30%; width: 60%; height: 40%; border-radius: 0; }
.orb-shine {
  left: 22%; top: 12%; width: 38%; height: 22%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, .22), rgba(255, 255, 255, 0));
  transform: rotate(-20deg);
}
@keyframes orbspin { to { transform: rotate(360deg); } }

/* состояния (класс на body ставит orb.js по кнопке «Говорить» и разговору) */
body.o-idle .orb-ring { opacity: .78; }
body.o-listening { --glow: var(--glow-listen); }
body.o-thinking { --glow: var(--glow-think); }
body.o-connecting { --glow: var(--grad-a); }
body.o-speaking { --glow: var(--glow-speak); }
body.o-speaking .orb-ring.warm { opacity: 1; }
body.o-speaking .orb-ring:not(.warm) { opacity: .25; }
body.o-thinking .orb-arc, body.o-connecting .orb-arc { opacity: .95; }
body.o-thinking .orb-ring:not(.warm) { opacity: .55; }
body.o-muted .orb { filter: saturate(.15) brightness(.85); }
body.o-muted .orb-glow { opacity: .2 !important; }
body.eng-spare { --glow-listen: var(--glow-spare); --glow-speak: var(--glow-spare); }
body.eng-spare .orb-ring:not(.warm) { background: conic-gradient(from 200deg, #FFB547, #FF8A3D, #FFD36B, #FF7A59, #FFC56B, #FFB547); }
body.eng-spare.o-speaking .orb-ring:not(.warm) { opacity: 1; }
body.eng-spare.o-speaking .orb-ring.warm { opacity: 0; }
.chips:has(#engineBadge:not([hidden])) #engLabel { display: none; }
body.o-idle .orb-glow { opacity: .42; }
.orb { transition: filter var(--t-mid) var(--effect); }

/* ── субтитры: две последние реплики крупно; касание открывает весь разговор ── */
.log {
  order: 5; flex: 0 0 auto; position: relative;
  height: clamp(84px, 17dvh, 150px); min-height: 0; margin-top: 4px;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 6px;
  overflow: hidden; cursor: pointer; padding: 0 4px;
  -webkit-mask: linear-gradient(to bottom, transparent 0, #000 28px);
  mask: linear-gradient(to bottom, transparent 0, #000 28px);
}
.log:empty::before {
  content: "Нажмите «Говорить» и спросите что угодно: о делах, почте, дороге, ценах.";
  display: block; text-align: center; color: var(--muted); font-size: 15px; line-height: 1.4; margin: auto auto 8px; max-width: 30ch;
}
/* подсказка только до разговора: во время разговора статус уже говорит «Слушаю» */
body:not(.o-idle) .log:empty::before { visibility: hidden; }
.log > .msg:first-child { margin-top: auto; }
/* реплики не сжимаются под высоту полосы: лишнее уходит вверх под плавное затухание, а не режет строку пополам */
.log > .msg { flex-shrink: 0; }
/* [fix-r3 28.09] две последние реплики без заготовок («Секунду, сейчас сделаю» вытесняла вопрос «Вы: ...») */
.log:not(.open) > .msg.filler { display: none; }
.log:not(.open) > .msg:not(:nth-last-child(-n+2 of .msg:not(.filler))) { display: none; }
.log:not(.open) .msg {
  max-width: 100%; margin: 0; padding: 0; border: 0; background: transparent; border-radius: 0; text-align: center;
  overflow-wrap: break-word; animation: msgin var(--t-mid) var(--spring) both;
}
.log:not(.open) .msg b { display: none; }
.log:not(.open) .msg.me span { font-size: 15px; color: var(--muted); line-height: 1.4; }
.log:not(.open) .msg.me span::before { content: "Вы: "; font-weight: 700; }
.log:not(.open) .msg.ai {
  display: flex; flex-direction: column; justify-content: flex-end; max-height: calc(4 * 1.38em); overflow: hidden;
  font-size: 19px; line-height: 1.38; font-weight: 500; letter-spacing: -.1px;
}
/* длинная реплика не влезла: верхняя видимая строка плавно гаснет (класс clip ставит orb.js) */
.log:not(.open) .msg.ai.clip {
  -webkit-mask: linear-gradient(to bottom, rgba(0, 0, 0, .28) 0, rgba(0, 0, 0, .28) 1.2em, #000 1.45em);
  mask: linear-gradient(to bottom, rgba(0, 0, 0, .28) 0, rgba(0, 0, 0, .28) 1.2em, #000 1.45em);
}
.log:not(.open) .msg.ai span { display: block; }
/* [fix-r3 28.09] 360 точек: под ответом системная строка («Google не ответил...»): ответ в 3 строки, верх гаснет (clip) */
.log:not(.open) > .msg.ai:has(+ .msg.sys) { max-height: calc(3 * 1.38em); }
.log:not(.open) .msg.sys { font-size: 13.5px; color: var(--muted); }
.log:not(.open) .msg.me img { display: inline-block; vertical-align: middle; width: 44px; height: auto; border-radius: 8px; margin: 0 0 0 6px; }
.log:not(.open) .msg .desc { display: none; }
.log:not(.open) .msg.card .cardLink { display: none; }
@keyframes msgin { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* весь разговор листом (open ставит orb.js) */
.log.open {
  position: fixed; z-index: 45; left: 0; right: 0; bottom: 0; top: calc(max(8px, env(safe-area-inset-top)) + 64px);
  height: auto; max-width: 640px; margin: 0 auto; cursor: auto; justify-content: flex-start;
  padding: 64px 16px max(20px, env(safe-area-inset-bottom));
  overflow-y: auto; overscroll-behavior: contain; -webkit-mask: none; mask: none;
  background: var(--bg); border-radius: 28px 28px 0 0; box-shadow: var(--shadow-lg);
  animation: sheetin var(--t-mid) var(--spring) both;
}
.log.open .msg {
  max-width: 88%; padding: 10px 14px; border-radius: 20px; border: 1px solid var(--line);
  overflow-wrap: anywhere; font-size: 16px; line-height: 1.45;
}
.log.open .msg b { display: block; font-size: 12.5px; color: var(--muted); font-weight: 700; margin-bottom: 2px; }
.log.open .msg.me { align-self: flex-end; background: var(--me); border-bottom-right-radius: 8px; }
.log.open .msg.ai { align-self: flex-start; background: var(--panel); border-bottom-left-radius: 8px; }
.log.open .msg.sys { align-self: center; background: transparent; border: 0; color: var(--muted); font-size: 14px; padding: 2px; text-align: center; }
.log.open .msg.card { border-color: color-mix(in srgb, var(--accent) 50%, transparent); }
.logbar {
  position: fixed; z-index: 46; left: 0; right: 0; max-width: 640px; margin: 0 auto;
  top: calc(max(8px, env(safe-area-inset-top)) + 64px);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 18px 12px 8px 20px; border-radius: 28px 28px 0 0; touch-action: none;
  background: linear-gradient(var(--bg) 70%, transparent);
  animation: sheetin var(--t-mid) var(--spring) both;
}
.logbar::before {
  content: ""; position: absolute; top: 7px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 2px;
  background: var(--line-2);
}
.logbar h2 { margin: 0; font-size: 20px; font-weight: 700; }
.logdim { position: fixed; inset: 0; z-index: 44; background: rgba(3, 8, 24, .5); animation: fadein var(--t-fx) var(--effect) both; }
@keyframes sheetin { from { transform: translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
.msg .cardLink {
  display: inline-flex; align-items: center; margin-top: 8px; padding: 8px 16px; min-height: 44px; border-radius: 999px;
  background: var(--accent); color: var(--accent-ink); font-weight: 650; text-decoration: none;
}
.msg.me img { display: block; width: 96px; height: auto; border-radius: 10px; margin-top: 4px; }
.msg .desc { display: block; margin-top: 4px; font-size: 14px; color: var(--muted); }

/* ── ошибки и подсказки ── */
.err {
  order: 6; margin: 6px 0 0; padding: 10px 14px; border-radius: 16px; max-width: 100%;
  background: color-mix(in srgb, var(--err) 12%, var(--panel)); border: 1px solid color-mix(in srgb, var(--err) 40%, transparent);
  color: var(--err); text-align: center; font-size: 15px; line-height: 1.4;
}

/* ── «Посмотри», «Камера», «Прочитай»: стеклянные таблетки со значками ── */
.tools { order: 7; display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; padding-top: 10px; min-height: 10px; }
.pill {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid var(--line); background: var(--surface); color: var(--text); border-radius: 999px;
  padding: 10px 16px 10px 14px; min-height: 46px; cursor: pointer; font-weight: 650; font-size: 15px;
  box-shadow: var(--shadow); touch-action: manipulation;
  transition: transform var(--t-fast) var(--spring-fast), background var(--t-fx) var(--effect), color var(--t-fx) var(--effect);
}
.pill:active { transform: scale(.95); }
.pill:disabled { opacity: .5; cursor: default; }
.tools .pill::before {
  content: ""; width: 20px; height: 20px; flex: 0 0 auto; background: currentColor;
  -webkit-mask: var(--pi) center / contain no-repeat; mask: var(--pi) center / contain no-repeat;
}
#look { --pi: var(--i-eye); }
#camBtn { --pi: var(--i-camera); }
#camBtn[aria-pressed="true"] { --pi: var(--i-camoff); }
#read { --pi: var(--i-read); }
#sound { --pi: var(--i-sound); }
#install { --pi: var(--i-install); }
.pill.cam-pill { color: var(--text); }
.pill.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.pill[aria-pressed="true"] { background: var(--text); color: var(--bg); border-color: var(--text); }
.pill#look:disabled, .pill#read:disabled { opacity: 1; background: linear-gradient(135deg, var(--grad-a), var(--grad-b)); color: #FFFFFF; border-color: transparent; }

/* ── нижний ряд как в звонилке: «Микрофон», «Говорить» / «Завершить», «Динамик» / «Трубка» ── */
.ctrls {
  order: 8; display: grid; grid-template-columns: 1fr auto 1fr; align-items: start; justify-items: center;
  padding: 12px 0 6px; min-height: 120px;
}
.ctl-slot { display: flex; justify-content: center; min-width: 64px; padding-top: 10px; }
.ctl, .ou-route {
  position: relative; width: 60px; height: 60px; min-height: 60px; padding: 0; border-radius: 50%;
  border: 1px solid var(--line); background: var(--surface); color: var(--text); box-shadow: var(--shadow);
  font-size: 0; cursor: pointer; display: grid; place-items: center; touch-action: manipulation;
  transition: transform var(--t-fast) var(--spring-fast), background var(--t-fx) var(--effect), color var(--t-fx) var(--effect);
}
.ctl::before {
  content: ""; width: 26px; height: 26px; background: currentColor;
  -webkit-mask: var(--ci, var(--i-mic)) center / contain no-repeat; mask: var(--ci, var(--i-mic)) center / contain no-repeat;
}
.ctl::after, .ou-route .ou-rcap {
  position: absolute; top: calc(100% + 7px); left: 50%; transform: translateX(-50%); white-space: nowrap;
  font-size: 12.5px; font-weight: 600; color: var(--muted); letter-spacing: .1px;
}
#mute.ctl { font-size: 0; padding: 0; gap: 0; }
#mute::after { content: "Микрофон"; }
#mute.on { background: var(--text); color: var(--bg); border-color: var(--text); --ci: var(--i-micoff); }
#mute.on::after { content: "Выключен"; color: var(--text); }
.ctl:active, .ou-route:active { transform: scale(.92); }
.ctl:disabled { opacity: .45; }

.talk {
  position: relative; border: 0; background: transparent; padding: 0; cursor: pointer; color: var(--text);
  display: flex; flex-direction: column; align-items: center; gap: 9px; min-width: 104px;
  touch-action: manipulation;
}
.talkDisc {
  position: relative; width: 80px; height: 80px; border-radius: 50%; display: grid; place-items: center;
  background: linear-gradient(135deg, var(--grad-a), var(--grad-b)); color: #FFFFFF;
  box-shadow: 0 10px 30px color-mix(in srgb, var(--grad-a) 45%, transparent), inset 0 1px 0 rgba(255, 255, 255, .25);
  transition: transform var(--t-fast) var(--spring-fast), background var(--t-mid) var(--effect), box-shadow var(--t-mid) var(--effect);
}
.talkIco {
  width: 32px; height: 32px; background: currentColor;
  -webkit-mask: var(--ti, var(--i-mic)) center / contain no-repeat; mask: var(--ti, var(--i-mic)) center / contain no-repeat;
}
.talk:active .talkDisc { transform: scale(.92); }
.talk:disabled { cursor: default; }
.talk:disabled .talkDisc { opacity: .55; }
.talkLabel { font-size: 15px; font-weight: 700; letter-spacing: .1px; }
.talk.live .talkDisc, .talk.connecting .talkDisc {
  background: linear-gradient(135deg, var(--live-2), var(--live));
  box-shadow: 0 10px 30px color-mix(in srgb, var(--live) 45%, transparent), inset 0 1px 0 rgba(255, 255, 255, .25);
}
.talk.live { --ti: var(--i-end); }
.talk.connecting { --ti: var(--i-close); }
.ring { position: absolute; inset: -7px; border-radius: 50%; border: 3px solid transparent; pointer-events: none; }
.talk.connecting .ring { border-color: rgba(255, 255, 255, .0); border-top-color: var(--live-2); border-right-color: var(--live-2); animation: orbspin 1s linear infinite; }
.talk.thinking .ring { border-color: transparent; border-top-color: var(--glow-think); animation: orbspin 1.6s linear infinite; }

/* ── камера: картинка крупно, сфера маленькая рядом со статусом ── */
.cam {
  order: 2; position: relative; margin-top: 10px; flex: 1 1 auto; min-height: 190px; max-height: 52dvh;
  border-radius: 28px; overflow: hidden; background: #03081A; border: 1px solid var(--line); box-shadow: var(--shadow-lg);
  animation: sheetin var(--t-mid) var(--spring) both;
}
.cam video { width: 100%; height: 100%; object-fit: cover; display: block; }
.cam video.front { transform: scaleX(-1); }
.camHint {
  position: absolute; inset: 0; margin: 0; padding: 16px; display: grid; place-items: center; text-align: center;
  color: #E8ECF9; font-size: 15px; text-wrap: balance;
}
.cam .camIco {
  position: absolute; top: 10px; width: 44px; height: 44px; min-height: 44px; padding: 0; border: 0; border-radius: 50%;
  display: grid; place-items: center; background: rgba(3, 8, 26, .55); color: #FFFFFF; cursor: pointer;
}
.cam .camIco svg { width: 24px; height: 24px; }
.cam #camFlip { right: 10px; }
.cam #torch { left: 10px; }
.cam #torch[aria-pressed="true"] { background: #FFD25C; color: #1B1400; }
body.mode-cam .hud { flex: 0 0 auto; flex-direction: row-reverse; justify-content: center; gap: 12px; padding-top: 10px; }
body.mode-cam .hudtxt { align-items: flex-start; text-align: left; min-height: 0; gap: 4px; }
body.mode-cam .chips { justify-content: flex-start; }
body.mode-cam .status { font-size: 18px; }
body.mode-cam .orbbox { flex: 0 0 52px; width: 52px; height: 52px; min-height: 0; }
body.mode-cam .orb { --os: 52px; }
body.mode-cam .orb-wave { display: none; }
body.mode-cam .badge.wait { display: none !important; }
body.mode-cam .log { height: clamp(52px, 9dvh, 84px); }
body.mode-cam .log.open { height: auto; }   /* [F 28.09] касание субтитров при камере открывало «Разговор» высотой 84 точки */
body.mode-cam .log:not(.open) .msg.ai { font-size: 16px; max-height: calc(3 * 1.38em); }
body.mode-cam .log:not(.open) > .msg:not(:last-child) { display: none; }
body.mode-cam .log:empty::before { display: none; }
body.mode-cam .ctrls { min-height: 108px; padding-top: 8px; }
body.mode-cam .tools { padding-top: 6px; }
.flash {
  position: fixed; top: calc(max(8px, env(safe-area-inset-top)) + 110px); right: 16px; z-index: 5;
  width: 112px; height: auto; border-radius: 16px; border: 3px solid var(--panel); box-shadow: var(--shadow-lg);
  animation: flash 1.8s var(--effect) forwards; pointer-events: none;
}
@keyframes flash { 0% { opacity: 0; transform: scale(.85); } 12% { opacity: 1; transform: scale(1); } 75% { opacity: 1; } 100% { opacity: 0; } }
.offscreen { position: fixed; left: 0; top: 0; width: 2px; height: 2px; opacity: 0; pointer-events: none; }

/* ── маленькие экраны ── */
@media (max-width: 370px) {
  .wrap { padding-left: 12px; padding-right: 12px; }
  .pill { padding: 9px 12px 9px 10px; font-size: 14.5px; gap: 6px; }
  .status { font-size: 20px; }
  .log:not(.open) .msg.ai { font-size: 18px; }
}
@media (max-height: 640px) {
  .log { height: clamp(64px, 14dvh, 110px); }
  .ctrls { min-height: 108px; padding-top: 8px; }
  .talkDisc { width: 72px; height: 72px; }
  .hudtxt { min-height: 50px; }
}

/* Альбомный экран во вкладке Chrome (приложение держит вертикаль): две колонки */
@media (orientation: landscape) and (max-height: 540px) {
  .wrap { max-width: none; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr) auto auto; gap: 4px 20px; }
  .ou-bar { grid-column: 1 / -1; grid-row: 1; }
  .top, .invite { grid-column: 1 / -1; grid-row: 2; }
  .hud { grid-column: 1; grid-row: 3 / 6; }
  .log { grid-column: 2; grid-row: 3; height: auto; }
  .err { grid-column: 2; grid-row: 4; }
  .tools { grid-column: 2; grid-row: 4; }
  .ctrls { grid-column: 2; grid-row: 5; min-height: 0; }
  body.mode-cam .cam { grid-column: 1; grid-row: 3 / 6; max-height: none; margin: 0; }
  body.mode-cam .hud { grid-column: 2; grid-row: 3; }
  body.tr .trp { grid-column: 1 / -1; grid-row: 3 / 6; }
}

@media (prefers-reduced-motion: reduce) {
  .orb-spin, .ring, .talk.connecting .ring, .talk.thinking .ring { animation: none !important; }
  .flash, .log:not(.open) .msg, .log.open, .logbar, .cam { animation: none !important; }
  .seg-ind, .pill, .ctl, .talkDisc { transition: none !important; }
}

/* ══ D2 (28.09.2026): правки строгого критика. Сравнение с ChatGPT (голос) и Gemini Live, снимки tests/results/d2/.
   1) подписи трёх нижних кнопок на одной линии и одного размера; 2) «думаю» только на сфере, без второго вращения
   на красной кнопке; 3) «Слушаю» видно по кольцу (голубое), не только по свечению; 4) сфера не прыгает в размере
   между состояниями (место под статусом одно и то же); 5) сфера «дышит» в тишине, внутри медленно плывут цветные
   облака (как у ChatGPT), кнопка «Говорить» пару раз мягко зовёт кругом; 6) субтитры: своя реплика одной строкой над
   ответом, верх длинного ответа гаснет плавно, а не серой полосой; 7) точка состояния у статуса; 8) камера без тёмной
   каёмки. Всё двигается только transform и opacity; «уменьшить движение»: без движения. ══ */

/* 1) нижний ряд: круги по центру большой кнопки, подписи на одной линии, один размер шрифта */
.ctl::after, .ou-route .ou-rcap {
  top: calc(100% + 20px); font-size: 13.5px; line-height: 18px; font-weight: 600; letter-spacing: 0;
}
.talk { gap: 9px; }
.talkLabel { font-size: 13.5px; line-height: 18px; font-weight: 650; letter-spacing: 0; }

/* значок микрофона ровно по центру круга (раньше невидимая подпись кнопки сдвигала его вверх на 4 точки) */
.ctl::before { position: absolute; left: 50%; top: 50%; margin: -13px 0 0 -13px; }

/* 2) «думаю / жду агента» показывает сфера; на кнопке «Завершить» второе вращение только сбивало */
.talk.thinking .ring { animation: none; border-color: transparent; }

/* 3) «Слушаю»: кольцо голубое (плавно проступает поверх радужного), у запасного движка остаётся янтарным */
.orb-spin::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 200deg, #35D6FF, #3F7BFF, #6E5CFF, #35D6FF, #8FEAFF, #3F7BFF, #35D6FF);
  -webkit-mask: radial-gradient(closest-side, transparent 86%, #000 88.5%, #000 97%, transparent 100%);
  mask: radial-gradient(closest-side, transparent 86%, #000 88.5%, #000 97%, transparent 100%);
  opacity: 0; transition: opacity var(--t-mid) var(--effect);
}
body.o-listening:not(.eng-spare) .orb-spin::before { opacity: .95; }
body.o-listening:not(.eng-spare) .orb-ring:not(.warm) { opacity: .12; }
body.o-muted { --glow: #8A93B0; }

/* 4) место под статусом и плашками одно во всех состояниях: сфера не меняет размер при «Слушаю», «Жду ответ» */
.hudtxt { height: 88px; min-height: 0; justify-content: flex-start; }
body.mode-cam .hudtxt { height: auto; }
/* в проверочном режиме (плашка «ТЕСТ» в две строки) место растёт, чтобы плашка не наезжала на сферу */
.hudtxt:has(#testBadge:not([hidden])) { height: auto; min-height: 88px; }
@media (max-height: 640px) { .hudtxt { height: 76px; } }

/* 4б) в тишине и при подключении ряда «Посмотри / Камера» нет, и раньше сфера была крупнее, а с началом разговора резко
   уменьшалась. Теперь пустой ряд отдаёт место полосе субтитров: сфера того же размера до, во время и после разговора */
.log { --logh: clamp(84px, 17dvh, 150px); height: var(--logh); }
@media (max-height: 640px) { .log { --logh: clamp(64px, 14dvh, 110px); } }
body:not(.mode-cam) .wrap:not(:has(.tools > .pill:not([hidden]))) .log:not(.open) { height: calc(var(--logh) + 46px); }

/* 5) живость: сфера дышит в тишине, внутри шара плывут облака цвета состояния */
/* облака: круг того же размера, что шар, поворачивается целиком (без обрезки по краю: обрезка дорогая для телефона) */
.orb-core::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background:
    radial-gradient(38% 34% at 30% 34%, color-mix(in srgb, var(--glow, #7A5CFF) 34%, transparent), transparent 72%),
    radial-gradient(40% 36% at 70% 68%, rgba(53, 214, 255, .16), transparent 72%),
    radial-gradient(30% 28% at 72% 28%, rgba(255, 79, 184, .12), transparent 70%);
  animation: orbspin 16s linear infinite reverse; will-change: transform;
}
body.o-speaking .orb-core::before { animation-duration: 7s; }
body.o-thinking .orb-core::before, body.o-connecting .orb-core::before { animation-duration: 9s; }
body.o-muted .orb-core::before { opacity: .35; }
@keyframes orbbreathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.028); } }
@keyframes glowbreathe { 0%, 100% { opacity: .34; } 50% { opacity: .56; } }
body.o-idle .orb { animation: orbbreathe 5.6s ease-in-out infinite; }
body.o-idle .orb-glow { animation: glowbreathe 5.6s ease-in-out infinite; }
.invite-orb { animation: orbbreathe 5.6s ease-in-out infinite; }
/* кнопка «Говорить» в тишине трижды мягко зовёт кругом, потом замирает (без постоянной работы экрана) */
.talkDisc::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none; opacity: 0;
  border: 2px solid color-mix(in srgb, var(--grad-b) 70%, #FFFFFF);
}
body.o-idle:not(.tr) .talk:not(:disabled):not(.live):not(.connecting) .talkDisc::after {
  animation: talkhalo 2.6s cubic-bezier(.2, .7, .3, 1) 1.2s 3 both;
}
@keyframes talkhalo { 0% { transform: scale(1); opacity: .75; } 75%, 100% { transform: scale(1.5); opacity: 0; } }

/* 6) субтитры: своя реплика над ответом одной строкой; пока говорит Андрей, видны три последние строки его речи */
.log { -webkit-mask: linear-gradient(to bottom, transparent 0, #000 10px); mask: linear-gradient(to bottom, transparent 0, #000 10px); }
.log:not(.open) > .msg.me:not(:last-child) span {
  display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 14.5px;
}
.log:not(.open) > .msg.me:last-child {
  display: flex; flex-direction: column; justify-content: flex-end; max-height: calc(3 * 1.4 * 15px + 2px); overflow: hidden;
}
.log:not(.open) > .msg.me:last-child span { display: block; }
.log:not(.open) .msg.ai.clip {
  -webkit-mask: linear-gradient(to bottom, rgba(0, 0, 0, .1) 0, rgba(0, 0, 0, .55) .75em, #000 1.5em);
  mask: linear-gradient(to bottom, rgba(0, 0, 0, .1) 0, rgba(0, 0, 0, .55) .75em, #000 1.5em);
}
@media (max-height: 780px) { .log:not(.open) .msg.ai { max-height: calc(3 * 1.38em); } }
/* подсказка до первого разговора: без повтора «Нажмите», по центру полосы субтитров */
.log:empty::before {
  content: "Спросите что угодно: о\00A0делах, почте, дороге, ценах"; margin: auto; max-width: 28ch;
  text-wrap: balance;
}

/* 7) точка состояния у статуса: цвет как у сферы (голубой слушаю, фиолетовый думаю, розовый говорю) */
body:not(.o-idle):not(.tr) .status::before {
  content: ""; display: inline-block; width: 9px; height: 9px; margin: 0 9px 0 0; border-radius: 50%; vertical-align: .12em;
  background: var(--glow, var(--grad-a)); box-shadow: 0 0 10px color-mix(in srgb, var(--glow, var(--grad-a)) 70%, transparent);
  transition: background var(--t-fx) var(--effect);
}
body.o-listening .status::before, body.o-speaking .status::before { animation: dotpulse 1.4s ease-in-out infinite; }
@keyframes dotpulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* 8) камера: без тёмной каёмки по краю картинки (видео чуть больше рамки), рамка тенью */
.cam { border: 0; box-shadow: 0 0 0 1px var(--line), var(--shadow-lg); }
.cam video { position: absolute; inset: -1px; width: calc(100% + 2px); height: calc(100% + 2px); }

/* переносы без «сирот»: последнее слово или «(≈» не остаётся одно на строке */
.log .msg, .status, .ou-rs, .err { text-wrap: pretty; }

/* пока открыт лист или «Да / Отмена», сфера под затемнением не крутится (меньше работы телефону) */
body:has(.ou-ov:not([hidden])) .orb-spin, body:has(.ou-ov:not([hidden])) .orb-core::before,
body:has(.log.open) .orb-spin, body:has(.log.open) .orb-core::before { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  body.o-idle .orb, body.o-idle .orb-glow, .invite-orb, .orb-core::before, .talkDisc::after, .status::before { animation: none !important; }
  .orb-spin::before { transition: none; }
}

/* [исправления 28.09] батарея: в покое (20 с без касаний до разговора), под листами, в фоне и у уха сфера стоит
   (orb.js ставит body.o-rest). Раньше 4 бесконечные анимации крутились всё время: 6-38 % процессора в тишине */
body.o-rest .orb, body.o-rest .orb *, body.o-rest .orb-core::before, body.o-rest .invite-orb,
body.o-rest .invite-orb *, body.o-rest .talkDisc::after, body.o-rest .status::before, body.o-rest .aura * {
  animation-play-state: paused !important;
}
/* ошибка («нет доступа к микрофону») не сжимает сферу: текст поверх субтитров, сфера того же размера */
/* [fix-r1] подсказка ошибки целиком (была обрезана на третьей строке); пока она видна, субтитры спрятаны */
.stage > #err:not([hidden]) { flex: 0 0 auto; max-height: none; overflow: visible; }
body:has(#err:not([hidden])) #log:not(.open) { display: none; }
#mute:disabled { opacity: .45; }
/* после конца разговора в субтитрах одна последняя пара реплик (весь разговор: в листе «Разговор») */
body.talk-idle #log:not(.open) > .msg:not(:nth-last-child(-n+2 of .msg:not(.filler))) { display: none; }
/* всплывшая карточка: субтитры под ней прячутся (торчала полстроки текста) */
body:has(.ou-pop) #log:not(.open) { opacity: 0; transition: opacity .2s; }
/* [fix-r3 28.09] подсказка «Звук в трубке: поднесите телефон к уху» ложилась поверх субтитров */
body:has(.ou-toast) #log:not(.open) { opacity: 0; transition: opacity .2s; }
/* [fix-r2 28.09] над новым вопросом висели прошлые ответы Оскара без строк «Вы:»: правило .msg.ai (display: flex) той же
   силы стояло ниже и перебивало «показывать только две последние реплики» */
/* [fix-r3 28.09] считаются только реплики без заготовок («Секунду, сейчас сделаю» вытесняла «Вы: ...») */
.log:not(.open) > .msg:not(:nth-last-child(-n+2 of .msg:not(.filler))) { display: none !important; }
.log:not(.open) > .msg.filler { display: none !important; }
body.mode-cam .log:not(.open) > .msg:not(:last-child) { display: none !important; }

/* ══ [камера 28.09] камера как у телефона. Андрей: «камера маленькая, сложно навести; хочу большой кадр, 0,6, 1×, 2×».
   Большой экран по умолчанию (кнопка в правом верхнем углу картинки уменьшает до окошка и обратно, выбор запоминается):
   картинка от края до края, кадр целиком (contain: Оскар получает ровно то, что видно), статус и субтитры поверх картинки,
   кнопки разговора внизу на своих местах. Низ картинки: фонарик, зум (что правда умеет камера: 0,6×, 1×, 2×, 5×;
   в приложении вырезом кадра 1× и 2×), смена камеры. Щипок двумя пальцами: зум; касание: фокус в этой точке. ══ */
.cam { touch-action: none; }
.cam video { transform: scale(var(--cz, 1)); transform-origin: 50% 50%; }
.cam video.front { transform: scale(calc(var(--cz, 1) * -1), var(--cz, 1)); }
.cam .camIco { z-index: 2; }
.cam #torch { top: auto; bottom: 10px; left: 10px; }
.cam #camFlip { top: auto; bottom: 10px; right: 10px; }
.cam #camSize { top: 10px; right: 10px; }
.cam #camSize .i-grow, .cam #camSize:not(.big) .i-shrink { display: none; }
.cam #camSize:not(.big) .i-grow { display: block; }
.camZoom {
  position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%); z-index: 2;
  display: flex; gap: 6px; margin: 0; padding: 0;
}
.camZoom button {
  width: 44px; height: 44px; min-height: 44px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(3, 8, 26, .55); color: #FFFFFF; font: inherit; font-size: 13px; font-weight: 700; letter-spacing: -.2px;
  font-variant-numeric: tabular-nums; cursor: pointer; touch-action: manipulation;
  transition: transform var(--t-fast) var(--spring-fast), color var(--t-fx) var(--effect), background var(--t-fx) var(--effect);
}
.camZoom button:active { transform: scale(.9); }
.camZoom button[aria-pressed="true"] { color: #FFD25C; font-size: 14px; background: rgba(3, 8, 26, .75); }
.camFocus {
  position: absolute; z-index: 2; width: 72px; height: 72px; margin: -36px 0 0 -36px; border-radius: 50%;
  border: 2px solid #FFD25C; box-shadow: 0 0 0 1px rgba(0, 0, 0, .25); pointer-events: none;
  animation: camfocus 1.2s var(--effect) forwards;
}
@keyframes camfocus { 0% { opacity: 0; transform: scale(1.4); } 18% { opacity: 1; transform: scale(1); } 70% { opacity: 1; } 100% { opacity: 0; } }
.camNote {
  position: absolute; z-index: 2; left: 50%; top: 50%; transform: translate(-50%, -50%); margin: 0; padding: 8px 16px;
  border-radius: 999px; background: rgba(3, 8, 26, .72); color: #FFFFFF; font-size: 15px; font-weight: 650;
  white-space: nowrap; pointer-events: none;
}

/* ══ [камера как у Gemini 28.09] Андрей, 21:17: «у нас очень маленький экран и при этом слишком крупно всё; сделай как у Гемини».
   Большой режим камеры: картинка на весь экран (cover, без чёрных полей), поверх неё маленькие полупрозрачные круглые кнопки.
   Сверху справа: «Уменьшить», «Сменить камеру», «Выкл. камеру» (выключатель ушёл из-под большого пальца и щеки).
   Сверху слева: сфера 36 и статус. Снизу один ряд из пяти колонок: «Прочитай», «Микрофон», «Завершить», «Динамик», «Фонарик»
   (нет фонарика или кнопки звука: место пустое, остальные кнопки не съезжают). Над рядом зум, над зумом субтитры до трёх
   строк, середина кадра свободна. На весь экран ползунок громкости спрятан (кнопки громкости телефона работают), в окошке
   он есть, как было. С приложением 2.2.5 картинка и под полосками часов и жестов (camBars просит edge), кнопки от них
   отступают на --oa-top / --oa-bottom. Оскар получает ровно видимую часть кадра (shownRect: cover уже учтён). Окошко (кнопка «Уменьшить») как было. ══ */
body.cam-big {
  --cf-top: max(10px, calc(var(--oa-top, env(safe-area-inset-top, 0px)) + 8px));
  --cf-bot: max(14px, calc(var(--oa-bottom, env(safe-area-inset-bottom, 0px)) + 8px));
  --cf-side: max(12px, env(safe-area-inset-left, 0px));
  --cf-row: min(calc(100vw - 16px), 420px);
  --cf-col: calc(var(--cf-row) / 5);
  --cf-btn: 48px; --cf-end: 56px; --cf-tb: 44px; --cf-zoom: 50px;
  --cf-glass: rgba(16, 18, 26, .50);
  background: #000;
}
body.cam-big .top, body.cam-big .ou-bar { display: none !important; }
body.cam-big .ou-vol-bottom { display: none !important; }

/* картинка на весь экран */
body.cam-big .cam {
  position: fixed; inset: 0; z-index: 0; margin: 0; min-height: 0; max-height: none; border-radius: 0;
  background: #000; box-shadow: none; animation: none;
}
body.cam-big .cam video { object-fit: cover; }
/* затемнения для читаемости: сверху под статусом и кнопками, снизу под субтитрами и рядом кнопок */
body.cam-big .cam::before, body.cam-big .cam::after {
  content: ""; position: absolute; z-index: 1; left: 0; right: 0; pointer-events: none;
}
body.cam-big .cam::before { top: 0; height: calc(var(--cf-top) + 116px); background: linear-gradient(rgba(0, 0, 0, .5), rgba(0, 0, 0, .16) 62%, rgba(0, 0, 0, 0)); }
body.cam-big .cam::after { bottom: 0; height: calc(var(--cf-bot) + 200px); background: linear-gradient(to top, rgba(0, 0, 0, .56), rgba(0, 0, 0, .2) 58%, rgba(0, 0, 0, 0)); }

/* общий вид круглых кнопок поверх картинки */
body.cam-big #camBtn, body.cam-big .cam #camFlip, body.cam-big .cam #camSize, body.cam-big #read, body.cam-big .cam #torch,
body.cam-big .ctl, body.cam-big .ou-route {
  position: fixed; z-index: 6; margin: 0; padding: 0; gap: 0; min-height: 0; border: 0; border-radius: 50%;
  display: grid; place-items: center; background: var(--cf-glass); color: #FFFFFF; box-shadow: none; font-size: 0;
}
/* сверху справа: «Выкл. камеру» у края, левее «Сменить камеру», ещё левее «Уменьшить» */
body.cam-big #camBtn, body.cam-big .cam #camFlip, body.cam-big .cam #camSize {
  top: var(--cf-top); bottom: auto; left: auto; width: var(--cf-tb); height: var(--cf-tb);
}
body.cam-big #camBtn { right: var(--cf-side); }
body.cam-big .cam #camFlip { right: calc(var(--cf-side) + var(--cf-tb) + 8px); }
body.cam-big .cam #camSize { right: calc(var(--cf-side) + 2 * (var(--cf-tb) + 8px)); }
body.cam-big #camBtn::before, body.cam-big #read::before { width: 22px; height: 22px; }
body.cam-big .cam .camIco svg { width: 22px; height: 22px; }

/* нижний ряд: пять одинаковых колонок, центры на одной линии */
body.cam-big #read, body.cam-big .cam #torch {
  width: var(--cf-btn); height: var(--cf-btn); top: auto;
  bottom: calc(var(--cf-bot) + (var(--cf-end) - var(--cf-btn)) / 2);
}
body.cam-big #read { left: calc(50% - 2 * var(--cf-col) - var(--cf-btn) / 2); right: auto; }
body.cam-big .cam #torch { right: calc(50% - 2 * var(--cf-col) - var(--cf-btn) / 2); left: auto; }
body.cam-big #read:disabled { opacity: 1; background: linear-gradient(135deg, var(--grad-a), var(--grad-b)); }
body.cam-big .cam #torch[aria-pressed="true"] { background: #FFD25C; color: #1B1400; }
body.cam-big .ctrls {
  position: fixed; z-index: 6; left: calc(50% - 1.5 * var(--cf-col)); width: calc(3 * var(--cf-col)); bottom: var(--cf-bot);
  height: var(--cf-end); min-height: 0; margin: 0; padding: 0; grid-template-columns: 1fr 1fr 1fr; align-items: center;
}
body.cam-big .ctl-slot { padding: 0; min-width: 0; }
body.cam-big .ctl, body.cam-big .ou-route { position: relative; width: var(--cf-btn); height: var(--cf-btn); }
body.cam-big .ctl::before { width: 22px; height: 22px; margin: -11px 0 0 -11px; }
body.cam-big .ou-route::before { width: 22px; height: 22px; }
body.cam-big .ctl::after, body.cam-big .ou-route .ou-rcap { display: none; }
body.cam-big #mute.on, body.cam-big .ou-route[data-route="earpiece"] { background: #FFFFFF; color: #10131C; }
body.cam-big .talk { min-width: 0; gap: 0; }
body.cam-big .talkDisc { width: var(--cf-end); height: var(--cf-end); box-shadow: 0 6px 18px rgba(0, 0, 0, .35); }
body.cam-big .talkIco { width: 26px; height: 26px; }
body.cam-big .ring { inset: -5px; }
body.cam-big .talkLabel {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* зум над рядом кнопок: одна полупрозрачная капсула, кнопки 44 точки (объективы 0,6× / 3,5×, если приложение скажет) */
body.cam-big .camZoom {
  position: fixed; z-index: 6; left: 50%; transform: translateX(-50%); bottom: calc(var(--cf-bot) + var(--cf-end) + 10px);
  height: var(--cf-zoom); gap: 2px; padding: 3px; border-radius: 999px; background: rgba(0, 0, 0, .34); box-sizing: border-box;
}
body.cam-big .camZoom button { width: 44px; height: 44px; min-height: 44px; font-size: 12.5px; background: transparent; }
body.cam-big .camZoom button[aria-pressed="true"] { background: rgba(0, 0, 0, .56); font-size: 13px; }

/* сверху слева: сфера и статус, справа от них три кнопки */
body.cam-big .hud {
  position: fixed; z-index: 6; top: var(--cf-top); left: var(--cf-side); right: calc(var(--cf-side) + 3 * (var(--cf-tb) + 8px));
  min-height: var(--cf-tb); margin: 0; padding: 0; flex-direction: row-reverse; justify-content: flex-end; align-items: center;
  gap: 8px; pointer-events: none;
}
body.cam-big .orbbox { flex: 0 0 36px; width: 36px; height: 36px; min-height: 0; pointer-events: auto; }
body.cam-big .orb { --os: 36px; }
body.cam-big .hudtxt { gap: 3px; min-width: 0; }
body.cam-big .hud .status { font-size: 16px; line-height: 1.25; color: #FFFFFF; text-shadow: 0 1px 3px rgba(0, 0, 0, .6); }
body.cam-big .hud .status::before { width: 7px; height: 7px; margin-right: 7px; }
body.cam-big .hud .englbl, body.cam-big .hud .badge:not(.wait) {
  font-size: 11.5px; padding: 1px 8px; background: rgba(0, 0, 0, .42); color: #E8ECF9; border-color: rgba(255, 255, 255, .24);
}
body.cam-big .hud .englbl.fast { color: #B4C6FF; }
body.cam-big .hud .englbl.spare, body.cam-big .hud .badge.eng { color: #FFC978; }
body.cam-big .hud .badge.test { color: #FFBAC6; }

/* субтитры над зумом: последняя реплика, до трёх строк; середина кадра свободна */
body.cam-big .log:not(.open) {
  position: fixed; z-index: 5; left: 16px; right: 16px; bottom: calc(var(--cf-bot) + var(--cf-end) + 10px + var(--cf-zoom) + 8px);
  max-width: 520px; height: auto; max-height: calc(3 * 1.4 * 15px + 4px); margin: 0 auto; padding: 0;
  background: none; color: #FFFFFF; text-shadow: 0 1px 3px rgba(0, 0, 0, .85); -webkit-mask: none; mask: none;
}
body.cam-big:not(:has(#camZoom:not([hidden]))) .log:not(.open) { bottom: calc(var(--cf-bot) + var(--cf-end) + 12px); }
body.cam-big .log:not(.open) .msg.ai { font-size: 15px; line-height: 1.4; max-height: calc(3 * 1.4em); color: #FFFFFF; }
body.cam-big .log:not(.open) .msg.me span { font-size: 13.5px; color: rgba(255, 255, 255, .86); }
body.cam-big .log:not(.open) .msg.sys { font-size: 13px; color: rgba(255, 255, 255, .82); }
/* лист «Разговор» поверх камеры: с приложением 2.2.5 страница и под полоской жестов, последняя реплика над ней */
body.cam-big .log.open { padding-bottom: max(20px, calc(var(--oa-bottom, 0px) + 16px)); }

/* ошибка и «Включить звук» под верхним рядом, поверх картинки */
body.cam-big #err:not([hidden]) {
  position: fixed; z-index: 7; top: calc(var(--cf-top) + var(--cf-tb) + 12px); left: 16px; right: 16px; max-width: 520px;
  margin: 0 auto; background: rgba(40, 8, 16, .84); color: #FFD3DA; border-color: rgba(255, 128, 146, .45); font-size: 14px;
}
body.cam-big .tools {
  position: fixed; z-index: 6; left: 0; right: 0; top: calc(var(--cf-top) + var(--cf-tb) + 12px); padding: 0; min-height: 0;
  pointer-events: none;
}
body.cam-big .tools > * { pointer-events: auto; }
body.cam-big .flash { top: calc(var(--cf-top) + var(--cf-tb) + 12px); }

/* альбомный экран (вкладка Chrome; приложение держит вертикаль): ряд кнопок столбиком у правого края */
@media (orientation: landscape) and (max-height: 540px) {
  body.cam-big { --cf-col: min(calc((100dvh - 2 * var(--cf-bot)) / 5), 64px); --cf-side: max(12px, env(safe-area-inset-right, 0px)); }
  body.cam-big .ctrls {
    left: auto; right: var(--cf-side); bottom: auto; top: calc(50% - 1.5 * var(--cf-col)); width: var(--cf-end); height: calc(3 * var(--cf-col));
    grid-template-columns: 1fr; grid-template-rows: 1fr 1fr 1fr;
  }
  body.cam-big #read, body.cam-big .cam #torch { left: auto; right: calc(var(--cf-side) + (var(--cf-end) - var(--cf-btn)) / 2); bottom: auto; }
  body.cam-big #read { top: calc(50% - 2 * var(--cf-col) - var(--cf-btn) / 2); }
  body.cam-big .cam #torch { top: calc(50% + 2 * var(--cf-col) - var(--cf-btn) / 2); }
  body.cam-big #camBtn { right: calc(var(--cf-side) + var(--cf-end) + 16px); }
  body.cam-big .cam #camFlip { right: calc(var(--cf-side) + var(--cf-end) + 16px + var(--cf-tb) + 8px); }
  body.cam-big .cam #camSize { right: calc(var(--cf-side) + var(--cf-end) + 16px + 2 * (var(--cf-tb) + 8px)); }
  body.cam-big .hud { right: calc(var(--cf-side) + var(--cf-end) + 16px + 3 * (var(--cf-tb) + 8px)); }
  body.cam-big .camZoom { bottom: var(--cf-bot); }
  body.cam-big .log:not(.open), body.cam-big:not(:has(#camZoom:not([hidden]))) .log:not(.open) {
    bottom: calc(var(--cf-bot) + var(--cf-zoom) + 8px); right: calc(var(--cf-side) + var(--cf-end) + 24px);
  }
  body.cam-big .cam::after { height: calc(var(--cf-bot) + 150px); }
  /* окошко: статус и субтитры справа в одной клетке наезжали друг на друга: статус сверху, субтитры снизу */
  body.mode-cam .hud { align-self: start; }
  body.mode-cam .log:not(.open) { align-self: end; }
}
@media (prefers-reduced-motion: reduce) {
  .camFocus { animation: none !important; }
  .camZoom button { transition: none !important; }
}

/* ══ [посмотри-видоискатель 29.09] «Посмотри» с видоискателем. Андрей, 29.09 00:15: «при нажатии кнопки посмотри выходила
   камера на полный экран как и видео, только с возможностью фото ... сейчас делается фото вслепую ... нужно отдалять и
   приближать». Тот же экран, что у живой камеры (body.cam-big: картинка на весь экран, объективы, щипок, фокус, фонарик,
   смена камеры), плюс body.look-vf: вместо «Завершить» большая круглая кнопка снимка, справа сверху крестик на месте
   «Выкл. камеру», «Уменьшить» нет. После снимка он замирает на экране с «Смотрю…» и кнопкой «Ещё снимок». ══ */
body.cam-big.look-vf { --cf-end: 76px; }
body.look-vf .ctrls { pointer-events: none; }
body.look-vf .ctrls > *:not(.talk) { pointer-events: auto; }
body.look-vf .ctrls .talk { visibility: hidden; pointer-events: none; }
/* «Прочитай» в видоискателе недоступна, пока снимок замер: просто тусклая (у живой камеры цветная значит «читаю») */
body.cam-big.look-vf #read:disabled { background: var(--cf-glass); opacity: .45; }
body.cam-big .cam .vfFreeze {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none;
}
body.cam-big .cam .vfFreeze.front { transform: scaleX(-1); }
.vfFreeze.shot { animation: vfshot .4s ease-out; }
@keyframes vfshot { 0% { filter: brightness(2.4); opacity: .6; } 100% { filter: none; opacity: 1; } }
body.cam-big .cam #vfClose {
  position: fixed; z-index: 6; top: var(--cf-top); right: var(--cf-side); left: auto; bottom: auto; margin: 0; padding: 0;
  width: var(--cf-tb); height: var(--cf-tb); min-height: 0; border: 0; border-radius: 50%; display: grid; place-items: center;
  background: var(--cf-glass); color: #FFFFFF; box-shadow: none;
}
body.cam-big .cam #vfClose svg { width: 22px; height: 22px; }
/* большая круглая кнопка снимка: белое кольцо, белый круг; «сниму сам»: жёлтая дуга по кольцу (--p от 0 до 1) */
.vfShot {
  position: fixed; z-index: 6; left: calc(50% - 38px); bottom: var(--cf-bot, 14px); width: 76px; height: 76px;
  margin: 0; padding: 0; border: 0; border-radius: 50%; background: transparent; cursor: pointer; touch-action: manipulation;
  display: grid; place-items: center; -webkit-tap-highlight-color: transparent;
}
.vfShot::before {
  content: ""; position: absolute; inset: 0; border-radius: 50%; border: 4px solid #FFFFFF;
  box-shadow: 0 2px 14px rgba(0, 0, 0, .35), inset 0 0 0 1px rgba(0, 0, 0, .12);
}
.vfShot::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%; pointer-events: none;
  background: conic-gradient(#FFD25C calc(var(--p, 0) * 360deg), transparent 0);
  -webkit-mask: radial-gradient(circle, transparent 33px, #000 34px); mask: radial-gradient(circle, transparent 33px, #000 34px);
}
.vfDot {
  width: 60px; height: 60px; border-radius: 50%; background: #FFFFFF; display: grid; place-items: center;
  transition: transform .12s ease-out, background .2s ease-out;
}
.vfShot:active .vfDot { transform: scale(.86); background: #E8ECF9; }
.vfShot:disabled { cursor: default; }
.vfShot:disabled .vfDot { background: rgba(255, 255, 255, .55); }
/* «Прочитай»: на круге значок текста */
.vfShot.read .vfDot::before {
  content: ""; width: 26px; height: 26px; background: #10131C;
  -webkit-mask: var(--i-read) center / contain no-repeat; mask: var(--i-read) center / contain no-repeat;
}
.vfTip, .vfBusy {
  position: fixed; z-index: 6; left: 50%; transform: translateX(-50%); margin: 0; padding: 8px 14px; border-radius: 999px;
  background: rgba(0, 0, 0, .58); color: #FFFFFF; font-size: 14.5px; font-weight: 600; line-height: 1.3; text-align: center;
  white-space: nowrap; max-width: calc(100vw - 32px); overflow: hidden; text-overflow: ellipsis; pointer-events: none;
}
.vfTip { top: calc(var(--cf-top, 10px) + var(--cf-tb, 44px) + 12px); }
body:has(#err:not([hidden])) .vfTip { display: none !important; }
.vfBusy { top: 50%; transform: translate(-50%, -50%); padding: 10px 20px 10px 16px; font-size: 16px; display: flex; align-items: center; gap: 10px; }
.vfBusy::before {
  content: ""; width: 10px; height: 10px; border-radius: 50%; background: #FFD25C; animation: vfpulse 1s ease-in-out infinite;
}
@keyframes vfpulse { 0%, 100% { opacity: .35; transform: scale(.8); } 50% { opacity: 1; transform: scale(1.15); } }
.vfMore {
  position: fixed; z-index: 6; left: 50%; transform: translateX(-50%); bottom: calc(var(--cf-bot, 14px) + var(--cf-end, 76px) + 10px);
  min-height: 46px; margin: 0; padding: 10px 20px; border: 0; border-radius: 999px; background: rgba(0, 0, 0, .62); color: #FFFFFF;
  font: inherit; font-size: 15px; font-weight: 650; cursor: pointer; touch-action: manipulation; white-space: nowrap;
}
.vfMore:active { transform: translateX(-50%) scale(.95); }
body.vf-frozen .camZoom { visibility: hidden; }
/* субтитры над «Ещё снимок» и тогда, когда кнопок зума нет */
body.cam-big.vf-frozen:not(:has(#vfMore[hidden])) #log:not(.open) { bottom: calc(var(--cf-bot) + var(--cf-end) + 10px + 46px + 8px); }
/* снимок в разговоре: маленький, вертикальный не растягивает строку */
.msg.me img.tall { width: auto; height: 112px; max-width: 96px; object-fit: cover; }
.log:not(.open) .msg.me img.tall { width: auto; height: 40px; }
@media (orientation: landscape) and (max-height: 540px) {
  .vfShot { left: auto; right: var(--cf-side, 12px); bottom: auto; top: calc(50% - 38px); }
  body.cam-big .cam #vfClose { right: calc(var(--cf-side) + var(--cf-end) + 16px); }
  .vfMore { bottom: var(--cf-bot, 14px); }
  body.cam-big.vf-frozen:not(:has(#vfMore[hidden])) #log:not(.open) { bottom: calc(var(--cf-bot) + 46px + 8px); }
}
/* доводка: пока снимок замер на весь экран, его маленькая копия в подписи внизу не нужна */
body.vf-frozen .log:not(.open) .msg.me img { display: none; }
/* узкий экран (до 340 точек): круг снимка меньше, не касается кнопок микрофона и динамика */
@media (max-width: 340px) {
  body.cam-big.look-vf { --cf-end: 68px; }
  .vfShot { left: calc(50% - 34px); width: 68px; height: 68px; }
  .vfShot::after {
    -webkit-mask: radial-gradient(circle, transparent 29px, #000 30px); mask: radial-gradient(circle, transparent 29px, #000 30px);
  }
  .vfDot { width: 53px; height: 53px; }
}
@media (prefers-reduced-motion: reduce) {
  .vfFreeze.shot, .vfBusy::before { animation: none !important; }
  .vfDot { transition: none !important; }
}

/* ── [экран 29.09] показ экрана Оскару и картинки в разговор ── */
:root {
  --i-screen: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Crect x=%226.5%22 y=%222.5%22 width=%2211%22 height=%2219%22 rx=%222.2%22/%3E%3Cpath d=%22M10.5 18.5h3%22/%3E%3Cpath d=%22M9.5 9.5l2 2 3-3.5%22/%3E%3C/svg%3E");
  --i-image: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Crect x=%223.5%22 y=%224.5%22 width=%2217%22 height=%2215%22 rx=%222.5%22/%3E%3Ccircle cx=%229%22 cy=%2210%22 r=%221.8%22/%3E%3Cpath d=%22M20.5 15.5l-4.5-4.5-8.5 8.5%22/%3E%3C/svg%3E");
  --i-shot: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M4 8V5.5A1.5 1.5 0 0 1 5.5 4H8M16 4h2.5A1.5 1.5 0 0 1 20 5.5V8M20 16v2.5a1.5 1.5 0 0 1-1.5 1.5H16M8 20H5.5A1.5 1.5 0 0 1 4 18.5V16%22/%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%223%22/%3E%3C/svg%3E");
}
#scrBtn { --pi: var(--i-screen); }
#imgBtn { --pi: var(--i-image); }
#lastBtn { --pi: var(--i-shot); }
.pill#scrBtn:disabled { opacity: 1; background: linear-gradient(135deg, var(--grad-a), var(--grad-b)); color: #FFFFFF; border-color: transparent; }
.scrBar {
  order: 7; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 10px;
  margin: 8px auto 0; padding: 8px 10px 8px 14px; border-radius: 22px; max-width: 100%;
  background: color-mix(in srgb, var(--accent) 12%, var(--panel)); border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
}
.scrBar[hidden] { display: none; }
.scrState { font-size: 14px; font-weight: 650; color: var(--text); display: inline-flex; align-items: center; gap: 8px; }
.scrState::before {
  content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--err); flex: 0 0 auto;
  animation: scrDot 1.6s ease-in-out infinite;
}
@keyframes scrDot { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.scrBtns { display: inline-flex; gap: 6px; flex-wrap: wrap; justify-content: center; }
.pill.scrPill { min-height: 44px; padding: 8px 14px; font-size: 14px; box-shadow: none; }
@media (max-width: 360px) {
  .pill.scrPill { padding: 8px 11px; }
  .tools .pill { padding: 10px 12px 10px 10px; font-size: 14px; }
}
@media (orientation: landscape) and (max-height: 540px) {
  .scrBar { grid-column: 2; grid-row: 4; }
}
@media (prefers-reduced-motion: reduce) {
  .scrState::before { animation: none !important; }
}
