/*
 * Экран проекта: слева чат с Рондом, справа превью.
 *
 * Палитра и пропорции — из макета Figma Make («Дизайн для сервиса Ронд»,
 * src/pages/Project.tsx): тёплая тёмная основа #100f0a, шапка #141209, поле
 * превью #0b0a06 со светлой карточкой #f6f4ee. Экран держится на своих
 * токенах и своих классах .ke-*, а не на дизайн-системе: так вёрстка
 * редактора не поедет, когда общий styles.css поменяют соседи.
 *
 * Два отступления от макета сделаны намеренно:
 *   1. Тусклый текст макета поднят там, где текст СОДЕРЖАТЕЛЬНЫЙ: #8a8577 на
 *      #100f0a — это 4.6:1, то есть ГОСТ Р 52872-2019 проходит. Совсем тусклое
 *      осталось только у декора.
 *   2. В шапке живут кнопки, которых у макета нет вовсе (версии, фотографии,
 *      «Перед запуском», «Обновить превью»): макет рисует витрину, а здесь
 *      идёт работа. Вид кнопок — макетный, состав — наш.
 */

.ke-screen {
  /* цвета макета */
  --ke-bg: #100f0a;
  --ke-surface: #141209;
  --ke-panel: #16140d;
  /* поле, на котором лежит превью, и сама светлая карточка */
  --ke-stage: #0b0a06;
  --ke-paper: #f6f4ee;
  /* пузырь реплики человека */
  --ke-bubble: #26241d;
  --ke-line: rgba(255, 255, 255, 0.07);
  --ke-line-2: rgba(255, 255, 255, 0.12);
  --ke-t1: #efece2;
  --ke-t2: #dcd8cc; /* основной вторичный текст */
  --ke-t3: #b3ad9d; /* подписи и мета */
  --ke-t4: #8a8577; /* тусклое: время, служебные пометки */
  --ke-brand: #f96332;
  --ke-brand-light: #ffb899;
  --ke-grad: linear-gradient(135deg, #f96332, #fb7c4d);
  --ke-brand-soft: rgba(249, 99, 50, 0.18);
  --ke-brand-line: rgba(249, 99, 50, 0.32);
  --ke-ok: #34d399;
  --ke-ok-grad: linear-gradient(135deg, #10b981, #06b6d4);
  --ke-danger: #ff9d9d;
  --ke-danger-line: rgba(255, 110, 110, 0.45);
  --ke-danger-soft: rgba(255, 110, 110, 0.12);
  --ke-focus: #ffb899;

  --ke-r-xs: 0.25rem;
  --ke-r-sm: 0.375rem;
  --ke-r: 0.5rem;
  --ke-r-lg: 0.75rem;
  --ke-r-xl: 1rem;

  --ke-font: var(--k-font);
  --ke-font-mono: var(--k-mono);

  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  overflow: hidden;
  background: var(--ke-bg);
  color: var(--ke-t1);
  font-family: var(--ke-font);
  font-size: 0.875rem;
}

/* атрибут hidden сильнее наших display:flex — иначе скрытое остаётся видимым */
.ke-screen [hidden] {
  display: none !important;
}

/* Фокус видно всегда и на всём: это не украшение, а требование доступности. */
.ke-screen :focus-visible {
  outline: 2px solid var(--ke-focus);
  outline-offset: 2px;
}

.ke-mono {
  font-family: var(--ke-font-mono);
}

/* Подпись, невидимая глазом, но читаемая скринридером: нужна там,
   где на узком экране текст кнопки убран, а смысл остаться обязан. */
.ke-vh {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.ke-scroll {
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}

.ke-screen ::-webkit-scrollbar {
  width: 0.5rem;
  height: 0.5rem;
}

.ke-screen ::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.16);
  border-radius: 999px;
}

.ke-screen ::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.26);
}

/* ───────────── общие кнопки экрана ───────────── */

.ke-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  flex: none;
  height: 1.75rem;
  padding: 0 0.625rem;
  border: 1px solid var(--ke-line-2);
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.04);
  color: var(--ke-t1);
  font: inherit;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 140ms ease, border-color 140ms ease, opacity 140ms ease;
}

.ke-btn:hover {
  background: rgba(255, 255, 255, 0.09);
}

.ke-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

.ke-btn__icon {
  display: inline-flex;
  color: var(--ke-t2);
}

.ke-btn--light {
  border-color: transparent;
  background: #ffffff;
  color: #111113;
  font-weight: 600;
}

.ke-btn--light:hover {
  background: #ededf0;
}

.ke-btn--light .ke-btn__icon {
  color: #111113;
}

.ke-btn--danger {
  border-color: var(--ke-danger-line);
  background: var(--ke-danger-soft);
  color: var(--ke-danger);
}

.ke-btn--danger:hover {
  background: rgba(255, 110, 110, 0.2);
}

.ke-iconbtn {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
  padding: 0;
  border: 0;
  border-radius: var(--ke-r);
  background: transparent;
  color: var(--ke-t2);
  cursor: pointer;
  transition: background-color 140ms ease, color 140ms ease;
}

.ke-iconbtn:hover {
  background: rgba(255, 255, 255, 0.08);
  color: var(--ke-t1);
}

/* ───────────── шапка ───────────── */

.ke-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex: none;
  height: 3.5rem;
  padding: 0 1rem;
  background: var(--ke-surface);
  border-bottom: 1px solid var(--ke-line);
}

.ke-topbar__left {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

.ke-topbar__right {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: none;
}

.ke-div {
  flex: none;
  width: 1px;
  height: 1rem;
  background: var(--ke-line-2);
}

.ke-head__name {
  min-width: 0;
  margin: 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ke-t1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/*
 * Логотип приезжает из ui.js. Оформление в :where() — нулевой вес: если
 * дизайн-система опишет .z-logo по-своему, победит она, а не редактор.
 */
:where(.ke-topbar .z-logo) {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  flex: none;
}

:where(.ke-topbar .z-logo__mark) {
  display: grid;
  place-items: center;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: var(--ke-r-sm);
  background: var(--ke-grad);
}

:where(.ke-topbar .z-logo__name) {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ke-t1);
}

/* состояние агента */

.ke-state {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  flex: none;
  padding: 0.1875rem 0.5rem;
  border: 1px solid var(--ke-line-2);
  border-radius: 999px;
  color: var(--ke-t2);
  font-size: 0.75rem;
  white-space: nowrap;
}

.ke-state__dot {
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  background: var(--ke-ok);
}

.ke-state[data-state='busy'] {
  border-color: var(--ke-brand-line);
  background: rgba(249, 99, 50, 0.1);
  color: var(--ke-brand-light);
}

.ke-state[data-state='busy'] .ke-state__dot {
  background: var(--ke-brand);
  animation: ke-pulse 1.2s ease-in-out infinite;
}

@keyframes ke-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.25;
  }
}

