/* ============================================================
   Я зову — полноэкранный редактор приглашения
   ------------------------------------------------------------
   Своя компоновка на весь экран: шапка, три области, холст в
   середине. Токены — общие с сайтом; отдельной дизайн-системы
   у редактора нет и быть не должно, иначе он через полгода
   станет другим сайтом внутри сайта.

   ПОЧЕМУ ФОН РАБОЧЕЙ ОБЛАСТИ СЕРО-СИРЕНЕВЫЙ, А ПАНЕЛИ БЕЛЫЕ

   Приглашение почти всегда светлое. На белом фоне его край
   теряется, и человек не понимает, где кончается лист и
   начинается страница, — а именно край он и двигает. Панели при
   этом белые: они инструмент, а не предмет, и спорить с
   карточкой за внимание им нечем.
   ============================================================ */

.yz-editor-page {
  margin: 0;
  background: var(--ed-stage);
  overflow: hidden;              /* прокручиваются области, а не страница */
}

.ed2 {
  --ed-stage: #F4F3F9;
  --ed-line: #E9E4F2;
  --ed-pick: #7562F3;
  --ed-pick-soft: color-mix(in oklab, #7562F3 12%, transparent);

  display: flex;
  flex-direction: column;

  /* ВЫСОТА — ЗА ВЫЧЕТОМ ТОГО, ЧТО ЗАКРЫЛА КЛАВИАТУРА

     На телефоне экранная клавиатура занимает нижнюю треть
     экрана, но 100dvh об этом не знает: в Safari при её
     появлении меняется только видимая часть окна (visualViewport),
     а вёрстка остаётся прежней высоты. Нижняя панель редактора
     стоит как раз внизу — то есть уезжает под клавиатуру вместе
     с полем, в которое человек в эту секунду печатает. Пролистать
     к нему нельзя: страница редактора не прокручивается вовсе.

     --ed-kb ставит скрипт по visualViewport. Там, где браузер
     ужимает саму вёрстку (Android с resizes-content), скрытого
     не остаётся, переменная равна нулю, и dvh справляется сам —
     правило верно в обоих случаях без развилки. */
  height: calc(100dvh - var(--ed-kb, 0px));
  background: var(--ed-stage);
}

/*
 * ВЫСОТА ШАПКИ ОБЪЯВЛЕНА НА КОРНЕ, А НЕ НА .ed2
 *
 * Её читает не только редактор: плашка о куки лежит прямым
 * ребёнком body, рядом с .ed2, а не внутри него, и переменную с
 * .ed2 не наследует. Объявленная там, она давала плашке
 * `top: calc(var(--ed-top) + .5rem)` с неизвестной переменной —
 * то есть недействительное правило целиком, вместе с `bottom`, и
 * плашка уезжала в самый низ документа, за край экрана.
 *
 * Этот файл подключается только на адресе редактора
 * (Yzt_Assets, по Yzt_Editor::on), так что :root здесь — это
 * корень одной страницы, а не всего сайта.
 */
:root { --ed-top: 68px }

/* ---------- шапка ---------- */
.ed2-top {
  display: flex;
  align-items: center;
  gap: .8rem;
  flex: 0 0 auto;
  height: var(--ed-top);
  padding: 0 1rem;
  background: var(--card);
  border-bottom: 1px solid var(--ed-line);
}
.ed2-logo { flex: 0 0 auto; margin-right: .2rem }

.ed2-back,
.ed2-name { font-size: .92rem }
.ed2-back {
  display: inline-flex; align-items: center; gap: .2rem;
  color: var(--ink-2); text-decoration: none; white-space: nowrap;
  padding: .4rem .5rem; border-radius: 10px;
}
.ed2-back:hover { color: var(--ink); background: var(--paper-2) }
.ed2-back svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round }
.ed2-name { font-weight: 600; white-space: nowrap }

/* Разделитель между «К шаблону» и названием — тонкая черта, а
   не отступ: без неё две строки читаются как одна фраза. */
.ed2-back::after {
  content: ""; width: 1px; height: 1.1rem; margin-left: .55rem;
  background: var(--ed-line);
}

.ed2-saved {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: .84rem; color: var(--ink-3); white-space: nowrap;
}
.ed2-saved svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: #2E9E6B; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round }

/* ДВЕ СТРОКИ, И ВТОРАЯ ПОЯВЛЯЕТСЯ САМА

   Владелец попросил под надписью мелкое «сегодня в 12:26».
   Строка пустая до первого сохранения в этом заходе, и пока она
   пуста — блок ровно той же высоты, что был: пустой <span> без
   содержимого не занимает ни строки. Резервировать под неё место
   заранее значило бы поднять надпись на три точки вверх у всех,
   кто ничего не правил. */
.ed2-saved-b { display: flex; flex-direction: column; line-height: 1.25; min-width: 0 }
.ed2-saved-when:not(:empty) { font-size: .74rem; color: var(--ink-3); opacity: .85 }
/* Три состояния, и «сохранено» — только когда правда сохранено. */
.ed2-saved[data-state="dirty"] svg { stroke: var(--ink-3) }
.ed2-saved[data-state="err"]   svg { stroke: var(--brick) }
.ed2-saved[data-state="err"]   { color: var(--brick) }

.ed2-top-r { display: flex; align-items: center; gap: .45rem; margin-left: auto }

.ed2-ico {
  display: grid; place-items: center; width: 40px; height: 40px;
  border: 0; background: none; border-radius: 10px; cursor: pointer; color: var(--ink-2);
}
.ed2-ico:hover:not([disabled]) { background: var(--paper-2); color: var(--ink) }
.ed2-ico:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-ico[disabled] { opacity: .35; cursor: default }
.ed2-ico svg { width: 1.2rem; height: 1.2rem; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round }

.ed2-eye svg, .ed2-buy svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }
.ed2-eye, .ed2-buy { gap: .4rem; white-space: nowrap }

/* КНОПКА, КОТОРАЯ УЖЕ РАБОТАЕТ, ВЫГЛЯДИТ ЗАНЯТОЙ

   «К покупке» кладёт в корзину и только потом уходит, то есть
   между нажатием и переходом есть запрос. На широком экране об
   этом говорит подпись («Кладём в корзину…»), а на узком подписи
   у кнопок нет вовсе — остаётся одна стрелка, и нажавший её
   человек видит ровно ничего. Гасим саму кнопку: это читается на
   любой ширине и заодно не даёт нажать второй раз. */
.ed2-buy[aria-busy="true"] { opacity: .65; pointer-events: none }

/* ---------- три области ---------- */
.ed2-body {
  flex: 1 1 auto;
  display: grid;

  /* minmax НА ВСЕ ТРИ КОЛОНКИ, А НЕ ТОЛЬКО НА СРЕДНЮЮ

     Боковые стояли жёсткими: 280 и 300. Пока ширина окна больше
     их суммы, разницы нет; как только меньше — сетка не
     ужимается, а вылезает, и правая панель уходит за край.
     Уходит молча: страница редактора не прокручивается
     (overflow:hidden у body), то есть до обрезанной панели ещё и
     не дотянуться.

     Проверить это здесь нельзя: у Chromium в этой среде полосы
     прокрутки ПЛАВАЮЩИЕ и занимают ноль точек, а у человека на
     Windows — обычные, пятнадцать. Ровно на эти пятнадцать
     содержимое и не влезает. Поэтому не «померили и починили», а
     «сделали неспособным вылезти»: с minmax сетка ужимает
     колонки вместо того, чтобы выйти за контейнер. */
  grid-template-columns: minmax(0, 280px) minmax(0, 1fr) minmax(0, 300px);
  min-height: 0;
  overflow: hidden;
}

.ed2-left, .ed2-right {
  background: var(--card);
  overflow-y: auto;
  padding: 1rem .9rem 2rem;
  display: flex; flex-direction: column; gap: 1.1rem;
}
.ed2-left  { border-right: 1px solid var(--ed-line) }
.ed2-right { border-left: 1px solid var(--ed-line) }

.ed2-block { display: flex; flex-direction: column; gap: .45rem }
.ed2-block--grow { flex: 1 1 auto; min-height: 0 }

.ed2-h {
  margin: 0 0 .15rem;
  font-size: 1.05rem; font-weight: 700; letter-spacing: -.01em;
}

/* Кнопки добавления белые с обводкой: красный на этой странице
   означает покупку, и больше ничего. */
/* ---------- полоска загруженных снимков ---------- */
/* Миниатюры квадратные и мелкие: это напоминание о том, что
   лежит на сервере, а не галерея. Выбранный обведён той же
   рамкой, которой в редакторе помечено всё выбранное.

   Крестик стоит в углу самой миниатюры, а не отдельной строкой:
   отдельная строка под каждым снимком вдвое удлинила бы полоску
   ради действия, которое делают раз. */
