/* ══════════════════════════════════════════════════════════════════════════
   ОКНО ДОКУМЕНТА — ОДИН СПОСОБ НА ВСЕ ДОКУМЕНТЫ

   Заведено решением заказчика В-71 от 19.09.2026 («там должно быть видно
   как у них реализованы окна… нам точно так же надо»), требования
   ТР-588, ТР-590, ТР-591, ТР-593, ТР-594. Дата файла — 21.09.2026.

   ПОЧЕМУ ОТДЕЛЬНЫМ ФАЙЛОМ, А НЕ В `base.css`. `base.css` — побайтная
   копия прототипа (ТР-573), его размер сверяется при выкладке. Всё, чего
   в прототипе нет, живёт слоем. `app.css` в этот же день правит другой
   заход (палитра В-71, ТР-592) — два захода в одном файле неизбежно
   разойдутся, поэтому окно взято третьим файлом.

   ЦВЕТА — ТОЛЬКО ТОКЕНАМИ. Ни одного шестнадцатеричного значения ниже:
   палитру задаёт `base.css` и слой палитры, а окно её ПОТРЕБЛЯЕТ.
   Иначе при смене вида (а она уже была дважды: В-65 отменён В-66,
   В-67 частично отменён В-71) окно осталось бы в прежних цветах.
   По этой же причине здесь НЕ задан цвет главной кнопки: `.button--primary`
   красит палитра, окно только ставит кнопку на место.

   ВСЕ ПАРЫ ТЕКСТ/ФОН ВЗЯТЫ ИЗ ИЗМЕРЕННЫХ В `base.css`, и ниже названы
   числами, чтобы «не ниже 4.5:1» не проверялось на глаз:
     --text  на --surface   17.22 светлая · 12.33+ тёмная
     --text  на --surface2  13.70 светлая · 12.33  тёмная
     --text2 на --surface2   5.91 светлая ·  5.80  тёмная
     --accent-main    на --surface2   6.13 светлая ·  6.32  тёмная
   Разделитель в колонке реквизитов взят `--line`, а НЕ `--line-inner`:
   в тёмной теме `--line-inner` равен `--surface2`, то есть на поверхности
   реквизитов он невидим вовсе.
   ══════════════════════════════════════════════════════════════════════════ */

:root{
  /* Размеры окна. Цветов здесь нет и быть не может. */
  --dialog-width:  1180px;  /* ширина за столом, дальше ограничивает 94vw */
  --dialog-height:   940px;   /* окно не растёт вместе с большим монитором */
  --dialog-props:  300px;   /* колонка реквизитов — как на записи Gectaro */
  --dialog-bar: 0px;    /* ширину полосы прокрутки подставляет dialog.js */
}

/* ─── 1. ЗАМОК СТРАНИЦЫ ────────────────────────────────────────────────────
   Пока окно открыто, страница под ним не прокручивается (ТР-594).

   Взято `overflow: hidden`, а НЕ приём с `position: fixed` на теле:
   фиксация тела теряет положение прокрутки и требует его восстанавливать
   числом — то есть заводит ВТОРОЙ источник одного «где мы стоим», и один
   из них начнёт врать. При `overflow: hidden` положение прокрутки не
   трогается вовсе, и возвращать нечего.

   Плата названа: исчезнувшая полоса прокрутки сдвигает страницу вправо
   на свою ширину. Её ширину меряет dialog.js и кладёт в `--dialog-bar`;
   на телефоне и на macOS полоса накладная, ширина 0, правило вхолостую. */
html[data-dialog-open="1"],
html[data-dialog-open="1"] body{ overflow: hidden; }
html[data-dialog-open="1"] body{ padding-right: var(--dialog-bar, 0px); }

/* ─── 2. ПОДЛОЖКА ──────────────────────────────────────────────────────────
   Страница затемнена и просвечивает — токен `--backdrop` тот же, что под
   выдвижным меню. z-index 100: выше всего, что есть в base.css
   (максимум там 90 — короткое подтверждение действия).

   Закрытое окно спрятано `visibility`, а не только прозрачностью. Причина
   записана в самом base.css у выдвижного меню: иначе все ссылки внутри
   стоят в порядке Tab на КАЖДОМ экране, и человек с клавиатуры жмёт Tab
   по невидимому. `dialog.js` на этом же держит захват фокуса: он считает
   фокусируемыми только то, у чего есть прямоугольник. */
