/* gsforge — оформление.
 *
 * Служебная тула, которой пользуются каждый день: плотно, но не тесно.
 * Цвет здесь работает, а не украшает — им размечены уверенность автодетекта,
 * доступность метрик и исход операции. Поэтому акцент один, а остальное
 * держится на границах и оттенках фона.
 *
 * Все размеры и цвета — токенами: тем четыре (авто/светлая/тёмная/розовая),
 * и правка в одном месте обязана доезжать до всех. */

:root {
  /* светлая по умолчанию */
  --bg:        #f4f6f9;
  --bg-soft:   #eaeef4;
  --card:      #ffffff;
  --card-2:    #f8fafc;
  --ink:       #0f1319;
  --ink-2:     #39424e;
  --muted:     #6a7482;
  --line:      #e2e7ee;
  --line-2:    #cdd5e0;
  --accent:    #2f6bd8;
  --accent-2:  #1e56bd;
  --accent-ink:#ffffff;
  --accent-soft: rgba(47, 107, 216, .10);
  --ok:        #16794a;
  --warn:      #8a5a00;
  --err:       #b02020;
  --ok-bg:     #e7f6ed;
  --warn-bg:   #fdf3e0;
  --err-bg:    #fdeceb;
  --sheets:    #0f9d58;
  --script:    #c98a00;

  --r-1: 8px;
  --r-2: 12px;
  --r-3: 18px;
  --shadow-1: 0 1px 2px rgba(15, 19, 25, .06);
  --shadow-2: 0 6px 20px -6px rgba(15, 19, 25, .18);
  --shadow-3: 0 24px 60px -20px rgba(15, 19, 25, .35);
  --side-w: 236px;

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  color-scheme: light;
}

/* Тёмная: по явному выбору либо системой при «авто». Объявлена дважды
   намеренно — CSS не умеет «ИЛИ» между медиа-запросом и атрибутом, а одна
   копия в общем блоке не даёт тёмной по умолчанию. */
:root[data-theme="dark"],
:root:not([data-theme="light"]):not([data-theme="pink"]) {
  --bg:        #0d1015;
  --bg-soft:   #141920;
  --card:      #151a21;
  --card-2:    #1a202a;
  --ink:       #e9eef5;
  --ink-2:     #c3ccd8;
  --muted:     #8794a4;
  --line:      #222a35;
  --line-2:    #2e3845;
  --accent:    #5b9dff;
  --accent-2:  #7bb2ff;
  --accent-ink:#07101d;
  --accent-soft: rgba(91, 157, 255, .14);
  --ok:        #5fcd93;
  --warn:      #e3bd6b;
  --err:       #f28b8b;
  --ok-bg:     #13291f;
  --warn-bg:   #2c2515;
  --err-bg:    #2e1c1c;
  --sheets:    #3ddc97;
  --script:    #ecc255;
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-2: 0 8px 24px -8px rgba(0, 0, 0, .6);
  --shadow-3: 0 28px 70px -24px rgba(0, 0, 0, .8);
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    --bg: #f4f6f9; --bg-soft: #eaeef4; --card: #ffffff; --card-2: #f8fafc;
    --ink: #0f1319; --ink-2: #39424e; --muted: #6a7482; --line: #e2e7ee; --line-2: #cdd5e0;
    --accent: #2f6bd8; --accent-2: #1e56bd; --accent-ink: #ffffff; --accent-soft: rgba(47,107,216,.10);
    --ok: #16794a; --warn: #8a5a00; --err: #b02020;
    --ok-bg: #e7f6ed; --warn-bg: #fdf3e0; --err-bg: #fdeceb;
    --sheets: #0f9d58; --script: #c98a00;
    --shadow-1: 0 1px 2px rgba(15,19,25,.06);
    --shadow-2: 0 6px 20px -6px rgba(15,19,25,.18);
    --shadow-3: 0 24px 60px -20px rgba(15,19,25,.35);
    color-scheme: light;
  }
}
:root[data-theme="light"] {
  --bg: #f4f6f9; --bg-soft: #eaeef4; --card: #ffffff; --card-2: #f8fafc;
  --ink: #0f1319; --ink-2: #39424e; --muted: #6a7482; --line: #e2e7ee; --line-2: #cdd5e0;
  --accent: #2f6bd8; --accent-2: #1e56bd; --accent-ink: #ffffff; --accent-soft: rgba(47,107,216,.10);
  --ok: #16794a; --warn: #8a5a00; --err: #b02020;
  --ok-bg: #e7f6ed; --warn-bg: #fdf3e0; --err-bg: #fdeceb;
  --sheets: #0f9d58; --script: #c98a00;
  color-scheme: light;
}
/* Розовая — светлая по контрасту, тёплая по тону. Доступна не всем:
   список в store.PINK_USERS. */
:root[data-theme="pink"] {
  --bg: #fdf2f7; --bg-soft: #fae6f0; --card: #ffffff; --card-2: #fff7fb;
  --ink: #331a26; --ink-2: #6b4557; --muted: #91697d;
  --line: #f4d4e4; --line-2: #e9b6d0;
  --accent: #d6337f; --accent-2: #b92568; --accent-ink: #ffffff; --accent-soft: rgba(214,51,127,.10);
  --ok: #1f7a54; --warn: #a9650f; --err: #c02b2b;
  --ok-bg: #e6f6ee; --warn-bg: #fdf0e2; --err-bg: #fdeaea;
  --sheets: #12a05c; --script: #c07f00;
  color-scheme: light;
}

* { box-sizing: border-box; }
::selection { background: var(--accent-soft); }

html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 14px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
}