.ed2-fotos { margin: 0 0 .7rem }
.ed2-fotos__row { display: flex; gap: .5rem; flex-wrap: wrap }
.ed2-foto { position: relative; width: 56px; height: 56px }
.ed2-foto__b {
  width: 100%; height: 100%; padding: 0; cursor: pointer;
  border: 2px solid transparent; border-radius: 10px; overflow: hidden;
  background: var(--ed-bg2, #f4f4f7);
}
.ed2-foto__b img { width: 100%; height: 100%; object-fit: cover; display: block }
.ed2-foto--on .ed2-foto__b { border-color: var(--ed-pick) }
.ed2-foto__b:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-foto__x {
  position: absolute; top: -6px; right: -6px; width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--ed-line, #dcdce4); border-radius: 50%;
  background: var(--ed-panel, #fff); color: var(--ed-ink2, #555);
  font-size: 14px; line-height: 1; cursor: pointer; padding: 0;
}
.ed2-foto__x:hover { color: #c0392b; border-color: #c0392b }
.ed2-foto__x:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 1px }
@media (max-width: 860px) {
  /* Мишень пальца: 56 точек у миниатюры хватает, а крестик
     вырастает до того же порога, что и прочие мелкие кнопки. */
  .ed2-foto__x { width: 28px; height: 28px; top: -8px; right: -8px; font-size: 17px }
}

.ed2-add {
  display: flex; align-items: center; gap: .55rem;
  min-height: 44px; padding: .5rem .7rem;
  border: 1px solid var(--rule-2); border-radius: 12px;
  background: var(--card); color: var(--ink);
  font: inherit; font-size: .9rem; text-align: left; cursor: pointer;
}
.ed2-add:hover { border-color: var(--ed-pick); color: var(--ed-pick) }
.ed2-add:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-add svg { width: 1.15rem; height: 1.15rem; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }

/* ---------- «Добавить»: список строк, а не стопка кнопок ----------

   §4 ТЗ: блок занимал слишком много высоты. Пять кнопок в
   рамках по 44 точки с зазорами — 205 точек на действия,
   которые делают раз или два за работу. Четыре строки без
   рамок — 160. Померено на стенде, а не посчитано на бумаге:
   первая же арифметика дала 249 и оказалась неверной.

   Рамку убрали не ради красоты: рамка вокруг каждой строки
   списка спорит сама с собой, и пять таких читаются как пять
   отдельных предметов, а не как один перечень. */
.ed2-put { list-style: none; margin: 0; padding: 0 }
.ed2-put > li { display: block }
.ed2-put-b {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  min-height: 40px; padding: .4rem .55rem;
  border: 0; border-radius: 10px;
  background: none; color: var(--ink);
  font: inherit; font-size: .92rem; text-align: left; cursor: pointer;
}
.ed2-put-b > span { flex: 1 1 auto }
.ed2-put-b:hover { background: var(--ed-pick-soft); color: var(--ed-pick) }
.ed2-put-b:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: -2px }
.ed2-put-b[disabled] { opacity: .45; cursor: default }
.ed2-put-b[disabled]:hover { background: none; color: var(--ink) }
.ed2-put-b svg {
  width: 1.15rem; height: 1.15rem; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
/* Шеврон говорит «здесь раскроется», а не «здесь произойдёт».
   У «Фото» он тоже есть: там раскрывается выбор файла системы —
   для человека это то же самое продолжение. */
.ed2-put-x { width: 1rem !important; height: 1rem !important; opacity: .45 }
.ed2-put-b[aria-expanded="true"] .ed2-put-x { transform: rotate(90deg); opacity: .8 }

/* Пальцем попадают в нижний лист на узком экране, и сорок
   четыре точки там не запас, а минимум. Высоту экономим только
   там, где указывают мышью. */
@media (pointer: coarse) {
  .ed2-put-b { min-height: 44px }
}

/* Три вида текста. Раскрываются под строкой — как наборы
   стикеров: окно поверх холста закрыло бы само приглашение, то
   есть то, на что человек смотрит, решая, что добавить. */
.ed2-texts {
  display: flex; flex-direction: column; gap: .15rem;
  margin: .1rem 0 .3rem; padding: .3rem 0 .3rem 2.3rem;
}
.ed2-text-v {
  min-height: 36px; padding: .35rem .55rem;
  border: 0; border-radius: 9px;
  background: none; color: var(--ink);
  font: inherit; font-size: .88rem; text-align: left; cursor: pointer;
}
.ed2-text-v:hover { background: var(--ed-pick-soft); color: var(--ed-pick) }
.ed2-text-v:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: -2px }
.ed2-text-v[disabled] { opacity: .45; cursor: default }
.ed2-text-v[disabled]:hover { background: none; color: var(--ink) }
/* Набран так, как встанет на лист: вид текста выбирают глазами,
   а не по названию. Тот же приём, что в списке шрифтов. */
.ed2-text-v--head { text-transform: uppercase; letter-spacing: .12em; font-size: .9rem; font-weight: 600 }
.ed2-text-v--sub { font-size: .95rem }
/* Цветом пункты НЕ красим, хотя на листе заголовок и
   подзаголовок берут цвет дизайна. Цвет этот у каждого дизайна
   свой и живёт на самой карточке (--c-acc), до панели не
   доходит; покрасить их фиолетовым редактора значило бы
   пообещать фиолетовый текст. Панель показывает НАБОР —
   прописные, размер, — а цвет человек увидит на листе через
   секунду после нажатия. */
@media (pointer: coarse) {
  .ed2-text-v { min-height: 40px }
}

/* ---------- слои ---------- */
.ed2-layers { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .3rem }
.ed2-lay {
  display: flex; align-items: center; gap: .5rem;
  min-height: 44px; padding: .35rem .5rem;
  border-radius: 10px; cursor: pointer; color: var(--ink-2); font-size: .88rem;
}
.ed2-lay:hover { background: var(--paper-2) }
.ed2-lay[aria-selected="true"] { background: var(--ed-pick-soft); color: var(--ink); font-weight: 500 }
.ed2-lay:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: -2px }
.ed2-lay-i { width: 1.05rem; height: 1.05rem; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }
.ed2-lay-t { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
/* Замок у заблокированных: фон и рамка принадлежат дизайну, и
   двигать их человек не вправе — но видеть, что они есть, должен. */
.ed2-lay--lock { color: var(--ink-3); cursor: default }
.ed2-lay--lock:hover { background: none }

/* ---------- глаз и замок в строке слоя ----------
   Появляются при наведении и при фокусе, а нажатые — всегда:
   спрятанная строка обязана говорить о себе, что она спрятана,
   даже когда курсор в другом конце экрана. Иначе человек ищет
   пропавшую надпись на листе, а она в списке с перечёркнутым
   глазом, которого не видно.

   Сорок четыре точки в высоту у самой строки; кнопки внутри
   меньше, и это единственное место, где так можно: обе стоят в
   ряду с настоящей целью нажатия — самой строкой, — и промах по
   кнопке попадает в неё, а не в пустоту. */
.ed2-lay-b {
  flex: none; display: grid; place-items: center;
  width: 30px; height: 30px; padding: 0;
  border: 0; border-radius: 8px; background: none;
  color: var(--ink-3); cursor: pointer;
  opacity: 0;
}
.ed2-lay-b svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }
.ed2-lay:hover .ed2-lay-b,
.ed2-lay:focus-within .ed2-lay-b,
.ed2-lay-b[aria-pressed="true"],
.ed2-lay-b:focus-visible { opacity: 1 }
.ed2-lay-b:hover { background: var(--paper-2); color: var(--ink) }
.ed2-lay-b[aria-pressed="true"] { color: var(--ed-pick) }
.ed2-lay-b:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: -2px }

/* Спрятанная строка приглушена, но читается: она остаётся
   единственной дорогой обратно. Запертая — обычного цвета:
   замок не прячет, он запрещает трогать. */
.ed2-lay[data-hidden] .ed2-lay-t,
.ed2-lay[data-hidden] .ed2-lay-i { opacity: .5 }
.ed2-lay[data-hidden] .ed2-lay-t { text-decoration: line-through; text-decoration-thickness: 1px }
.ed2-lay[data-locked] { cursor: default }
.ed2-lay[data-locked] .ed2-lay-t { color: var(--ink-3) }

@media (prefers-reduced-motion: no-preference) {
  .ed2-lay-b { transition: opacity .12s ease, background .12s ease, color .12s ease }
}

/* Дорога назад к слоям — только на узком экране, где панели не
   помещаются рядом. На широком обе видны, и кнопка «Все слои»
   рядом со списком слоёв означала бы, что список куда-то делся. */
.ed2-back-lay {
  display: none;
  align-items: center; gap: .3rem;
  align-self: flex-start;
  min-height: 40px; padding: .35rem .6rem .35rem .35rem;
  border: 0; border-radius: 10px; background: none;
  color: var(--ink-2); font: inherit; font-size: .88rem; cursor: pointer;
}
.ed2-back-lay:hover { background: var(--paper-2); color: var(--ink) }
.ed2-back-lay:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-back-lay svg { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round }

/* ============================================================
   РУЧКА НИЖНЕГО ЛИСТА
   ------------------------------------------------------------
   На широком экране её нет совсем, а не «спрятана прозрачностью»:
   панели там стоят по бокам и тянуть нечего. Узел при этом
   остаётся в разметке — иначе он был бы ЧЕТВЁРТЫМ элементом
   сетки из трёх колонок и сдвигал бы всё вправо: левая панель
   уезжала во вторую колонку, правая переносилась на новую
   строку. Так оно и выглядело до этого правила.
   ============================================================ */
.ed2-grip { display: none }

