/* ═══════════════════════════════════════════════════════════════════════════
   ПЛАТФОРМА VM GEO - ВИЗУАЛ VM ANALYTICS

   Владелец 24.09.2026: «возьми из VM Analytics весь визуал именно платформы, там он
   идеален. Сохрани его отдельным файлом и тут поправь всё, делаем дальше в тех стилях и
   интерфейсах, чтобы всё было похоже».

   Источник - кабинет VM Analytics (zaffiro-analytics/frontend):
     src/styles.css        палитра светлой и тёмной темы, подсветка под курсором
     tailwind.config.js    роли цветов, шрифты, скругления, тень карточки
     src/Layout.tsx        каркас: боковое меню + шапка + содержимое
     src/Sidebar.tsx       меню: знак, разделы, вкладки раздела, «Выйти»
     src/SectionTabs.tsx   вкладки раздела
     src/ThemeToggle.tsx   солнце / луна в шапке
     App.tsx (AuthShell)   экран входа
   Там это Tailwind-классы, здесь - те же значения обычным CSS: у нас нет сборки.
   Цвета, размеры и отступы списаны один в один; описание и правила - ВИЗУАЛ.md.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Палитра, светлая тема (styles.css VM Analytics, один в один) ── */
:root{
  --vm-header-h:61px;

  --vm-bg:245 246 251;  --vm-surface:242 244 251;  --vm-subbar:242 244 251;
  --vm-panel:255 255 255;  --vm-panel-soft:242 244 251;
  --vm-invert:15 18 38;  --vm-invert-soft:27 31 56;  --vm-invert-text:255 255 255;
  --vm-disabled:rgba(18,20,45,.17);

  --vm-net-dot:rgba(107,79,224,.30);  --vm-net-line:rgba(107,79,224,.10);
  --vm-net-thread:rgba(107,79,224,.34);

  --vm-line:rgba(18,20,45,.10);  --vm-line-soft:rgba(18,20,45,.05);
  --vm-line-strong:rgba(18,20,45,.17);  --vm-line-strongest:rgba(18,20,45,.28);

  --vm-text:15 18 38;  --vm-text-strong:10 12 28;  --vm-text-800:35 40 63;
  --vm-text-soft:58 65 88;  --vm-text-mid:78 85 104;  --vm-muted:78 85 104;
  --vm-faint:99 106 128;  --vm-faint-soft:155 161 180;

  --vm-accent:107 79 224;  --vm-accent-strong:89 64 196;
  --vm-accent-bg:rgba(107,79,224,.07);  --vm-accent-line:rgba(107,79,224,.22);
  --vm-good:14 122 78;  --vm-good-bg:rgba(14,122,78,.08);  --vm-good-line:rgba(14,122,78,.22);
  --vm-bad:196 43 43;  --vm-bad-bg:rgba(196,43,43,.07);  --vm-bad-line:rgba(196,43,43,.20);
  --vm-warn:138 106 31;  --vm-warn-bg:rgba(138,106,31,.08);  --vm-warn-line:rgba(138,106,31,.22);

  --vm-scrim:rgba(15,18,38,.45);
  --vm-spot-a:rgba(107,79,224,.16);  --vm-spot-b:rgba(107,79,224,.05);
  --vm-spot-ring:rgba(107,79,224,.28);
  --vm-shadow-card:0 18px 45px rgba(15,18,38,.10);
  /* Сетка на фоне - из прежнего вида платформы (владелец 24.09.2026: «сетку сделай на
     фоне как было, как будто её не хватает»). Шаг и прозрачность - прежние. */
  --vm-grid:rgba(18,20,45,.05);

  /* Скругления: кнопка 11, поле 12, карточка 18, панель 22. */
  --r-btn:11px; --r-field:12px; --r-card:18px; --r-panel:22px;

  /* Основной текст - Inter (если установлен), иначе системный: как в VM Analytics.
     Заголовки - Oswald капсом. */
  --font:"Inter",ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --font-display:"Oswald","PT Sans Narrow","Inter",sans-serif;

  color-scheme:light;
  accent-color:rgb(var(--vm-accent));
  color:rgb(var(--vm-text));
  background:rgb(var(--vm-bg));
}

/* ── Палитра, тёмная тема (тоже один в один) ── */
:root[data-theme="dark"]{
  --vm-bg:8 8 12;  --vm-surface:26 26 38;  --vm-subbar:26 26 38;
  --vm-panel:16 16 24;  --vm-panel-soft:26 26 38;
  --vm-invert:244 245 250;  --vm-invert-soft:228 230 240;  --vm-invert-text:8 8 12;
  --vm-disabled:rgba(255,255,255,.14);
  --vm-net-dot:rgba(180,190,235,.42);  --vm-net-line:rgba(155,132,255,.16);
  --vm-net-thread:rgba(155,132,255,.45);

  --vm-line:rgba(255,255,255,.08);  --vm-line-soft:rgba(255,255,255,.045);
  --vm-line-strong:rgba(255,255,255,.14);  --vm-line-strongest:rgba(255,255,255,.24);

  --vm-text:244 245 250;  --vm-text-strong:255 255 255;  --vm-text-800:221 224 236;
  --vm-text-soft:194 199 216;  --vm-text-mid:163 168 186;  --vm-muted:163 168 186;
  --vm-faint:131 137 153;  --vm-faint-soft:95 101 119;

  --vm-accent:155 132 255;  --vm-accent-strong:185 166 255;
  --vm-accent-bg:rgba(155,132,255,.10);  --vm-accent-line:rgba(155,132,255,.28);
  --vm-good:61 220 151;  --vm-good-bg:rgba(61,220,151,.10);  --vm-good-line:rgba(61,220,151,.26);
  --vm-bad:255 107 107;  --vm-bad-bg:rgba(255,107,107,.10);  --vm-bad-line:rgba(255,107,107,.26);
  --vm-warn:227 180 87;  --vm-warn-bg:rgba(227,180,87,.10);  --vm-warn-line:rgba(227,180,87,.26);

  --vm-scrim:rgba(0,0,0,.62);
  --vm-spot-a:rgba(155,132,255,.20);  --vm-spot-b:rgba(155,132,255,.07);
  --vm-spot-ring:rgba(155,132,255,.34);
  --vm-shadow-card:0 18px 45px rgba(0,0,0,.45);
  --vm-grid:rgba(255,255,255,.028);

  color-scheme:dark;
  color:rgb(var(--vm-text));
  background:rgb(var(--vm-bg));
}