.ke-cost {
  flex: none;
  padding: 0.1875rem 0.5rem;
  border: 1px solid var(--ke-line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--ke-t2);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ───────────── панель версий ───────────── */

.ke-versions-wrap {
  position: relative;
  flex: none;
}

.ke-versions {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 30;
  width: min(26rem, 92vw);
  padding: 0.75rem;
  border: 1px solid var(--ke-line-2);
  border-radius: var(--ke-r-lg);
  background: var(--ke-panel);
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, 0.6);
}

.ke-versions__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  font-size: 0.8125rem;
  font-weight: 600;
}

.ke-versions__list {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  max-height: min(50vh, 24rem);
  overflow-y: auto;
}

.ke-versions__empty {
  padding: 1rem;
  color: var(--ke-t3);
  font-size: 0.75rem;
  line-height: 1.5;
  text-align: center;
}

/* У пустого состояния есть заголовок и объяснение под ним: одно называет,
   второе отвечает на «а когда будет?». */
.ke-versions__empty-title {
  margin-bottom: 0.25rem;
  color: var(--ke-t1);
  font-size: 0.8125rem;
  font-weight: 600;
}

.ke-version {
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--ke-line);
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.03);
}

.ke-version__top {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.75rem;
}

.ke-version__sha {
  padding: 0.0625rem 0.375rem;
  border-radius: var(--ke-r-xs);
  background: rgba(255, 255, 255, 0.07);
  color: var(--ke-t2);
}

.ke-version__at {
  color: var(--ke-t3);
}

.ke-version__now {
  margin-left: auto;
  padding: 0.0625rem 0.375rem;
  border-radius: 999px;
  background: rgba(249, 99, 50, 0.16);
  color: var(--ke-brand-light);
  font-size: 0.6875rem;
}

.ke-version__msg {
  margin: 0.25rem 0 0.5rem;
  font-size: 0.8125rem;
  color: var(--ke-t1);
  overflow-wrap: anywhere;
}

.ke-version__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
}

.ke-version__ask {
  font-size: 0.75rem;
  color: var(--ke-t2);
}

.ke-versions__note {
  margin: 0.5rem 0 0;
  padding-top: 0.5rem;
  border-top: 1px solid var(--ke-line);
  color: var(--ke-t3);
  font-size: 0.6875rem;
  line-height: 1.5;
}

/* ───────────── две панели ───────────── */

.ke-split {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
}

.ke-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.ke-chat-pane {
  width: var(--ke-left, 42%);
  flex: none;
  min-width: 0;
  background: transparent;
  border-right: 1px solid var(--ke-line);
}

.ke-preview {
  flex: 1 1 auto;
  min-width: 0;
  background: var(--ke-stage);
}

/* Ручка тонкая, но зона захвата шире линии — иначе в неё не попасть мышью. */
.ke-bar {
  position: relative;
  flex: none;
  width: 0.375rem;
  margin: 0 -0.1875rem;
  z-index: 5;
  cursor: col-resize;
  background: transparent;
}

.ke-bar::after {
  content: '';
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0.125rem;
  height: 2.5rem;
  border-radius: 999px;
  background: transparent;
  transition: background-color 140ms ease;
}

.ke-bar:hover::after,
.ke-bar[data-dragging='true']::after {
  background: var(--ke-brand);
}

/* пока тянем границу, указатель не должен проваливаться в превью */
.ke-screen--dragging {
  user-select: none;
}

.ke-screen--dragging .ke-iframe {
  pointer-events: none;
}

/* ───────────── чат ───────────── */

.ke-chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex: none;
  padding: 0.5rem 0.875rem;
  border-bottom: 1px solid var(--ke-line);
}

.ke-chat-head__title {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ke-t2);
}

.ke-chat-head__mode {
  font-size: 0.6875rem;
  color: var(--ke-t3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ke-log {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  flex: 1 1 auto;
  min-height: 0;
  padding: 1rem 0.875rem;
  overflow-y: auto;
  scroll-behavior: smooth;
}

.ke-msg {
  display: flex;
  flex-direction: column;
  max-width: 92%;
  min-width: 0;
}

.ke-msg--user {
  align-self: flex-end;
  align-items: flex-end;
  max-width: 85%;
}

.ke-msg--assistant {
  align-self: stretch;
  max-width: none;
}

/* реплика пользователя — тёплый пузырь со срезанным правым нижним углом */
.ke-bubble {
  padding: 0.625rem 1rem;
  border: 0;
  border-radius: var(--ke-r-xl) var(--ke-r-xl) var(--ke-r-sm) var(--ke-r-xl);
  background: var(--ke-bubble);
  color: var(--ke-t1);
  font-size: 14.5px;
  line-height: 1.625;
  overflow-wrap: anywhere;
}

/*
 * Ответ агента по образцу заказчика. Карточка — это ТОЛЬКО шапка со сделанным
 * и два переключателя; человеческое объяснение живёт под ней обычным текстом,
 * потому что читать его должно быть так же легко, как письмо, а не как отчёт
 * системы. Всё техническое спрятано внутрь «Подробностей».
 */
.ke-card-msg {
  border: 1px solid var(--ke-line);
  border-radius: var(--ke-r-lg);
  background: rgba(255, 255, 255, 0.04);
  overflow: hidden;
}

.ke-card-msg__head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 0.75rem 0.5rem;
}

.ke-card-msg__mark {
  display: grid;
  place-items: center;
  flex: none;
  width: 1rem;
  height: 1rem;
  border-radius: var(--ke-r-xs);
  background: var(--ke-ok-grad);
  color: #ffffff;
}

.ke-msg--live .ke-card-msg__mark {
  background: var(--ke-grad);
}

.ke-card-msg__pulse {
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: #ffffff;
  animation: ke-pulse 1.1s ease-in-out infinite;
}

/* заголовок сделанного: короткий и жирный — по нему ответ узнают в ленте */
.ke-card-msg__title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--ke-t1);
  overflow-wrap: anywhere;
}