.dialog-layer{
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  /* сверху больше: там, ВНЕ окна, стоит крестик */
  padding: calc(var(--target) + var(--p4)) var(--p5) var(--p5);
  background: var(--backdrop);
  /* Горизонтальной прокрутки страницы из-за окна быть не может:
     широкая таблица внутри прокручивается в своей области (ТР-593). */
  overflow: hidden;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .16s ease, visibility 0s linear .16s;
}
.dialog-layer[data-open="1"]{
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity .16s ease, visibility 0s linear 0s;
}
/* Адресная строка браузера на телефоне съедает часть 100vh; dvh мерит
   то, что видно сейчас, — иначе подвал с главной кнопкой уезжает под неё. */
@supports (height: 100dvh){
  .dialog-layer{ height: 100dvh; }
}

@media (prefers-reduced-motion: reduce){
  .dialog-layer{ transition: visibility 0s linear 0s; }
  .dialog-layer[data-open="1"] .dialog__frame{ transform: none; }
}

/* ─── 3. ОБОЛОЧКА: окно плюс крестик снаружи ───────────────────────────────
   Крестик стоит ВНЕ окна, справа сверху, но внутри подложки — как
   на записи. Поэтому ему нужна точка отсчёта, привязанная к окну,
   а не к экрану: при коротком экране окно поднимается к верхнему краю,
   и крестик, привязанный к экрану, наехал бы на шапку.

   `max-height: 100%` в min() — чтобы 88vh не вылезло за вычетом отступов
   подложки на низком окне браузера. */
.dialog__shell{
  position: relative;
  display: flex; flex-direction: column;
  width: min(var(--dialog-width), 94vw);
  max-height: min(88vh, var(--dialog-height), 100%);
  min-height: 0;
}

.dialog__close{
  position: absolute; right: 0; top: calc(-1 * (var(--target) + var(--p2)));
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--target); height: var(--target);   /* цель нажатия 44×44, WCAG 2.5.5 */
  padding: 0;
  /* Не белый значок на полупрозрачной завесе: контраст к ней считать
     нечем — под ней произвольная страница. Своя плотная подложка делает
     пару измеримой: --text на --surface = 17.22:1. */
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r-round);
  box-shadow: var(--shadow-float);
  font-size: var(--t4); line-height: 1; cursor: pointer;
}
.dialog__close:hover{ background: var(--surface2); }
.dialog__close:active{ background: var(--surface3); }

/* ─── 4. РАМКА ОКНА ────────────────────────────────────────────────────────
   Колонка из трёх частей: шапка — середина — подвал. Прокручивается
   только середина, шапка и подвал стоят на месте (ТР-588, ТР-591).

   Подвал прилипший ПО УСТРОЙСТВУ, а не `position: sticky`: он просто
   не входит в прокручиваемую область. Замер `getBoundingClientRect`
   до и после прокрутки даёт одно число — проверять нечего. */
.dialog__frame{
  display: flex; flex-direction: column;
  flex: 0 1 auto; min-height: 0; width: 100%;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  box-shadow: var(--shadow-float);
  overflow: hidden;              /* скругление не режется содержимым */
  transform: translateY(8px);
  transition: transform .16s ease;
}
.dialog-layer[data-open="1"] .dialog__frame{ transform: none; }

/* ─── 5. ШАПКА ОКНА ────────────────────────────────────────────────────────
   Крупный заголовок («Акт № 1 от 17 сен 2026»), под ним серым строка
   «кто и когда завёл», справа место под меню «⋮». */
.dialog__header{
  flex: 0 0 auto;
  display: flex; align-items: flex-start; gap: var(--p3);
  padding: var(--p4) var(--p5);
  border-bottom: 1px solid var(--line);
}
.dialog__header-body{ flex: 1 1 auto; min-width: 0; }

.dialog__title{
  margin: 0;
  font-size: var(--t5); font-weight: 600; line-height: var(--lh-heading);
  color: var(--text);
}
/* Заголовок получает фокус при открытии (ТР-594), но обводкой это
   не показывается: человек фокус сюда не переводил. */
.dialog__title:focus{ outline: none; }

.dialog__caption{
  margin: var(--p1) 0 0;
  font-size: var(--t2); color: var(--text2);   /* 5.91:1 к --surface */
}
.dialog__caption:empty{ display: none; }

.dialog__menu{ flex: 0 0 auto; display: flex; align-items: center; gap: var(--p2); }
.dialog__menu[hidden]{ display: none; }

/* ─── 6. СЕРЕДИНА: содержимое и реквизиты ──────────────────────────────────
   Слева шире — состав документа или поля формы; справа уже (≈300 px) —
   реквизиты столбиком. Колонки прокручиваются САМОСТОЯТЕЛЬНО: длинный
   состав акта не должен уносить наверх реквизиты, по которым его
   проверяют.

   `min-width: 0` обязателен обеим: без него широкая таблица внутри
   раздувает колонку грида, и появляется горизонтальная прокрутка. */