h1 { margin: 0; font-size: 21px; letter-spacing: -.02em; font-weight: 650; }
h2 { margin: 0 0 6px; font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
h3 { margin: 0 0 4px; font-size: 13px; font-weight: 650; }
p  { margin: 0; }
.muted { color: var(--muted); }
.hidden { display: none !important; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ═══════════ дополнительные настройки ═══════════
   Свёрнутый блок на создании таблицы: при первом развёртывании отбор почти
   никогда не трогают, а шесть групп на экране мешают дойти до кнопки. На
   странице таблицы это отдельная вкладка — там сворачивать не от чего, и
   заголовок-раскрывашка прячется классом locked. */
.advanced > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; margin: -2px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-soft);
  transition: border-color .12s, background .12s;
}
.advanced > summary::-webkit-details-marker { display: none; }
/* Общий треугольник у summary здесь лишний: у блока свой шеврон. */
.advanced > summary::before { content: none; }
.advanced > summary:hover { border-color: var(--accent); background: var(--card); }
.advanced > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.adv-chev { display: flex; color: var(--muted); flex: none; }
.adv-chev .ic { transition: transform .15s; }
.advanced[open] > summary .adv-chev .ic { transform: rotate(90deg); }
.adv-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.adv-t { font-weight: 650; letter-spacing: -.01em; }
.adv-sub { font-size: 12px; color: var(--muted); }
.adv-badge { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; flex: none; }
.adv-badge .pill.accent { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.advbody { padding-top: 14px; }
.advanced.locked > summary { display: none; }
.advanced.locked .advbody { padding-top: 0; }
@media (max-width: 720px) {
  .adv-sub { display: none; }
}

/* ═══════════ отбор и поправки ═══════════ */
.selgroups { display: grid; gap: 14px; margin-top: 12px; }
.selgroup { border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px; background: var(--bg-soft); }
.selgroup h3 { margin: 0 0 4px; }
.selgroup > p.muted { margin: 0 0 10px; max-width: 78ch; }
.selgroup.off { opacity: .55; }
/* Подпись и поле в строку, пояснение — под ними во всю ширину: пояснения
   тут длинные, и третьей колонкой они сплющивались в столбик по слову. */
.selrow { display: grid; grid-template-columns: minmax(150px, 18rem) minmax(0, 1fr); gap: 3px 12px; align-items: center; padding: 6px 0; font-size: 13px; }
.selrow.inline { grid-template-columns: auto minmax(0, 1fr); cursor: pointer; }
.selrow .sel-l { color: var(--ink-2); }
.selrow .sel-h { grid-column: 2; color: var(--muted); font-size: 12px; }
.selrow input[type="number"] { width: 92px; }
.selrow select { min-width: 16rem; }
@media (max-width: 720px) {
  .selrow { grid-template-columns: 1fr; gap: 4px; }
  /* Строка-галочка остаётся строкой: галочка над подписью читалась как две
     разные настройки. */
  .selrow.inline { grid-template-columns: auto minmax(0, 1fr); gap: 4px 10px; align-items: center; }
  .selrow.inline .sel-h { grid-column: 1 / -1; }
}

/* Ничто не вылезает за карточку: длинные значения и объяснения обрезаются,
   а не растягивают колонку. Раньше строка полей уезжала под правый край. */
.field, .field > div, .pick, .pick-btn { min-width: 0; }
.field .why, .field .vals, .pick-btn .vals { overflow: hidden; text-overflow: ellipsis; }
.field .vals, .pick-btn .vals { white-space: nowrap; }

/* Ярлычок «поделиться» на карточке — в один ряд со ссылками в Google. */
.share-btn:hover { color: var(--accent); border-color: var(--accent); }

.settings-io { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 12px; }
.settings-io a.btn { text-decoration: none; }

/* ═══════════ движение ═══════════
   Анимации короткие и об одном: что-то изменилось и где это искать. Всё
   отключается системной настройкой «уменьшить движение» — для тех, кому от
   него плохо, это не украшение, а препятствие. */
@keyframes view-in { from { opacity: 0; transform: translateY(6px); } }
.view-in { animation: view-in .22s ease-out; }

@keyframes sec-in { from { opacity: 0; transform: translateY(8px); } }
.sec-in { animation: sec-in .2s ease-out; }

.tcard.leaving { transform: scale(.98); opacity: .35; transition: transform .12s ease-in, opacity .12s ease-in; }

/* Смена темы. Мгновенный перещёлк читается как сбой отрисовки, поэтому цвета
   переезжают за две десятых секунды. Переход висит ТОЛЬКО на время
   переключения: оставить его постоянно значит сделать вялым каждое наведение
   и каждую подсветку строки. */
.theme-switching, .theme-switching * {
  transition: background-color .2s ease, color .2s ease, border-color .2s ease,
              fill .2s ease, stroke .2s ease, box-shadow .2s ease !important;
}

/* Заглушки на месте чисел, пока их считает Google. Одно кольцо посреди
   пустой панели читается как «повисло»; ряд заглушек показывает, сколько
   чисел приедет и куда они встанут, — и сам переход получается спокойным. */
.skel-tile { pointer-events: none; }
.sk {
  border-radius: 5px;
  background: linear-gradient(90deg, var(--bg-soft) 25%, var(--line) 37%, var(--bg-soft) 63%);
  background-size: 400% 100%;
  animation: sk-slide 1.3s ease-in-out infinite;
}
.sk-k { height: 9px; width: 60%; }
.sk-v { height: 15px; width: 84%; margin-top: 8px; }
@keyframes sk-slide { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* Конец развёртывания: крутившееся кольцо доводит оборот и замыкается в
   полный круг. Готовность видно телом, а не только текстом, который ещё
   надо прочитать. */
.ring-done {
  width: 18px; height: 18px; flex: none;
  border: 2px solid var(--accent-soft); border-radius: 50%;
  border-top-color: var(--accent); border-right-color: var(--accent);
  animation: ring-close .5s cubic-bezier(.2, .7, .3, 1) forwards;
}
@keyframes ring-close {
  70% { border-color: var(--accent-soft); border-top-color: var(--accent); border-right-color: var(--accent); }
  to { transform: rotate(360deg); border-color: var(--accent); }
}
.ring-done.fail { border-top-color: var(--err); border-right-color: var(--err); animation-name: ring-close-fail; }
@keyframes ring-close-fail {
  70% { border-color: var(--accent-soft); border-top-color: var(--err); border-right-color: var(--err); }
  to { transform: rotate(360deg); border-color: var(--err); }
}

/* Возврат версии: строки, которые от него изменились, вспыхивают трижды.
   Без этого экран после отката выглядит прежним, и что именно поменялось,
   приходится искать глазами по двум десяткам полей. */
@keyframes field-flash {
  0%, 100% { background: transparent; box-shadow: none; }
  35% {
    background: color-mix(in srgb, var(--accent) 16%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent);
  }
}
.field.flash { animation: field-flash 1.2s ease-in-out 3; }

/* Изменившееся число подсвечивается на мгновение: анимация набегания видна
   не всегда, а вспышка ловится боковым зрением. */
.tile .v.changed { color: var(--accent); }
.tile .v { transition: color .5s ease; }

/* Кольцо готовности профиля в шапке таблицы. */
.thead-ring { width: 34px; height: 34px; flex: none; cursor: help; }
.thead-ring .pring { width: 34px; height: 34px; display: block; }
.thead-ring .pring circle:last-of-type { transition: stroke-dashoffset .5s ease; }
.pring-t { font: 650 12px var(--sans); fill: var(--ink-2); }

@media (prefers-reduced-motion: reduce) {
  .view-in, .sec-in { animation: none; }
  .tcard.leaving { transition: none; }
  .ring-spin { animation-duration: 2.4s; }
  .busy .deploy-steps li::before { animation: none; }
  .theme-switching, .theme-switching * { transition: none !important; }
  .sk { animation: none; background: var(--bg-soft); }
  .dropveil, .dropveil-ring, .drop.over .drop-icon::after { animation: none; }
  .ring-done { animation: none; border-color: var(--accent); }
  .ring-done.fail { border-color: var(--err); }
  .field.flash { animation: none; background: var(--accent-soft); }
}

/* ═══════════ шеринг ═══════════
   Список людей с мгновенным применением: нажал — ушло на сервер, как в
   мессенджерах. Кнопки «сохранить» нет намеренно, поэтому состояние каждой
   строки должно читаться с одного взгляда. */
.modal.share { width: min(460px, calc(100vw - 32px)); padding: 0; overflow: hidden; }
.share-head { padding: 18px 20px 12px; }
.share-head h2 { margin: 0 0 2px; }
.share-head .muted { font-size: 12.5px; }
.share-q { width: 100%; margin: 0 0 10px; background: var(--bg-soft); }
.share-list { display: grid; gap: 2px; }
/* В окне список прокручивается и отбит от краёв; в карточке он просто
   продолжение карточки. Разметка и строки при этом те же самые — это один
   и тот же список в трёх местах, а не три похожих. */
.modal.share .share-q { width: calc(100% - 40px); margin: 0 20px 12px; }
.modal.share .share-list {
  max-height: min(46vh, 380px); overflow-y: auto;
  padding: 0 12px 4px;
}
.share-list.inline .share-row { padding-left: 0; padding-right: 0; }
.pick-owner { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.share-row {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) auto;
  gap: 11px; align-items: center;
  padding: 8px; border-radius: var(--r-2);
  transition: background .12s;
}
.share-row:hover { background: var(--bg-soft); }
/* У того, кому уже открыто, аватар в акцентном кольце — то же кольцо, что
   в логотипе, и по нему список читается без чтения подписей. */
.share-row.on .ava { box-shadow: 0 0 0 2px var(--card), 0 0 0 3.5px var(--accent); }
.share-row .ava {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--bg-soft); color: var(--ink-2);
  display: grid; place-items: center;
  font-size: 12px; font-weight: 650; letter-spacing: -.02em;
  transition: box-shadow .16s;
}
.share-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.share-txt b { font-size: 13.5px; }
.share-txt .muted { font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.share-seg button { padding: 5px 9px; font-size: 11.5px; }
.share-empty { padding: 28px 8px; text-align: center; color: var(--muted); font-size: 13px; }
.share-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 20px 16px; border-top: 1px solid var(--line); margin-top: 8px;
}
.share-foot .muted { font-size: 12px; }

/* ═══════════ лист действий ═══════════
   Кнопки нижней панели, которым не хватило места в строке. Список, а не
   сетка: на телефоне палец попадает в строку во всю ширину, а не в кнопку
   рядом с другой кнопкой. */
.modal.sheet { padding: 0; overflow: hidden; width: min(380px, calc(100vw - 32px)); }
.sheet-head {
  padding: 15px 18px 11px; border-bottom: 1px solid var(--line);
  font-size: 12.5px; font-weight: 650; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sheet-list { display: flex; flex-direction: column; padding: 6px; }
.sheet-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left;
  padding: 13px 14px; border: 0; border-radius: var(--r-1);
  background: transparent; color: var(--ink);
  font: inherit; font-size: 14.5px; cursor: pointer;
  transition: background .12s;
}
.sheet-item:hover { background: var(--bg-soft); }
.sheet-item.danger { color: var(--err); }
.sheet-cancel {
  margin: 0 6px 6px; justify-content: center;
  color: var(--muted); border-top: 1px solid var(--line); border-radius: 0;
}

/* ═══════════ развёртывание ═══════════
   Пока идёт запрос, показывается план: перечень шагов притушен, крутится
   одно кольцо. Ставить галочки по таймеру нельзя — сервер не сообщает, где
   он сейчас, и такой «прогресс» был бы выдуманным. */
.deploy { margin-top: 10px; }
.deploy-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.deploy-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.deploy-steps li {
  display: flex; align-items: baseline; gap: 8px;
  padding: 5px 0 5px 24px; position: relative;
  font-size: 13px; color: var(--ink-2);
}
.deploy-steps li::before {
  content: ""; position: absolute; left: 6px; top: 11px;
  width: 6px; height: 6px; border-radius: 50%; background: var(--line-2);
}
.busy .deploy-steps li { color: var(--muted); }
/* Бегущая подсветка по списку: видно, что процесс жив, но ни один шаг не
   объявляется выполненным. */
.busy .deploy-steps li::before { animation: step-pulse 1.8s ease-in-out infinite; }
.busy .deploy-steps li:nth-child(2)::before { animation-delay: .15s; }
.busy .deploy-steps li:nth-child(3)::before { animation-delay: .3s; }
.busy .deploy-steps li:nth-child(4)::before { animation-delay: .45s; }
.busy .deploy-steps li:nth-child(5)::before { animation-delay: .6s; }
.busy .deploy-steps li:nth-child(6)::before { animation-delay: .75s; }
.busy .deploy-steps li:nth-child(n+7)::before { animation-delay: .9s; }
@keyframes step-pulse {
  0%, 100% { background: var(--line-2); transform: scale(1); }
  50% { background: var(--accent); transform: scale(1.5); }
}
.deploy-steps.done li.ok::before { background: var(--ok); }
.deploy-steps.done li.bad::before { background: var(--err); }
.deploy-steps li .d { color: var(--muted); font-size: 12px; }
.deploy-done {
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}

/* ═══════════ подсказки ═══════════
   Значок — то же кольцо, что в логотипе: в покое просто обводка, при
   наведении верхняя дуга загорается акцентом и круг «дособирается» в знак.
   Текст живёт во всплывашке, а не под заголовком: объяснение читают один
   раз, а место занимает всегда. */
.hint {
  display: inline-grid; place-items: center; position: relative;
  width: 15px; height: 15px; margin-left: 7px; flex: none;
  border: 1.5px solid var(--line-2); border-radius: 50%;
  background: none; padding: 0; color: var(--muted);
  font: 650 9.5px/1 var(--sans); cursor: help;
  vertical-align: 1px; transition: color .12s, border-color .12s;
}
.hint::before { content: "i"; }
.hint::after {
  content: ""; position: absolute; inset: -1.5px;
  border: 1.5px solid transparent; border-radius: 50%;
  border-top-color: var(--accent); border-right-color: var(--accent);
  transform: rotate(-40deg); opacity: 0; transition: opacity .14s;
}
/* Подсказка на своём элементе: всплывашка работает, а вид остаётся свой.
   Без этого кольцо готовности превращалось в кружок 15×15 — правила значка
   переписывали его размер. */
.hint.plain {
  width: auto; height: auto; margin: 0; padding: 0;
  border: 0; border-radius: 0; background: none; display: block;
}
.hint.plain::before, .hint.plain::after { content: none; }

.hint:hover, .hint:focus-visible { color: var(--accent); border-color: var(--accent-soft); outline: none; }
.hint:hover::after, .hint:focus-visible::after { opacity: 1; }

.hintpop {
  position: fixed; z-index: 90; max-width: 340px;
  padding: 12px 14px; border-radius: var(--r-2);
  background: var(--card); border: 1px solid var(--line);
  box-shadow: var(--shadow-3);
  font-size: 13px; line-height: 1.5; color: var(--ink-2);
  pointer-events: none; opacity: 0; transform: translateY(-4px);
  transition: opacity .13s ease, transform .13s ease;
}
.hintpop.on { opacity: 1; transform: none; }
.hp-where {
  margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--line);
  color: var(--muted); font-size: 12px;
}

