/* mail-files — вложения письма и полоса прикрепления.

   Стили этого куска почты складывают сюда, а не в app.css: над разделом
   работают в несколько рук, и общий файл означает, что правки затирают друг
   друга.

   Прежние `.mail-file` / `.mail-files` из app.css здесь не переопределяются, а
   заменяются новыми именами (`mail-att*`): переопределять чужой лист «сверху»
   значит оставить в системе два набора правил на один узел, и следующий, кто
   полезет менять отступ, будет менять не тот. */

/* ---------- цвет типа файла ----------

   Роман 27.08.2026: «мне достаточно просто показать цветом тип файла — не надо
   никаких вьюеров писать» и «как в Яндексе, с пометкой цвета: Excel зелёный,
   Word синий, PDF красный».

   Цвета берём из палитры Флоу, а не подбираем на глаз: `--green`, `--red`,
   `--amber` уже отвечают в системе за «хорошо», «плохо» и «внимание», и в
   плашке файла они читаются как принадлежность к семье, а не как оценка.
   «Синий» у нас — `--accent` (им же покрашен `badge--blue`), фиолетовый
   `--logo-to` достаётся картинкам: он свободен и заметно отличается от
   акцента, чтобы `.png` рядом с `.docx` не слились.

   Тон — не заливка, а подмешивание к подложке (`color-mix` с `--surface`):
   так одно правило работает и в светлой теме, и в тёмной, где подложка сама
   меняется, а плашка остаётся плашкой, а не светящимся пятном. */
.mail-att__plate--sheet { --att: var(--green); }
.mail-att__plate--text  { --att: var(--accent); }
.mail-att__plate--pdf   { --att: var(--red); }
.mail-att__plate--pack  { --att: var(--amber); }
.mail-att__plate--shot  { --att: var(--logo-to); }
.mail-att__plate--any   { --att: var(--text-faint); }

/* Запасного `--att` в общем правиле нет нарочно: у него тот же вес, что у
   правил вида выше, и он побеждал бы их порядком — все плашки выходили серыми.
   Вид проставляется всегда (`kindOf` возвращает `any`, если не узнал), так что
   подстраховка тут только вредит. */
/* Плашка залита цветом типа, буквы белые. Просьба Романа 28.08.2026: «лучше
   DOCX белым шрифтом, а ярлычок синим полностью, и так для всех типов
   вложений, которым такое превью положено».

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

   Белый на всех пяти красках намеренно, а не «где хватает контраста»: пять
   плашек с разным цветом букв — это пять разных значков, и глаз перестаёт
   видеть в них один род. Самая светлая краска (жёлтая у архивов) на белом
   держит 2,3:1 — мало для текста, но это не текст, а знак из четырёх букв
   девятым кеглем; тень под буквами вытягивает его до читаемого. */
.mail-att__plate {
  display: grid; place-items: center; flex: none;
  min-width: 30px; height: 18px; padding: 0 6px; font-size: 9.5px;
  border-radius: 5px;
  background: var(--att);
  color: #fff; text-shadow: 0 1px 1px rgb(0 0 0 / .28);
  font-weight: 700; letter-spacing: .3px; line-height: 1;
}

/* ---------- сами карточки ----------

   Вложение бывает двух видов, и разница между ними не в оформлении, а в том,
   чем файл является.

   Роман 27.08.2026 утром: «огромные вложения — нужно сделать их миниатюрнее,
   как в Spike. Слишком крупные и придают странный формат сообщения». Квадрат
   в сто точек с подписью в две строки давал письму из трёх строк вид
   страницы. Вечером того же дня, посмотрев боевой: «в превью jpeg не
   показываются в виде вложений как медиа в чате… у нас с тобой вложения
   куцые и некрасивые пока что». Оба раза он прав, и середина между двумя
   просьбами не в размере плитки: снимок и бумага — разные вещи, и мерить их
   одной меркой значит промахнуться то в одну сторону, то в другую.

   **Снимок — карточкой** (`--shot`): миниатюра во всю ширину, имя поверх неё
   на затемнении, как медиа в разговоре. У снимка вид и есть содержание:
   своё фото стенда человек узнаёт с одного взгляда и имя не читает вовсе.
   Утренняя правка свела снимок к плашке в 26 точек — и картинка перестала
   быть видна; об этом вечером и пришло замечание.

   **Бумага — строкой** (`--row`): цветная плашка типа, имя в две строки,
   вес, кнопка скачивания. Первую страницу PDF не рисуем и не собираемся (см.
   заголовок `mailFiles.js`): имя отвечает на вопрос «что это» точнее, а
   стоит нисколько.

   Наборы раздельные, а не один общий ряд: карточка снимка (сто точек) и
   строка бумаги (полсотни) в одном ряду равнялись бы по высокому, и бумага
   раздувалась бы вдвое ни за чем.

   **Про место.** Письмо с пятью вложениями не должно снова стать страницей —
   в этом и был утренний упрёк. Отсюда все числа: 132 точки на карточку
   снимка (три в ряд встают в пузырь переписки), 100 на миниатюру, 210 на
   строку бумаги — две в ряд.

   Замерено на стенде, пузырь в 540 точек, высота самого набора вложений.
   Одно вложение-снимок: было 34 точки, стало 150 — карточка на всю ширину
   (`:only-child`). Одно вложение-бумага: было 34, стало 57 — имя в две
   строки. Пять вложений, два снимка и три бумаги: было 114, стало 217.

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

   Один снимок в письме — случай частый и особый: «вот как встало на
   подложке». Ему отдаём двести точек (`:only-child`): ряда всё равно нет, а
   разглядывать в 132 точки то, ради чего письмо написано, — снова куцо.

   Ширина ограничена, а не резиновая: карточки стоят в пузыре, а пузырь
   меняет ширину от длины текста. Резиновая означала бы, что один и тот же
   файл в двух соседних письмах выглядит по-разному.

   Оформление одно на все места: письмо в ленте, письмо в списке и полоса
   приложенных файлов у окна нового письма. Прежде их было три, и один и тот
   же PDF выглядел в системе тремя разными вещами; это и был долг П-19.
   Половина его сидит не здесь: окно нового письма (`mailCompose.js`) рисует
   свою таблетку `mc-file` из `mail-compose.css`. Плитка для него готова и
   вынесена наружу — `attachChip` в `mailFiles.js`. */
