  /* ── этап advertisement: редактор креатива + живое Telegram-превью ── */
  .ad-panel { border:0; border-radius:var(--radius-card); background:transparent; overflow:hidden }
  /* карточки расчёта и объявления — чуть мельче масштабом (равномерно ужимаем всё содержимое) */
  .cn-body .calc-panel, .cn-body .ad-panel { zoom: .9 }
  .ad-head { display:flex; gap:11px; padding:2px 0 14px; border-bottom:0 }
  .ad-ava { flex:0 0 auto; width:30px; height:30px; border-radius:var(--radius-mark);
            background:var(--ink); color:var(--paper);
            display:flex; align-items:center; justify-content:center;
            font-variation-settings:var(--axis-active); font-size:14px }
  .ad-head h4 { margin:0; font-family:var(--font-display); font-weight:700; font-size:19px; letter-spacing:.1px }
  .ad-head h4 .fmt { font-family:var(--font-script); font-weight:300; font-size:14px; letter-spacing:.2px;
                     text-transform:none; color:var(--ink-muted); margin-left:7px }
  .ad-head p { margin:3px 0 0; font-size:12.5px; color:var(--muted); line-height:1.45 }
  .ad-body { display:flex; flex-wrap:wrap; gap:22px; padding:0 }
  .adf { margin-top:18px } .adf:first-child { margin-top:0 }
  .adf-lab { display:flex; justify-content:space-between; align-items:baseline; gap:6px; margin-bottom:5px }
  /* ✨ у каждого поля: генерируем заголовок и описание по отдельности */
  .genf { border:0; background:none; padding:0 2px; margin-right:auto; font-size:12px; line-height:1;
          cursor:pointer; opacity:.55 }
  .genf:hover { opacity:1 }
  .genf:disabled { opacity:.25; cursor:default }
  /* ── идёт генерация: крутилка + секундомер ── */
  /* Процентов у нас нет и быть не может — модель не отчитывается о прогрессе.
     Поэтому честный индикатор это «работаю» + счётчик секунд: он показывает, что
     процесс жив, и даёт понять, сколько обычно ждать. Врать шкалой не станем. */
  .spin { display:inline-block; width:12px; height:12px; border:2px solid var(--faint);
          border-top-color:var(--ink); border-radius:50%; animation:spin .7s linear infinite;
          vertical-align:-2px; flex:0 0 auto }
  @keyframes spin { to { transform:rotate(360deg) } }
  .genf.busy { opacity:1 }
  .gen-busy { position:relative }
  .gen-busy input, .gen-busy textarea { color:var(--muted) }
  .genover { position:absolute; inset:0; z-index:2; display:flex; align-items:center; justify-content:center;
             gap:7px; background:rgb(239 239 239 / .86); border-radius:var(--radius-card);
             font-size:11.5px; color:var(--ink-muted) }
  #adMediaBox .genover {
    background:rgba(13,24,35,.86); color:#fff; border-radius:9px; flex-direction:column;
    gap:7px; font-size:12px; text-align:center; backdrop-filter:blur(3px) }
  #adMediaBox .genover .spin { border-color:rgb(255 255 255 / .3); border-top-color:#fff;
                               width:18px; height:18px }
  .cn-save .spin { margin-right:5px }
  .adf-lab .k { font-size:10.5px; font-variation-settings:var(--axis-active); letter-spacing:.07em;
                text-transform:uppercase; color:var(--ink-muted) }
  .adf-lab .cnt { font-size:11px; color:var(--muted); font-variant-numeric:tabular-nums }
  .adf input, .adf textarea, .adf select { width:100%; box-sizing:border-box; border:0;
            border-radius:var(--radius-card);
            padding:11px 15px; font:inherit; font-size:13.5px; color:var(--ink-strong);
            background:var(--paper); box-shadow:var(--shadow-field); resize:none; line-height:1.45 }
  .adf input::placeholder, .adf textarea::placeholder { color:var(--ink-muted) }
  /* Описание — 160 символов, и они обязаны быть видны целиком: в поле на две строки
     клиент правил текст, половину которого не видел, а скролл внутри маленького поля
     в панели шириной 300px не замечают вовсе. Высота считается по содержимому
     (autoGrow), а min-height держит поле ровным, пока текст короткий. */
  .adf textarea { min-height:96px; overflow:hidden }
  /* Фокус поле показывает само — оно уже продавлено; вторую границу не рисуем. */
  .adf input:focus, .adf textarea:focus, .adf select:focus { outline:none; box-shadow:var(--shadow-field) }
  .adf select { cursor:pointer; appearance:none; -webkit-appearance:none;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2373706a' stroke-width='2.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat:no-repeat; background-position:right 12px center; padding-right:32px }
  /* Реквизит для ОРД: поле ниже остальных (это одна фраза, не текст объявления) и
     с пояснением под ним — иначе «описание для ОРД» на экране про рекламу читается
     как второе описание объявления. */
  .adf.ad-ord textarea { min-height:56px }
  .adf-hint { margin-top:5px; font-size:11.5px; line-height:1.45; color:var(--muted) }
  .ad-mbtn { border:0; border-radius:var(--radius-mark); background:var(--paper);
             box-shadow:var(--shadow-chip); padding:9px 16px; font:inherit;
             font-size:13px; cursor:pointer; color:var(--ink-strong); display:flex;
             align-items:center; justify-content:center; gap:7px }
  .ad-mbtn:hover { color:var(--ink) }
  .ad-mbtn:active { transform:translateY(1px) }
  /* ── поле «что рекламируем» (ККТУ): обязательный реквизит маркировки ── */
  /* Внутри значение и кнопка стоят в один ряд, поэтому рамка у самого ряда, а не у
     блока: иначе подпись поля («ЧТО РЕКЛАМИРУЕМ») оказывалась внутри карточки и
     ломала общий ритм — у соседних полей подпись снаружи. */
  /* Кнопка прижата к верху, значение переносится: категория — это то, за что клиент
     отвечает перед ОРД, и читать её в виде «Страховые услуги для физич…» он не должен.
     Ради этого блок и растёт в высоту, а не ужимает текст. */
  .kk-row { display:flex; align-items:flex-start; gap:10px; border:0;
            border-radius:var(--radius-card); padding:11px 12px 11px 15px;
            background:var(--paper); box-shadow:var(--shadow-chip) }
  .kk-val { flex:1; min-width:0; font-size:13px; line-height:1.35 }
  .kk-val b { display:block; font-weight:600; white-space:normal; overflow-wrap:anywhere }
  .kk-val small { display:block; color:var(--muted); font-size:11px; margin-top:3px;
                  white-space:normal; line-height:1.4; overflow-wrap:anywhere }
  .kk-none { color:var(--muted); font-size:12.5px }
  .kk-row .ad-mbtn { flex:0 0 auto; white-space:nowrap; padding:7px 12px; font-size:12.5px }
  /* Обязательность видна СРАЗУ — точкой у подписи; красным поле становится только
     после неудачной попытки запуска. Красить всю форму при открытии нельзя: клиент
     ещё ничего не сделал, а экран уже кричит на него. */
  .adf.req .adf-lab .k::after { content:' •'; color:var(--bad) }
  .adf.need input, .adf.need textarea, .adf.need select,
  .ad-kktu.need .kk-row { border-color:#e8c5bf; background:#fdf7f5 }
  .adf.need .adf-lab .k { color:var(--bad) }
  /* Реквизиты маркировки — свой раздел под чертой, но НЕ спрятанный: оба поля
     обязательны, и человек должен видеть, что именно уедет в реестр под его именем.
     Компактность берём шириной (два поля в ряд), а не сокрытием. */
  .ad-mark { margin-top:16px; border-top:1px solid var(--border); padding-top:11px }
  .ad-mark-h { display:flex; align-items:baseline; gap:9px }
  .ad-mark-h .k { font-size:10.5px; font-weight:700; letter-spacing:.05em;
                  text-transform:uppercase; color:var(--muted) }
  .ad-mark-h .cnt { flex:1; min-width:0; font-size:11.5px; color:var(--muted);
                    overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
  /* В колонку, а не в ряд: в форме шириной под пол-ленты карточка ККТУ рядом с
     полем ОРД сжимается до кнопки «Изменить» и обрезанного названия категории. */
  .ad-mark .adf { margin-top:11px }
  .play { position:absolute; inset:0; margin:auto; width:40px; height:40px }
  /* ── объявление: правится прямо в телефоне ──────────────────────────────
     Формы рядом нет. Раньше объявление жило на экране в двух экземплярах — поля
     слева, превью справа, — и человек писал в одном месте, а проверял в другом.
     Теперь поля стоят внутри самого объявления, а кнопка и медиа настраиваются
     нажатием на себя (всплывашки .ad-pop). Рядом остаётся только то, чего в
     объявлении не видно: данные для маркировки.

     Показан аппарат, а не карточка: белая рамка, строка состояния, шапка канала
     с «‹ Назад», обои и лента. Тёмный прямоугольник посреди бумаги читался
     просто плашкой и на Telegram похож не был. */
  /* Слева телефон, справа маркировка. Это не возврат к «форма и превью»: справа
     не копия объявления, а то, чего в нём нет и не будет — реквизиты для
     реестра. Их заполняют один раз и не перечитывают, поэтому им место сбоку,
     а не вровень с текстом, который переписывают по десять раз. */
  /* Раскладку решает МЕСТО, а не ширина окна: колонка документа бывает и 548px,
     и 820px при одном и том же окне (сайдбар, .wide), и медиазапрос тут врал бы.
     flex-wrap с min-width у маркировки складывает её под телефон сам, как только
     рядом перестаёт помещаться. */
  .ad-live { display:flex; flex-wrap:wrap; gap:30px 40px;
             justify-content:center; align-items:flex-start }
  .ad-live-main { flex:0 0 auto; display:flex; flex-direction:column; align-items:center }
  .ad-phone { display:flex; flex-direction:column; align-items:center }
  /* Явно называем среду один раз над аппаратом. Это полезнее длинной инструкции
     снизу: контекст считывается до просмотра, а не после него. */
  .tg-context { display:flex; align-items:center; gap:7px; margin:0 0 12px;
                font-size:12px; color:var(--ink-muted);
                font-variation-settings:var(--axis-active) }
  .tg-logo { width:20px; height:20px; display:inline-flex; align-items:center;
             justify-content:center; border-radius:50%; background:#2f83e0; color:#fff;
             font-size:10px; line-height:1; transform:rotate(-38deg) }
  /* Корпус светлый, экран тёмный — так и выглядит телефон с тёмной темой.
     Рамка нужна: без неё тёмный прямоугольник снова читается плашкой. */
  .tg-device { width:330px; max-width:100%; border-radius:34px; overflow:hidden;
               background:#17212b; box-shadow:var(--shadow-card), 0 0 0 8px #fff,
               0 0 0 9px rgb(0 0 0 / .12); text-align:left }
  .tg-bar { display:flex; justify-content:space-between; align-items:center;
            padding:9px 20px 5px; font-size:11px; color:#e7edf3;
            font-variation-settings:var(--axis-active) }
  .tg-bar-r { letter-spacing:1px; opacity:.75 }
  .tg-nav { display:flex; align-items:center; gap:9px; padding:6px 14px 10px;
            border-bottom:1px solid rgb(255 255 255 / .07); background:#17212b }
  .tg-back { color:#62a3e8; font-size:25px; line-height:1; flex:0 0 auto }
  .tg-ch { flex:1; min-width:0; text-align:left }
  .tg-ch b { display:block; font-size:13.5px; color:#e7edf3; overflow:hidden;
             text-overflow:ellipsis; white-space:nowrap }
  .tg-ch small { font-size:10.5px; color:#8b9aa8 }
  .tg-ava { width:28px; height:28px; border-radius:50%; background:#4a7fb5; color:#fff;
            display:flex; align-items:center; justify-content:center; font-size:13px;
            flex:0 0 auto; font-variation-settings:var(--axis-active) }
  .tg-more { flex:0 0 auto; color:#8b9aa8; font-size:12px; letter-spacing:1px }
  /* Обои — мягкий градиент, а не картинка: узнаваемости хватает, а лишний
     килобайт и чужой рисунок в кабинете не нужны. */
  /* Обои — мягкий градиент, а не картинка: узнаваемости хватает, а чужой
     рисунок в кабинете ни к чему. */
  .tg-screen { padding:12px 10px 14px; min-height:210px;
               background:linear-gradient(160deg,#0f1a24,#16222e 55%,#101b26) }
  /* Посты канала — фон, а не содержание: читать их не надо. */
  .tg-post { background:#1c2a38; border-radius:12px; padding:8px 11px 20px; margin-bottom:8px;
             position:relative;
             font-size:11.5px; color:#7c8794; line-height:1.45 }
  .tg-post-meta, .tg-ad-meta { position:absolute; right:10px; bottom:5px; font-size:9px;
                               color:#697887; font-variant-numeric:tabular-nums }
  /* Синяя полоса слева и подпись «Реклама» — так это выглядит в приложении. */
  .tg-ad { position:relative; background:#1c2a38; border-radius:12px;
           border-left:3px solid #62a3e8; padding:10px 12px 12px }
  .tg-ad-top { display:flex; justify-content:space-between; align-items:center; margin-bottom:6px }
  .tg-mark { font-size:12px; color:#62a3e8; font-variation-settings:var(--axis-active) }
  .tg-x { font-size:13px; color:#7c8794 }
  /* Медиа кликается: по нему открывается выбор файла или генерация. */
  #adMediaBox.has-media { cursor:pointer; position:relative }
  .tg-media { border-radius:9px; overflow:hidden; margin-bottom:9px; position:relative;
              aspect-ratio:16/9; background:linear-gradient(135deg,#243748,#151f2c) }
  .tg-media img, .tg-media video { width:100%; height:100%; object-fit:cover; display:block }
  .tg-media .dur { position:absolute; left:8px; top:8px; font-size:10px; color:#fff;
                   background:rgb(0 0 0 / .5); padding:1px 6px; border-radius:5px }
  #adMediaBox.has-media:hover .tg-media { filter:brightness(.93) }
  .tg-edit-tag { position:absolute; right:7px; top:7px; z-index:1; padding:3px 7px 4px;
                 border-radius:6px; background:rgb(13 24 35 / .8); color:#fff;
                 font-size:9.5px; opacity:.88; pointer-events:none }
  /* Поля объявления. Это настоящие input/textarea — на них висит вся обвязка, —
     но выглядеть они обязаны текстом Telegram, а не полями ввода: рамка тут
     сразу возвращает форму, от которой мы и уходили. Подсветка только под
     курсором и в фокусе. */
  .tg-edit { position:relative; display:flex; align-items:flex-start; padding-right:31px;
             border-radius:6px; transition:background var(--dur-hover) var(--ease-out) }
  .tg-edit:hover, .tg-edit:focus-within { background:rgb(98 163 232 / .14) }
  .tg-t, .tg-d { display:block; width:100%; box-sizing:border-box; border:0; outline:0;
                 background:transparent; color:#e7edf3; font-family:inherit;
                 padding:2px 5px; margin:0 -5px; border-radius:5px; resize:none;
                 transition:background var(--dur-hover) var(--ease-out) }
  .tg-t:hover, .tg-d:hover, .tg-t:focus, .tg-d:focus { background:transparent }
  .tg-t { font-size:14px; font-variation-settings:var(--axis-active); line-height:1.3 }
  .tg-d { margin-top:2px; font-size:12.5px; line-height:1.45; color:#c4cdd6; overflow:hidden }
  .tg-t::placeholder, .tg-d::placeholder { color:#5c6773 }
  .tg-pencil { position:absolute; right:17px; top:4px; color:#7f9cb8; font-size:11px;
               line-height:1; pointer-events:none }
  .tg-edit-description .tg-pencil { top:5px }
  .tg-gen { position:absolute; right:0; top:1px; margin:0; color:#e7edf3; opacity:.62 }
  .tg-gen:hover { opacity:1 }
  .tg-edit .genover { padding:0 7px; justify-content:flex-start; flex-direction:row;
                      background:#22384b; color:#fff; border-radius:6px;
                      font-size:10px; white-space:nowrap }
  .tg-edit .genover .spin { border-color:rgb(255 255 255 / .3); border-top-color:#fff }
  /* Кнопка объявления — она же ручка: нажатие открывает выбор действия и адреса. */
  .tg-btn { margin-top:10px; width:100%; display:flex; align-items:center; justify-content:center;
            gap:7px; border:0; border-radius:9px; padding:9px 10px 10px; background:#2f83e0;
            color:#fff; font:inherit; font-size:13px; cursor:pointer;
            font-variation-settings:var(--axis-active) }
  .tg-btn:hover { background:#3a8ae0 }
  .tg-arr { opacity:.7; font-size:12px }
  .tg-ad-meta { bottom:3px; right:12px; color:#708090 }
  .tg-ad { padding-bottom:20px }

  /* Пока курсор над телефоном — правимое подчёркивается. Постоянное подчёркивание
     вернуло бы объявлению вид формы, а без всякого его не найти вовсе: показываем
     только тому, кто уже сюда тянется. */
  .tg-device:hover .tg-edit { box-shadow:inset 0 -1px 0 rgb(98 163 232 / .45) }
  .tg-device:hover .tg-btn { outline:1px dashed rgb(255 255 255 / .35); outline-offset:2px }
  .tg-device:hover #adMediaBox.has-media .tg-media { outline:1px dashed rgb(255 255 255 / .3);
                                                     outline-offset:-3px }
  .tg-edit-media.need .tg-media, .tg-btn.need { outline:2px solid #e8c5bf; outline-offset:2px }

  /* Всплывашка у элемента объявления. Единственный случай тени наружу, кроме
     карточки объявления и меню: она висит над бумагой. */
  /* Ширину задаёт ссылка, а не список действий: адрес с utm-метками длиннее
     сотни символов, и в узкой всплывашке от него видно треть. Играть высотой
     вместо ширины бессмысленно — от переносов адрес читаться не начинает. */
  /* popover: браузер сам кладёт её в верхний слой и центрирует своим
     `inset:0; margin:auto`. Координаты ставит adPop, поэтому инсеты и поля
     снимаем — иначе всплывашка встанет посреди экрана, а не у кнопки. */
  .ad-pop { position:fixed; inset:auto; margin:0; border:0; overflow:visible;
            width:520px; max-width:calc(100vw - 24px);
            padding:14px; border-radius:var(--radius-card); color:var(--ink-strong);
            background:var(--paper); box-shadow:var(--shadow-pop) }
  .ad-pop-h { font-size:10.5px; letter-spacing:.07em; text-transform:uppercase;
              color:var(--ink-muted); font-variation-settings:var(--axis-active) }
  /* Действий тринадцать, и списком во всю высоту всплывашка накрывала телефон
     целиком — то есть прятала ровно то, ради чего её открыли. Прокручиваем. */
  .ad-pop-list { display:flex; flex-direction:column; gap:3px; margin-top:7px;
                 max-height:212px; overflow-y:auto; scrollbar-width:thin;
                 scrollbar-color:rgb(0 0 0 / .22) transparent }
  .ad-pop-list::-webkit-scrollbar { width:5px }
  .ad-pop-list::-webkit-scrollbar-thumb { background:rgb(0 0 0 / .22); border-radius:99px }
  .ad-pop-item { border:0; background:none; text-align:left; padding:7px 9px; border-radius:8px;
                 font:inherit; font-size:13.5px; color:var(--ink-strong); cursor:pointer }
  .ad-pop-item:hover { background:var(--ink-faint) }
  .ad-pop-item.sel { background:var(--ink); color:var(--paper);
                     font-variation-settings:var(--axis-active) }
  /* Переносится по любому символу: в адресе нет пробелов, и без break-all он
     уехал бы одной строкой за край. Скролла внутри нет — поле растёт под текст
     (growUrl), иначе правится хвост, которого не видно. */
  .ad-pop-url { display:block; width:100%; box-sizing:border-box; margin-top:7px; border:0;
                border-radius:var(--radius-field); padding:9px 13px 11px;
                background:var(--paper); box-shadow:var(--shadow-field);
                font-family:var(--font-mono); font-size:12.5px; line-height:1.5;
                color:var(--ink-strong); outline:0; resize:none; overflow:hidden;
                word-break:break-all; max-height:8.5em }
  .ad-pop-req { display:flex; flex-wrap:wrap; gap:4px 8px; margin-top:10px;
                font-size:11px; color:var(--ink-muted) }
  .ad-pop-err { font-size:11.5px; color:var(--bad) }
  .ad-pop-err:empty { display:none }

  /* В боковой колонке маркировка идёт столбиком: поля во всю её ширину.
     min-width — та самая точка, ниже которой она уезжает под телефон. */
  .ad-live .ad-mark { flex:1 1 300px; min-width:290px; max-width:560px; margin-top:0 }
  .ad-live .ad-mark .adf { margin-top:14px }
  .ad-actions { display:flex; flex-wrap:wrap; gap:10px; margin-top:12px; align-items:center }
  .ad-ghost { border:0; border-radius:var(--radius-mark); background:var(--paper);
              box-shadow:var(--shadow-chip); padding:10px 20px 12px; font:inherit;
              font-size:13.5px; font-weight:600; cursor:pointer; color:var(--text); display:inline-flex; align-items:center; gap:6px }
  .ad-ghost:hover { background:var(--panel) }
  /* Два действия по счёту равнозначны — скачать и посмотреть все счета, — и
     стоять им положено в ряд. Друг под другом они читались лестницей, где
     нижнее важнее верхнего. */
  .ord-acts { display:flex; flex-wrap:wrap; gap:10px; justify-content:center;
              align-items:center; margin-top:16px }
  .ord-acts .act-btn, .ord-acts .ad-ghost { margin-top:0 }
  /* Отмена — не кнопка. Таблетка с обводкой ставила её вровень с оплатой, хотя
     это выход, а не действие: строка текста, и та красная. */
  .ord-cancel { display:block; margin:18px auto 0; padding:4px 0; border:0; border-radius:0;
                background:transparent; box-shadow:none; color:var(--bad);
                font-size:12.5px; font-weight:400;
                font-variation-settings:var(--axis-body) }
  .ord-cancel:hover { background:transparent; box-shadow:none; text-decoration:underline }