/* ============================================================
   ПЛАШКА О КУКИ УХОДИТ ИЗ УГЛА НАВЕРХ
   ------------------------------------------------------------
   Она стоит в левом нижнем углу — на сайте там пусто, а в
   редакторе ровно там панель с органами управления. Замерено:
   на 1366 точках плашка накрывает низ правой панели, на 390 —
   ложится поверх выбора шрифта. Человек видит список, нажимает —
   и попадает в «Подробнее».

   Спрятать её здесь было бы нечестно: плашка сообщает факт и
   обязана быть видна. Поэтому не прячем, а переносим под шапку —
   в единственное место редактора, где нет ни одной кнопки. Она
   ложится на приглашение, но на приглашение смотрят, а не
   нажимают, и уходит она одним касанием.

   На узком экране растягивается на всю ширину: карточка в
   23 rem там и так занимает почти всё, а прижатая к левому краю
   выглядит уехавшей.
   ============================================================ */
body:has(.ed2) .cookie {
  left: 50%; right: auto; bottom: auto;
  top: calc(var(--ed-top) + .55rem);
  transform: translateX(-50%);
}
@media (max-width: 899px) {
  body:has(.ed2) .cookie {
    left: .6rem; right: .6rem;
    transform: none; max-width: none;
  }
}

/* ============================================================
   ЩИПОК НА КАРТОЧКЕ — НАШ, А НЕ БРАУЗЕРНЫЙ
   ------------------------------------------------------------
   Без touch-action два пальца на приглашении масштабируют всю
   страницу средствами браузера, и до наших событий дело не
   доходит вовсе: редактор растягивается вместе с шапкой, а
   вернуть его обратно можно только тем же жестом наугад.

   Правило стоит на карточке ЦЕЛИКОМ, а не только на строках и
   снимке (у тех своё, в product.css): второй палец приходит
   куда придётся, в том числе на пустое поле между строками, и
   там жест доставался бы браузеру.

   Только внутри .ed2. На странице товара та же карточка стоит
   посреди прокручиваемой страницы, и запрет на ней означал бы,
   что палец, попавший на приглашение, страницу не листает.
   ============================================================ */
.ed2 .yz-inv { touch-action: none }

/* ---------- холст ---------- */
.ed2-stage {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .9rem;
  min-height: 0;
  padding: 1.4rem 1rem 1rem;
  overflow: auto;
}
.ed2-canvas {
  position: relative;
  width: min(var(--ed-w, 460px), 100%);
  flex: 0 0 auto;
  border-radius: 10px;
  box-shadow: 0 18px 44px -24px rgba(24, 20, 40, .45);

  /* КОНТЕЙНЕР ОБЯЗАТЕЛЕН, И ЭТО НЕ ФОРМАЛЬНОСТЬ

     Весь набор кеглей карточки стоит на font-size:5.26cqw. Без
     объявленного контейнера cqw считается от вьюпорта — и на
     экране в 1440 точек имя выходит кеглем в семьдесят пять
     пикселей, вылезая за лист. Именно так этот холст и выглядел
     с первого раза: три буквы во весь макет.

     Карточку сюда кладут без своей обёртки (wrap => false),
     поэтому контейнером обязан быть холст. */
  container-type: inline-size;
}

.ed2-zoom {
  display: flex; align-items: center; gap: .2rem;
  padding: .25rem .3rem;
  background: var(--card); border: 1px solid var(--ed-line); border-radius: 100px;
}
.ed2-z {
  display: inline-flex; align-items: center; gap: .35rem;
  min-width: 36px; min-height: 36px; padding: 0 .6rem;
  border: 0; background: none; border-radius: 100px;
  font: inherit; font-size: .88rem; color: var(--ink-2); cursor: pointer;
  justify-content: center;
}
.ed2-z:hover { background: var(--paper-2); color: var(--ink) }
.ed2-z:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: -2px }
.ed2-z svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round }
.ed2-z-v { min-width: 3.2rem; text-align: center; font-size: .88rem; color: var(--ink); font-variant-numeric: tabular-nums }
.ed2-z-sep { width: 1px; height: 1.2rem; background: var(--ed-line); margin: 0 .15rem }

/* Подпись размера приглашения: нейтральная, мелкая, под
   полосой масштаба. Не подсказка и не действие — факт о
   предмете, поэтому цвет самый тихий из трёх. */
.ed2-size { margin: .35rem 0 0; text-align: center; font-size: .78rem; color: var(--ink-3) }

.ed2-say { margin: 0; min-height: 1.2rem; font-size: .84rem; color: var(--ink-3); text-align: center }

/* ---------- правая панель ---------- */
.ed2-empty { margin: 0; padding: 1.5rem .2rem; color: var(--ink-3); font-size: .9rem; line-height: 1.5 }
.ed2-props { display: flex; flex-direction: column; gap: .4rem }

.ed2-lab { font-size: .82rem; color: var(--ink-2); margin-top: .5rem }
.ed2-area, .ed2-sel, .ed2-num {
  width: 100%; padding: .55rem .7rem;
  border: 1px solid var(--rule-2); border-radius: 10px;
  background: var(--card); color: var(--ink); font: inherit; font-size: .92rem;
}
.ed2-area { resize: vertical; min-height: 68px; line-height: 1.35 }
/* Адрес — одна строка: у поля ввода нет ни переноса, ни ручки
   растягивания, и высота в две строки читалась бы как «сюда
   можно много». */
.ed2-area--one { min-height: 0; resize: none }

/* ---------- выбор из двух: куда ведёт код ----------

   Настоящие radio, а не кнопки с aria-checked: стрелками между
   ними ходит сам браузер, озвучиватель говорит «один из двух»,
   а на телефоне работает нажатие по подписи. Своя реализация
   всего этого — три десятка строк, которые однажды разойдутся
   с тем, что человек ждёт от системы.

   Кружок оставлен родной (accent-color), а не нарисован: свой
   кружок пришлось бы красить ещё и для тёмной темы, для
   контрастного режима и для фокуса с клавиатуры. */
.ed2-radio { display: flex; flex-direction: column; gap: .1rem; margin-top: .15rem }
.ed2-radio-i {
  display: flex; align-items: flex-start; gap: .5rem;
  padding: .45rem .5rem; border-radius: 9px;
  font-size: .88rem; color: var(--ink); line-height: 1.35; cursor: pointer;
}
.ed2-radio-i:hover { background: var(--ed-pick-soft) }
.ed2-radio-i input { accent-color: var(--ed-pick); margin: .15rem 0 0; flex: none }
.ed2-radio-i:focus-within { outline: 2px solid var(--ed-pick); outline-offset: 1px }

/* Что гость увидит на странице праздника. Список стоит ПОД
   своим переключателем и с отступом: он относится к первому
   варианту, а не ко второму, и без сдвига читался бы как общий
   для обоих. Маркеры убраны — это перечисление внутри
   подписи, а не список дел. */
.ed2-radio-list {
  margin: 0 0 .35rem; padding: 0 0 0 2.6rem; list-style: none;
  font-size: .8rem; color: var(--ink-3); line-height: 1.5;
}
/* Висячая строка: перенос обязан начинаться под буквой, а не
   под точкой. Иначе вторая строка пункта читается как новый
   пункт, и список из четырёх обещаний выглядит на семь. */
.ed2-radio-list li { text-indent: -.65rem }
.ed2-radio-list li::before { content: '· '; opacity: .7 }

/* Подпись поля, которое появилось прямо под выбором: обычный
   верхний отступ оторвал бы его от своего переключателя. */
.ed2-lab--tight { margin-top: .15rem }
.ed2-area:focus, .ed2-sel:focus, .ed2-num:focus {
  outline: none; border-color: var(--ed-pick);
  box-shadow: 0 0 0 3px var(--ed-pick-soft);
}

/* Плашка связи. Не украшение: без неё человек правит имя на
   холсте и не понимает, почему оно поменялось и в форме. */
.ed2-link {
  display: flex; align-items: center; gap: .4rem; margin: .1rem 0 0;
  padding: .4rem .55rem; border-radius: 9px;
  background: var(--ed-pick-soft); color: var(--ed-pick); font-size: .82rem;
}
.ed2-link svg { width: 1rem; height: 1rem; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round }

.ed2-row { display: flex; align-items: center; gap: .4rem }
.ed2-row--2 > * { flex: 1 1 0 }
.ed2-step {
  display: grid; place-items: center; width: 40px; height: 40px; flex: none;
  border: 1px solid var(--rule-2); border-radius: 10px; background: var(--card);
  font: inherit; font-size: 1.1rem; color: var(--ink-2); cursor: pointer;
}
.ed2-step:hover { border-color: var(--ed-pick); color: var(--ed-pick) }
.ed2-step:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-num { text-align: center; font-variant-numeric: tabular-nums }

/* РАСШИРЕННЫЙ НАБОР СВОЙСТВ

   Ползунок тянется, поле держит постоянную ширину: без flex:none
   у числа строка «−180» раздвигала бы ползунок, и он менял бы
   длину от значения к значению — то есть дёргался бы под рукой,
   пока его тянут.

   Ширина в ch, а не в пикселях: поле должно вмещать четыре знака
   со знаком минуса тем шрифтом, которым набрана панель, а не тем,
   которым её рисовали в макете. */
.ed2-row--sl { gap: .5rem }
/* Ширина поля — не «на глаз в ch»: поле считается по внешней
   коробке, а из неё 22 точки съедают поля ввода, ещё десяток —
   стрелки счётчика браузера. Пять знаков «−180» при таком
   вычитании из 5.2ch не помещались, и «100» показывалось как
   «1(». Считаем от знаков ПЛЮС то, что съедено. */