/* правый значок карточки: у образца там закладка, у нас — возврат к этому шагу */
.ke-card-msg__pin {
  flex: none;
  margin-left: auto;
  color: var(--ke-t3);
}

.ke-card-msg__pin:hover {
  color: var(--ke-t1);
}

/* ───────────── переключатели «Подробности» и «Превью» ───────────── */

.ke-switches {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
  padding: 0 0.75rem 0.625rem;
}

.ke-switch {
  display: inline-flex;
  align-items: center;
  height: 1.5rem;
  padding: 0 0.625rem;
  border: 1px solid var(--ke-line-2);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  color: var(--ke-t2);
  font: inherit;
  font-size: 0.75rem;
  cursor: pointer;
}

.ke-switch:hover {
  background: rgba(255, 255, 255, 0.08);
  color: var(--ke-t1);
}

.ke-switch[aria-expanded='true'] {
  border-color: var(--ke-brand-line);
  background: var(--ke-brand-soft);
  color: var(--ke-brand-light);
}

/*
 * Превью показывает живой проект, то есть последнюю версию. Для прошлого шага
 * оно честно недоступно — кнопка выключена. Но молчать ей нельзя: по нажатию
 * она объясняет словами, почему сейчас нельзя и что делать вместо этого.
 */
.ke-switch[data-off='1'] {
  border-style: dashed;
  color: var(--ke-t4);
  cursor: default;
}

.ke-switch[data-off='1']:hover {
  background: rgba(255, 255, 255, 0.03);
  color: var(--ke-t3);
}

.ke-why {
  margin: 0;
  padding: 0 0.75rem 0.625rem;
  color: var(--ke-t3);
  font-size: 0.75rem;
  line-height: 1.5;
}

/* ───────────── «Подробности»: всё техническое ───────────── */

.ke-tech {
  border-top: 1px solid var(--ke-line);
  background: rgba(0, 0, 0, 0.16);
}

.ke-steps {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.375rem 0.5rem;
}

.ke-tech .ke-meta {
  padding: 0.375rem 0.75rem 0.5rem;
}

/* показ проекта прямо в карточке — только для той версии, что сейчас живая */
.ke-shot {
  border-top: 1px solid var(--ke-line);
  background: #ffffff;
}

.ke-shot__frame {
  display: block;
  width: 100%;
  height: 18rem;
  border: 0;
}

/* ───────────── текст, состояние и действия под карточкой ───────────── */

/* человеческое объяснение: обычный текст, без рамок и без служебного вида */
.ke-say {
  padding: 0.625rem 0.25rem 0;
  color: var(--ke-t1);
  font-size: 0.875rem;
  line-height: 1.6;
}

/* спокойная строка «чем занят прямо сейчас» */
.ke-work {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.25rem 0;
  color: var(--ke-t2);
  font-size: 0.8125rem;
}

.ke-work__text {
  min-width: 0;
  overflow-wrap: anywhere;
}

.ke-acts {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.25rem;
  padding: 0.5rem 0.125rem 0;
}

.ke-act {
  display: inline-flex;
  align-items: center;
  gap: 0.3125rem;
  flex: none;
  height: 1.625rem;
  padding: 0 0.5rem;
  border: 0;
  border-radius: var(--ke-r);
  background: transparent;
  color: var(--ke-t3);
  font: inherit;
  font-size: 0.75rem;
  cursor: pointer;
}

.ke-act:hover {
  background: rgba(255, 255, 255, 0.07);
  color: var(--ke-t1);
}

.ke-acts__ask {
  margin-right: 0.25rem;
  color: var(--ke-t2);
  font-size: 0.75rem;
}

/* тело осталось только у служебных заметок ленты */
.ke-msg__body {
  padding: 0 1rem 0.75rem;
  color: var(--ke-t2);
  font-size: 0.8125rem;
}

.ke-msg__body:empty {
  display: none;
}

.ke-text {
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.ke-text + .ke-text,
.ke-text + .ke-code {
  margin-top: 0.5rem;
}

.ke-code + .ke-text {
  margin-top: 0.5rem;
}

/*
 * Код не переносим по словам: длинная строка честнее прокручивается вбок,
 * чем рвётся посередине пути. Прокрутка своя — наружная вёрстка не едет.
 */
.ke-code {
  max-height: 22rem;
  margin: 0;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--ke-line);
  border-radius: var(--ke-r);
  background: rgba(0, 0, 0, 0.32);
  color: rgba(255, 255, 255, 0.82);
  font-size: 0.75rem;
  line-height: 1.5;
  white-space: pre;
  overflow: auto;
}

.ke-msg__body code.ke-mono,
.ke-note code.ke-mono {
  padding: 0.0625rem 0.25rem;
  border-radius: var(--ke-r-xs);
  background: rgba(255, 255, 255, 0.09);
  color: var(--ke-brand-light);
  font-size: 0.95em;
  overflow-wrap: anywhere;
}

.ke-meta {
  color: var(--ke-t3);
  font-size: 0.6875rem;
  font-variant-numeric: tabular-nums;
}

.ke-msg--user .ke-meta {
  margin-top: 0.25rem;
}

/* рассуждения модели: длинные, поэтому свёрнуты и с потолком по высоте */
.ke-think {
  margin: 0.5rem;
  border: 1px dashed var(--ke-line-2);
  border-radius: var(--ke-r);
  background: rgba(0, 0, 0, 0.22);
}