/* Колонка ограничена шириной пузыря, а не содержимым, и это не придирка.

   `justify-items: start` прижимает вложения влево — так и надо. Но колонка
   `auto` растёт до самого широкого содержимого, а у сетки снимков ширина
   жёсткая, 300 точек. На телефоне пузырь — 282, и колонка в 300 вылезала за
   него: снимки уходили за край сообщения, а лента переписки ехала вбок на
   двадцать три точки. Роман прислал снимок ровно с этим и отдельно сказал
   про горизонтальную прокрутку в чат-виде.

   `max-width: 100%` у самой сетки тут бессилен: сто процентов она считает от
   **колонки**, то есть от тех же 300. Лечится только у колонки. */
.mail-atts {
  display: grid; gap: 8px; margin-top: 8px;
  justify-items: start;
  grid-template-columns: minmax(0, max-content);
}
.mail-atts__set,
.mail-attach__set { display: flex; flex-wrap: wrap; gap: 6px; }
/* Оговорка про высоту ряда здесь стояла до 28.08.2026 и больше не нужна:
   плитка снимка и плитка бумаги теперь одного роста, и равнять ряд не по
   чему. */

/* Общее у обоих видов — рамка, подложка и кегль. Ширина и отступы у каждого
   свои: там, где карточка снимка отдана картинке целиком, отступ означал бы
   белую кайму вокруг фотографии. */
/* Подложка плитки — на ступень светлее письма, а не вровень с ним. Роман
   28.08.2026: «плашки этих вложений сделать поконтрастнее на фоне тела письма,
   а то почти не видно». Так и было: в тёмной теме пузырь письма #1B1B27, а
   плитка стояла на `--surface-2` (#1F1F2B) — четыре единицы яркости, глазом
   не различимые вовсе, и карточка бумаги читалась как пятно в тексте.

   Берём `--surface-3` и рамку погуще: в обеих темах плитка теперь отделена от
   письма, а не угадывается. Считать её от цвета пузыря нельзя — пузырь бывает
   двух цветов (своё письмо цветное), и плитка на нём живёт своим правилом
   ниже. */
.mail-att {
  position: relative;
  display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid color-mix(in oklab, var(--border) 55%, var(--text-faint));
  border-radius: 8px;
  background: var(--surface-3); color: var(--text-soft);
  font: inherit; font-size: 12px; text-decoration: none; text-align: left;
}
/* Открывающая часть: в письме ссылкой служит почти вся карточка, но не вся —
   рядом стоит кнопка скачивания, а у приложенного файла крестик. Кнопку
   внутрь ссылки класть нельзя, поэтому они соседи, и ссылка забирает всё
   свободное место. */
.mail-att__open {
  display: flex; align-items: center; gap: 7px;
  flex: 1; min-width: 0;
  color: inherit; text-decoration: none;
}

/* ---------- бумага плиткой ----------

   Ровно как в Яндекс.Почте: имя сверху, цветная плашка типа — подвалом.
   Роман 28.08.2026 прислал оттуда четыре снимка: «хочу вот в таком стиле…
   это красиво и минималистично».

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

   Размеры одни со снимком (132×100) — и это второе, что даёт плитка. Прежде
   набор был **раздельным**: снимки своим рядом, бумаги своим, потому что в
   общем ряду ряд равнялся по высокому и строка бумаги раздувалась вдвое ни
   за чем. Одинаковая плитка снимает и это: наборы слились в один, и пять
   вложений письма встают тремя в ряд, как в образце. */
/* Фиолетовый отлив — только у плитки **без предпросмотра**.

   Роман 28.08.2026: «добавить лёгкий градиент фиолетового в блоке вложения
   (только для тех, у кого нет предпросмотра)… сейчас их вид мне не нравится,
   они не контрастны на фоне сообщений входящих особенно».

   Жалоба про контраст, а не про красоту, и решается она именно так. У снимка
   плитка сама себя показывает — кадром; у бумаги на её месте ровная заливка
   `--surface-3`, а пузырь входящего письма покрашен близким к ней тоном.
   Отлив разводит их, ничего не крича.

   Фиолетовый берём из логотипа (`--logo-from`, `--logo-to`) — тот же,
   которым покрашена шапка системы. Он не занят состоянием: зелёный, красный
   и янтарный в палитре Флоу означают «хорошо», «плохо» и «внимание», и
   плитка в любом из них читалась бы как оценка файла.

   Двенадцать процентов и восемь — это отлив, а не заливка: имя файла поверх
   должно остаться таким же читаемым, каким было. Подмешивание (`color-mix` с
   подложкой), а не готовый цвет: одно правило работает и в светлой теме, и в
   тёмной, где подложка сама меняется. */
.mail-att--tile {
  display: block; width: 132px; height: 100px; padding: 8px; border-radius: 10px;
  background-image: linear-gradient(150deg,
    color-mix(in oklab, var(--logo-from) 12%, transparent) 0%,
    color-mix(in oklab, var(--logo-to) 8%, transparent) 55%,
    transparent 100%);
}
/* Раскладка одна на два случая: у своей бумаги начинка лежит в ссылке
   (`__open`), у невыкачанной сама плитка — кнопка, и начинка лежит прямо в
   ней. Высоту при этом задаёт только плитка: `height: 100%` на самой кнопке
   растянул бы её по высокому соседу в ряду. */
.mail-att--tile .mail-att__open {
  display: flex; flex-direction: column; justify-content: space-between;
  align-items: stretch; gap: 6px; height: 100%;
}
.mail-att--tile.is-remote {
  display: flex; flex-direction: column; justify-content: space-between;
  align-items: stretch; gap: 6px;
}