.ed2-row--sl .ed2-num {
  flex: none;
  width: calc(4.5ch + 1.5rem);
  padding-inline: .45rem;
}
.ed2-sl { flex: 1 1 auto; min-width: 0; accent-color: var(--ed-pick); height: 1.6rem }
.ed2-sl:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
/* Единица занимает одну и ту же ширину у всех четырёх величин:
   «°» уже «%», и без этого поля с числами вставали лесенкой —
   на три точки в сторону, которых никто не объяснит. */
.ed2-unit { flex: none; width: 1.1rem; font-size: .82rem; color: var(--ink-2) }

/* Набор целиком отделён от простых свойств чертой: так видно, что
   переключатель наверху показал именно эту часть, а не добавил
   четыре случайные строки в общий столбец. */
.ed2-more {
  display: flex; flex-direction: column; gap: .1rem;
  margin-top: .7rem; padding-top: .6rem;
  border-top: 1px solid var(--rule-2);
}
.ed2-more[hidden] { display: none }

/* Переключатель набора — тот же сегмент, что у выравнивания, но
   со словами: значка для «Просто» не существует, а придуманный
   пришлось бы объяснять подписью. */
/* Переключатель живёт в строке заголовка и не занимает своей:
   на телефоне каждая лишняя строка над полем «Содержание»
   опускает это поле под клавиатуру. Ширина по содержимому —
   иначе он растянулся бы на всю строку и выдавил заголовок. */
.ed2-h-row--mode { align-items: center; margin-bottom: .1rem }
.ed2-seg--mode { flex: 0 0 auto }
.ed2-seg--mode button { min-height: 30px; padding-inline: .55rem; font: inherit; font-size: .78rem }

.ed2-seg { display: flex; gap: .3rem }
.ed2-seg button {
  flex: 1 1 0; display: grid; place-items: center; min-height: 40px;
  border: 1px solid var(--rule-2); border-radius: 10px; background: var(--card);
  color: var(--ink-2); cursor: pointer;
}
.ed2-seg button[aria-pressed="true"] {
  background: var(--ed-pick-soft); border-color: var(--ed-pick); color: var(--ed-pick);
}
.ed2-seg button:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-seg svg { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }
.ed2-seg--big button { min-height: 48px }
.ed2-seg--big svg { width: 1.4rem; height: 1.4rem }

.ed2-hex { display: flex; align-items: center; gap: .5rem; font-size: .88rem; color: var(--ink-2); font-variant-numeric: tabular-nums }
.ed2-hex i { width: 1.4rem; height: 1.4rem; border-radius: 50%; background: var(--dot, #ccc); box-shadow: inset 0 0 0 1px rgba(0,0,0,.12) }

.ed2-pal { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .2rem }
.ed2-pal button {
  width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
  border: 2px solid transparent; padding: 0;
  background: var(--dot); box-shadow: inset 0 0 0 1px rgba(0,0,0,.12);
}
.ed2-pal button[aria-pressed="true"] { border-color: var(--ed-pick); outline: 2px solid var(--card); outline-offset: -4px }
.ed2-pal button:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }

/* Свой цвет. Само поле — системное, и показывать его «как есть»
   нельзя: в трёх браузерах это три разные плашки. Поэтому оно
   лежит внутри подписи невидимым, а видна кнопка — такая же,
   как соседние кнопки панели. Клик по подписи открывает поле:
   это поведение <label>, а не наш обработчик. */
.ed2-svoyc { display: flex; flex-direction: column; gap: .35rem; margin-top: .45rem }
/* Две кнопки цвета в один ряд: «выбрать свой» и «вернуть как
   было» — это одна пара, и на узкой панели они переносятся
   вместе, а не разъезжаются по разным строкам. */
.ed2-svoyc-row { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem }
.ed2-svoyc-def {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: 40px; padding: 0 .7rem;
  border: 1px solid transparent; border-radius: 10px; background: none;
  font: inherit; font-size: .86rem; color: var(--ink-3); cursor: pointer;
}
.ed2-svoyc-def:hover:not([disabled]) { color: var(--ed-pick); border-color: var(--rule-2) }
.ed2-svoyc-def:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-svoyc-def[disabled] { opacity: .45; cursor: default }
.ed2-svoyc-def svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }
.ed2-svoyc-b {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: 40px; padding: 0 .7rem; align-self: flex-start;
  border: 1px solid var(--rule-2); border-radius: 10px; background: var(--card);
  font-size: .86rem; color: var(--ink-2); cursor: pointer;
}
.ed2-svoyc-b:hover { border-color: var(--ed-pick); color: var(--ed-pick) }
.ed2-svoyc-b:focus-within { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-svoyc-b svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linejoin: round }
.ed2-svoyc-b input[type="color"] {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: 0;
  opacity: 0; pointer-events: none;
}
.ed2-svoyc-w { margin: 0; font-size: .8rem; line-height: 1.35; color: var(--ink-2) }
.ed2-svoyc-w b { font-weight: 500; color: var(--ink) }

/* ОТКАЗ КУПИТЬ — НЕ ТИХАЯ ПОДСКАЗКА

   Первый раз этот абзац был набран классом .ed2-svoyc-w —
   серым пояснением на .8rem, каким подписаны предупреждения про
   цвет и про код. Для пояснения это верный вес, для отказа —
   нет: человек нажал «К покупке» и должен УВИДЕТЬ, почему не
   купилось, а не найти это среди подписей к полям.

   Отсюда кирпичная полоса слева и цвет ошибки — те же, что у
   отказов в корзине (.tir-err, .bm-err). Один сайт, один язык
   отказов. */
.ed2-buy-err {
  margin: 0 0 .1rem; padding: .5rem .6rem;
  border-left: 3px solid var(--brick);
  background: var(--paper);
  font-size: .86rem; line-height: 1.4; color: var(--brick);
}

/* ============================================================
   ВЫБОР СТИКЕРА
   ------------------------------------------------------------
   Сетка три на два, а не шесть в ряд: колонка слева узкая, и в
   ряд рисунки стали бы по двенадцать точек — размером с букву,
   то есть неразличимыми.
   ============================================================ */
.ed2-sticks { margin: .35rem 0 .2rem; border: 1px solid var(--rule-2); border-radius: 12px; padding: .45rem }

/* Поиск по стикерам: значок внутри поля, а не рядом с ним —
   иначе он отнимает у поля ширину, которой в колонке шириной в
   палец и так нет. */
.ed2-find {
  display: flex; align-items: center; gap: .4rem;
  margin: 0 0 .45rem; padding: .3rem .5rem;
  border: 1px solid var(--rule-2); border-radius: 8px; background: var(--paper);
}
.ed2-find:focus-within { border-color: var(--ed-pick); box-shadow: 0 0 0 3px var(--ed-pick-soft) }
.ed2-find svg {
  width: .95rem; height: .95rem; flex: none; fill: none;
  stroke: var(--ink-3); stroke-width: 1.8; stroke-linecap: round;
}
.ed2-find input {
  flex: 1; min-width: 0; border: 0; background: none; padding: 0;
  font: inherit; font-size: .88rem; color: var(--ink);
}
.ed2-find input:focus { outline: none }
.ed2-sticks-tabs { display: flex; flex-wrap: wrap; gap: .25rem; margin-bottom: .45rem }
.ed2-sticks-tabs button {
  flex: 1 1 auto; min-height: 32px; padding: 0 .5rem;
  border: 1px solid transparent; border-radius: 8px; background: none;
  font: inherit; font-size: .76rem; color: var(--ink-2); cursor: pointer; white-space: nowrap;
}
.ed2-sticks-tabs button[aria-selected="true"] {
  border-color: var(--ed-pick); color: var(--ed-pick); background: var(--ed-pick-soft);
}
.ed2-sticks-tabs button:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 1px }
.ed2-sticks-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: .3rem }
.ed2-sticks-grid button {
  display: grid; place-items: center; aspect-ratio: 1; padding: .3rem;
  border: 1px solid var(--rule-2); border-radius: 10px; background: var(--card);
  color: var(--ed-pick); cursor: pointer;
}
.ed2-sticks-grid button:hover { border-color: var(--ed-pick); background: var(--ed-pick-soft) }
.ed2-sticks-grid button:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-sticks-grid svg { width: 100%; height: 100%; fill: currentColor }

.ed2-btn2 {
  display: inline-flex; align-items: center; justify-content: center; gap: .35rem;
  min-height: 40px; padding: 0 .6rem;
  border: 1px solid var(--rule-2); border-radius: 10px; background: var(--card);
  font: inherit; font-size: .86rem; color: var(--ink-2); cursor: pointer;
}
.ed2-btn2:hover { border-color: var(--ed-pick); color: var(--ed-pick) }
.ed2-btn2:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-btn2 svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }
/* Кнопка с подписью, а не только со значком: «Отразить» и
   «Сбросить кадр» значком не объяснить — зеркало и стрелка
   по кругу означают слишком многое. */
.ed2-btn2--w { padding: 0 .5rem; font-size: .82rem }
/* Нажатое «Отразить» держит вид, пока отражение стоит: иначе
   человек, вернувшийся к фотографии, жмёт наугад. */
.ed2-btn2[aria-pressed="true"] {
  border-color: var(--ed-pick); color: var(--ed-pick); background: var(--ed-pick-soft);
}

.ed2-range { width: 100%; min-height: 40px; accent-color: var(--ed-pick) }