.ke-think__sum {
  padding: 0.3125rem 0.625rem;
  color: var(--ke-t3);
  font-size: 0.6875rem;
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.ke-think__sum::-webkit-details-marker {
  display: none;
}

.ke-think__sum::before {
  content: '▸ ';
}

.ke-think[open] .ke-think__sum::before {
  content: '▾ ';
}

.ke-think__body {
  max-height: 13rem;
  padding: 0 0.625rem 0.5rem;
  overflow-y: auto;
  color: var(--ke-t3);
  font-size: 0.6875rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ───────────── лента вызовов инструментов ───────────── */

.ke-tools {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.375rem 0.5rem;
}

.ke-tool {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.25rem 0.5rem;
  border-radius: var(--ke-r-sm);
  font-size: 0.75rem;
}

.ke-tool:hover {
  background: rgba(255, 255, 255, 0.04);
}

.ke-tool__name {
  flex: none;
  color: var(--ke-brand-light);
}

/* длинный путь к файлу обязан переноситься, а не раздвигать панель */
.ke-tool__target {
  flex: 1 1 6rem;
  min-width: 0;
  color: var(--ke-t3);
  font-size: 0.6875rem;
  overflow-wrap: anywhere;
}

/* у «читаю логи браузера» цели нет: пустая колонка сталкивала отметку на вторую строку */
.ke-tool__target:empty {
  display: none;
}

.ke-tool__mark {
  display: inline-flex;
  flex: none;
  margin-left: auto;
  color: var(--ke-ok);
}

.ke-tool[data-state='fail'] .ke-tool__mark {
  color: var(--ke-danger);
}

.ke-tool__err {
  flex-basis: 100%;
  max-height: 8rem;
  margin-top: 0.125rem;
  padding: 0.5rem;
  border-radius: var(--ke-r-sm);
  background: var(--ke-danger-soft);
  color: var(--ke-danger);
  font-size: 0.6875rem;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  overflow: auto;
}

/* ───────────── служебные строки ленты ───────────── */

/* успешный шаг: та самая отметка «готово» из макета, но с реальной версией */
.ke-step {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-self: stretch;
  padding: 0.375rem 0.625rem;
  border: 1px solid var(--ke-line);
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.025);
  font-size: 0.6875rem;
}

.ke-step__mark {
  display: grid;
  place-items: center;
  flex: none;
  width: 0.9375rem;
  height: 0.9375rem;
  border-radius: var(--ke-r-xs);
  background: rgba(16, 185, 129, 0.18);
  color: var(--ke-ok);
}

.ke-step__title {
  color: var(--ke-t2);
  font-weight: 600;
}

.ke-step__meta {
  color: var(--ke-t3);
  font-variant-numeric: tabular-nums;
}

.ke-step__ver {
  margin-left: auto;
  padding: 0.0625rem 0.375rem;
  border-radius: var(--ke-r-xs);
  background: rgba(249, 99, 50, 0.14);
  color: var(--ke-brand-light);
}

.ke-note {
  align-self: stretch;
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--ke-line);
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.03);
  color: var(--ke-t2);
  font-size: 0.8125rem;
}

.ke-note .ke-msg__body {
  padding: 0;
  color: inherit;
  font-size: inherit;
}

.ke-note[data-kind='warn'] {
  border-color: var(--ke-brand-line);
  background: rgba(249, 99, 50, 0.1);
  color: #ffcdb6;
}

.ke-note[data-kind='error'] {
  border-color: var(--ke-danger-line);
  background: var(--ke-danger-soft);
  color: var(--ke-danger);
}

.ke-error {
  align-self: stretch;
  padding: 0.75rem 1rem;
  border: 1px solid var(--ke-danger-line);
  border-radius: var(--ke-r-lg);
  background: var(--ke-danger-soft);
}

.ke-error__title {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  color: var(--ke-danger);
  font-size: 0.8125rem;
  font-weight: 600;
}

.ke-error__mark {
  display: grid;
  place-items: center;
  flex: none;
  width: 1rem;
  height: 1rem;
  border-radius: var(--ke-r-xs);
  background: rgba(255, 110, 110, 0.2);
}

.ke-error__text {
  max-height: 14rem;
  margin: 0.375rem 0 0.75rem;
  color: var(--ke-t2);
  font-size: 0.75rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  overflow: auto;
}

.ke-hello {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  align-self: stretch;
  margin: auto 0;
  padding: 2rem 1rem;
  text-align: center;
}

.ke-hello__mark {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--ke-r-lg);
  background: var(--ke-grad);
  color: #ffffff;
}

.ke-hello__title {
  font-size: 0.9375rem;
  font-weight: 600;
}

.ke-hello__sub {
  max-width: 34ch;
  color: var(--ke-t2);
  font-size: 0.8125rem;
  line-height: 1.5;
}

/* ───────────── строка ввода ───────────── */

.ke-composer {
  flex: none;
  padding: 0.75rem;
  border-top: 1px solid var(--ke-line);
  background: var(--ke-panel);
}

.ke-prompt {
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: var(--ke-r-xl);
  background: rgba(255, 255, 255, 0.05);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}

/* кольцо фокуса рисует рамка поля: сам textarea свой контур гасит */
.ke-prompt:focus-within {
  border-color: rgba(249, 99, 50, 0.55);
  box-shadow: 0 0 0 3px rgba(249, 99, 50, 0.16);
}

.ke-input {
  display: block;
  width: 100%;
  /* две строки в покое: подсказка с примером не должна обрезаться на полуслове */
  min-height: 4.25rem;
  max-height: 40vh;
  padding: 0.75rem 1rem;
  border: 0;
  background: transparent;
  color: var(--ke-t1);
  font: inherit;
  font-size: 0.875rem;
  line-height: 1.55;
  caret-color: var(--ke-brand-light);
  resize: none;
  overflow-y: auto;
}

.ke-input:focus,
.ke-input:focus-visible {
  outline: none;
}

.ke-input::placeholder {
  color: var(--ke-t3);
}

.ke-prompt__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0 0.625rem 0.625rem;
}

.ke-mode {
  display: inline-flex;
  gap: 0.125rem;
  padding: 0.125rem;
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.05);
}

.ke-mode__btn {
  padding: 0.1875rem 0.5rem;
  border: 0;
  border-radius: var(--ke-r-sm);
  background: transparent;
  color: var(--ke-t2);
  font: inherit;
  font-size: 0.75rem;
  cursor: pointer;
  transition: background-color 140ms ease, color 140ms ease;
}

.ke-mode__btn[aria-pressed='true'] {
  background: rgba(255, 255, 255, 0.1);
  color: var(--ke-t1);
  font-weight: 600;
}

.ke-send {
  display: grid;
  place-items: center;
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
  border: 0;
  border-radius: var(--ke-r-lg);
  background: rgba(255, 255, 255, 0.08);
  color: var(--ke-t2);
  cursor: pointer;
  transition: background-color 140ms ease, color 140ms ease;
}

/* есть что отправить — кнопка загорается фирменным градиентом */
.ke-send[data-filled='1'] {
  background: var(--ke-grad);
  color: #ffffff;
}

.ke-send[data-busy='1'] {
  background: #e5484d;
  color: #ffffff;
}

.ke-send:disabled {
  opacity: 0.6;
  cursor: default;
}

/* ───────────── превью ───────────── */

.ke-preview__bar {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  flex: none;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--ke-line);
}