/* Имя ужимается, всё прочее — нет: `min-width: 0` снимает с текста
   собственный минимум по ширине, иначе длинное имя распирало бы карточку
   мимо потолка вместо многоточия. */
.mail-att__name {
  min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
/* Имя в две строки, как в образце. Одной строкой «Протокол согласования
   цвета.docx» обрывался на «Протокол согласов…». Две — потолок: третья
   ничего не добавляет, а высоту набора растит на всех сразу. */
.mail-att--tile .mail-att__name {
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical;
  white-space: normal; overflow-wrap: anywhere; line-height: 1.3;
}
/* Подвал плитки: плашка типа и вес в одну строку. Вес приглушён и стоит
   после плашки — по нему не узнают файл, но по нему понимают, стоит ли ждать
   загрузки. */
.mail-att__foot { display: flex; align-items: center; gap: 6px; min-width: 0; }
.mail-att__size { flex: none; color: var(--text-faint); white-space: nowrap; font-size: 11px; }

/* ---------- снимок карточкой ---------- */
/* Рост задан плитке, а не картинке внутри: у бумаги те же 132×100, и ряд из
   снимков вперемешку с бумагами обязан стоять ровно. Считай мы высоту от
   картинки, рамка прибавляла бы к снимку две точки — и ряд заметно рябил. */
.mail-att--shot {
  display: block; overflow: hidden;
  width: 132px; height: 100px; padding: 0; border-radius: 10px;
}
.mail-att--shot .mail-att__open { display: block; }
/* `cover`, а не `contain`: миниатюра приходит с сохранённой пропорцией, и в
   рамке 132×100 у вертикального снимка осталось бы по сорок точек пустоты с
   боков. Обрезка честнее — по ней всё равно узнают, а рамка держит ряд. */
.mail-att__shot {
  display: block; width: 100%; height: 100%;
  object-fit: cover; background: var(--surface-3);
}
/* Подпись поверх снимка, а не строкой под ним: строка стоила бы двадцати
   точек на каждой карточке. Затемнение — от чёрного, а не от подложки темы:
   лежит оно на фотографии, а не на интерфейсе, и белое имя обязано читаться
   и на светлом небе, и на тёмной коробке. */
.mail-att__cap {
  position: absolute; inset: auto 0 0 0;
  display: flex; align-items: baseline; gap: 6px;
  padding: 16px 8px 6px;
  background: linear-gradient(to top,
    rgb(0 0 0 / .8) 0%, rgb(0 0 0 / .5) 55%, rgb(0 0 0 / 0) 100%);
  color: #fff; font-size: 11px; line-height: 1.25;
}
/* Кегль подписи меньше, чем у строки бумаги: на 132 точках каждая доля
   пункта — это ещё пара букв имени до многоточия, а читают её на пёстром
   снимке, где мелкое не мельчит. */
.mail-att__cap .mail-att__name { flex: 1; font-size: 10.5px; }
.mail-att__cap .mail-att__size { color: rgb(255 255 255 / .74); font-size: 10px; }
/* Один снимок в письме — случай частый и особый: «вот как встало на
   подложке». Ряда всё равно нет, и разглядывать ради этого 132 точки куцо. */
.mail-atts__set > .mail-att--shot:only-child { width: 200px; height: 148px; }

/* ---------- снимки чат-вида: сетка медиа ----------

   Роман 28.08.2026, со снимком Spike: «в чатовой почте сделай предпросмотр
   вложений-картинок вот таким образом… Вложения-картинки должны выглядеть как
   вложения в чате, только под текстом».

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

   **Числа взяты у чата, все до одного** (`.msg__album` в app.css): триста
   точек ширины, зазор в два пикселя, два — в ряд, три — крупный слева и два
   столбиком, четыре — квадрат, дальше по три в ряду, ячейки квадратные. Ни
   одно из них не подбиралось заново. Почта и чат стоят в одном окне одной
   системы, и снимок, который в почте выглядит иначе, чем в чате, читается как
   другая программа.

   Ширина фиксированная, а не «во всю ширину пузыря»: пузырь меняет ширину от
   длины текста, и резиновая сетка означала бы, что один и тот же снимок в
   двух соседних письмах разного размера. В чате ровно так же — там ширина
   пузыря с медиа как раз и **задаётся** снимком.

   **Про место.** Замерено на стенде, пузырь до 640 точек, высота самой
   сетки. Один снимок поперёк (1600×1200) — 300×225, по пропорциям кадра. Один
   вдоль (1200×1800) — 300×400, это и есть потолок: рамка уже глубины кадра, и
   он подрезан. Два — 300×150, три — 300×200, четыре — 300×300, пять и шесть —
   300×199.

   Пять снимков плитками 132×100 занимали бы в том же пузыре два ряда, то есть
   206 точек. Сетка — 199. **Сетка не стоит письму ничего, а снимок в ней виден
   вчетверо крупнее.** Дальше письмо не пухнет вовсе: шесть ячеек потолок, и
   седьмой скан договора добавляет не ряд, а число на последней плитке. */
.mail-shots {
  --mail-shot: 300px;
  display: grid; gap: 2px;
  width: var(--mail-shot); max-width: 100%;
  border-radius: 10px; overflow: hidden;
}
.mail-shots__cell {
  position: relative; display: block; overflow: hidden;
  background: var(--surface-3); line-height: 0;
}
.mail-shots__link { display: block; width: 100%; height: 100%; }
/* `cover`, а не `contain`: в сетке кадр узнают, а разглядывают его в окне
   поверх системы, куда и ведёт нажатие. Поля вместо обрезки читались бы
   дырами между снимками. */
.mail-shots__img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Рамку одиночного снимка проставляет разметка по загрузке (`fitOne` в
   `mailFiles.js`) — до неё стоит эта, чтобы письмо не дёргалось на приезде
   картинки. */
.mail-shots--one .mail-shots__cell { aspect-ratio: 4 / 3; }
/* Значок или обрезок скриншота растягивать не за чем: он остаётся своего
   размера, и сетка ужимается под него. */
.mail-shots:has(.is-small) { width: auto; }
.mail-shots--one .mail-shots__cell.is-small { aspect-ratio: auto; }
.mail-shots--one .is-small .mail-shots__img { width: auto; height: auto; max-width: 100%; }

.mail-shots--two { grid-template-columns: 1fr 1fr; aspect-ratio: 2 / 1; }
/* Три: первый снимок во всю высоту слева, два других столбиком справа. */
.mail-shots--three {
  grid-template-columns: 2fr 1fr; grid-template-rows: 1fr 1fr; aspect-ratio: 3 / 2;
}
.mail-shots--three > :first-child { grid-row: span 2; }
.mail-shots--four {
  grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; aspect-ratio: 1 / 1;
}
/* Пять и больше — по три в ряду, ячейки квадратные: число снимков заранее
   неизвестно, и жёсткая пропорция всей сетки тут врала бы. */
.mail-shots--many { grid-template-columns: repeat(3, 1fr); }
.mail-shots--many .mail-shots__cell { aspect-ratio: 1 / 1; }

/* Подпись — только у одиночного снимка, и та же, что у плитки. В сетке её
   нет: имена файлов, набранные поверх шести снимков сразу, — это шесть
   строк мелкого текста на месте картинок, ради которых сетка и заведена. Имя
   там живёт в подсказке и в окне просмотра. У одиночного места хватает, а
   имя у него как раз то самое («макет-3.jpg»), по которому договариваются. */
.mail-shots--one .mail-att__cap { padding: 24px 10px 8px; }
.mail-shots--one .mail-att__cap .mail-att__name { font-size: 12px; }
.mail-shots--one .mail-att__cap .mail-att__size { font-size: 11px; }

/* «Ещё N» на последней плитке. Нажатие проходит сквозь: под числом живой
   снимок, и окно с пачкой (в ней все, а не шесть) открывают именно им. */
.mail-shots__more {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background: rgb(0 0 0 / .55); color: #fff;
  font-size: 22px; font-weight: 600; line-height: 1;
  pointer-events: none;
}

/* ---------- снимок, который ещё в почте ----------

   У писем из истории вложений на диске нет — только опись. Плитка стоит на
   своём месте в сетке с самого начала: письмо не должно менять высоту под
   рукой у читающего, когда снимок доедет.

   Отличается она тем же, чем невыкачанная бумага, — приглушённостью и
   пунктиром, а не пустой рамкой и не значком поломки. Файл есть, он просто
   ещё едет. */
.mail-shots__cell.is-wait {
  background: color-mix(in oklab, var(--text-faint) 7%, var(--surface-2));
  outline: 1px dashed color-mix(in oklab, var(--text-faint) 32%, transparent);
  outline-offset: -1px;
}
.mail-shots__wait {
  display: grid; place-content: center; justify-items: center; gap: 5px;
  width: 100%; height: 100%; padding: 6px;
  border: 0; background: none; cursor: pointer;
  color: var(--text-faint); font: inherit; font-size: 11px; line-height: 1.2;
}
.mail-shots__wait:hover { color: var(--accent); }
/* Не приехал. Пунктир краснеет, значок остаётся тем же: это не «файла нет»,
   а «в этот раз не вышло», и нажатие по-прежнему что-то делает. */
.mail-shots__cell.is-failed {
  outline-color: color-mix(in oklab, var(--red) 45%, transparent);
}
.mail-shots__cell.is-failed .mail-shots__wait { color: var(--red); }
/* Пока идёт забор — та же полоска понизу, что и у плитки бумаги (её правила
   ниже, у раздела «пока файл едет из почты»). Знак один на оба вида: и там и
   там он значит ровно одно. */
.mail-shots__cell.is-taking .mail-shots__wait { cursor: default; }

/* Снимка не будет: байты подмело уборкой кэша, а пути к части письма нет,
   либо почта отказала. Плитка оборачивается бумагой — тем же именем и той же
   цветной плашкой, что и везде. Пустая рамка на этом месте читалась бы
   поломкой системы, а поломки тут нет: файл просто не достать. */
.mail-shots__cell.is-cold { background: var(--surface-2); }
.mail-shots__cold {
  display: flex; flex-direction: column; justify-content: space-between; gap: 6px;
  width: 100%; height: 100%; padding: 8px;
  color: var(--text-soft); font-size: 12px; line-height: 1.3;
}
.mail-shots__cold .mail-att__name {
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical; white-space: normal; overflow-wrap: anywhere;
}

/* Кнопка скачивания у ячейки сетки — та же и на том же месте, что у плитки:
   углом и по наведению. Своих правил у неё почти нет, только показ (правило
   ниже держится на `.mail-att:hover`, а ячейка сетки — не `.mail-att`). */
.mail-shots__cell .mail-att__get { background: rgb(0 0 0 / .5); color: #fff; }
.mail-shots__cell:hover .mail-att__get,
.mail-shots__cell:focus-within .mail-att__get { opacity: 1; pointer-events: auto; }
.mail-shots__cell .mail-att__get:hover { background: rgb(0 0 0 / .8); color: #fff; }

/* ---------- кнопка «скачать» ----------

   Углом поверх плитки — у обоих видов одинаково, и **по наведению**: так
   просил Роман 28.08.2026 («при наведении мышки на превью вложения — кнопка
   „скачать“»), и так устроен образец. До этого кнопка стояла в плитке всегда
   и занимала место, которое у бумаги нужнее имени.

   `pointer-events` снимаются вместе с видимостью нарочно: прозрачная кнопка
   остаётся кнопкой и перехватывала бы нажатие, которым открывают сам файл.

   На телефоне наведения нет вовсе, и спрятанная кнопка там равна её
   отсутствию — поэтому у сенсорного ввода она видна всегда. */
.mail-att__get {
  position: absolute; top: 5px; right: 5px;
  display: grid; place-items: center; flex: none;
  width: 24px; height: 24px; border-radius: 50%;
  background: color-mix(in oklab, var(--surface-3) 88%, transparent);
  color: var(--text-soft); text-decoration: none;
  opacity: 0; pointer-events: none;
  transition: opacity .12s ease, background .12s ease, color .12s ease;
}
.mail-att:hover .mail-att__get,
.mail-att:focus-within .mail-att__get { opacity: 1; pointer-events: auto; }
.mail-att__get:hover { background: var(--accent); color: var(--on-accent); }
.mail-att__get:focus-visible { outline: none; box-shadow: var(--ring); }
.mail-att--shot .mail-att__get { background: rgb(0 0 0 / .5); color: #fff; }
.mail-att--shot .mail-att__get:hover { background: rgb(0 0 0 / .8); color: #fff; }
@media (hover: none) {
  .mail-att__get { opacity: 1; pointer-events: auto; }
}

/* Отзывается на руку только то, за чем что-то есть: своя бумага открывается
   ссылкой, чужая забирается кнопкой. Приложенная к неотправленному письму
   никуда не ведёт, и палец о неё спотыкаться не должен — поэтому по имени
   узла, а не по классу. */
a.mail-att, button.mail-att, a.mail-att__open, a.mail-att__get { cursor: pointer; }
/* Подчёркивания на плитке нет ни в каком состоянии. Плитка — это ссылка
   (`<a>`), и общее правило системы `a:hover { text-decoration: underline }`
   доставало её через `:hover` вместе со всем, что внутри: под курсором
   подчёркивались и имя файла, и вес, и плашка типа (Роман 28.08.2026: «на пк
   при наведении курсора ссылки во вложениях подсвечиваются»). Плитка и так
   отвечает на руку — краской рамки и именем; подчёркивание в ней читается
   как ошибка вёрстки, потому что подчёркивают слово в тексте, а не карточку. */
a.mail-att, a.mail-att:hover, a.mail-att:focus,
a.mail-att__open, a.mail-att__open:hover, a.mail-att__open:focus,
a.mail-att__get, a.mail-att__get:hover,
.mail-att *, .mail-att:hover * { text-decoration: none; }
a.mail-att:hover, button.mail-att:hover,
.mail-att:has(a.mail-att__open:hover) { color: var(--text); border-color: var(--accent); }
a.mail-att:hover .mail-att__plate,
button.mail-att:hover .mail-att__plate,
a.mail-att__open:hover .mail-att__plate { filter: brightness(1.06); }
a.mail-att__open:hover .mail-att__shot { filter: brightness(1.06); }
.mail-att:focus-visible,
.mail-att:has(.mail-att__open:focus-visible) { outline: none; box-shadow: var(--ring); }
.mail-att__open:focus-visible { outline: none; }

/* Невыкачанная бумага — приглушённо. Не пунктиром вокруг всего и не серым
   насквозь: вид у неё общий с остальными (тот же цвет типа, то же имя, тот же
   размер), а отличается она только тем, что чуть тише и со значком. Иначе
   старое письмо выглядело бы письмом со сломанными вложениями. */
.mail-att.is-remote { opacity: .78; }
/* Отлив у невыкачанной — вдвое слабее. Приглушённости мало: она снимает и
   краску тоже, и полный отлив на приглушённой плитке подтягивал её обратно к
   обычной. Разница между «файл у нас» и «файл ещё в почте» должна читаться
   без наведения. */
.mail-att--tile.is-remote {
  background-image: linear-gradient(150deg,
    color-mix(in oklab, var(--logo-from) 6%, transparent) 0%,
    transparent 70%);
}
.mail-att.is-remote .mail-att__plate {
  background: color-mix(in oklab, var(--att) 8%, var(--surface));
  outline: 1px dashed color-mix(in oklab, var(--att) 45%, transparent);
  outline-offset: -1px;
}
/* ---------- пока файл едет из почты ----------

   Роман 28.08.2026: «показывать бар загрузки как-то симпатично и плавно».
   Забор — это поход в IMAP: три-пять секунд, в которые до сих пор не
   происходило ничего, кроме поблёкшей плитки. Отсюда полоска понизу.

   Она **не показывает долю**, и это честно: ручка отвечает одним куском, доли
   у неё нет вовсе, а нарисованные проценты, которые ползут к девяноста и
   стоят, — обман, который замечают на второй раз. Полоска ходит из края в
   край: это значит «работа идёт», и ровно это мы и знаем.

   Ход — с разгоном и торможением (`cubic-bezier`), а не равномерный: ровно
   бегущая полоска читается как заставка, а с разгоном — как дыхание. Плитку
   при этом не гасим до половины, как раньше: приглушённая до неузнаваемости,
   она пропадала из письма, а человек ждёт именно её. */
.mail-att.is-taking { opacity: .82; cursor: default; overflow: hidden; }
.mail-att.is-taking::after,
.mail-shots__cell.is-taking::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 3px;
  background-image: linear-gradient(90deg,
    color-mix(in oklab, var(--accent) 20%, transparent) 0%,
    var(--accent) 45%, var(--accent) 55%,
    color-mix(in oklab, var(--accent) 20%, transparent) 100%);
  background-size: 55% 100%; background-repeat: no-repeat;
  animation: mail-take 1.15s cubic-bezier(.45, 0, .55, 1) infinite;
  pointer-events: none;
}
@keyframes mail-take {
  from { background-position: -60% 0; }
  to { background-position: 160% 0; }
}
/* Кому движение мешает — полоска остаётся на месте, но остаётся: без неё у
   человека не будет вовсе никакого знака, что файл едет. */
@media (prefers-reduced-motion: reduce) {
  .mail-att.is-taking::after,
  .mail-shots__cell.is-taking::after {
    animation: none; background-size: 100% 100%; background-position: 0 0;
    opacity: .55;
  }
}

/* «Приедет по нажатию» — стрелкой в конце строки, а не кружком на плашке:
   плашка мелкая, и кружок на ней сминался в закорючку без опознаваемой
   формы. Стрелка вниз закреплена за этим значением и больше нигде во
   вложениях не встречается: у кнопки скачивания свой значок. */
.mail-att__take {
  display: grid; place-items: center; flex: none;
  margin-left: auto; color: var(--accent);
}

/* ---------- полоса приложенных файлов у окна письма ---------- */
.mail-attach {
  display: grid; gap: 6px;
  padding: 8px; border: 1px solid var(--border); border-radius: var(--r);
  background: var(--surface);
}
/* Внутри полосы стоит та же `.mail-att`, что и в письме, — своих чипа,
   картинки и плашки у неё больше нет. Раскладку набора задаёт общее правило
   выше, вместе с набором бумаг письма. */

/* ---------- крестик «убрать из письма» ----------

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

   Некрасиво было потому, что у плитки крестик стоял **соседом** ссылки, а не
   на ней: плитка занимает всю ширину строки набора, и кнопка в 18 точек
   сваливалась под неё, повиснув под левым нижним углом. У карточки снимка
   такой беды не было никогда — там крестик с самого начала лежал в углу
   поверх картинки.

   **Серый до наведения, красный под ним.** Красный крестик на каждой плитке
   превратил бы набор из трёх файлов в три предупреждения; а вот под рукой
   цвет обязан сказать, что случится, — нажатие здесь не отменяется ничем,
   кроме повторного прикрепления файла.

   **Угол у плитки нижний, у снимка верхний**, и это не разнобой — у них
   заняты разные края.

   У плитки сверху имя. Первый заход поставил кружок туда и ужал имя на
   двадцать точек справа; Роман 30.08.2026: «во-первых, криво; во-вторых,
   может лучше в нижний правый, чтобы не ужимать имя файла?» Криво было
   потому, что двадцати точек кружку мало — ему нужно тридцать (24 своих плюс
   6 отступа), — и имя всё равно лезло под него, обрываясь посреди слова:
   `REIZ_invite_c1.pn` / `g`. Внизу же у плитки подвал из плашки типа и веса,
   и там кружку хватает места рядом: имя, ради которого файл и узнают,
   остаётся целым во всю ширину.

   У снимка наоборот: подпись лежит **поверх картинки понизу**
   (`.mail-att__cap`), и нижний угол занят ею. Сверху там чистая фотография —
   туда кружок и встаёт. */
.mail-attach__drop {
  position: absolute; bottom: 6px; right: 6px; z-index: 2;
  display: grid; place-items: center;
  width: 24px; height: 24px;
  border: 0; border-radius: 50%;
  cursor: pointer;
  /* `padding: 0` здесь обязателен, и это не уборка лишней строки. У кнопки
     своё поле от браузера — `1px 6px`, — а `box-sizing` в системе везде
     `border-box`: при ширине 24 точки на содержимое остаётся двенадцать, и
     крест в пятнадцать в них не влезает. Перелившийся значок раскладка
     прижимает к началу строки, и крест вставал на полторы точки правее
     середины. Роман 30.08.2026 разглядел это на превью: «оцентруй крест!!!
     уже вижу, что неровно». По вертикали поля всего точка, и там перекоса
     не было — оттого перекос и читался как случайный. */
  padding: 0;
  /* Подложка сквозная и берётся из чернил темы, а не задана краской: плитка
     в светлой теме светлая, в тёмной тёмная, и один и тот же серый кружок
     пропал бы в одной из них. */
  background: color-mix(in oklab, var(--text) 14%, transparent);
  color: var(--text-soft);
  transition: background var(--speed), color var(--speed);
}
.mail-attach__drop:hover,
.mail-attach__drop:focus-visible {
  outline: none;
  background: var(--red); color: var(--on-accent);
}
/* Место кружку освобождает **подвал**, а не имя: в подвале лежат плашка типа
   и вес, и оба короткие. Вес при этом ужимается первым — он единственный, кто
   здесь готов потесниться: плашка типа опознаётся целиком или никак, а «4,3
   МБ» и обрезанное до «4,3 М» говорят человеку одно и то же.

   Только у плитки с крестиком: у бумаги пришедшего письма его нет вовсе, и
   отступ там был бы дырой в подвале. */
.mail-att--tile:has(.mail-attach__drop) .mail-att__foot { padding-right: 26px; }
.mail-att--tile:has(.mail-attach__drop) .mail-att__size {
  min-width: 0; flex: 0 1 auto;
  overflow: hidden; text-overflow: ellipsis;
}
/* На карточке снимка кружок лежит поверх картинки: там серого из чернил темы
   не хватит — под ним не тема, а чужая фотография, и светлая ровно так же
   часто, как тёмная. Чернила своей краской, потому и белые.

   И стоит он сверху: низ карточки занят подписью (`.mail-att__cap`). */
.mail-att--shot .mail-attach__drop {
  top: 6px; bottom: auto;
  background: rgb(0 0 0 / .45); color: #fff;
}
.mail-att--shot .mail-attach__drop:hover,
.mail-att--shot .mail-attach__drop:focus-visible {
  background: var(--red); color: var(--on-accent);
}

/* Счётчик веса виден всё время, пока письмо пишут, а не всплывает на
   отправке: письмо кодируется base64 и пухнет на 37%, у mail.ru предел на
   письмо 25 МБ, и отказ чужого сервера после нажатия «Отправить» — худший
   момент, чтобы узнать про потолок. */
.mail-attach__total { font-size: 11.5px; color: var(--text-faint); }
.mail-attach__total.is-tight { color: var(--amber); font-weight: 550; }

/* Занавес перетаскивания. Ложится в окно письма (`bind` вешает
   `mail-attach-host` на корень), а не во весь экран: бросают на письмо, и
   гасить ради этого всю страницу незачем. */
.mail-attach-host { position: relative; }
.mail-attach-veil {
  position: absolute; inset: 0; z-index: 5;
  display: grid; place-items: center;
  border-radius: inherit;
  background: color-mix(in oklab, var(--accent) 40%, var(--scrim));
  backdrop-filter: blur(2px);
  pointer-events: none;
}
.mail-attach-veil__box {
  display: grid; gap: 8px; justify-items: center;
  padding: 18px 24px; border-radius: var(--r-lg);
  border: 2px dashed var(--on-accent);
  color: var(--on-accent); font-size: 13px; font-weight: 550;
}

/* Телефонной оговорки у плитки нет нарочно. Она была у строки бумаги: потолок
   в 210 точек съедал имя многоточием почти всегда, и на узком экране строке
   разрешали растянуться. Плитка шириной 132, и две таких встают в пузырь на
   телефоне (около трёхсот точек) ровно так же, как три на столе; растягивать
   нечего. */


/* Своё письмо подчёркивает ссылки в теле (`.mail-msg--out .mail-body a` в
   mail-thread.css) — чтобы на цветном пузыре они читались ссылками, а не
   просто текстом того же цвета. Плитка вложения под это правило попадать не
   должна: она не ссылка в тексте, а карточка бумаги, и подчёркнутое имя
   файла в ней выглядит поломкой (Роман, 27.08.2026 — «подчёркивания
   странные»). Задавлено по месту, а не снятием общего правила: ссылки в
   тексте письма подчёркиваться обязаны. */
.mail-msg .mail-att,
.mail-msg--out .mail-body a.mail-att,
.mail-msg--out a.mail-att { text-decoration: none; }

/* ---------- окно предпросмотра бумаги ----------

   Роман 28.08.2026: «что-то простенькое, и главное, чтобы оно работало
   быстро». Оформление здесь ровно про это: показать содержимое и не мешать.
   Ни своих рамок вокруг каждого абзаца, ни зебры в таблице — читают тут
   секунду, чтобы решить «тот ли файл», а не работают.

   Высота окна привязана к экрану, а не к содержимому: у счёта на две строки
   и у спецификации на сорок окно должно быть одного роста, иначе оно прыгает
   под рукой при каждом открытии. */
.peek, .peek__wait {
  min-height: 40vh;
  max-height: 68vh;
  overflow: auto;
}
.peek__wait { display: grid; place-items: center; color: var(--text-faint); }
.peek__empty { padding: 28px 8px; text-align: center; color: var(--text-faint); }

/* Рамка PDF занимает всё окно: это единственный вид, где показывает не наш
   код, а сам браузер, и делить с ним место нечем. */
.peek--pdf { overflow: hidden; }
.peek__frame { display: block; width: 100%; height: 68vh; border: 0; background: #fff; }

/* Страницы PDF картинками — путь для тех, кому рамка не годится (айфон её не
   рисует вовсе). Одна под другой, во всю ширину, с белой подложкой: страница
   документа белая, и на тёмной теме без подложки её края теряются. */
.peek--pdf:has(.peek__pages) { overflow: auto; }
.peek__pages { gap: 10px; }
.peek__page {
  display: block; width: 100%; height: auto;
  border-radius: 6px; background: #fff;
  /* Край держит рамка, а не тень. Общая тень плашки на светлой теме еле
     заметна, а лист тут белый и лежит на белой же панели — без рамки он в
     ней растворяется. Тень осталась, но её работа теперь только оторвать
     лист от подложки, а не обвести. */
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

.peek__doc { display: flex; flex-direction: column; gap: 8px; padding: 2px; }
.peek__p { margin: 0; font-size: 14px; line-height: 1.5; }
/* Пустых абзацев в документах бывает больше, чем слов; здесь они уже отсеяны
   разбором, но отступ между оставшимися нужен ровный. */
.peek__p:empty { display: none; }

.peek__tab-name {
  font-size: 12px; font-weight: 600; color: var(--text-faint);
  text-transform: uppercase; letter-spacing: .03em;
  padding: 8px 0 4px;
}
/* Таблица уезжает вбок **внутри себя**, а не тянет окно: у счёта двенадцать
   столбцов, и на телефоне они не помещаются никогда. */
.peek__scroll { overflow-x: auto; }
.peek__table {
  border-collapse: collapse;
  font-size: 13px;
  /* Ширину считает содержимое: у счёта первый столбец — номер, а последний —
     сумма, и равные столбцы делают из них кашу. */
  width: max-content;
  max-width: 100%;
}
.peek__table td {
  border: 1px solid var(--border);
  padding: 4px 8px;
  vertical-align: top;
  white-space: pre-wrap;
  /* Ячейку с длинным примечанием ограничиваем: без этого одна такая ячейка
     растягивает таблицу на два экрана. */
  max-width: 320px;
}
.peek__text {
  margin: 0; font-size: 13px; line-height: 1.45;
  white-space: pre-wrap; word-break: break-word;
}
.peek__more { padding: 8px 2px 0; font-size: 12px; color: var(--text-faint); }

/* Вид документа — те же страницы картинками, что и у PDF (класс `peek__page`
   общий): docx и xlsx показываются ровно так же, как показался бы счёт, и
   разного вида у одной и той же бумаги быть не должно. */
.peek--paper { overflow: auto; }
/* Строка под страницами: слева — что показано, справа — переключатель на
   текст. Прижимать их друг к другу нельзя: подпись читают, кнопку нажимают. */
.peek__swap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding-bottom: 2px;
}

/* ---------- окно отправки бумаги заказа письмом ----------

   Бумага стоит первой и занимает столько же, сколько в обычном предпросмотре:
   окно открывают, чтобы на неё посмотреть, а поля «кому» и «тема» — то, что
   заполняют уже после взгляда. Меньший рост превратил бы предпросмотр в
   значок, то есть в то, ради чего окно не открывают. */
.docmail__paper {
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface-2);
}
.docmail__paper-head {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
/* Имя файла режем, а не переносим: длинное имя в две строки отодвигает вниз
   сам документ, ради которого окно и открыто. Кнопка при этом не уезжает. */
.docmail__file {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.docmail__paper .peek, .docmail__paper .peek__wait {
  min-height: 26vh; max-height: 42vh; padding: 8px 10px;
}

/* Список сотрудников — столбиком и с прокруткой: в фирме их два десятка, и
   развёрнутый список отодвинул бы «Отправить» за край окна. */
.docmail__list {
  display: flex; flex-direction: column;
  max-height: 30vh; overflow: auto;
  border: 1px solid var(--border); border-radius: 10px;
  padding: 4px;
}
/* Приписка под выбором ящика. Пустая — не занимает места вовсе: обычный
   случай это когда ящик фирмы нашёлся и говорить не о чем. */
.docmail__from-note:empty { display: none; }
.docmail__from-note {
  margin-top: 6px; padding: 6px 9px; border-radius: 8px; line-height: 1.4;
}
.docmail__from-note--warn {
  background: var(--amber-soft); color: var(--text);
}

.docmail__who {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px; border-radius: 8px; cursor: pointer;
}
.docmail__who:hover { background: var(--surface-2); }
.docmail__tick { flex: 0 0 auto; width: 16px; height: 16px; }
.docmail__who-body { display: grid; gap: 2px; min-width: 0; }
.docmail__name { font-size: 14px; }
/* Должность — рядом с именем и приглушённо: она отвечает на «тот ли это
   человек», но спорить за внимание с именем не должна. */
.docmail__post { color: var(--text-faint); font-size: 12px; margin-left: 6px; }
.docmail__mail {
  font-size: 12px; color: var(--text-faint);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Адрес не из подключённого ящика, а из карточки. Приписка, а не
   предупреждение: письмо уйдёт и дойдёт, разница лишь в том, что переписку не
   будет видно внутри Флоу. Тем же серым, что и сам адрес. */
.docmail__from { color: var(--text-faint); }

@media (max-width: 820px) {
  /* На телефоне окно письма уже во весь экран (`mail-phone.css`), и это —
     обычное окно системы. Ему хватает своих полей, но рамке PDF нужен весь
     оставшийся рост: первая страница счёта в четверть экрана нечитаема. */
  .peek, .peek__wait { max-height: none; }
  .peek__frame { height: 62vh; }
  .peek__table td { max-width: 200px; }
  /* А вот в окне отправки рост держим: под бумагой лежат «кому», «тема» и
     «отправить», и без потолка они уезжают за третий экран. */
  .docmail__paper .peek, .docmail__paper .peek__wait { max-height: 40vh; }
}

/* ---------- заставка предпросмотра ----------

   Лист бумаги, по которому идёт свет. Стоит те секунды, пока LibreOffice
   собирает вид документа: до трёх на первый файл, дальше из кэша мгновенно.

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

   Лист рисуем **в тех же пропорциях, что и А4** (1:1.41): человек ждёт
   страницу и видит место, куда она встанет. Полосы внутри — не текст, а
   намёк на него: четыре штриха разной длины, как у бликующих плашек списков.

   Блик — единственное, что движется, и едет он `transform`, а не сменой
   `background-position`: композитор считает это на видеокарте и не трогает
   раскладку. */
.peek-wait {
  position: fixed; inset: 0; z-index: 126;
  display: grid; place-content: center; justify-items: center; gap: 14px;
  background: color-mix(in oklab, #0B0B0D 78%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  backdrop-filter: blur(14px) saturate(120%);
  opacity: 0; transition: opacity .14s ease;
}
.peek-wait.is-open { opacity: 1; }
.peek-wait__sheet {
  position: relative; overflow: hidden;
  width: min(38vh, 260px); height: min(54vh, 367px);
  display: flex; flex-direction: column; gap: 14px;
  padding: 26px 22px;
  border-radius: 10px;
  background: color-mix(in oklab, #fff 92%, var(--accent));
  box-shadow: 0 24px 70px rgb(0 0 0 / .55);
}
.peek-wait__line {
  height: 9px; border-radius: 4px;
  background: color-mix(in oklab, #0B0B0D 12%, transparent);
}
.peek-wait__line:nth-child(2) { width: 82%; }
.peek-wait__line:nth-child(3) { width: 94%; }
.peek-wait__line:nth-child(4) { width: 61%; }
.peek-wait__glare {
  position: absolute; top: 0; bottom: 0; left: 0; width: 45%;
  background: linear-gradient(100deg,
    transparent, color-mix(in oklab, var(--accent), transparent 55%), transparent);
  animation: peek-glare 1.25s ease-in-out infinite;
}
@keyframes peek-glare {
  0% { transform: translateX(-120%); }
  100% { transform: translateX(320%); }
}
.peek-wait__name {
  max-width: min(80vw, 420px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: #fff; font-size: 13.5px;
}
.peek-wait__word { color: rgb(255 255 255 / .62); font-size: 12.5px; }

/* Та же заставка внутри отведённого места — в окне отправки документа. Там
   она не накрывает систему, а стоит на месте будущей страницы. */
.peek-wait--inline {
  position: static; inset: auto; z-index: auto;
  padding: 18px 0; gap: 10px;
  background: none; -webkit-backdrop-filter: none; backdrop-filter: none;
}
.peek-wait--inline .peek-wait__sheet { width: min(30vh, 180px); height: min(42vh, 254px); }
.peek-wait--inline .peek-wait__word { color: var(--text-faint); }

@media (prefers-reduced-motion: reduce) {
  /* Движение снято, лист остаётся: он и есть ответ на вопрос «чего ждём».
     Блик же — чистое украшение, и без хода он лишняя полоса поперёк листа. */
  .peek-wait__glare { display: none; }
  .peek-wait { transition: none; }
}