.ed2-reset, .ed2-del {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: 44px; margin-top: .7rem;
  border: 0; background: none; font: inherit; font-size: .87rem; cursor: pointer;
  color: var(--ink-3); border-radius: 10px;
}
.ed2-reset:hover:not([disabled]) { color: var(--ink) }
.ed2-reset[disabled] { opacity: .45; cursor: default }

/* Заголовок блока и действие над всем блоком — в одной строке.
   Внизу колонки такой кнопке не место: там плашка про куки, и
   под ней кнопка не нажимается вовсе. */
.ed2-h-row { display: flex; align-items: baseline; gap: .5rem }
.ed2-h-row .ed2-h { flex: 1 1 auto }
.ed2-h-act {
  flex: 0 0 auto;
  border: 0; background: transparent; padding: 0;
  font: inherit; font-size: .76rem; color: var(--ink-2);
  cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.ed2-h-act:hover { color: var(--ed-pick) }
/* Удаление — нейтральная иконка с явным названием. Красной
   заливки тут нет: опасность подчёркивает подтверждение, а не
   цвет кнопки, иначе красное перестаёт значить «купить». */
.ed2-del:hover { color: var(--brick) }
.ed2-reset:focus-visible, .ed2-del:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-reset svg, .ed2-del svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round }

.ed2-note { margin: .5rem 0 0; font-size: .82rem; color: var(--ink-3); line-height: 1.45 }
.ed2-note--tiny { font-size: .78rem }

/* Точки на дюйм. Спокойная строка, пока их хватает, и
   предупреждение, когда нет: красным здесь говорит не вкус, а
   то, что исправить это можно ТОЛЬКО до покупки. */
/* ПЛОЩАДКА ДЛЯ ПЕРЕТАСКИВАНИЯ ФОТОГРАФИИ

   В покое её не видно вовсе: рамка «сюда можно бросить» нужна
   ровно в ту секунду, когда над ней держат файл, а всё остальное
   время это ещё один прямоугольник в панели, где их и так
   хватает. Поэтому в покое — только подпись под кнопкой. */
.ed2-drop { border-radius: 12px; padding-bottom: .25rem; transition: background-color .12s, box-shadow .12s }
/* Подпись набирается по тем же боковым полям, что текст кнопки
   над ней: иначе она начинается левее её и читается как чужая
   строка, а под подсветкой ещё и вылезает за рамку. */