/* ═══════════ кольцо как знак загрузки ═══════════
   Тот же мотив в третьем месте: логотип, подсказка, ожидание. */
.ring-spin {
  width: 18px; height: 18px; flex: none;
  border: 2px solid var(--line-2); border-radius: 50%;
  border-top-color: var(--accent); border-right-color: var(--accent);
  animation: ring-turn .7s linear infinite;
}
@keyframes ring-turn { to { transform: rotate(360deg); } }
.loading { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 13px; padding: 6px 0; }

/* ═══════════ логотип ═══════════
   Кольцо вместо «o» — это доля: процент, OAS, то, ради чего тулу открывают.
   Оно берёт цвет акцента, поэтому в розовой теме логотип розовый, а не
   вставной чужеродный элемент. Отдельная иконка нужна только там, где слово
   не помещается, — это favicon.svg. */
.wordmark {
  display: inline-flex; align-items: center;
  font-weight: 700; letter-spacing: -.035em;
  color: var(--ink);
}
.wordmark .ring { width: .8em; height: .8em; flex: none; }
.wordmark .ring circle { fill: none; stroke: currentColor; stroke-width: 4.4; opacity: .24; }
.wordmark .ring path { fill: none; stroke: var(--accent); stroke-width: 4.4; stroke-linecap: round; }

/* ═══════════ иконки ═══════════ */
.ic { width: 16px; height: 16px; flex: none; display: inline-block; vertical-align: -3px; }
.ic path, .ic circle, .ic rect, .ic line, .ic polyline {
  stroke: currentColor; stroke-width: 1.7; fill: none;
  stroke-linecap: round; stroke-linejoin: round;
}
.ic.fill path { fill: currentColor; stroke: none; }
/* Точки в «ещё»: три обводки читались бы как три кружка, а не как многоточие. */
.ic-dots circle { fill: currentColor; stroke: none; }

/* ═══════════ вход ═══════════ */
.login {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(900px 500px at 50% -10%, var(--accent-soft), transparent 70%),
    var(--bg);
}
/* Кольцо из логотипа, увеличенное до размера экрана: тот же знак, что в
   «o» вордмарка, в подсказках и в ожидании. Четвёртое его появление —
   и единственное украшение во всей туле. */
.login::before {
  content: ""; position: absolute; z-index: 0;
  width: min(560px, 90vw); aspect-ratio: 1;
  border: 1.5px solid var(--line-2); border-radius: 50%;
  border-top-color: var(--accent); border-right-color: var(--accent);
  transform: rotate(-35deg); opacity: .22; pointer-events: none;
}
.login-card { position: relative; z-index: 1; }
.login-card {
  width: min(370px, 100%);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  padding: 30px 28px 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  box-shadow: var(--shadow-2);
}
.login-card h1 { font-size: 28px; margin-bottom: 2px; }
.login-card .sub { color: var(--muted); margin-bottom: 8px; }
.login-card label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--muted); }
.login-card input { width: 100%; min-width: 0; }

/* ═══════════ оболочка ═══════════ */
.shell { display: flex; min-height: 100vh; }

.side {
  width: var(--side-w);
  flex: none;
  background: var(--card);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  z-index: 30;
}
.brand {
  display: flex; align-items: center; gap: 10px;
  padding: 18px 16px 14px;
}
.brand .wordmark { font-size: 18px; }
.brand .icon-btn { margin-left: auto; }

.nav { display: flex; flex-direction: column; gap: 1px; padding: 4px 10px; }
.nav button {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0; border-radius: var(--r-1);
  background: transparent; color: var(--ink-2);
  font: inherit; font-size: 13.5px;
  cursor: pointer;
  text-align: left;
  transition: background .12s, color .12s;
}
.nav button:hover { background: var(--bg-soft); color: var(--ink); }
.nav button.on { background: var(--accent-soft); color: var(--accent); font-weight: 600;   position: relative;
}
/* Риска слева у активного пункта — та же дуга акцента, что и везде. */
.nav button.on::before {
  content: ""; position: absolute; left: 0; top: 8px; bottom: 8px;
  width: 3px; border-radius: 0 3px 3px 0; background: var(--accent);
}

.nav button.on .ic { color: var(--accent); }
.nav .count {
  margin-left: auto;
  font-size: 11px; font-weight: 600;
  color: var(--muted);
  background: var(--bg-soft);
  border-radius: 20px; padding: 1px 7px;
}
.nav button.on .count { background: var(--card); color: var(--accent); }
.nav-sep { height: 1px; background: var(--line); margin: 8px 10px; }