.dialog__middle{
  flex: 1 1 auto; min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--dialog-props);
}
/* Документ без реквизитов (заявка, извещение) не оставляет пустой
   колонки: её нет вовсе, содержимое занимает всю ширину. */
.dialog__middle[data-props="0"]{ grid-template-columns: minmax(0, 1fr); }

.dialog__body{
  min-width: 0; min-height: 0;
  overflow: auto; overscroll-behavior: contain;
  padding: var(--p5);
}

.dialog__props{
  min-width: 0; min-height: 0;
  overflow: auto; overscroll-behavior: contain;
  padding: var(--p4);
  background: var(--surface2);
  border-left: 1px solid var(--line);
}
.dialog__props[hidden]{ display: none; }

.dialog__props-name{
  margin: 0 0 var(--p3);
  font-size: var(--t1); font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text2);          /* 5.91:1 к --surface2 */
}

/* ─── 7. РЕКВИЗИТ — ДОГОВОР РАЗМЕТКИ ДЛЯ ТР-590 ────────────────────────────
   Незаполненный реквизит показан ССЫЛКОЙ-ДЕЙСТВИЕМ, а не пустым полем
   и не прочерком: пустое поле молчит о том, что с ним делать, и человек
   уходит звонить. Классы объявлены здесь, а ставит их страница документа
   (окно берёт её блоки как есть).

     <div class="prop">
       <span class="prop__name">Контрагент</span>
       <a class="prop__action" href="…">+ Выбрать</a>
     </div>

   Граница ТР-590: реквизит, который человек в этой роли менять НЕ вправе,
   ссылкой не притворяется — `prop__missing` с объяснением. */
.prop{
  display: flex; flex-direction: column; gap: var(--p1);
  padding: var(--p2) 0;
  border-bottom: 1px solid var(--line);
}
.prop:last-child{ border-bottom: 0; }

.prop__name{ font-size: var(--t1); color: var(--text2); }
.prop__value{ font-size: var(--t3); color: var(--text); }

/* Цель нажатия 44×44 и здесь: реквизит меняют пальцем на планшете. */
.prop__action{
  display: inline-flex; align-items: center; gap: var(--p1);
  min-height: var(--target); min-width: var(--target);
  font-size: var(--t3); color: var(--accent-main);   /* 6.13:1 к --surface2 */
  text-decoration: none; cursor: pointer;
}
.prop__action:hover{ text-decoration: underline; }

/* Прочерк с объяснением — недоступное ДЕЙСТВИЕ объясняется,
   а не исчезает молча. */
.prop__missing{ font-size: var(--t2); color: var(--text2); }

/* ─── 8. ПОДВАЛ: итог слева, кнопки справа (ТР-591) ────────────────────────
   Итог стоит рядом с кнопкой намеренно: состав акта длиннее экрана,
   и сумма — то, на что смотрят ПЕРЕД подписью. Сама сходимость суммы
   со строками — инвариант базы (В-52), и окно её не заменяет. */