.ed2-drop-n { margin: .15rem 0 0; padding: 0 .55rem; font-size: .74rem; color: var(--ink-2) }
.ed2-drop.is-drop,
.ed2-stage.is-drop {
  background: var(--brand-soft, rgba(219,97,118,.08));
  box-shadow: inset 0 0 0 2px var(--brand, #DB6176);
}
/* Холст подсвечиваем по его же скруглению, иначе рамка
   обрезается по прямому углу поверх круглой сцены. */
.ed2-stage.is-drop { border-radius: 14px }

.ed2-dpi { margin: .35rem 0 .9rem }
.ed2-dpi.is-bad { color: var(--amber-ink, var(--amber, #8A5A00)) }

/* ---------- предпросмотр ----------
   Прячем всё служебное, ничего не разбирая: состояние документа
   остаётся, меняется только то, что видно. */
.ed2[data-preview] .ed2-left,
.ed2[data-preview] .ed2-right,
.ed2[data-preview] .ed2-zoom,
.ed2[data-preview] .rz-over { display: none }
.ed2[data-preview] .ed2-body { grid-template-columns: 1fr }
.ed2[data-preview] .ed2-canvas { --ed-w: 520px }

/* ============================================================
   ПУНКТИР — ПО НАВЕДЕНИЮ, А НЕ НА ВСЕХ СРАЗУ
   ------------------------------------------------------------
   На странице шаблона расширенный режим включают на минуту, и
   там пунктир вокруг каждой строки — подсказка «вот что можно
   схватить». Он и остаётся: правило в product.css не тронуто.

   Здесь режим включён всегда. Шесть пунктирных прямоугольников
   поверх приглашения означают, что человек за всё время работы
   ни разу не увидит того, что делает: он смотрит на сетку, а
   покупает открытку. Поэтому обводим то, на что навели, а
   выбранное и без того обведено рамкой в слое поверх.

   Гасим цветом, а не outline:none: ширина и отступ остаются
   объявленными в одном месте — там же, где для страницы
   товара, — и наведение возвращает ровно ту же рамку.
   ============================================================ */
.ed2 .yz-inv[data-rz] [data-layer] { outline-color: transparent }
.ed2 .yz-inv[data-rz] [data-layer]:hover {
  outline-color: color-mix(in oklab, var(--c-ink) 34%, transparent);
}
/* В предпросмотре не должно быть ни рамок, ни руки-хваталки:
   человек смотрит на приглашение так, как его увидит гость. */
.ed2[data-preview] .yz-inv[data-rz] [data-layer] { outline-color: transparent; cursor: default }
.ed2[data-preview] .yz-inv[data-rz] .yz-photo { cursor: default }

/* ============================================================
   Узкий экран: не сжатые три колонки, а своя компоновка
   ============================================================ */
@media (max-width: 1099px) {
  .ed2-body { grid-template-columns: 240px minmax(0, 1fr) 260px }
  .ed2-left, .ed2-right { padding-inline: .7rem }
}

/* ------------------------------------------------------------
   Телефон: холст сверху, одна панель снизу

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

   ПОЧЕМУ ОДНА, А НЕ ОБЕ

   Обе не помещаются. Список слоёв и свойства занимают по трети
   экрана каждый, и холсту остаётся полоса в два пальца — то
   есть человек правит приглашение, не видя приглашения. Пока
   ничего не выбрано, внизу «Добавить» и слои; выбрал — там
   свойства выбранного, а наверху панели появляется дорога
   назад.
   ------------------------------------------------------------ */
@media (max-width: 899px) {
  .ed2 { --ed-top: 56px }

  /* В шапке остаются значки и название. Название сжимается с
     многоточием: «Единорог и сирень» в одну нерушимую строку
     раздвигал шапку на треть экрана вправо, и кнопки уезжали
     за край — вместе с «Готово». */
  .ed2-back span, .ed2-saved-t, .ed2-saved-when, .ed2-eye span { display: none }
  .ed2-top { gap: .4rem; padding-inline: .6rem }
  .ed2-back::after { margin-left: .35rem }
  .ed2-eye { padding-inline: .6rem }
  .ed2-name {
    font-size: .88rem; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .ed2-top-r { gap: .25rem }

  /* Холст наверху, панель под ним. В разметке панели идут по
     краям от холста — так правильно и на широком экране, и для
     чтения с экранным диктором. Здесь их порядок только
     показанный: холст первым, потому что человек смотрит на
     приглашение, а не на список. */
  .ed2-body { display: flex; flex-direction: column }
  .ed2-stage { order: 1; flex: 1 1 auto; min-height: 0; padding: .7rem .8rem .4rem }

  /* ------------------------------------------------------------
     НИЖНИЙ ЛИСТ НА ТРИ ВЫСОТЫ

     Панель стояла жёсткими 44 % высоты экрана, и обе стороны
     этого числа мешали. Свойства выбранной строки — шрифт,
     интервал, цвет, размер фотографии — не помещаются: замерено
     830 точек содержимого в окне 370, то есть больше половины
     панели человек не видит и прокручивает её вслепую, пока
     приглашение сверху занимает место, на которое он в эту
     секунду не смотрит. А когда он как раз смотрит на
     приглашение — двигает строку, сверяет цвет, — те же 44 %
     отъедены у карточки.

     Одно число не может быть верным в обоих случаях, потому что
     это разные занятия. Значит, число выбирает человек: три
     остановки, ручка сверху, защёлкивание на ближайшей.

     ПОЧЕМУ ИМЕННО ТРИ

     Две (открыто/закрыто) не дают промежуточного, ради которого
     всё и затевалось. Больше трёх нечем назвать: «чуть выше
     половины» — не состояние, а оттенок, и по кругу их не
     обойти.

     Высоты — доли svh, а не dvh: dvh на телефоне меняется, когда
     уезжает адресная строка браузера, и лист дёргался бы от
     прокрутки, которой здесь даже нет.
     ------------------------------------------------------------ */
  .ed2 { --ed-sheet: 44svh }

  .ed2-grip {
    display: flex; order: 2; flex: 0 0 auto;
    justify-content: center; align-items: stretch;
    background: var(--card);
    border-top: 1px solid var(--ed-line);
  }
  .ed2-grip-b {
    /* Полоса во всю ширину, а не одна засечка: тянут её пальцем,
       и промахнуться по цели в два сантиметра посреди экрана
       легко. Видимая засечка внутри — только знак, куда браться. */
    flex: 1 1 auto; display: grid; place-items: center;
    min-height: 26px; padding: 0;
    border: 0; background: none; cursor: grab;
    touch-action: none;
  }
  .ed2-grip-b:active { cursor: grabbing }
  .ed2-grip-l {
    display: block; width: 38px; height: 4px; border-radius: 2px;
    background: var(--ed-line);
    transition: background .15s ease;
  }
  .ed2-grip-b:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: -2px }
  .ed2-grip-b:focus-visible .ed2-grip-l,
  .ed2-grip-b:hover .ed2-grip-l { background: var(--ink-3, #9990ad) }

  .ed2-left, .ed2-right {
    order: 3;
    flex: 0 0 auto;
    height: var(--ed-sheet); max-height: none; overflow-y: auto;
    /* Толчок по инерции внутри листа не должен уходить странице:
       страница редактора не прокручивается вовсе, и «протянутый»
       жест выглядел бы как залипание. */
    overscroll-behavior: contain;
    border: 0;
    padding: .7rem .9rem calc(.9rem + env(safe-area-inset-bottom));
  }

  /* Плавно — только когда лист защёлкивается сам. Пока палец на
     ручке, переход означал бы, что лист отстаёт от пальца. */
  .ed2[data-sheet-snap] .ed2-left,
  .ed2[data-sheet-snap] .ed2-right { transition: height .18s ease }

  /* На верхней остановке полоса масштаба уходит.

     Сначала она была спрятана на НИЖНЕЙ — ровно наоборот. Внизу
     листа места как раз вдоволь: сцене остаётся 677 точек из
     844. А наверху её 214, и полоса масштаба съедала бы из них
     46 — пятую часть того, что осталось карточке. То же самое
     там делают два пальца, которым полоса не нужна.

     Замерено, а не прикинуто: без этого правила на верхней
     остановке карточка вставала на y = −65 при сцене высотой
     103 — то есть вылезала за верхний край и обрезалась с обеих
     сторон. */
  .ed2[data-sheet="2"] .ed2-zoom { display: none }

  /* Карточка центрируется, но не обрезается.

     У flex с justify-content:center содержимое, которое не
     влезло, уезжает за ОБА края разом, и до верхней его половины
     не добраться никакой прокруткой. safe center в этом случае
     прижимает к началу — видно хотя бы то, что поместилось. */
  .ed2-stage { justify-content: safe center }

  /* Видна ровно одна: выбор слоя переключает панель. */
  .ed2[data-sel] .ed2-left { display: none }
  .ed2:not([data-sel]) .ed2-right { display: none }

  .ed2-back-lay { display: inline-flex }

  /* Кнопки добавления — рядом, заголовок над ними. Заголовок
     обязан занять всю строку сам: без этого он встаёт первым
     столбцом сетки, и «Добавить» оказывается слева от кнопки
     «Добавить заголовок». */
  .ed2-left .ed2-block {
    display: grid; gap: .45rem;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  }
  .ed2-left .ed2-h { grid-column: 1 / -1 }
  .ed2-left .ed2-layers { grid-column: 1 / -1 }
}

/* ------------------------------------------------------------
   Совсем узко: в шапке остаётся только необходимое

   На 390 точках сумма нужного больше ширины экрана, и что-то
   обязано уйти. Уходит логотип: он ведёт на главную, а из
   рабочего места на главную не уходят — уходят к своему
   шаблону, и эта дорога рядом. Уходит и подпись у «К покупке»:
   стрелка вправо у правого края читается однозначно, а
   aria-label остаётся для тех, кто слушает.
   ------------------------------------------------------------ */
@media (max-width: 620px) {
  .ed2-logo { display: none }
  .ed2-buy span { display: none }
  .ed2-buy { padding-inline: .7rem }
}

@media (prefers-reduced-motion: reduce) {
  .ed2 *, .ed2 *::before, .ed2 *::after { transition: none !important; animation: none !important }
}

/* ============================================================
   СМЕНА ШАБЛОНА: КАТАЛОГ ПОВЕРХ РЕДАКТОРА
   ------------------------------------------------------------
   Внутри рамки — настоящая страница каталога в режиме выбора
   (Yzt_Editor::vybor). Её оформление лежит не здесь, а в
   catalog.css рядом с самим каталогом: правила для одной
   страницы должны лежать вместе с ней, а не в файле соседа.
   ============================================================ */
/* «Сменить шаблон» — вторая по важности кнопка на этой полосе.

   Первая — «К покупке», и она одна красная. Серой рамкой среди
   серых значков сменa шаблона терялась: человек, которому дизайн
   не подошёл, правил чужую композицию вместо того, чтобы взять
   свою.

   Поэтому здесь фиолетовый — тот же --ed-pick, которым в
   редакторе помечено выбранное и наведённое. Заливка бледная, а
   не сплошная: сплошная спорила бы с «К покупке» за главное
   место, а бледная читается как «тоже кнопка, но не эта». */
.ed2-swap {
  display: inline-flex; align-items: center; gap: .3rem;
  flex: 0 0 auto;
  border: 1px solid color-mix(in oklab, var(--ed-pick) 42%, transparent);
  background: var(--ed-pick-soft);
  border-radius: 99px; padding: .34rem .78rem;
  font: inherit; font-size: .84rem; font-weight: 500; color: var(--ed-pick);
  cursor: pointer;
}
.ed2-swap svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.9 }
.ed2-swap:hover {
  background: color-mix(in oklab, var(--ed-pick) 20%, transparent);
  border-color: var(--ed-pick);
}
.ed2-swap:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }

/* ОКНО ВЫБОРА — ВЫШЕ ВСЕГО, ЧТО ВИСИТ НАД СТРАНИЦЕЙ

   Было 60 — ровно столько же, сколько у плашки о куки. При
   равном слое побеждает тот, кто ниже в разметке, а плашку
   печатает скрипт в конце: она ложилась поверх заголовка
   «Выберите другой шаблон» и подписи под ним. Причём именно в
   редакторе, где плашка намеренно перенесена из угла под шапку
   (см. выше) — то есть ровно туда, где стоит заголовок окна.

   Окно объявлено aria-modal: пока оно открыто, оно и есть то,
   что на экране, и закрывать его чем-либо со страницы нельзя.
   100 — выше плашки (60) и шторки фасетов (60) и ниже
   увеличенной карточки товара (120), которой в редакторе нет. */
/* ============================================================
   РАЗБОР МАКЕТА ПЕРЕД КОРЗИНОЙ
   ------------------------------------------------------------
   Окно небольшое и без картинок: в нём список из одной-двух
   строк, и растягивать его на пол-экрана значит делать из
   предупреждения событие. Кнопок две, и главная — «Всё равно
   продолжить»: человек уже нажал «Продолжить», и окно не должно
   выглядеть как отказ.
   ============================================================ */
.ed2-chk { position: fixed; inset: 0; z-index: 110; display: flex }
.ed2-chk-veil { position: absolute; inset: 0; background: rgba(24, 20, 40, .5) }
.ed2-chk-box {
  position: relative; margin: auto;
  width: min(460px, 92vw);
  padding: 1.15rem 1.2rem 1.1rem;
  background: var(--card); border-radius: 14px;
  box-shadow: 0 30px 70px -30px rgba(24, 20, 40, .6);
}
.ed2-chk-box > b { display: block; font-size: 1.05rem; margin-bottom: .6rem }
.ed2-chk-list { margin: 0 0 1rem; padding: 0; list-style: none; display: grid; gap: .5rem }
.ed2-chk-list li {
  position: relative; padding-left: 1.6rem;
  font-size: .9rem; line-height: 1.45; color: var(--ink-2);
}
/* Знак внимания — текстом, а не рисунком: он должен читаться
   озвучивателем как знак, а не молчать как декоративный svg. */
.ed2-chk-list li::before {
  content: "⚠"; position: absolute; left: 0; top: 0;
  color: var(--warn, #b36a00);
}
.ed2-chk-btns { display: flex; gap: .55rem; justify-content: flex-end; flex-wrap: wrap }

.ed2-cat { position: fixed; inset: 0; z-index: 100; display: flex }
.ed2-cat-veil { position: absolute; inset: 0; background: rgba(24, 20, 40, .5) }
.ed2-cat-box {
  position: relative;
  margin: auto;
  width: min(1180px, 94vw);
  height: min(860px, 92dvh);
  display: flex; flex-direction: column;
  background: var(--card);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 30px 70px -30px rgba(24, 20, 40, .6);
}
.ed2-cat-top {
  display: flex; align-items: center; gap: .6rem;
  flex: 0 0 auto;
  padding: .8rem 1rem;
  border-bottom: 1px solid var(--ed-line);
}
.ed2-cat-hint { font-size: .82rem; color: var(--ink-2); flex: 1 1 auto }
.ed2-cat-x {
  flex: 0 0 auto; width: 34px; height: 34px;
  border: 0; background: transparent; border-radius: 8px; cursor: pointer; color: var(--ink-2);
}
.ed2-cat-x svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8 }
.ed2-cat-x:hover { background: var(--ed-stage); color: var(--ink) }
.ed2-cat-frame { flex: 1 1 auto; width: 100%; border: 0; display: block }

@media (max-width: 780px) {
  .ed2-swap span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%) }
  .ed2-swap { padding: .34rem .5rem }
  .ed2-cat-box { width: 100vw; height: 100dvh; border-radius: 0 }
}

/* Дата и время в панели свойств: те же календарь и часы, что в
   форме на странице шаблона. Ширины у панели меньше, поэтому
   ряд из двух полей переносится, а не сжимается в нечитаемое. */
.ed2-when { display: flex; flex-direction: column; gap: .45rem }
.ed2-when .when-row { display: flex; flex-wrap: wrap; gap: .4rem }
.ed2-when .dp { flex: 1 1 9rem; min-width: 0 }
.ed2-when .tp { flex: 0 0 auto }

/* ============================================================
   ОКНО ПРАВКИ ПО НАЖАТИЮ НА НАДПИСЬ
   ------------------------------------------------------------
   Не затемняющий слой на весь экран: окно ничего не держит и
   ответа не требует, это поле, подведённое к строке. Затемнение
   вдобавок спрятало бы саму карточку — то есть то, ради чего
   человек и набирает текст.

   Подложка всё же есть, прозрачная: она ловит нажатие мимо
   коробки и закрывает окно. Без неё закрыть его можно было бы
   только кнопкой, а нажатие «куда-нибудь» — самый частый способ
   выйти из маленького окна.
   ============================================================ */
/* Подложка ничего не ловит: нажатие мимо коробки должно и окно
   закрыть, и сделать то, ради чего нажимали. Ловящий слой
   означал бы, что открытое окно запирает холст. */
.ed2-pop { position: absolute; inset: 0; z-index: 7; pointer-events: none }
.ed2-pop__box { pointer-events: auto }
.ed2-pop__box {
  position: absolute;
  /* Ширина по содержимому: панель действий — это ряд кнопок, и
     коробка в 21rem вокруг пяти значков выглядит окном, из
     которого что-то выпало. Прежняя ширина осталась потолком:
     календарю она нужна целиком. */
  width: max-content;
  /* Потолок поднят в выпуске 130: в ряд добавились шрифт и
     цвет (§7 ТЗ), и прежние 21rem их не вмещали — flex не
     переносил ряд, а СЖИМАЛ кнопки, и значки выравнивания
     становились по семнадцать точек шириной. Сжатая кнопка
     выглядит поломкой, а не теснотой. */
  max-width: min(24rem, 92%);
  background: var(--card);
  border: 1px solid var(--ed-line);
  border-radius: 12px;
  padding: .45rem .5rem;
  box-shadow: 0 16px 40px -18px rgba(24, 20, 40, .5);
}
/* Окно с календарём остаётся окном: у него свои поля и своя
   ширина. Отличаем по тому, что в гнезде что-то лежит. */
.ed2-pop__box:has(.ed2-pop__slot > *) { width: min(21rem, 90%); padding: .8rem .85rem .85rem }

/* ---------- ряд действий ----------
   Кнопки одного роста и одной ширины, значок по центру: ряд из
   разнокалиберных кнопок читается как список, а не как пульт. */
/* Пульт — два ряда по смыслу: чем набрано и что с этим сделать.
   Перенос внутри ряда всё равно разрешён: он последняя защита
   от сжатия, а сжатые до неузнаваемости кнопки человек читает
   как сломанный редактор. */
.ed2-pop__bar { display: flex; flex-direction: column; gap: .15rem }
.ed2-pop__row { display: flex; align-items: center; flex-wrap: wrap; gap: .1rem }
.ed2-pop__row[hidden] { display: none }
.ed2-pop__b {
  display: inline-flex; align-items: center; gap: .3rem;
  min-height: 34px; padding: 0 .5rem;
  border: 0; border-radius: 8px; background: none; color: var(--ink-2);
  font: inherit; font-size: .86rem; cursor: pointer;
}
.ed2-pop__i { width: 34px; flex: none; padding: 0; justify-content: center; font-size: 1rem }
.ed2-pop__b svg {
  width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
.ed2-pop__b:hover { background: var(--ed-pick-soft); color: var(--ed-pick) }
.ed2-pop__b:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 1px }
.ed2-pop__b[aria-pressed="true"] { background: var(--ed-pick-soft); color: var(--ed-pick) }
.ed2-pop__del:hover { background: color-mix(in oklab, var(--brick) 12%, transparent); color: var(--brick) }
.ed2-pop__sep { width: 1px; height: 20px; flex: none; margin: 0 .12rem; background: var(--rule-2) }

/* Шрифт в пульте — системный список. Своей стрелки не рисуем и
   высоту держим ту же, что у кнопок рядом: ряд из
   разнокалиберных предметов читается как список, а не как
   пульт. Ширину ограничиваем — «Как в дизайне» длиннее всех
   кнопок вместе взятых. */
.ed2-pop__sel {
  min-height: 34px; flex: none; max-width: 8.6rem; padding: 0 .35rem;
  border: 1px solid var(--rule-2); border-radius: 8px;
  background: var(--card); color: var(--ink);
  font: inherit; font-size: .84rem; cursor: pointer;
}
.ed2-pop__sel:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 1px }

/* Кнопка цвета — кружок текущего цвета, а не значок палитры:
   человек ищет глазами свой цвет, а не слово «цвет». Обводка
   нужна на светлом: белый кружок на белой кнопке невидим. */
.ed2-pop__c i {
  width: 18px; height: 18px; border-radius: 50%;
  border: 1px solid var(--rule-2); display: block;
}

/* Второй ряд окна: палитра. Не выпадающий список — он встал бы
   третьим слоем над карточкой, ради которой цвет и подбирают. */
.ed2-pop__pal {
  display: flex; align-items: center; flex-wrap: wrap; gap: .35rem;
  margin-top: .4rem; padding-top: .4rem; border-top: 1px solid var(--ed-line);
}
.ed2-pop__pal .ed2-pal { margin: 0 }
.ed2-pop__def {
  min-height: 30px; padding: 0 .5rem;
  border: 0; border-radius: 8px; background: none;
  color: var(--ink-3); font: inherit; font-size: .8rem; cursor: pointer;
}
.ed2-pop__def:hover:not([disabled]) { background: var(--ed-pick-soft); color: var(--ed-pick) }
.ed2-pop__def[disabled] { opacity: .45; cursor: default }
.ed2-pop__def:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 1px }
.ed2-pop__n {
  min-width: 2.3rem; flex: none; text-align: center; font-size: .86rem;
  color: var(--ink); font-variant-numeric: tabular-nums;
}