.ke-url {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.3125rem 0.625rem;
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.04);
  font-size: 0.75rem;
}

.ke-url__icon {
  display: inline-flex;
  flex: none;
  color: var(--ke-ok);
}

.ke-url__text {
  min-width: 0;
  color: var(--ke-t2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ke-devices {
  display: inline-flex;
  gap: 0.125rem;
  flex: none;
  padding: 0.125rem;
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.05);
}

.ke-device {
  display: grid;
  place-items: center;
  width: 1.875rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  border-radius: var(--ke-r-sm);
  background: transparent;
  color: var(--ke-t2);
  cursor: pointer;
  transition: background-color 140ms ease, color 140ms ease;
}

.ke-device:hover {
  color: var(--ke-t1);
}

.ke-device[aria-pressed='true'] {
  background: rgba(255, 255, 255, 0.1);
  color: var(--ke-t1);
}

.ke-preview__stage {
  display: flex;
  justify-content: center;
  flex: 1 1 auto;
  min-height: 0;
  padding: 1.25rem;
  overflow: auto;
}

.ke-frame {
  display: flex;
  width: 100%;
  max-width: 100%;
  border: 0;
  border-radius: var(--ke-r-xl);
  background: var(--ke-paper);
  box-shadow: 0 20px 60px -20px rgba(0, 0, 0, 0.6);
  overflow: hidden;
}

.ke-frame[data-device='phone'],
.ke-frame[data-device='tablet'] {
  align-self: center;
  height: 100%;
}

.ke-iframe {
  display: block;
  flex: 1 1 auto;
  width: 100%;
  height: 100%;
  border: 0;
  background: #ffffff;
}

.ke-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  margin: auto;
  padding: 1rem;
  text-align: center;
}

.ke-placeholder__mark {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border: 1px solid var(--ke-line-2);
  border-radius: var(--ke-r-xl);
  background: rgba(255, 255, 255, 0.05);
  color: var(--ke-brand-light);
}

.ke-placeholder__title {
  font-size: 0.9375rem;
  font-weight: 600;
}

.ke-placeholder__sub {
  max-width: 34ch;
  margin-bottom: 0.25rem;
  color: var(--ke-t2);
  font-size: 0.8125rem;
  line-height: 1.5;
}

.ke-status {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: none;
  padding: 0.375rem 0.75rem;
  border-top: 1px solid var(--ke-line);
  color: var(--ke-t3);
  font-size: 0.6875rem;
}

.ke-status__dot {
  flex: none;
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: var(--ke-ok);
}

.ke-status[data-state='busy'] .ke-status__dot {
  background: var(--ke-brand);
  animation: ke-pulse 1.2s ease-in-out infinite;
}

.ke-status__text {
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ke-status__ver {
  margin-left: auto;
  flex: none;
  color: var(--ke-t3);
}

/* ───────────── крутилка ───────────── */

.ke-spin {
  display: inline-block;
  flex: none;
  width: 0.75rem;
  height: 0.75rem;
  border: 0.125rem solid rgba(255, 255, 255, 0.18);
  border-top-color: var(--ke-brand-light);
  border-radius: 50%;
  animation: ke-spin 0.7s linear infinite;
}

.ke-placeholder__mark .ke-spin {
  width: 1.25rem;
  height: 1.25rem;
  border-width: 0.1875rem;
}

@keyframes ke-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ───────────── узкий экран ───────────── */

/*
 * Ниже 900px панели встают друг под друга, а ручка начинает тянуть по
 * вертикали (editor.js сам переключает ось). Обе панели растут «от нуля»:
 * иначе длинная переписка съедает высоту и от превью остаётся полоска.
 */
@media (max-width: 56.25rem) {
  .ke-topbar {
    height: auto;
    flex-wrap: wrap;
    padding: 0.5rem 0.75rem;
  }

  .ke-topbar__left {
    flex: 1 1 12rem;
  }

  /*
   * Группа кнопок обязана ПЕРЕНОСИТЬСЯ, а не уезжать за край. Замер на 390 px:
   * шапка 390, содержимое 495 — при `flex: none` группа не сжималась и не
   * переносилась, «Опубликовать» уходила на 464…495 (целиком за экраном) и не
   * нажималась вовсе, а у «Перед запуском» отрезало правую половину. Страница
   * при этом по горизонтали не прокручивается, так что достать их было нечем.
   */
  .ke-topbar__right {
    flex: 1 1 auto;
    flex-wrap: wrap;
    justify-content: flex-end;
    min-width: 0;
  }

  /* подпись не удаляем, а прячем от глаз: скринридеру имя кнопки нужно */
  .ke-refresh .ke-btn__label,
  .ke-open .ke-btn__label,
  .ke-versions-btn .ke-btn__label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .ke-refresh,
  .ke-open,
  .ke-versions-btn {
    padding: 0 0.5rem;
  }

  .ke-chat-head__mode {
    display: none;
  }

  .ke-split {
    flex-direction: column;
  }

  /*
   * Доля чата задаётся flex-basis, а не height: в колоночном флексе высота
   * проигрывает базису, и ручка бы возила ползунок вхолостую.
   */
  .ke-chat-pane {
    width: auto;
    height: auto;
    flex: 0 0 var(--ke-left, 50%);
    border-right: 0;
    border-bottom: 1px solid var(--ke-line);
  }

  .ke-preview {
    flex: 1 1 0;
    min-height: 0;
  }

  .ke-bar {
    width: auto;
    height: 0.375rem;
    margin: -0.1875rem 0;
    cursor: row-resize;
  }

  .ke-bar::after {
    width: 2.5rem;
    height: 0.125rem;
  }

  .ke-preview__stage {
    padding: 0.5rem;
  }

  .ke-msg,
  .ke-msg--user {
    max-width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ke-log {
    scroll-behavior: auto;
  }

  .ke-spin,
  .ke-state[data-state='busy'] .ke-state__dot,
  .ke-status[data-state='busy'] .ke-status__dot,
  .ke-card-msg__pulse {
    animation: none;
  }
}

/* ───────────── публикация ─────────────
 *
 * Блок дописан отдельно и целиком: он ничего не переопределяет у соседей,
 * поэтому его можно снять одним куском, не тронув остальной экран. Панель
 * намеренно повторяет геометрию панели версий (.ke-versions) — это одна и та
 * же «шторка из шапки», и человек не должен разбираться в двух разных.
 */

.ke-publish-wrap {
  position: relative;
  flex: none;
}

/* Первичное действие экрана: у него фирменный цвет, а не белый, как у «Открыть». */
.ke-btn--brand {
  border-color: transparent;
  background: var(--ke-brand);
  color: #fff;
  font-weight: 600;
}

.ke-btn--brand:hover {
  background: #fb7c4d;
}

.ke-btn--brand .ke-btn__icon {
  color: #fff;
}

.ke-btn--brand:disabled {
  background: rgba(249, 99, 50, 0.45);
}

/* Точка «есть неопубликованные изменения»: белая на оранжевой кнопке. */
.ke-publish-dot {
  width: 0.4375rem;
  height: 0.4375rem;
  margin-left: 0.125rem;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 0.1875rem rgba(255, 255, 255, 0.22);
}

.ke-publish {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 30;
  width: min(30rem, 94vw);
  padding: 0.75rem;
  border: 1px solid var(--ke-line-2);
  border-radius: var(--ke-r-lg);
  background: var(--ke-panel);
  box-shadow: 0 1.5rem 4rem rgba(0, 0, 0, 0.6);
}

.ke-publish__body {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  max-height: min(64vh, 34rem);
  overflow-y: auto;
}

.ke-pub-card {
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--ke-line);
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.03);
}