.side-foot { margin-top: auto; padding: 10px; border-top: 1px solid var(--line); }
.who {
  display: flex; align-items: center; gap: 9px;
  width: 100%; padding: 7px 8px;
  border: 0; border-radius: var(--r-1);
  background: transparent; color: inherit; font: inherit;
  cursor: pointer; text-align: left;
}
.who:hover { background: var(--bg-soft); }
.ava {
  width: 28px; height: 28px; flex: none; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent);
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700;
}
.who-txt { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.who-txt b { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.who-txt span { font-size: 11px; }
.side-tools { display: flex; align-items: center; gap: 6px; padding: 4px 4px 0; }
.side-tools .theme { flex: 1; min-width: 0; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 12px;
  padding: 10px 26px;
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: saturate(160%) blur(10px);
  border-bottom: 1px solid var(--line);
  min-height: 52px;
}
.crumbs { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--muted); min-width: 0; }
.crumbs .sep { opacity: .5; }
.crumbs b { color: var(--ink); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crumbs button {
  border: 0; background: transparent; color: var(--muted);
  font: inherit; cursor: pointer; padding: 0;
}
.crumbs button:hover { color: var(--accent); }
.top-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; }
.kbd {
  font-family: var(--mono); font-size: 10.5px;
  border: 1px solid var(--line-2); border-radius: 5px;
  padding: 1px 5px; color: var(--muted);
}

.content { padding: 22px 26px 120px; max-width: 1240px; width: 100%; }

.page-head {
  display: flex; align-items: flex-start; gap: 16px;
  margin-bottom: 18px; flex-wrap: wrap;
}
.page-head p { margin-top: 3px; font-size: 13px; }
.head-actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  padding: 18px 20px;
  margin-bottom: 14px;
  box-shadow: var(--shadow-1);
}
.card > h2 + .muted { margin-bottom: 12px; font-size: 13px; }
.sec-head { margin: 22px 0 10px; }
.sec-head p { font-size: 12.5px; margin-top: 2px; }
.two { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.pane { min-width: 0; }

/* ═══════════ элементы управления ═══════════ */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-1);
  background: var(--card);
  color: var(--ink);
  font: inherit; font-size: 13px; font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .12s, background .12s, transform .06s, box-shadow .12s;
}
.btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn.primary {
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
  box-shadow: var(--shadow-1);
}
.btn.primary:hover:not(:disabled) { background: var(--accent-2); border-color: var(--accent-2); color: var(--accent-ink); }
.btn.ghost { background: transparent; border-color: var(--line); color: var(--ink-2); }
.btn.ghost:hover:not(:disabled) { background: var(--bg-soft); }
.btn.danger { color: var(--err); border-color: color-mix(in srgb, var(--err) 45%, var(--line)); }
.btn.danger:hover:not(:disabled) { background: var(--err-bg); border-color: var(--err); color: var(--err); }
.btn.small { padding: 5px 10px; font-size: 12px; }
.btn.block { justify-content: center; width: 100%; padding: 10px; }

.icon-btn {
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center;
  border: 1px solid transparent; border-radius: var(--r-1);
  background: transparent; color: var(--muted);
  cursor: pointer; padding: 0;
  transition: background .12s, color .12s, border-color .12s;
}
.icon-btn:hover { background: var(--bg-soft); color: var(--ink); border-color: var(--line); }

.actions { display: flex; gap: 9px; margin-top: 14px; flex-wrap: wrap; align-items: center; }
.row { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; align-items: flex-end; }
.row label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--muted); }
.row label.inline { flex-direction: row; align-items: center; gap: 7px; font-size: 13px; color: var(--ink-2); padding-bottom: 7px; }

input[type=text], input[type=password], input[type=search], textarea, select.sel, .theme {
  padding: 7px 10px;
  border: 1px solid var(--line-2);
  border-radius: var(--r-1);
  background: var(--card);
  color: var(--ink);
  font: inherit; font-size: 13px;
  min-width: 230px;
  transition: border-color .12s, box-shadow .12s;
}
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
input::placeholder, textarea::placeholder { color: color-mix(in srgb, var(--muted) 75%, transparent); }
input:disabled, select:disabled { opacity: .55; cursor: not-allowed; }
select.sel, .theme { min-width: 0; cursor: pointer; }
select.sel.small, .theme { padding: 5px 8px; font-size: 12px; }
textarea { width: 100%; font-family: var(--mono); font-size: 12px; margin: 10px 0 0; }
input[type=checkbox] { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }

details { margin-top: 14px; }
summary {
  cursor: pointer; color: var(--accent); font-size: 13px; font-weight: 500;
  list-style: none; display: inline-flex; align-items: center; gap: 6px;
  user-select: none;
}
summary::-webkit-details-marker { display: none; }
summary::before { content: "▸"; font-size: 10px; transition: transform .12s; }
details[open] > summary::before { transform: rotate(90deg); }

.seg { display: inline-flex; background: var(--bg-soft); border-radius: var(--r-1); padding: 2px; gap: 2px; }
.seg button {
  padding: 5px 12px; border: 0; border-radius: 6px;
  background: transparent; color: var(--muted);
  font: inherit; font-size: 12.5px; cursor: pointer;
  transition: background .12s, color .12s;
}
.seg button:hover { color: var(--ink); }
.seg button.on { background: var(--card); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-1); }

.toolbar { display: flex; gap: 10px; align-items: center; margin-bottom: 14px; flex-wrap: wrap; }
.toolbar .search { flex: 1; min-width: 200px; display: flex; }
.toolbar .search input { width: 100%; }

.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 20px;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  font-size: 11px; font-weight: 500; color: var(--muted);
  white-space: nowrap;
}
.pill.ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 40%, var(--line)); background: var(--ok-bg); }
.pill.bad { color: var(--err); border-color: color-mix(in srgb, var(--err) 40%, var(--line)); background: var(--err-bg); }

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: 20px;
  background: var(--bg-soft); border: 1px solid var(--line);
  font-size: 12px; color: var(--ink-2);
}
.chip b { font-weight: 650; color: var(--ink); }

/* ═══════════ ссылки в Google ═══════════
   Кнопка на файл — главное действие карточки, поэтому у неё цвет продукта
   в иконке и нейтральная оправа: так она узнаётся с одного взгляда и при
   этом не спорит с акцентом интерфейса. */
.glinks { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.glink {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px;
  border: 1px solid var(--line-2); border-radius: var(--r-1);
  background: var(--card); color: var(--ink);
  font-size: 12.5px; font-weight: 550;
  text-decoration: none; white-space: nowrap;
  transition: border-color .12s, background .12s, box-shadow .12s, transform .06s;
}
.glink:hover { text-decoration: none; box-shadow: var(--shadow-1); }
.glink:active { transform: translateY(1px); }
.glink .ic { color: var(--brand, var(--muted)); }
.glink .ext { width: 13px; height: 13px; color: var(--muted); opacity: .75; margin-left: -1px; }
.glink.sheets { --brand: var(--sheets); }
.glink.sheets:hover { border-color: var(--sheets); background: color-mix(in srgb, var(--sheets) 8%, var(--card)); }
.glink.script { --brand: var(--script); }
.glink.script:hover { border-color: var(--script); background: color-mix(in srgb, var(--script) 10%, var(--card)); }
.glink.lead { padding: 9px 15px; font-size: 13px; }
.glink.mini { padding: 5px 9px; font-size: 12px; }
.copy-btn { width: 30px; height: 30px; border: 1px solid var(--line-2); border-radius: var(--r-1); background: var(--card); }
.copy-btn:hover { border-color: var(--accent); color: var(--accent); background: var(--card); }
.copy-btn.done { color: var(--ok); border-color: var(--ok); }

/* ═══════════ список таблиц ═══════════ */
.tgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 12px; }
.tcard {
  display: flex; flex-direction: column; gap: 10px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  padding: 15px 16px 13px;
  box-shadow: var(--shadow-1);
  transition: border-color .14s, box-shadow .14s, transform .1s;
  position: relative;
}
.tcard:hover { border-color: var(--line-2); box-shadow: var(--shadow-2); transform: translateY(-1px); }
.tcard .t-top { display: flex; align-items: flex-start; gap: 10px; }
.tcard .t-mark {
  width: 32px; height: 32px; flex: none; border-radius: 9px;
  background: var(--accent-soft); color: var(--accent);
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
}
.tcard .t-name { min-width: 0; flex: 1; }
.tcard .t {
  font-size: 14.5px; font-weight: 600; letter-spacing: -.01em;
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tcard .t-sub { font-size: 12px; color: var(--muted); margin-top: 1px; }
.tcard .open-settings {
  border: 0; background: transparent; color: var(--muted);
  cursor: pointer; padding: 4px; border-radius: 6px; flex: none;
}
.tcard .open-settings:hover { background: var(--bg-soft); color: var(--accent); }
.tcard .tags { display: flex; gap: 5px; flex-wrap: wrap; }
.tag {
  font-size: 10.5px; font-weight: 600; letter-spacing: .01em;
  padding: 2px 8px; border-radius: 20px;
  border: 1px solid var(--line); color: var(--muted); background: var(--bg-soft);
}
.tag.mine { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); background: var(--accent-soft); }
/* Чужая таблица — это не «хорошо» и не «плохо», а просто не твоя:
   зелёный здесь читался бы как оценка. */