/* На узком экране у кнопки остаётся только значок: восемь
   кнопок с подписью в ряд не помещаются в 390 точек, а
   переносить пульт в две строки значит закрыть им пол-карточки.
   Название остаётся в aria-label и в подсказке. */
@media (max-width: 899px) {
  .ed2-pop__b span { display: none }
  .ed2-pop__b { width: 40px; padding: 0; justify-content: center }
  .ed2-pop__bar { justify-content: center; flex-wrap: wrap }
}

.ed2-pop__slot { display: grid; gap: .35rem }
.ed2-pop__slot:empty { display: none }
.ed2-pop__slot .ed2-area { width: 100%; box-sizing: border-box }
.ed2-pop__ok[hidden] { display: none }
.ed2-pop__ok {
  margin-top: .7rem; width: 100%;
  font: inherit; font-size: .92rem; font-weight: 500; cursor: pointer;
  min-height: 44px; padding: .5rem 1rem; border: 0; border-radius: 9px;
  background: var(--ed-pick); color: #fff;
}
.ed2-pop__ok:hover { filter: brightness(1.07) }
.ed2-pop__ok:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }

@media (prefers-reduced-motion: no-preference) {
  .ed2-pop__box { animation: ed2-pop-in .13s ease-out }
  @keyframes ed2-pop-in { from { opacity: 0; transform: translateY(4px) } }
}

/* ---------- строка, которую правят прямо на карточке ----------
   Видимый признак нужен: каретка мигает в одну точку, и на
   тёмном дизайне её легко не заметить вовсе. Подсветка — та же
   мягкая заливка, что у выбранного в панелях, и она НЕ уезжает
   в печать: правка выключается раньше, чем лист уходит на
   сервер, а сама заливка живёт на атрибуте состояния. */
[data-rz-edit] [contenteditable] {
  outline: 2px solid var(--ed-pick);
  outline-offset: 3px;
  border-radius: 3px;
  cursor: text;
}

/* Место одолженных окну полей: та же высота, и вместо дыры —
   объяснение, куда они делись. */