/* ── Основа (как preflight Tailwind: без полей по умолчанию) ── */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; font-synthesis:none; text-rendering:optimizeLegibility;
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale}
body{margin:0; min-width:320px; min-height:100vh; font-family:var(--font); font-size:16px;
  line-height:1.5; color:rgb(var(--vm-text)); background:rgb(var(--vm-bg))}
h1,h2,h3,h4,p{margin:0}
a{color:inherit; text-decoration:none}
button,input,select,textarea{font:inherit; color:inherit}
img,svg{display:block}

/* Поля в тёмной теме: без явного фона браузер рисует белое поле посреди тёмной карточки. */
:where(:root[data-theme="dark"] input, :root[data-theme="dark"] textarea,
       :root[data-theme="dark"] select){background-color:rgb(var(--vm-panel)); color:rgb(var(--vm-text))}
:root[data-theme="dark"] input::placeholder,
:root[data-theme="dark"] textarea::placeholder{color:rgb(var(--vm-faint))}

/* Значок: 16px (h-4 w-4) по умолчанию. */
.i{width:16px; height:16px; flex:none}
.i-sm{width:14px; height:14px; flex:none}
.i-md{width:20px; height:20px; flex:none}
.spin{animation:vm-spin 1s linear infinite}
@keyframes vm-spin{to{transform:rotate(360deg)}}

/* ── Сетка на фоне: клетка 54px, ярче сверху, к низу растворяется. Лежит под живым
   фоном и под всем содержимым, клики не ловит. ── */