.ke-pub-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ke-t1);
}

.ke-pub-ver {
  margin-left: auto;
  padding: 0.0625rem 0.375rem;
  border-radius: 999px;
  background: rgba(249, 99, 50, 0.16);
  color: var(--ke-brand-light);
  font-size: 0.6875rem;
  font-weight: 500;
}

.ke-pub-sub {
  margin-top: 0.375rem;
  color: var(--ke-t2);
  font-size: 0.75rem;
  line-height: 1.5;
}

.ke-pub-urlrow {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.5rem;
}

.ke-pub-url {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0.25rem 0.5rem;
  border-radius: var(--ke-r-xs);
  background: rgba(255, 255, 255, 0.06);
  color: var(--ke-brand-light);
  font-size: 0.75rem;
  /* Адрес с ключом длинный: рвём его по любому символу, а не прячем в многоточие —
     человек должен видеть, что именно он копирует. */
  overflow-wrap: anywhere;
}

.ke-pub-line {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.375rem;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--ke-line);
  font-size: 0.75rem;
  line-height: 1.5;
}

.ke-pub-line__label {
  font-weight: 600;
}

.ke-pub-line__value {
  color: var(--ke-t2);
}

.ke-pub-line[data-kind='warn'] .ke-pub-line__label {
  color: var(--ke-brand-light);
}

.ke-pub-line[data-kind='ok'] .ke-pub-line__label {
  color: var(--ke-ok);
}

.ke-pub-legal[data-kind='block'] {
  border-color: var(--ke-danger-line);
  background: var(--ke-danger-soft);
}

.ke-pub-legal[data-kind='block'] .ke-pub-title {
  color: var(--ke-danger);
}

.ke-pub-legal__list {
  margin: 0.5rem 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.ke-pub-legal__what {
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--ke-t1);
}

.ke-pub-legal__how {
  font-size: 0.6875rem;
  line-height: 1.5;
  color: var(--ke-t2);
}

.ke-pub-legal__where {
  font-size: 0.6875rem;
  color: var(--ke-t3);
  overflow-wrap: anywhere;
}

.ke-pub-legal__more {
  font-size: 0.6875rem;
  color: var(--ke-t3);
}

.ke-pub-error {
  border-color: var(--ke-danger-line);
  background: var(--ke-danger-soft);
  color: var(--ke-danger);
  font-size: 0.75rem;
  line-height: 1.5;
}

.ke-pub-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.5rem;
}

.ke-pub-main {
  height: 2rem;
  padding: 0 0.875rem;
}

.ke-pub-history {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.ke-pub-history .ke-pub-title {
  margin-bottom: 0.125rem;
}

.ke-pub-meta {
  margin-bottom: 0.5rem;
  color: var(--ke-t3);
  font-size: 0.6875rem;
}

@media (max-width: 56.25rem) {
  /* подпись прячем от глаз, но не от скринридера — как у соседних кнопок шапки */
  .ke-publish-btn .ke-btn__label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .ke-publish-btn {
    padding: 0 0.5rem;
  }

  .ke-publish {
    /* На узком экране шторка от края до края: 30rem справа уезжали бы за экран. */
    right: auto;
    left: 0;
    width: min(30rem, calc(100vw - 1.5rem));
  }
}

/* =============================================================================
   ХОД РАБОТЫ, ОШИБКИ И ТЕЛЕФОН

   Блок дописан целиком и ничего у соседей не переопределяет, кроме того, что
   названо в комментариях. Разделён на три части: полоса хода работы, карточка
   отказа с действием и режим одной панели на узком экране.
   ============================================================================= */

/* ───────────── 1. Ход работы ─────────────
 *
 * Семнадцать минут сборки — главное место, где теряют человека. Раньше он
 * видел здесь одну строку со спиннером и не знал ни сколько ждать, ни сколько
 * уже сделано. Теперь блок отвечает на четыре вопроса подряд: сколько идёт,
 * сколько обычно, что прямо сейчас, что уже готово.
 */

.ke-prog {
  margin-top: 0.625rem;
  padding: 0.625rem 0.75rem 0.5rem;
  border: 1px solid var(--ke-line-2);
  border-radius: var(--ke-r-lg);
  background: rgba(255, 255, 255, 0.03);
}

.ke-prog__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.ke-prog__phase {
  color: var(--ke-t1);
  font-size: 0.8125rem;
  font-weight: 600;
}

/* Цифры времени тикают раз в секунду: без табличных цифр строка дрожит. */
.ke-prog__time {
  flex: none;
  color: var(--ke-t2);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.ke-prog__track {
  height: 0.25rem;
  margin: 0.5rem 0 0.375rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.09);
  overflow: hidden;
}

.ke-prog__fill {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--ke-grad);
  /* Плавность нужна: шаг раз в секунду скачками читается как рывки. */
  transition: width 900ms linear;
}

.ke-prog__note {
  color: var(--ke-t3);
  font-size: 0.6875rem;
  line-height: 1.45;
}

/* Строка «чем занят прямо сейчас» живёт внутри блока: отступ сверху её же. */
.ke-prog .ke-work {
  padding-top: 0.4375rem;
}