.ed2-vzato {
  margin: 0; display: grid; place-items: center; text-align: center;
  border: 1px dashed var(--ed-line); border-radius: 10px;
  color: var(--ink-3, #9990ad); font-size: .85rem;
}

/* ============================================================
   ПЕРЕНОС СТРОК В СПИСКЕ СЛОЁВ
   ------------------------------------------------------------
   Курсор «схватить» стоит здесь не для красоты: значок из трёх
   линий уже обещал перенос, и обещание надо либо снять, либо
   выполнить. Выполнили — значит, и курсор должен говорить то же
   самое, что значок.
   ============================================================ */
.ed2-lay[data-perenos] { cursor: grab }
.ed2-lay[data-tashchim] { cursor: grabbing; opacity: .55 }

/* Пальцем тянем за значок, мышью — за всю строку.

   Строка целиком, отданная пальцу, отняла бы у списка прокрутку:
   палец на строке означал бы перенос, и до нижних слоёв было бы
   не добраться. Значок из трёх линий — ровно то место, которое
   и так обещает перенос, поэтому прокрутку отключаем только на
   нём. На широком экране прокрутка списку не нужна, и там
   тянется вся строка. */
.ed2-lay[data-perenos] > .ed2-lay-i { touch-action: none }
@media (pointer: coarse) {
  .ed2-lay[data-perenos] > .ed2-lay-i {
    box-sizing: content-box; padding: .62rem; margin: -.62rem .1rem -.62rem -.2rem;
  }
}
.ed2-layers[data-tashchim] .ed2-lay { transition: none }

/* Куда встанет строка — видно до того, как отпустили. */
.ed2-lay[data-pered] { box-shadow: 0 -2px 0 0 var(--ed-pick) }

/* ============================================================
   ГОТОВЫЕ ФРАЗЫ В ПАНЕЛИ «СОДЕРЖАНИЕ»
   ------------------------------------------------------------
   Закрытое окошко, а не список: фразы нужны один раз и не
   каждому, а панель свойств и без них длиной в два экрана.
   Открытое по умолчанию, оно отодвигало бы кегль и цвет — то
   есть то, за чем в панель приходят.

   Фразы — кнопки во всю ширину, а не чипсы в ряд: в них
   предложения («Подарков не нужно — приходите сами»), и
   свёрстанные в ряд они превратились бы в лестницу из обрывков.
   ============================================================ */
.ed2-frazy { margin: .45rem 0 .2rem }
.ed2-frazy > summary {
  display: flex; align-items: center; gap: .35rem;
  min-height: 36px;
  font-size: .84rem; color: var(--ink-2); cursor: pointer;
  list-style: none;
}
.ed2-frazy > summary::-webkit-details-marker { display: none }
.ed2-frazy > summary::after { content: "↓"; font-size: .9em; color: var(--ink-3) }
.ed2-frazy[open] > summary::after { content: "↑" }
.ed2-frazy > summary:hover { color: var(--ink) }
.ed2-frazy-g { display: grid; gap: .3rem; margin-bottom: .45rem }
.ed2-frazy-h { font-size: .76rem; color: var(--ink-3); margin-top: .2rem }
.ed2-fraza {
  display: block; width: 100%;
  min-height: 36px; padding: .4rem .6rem;
  border: 1px solid var(--ed-line); border-radius: 9px;
  background: var(--card); color: var(--ink);
  font: inherit; font-size: .85rem; line-height: 1.35; text-align: left;
  cursor: pointer;
}
.ed2-fraza:hover { border-color: var(--ed-pick); color: var(--ed-pick) }
.ed2-fraza:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-frazy-n { margin: .2rem 0 0; font-size: .78rem; color: var(--ink-3); line-height: 1.45 }
@media (pointer: coarse) {
  .ed2-fraza { min-height: 44px }
  .ed2-frazy > summary { min-height: 44px }
}

/* «Вписать в ширину» — действие над кеглем, и стоит оно под
   кеглем. Вид тот же, что у «вернуть набор как в дизайне»:
   это тоже разовое действие, а не переключатель. */
.ed2-fit {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: 40px; margin-top: .4rem;
  border: 0; background: none; font: inherit; font-size: .85rem; cursor: pointer;
  color: var(--ink-3); border-radius: 10px;
}
.ed2-fit:hover { color: var(--ed-pick) }
.ed2-fit:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }
.ed2-fit svg {
  width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
@media (pointer: coarse) { .ed2-fit { min-height: 44px } }

/* ============================================================
   ПОДСКАЗКА КЛАВИШ
   ------------------------------------------------------------
   Значка нет на узком экране, и это не «скрыли, чтобы
   поместилось»: клавиатуры с Ctrl, Alt и Delete там нет, а
   список клавиш, которых у человека нет, — это обещание.

   Порог тот же, по которому редактор перестраивается в один
   столбец (899px): второе число здесь означало бы ширину, на
   которой значок уже есть, а привычной раскладки панелей ещё
   нет.
   ============================================================ */
.ed2-keys-w { position: fixed; inset: 0; z-index: 110; display: flex }
.ed2-keys-veil { position: absolute; inset: 0; background: rgba(24, 20, 40, .5) }
.ed2-keys-box {
  position: relative; margin: auto;
  width: min(520px, 92vw); max-height: 88dvh; overflow: auto;
  padding: .2rem 1.2rem 1.1rem;
  background: var(--card); border-radius: 14px;
  box-shadow: 0 30px 70px -30px rgba(24, 20, 40, .6);
}
.ed2-keys-top {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; gap: .6rem;
  padding: .85rem 0 .7rem;
  background: var(--card);
  border-bottom: 1px solid var(--ed-line);
}
.ed2-keys-top > b { flex: 1 1 auto; font-size: 1.05rem }
.ed2-keys-list { display: grid; gap: .1rem; margin-top: .55rem }
.ed2-keys-r {
  display: grid; grid-template-columns: minmax(8.5rem, 42%) 1fr; gap: .2rem .7rem;
  align-items: baseline;
  padding: .36rem 0;
  font-size: .87rem; line-height: 1.4; color: var(--ink-2);
}
.ed2-keys-r + .ed2-keys-r { border-top: 1px solid var(--ed-line) }
.ed2-keys-k { color: var(--ink) }
.ed2-keys-k kbd {
  display: inline-block;
  padding: .08em .38em;
  border: 1px solid var(--ed-line); border-bottom-width: 2px; border-radius: 6px;
  background: var(--ed-stage);
  font: inherit; font-size: .92em; white-space: nowrap;
}
.ed2-keys-n { margin: .8rem 0 0; font-size: .8rem; color: var(--ink-3); line-height: 1.45 }
@media (max-width: 899px) { .ed2-keys { display: none } }
@media (max-width: 520px) {
  .ed2-keys-r { grid-template-columns: 1fr }
}

/* Пипетка стоит рядом со «Своим цветом» и выглядит так же: обе
   кнопки открывают чужое окно выбора цвета — системное и
   браузерное. Разный вид у двух соседних кнопок с одним смыслом
   означал бы, что одна из них главнее. */
.ed2-pip {
  border: 1px solid var(--ed-line); background: var(--card); color: var(--ink);
  cursor: pointer; font: inherit;
}
.ed2-pip:hover { border-color: var(--ed-pick); color: var(--ed-pick) }
.ed2-pip:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }

/* Подпись к режиму «Поля»: появляется вместе с линиями на
   холсте и объясняет, какая из них что значит. */
.ed2-safe-note {
  margin: .35rem auto 0; max-width: 42rem;
  font-size: .8rem; line-height: 1.45; color: var(--ink-3); text-align: center;
}

/* ============================================================
   ПРИМЕРКА СПИСКА ИМЁН
   ------------------------------------------------------------
   Зов стоит под холстом обычной строкой, а не кнопкой: это
   предложение, а не действие над приглашением, и кнопочный вид
   среди «Вписать» и «Поля» читался бы как третий режим холста.
   ============================================================ */
.ed2-tir-zov { margin: .5rem auto 0; font-size: .85rem; color: var(--ink-3); text-align: center }
.ed2-tir-b {
  border: 0; background: none; padding: 0;
  font: inherit; color: var(--ed-pick); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.ed2-tir-b:hover { color: var(--ink) }
.ed2-tir-b:focus-visible { outline: 2px solid var(--ed-pick); outline-offset: 2px }

.ed2-tir { position: fixed; inset: 0; z-index: 115; display: flex }
.ed2-tir-veil { position: absolute; inset: 0; background: rgba(24, 20, 40, .5) }
.ed2-tir-box {
  position: relative; margin: auto;
  width: min(980px, 94vw); max-height: 92dvh;
  display: flex; flex-direction: column;
  background: var(--card); border-radius: 14px; overflow: hidden;
  box-shadow: 0 30px 70px -30px rgba(24, 20, 40, .6);
}
.ed2-tir-top {
  display: flex; align-items: center; gap: .6rem;
  flex: 0 0 auto; padding: .8rem 1rem;
  border-bottom: 1px solid var(--ed-line);
}
.ed2-tir-top > b { flex: 1 1 auto; font-size: 1.05rem }
.ed2-tir-body { flex: 1 1 auto; overflow: auto; padding: .9rem 1rem }
.ed2-tir-area { width: 100%; min-height: 6.5rem; resize: vertical }
.ed2-tir-hint { margin: .35rem 0 0; font-size: .8rem; color: var(--ink-3); line-height: 1.45 }
.ed2-tir-zam {
  margin: .6rem 0 0; padding: .5rem .7rem;
  border-radius: 10px; background: var(--ed-stage);
  font-size: .85rem; line-height: 1.45; color: var(--ink-2);
}

/* Карточки — сеткой, которая сама решает, сколько поместится.
   Число колонок в правиле означало бы, что на узком экране
   карточка станет с ноготь, а на широком их будет три при
   месте на пять. */
.ed2-tir-grid {
  display: grid; gap: .8rem; margin-top: .9rem;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.ed2-tir-cell { display: flex; flex-direction: column; gap: .3rem }
.ed2-tir-cell .yz-inv-wrap { width: 100%; border-radius: 8px; overflow: hidden }
.ed2-tir-bad { margin: 0; font-size: .76rem; line-height: 1.35; color: var(--brick) }
.ed2-tir-more { margin: .7rem 0 0; font-size: .82rem; color: var(--ink-3); text-align: center }
.ed2-tir-btns {
  flex: 0 0 auto; display: flex; gap: .55rem; justify-content: flex-end; flex-wrap: wrap;
  padding: .8rem 1rem; border-top: 1px solid var(--ed-line);
}
.ed2-tir-err { margin: 0 1rem .8rem; font-size: .85rem; color: var(--brick) }

@media (max-width: 700px) {
  .ed2-tir-box { width: 100vw; height: 100dvh; max-height: none; border-radius: 0 }
  .ed2-tir-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)) }
}

/* Выравнивание: два ряда по три кнопки — по ширине и по высоте.
   Один ряд из шести на узкой панели ломается пополам в
   произвольном месте, и «по правому краю» оказывается под
   «по верху». */
.ed2-rov { margin-top: .7rem; display: grid; gap: .4rem }
.ed2-rov .ed2-seg { width: 100% }
.ed2-rov-r { margin-top: .2rem }
.ed2-rov-n { margin: .1rem 0 0; font-size: .78rem; line-height: 1.4; color: var(--ink-3) }