.tag.shared { color: var(--ink-2); }
.tag.ro { border-style: dashed; }
.tcard .t-foot {
  display: flex; align-items: center; gap: 6px;
  margin-top: auto; padding-top: 10px; border-top: 1px solid var(--line);
  flex-wrap: wrap;
}
.tcard .t-foot .grow { flex: 1; }

.empty {
  border: 1px solid var(--line); border-radius: var(--r-3);
  padding: 56px 24px 52px; text-align: center; color: var(--muted);
  background: var(--card-2); position: relative; overflow: hidden;
}
.empty::before {
  content: ""; position: absolute; left: 50%; top: -96px;
  width: 260px; height: 260px; margin-left: -130px;
  border: 1.5px solid var(--line-2); border-radius: 50%;
  border-top-color: var(--accent); border-right-color: var(--accent);
  transform: rotate(-35deg); opacity: .2; pointer-events: none;
}
.empty > * { position: relative; }
.empty b { display: block; color: var(--ink); font-size: 16px; margin-bottom: 4px; }
.empty .btn { margin-top: 16px; }

.skel { background: var(--bg-soft); border-radius: var(--r-2); height: 128px; animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* ═══════════ шаги и загрузка файла ═══════════ */
.steps { display: flex; gap: 8px; list-style: none; margin: 0 0 16px; padding: 0; flex-wrap: wrap; }
.steps li {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 14px 7px 8px;
  border: 1px solid var(--line); border-radius: 30px;
  font-size: 12.5px; color: var(--muted); background: var(--card);
}
.steps li b {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--bg-soft); color: var(--muted);
  display: grid; place-items: center; font-size: 11px; font-weight: 700;
}
.steps li.on { color: var(--ink); border-color: var(--accent); }
.steps li.on b { background: var(--accent); color: var(--accent-ink); }
.steps li.done b { background: var(--ok); color: #fff; }
.steps li.done { color: var(--ink-2); }

.drop {
  border: 2px dashed var(--line-2);
  border-radius: var(--r-2);
  padding: 30px 22px;
  text-align: center;
  background: var(--card-2);
  transition: border-color .15s, background .15s;
}
/* Файл над зоной: пунктир становится сплошным, а знак загрузки —
   акцентным кольцом, которое собирается за полоборота. Знак продукта
   буквально принимает файл. */
.drop.over {
  border-style: solid; border-color: var(--accent);
  background: var(--accent-soft);
}
.drop.over .drop-icon { position: relative; color: var(--accent); }
.drop.over .drop-icon .ic { opacity: 0; }
.drop.over .drop-icon::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 30px; height: 30px; margin: -15px 0 0 -15px;
  border: 2.5px solid var(--accent-soft); border-radius: 50%;
  border-top-color: var(--accent); border-right-color: var(--accent);
  animation: ring-gather .45s ease-out forwards;
}
.drop.small.over .drop-icon::after { width: 22px; height: 22px; margin: -11px 0 0 -11px; border-width: 2px; }
@keyframes ring-gather {
  from { transform: rotate(-150deg) scale(.55); opacity: .25; }
  70% { border-color: var(--accent-soft); border-top-color: var(--accent); border-right-color: var(--accent); }
  to { transform: none; opacity: 1; border-color: var(--accent); }
}

/* Завеса на всю страницу. Раньше файл ловила только сама зона, а мимо неё
   браузер открывал его вкладкой — и несохранённая работа пропадала. Теперь
   лист ловит вся страница, и она же показывает, что с ним будет.
   pointer-events выключены намеренно: иначе завеса сама становится целью
   перетаскивания и dragleave начинает мигать. */
.dropveil {
  position: fixed; inset: 0; z-index: 95;
  display: grid; place-content: center; justify-items: center; gap: 13px;
  padding: 24px;
  background: color-mix(in srgb, var(--bg) 84%, transparent);
  backdrop-filter: blur(3px) saturate(140%);
  pointer-events: none;
  animation: fade .14s ease-out;
}
.dropveil-ring {
  width: 74px; height: 74px; border-radius: 50%;
  border: 3px solid var(--accent-soft);
  border-top-color: var(--accent); border-right-color: var(--accent);
  animation: ring-gather .45s ease-out forwards;
}
.dropveil-text { font-size: 17px; font-weight: 700; letter-spacing: -.02em; color: var(--ink); }
.dropveil-sub { font-size: 13px; color: var(--muted); max-width: 360px; text-align: center; }
.dropveil.nodrop { background: color-mix(in srgb, var(--bg) 90%, transparent); }
.dropveil.nodrop .dropveil-ring { border-color: var(--line-2); animation: none; }
.dropveil.nodrop .dropveil-text { color: var(--ink-2); }
.drop p { margin: 3px 0; }
.drop .drop-icon { color: var(--muted); margin-bottom: 8px; }
.drop .drop-icon .ic { width: 28px; height: 28px; }
.drop-actions { display: flex; gap: 8px; justify-content: center; margin-top: 14px; }
.drop.small { padding: 18px 14px; margin-top: 10px; }
.drop.small .drop-icon .ic { width: 20px; height: 20px; }

/* ═══════════ страница таблицы ═══════════ */
.thead { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.thead-main { min-width: 0; flex: 1; }
.thead-title { display: flex; align-items: center; gap: 10px; min-width: 0; }
.thead-title h1 { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.thead-meta { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 5px; font-size: 12px; color: var(--muted); align-items: center; }
.thead-links { display: flex; gap: 6px; flex-wrap: wrap; }

.secnav {
  position: sticky; top: 52px; z-index: 15;
  display: flex; gap: 2px; flex-wrap: wrap;
  padding: 8px 0 10px;
  background: linear-gradient(var(--bg) 70%, transparent);
  margin-bottom: 4px;
}
.secnav button {
  padding: 5px 11px; border: 1px solid transparent; border-radius: 20px;
  background: transparent; color: var(--muted);
  font: inherit; font-size: 12.5px; cursor: pointer;
  transition: background .12s, color .12s;
}
.secnav button:hover { background: var(--bg-soft); color: var(--ink); }
.secnav button.on {
  background: var(--accent-soft); border-color: transparent;
  color: var(--accent); font-weight: 650;
}

.savebar {
  position: sticky; bottom: 0; z-index: 18;
  display: flex; align-items: center; gap: 9px;
  padding: 12px 16px;
  margin: 18px -4px 0;
  background: color-mix(in srgb, var(--card) 92%, transparent);
  backdrop-filter: saturate(160%) blur(10px);
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  box-shadow: var(--shadow-2);
  flex-wrap: wrap;
}
.dirty-tag { font-size: 12.5px; color: var(--muted); margin-right: auto; display: flex; align-items: center; gap: 7px; }
.savebar.dirty .dirty-tag { color: var(--warn); font-weight: 600; }
.savebar.dirty .dirty-tag::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--warn);
}
.manage-only { display: none; }
.savebar.can-manage .manage-only { display: inline-flex; }
.admin-only { display: none; }
body.is-admin .admin-only { display: revert; }
body.is-admin section.admin-only { display: block; }
body.is-admin .nav .admin-only { display: flex; }
body.is-admin .head-actions .admin-only { display: inline-flex; }