/* Единственная строка, снимающая главный страх долгого ожидания. Она заметнее
   остальных подписей намеренно: её должны прочитать, а не проглядеть. */
.ke-prog__stay {
  margin-top: 0.4375rem;
  padding-top: 0.4375rem;
  border-top: 1px dashed var(--ke-line-2);
  color: var(--ke-t2);
  font-size: 0.6875rem;
  line-height: 1.45;
}

.ke-prog__label {
  margin-top: 0.5rem;
  color: var(--ke-t3);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.ke-prog__more {
  margin-top: 0.25rem;
  color: var(--ke-t3);
  font-size: 0.6875rem;
}

.ke-prog__done {
  margin: 0.25rem 0 0;
  padding: 0;
  list-style: none;
}

.ke-prog__item {
  display: flex;
  align-items: flex-start;
  gap: 0.375rem;
  padding: 0.0625rem 0;
  color: var(--ke-t2);
  font-size: 0.75rem;
  line-height: 1.45;
}

.ke-prog__tick {
  display: grid;
  place-items: center;
  flex: none;
  margin-top: 0.0625rem;
  color: var(--ke-ok);
}

/* ───────────── 2. Отказ с ответом «что делать» ─────────────
 *
 * Кнопка действия обязательна: карточка, которая только сообщает о беде и
 * ничего не предлагает, — тупик.
 */

.ke-error__acts {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.625rem;
}

.ke-error__more {
  margin-top: 0.625rem;
  color: var(--ke-t3);
  font-size: 0.6875rem;
}

.ke-error__more > summary {
  cursor: pointer;
  padding: 0.125rem 0;
}

.ke-error__raw {
  max-height: 10rem;
  margin-top: 0.375rem;
  color: var(--ke-t3);
  font-size: 0.6875rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  overflow: auto;
}

/* Объяснение больше не техническое, поэтому и выглядит как текст, а не как
   лог: моноширинный шрифт с него снят там, где он ставился разметкой. */
.ke-error__text {
  font-size: 0.8125rem;
}

/* ───────────── 3. Вкладки: одна панель на телефоне ─────────────
 *
 * На широком экране вкладок нет вовсе. Ниже 48rem (768 px) две панели рядом
 * не помещаются: замер на 390×844 дал ленте переписки 129 px высоты, то есть
 * две строки. Поэтому там видна ровно одна панель, а переключает их этот ряд.
 */

.ke-tabs {
  display: none;
  flex: none;
  gap: 0.25rem;
  padding: 0.375rem 0.5rem;
  background: var(--ke-surface);
  border-bottom: 1px solid var(--ke-line);
}

.ke-tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  flex: 1 1 0;
  min-height: 2.75rem; /* 44 px — минимум под палец */
  border: 0;
  border-radius: var(--ke-r);
  background: transparent;
  color: var(--ke-t2);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
}

.ke-tab[aria-selected='true'] {
  background: rgba(255, 255, 255, 0.08);
  color: var(--ke-t1);
}

/* Точка «есть обновление»: превью уехало вперёд, пока смотрели в чат. */
.ke-tab__dot {
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  background: var(--ke-brand);
}

@media (max-width: 47.9375rem) {
  .ke-tabs {
    display: flex;
  }

  /*
   * Шторки «Версии» и «Публикация» на телефоне — снизу, во всю ширину.
   *
   * Так они были выпадашками под кнопкой (`right: 0` от своей обёртки), и на
   * узкой шапке, которая переносится на две строки, кнопка оказывалась почти
   * посередине: замер на 390 дал левый край панели версий на -86, то есть
   * восемьдесят шесть точек уезжали за экран. Привязка к нижнему краю окна
   * снимает зависимость от того, где именно оказалась кнопка.
   */
  .ke-versions,
  .ke-publish {
    position: fixed;
    top: auto;
    right: 0;
    /* Не «в самый низ», а над клавиатурой: --k-kb ведёт app.js по
       visualViewport, и без него шторка, открытая при активном поле ввода,
       наполовину оказалась бы под клавиатурой. На настольном браузере ноль. */
    bottom: var(--k-kb, 0px);
    left: 0;
    width: auto;
    max-height: 80vh;
    padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
    border-width: 1px 0 0;
    border-radius: var(--ke-r-xl) var(--ke-r-xl) 0 0;
    overflow-y: auto;
  }

  /* Потолок списка теперь задаёт сама шторка: 50vh внутри 80vh обрезали бы его
     вдвое раньше срока. */
  .ke-versions__list {
    max-height: none;
  }

  /* Ручка размера панелей на вкладках бессмысленна: панель всегда одна. */
  .ke-bar {
    display: none;
  }

  .ke-split {
    flex-direction: column;
  }

  /* Видна ровно одна панель, и она занимает всё, что осталось от экрана. */
  .ke-screen[data-pane='chat'] .ke-preview,
  .ke-screen[data-pane='preview'] .ke-chat-pane {
    display: none;
  }

  .ke-chat-pane,
  .ke-preview {
    width: auto;
    height: auto;
    flex: 1 1 0;
    min-height: 0;
    border-right: 0;
    border-bottom: 0;
  }

  /* Заголовок «Чат с Рондом» дублирует вкладку — убираем, высота дорога. */
  .ke-chat-head {
    display: none;
  }

  .ke-topbar {
    padding: 0.25rem 0.5rem;
  }

  /*
   * Низ формы. Отступ снизу складывается из «подбородка» телефона и высоты
   * клавиатуры: оболочка уже сжата переменной --k-app-h (её ведёт app.js), а
   * здесь добирается запас, чтобы кнопка отправки не липла к самой кромке.
   */
  .ke-composer {
    padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
  }

  /* Полоса состояния под превью на телефоне съедает строку, а повторяет то же,
     что уже сказано в шапке. */
  .ke-status {
    display: none;
  }
}

/*
 * Мишени под палец. Порог ДРУГОЙ, чем у вкладок: ровно 768 px (48rem) —
 * это планшет в портрете, где две панели ещё помещаются, а мышь уже не
 * подразумевается. Поэтому раскладка там прежняя, а кнопки уже крупные.
 */
@media (max-width: 48rem) {
  .ke-screen :where(.ke-btn, .ke-iconbtn, .ke-device, .ke-send, .ke-mode__btn, .ke-act, .ke-switch) {
    min-height: 2.75rem;
  }

  .ke-screen :where(.ke-iconbtn, .ke-device, .ke-send) {
    min-width: 2.75rem;
  }
}