.dialog__footer{
  flex: 0 0 auto;
  display: flex; align-items: center; gap: var(--p3);
  padding: var(--p3) var(--p5) calc(var(--p3) + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 1px solid var(--line);
}
.dialog__footer[hidden]{ display: none; }

.dialog__total{ flex: 1 1 auto; min-width: 0; font-size: var(--t4); color: var(--text); }
/* Документ без итога (заявка, извещение) не оставляет пустого места
   слева — кнопки прижимает к правому краю `margin-left: auto` ниже. */
.dialog__total:empty{ display: none; }

.dialog__buttons{
  flex: 0 0 auto; margin-left: auto;
  display: flex; align-items: center; gap: var(--p2); flex-wrap: wrap;
  justify-content: flex-end;
}

/* ─── 9. ТЕЛЕФОН: во весь экран, одна колонка (ТР-593) ─────────────────────
   Порог 768 px назван в самом требовании. Две колонки на 375 px дают
   горизонтальную прокрутку — то самое, из-за чего прораб уходит диктовать
   цифры в мессенджер.

   Реквизиты идут НИЖЕ содержимого, а не выше: открывают документ,
   чтобы увидеть документ. */
@media (max-width: 767.98px){
  .dialog-layer{ padding: 0; }

  .dialog__shell{
    width: 100%; height: 100%; max-height: 100%;
  }

  .dialog__frame{
    flex: 1 1 auto; height: 100%; max-height: 100%;
    border: 0; border-radius: 0; box-shadow: none;
  }

  /* Места снаружи больше нет — крестик переезжает в угол самого окна.
     Шапка освобождает под него место справа, иначе длинный номер акта
     уходит под крестик. */
  .dialog__close{
    top: calc(var(--p2) + env(safe-area-inset-top, 0px));
    right: var(--p2);
    z-index: 2;
    /* --target: 44 px до 560 px ширины и 56 px ниже — мера общая,
       и крестик растёт вместе с остальными целями нажатия. */
    width: var(--target); height: var(--target);
    box-shadow: none;
  }
  .dialog__header{
    padding: calc(var(--p3) + env(safe-area-inset-top, 0px))
             calc(var(--target) + var(--p4)) var(--p3) var(--p4);
  }

  /* Прокручивается вся середина целиком: две независимые области
     прокрутки на одном экране телефона — способ потерять обе. */
  .dialog__middle{
    display: block;
    overflow: auto; overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  .dialog__body,
  .dialog__props{ overflow: visible; min-height: 0; }
  .dialog__body{ padding: var(--p4); }
  .dialog__props{
    border-left: 0; border-top: 1px solid var(--line);
  }

  /* Подвал остаётся прилипшим, кнопки — во всю ширину и не ниже 56 px.
     Высоту здесь держит собственное число, а не --target-primary: та мера
     переключается на 560 px, а порог окна — 768. */
  .dialog__footer{
    flex-wrap: wrap; align-items: stretch;
    padding: var(--p3) var(--p4) calc(var(--p3) + env(safe-area-inset-bottom, 0px));
  }
  .dialog__total{ flex: 1 0 100%; font-size: var(--t3); }
  .dialog__buttons{ flex: 1 0 100%; flex-wrap: wrap; margin-left: 0; }
  /* ЗАМЕРЕНО 21.09.2026 НА 375×812, а не придумано: три кнопки в одну
     строку делят 343 px, то есть по 109 px, и «Сохранить в черновик»
     ломается на ТРИ строки. Поэтому главная кнопка встаёт первой и во всю
     ширину (`order: -1`), а остальные делят строку под ней и переносятся
     сами, если не помещаются. Главная видна без прокрутки — это прямая
     проверка ТР-593. */
  .dialog__buttons .button{ flex: 1 1 auto; min-width: 0; min-height: 56px; }
  .dialog__buttons .button--primary{ flex: 1 0 100%; order: -1; }
}

/* ═══ КОЛОНКА РЕКВИЗИТОВ ВНУТРИ ОКНА — 21.09.2026, найдено ЗАПУСКОМ ═══════
   Страница документа одноколоночная, и строка реквизита на ней — это
   `.row`: flex «имя слева, значение справа», где имя занимает до 46rem.
   В колонке окна ширина 300 px, и тот же flex ломает КАЖДОЕ СЛОВО
   значения в свой столбик: «Акт выполненных работ» читалось сверху вниз
   по одному слову. Замер 1440×900: строка реквизита 630 px высотой при
   колонке 300 px.

   Поэтому внутри окна строка реквизита кладётся В СТОЛБИК: имя сверху,
   значение под ним. Правила стоят ВНУТРИ `.dialog`, поэтому вид самой
   страницы не меняется — она остаётся вторым полноценным входом
   к документу (ТР-589).

   Объяснение реквизита (`.row__where`) на странице — абзац на всю ширину;
   в колонке он занял бы её целиком и утопил сами значения. Здесь он
   мельче и прижат к имени: он объясняет, почему реквизит такой,
   и читается вторым, а не первым. Совсем убрать его нельзя —
   это правило проекта: недоступное действие ОБЪЯСНЯЕТСЯ, а не прячется. */
.dialog__props .row{
  display: block;
  padding: var(--p3) 0;
}
.dialog__props .row__body{ max-width: none; }
.dialog__props .row__name{
  font-size: var(--t0); color: var(--text2); font-weight: 400;
}
.dialog__props .row__value{
  display: block; margin-top: var(--p1); text-align: left;
  font-size: var(--t2); font-weight: 600; white-space: normal;
}
.dialog__props .row__where{
  font-size: var(--t0); line-height: 1.4; color: var(--text3);
}
/* Ссылка-действие (ТР-590) в колонке — во всю её ширину и не ниже цели
   нажатия: в узкой колонке промах пальцем стоит дороже, чем на странице. */
.dialog__props .button--quiet{
  display: flex; width: 100%; justify-content: flex-start;
  margin-top: var(--p1);
}