/* ═══════════ поля ═══════════ */
.summary { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.cur-pick { padding: 2px 6px 2px 10px; }
.cur-pick select { padding: 2px 6px; font-size: 12px; border: 0; background: transparent; min-width: 0; }

.notes { font-size: 12.5px; color: var(--muted); }
.notes p { margin: 3px 0; }
.warnings { margin: 12px 0; display: flex; flex-direction: column; gap: 6px; }
.w {
  padding: 9px 12px; border-radius: var(--r-1); font-size: 13px;
  border: 1px solid transparent; border-left-width: 3px;
}
.w.info { background: var(--ok-bg); border-left-color: var(--ok); }
.w.warn { background: var(--warn-bg); border-left-color: var(--warn); }
.w.error { background: var(--err-bg); border-left-color: var(--err); }
.w .f { font-family: var(--mono); font-size: 11.5px; opacity: .8; margin-right: 6px; }

.suggest {
  margin: 0 0 14px; padding: 14px 16px;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line));
  border-radius: var(--r-2);
  background: var(--accent-soft);
}
.suggest .actions { margin-top: 10px; }

.fields { display: flex; flex-direction: column; gap: 3px; }
.field {
  display: grid;
  grid-template-columns: minmax(150px, 220px) minmax(0, 1fr);
  gap: 14px; align-items: center;
  padding: 8px 10px;
  border-radius: var(--r-1);
  border-left: 3px solid transparent;
  transition: background .12s;
}
.field:hover { background: var(--card-2); }
.field .name { font-weight: 600; font-size: 13px; }
.field .why { font-size: 12.5px; color: var(--ink-2); }
.field .samples { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.field.none .name > div { color: var(--muted); font-weight: 400; }
/* Уверенность автодетекта — полоской слева и значком у названия: отвечает
   на единственный вопрос, который тут задают, — смотреть глазами или пройти
   мимо. Голый процент на него не отвечает. */
.field.c-high   { border-left-color: var(--ok); }
.field.c-mid    { border-left-color: var(--warn); }
.field.c-low    { border-left-color: var(--err); }
.field.c-manual { border-left-color: var(--accent); }
.field.c-absent { border-left-color: var(--line-2); }

.conf {
  display: inline-block; margin-top: 3px;
  padding: 1px 7px; border-radius: 10px;
  font-size: 10px; font-weight: 700; white-space: nowrap;
}
.conf.high   { background: var(--ok-bg);   color: var(--ok); }
.conf.mid    { background: var(--warn-bg); color: var(--warn); }
.conf.low    { background: var(--err-bg);  color: var(--err); }
.conf.manual { background: var(--accent-soft); color: var(--accent); }
.conf.absent { background: transparent; color: var(--muted); border: 1px dashed var(--line-2); }

/* выбор источника поля */
.pick { position: relative; }
.pick-btn {
  width: 100%; text-align: left;
  padding: 7px 11px;
  border: 1px solid var(--line-2); border-radius: var(--r-1);
  background: var(--card); color: var(--ink);
  font: inherit; cursor: pointer;
  display: flex; flex-direction: column; gap: 2px;
  transition: border-color .12s, box-shadow .12s;
}
.pick-btn:hover { border-color: var(--accent); }
.pick-btn .cur { font-size: 12.5px; font-weight: 550; }
.pick-btn .vals { font-family: var(--mono); font-size: 10.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-btn .vals.empty { color: var(--err); }

.pop {
  position: absolute; z-index: 60; right: 0; top: calc(100% + 5px);
  width: min(460px, 78vw); max-height: 420px; overflow: auto;
  background: var(--card); border: 1px solid var(--line-2);
  border-radius: var(--r-2); box-shadow: var(--shadow-3);
}
.pop .filter { position: sticky; top: 0; background: var(--card); padding: 9px; border-bottom: 1px solid var(--line); }
.pop .filter input { width: 100%; min-width: 0; }
.pop .grp {
  padding: 8px 12px 4px; font-size: 10.5px; font-weight: 700;
  color: var(--muted); text-transform: uppercase; letter-spacing: .04em;
  position: sticky; top: 49px; background: var(--card);
}
.pop .opt { padding: 8px 12px; cursor: pointer; border-top: 1px solid var(--line); }
.pop .opt:hover { background: var(--card-2); }
.pop .opt.sel { background: var(--accent-soft); }
.pop .opt .n { display: flex; align-items: center; gap: 7px; justify-content: space-between; font-size: 13px; font-weight: 550; }
.pop .opt .why { font-size: 11.5px; color: var(--muted); margin-top: 4px; }

/* Значения-примеры вразбивку: источник выбирают именно по ним, и одной
   строкой через точку четыре значения читаются как одно длинное. */
.vchips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.vchip {
  font-family: var(--mono); font-size: 11px;
  padding: 2px 7px; border-radius: 5px;
  background: var(--bg-soft); border: 1px solid var(--line);
  color: var(--ink-2);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.vmore { font-size: 11px; color: var(--muted); align-self: center; }
.pop .opt.sel .vchip { background: var(--card); }

/* Свёрнутое «неприменимое»: показывать его наравне с рабочим — значит
   вытеснить вниз то, ради чего сюда пришли. */
details.more { margin-top: 14px; border-top: 1px dashed var(--line); padding-top: 10px; }
details.more > summary { color: var(--muted); font-weight: 500; }
details.more > summary:hover { color: var(--ink); }
details.more > p { font-size: 12px; margin-top: 6px; }
details.more .fields { margin-top: 8px; }

/* карточки колонок */
.colgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 9px; margin-top: 12px; }
.col {
  border: 1px solid var(--line); border-radius: var(--r-2);
  padding: 11px 12px; font-size: 12px;
  display: flex; flex-direction: column; gap: 5px;
  background: var(--card);
  transition: border-color .12s;
}
.col:hover { border-color: var(--line-2); }
.col.dead { opacity: .5; }
.col-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.col b { font-size: 13px; }
.col .hint { color: var(--ink-2); }
.col .meta { color: var(--muted); font-size: 11px; }
.col .s { font-family: var(--mono); font-size: 10.5px; color: var(--muted); word-break: break-all; }
.col .tail { font-size: 11px; color: var(--ok); background: var(--ok-bg); border-radius: 6px; padding: 4px 8px; }
.col .roles { display: flex; gap: 4px; flex-wrap: wrap; }
.col .role { font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 20px; background: var(--accent); color: var(--accent-ink); }
.col select { width: 100%; margin-top: 2px; padding: 5px 7px; font-size: 11.5px; border: 1px solid var(--line-2); border-radius: 7px; background: var(--card); color: var(--ink); font-family: inherit; }

.kind {
  font-size: 10px; font-weight: 700; padding: 1px 7px;
  border-radius: 20px; white-space: nowrap; border: 1px solid;
}
.kind.k-web   { color: var(--sheets); border-color: var(--sheets); background: color-mix(in srgb, var(--sheets) 14%, transparent); }
.kind.k-token { color: #8b5cf6; border-color: #8b5cf6; background: color-mix(in srgb, #8b5cf6 14%, transparent); }
.kind.k-date  { color: #0ea5e9; border-color: #0ea5e9; background: color-mix(in srgb, #0ea5e9 14%, transparent); }
.kind.k-geo   { color: var(--ok); border-color: var(--ok); background: var(--ok-bg); }
.kind.k-id    { color: var(--warn); border-color: var(--warn); background: var(--warn-bg); }
.kind.k-num   { color: var(--accent); border-color: var(--accent); background: var(--accent-soft); }
.kind.k-dim   { color: var(--muted); border-color: var(--line-2); }
.kind.k-dead  { color: var(--muted); border-color: var(--line-2); border-style: dashed; }

/* ═══════════ числа ═══════════ */
.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(146px, 1fr)); gap: 9px; }
.tile {
  border: 1px solid var(--line); border-radius: var(--r-2);
  padding: 11px 13px; background: var(--card-2);
}
.tile .k { font-size: 11px; color: var(--muted); }
.tile .v { font-size: 19px; font-weight: 650; font-variant-numeric: tabular-nums; margin-top: 3px; letter-spacing: -.02em; }
.tile.na .v { color: var(--muted); font-size: 13px; font-weight: 400; }

.caps { margin: 14px 0; display: flex; gap: 6px; flex-wrap: wrap; font-size: 12px; }
.cap { padding: 3px 10px; border-radius: 20px; border: 1px solid var(--line); color: var(--muted); }
.cap.on { background: var(--ok-bg); color: var(--ok); border-color: color-mix(in srgb, var(--ok) 35%, var(--line)); }
.cap.off { text-decoration: line-through; opacity: .7; }

.tablewrap { overflow-x: auto; margin-top: 12px; border-radius: var(--r-1); }
table { border-collapse: collapse; font-size: 12.5px; width: 100%; }
th, td { padding: 7px 11px; border-bottom: 1px solid var(--line); text-align: right; white-space: nowrap; }
th {
  background: var(--bg-soft); color: var(--ink-2);
  position: sticky; top: 0; font-weight: 650; font-size: 11.5px;
  text-transform: uppercase; letter-spacing: .03em;
}
th:first-child, td:first-child { text-align: left; }
td:first-child { font-family: var(--mono); font-size: 11.5px; }
tbody tr:hover { background: var(--card-2); }
.tablewrap.card { padding: 0; overflow: hidden; }
.tablewrap.card table { border-radius: var(--r-2); }

/* ═══════════ функционал и метрики ═══════════ */
.features { display: grid; grid-template-columns: repeat(auto-fill, minmax(215px, 1fr)); gap: 7px; }
.feature, .metric {
  display: flex; gap: 9px;
  padding: 9px 11px;
  border: 1px solid var(--line); border-radius: var(--r-1);
  cursor: pointer; font-size: 13px;
  background: var(--card);
  transition: border-color .12s, background .12s;
}
.feature { align-items: center; }
.metric { align-items: flex-start; }
.feature:hover, .metric:hover { border-color: var(--accent); background: var(--card-2); }
.feature.off, .metric.off { opacity: .45; cursor: not-allowed; border-style: dashed; }
.feature.off:hover, .metric.off:hover { border-color: var(--line); background: var(--card); }
.metrics { display: grid; grid-template-columns: repeat(auto-fill, minmax(245px, 1fr)); gap: 7px; }
.metric b { font-weight: 650; }
.metric .formula { font-family: var(--mono); font-size: 10.5px; color: var(--muted); margin-top: 3px; line-height: 1.4; }
.metric.core { border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); }
.metric.core b::after { content: " ·"; color: var(--accent); }
.metric input { margin-top: 2px; }

/* ═══════════ статусы ═══════════ */
.status { margin-top: 12px; font-size: 13px; }
.status:empty { margin-top: 0; }
.status .line { padding: 4px 0; display: flex; gap: 7px; align-items: flex-start; }
.status .line::before { flex: none; font-weight: 700; }
.status .line.ok::before { content: "✓"; color: var(--ok); }
.status .line.bad::before { content: "✕"; color: var(--err); }
.status .line.run::before { content: "◌"; color: var(--muted); animation: spin 1.6s linear infinite; }
.status .line.muted { color: var(--muted); }
.status .line.muted::before { content: "·"; color: var(--muted); }
@keyframes spin { to { transform: rotate(360deg); } }
.status ul { margin: 6px 0 0; padding-left: 20px; font-size: 12.5px; }

pre {
  font-family: var(--mono); font-size: 11.5px;
  background: var(--card-2); border: 1px solid var(--line);
  border-radius: var(--r-1); padding: 12px;
  overflow: auto; max-height: 420px; margin: 10px 0 0;
}

/* ═══════════ история и доступ ═══════════ */
.hist .hrow { padding: 12px 0; border-top: 1px solid var(--line); }
.hist .hrow:first-child { border-top: 0; padding-top: 4px; }
.hist .hh { display: flex; gap: 9px; align-items: baseline; flex-wrap: wrap; }
.hist .hh b { font-size: 13px; }
.hist .hrow.cur .hh b::after { content: " · текущая"; color: var(--ok); font-weight: 500; font-size: 12px; }
.hist .hrow ul { margin: 7px 0 0; padding-left: 20px; font-size: 12.5px; color: var(--ink-2); }
.hist .hrow ul li { margin: 2px 0; }
.hist .hrow .btn { margin-top: 9px; }

.pw-once {
  font-family: var(--mono); font-size: 13px;
  background: var(--warn-bg); border: 1px solid var(--warn);
  border-radius: var(--r-1); padding: 10px 12px; margin-bottom: 6px;
  user-select: all;
}
.auth { font-size: 13px; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }

/* ═══════════ тосты ═══════════ */
.toasts {
  position: fixed; z-index: 90; right: 18px; bottom: 18px;
  display: flex; flex-direction: column; gap: 8px; align-items: flex-end;
  pointer-events: none;
}
.toast {
  display: flex; align-items: flex-start; gap: 9px;
  min-width: 250px; max-width: 420px;
  padding: 11px 14px;
  background: var(--card); border: 1px solid var(--line-2);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-1); box-shadow: var(--shadow-3);
  font-size: 13px; pointer-events: auto;
  animation: toast-in .18s ease-out;
}
.toast.ok { border-left-color: var(--ok); }
.toast.bad { border-left-color: var(--err); }
.toast.out { animation: toast-out .18s ease-in forwards; }
.toast .ic { margin-top: 1px; }
.toast.ok .ic { color: var(--ok); }
.toast.bad .ic { color: var(--err); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }
@keyframes toast-out { to { opacity: 0; transform: translateX(16px); } }