/*
 * Клавиатура открыта. Экрана осталось совсем мало, и ряд вкладок уходит с глаз:
 * пока человек печатает, он и так в чате, переключаться ему некуда.
 * Шапку при этом НЕ прячем — через неё уходят с экрана, и отнимать выход
 * у того, кто просто открыл клавиатуру, нельзя.
 */
@media (max-width: 47.9375rem) {
  :root[data-keyboard='open'] .ke-tabs {
    display: none;
  }
}

/* ─────────────────────── ключи интеграций ─────────────────────── */

/*
 * Панель, куда владелец сайта вписывает токен бота, номер чата, ключ кассы.
 * Появилась после живого случая: агент честно предложил «впишите ключ в файл
 * .env внутри проекта», и человек ответил, что это «не для казуального юзера».
 * Значения идут прямо на сервер, мимо модели.
 */

.ke-keys-wrap {
  position: relative;
}

.ke-keys {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 40;
  width: min(26rem, calc(100vw - 2rem));
  max-height: min(32rem, calc(100vh - 6rem));
  display: flex;
  flex-direction: column;
  background: var(--ke-surface);
  border: 1px solid var(--ke-line-2);
  border-radius: var(--ke-r-lg);
  box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.55);
  overflow: hidden;
}

.ke-keys__body {
  padding: 0.75rem 1rem 1rem;
  overflow: auto;
}

/* Точка на кнопке: горит, пока обязательное поле пустует. */
.ke-keys-dot {
  width: 0.4rem;
  height: 0.4rem;
  border-radius: 50%;
  background: var(--ke-brand);
  margin-left: 0.35rem;
  flex: none;
}

.ke-keys__group + .ke-keys__group {
  margin-top: 1.25rem;
  padding-top: 1rem;
  border-top: 1px solid var(--ke-line);
}

.ke-keys__title {
  margin: 0 0 0.5rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ke-t1);
}

.ke-keys__field {
  display: block;
  margin-bottom: 0.875rem;
}

.ke-keys__what {
  display: block;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ke-t2);
  margin-bottom: 0.375rem;
}

.ke-keys__ok {
  color: var(--ke-ok);
  font-weight: 600;
}

.ke-keys__need {
  color: var(--ke-brand);
  font-weight: 600;
}

.ke-keys__input {
  width: 100%;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--ke-line-2);
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.04);
  color: var(--ke-t1);
  font-family: var(--ke-font-mono);
  font-size: 0.8125rem;
}

.ke-keys__input:focus {
  outline: 2px solid var(--ke-focus);
  outline-offset: 1px;
}

/* Где взять значение — самая нужная строка для того, кто видит это впервые. */
.ke-keys__where {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--ke-t3);
  overflow-wrap: anywhere;
}

.ke-keys__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.5rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--ke-line);
}

.ke-keys__status {
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--ke-t3);
}

/* ─────────────────────── страницы сайта над превью ─────────────────────── */

/*
 * Здесь стоял адрес dev-сервера. Он не нужен владельцу сайта: адреса он не
 * набирает, про порты не знает. Полезен переход на свою страницу — им и стал
 * этот список.
 */

.ke-pages {
  display: flex;
  align-items: center;
  min-width: 0;
  margin-right: auto;
}

.ke-pages__select {
  max-width: 16rem;
  padding: 0.3rem 0.5rem;
  border: 1px solid var(--ke-line-2);
  border-radius: var(--ke-r);
  background: rgba(255, 255, 255, 0.04);
  color: var(--ke-t1);
  font-family: inherit;
  font-size: 0.8125rem;
  line-height: 1.2;
  cursor: pointer;
}

.ke-pages__select:hover {
  border-color: var(--ke-line-2);
  color: #fff;
}

.ke-pages__select:focus {
  outline: 2px solid var(--ke-focus);
  outline-offset: 1px;
}

/* Список раскрывается системным меню — там свой фон, а не наш тёмный. */
.ke-pages__select option {
  background: var(--ke-surface);
  color: var(--ke-t1);
}

/* ─────────────────────── поле ввода: скрепка и отправка ─────────────────── */

/*
 * Слева прикрепить, справа отправить — привычный порядок переписки.
 * Раньше слева стоял выбор «правка / вопрос», а он требовал от человека
 * решения, которое принимает агент.
 */

.ke-clip {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 0;
  border-radius: var(--ke-r);
  background: transparent;
  color: var(--ke-t3);
  cursor: pointer;
  transition: color 120ms ease, background-color 120ms ease;
}

.ke-clip:hover {
  color: var(--ke-t1);
  background: rgba(255, 255, 255, 0.06);
}

.ke-clip:focus-visible {
  outline: 2px solid var(--ke-focus);
  outline-offset: 1px;
}

/* Отправка прижата вправо, что бы ни стояло слева. */
.ke-prompt__row .ke-send {
  margin-left: auto;
}

/* ─────────────────────────── заявки с сайта ─────────────────────────── */

/*
 * Форма на сайте работает без настроек: приём взяла на себя платформа, заявка
 * ложится в архив проекта всегда. Эта панель показывает архив — без неё
 * заявки приходили бы в файл, которого никто не видит.
 */

.ke-leads-wrap {
  position: relative;
}

.ke-leads {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  z-index: 40;
  width: min(26rem, calc(100vw - 2rem));
  max-height: min(32rem, calc(100vh - 6rem));
  display: flex;
  flex-direction: column;
  background: var(--ke-surface);
  border: 1px solid var(--ke-line-2);
  border-radius: var(--ke-r-lg);
  box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.55);
  overflow: hidden;
}

.ke-leads__body {
  padding: 0.75rem 1rem 1rem;
  overflow: auto;
}

/* Сколько заявок пришло — видно, не открывая панель. */
.ke-leads-count {
  margin-left: 0.35rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--ke-brand);
  color: #fff;
  font-size: 0.6875rem;
  line-height: 1.35;
}

.ke-lead + .ke-lead {
  margin-top: 0.875rem;
  padding-top: 0.875rem;
  border-top: 1px solid var(--ke-line);
}

.ke-lead__at {
  margin: 0 0 0.35rem;
  font-size: 0.75rem;
  color: var(--ke-t4);
}

.ke-lead__row {
  margin: 0 0 0.2rem;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--ke-t1);
  overflow-wrap: anywhere;
}

.ke-lead__title {
  color: var(--ke-t3);
}