body::before{content:""; position:fixed; inset:-2px; z-index:0; pointer-events:none;
  background-image:linear-gradient(var(--vm-grid) 1px,transparent 1px),
                   linear-gradient(90deg,var(--vm-grid) 1px,transparent 1px);
  background-size:54px 54px;
  -webkit-mask:radial-gradient(120% 85% at 50% 0%,#000 30%,transparent 78%);
  mask:radial-gradient(120% 85% at 50% 0%,#000 30%,transparent 78%)}

/* ── Живой фон (MoleculesBackdrop) ── */
.net{position:fixed; inset:0; z-index:0; width:100vw; height:100vh; pointer-events:none;
  display:none; transform:translateZ(0); will-change:transform}
@media(min-width:1024px){ .net{display:block} }

/* ── Каркас платформы (Layout + Sidebar) ── */
.shell{position:relative; display:flex; min-height:100vh}
.side{position:relative; z-index:10; display:none; width:240px; flex-shrink:0;
  border-right:1px solid var(--vm-line-soft); background:rgb(var(--vm-panel) / .85);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px); flex-direction:column}
@media(min-width:1024px){ .side{display:flex} }
/* Строка знака - ровно высоты шапки: разделитель под ними идёт одной линией через весь
   экран, а не двумя ступенькой. */
.side-brand{display:flex; align-items:center; gap:12px; height:var(--vm-header-h); padding:0 20px;
  border-bottom:1px solid var(--vm-line-soft)}
.side-brand img{width:32px; height:32px; object-fit:contain; user-select:none}
.brand-t{display:flex; flex-direction:column; line-height:1.25}
.brand-name{font-family:var(--font-display); font-size:19px; font-weight:600;
  text-transform:uppercase; letter-spacing:.06em; color:rgb(var(--vm-text))}
.brand-sub{font-size:10px; font-weight:500; text-transform:uppercase; letter-spacing:.14em;
  color:rgb(var(--vm-faint))}
.side-nav{display:flex; flex-direction:column; gap:4px; padding:12px}
.side-link{display:flex; align-items:center; gap:12px; padding:8px 12px; border-radius:var(--r-btn);
  font-size:14px; line-height:20px; font-weight:500; color:rgb(var(--vm-text-soft));
  transition:background-color .15s, color .15s}
.side-link:hover{background:rgb(var(--vm-panel-soft))}
.side-link.on{background:rgb(var(--vm-accent)); color:rgb(var(--vm-invert-text))}
/* Вкладки раздела в меню - отступом, без линии слева: полоски в меню владелец убрал
   (24.09.2026). */
.side-sub{display:flex; flex-direction:column; gap:2px; margin:2px 0 0 28px}
.side-tab{padding:6px 12px; border-radius:var(--r-btn); font-size:14px; line-height:20px;
  color:rgb(var(--vm-muted)); transition:background-color .15s, color .15s}
.side-tab:hover{background:rgb(var(--vm-panel-soft)); color:rgb(var(--vm-text))}
.side-tab.on{font-weight:500; color:rgb(var(--vm-text))}
.side-foot{margin-top:auto; padding:12px; display:flex; flex-direction:column; gap:4px}
.side-me{padding:0 12px; font-size:12px; line-height:16px; color:rgb(var(--vm-faint));
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.side-foot .side-link{width:100%; border:0; background:none; cursor:pointer; color:rgb(var(--vm-muted))}
.side-foot .side-link:hover{background:rgb(var(--vm-panel-soft)); color:rgb(var(--vm-text))}

.main{position:relative; z-index:10; display:flex; flex:1; min-width:0; flex-direction:column}
.topbar{position:sticky; top:0; z-index:20; display:flex; height:var(--vm-header-h);
  align-items:center; justify-content:flex-end; gap:12px; padding:0 20px;
  border-bottom:1px solid var(--vm-line-soft); background:rgb(var(--vm-bg))}
@media(min-width:640px){ .topbar{padding:0 32px} }
@media(min-width:1024px){ .topbar{padding:0 40px} }
/* Переключатель профиля - место и подпись как у «Проекта» в шапке VM Analytics
   (ProjectSwitcher), а сам список - свой: у компании видно название, рубрику и адрес. */
.switch{position:relative; display:flex; min-width:0; align-items:center; gap:8px}
.switch-l{font-size:12px; line-height:16px; font-weight:500; color:rgb(var(--vm-muted))}
@media(max-width:639px){ .switch-l{display:none} }
.switch-b{display:flex; min-width:0; max-width:320px; align-items:center; gap:8px;
  border-radius:var(--r-field); border:1px solid var(--vm-line); background:rgb(var(--vm-panel));
  padding:6px 10px 6px 12px; font-size:14px; line-height:20px; font-weight:500;
  color:rgb(var(--vm-text)); cursor:pointer; transition:border-color .15s}
.switch-b:hover{border-color:var(--vm-line-strong)}
.switch-b:focus-visible{outline:2px solid rgb(var(--vm-accent)); outline-offset:2px}
.switch-b .i-sm{color:rgb(var(--vm-faint))}
.switch-name{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.switch-chev{transition:transform .15s}
.switch.open .switch-chev{transform:rotate(180deg)}
@media(max-width:639px){ .switch-b{max-width:52vw} }

/* Выпадающий список: панель как карточка, строка - как пункт меню. */
.dd{position:absolute; top:calc(100% + 8px); right:0; z-index:50; width:380px;
  max-width:calc(100vw - 24px); display:flex; flex-direction:column; gap:4px; padding:6px;
  border-radius:var(--r-card); border:1px solid var(--vm-line); background:rgb(var(--vm-panel));
  box-shadow:var(--vm-shadow-card)}
.dd[hidden]{display:none}
/* На телефоне список - во всю ширину экрана под шапкой: от кнопки он уезжал за край. */
@media(max-width:639px){
  .dd{position:fixed; top:calc(var(--vm-header-h) + 8px); left:12px; right:12px; width:auto;
    max-width:none}
}
.dd-search{display:flex; align-items:center; gap:8px; margin:2px 2px 4px; padding:8px 12px;
  border-radius:var(--r-field); border:1px solid var(--vm-line); background:rgb(var(--vm-panel-soft));
  color:rgb(var(--vm-faint)); cursor:text}
.dd-search:focus-within{border-color:rgb(var(--vm-accent))}
.dd-search input{flex:1; min-width:0; border:0; background:none; outline:none; padding:0;
  font-size:14px; line-height:20px; color:rgb(var(--vm-text))}
.dd-list{display:flex; max-height:min(60vh,420px); flex-direction:column; gap:2px; overflow-y:auto}
.dd-item{display:flex; align-items:center; gap:12px; padding:10px 12px; border-radius:var(--r-btn);
  transition:background-color .15s}
button.dd-item, button.dd-foot{width:100%; border:0; background:transparent; font:inherit;
  text-align:left; cursor:pointer}
.dd form{display:block; margin:0}
.dd-item[hidden]{display:none}
.dd-item:hover, .dd-item:focus-visible{background:rgb(var(--vm-panel-soft)); outline:none}
.dd-item.on{background:var(--vm-accent-bg)}
.dd-ic{display:flex; width:32px; height:32px; flex:none; align-items:center; justify-content:center;
  border-radius:10px; background:var(--vm-accent-bg); color:rgb(var(--vm-accent))}
.dd-t{display:flex; min-width:0; flex:1; flex-direction:column; gap:2px}
.dd-t b{font-size:14px; line-height:20px; font-weight:600; color:rgb(var(--vm-text));
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.dd-t span{font-size:12px; line-height:16px; color:rgb(var(--vm-muted));
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.dd-check{color:rgb(var(--vm-accent))}
.dd-empty{padding:12px; font-size:14px; line-height:20px; color:rgb(var(--vm-muted))}
.dd-empty[hidden]{display:none}
.dd-foot{display:flex; align-items:center; justify-content:space-between; gap:8px; padding:10px 12px;
  border-radius:var(--r-btn); font-size:14px; line-height:20px; font-weight:500;
  color:rgb(var(--vm-accent)); transition:background-color .15s}
.dd-foot:hover{background:var(--vm-accent-bg)}
.dd-foot-muted{color:rgb(var(--vm-muted))}
.dd-foot-muted:hover{background:rgb(var(--vm-panel-soft)); color:rgb(var(--vm-text))}
button.dd-item.on{background:var(--vm-accent-bg)}
button.dd-item:hover{background:rgb(var(--vm-panel-soft))}
.icon-btn{display:flex; width:36px; height:36px; flex-shrink:0; align-items:center;
  justify-content:center; border-radius:var(--r-btn); border:1px solid var(--vm-line);
  background:rgb(var(--vm-panel)); color:rgb(var(--vm-text-soft)); cursor:pointer;
  transition:border-color .15s, color .15s}
.icon-btn:hover{border-color:var(--vm-line-strong); color:rgb(var(--vm-text))}
.theme-btn .i-sun{display:none}
:root[data-theme="dark"] .theme-btn .i-sun{display:block}
:root[data-theme="dark"] .theme-btn .i-moon{display:none}
.menu-btn{position:fixed; left:16px; top:12px; z-index:30; width:40px; height:40px}
@media(min-width:1024px){ .menu-btn{display:none} }
@media(max-width:1023px){ .topbar{padding-left:72px} }

/* Меню на телефоне: выезжает слева поверх затемнения. */
.drawer{position:fixed; inset:0; z-index:40; display:none}
.drawer.open{display:flex}
.drawer .scrim{flex:1; background:var(--vm-scrim); order:2}
.drawer .side{display:flex; width:256px; background:rgb(var(--vm-panel)); box-shadow:var(--vm-shadow-card)}
@media(min-width:1024px){ .drawer{display:none !important} }

.content{min-width:0; flex:1; padding-bottom:64px}
.page{padding:32px 20px; color:rgb(var(--vm-text-strong))}
@media(min-width:640px){ .page{padding:32px} }
@media(min-width:1024px){ .page{padding:32px 40px} }
.page-in{margin:0 auto; display:flex; max-width:1280px; flex-direction:column; gap:32px}
.page-head{display:flex; align-items:flex-end; justify-content:space-between; gap:20px;
  padding-bottom:28px; border-bottom:1px solid var(--vm-line)}
.page-head p{margin-top:8px; font-size:14px; line-height:24px; color:rgb(var(--vm-muted))}
.back{display:inline-flex; align-items:center; gap:6px; margin-bottom:12px; font-size:14px;
  line-height:20px; color:rgb(var(--vm-muted))}
.back:hover{color:rgb(var(--vm-accent))}

/* Заголовок страницы: Oswald капсом, как во всех разделах VM Analytics. */
.display{font-family:var(--font-display); text-transform:uppercase; letter-spacing:.04em;
  font-weight:600; color:rgb(var(--vm-text-strong))}
h1.display{font-size:30px; line-height:36px}
@media(min-width:640px){ h1.display{font-size:36px; line-height:40px} }
h2.display{font-size:24px; line-height:32px}

/* Вкладки раздела (SectionTabs). */
.tabs{position:sticky; top:var(--vm-header-h); z-index:10; padding:0 20px;
  border-bottom:1px solid var(--vm-line); background:rgb(var(--vm-subbar))}
@media(min-width:640px){ .tabs{padding:0 32px} }
@media(min-width:1024px){ .tabs{padding:0 40px} }
.tabs-in{margin:0 auto; display:flex; max-width:1280px; gap:4px; overflow-x:auto; scrollbar-width:none}
.tabs-in::-webkit-scrollbar{display:none}
.tab{margin-bottom:-1px; white-space:nowrap; padding:12px 16px; border-bottom:2px solid transparent;
  font-size:14px; line-height:20px; font-weight:600; color:rgb(var(--vm-muted)); transition:color .15s}
.tab:hover{color:rgb(var(--vm-text-800))}
.tab.on{border-color:rgb(var(--vm-accent)); color:rgb(var(--vm-accent))}

/* ── Карточки ── */
.card{border-radius:var(--r-card); border:1px solid var(--vm-line); background:rgb(var(--vm-panel));
  padding:24px; box-shadow:var(--vm-shadow-card)}
.card-sm{padding:16px 20px}
.card-soft{border-radius:var(--r-card); border:1px solid var(--vm-line);
  background:rgb(var(--vm-surface)); padding:16px 20px}
.panel-accent{border-radius:var(--r-panel); border:1px solid var(--vm-accent-line);
  background:var(--vm-accent-bg); padding:20px 24px; box-shadow:var(--vm-shadow-card)}
.card-h{display:flex; align-items:center; justify-content:space-between; gap:12px}
.card-t{font-size:16px; line-height:24px; font-weight:600; color:rgb(var(--vm-text-strong))}
.stack{display:flex; flex-direction:column; gap:12px}
.stack-lg{display:flex; flex-direction:column; gap:20px}
.row{display:flex; flex-wrap:wrap; align-items:center; gap:8px}

/* Подсветка под курсором (.spot) - один в один со styles.css VM Analytics. */
.spot{position:relative; isolation:isolate}
.spot::before{content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  z-index:-1; background:radial-gradient(260px circle at var(--mx,50%) var(--my,50%),
  var(--vm-spot-a), var(--vm-spot-b) 40%, transparent 66%);
  box-shadow:inset 0 0 0 1px var(--vm-spot-ring); opacity:0; transition:opacity .25s ease}
.spot:hover::before{opacity:1}
@media(hover:none){ .spot::before{display:none} }
@media(prefers-reduced-motion:reduce){ .spot::before{transition:none} }

/* ── Текст ── */
.t-muted{font-size:14px; line-height:24px; color:rgb(var(--vm-muted))}
.t-mid{font-size:14px; line-height:24px; color:rgb(var(--vm-text-mid))}
.t-small{font-size:12px; line-height:16px; color:rgb(var(--vm-muted))}
.t-faint{font-size:12px; line-height:16px; color:rgb(var(--vm-faint))}
.eyebrow{font-size:12px; line-height:16px; text-transform:uppercase; letter-spacing:.025em;
  color:rgb(var(--vm-faint))}
.section-t{font-size:14px; line-height:20px; font-weight:600; text-transform:uppercase;
  letter-spacing:.05em; color:rgb(var(--vm-muted))}
.t-strong{font-weight:600; color:rgb(var(--vm-text))}

/* ── Кнопки ── */
.btn{display:inline-flex; align-items:center; justify-content:center; gap:8px;
  border-radius:var(--r-btn); border:1px solid transparent; padding:8px 16px;
  font-size:14px; line-height:20px; font-weight:600; cursor:pointer; text-align:center;
  transition:background-color .15s, border-color .15s, color .15s}
.btn-primary{background:rgb(var(--vm-accent)); color:rgb(var(--vm-invert-text))}
.btn-primary:hover{background:rgb(var(--vm-accent-strong))}
.btn-primary:disabled{cursor:not-allowed; background:var(--vm-disabled); color:rgb(var(--vm-faint))}
.btn-outline{border-color:var(--vm-line-strong); background:rgb(var(--vm-panel));
  color:rgb(var(--vm-text-soft))}
.btn-outline:hover{border-color:var(--vm-line-strongest)}
.btn-outline:disabled{cursor:not-allowed; color:rgb(var(--vm-faint-soft))}
.btn-soft{border-color:var(--vm-accent-line); background:var(--vm-accent-bg);
  color:rgb(var(--vm-accent-strong))}
.btn-dark{background:rgb(var(--vm-invert)); color:rgb(var(--vm-invert-text))}
.btn-dark:hover{background:rgb(var(--vm-invert-soft))}
.btn-sm{padding:6px 12px; font-weight:500}
.btn-block{display:flex; width:100%}
.linkbtn{border:0; background:none; padding:0; cursor:pointer; font-size:14px; line-height:20px;
  font-weight:500; color:rgb(var(--vm-accent))}
.linkbtn:hover{text-decoration:underline}

/* ── Поля ── */
.lbl{display:block; margin-bottom:4px; font-size:14px; line-height:20px; font-weight:500;
  color:rgb(var(--vm-text-soft))}
.fld{display:flex; flex-direction:column; gap:4px}
.inp{width:100%; border-radius:var(--r-field); border:1px solid var(--vm-line);
  background:rgb(var(--vm-panel)); padding:8px 12px; font-size:14px; line-height:20px;
  color:rgb(var(--vm-text)); outline:none; transition:border-color .15s}
.inp:focus{border-color:rgb(var(--vm-accent))}
.inp.bad{border-color:var(--vm-bad-line)}
/* Поле растёт по тексту: текст модели бывает в три-пять строк, и поле в две строки
   обрезало его посередине (владелец 24.09.2026: «текст вылазит»). Где браузер не умеет
   field-sizing, высоту подгоняет platform.js. */
textarea.inp{resize:vertical; line-height:24px; field-sizing:content; min-height:64px;
  overflow-wrap:anywhere}
.hint{font-size:12px; line-height:16px; color:rgb(var(--vm-faint))}
.why{font-size:12px; line-height:16px; color:rgb(var(--vm-bad))}
.check{display:flex; align-items:flex-start; gap:8px; font-size:14px; line-height:20px;
  color:rgb(var(--vm-text-soft)); cursor:pointer}
.check input{margin:2px 0 0; accent-color:rgb(var(--vm-accent))}

/* ── Метки и плашки ── */
.badge{display:inline-flex; align-items:center; gap:4px; flex:none; white-space:nowrap;
  border-radius:999px; padding:2px 8px; font-size:12px; line-height:16px; font-weight:500}
.badge.good{background:var(--vm-good-bg); color:rgb(var(--vm-good))}
.badge.bad{background:var(--vm-bad-bg); color:rgb(var(--vm-bad))}
.badge.warn{background:var(--vm-warn-bg); color:rgb(var(--vm-warn))}
.badge.accent{background:var(--vm-accent-bg); color:rgb(var(--vm-accent))}
.badge.muted{background:rgb(var(--vm-panel-soft)); color:rgb(var(--vm-faint))}
.chip{display:inline-flex; border-radius:999px; border:1px solid var(--vm-line);
  padding:4px 12px; font-size:12px; line-height:16px; color:rgb(var(--vm-text-mid))}
.banner{border-radius:var(--r-card); border:1px solid; padding:12px 20px; font-size:14px; line-height:20px}
.banner.good{border-color:var(--vm-good-line); background:var(--vm-good-bg); color:rgb(var(--vm-good))}
.banner.bad{border-color:var(--vm-bad-line); background:var(--vm-bad-bg); color:rgb(var(--vm-bad))}
.banner.warn{border-color:var(--vm-warn-line); background:var(--vm-warn-bg); color:rgb(var(--vm-warn))}

/* ── Экран входа (AuthShell) ── */
.auth{position:relative; display:flex; min-height:100vh; flex-direction:column}
.auth-main{position:relative; z-index:10; display:flex; flex:1; flex-direction:column;
  align-items:center; justify-content:center; gap:28px; padding:32px 20px;
  color:rgb(var(--vm-text-strong))}
.auth-brand{display:flex; align-items:center; gap:12px}
.auth-brand img{width:40px; height:40px; object-fit:contain; user-select:none}
.auth-brand .brand-name{font-size:22px}
.auth-card{width:100%; max-width:384px; border-radius:var(--r-card); border:1px solid var(--vm-line);
  background:rgb(var(--vm-panel) / .9); padding:32px 28px; box-shadow:var(--vm-shadow-card);
  -webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px)}
.auth-card h1.display{font-size:24px; line-height:32px}
.auth-card.wide{max-width:540px}

/* ── Подвал ── */
.foot{border-top:1px solid var(--vm-line)}
.foot-in{margin:0 auto; max-width:1280px; padding:24px 20px; font-size:12px; line-height:16px;
  color:rgb(var(--vm-muted))}
@media(min-width:640px){ .foot-in{padding:24px 32px} }
@media(min-width:1024px){ .foot-in{padding:24px 40px} }

/* ═══════════════════ Компоненты экранов платформы ═══════════════════
   Собраны из тех же деталей VM Analytics: карточка, вложенная плашка bg-surface,
   метки rounded-full, подписи text-xs muted. Новых цветов и размеров здесь нет. */
.stack-sm{display:flex; flex-direction:column; gap:8px}
.warn-t{color:rgb(var(--vm-warn))}

/* Строка профиля в списке: слева ссылка на профиль, справа состояние и (у руководителя)
   закрепление за аккаунт-менеджером. */
.client-row{display:flex; align-items:center; gap:16px}
.client-main{display:flex; min-width:0; flex:1; align-items:center; gap:16px}
.client-go-a{display:flex; flex:none}
/* Открытый список поверх соседних строк: иначе следующая карточка его перекрывает. */
.spot:has([data-dd].open){z-index:5}
.client-ic{display:flex; width:40px; height:40px; flex:none; align-items:center; justify-content:center;
  border-radius:var(--r-btn); background:var(--vm-accent-bg); color:rgb(var(--vm-accent))}
.client-t{display:flex; min-width:0; flex:1; flex-direction:column; gap:2px}
.client-meta{display:flex; flex-direction:column; align-items:flex-end; gap:4px; text-align:right}
.client-go{color:rgb(var(--vm-faint-soft))}
.assign{position:relative; flex:none}
.assign-b{max-width:220px}
.assign-none{border-style:dashed; color:rgb(var(--vm-muted))}
@media(max-width:639px){
  .client-row{flex-wrap:wrap}
  .client-meta{width:100%; flex-direction:row; align-items:center; justify-content:space-between}
  .client-go-a{display:none}
  .assign{width:100%}
  .assign-b{max-width:none; width:100%}
}

/* Команда. */
.team-form{display:grid; grid-template-columns:1fr 1fr auto; align-items:end; gap:12px}
@media(max-width:767px){ .team-form{grid-template-columns:1fr} }
.team-row{display:flex; align-items:center; gap:16px; flex-wrap:wrap}
.team-act{flex:none; justify-content:flex-end}
.team-act form{display:flex}

/* Этапы упаковки: номер, название, что делаем. Открыт один - он и развёрнут. */
.stages{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:16px}
.stage-h{display:flex; align-items:flex-start; gap:16px}
.stage-mark{display:flex; width:32px; height:32px; flex:none; align-items:center; justify-content:center;
  border-radius:999px; font-size:14px; font-weight:600; border:1px solid var(--vm-line-strong);
  color:rgb(var(--vm-faint)); background:rgb(var(--vm-panel))}
.stage-open .stage-mark{border-color:transparent; background:rgb(var(--vm-accent));
  color:rgb(var(--vm-invert-text))}
.stage-done .stage-mark{border-color:var(--vm-good-line); background:var(--vm-good-bg); color:rgb(var(--vm-good))}
.stage-t{display:flex; min-width:0; flex:1; flex-direction:column; gap:4px}
.stage-t p{max-width:72ch}
.stage-badges{display:flex; flex:none; flex-wrap:wrap; justify-content:flex-end; gap:6px}
@media(max-width:639px){ .stage-h{flex-wrap:wrap} .stage-t{flex-basis:calc(100% - 48px)}
  .stage-badges{margin-left:48px; justify-content:flex-start} }
.stage-locked .card-t{color:rgb(var(--vm-muted))}
.stage-body{display:flex; flex-direction:column; gap:16px; margin:24px 0 0 48px}
@media(max-width:639px){ .stage-body{margin-left:0} }

.facts{display:grid; grid-template-columns:max-content 1fr; gap:8px 20px; margin:0;
  font-size:14px; line-height:20px}
.facts dt{color:rgb(var(--vm-muted))}
.facts dd{margin:0; min-width:0; overflow-wrap:anywhere; color:rgb(var(--vm-text))}

.brand-row{display:flex; align-items:center; gap:16px}
.brand-col{gap:4px; min-width:0}
.logo-box{display:flex; width:64px; height:64px; flex:none; align-items:center; justify-content:center;
  overflow:hidden; border-radius:var(--r-field); border:1px solid var(--vm-line);
  background:rgb(var(--vm-panel)); color:rgb(var(--vm-faint-soft))}
.logo-box img{max-width:100%; max-height:100%; object-fit:contain}
.sw{width:28px; height:28px; border-radius:8px; border:1px solid var(--vm-line)}
.inl-row{display:flex; align-items:center; gap:8px}
.inl-row .inp{flex:1; min-width:0}
input[type=file].inp{padding:6px 8px; font-size:12px}

.tiles{display:grid; grid-template-columns:repeat(auto-fill,minmax(120px,1fr)); gap:8px}
.tile{display:flex; flex-direction:column; gap:2px; padding:12px 16px; border-radius:var(--r-field);
  border:1px solid var(--vm-line); background:rgb(var(--vm-panel))}
.tile b{font-size:24px; line-height:32px; font-weight:600; color:rgb(var(--vm-text-strong))}
.tile span{font-size:12px; line-height:16px; color:rgb(var(--vm-muted))}
.tile-empty b{color:rgb(var(--vm-warn))}

.ask-list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px;
  font-size:14px; line-height:20px; color:rgb(var(--vm-text-soft))}
.ask-list li{display:flex; align-items:flex-start; gap:8px}
.ask-list .i-sm{margin-top:3px; color:rgb(var(--vm-accent))}

/* ── ТЗ и картинки упаковки ──
   Превью в кадре своего места (главное 3:1, следующие 4:3, обложки 16:9 или 9:16), под ним
   варианты миниатюрами. Всё из тех же токенов: панель, линия, акцент, радиусы полей. */
.sw-sm{width:18px; height:18px; border-radius:6px}
.more > summary{display:inline-flex; align-items:center; gap:6px; cursor:pointer; list-style:none;
  font-size:13px; line-height:20px; font-weight:500; color:rgb(var(--vm-accent))}
.more > summary::-webkit-details-marker{display:none}
.more > summary:hover{color:rgb(var(--vm-accent-strong))}
.more-body{margin-top:12px; padding-top:12px; border-top:1px solid var(--vm-line)}
.tz-facts{margin-top:12px}
.tz-cover + .tz-cover{padding-top:16px; border-top:1px solid var(--vm-line)}

.pics-head{flex-wrap:wrap; gap:12px}
.pics{display:grid; gap:16px}
@media(min-width:900px){ .pics-extra, .pics-cover{grid-template-columns:1fr 1fr} }
.pic{min-width:0}
.pic-t{gap:2px}
.pic-task{max-width:80ch}
.pic-frame{position:relative; width:100%; overflow:hidden; border-radius:var(--r-field);
  border:1px solid var(--vm-line); background:rgb(var(--vm-panel))}
/* Вертикальная обложка 9:16: держим высоту, ширина - по пропорции, иначе кадр вытянется. */
.pic-frame.pic-tall{width:auto; height:520px; max-width:100%; margin:0 auto}
@media(max-width:639px){ .pic-frame.pic-tall{height:440px} }
.pic-frame a, .pic-frame img{display:block; width:100%; height:100%}
.pic-frame img{object-fit:cover}
.pic-empty{display:flex; height:100%; flex-direction:column; align-items:center; justify-content:center;
  gap:8px; font-size:12px; color:rgb(var(--vm-faint))}
.pic-busy{position:absolute; left:8px; bottom:8px; display:inline-flex; align-items:center; gap:6px;
  padding:4px 10px; border-radius:999px; font-size:12px; background:rgb(var(--vm-panel) / .92);
  color:rgb(var(--vm-accent)); border:1px solid var(--vm-accent-line)}
/* Полоса 4:1 у главного: сверху и снизу по 1/8 высоты затемняем - там только фон. */
.safe-band{position:absolute; left:0; right:0; top:12.5%; bottom:12.5%; pointer-events:none;
  border-top:1px dashed rgba(255,255,255,.9); border-bottom:1px dashed rgba(255,255,255,.9);
  box-shadow:0 0 0 999px rgba(15,18,38,.38); opacity:0; transition:opacity .15s}
.pic:has(.band-toggle input:checked) .safe-band{opacity:1}
.band-toggle{font-size:12px}

.vers{display:flex; flex-wrap:wrap; gap:8px}
.ver{position:relative; display:block; height:56px; overflow:hidden; border-radius:8px;
  border:2px solid transparent; outline:1px solid var(--vm-line); background:rgb(var(--vm-panel))}
.ver img{display:block; height:100%; width:auto; object-fit:cover}
.ver:hover{outline-color:var(--vm-accent-line)}
.ver.on{border-color:rgb(var(--vm-accent)); outline-color:transparent}
.ver-ok{position:absolute; right:3px; top:3px; display:flex; width:18px; height:18px; align-items:center;
  justify-content:center; border-radius:999px; background:rgb(var(--vm-good)); color:#fff}
.ver-ok .i-sm{width:12px; height:12px}

.vid{padding-top:12px; border-top:1px solid var(--vm-line)}
.vid .card-h{flex-wrap:wrap; gap:8px}
.vid-t{display:flex; min-width:0; align-items:flex-start; gap:6px; font-size:14px; line-height:20px;
  font-weight:500; color:rgb(var(--vm-text))}
.vid-t .i-sm{flex:none; margin-top:2px; color:rgb(var(--vm-accent))}

/* ── Упаковка целиком: прайс, ТЗ, сетки мест, фото по разделам ── */
.pics-one{grid-template-columns:1fr}
@media(min-width:900px){ .pics-one .pic{max-width:560px} }
@media(min-width:900px){ .pics-grid{grid-template-columns:1fr 1fr} }
@media(min-width:1280px){ .pics-grid{grid-template-columns:1fr 1fr 1fr} }

.price-list{display:flex; flex-direction:column; gap:8px}
.price-it{display:flex; align-items:center; gap:12px; padding:8px; border-radius:var(--r-field);
  border:1px solid var(--vm-line); background:rgb(var(--vm-panel))}
.price-ph{display:flex; width:56px; height:56px; flex:none; align-items:center; justify-content:center;
  overflow:hidden; border-radius:8px; background:rgb(var(--vm-surface)); color:rgb(var(--vm-faint-soft))}
.price-ph img{width:100%; height:100%; object-fit:cover}
.price-t{min-width:0; flex:1; gap:2px}
.price-t b{font-size:14px; line-height:20px; font-weight:500; color:rgb(var(--vm-text))}
.price-p{flex:none; font-size:14px; font-weight:600; color:rgb(var(--vm-text-strong)); white-space:nowrap}
@media(max-width:639px){ .price-it{flex-wrap:wrap} .price-p{width:100%; padding-left:68px} }

.tz-sec > summary{font-size:14px}
.tz-row{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,2fr); gap:8px; align-items:start}
.tz-row3{grid-template-columns:minmax(0,2fr) minmax(0,1fr) minmax(0,1fr)}
.tz-story{grid-template-columns:minmax(0,1fr) minmax(0,1fr) minmax(0,2fr)}
.tz-date{display:flex; align-items:center; gap:6px; font-weight:400}
.tz-date .inp{width:auto}
@media(max-width:767px){ .tz-row, .tz-row3, .tz-story{grid-template-columns:1fr} }

.sec-list{display:grid; gap:12px}
@media(min-width:900px){ .sec-list{grid-template-columns:1fr 1fr} }
.sec{display:flex; flex-direction:column; gap:8px; padding:12px; border-radius:var(--r-field);
  border:1px solid var(--vm-line); background:rgb(var(--vm-panel))}
.sec .card-h b{font-size:14px; font-weight:600; color:rgb(var(--vm-text-strong))}
.ver-box{display:flex; flex-direction:column; align-items:center; gap:2px}

/* Выбор кадра другого места: миниатюры с отметкой. */
.pick{display:flex; flex-wrap:wrap; gap:6px}
.pick-i{position:relative; display:block; height:56px; cursor:pointer}
.pick-i input{position:absolute; opacity:0; pointer-events:none}
.pick-i img{display:block; height:100%; width:auto; border-radius:8px; border:2px solid transparent;
  outline:1px solid var(--vm-line)}
.pick-i input:checked + img{border-color:rgb(var(--vm-accent)); outline-color:transparent}
.pick-i input:focus-visible + img{outline:2px solid rgb(var(--vm-accent))}

/* ── Истории: план серии строками и кадры 9:16 сеткой ── */
.slide-row{display:grid; grid-template-columns:24px 150px minmax(0,1.4fr) minmax(0,1.4fr) 130px 150px;
  gap:6px; align-items:center}
.slide-row .slide-frame{grid-column:3 / -1}
.slide-row .slide-real{grid-column:3 / -1; font-size:13px}
.slide-n{font-size:12px; color:rgb(var(--vm-faint)); text-align:right}
@media(max-width:1023px){
  .slide-row{grid-template-columns:24px minmax(0,1fr) minmax(0,1fr); padding-bottom:8px;
    border-bottom:1px solid var(--vm-line)}
  .slide-row .slide-frame, .slide-row .slide-real{grid-column:2 / -1}
}
.pics-story{grid-template-columns:repeat(auto-fill, minmax(200px, 1fr))}
.pics-story .pic{gap:10px; padding:14px}
.pics-story .pic-frame.pic-tall{height:auto; width:100%}
.text-box{padding-top:12px; border-top:1px solid var(--vm-line)}
@media(max-width:639px){
  .pics-story{grid-template-columns:1fr 1fr; gap:10px}
  .pics-story .pic{padding:10px; gap:8px}
  .pics-story .pic .card-h{flex-direction:column; align-items:flex-start; gap:4px}
  .pics-story .btn-sm{padding-left:8px; padding-right:8px}
}

.add-row{display:flex; flex-direction:column; gap:8px; margin-bottom:16px}

/* ── Палитры в брифе: карточка = полоса из пяти цветов, имя, настроение, «Выбрать» ── */
.pal-grid{display:grid; grid-template-columns:repeat(auto-fill, minmax(180px, 1fr)); gap:10px}
.pal{display:flex; flex-direction:column; gap:6px; padding:10px; border-radius:var(--r-field);
  border:1px solid var(--vm-line); background:rgb(var(--vm-panel))}
.pal.on{border-color:rgb(var(--vm-accent)); box-shadow:0 0 0 1px rgb(var(--vm-accent))}
.pal b{font-size:13px; line-height:18px; font-weight:600; color:rgb(var(--vm-text-strong))}
.pal-sw{display:flex; height:36px; overflow:hidden; border-radius:8px; border:1px solid var(--vm-line)}
.pal-sw span{flex:1}
.pal .btn{align-self:flex-start}
.dir-row{display:grid; grid-template-columns:24px minmax(0,2fr) 110px 110px; gap:6px; align-items:start}
.dir-row .dir-desc{grid-column:2 / -1}
@media(max-width:767px){ .dir-row{grid-template-columns:24px minmax(0,1fr) minmax(0,1fr); padding-bottom:8px;
  border-bottom:1px solid var(--vm-line)} .dir-row input[name^="sc_name"]{grid-column:2 / -1} }
.auto-note{display:flex; align-items:center; gap:6px; margin:16px 0 0 48px; color:rgb(var(--vm-accent))}
.auto-note form{margin:0 0 0 auto}
@media(max-width:639px){ .auto-note{margin-left:0} }
.tariff{display:flex; flex-direction:column; gap:6px; padding:14px 20px; margin-bottom:16px}
.tariff-h{display:flex; flex-wrap:wrap; align-items:center; gap:8px; color:rgb(var(--vm-text-strong))}
.tariff-choice{display:flex; flex-direction:column; gap:10px; margin:16px 0 0 48px}
.tariff-choice .row form{margin:0}
@media(max-width:639px){ .tariff-choice{margin-left:0} }

/* ТЗ - документ для менеджера: из чего собрано, сравнение с похожими, суть, план по блокам. */
.basis{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:8px;
  font-size:14px; line-height:20px}
.basis li{display:flex; align-items:flex-start; gap:8px}
.basis .i-sm{flex:none; margin-top:3px}
.basis-ok .i-sm{color:rgb(var(--vm-good))}
.basis-wait .i-sm{color:rgb(var(--vm-warn))}
.basis-no{color:rgb(var(--vm-faint))}
.basis b{font-weight:600; color:rgb(var(--vm-text-strong))}
.basis-no b{color:inherit}
.cmp-wrap{overflow-x:auto}
.cmp{width:100%; border-collapse:collapse; font-size:14px; line-height:20px}
.cmp th, .cmp td{padding:6px 10px; text-align:right; border-bottom:1px solid var(--vm-line);
  white-space:nowrap}
.cmp th:first-child, .cmp td:first-child{text-align:left; padding-left:0}
.cmp th{font-size:12px; font-weight:500; color:rgb(var(--vm-faint))}
.cmp tr.behind td:nth-child(2){color:rgb(var(--vm-bad)); font-weight:600}
.tz-lead{font-size:16px; line-height:24px; color:rgb(var(--vm-text-strong))}
.tz-doc p{margin:0; max-width:80ch}
.tz-plan dd .row{gap:6px}
.tz-plan dd .hint{display:block; margin-top:4px}
.tz-ol{margin:0; padding-left:20px; display:flex; flex-direction:column; gap:2px}
.tz-edit > summary{font-weight:500}
@media(max-width:639px){ .tz-doc .facts{grid-template-columns:1fr; gap:2px 0} .tz-doc .facts dd{margin-bottom:10px}
  .cmp th, .cmp td{padding:6px 4px; font-size:13px} .cmp th:first-child{font-size:0}
  .cmp td:first-child, .cmp th{white-space:normal} }

/* Креативы клиента в брифе - миниатюры образцов стиля. */
.samples{display:grid; grid-template-columns:repeat(auto-fill, minmax(140px, 1fr)); gap:10px}
.sample{margin:0; display:flex; flex-direction:column; gap:4px}
.sample img{width:100%; aspect-ratio:1; object-fit:cover; border-radius:var(--r-field);
  border:1px solid var(--vm-line); background:rgb(var(--vm-panel))}
.sample figcaption{display:flex; align-items:flex-start; justify-content:space-between; gap:4px;
  overflow-wrap:anywhere}
.sample form{margin:0}

/* Ролики: раскадровка таблицей для монтажёра. */
.scen-table-wrap{overflow-x:auto}
.scen-table{width:100%; border-collapse:collapse; font-size:13px; line-height:18px}
.scen-table th, .scen-table td{padding:6px 8px; border-bottom:1px solid var(--vm-line); vertical-align:top;
  text-align:left}
.scen-table th{font-size:12px; font-weight:500; color:rgb(var(--vm-faint)); white-space:nowrap}
.scen-table td:first-child, .scen-table td:nth-child(2){white-space:nowrap; color:rgb(var(--vm-faint))}
.scen-table .hint{display:block}
.scen-kind{max-width:220px}
@media(max-width:639px){ .scen-table{min-width:720px} }

.good-t{color:rgb(var(--vm-good))}
.pre{white-space:pre-line}