/* ═══════════ модальные окна ═══════════
   Свои вместо prompt()/confirm(): в системных нельзя ни объяснить
   последствие, ни потребовать слово для подтверждения. */
.scrim {
  position: fixed; inset: 0; z-index: 70;
  background: rgba(8, 11, 16, .5);
  backdrop-filter: blur(2px);
  animation: fade .15s;
}
@keyframes fade { from { opacity: 0; } }
.modal {
  position: fixed; z-index: 80;
  left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(460px, calc(100vw - 32px));
  background: var(--card); border: 1px solid var(--line-2);
  border-radius: var(--r-3); box-shadow: var(--shadow-3);
  padding: 22px 24px 18px;
  animation: pop .16s ease-out;
}
@keyframes pop { from { opacity: 0; transform: translate(-50%, -46%) scale(.98); } }
.modal h2 { font-size: 16px; margin-bottom: 8px; }
.modal p { font-size: 13px; color: var(--ink-2); }
.modal input[type=text] { width: 100%; margin-top: 12px; }
.modal .actions { justify-content: flex-end; margin-top: 18px; }
.modal .hintline { font-size: 12px; color: var(--muted); margin-top: 8px; }

/* ═══════════ палитра ═══════════ */
.palette { position: fixed; inset: 0; z-index: 85; display: grid; place-items: start center; padding-top: 12vh; }
.palette-box {
  width: min(600px, calc(100vw - 32px));
  background: var(--card); border: 1px solid var(--line-2);
  border-radius: var(--r-2); box-shadow: var(--shadow-3);
  overflow: hidden;
  animation: pop-top .16s ease-out;
}
@keyframes pop-top { from { opacity: 0; transform: translateY(-8px); } }
.palette-box input {
  width: 100%; border: 0; border-bottom: 1px solid var(--line);
  border-radius: 0; padding: 14px 16px; font-size: 15px; background: var(--card);
}
.palette-box input:focus { box-shadow: none; border-color: var(--line); }
.palette-list { max-height: 50vh; overflow: auto; padding: 6px; }
.palette-list .p-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; border-radius: var(--r-1); cursor: pointer;
}
.palette-list .p-row:hover, .palette-list .p-row.on { background: var(--accent-soft); }
.palette-list .p-row b { font-size: 13.5px; font-weight: 600; }
.palette-list .p-row .p-sub { font-size: 11.5px; color: var(--muted); margin-left: auto; }
.palette-list .p-empty { padding: 20px; text-align: center; color: var(--muted); font-size: 13px; }

/* ═══════════ узкий экран ═══════════
   Телефон — не уменьшенный десктоп. Здесь другой размер пальца (кнопка
   меньше 38 точек не нажимается), другая высота экрана (нижняя панель из
   шести кнопок съедала половину) и другой браузер: iOS увеличивает страницу,
   если поле ввода меньше 16px, и обратно уже не возвращает. Всё это правится
   стилями, а не второй вёрсткой: разметка одна, иначе половина правок
   доезжала бы только до одной из них. */
.only-narrow, .only-narrow-flex { display: none; }

@media (max-width: 960px) {
  .two { grid-template-columns: 1fr; }
  .field { grid-template-columns: 1fr; gap: 6px; }
  .field .name { display: flex; align-items: center; gap: 8px; }
  .content { padding: 18px 16px 120px; }
  .topbar { padding: 10px 16px; }
}

@media (max-width: 760px) {
  .only-narrow { display: grid; }
  .only-narrow-flex { display: inline-flex; }

  /* ── меню выезжает поверх, а не сжимает страницу ── */
  .side {
    position: fixed; left: 0; top: 0; bottom: 0;
    width: min(290px, 86vw);
    transform: translateX(-100%);
    transition: transform .2s ease-out;
    box-shadow: var(--shadow-3);
    /* Выше затемнения (70) — иначе оно гасит само меню — и выше
       уведомлений (90), которые иначе ложатся на первые пункты. */
    z-index: 92;
  }
  body.side-open .side { transform: none; }
  body.side-open { overflow: hidden; }   /* страница под меню не ездит */
  .side-foot { padding-bottom: calc(10px + env(safe-area-inset-bottom)); }

  /* ── шапка ── */
  .topbar { gap: 8px; padding: 8px 14px; }
  .kbd { display: none; }               /* ⌘K на телефоне не нажать */
  .crumbs { font-size: 12.5px; }

  /* ── содержимое ── */
  /* Боковые отступы считаются с вырезом: в горизонтальной ориентации iPhone
     «чёлка» съедала левый край карточек. */
  .content {
    padding: 14px max(14px, env(safe-area-inset-right)) calc(92px + env(safe-area-inset-bottom))
             max(14px, env(safe-area-inset-left));
  }
  .card { padding: 16px 14px; }
  .page-head { flex-direction: column; }
  .head-actions { margin-left: 0; width: 100%; }
  .head-actions .btn { flex: 1; justify-content: center; }
  /* minmax(0,…) обязателен: иначе колонка растягивается по самой широкой
     неразрывной строке внутри карточки — ряд ссылок в Google выпихивал
     карточку за край экрана. */
  .tgrid { grid-template-columns: minmax(0, 1fr); }
  .tcard { min-width: 0; }
  .thead-title h1 { font-size: 18px; }
  .tiles { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 7px; }

  /* Вкладки таблицы — одна прокручиваемая строка. В две строки они занимали
     столько же места, сколько первая карточка под ними. */
  .secnav {
    flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x proximity;
    scrollbar-width: none; margin: 0 -14px 4px; padding: 8px 14px 10px;
  }
  .secnav::-webkit-scrollbar { display: none; }
  .secnav button { flex: none; padding: 7px 13px; font-size: 13px; scroll-snap-align: start; }
  /* Ссылки в Google — одной прокручиваемой строкой. Перенос на вторую
     строку отодвигал вкладки на пол-экрана вниз. */
  .thead-links, .thead-links .glinks {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px;
  }
  .thead-links::-webkit-scrollbar, .thead-links .glinks::-webkit-scrollbar { display: none; }
  .thead-links .glink { flex: none; }

  /* Карточка таблицы в списке: ссылки — прокручиваемой строкой, ярлычок
     «поделиться» остаётся с ними в одном ряду, а не уезжает под них. */
  .tcard .t-foot { flex-wrap: nowrap; }
  .tcard .glinks {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    min-width: 0; flex: 1;
  }
  .tcard .glinks::-webkit-scrollbar { display: none; }
  .tcard .glink { flex: none; }
  .tcard .share-btn { flex: none; }
  /* «Скрипт» в карточке — значком: подпись обрезалась на полуслове, а
     заходят по ней с телефона редко. У главной ссылки подпись остаётся. */
  .tcard .glink.script span { display: none; }
  .tcard .glink.script { padding-left: 9px; padding-right: 9px; }

  /* ── нижняя панель: одна строка ──
     Главное действие видно всегда, остальное — под «Ещё» (лист действий).
     Панель во всю ширину, без скруглений: так она читается как часть окна, а
     не как уехавшая вниз карточка. */
  .savebar {
    flex-wrap: nowrap; gap: 8px;
    margin: 16px -14px 0; border-radius: 0; border-left: 0; border-right: 0;
    padding: 10px 14px calc(10px + env(safe-area-inset-bottom));
  }
  .savebar > .btn:not(#btn-save):not(#btn-more) { display: none; }
  .savebar #btn-save { flex: 1; justify-content: center; }
  .savebar #btn-more { flex: none; }
  .dirty-tag { display: none; }         /* состояние показывает сама кнопка */
  .savebar.dirty { border-top: 2px solid var(--warn); }

  /* ── поля ввода ── */
  input[type=text], input[type=password], input[type=search], textarea, select.sel {
    min-width: 0; width: 100%;
    font-size: 16px;                    /* меньше — и iOS увеличит страницу при фокусе */
  }
  select.sel.small { font-size: 16px; padding: 7px 10px; }
  .row label { width: 100%; }
  .selrow input[type="number"], .selrow select { width: 100%; min-width: 0; font-size: 16px; }
  .toolbar { flex-direction: column; align-items: stretch; }
  .toolbar .search { width: 100%; }

  /* ── тач-цели ── */
  /* Серая вспышка на каждом касании — привычка старых мобильных браузеров;
     свои состояния :hover/:active рисуют то же самое, но по делу. */
  button, a, label, summary { -webkit-tap-highlight-color: transparent; }
  .btn, .icon-btn, .seg button, .secnav button, .sheet-item { touch-action: manipulation; }
  .share-list, .palette-list, #events, .tablewrap { overscroll-behavior: contain; }
  .icon-btn { width: 38px; height: 38px; }
  .btn { padding: 10px 14px; }
  .btn.small { padding: 8px 12px; }
  .seg button { padding: 8px 12px; font-size: 13px; }
  .share-seg button { padding: 7px 10px; font-size: 12px; }

  /* ── окна снизу, как в мобильных приложениях ── */
  .modal {
    left: 0; top: auto; bottom: 0; transform: none;
    width: 100%; max-height: 88vh; overflow-y: auto;
    border-radius: var(--r-3) var(--r-3) 0 0; border-bottom: 0;
    padding-bottom: calc(18px + env(safe-area-inset-bottom));
    animation: sheet-up .2s ease-out;
  }
  .modal.share, .modal.sheet { width: 100%; }
  .modal.share .share-list { max-height: 52vh; }
  @keyframes sheet-up { from { transform: translateY(14%); opacity: .5; } }
  /* Поиск опускается ниже уведомлений и ложится поверх них: пока человек
     ищет таблицу, всплывашка не должна закрывать строку ввода. */
  .palette { padding-top: 12vh; z-index: 95; }
  .palette-box { width: calc(100vw - 20px); }
  .palette-box input { font-size: 16px; }
  .palette-list { max-height: 58vh; }

  /* ── уведомления сверху ──
     Снизу они ложились поверх нижней панели и поверх листа действий — то
     есть ровно поверх того, к чему человек в этот момент тянется. */
  .toasts {
    left: 10px; right: 10px; bottom: auto;
    top: calc(58px + env(safe-area-inset-top));
    align-items: stretch;
  }
  .toast { min-width: 0; max-width: none; }

  /* ── таблица пользователей разворачивается карточками ──
     Шесть колонок в 375 точек не помещаются никаким шрифтом, а
     горизонтальная прокрутка прятала как раз кнопки справа. */
  .utable, .utable tbody, .utable tr, .utable td { display: block; width: auto; }
  .utable thead { display: none; }
  .utable tr {
    border: 1px solid var(--line); border-radius: var(--r-2);
    padding: 12px 14px; margin-bottom: 10px; background: var(--card-2);
  }
  .utable td { border: 0; padding: 3px 0; text-align: left; }
  .utable td:first-child { font-size: 15px; }
  .utable td[data-label]::before {
    content: attr(data-label) ": "; color: var(--muted); font-size: 12px;
  }
  .umail { width: 100%; }
  /* Журнал действий — четыре колонки; на телефоне он просто прокручивается
     вбок: это диагностика для админа, а не то, с чем работают с телефона. */
  #events { overflow-x: auto; }
  .evtable { min-width: 460px; }
  .evtable td { font-size: 11.5px; }
}

/* Строка доступа на телефоне: переключатель уходит под имя. Трём уровням
   нужно около 200 точек, и на экране 390 имени с почтой оставалось меньше
   половины — читалось «BDM_Ekat…» и обрезанная почта. */
@media (max-width: 460px) {
  .share-row { grid-template-columns: 32px minmax(0, 1fr); gap: 4px 10px; padding: 10px 8px; }
  .share-row .ava { width: 32px; height: 32px; }
  .share-seg { grid-column: 2; justify-self: start; margin-top: 2px; }
}

/* Совсем узкие экраны — 360 точек и меньше. */
@media (max-width: 380px) {
  .btn { padding: 10px 11px; font-size: 12.5px; }
  .thead-title h1 { font-size: 17px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
