@charset "UTF-8";
/* ══════════════════════════════════════════════════════════════════════════
   «Стройплощадка» — общий каркас экранов.
   ЖК «Молдир», 3-я очередь. СК Курылыс.
   Правка вида от 17.08.2026. Правила задачи: PRINCIPY.md.

   Здесь задан ВЕСЬ вид системы. Экран не имеет права переопределять каркас:
   если экрану нужен свой размер, вес или цвет — значит, его не хватает здесь.

   Шкалы, вне которых значений нет:
     размер текста   12 · 13 · 15 · 18 · 22 · 28 · 36
     вес             400 · 500 · 600
     отступ          4 · 8 · 12 · 16 · 24 · 32 · 48 · 64  (+20 внутри карточки)
     скругление      8 кнопки и поля · 10 карточки · 999 чипы
     высота цели     44 обычная · 52 главное действие

   Ни одного внешнего запроса. Шрифт системный, значки — символы и SVG.
   ══════════════════════════════════════════════════════════════════════════ */

/* ═══ 1. ПОЛНАЯ СВЕТЛАЯ ПАЛИТРА НА ГОЛОМ :root ═════════════════════════════
   Здесь определён КАЖДЫЙ цвет. В тёмной теме они только переопределяются.
   Ни один цвет не имеет единственного определения в тёмном блоке.            */

:root{
  /* ── поверхности ─────────────────────────────────────────────────────────
     База тёплая, а не белая. Холодный белый на солнце даёт блик и читается
     дёшево; тёплая бумага мягче и на площадке, и на встрече. Каждое
     значение — измерено, все пары ниже проходят AA.                       */
  --bg:        #f4f2ee;   /* страница: тёплая бумага */
  --surface:        #fffefb;   /* карточки, поля, таблицы */
  --surface2:       #ece9e2;   /* приглушённая поверхность, наведение */
  --surface3:       #e0dcd3;   /* дорожка полосы, нажатое состояние */

  /* ── текст ───────────────────────────────────────────────────────────── */
  --text:      #1c1a17;   /* 15.53:1 на фоне, 17.22:1 на поверхности */
  --text2:     #5c574f;   /* 6.41 на фоне, 5.91 на пов2, 5.24 на пов3 */
  /* 2.4:1 — НЕ ДЛЯ ТЕКСТА. Только подсказка в пустом поле и отключённое,
     то есть ровно то, что WCAG выводит из-под требования контраста.
     Намеренно НЕ дизайнерский #7a746a: тот даёт 4.14 и годится для
     надписей от 24 px, но у нас этим цветом красят подписи 13 px. */
  --text3:     #9a9287;
  --text-inv:  #ffffff;

  /* ── линии ───────────────────────────────────────────────────────────── */
  --line:     #ded9cf;   /* внешняя граница карточки и таблицы */
  --line-inner:  #ebe7df;   /* разделитель строк внутри карточки */
  /* Граница поля ввода и обычной кнопки. WCAG 2.1, 1.4.11: граница несёт
     форму элемента, значит нужны 3:1 к соседнему цвету. Прежний #b3aca0
     давал 2.23:1 к поверхности — мягче на вид и ниже нормы. Тон тот же,
     изменилась только светлота.
     #817c73: к --surface 4.11:1 · к --bg 3.71:1 · к --surface2 3.42:1 ·
     к --surface3 3.03:1 — покрыты покой, наведение и нажатие. */
  --line2:    #817c73;
  --edge:       #5c574f;   /* обводка, несущая смысл: дорожка Ганта, рамка фото */

  /* ── единственный акцент ─────────────────────────────────────────────── */
  --accent-main:        #3d4f96;   /* 7.55:1 на поверхности, белый на нём 7.62:1 */
  --accent-dark:    #31407c;   /* наведение на главной кнопке, белый 9.74:1 */
  --accent-bg:    #e7e8f4;   /* акцент на нём 6.26:1 */
  --accent-text:  #ffffff;
  --accent-ring:   0 0 0 3px rgba(61,79,150,.18);

  /* ── состояния: только для статусов, не для украшения ────────────────── */
  --ok:         #2f6b45;   /* 5.24:1 на своём чипе */
  --ok-bg:     #e3ece0;
  --warn:       #8a5a12;   /* 4.93:1 на своём чипе */
  --warn-bg:   #f6e9d4;
  --error:       #a33327;   /* 5.55:1 на своём чипе */
  --error-bg:   #f7e3de;

  /* завеса под выдвижным меню */
  --backdrop:      rgba(28,26,23,.45);

  /* ── глубина: теней почти нет ────────────────────────────────────────── */
  --shadow:        none;                            /* карточка — граница, не тень */
  --shadow-float:   0 4px 16px rgba(0,0,0,.08);      /* меню, всплывающее, ящик */
  --shadow-top:   0 -1px 0 var(--line);          /* закреплённая полоса внизу */

  /* ── отступы: 4 8 12 16 24 32 48 64 ──────────────────────────────────── */
  --p1: 4px;  --p2: 8px;  --p3: 12px; --p4: 16px;
  --p5: 24px; --p6: 32px; --p7: 48px; --p8: 64px;
  --p9: 64px;                 /* сохранено ради экранов; равно --p8 */
  --p-card: 20px;            /* внутренний отступ карточки — ровно 20 */

  /* ── размер текста: 12 13 15 18 22 28 36 ─────────────────────────────── */
  --t0: 12px;  /* артикул, микроподпись */
  --t1: 13px;  /* подпись, чип, шапка таблицы */
  --t2: 13px;  /* мелкий текст */
  --t3: 15px;  /* основной текст, кнопка, поле */
  --t4: 18px;  /* подзаголовок, значение в строке */
  --t5: 22px;  /* заголовок раздела */
  --t6: 28px;  /* заголовок экрана */
  --t7: 28px;  /* крупное число */
  --t8: 36px;  /* главное число экрана */

  --lh:      1.5;    /* текст */
  --lh-heading:  1.25;   /* заголовки от 22 px */

  /* ── скругления ──────────────────────────────────────────────────────── */
  --r1: 8px;    /* кнопки и поля */
  --r2: 10px;   /* карточки */
  --r3: 10px;   /* сохранено ради экранов; равно --r2 */
  --r-round: 999px;

  /* ── ширины колонок ──────────────────────────────────────────────────── */
  --width:      1120px;  /* реестры и Гант */
  --width-narrow:   720px;  /* экран одной задачи */
  --menu-width:    256px;

  /* ── цели нажатия ────────────────────────────────────────────────────── */
  --target:      44px;   /* обычная */
  --target-primary: 52px;   /* главное действие */
  /* Значки и кнопки самой шапки. Отдельно от --target: в поле цель растёт до 56,
     но шапка от этого расти не должна — иначе на телефоне она съедает экран. */
  --target-topbar: 44px;
  /* Строка списка. Не ниже 44 нигде, 52 за столом, 56 в поле. */
  --row:     52px;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
            "Helvetica Neue", Arial, sans-serif;

  color-scheme: light;
}

/* ═══ 2. ТЁМНАЯ ТЕМА — ТОЛЬКО ПЕРЕОПРЕДЕЛЕНИЕ ═════════════════════════════
   Те же роли, те же имена. Под защитой :root:not([data-theme="light"]) —
   ручной выбор светлой темы побеждает системную настройку.                  */

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:        #171613;
    --surface:        #1f1e1a;
    --surface2:       #2a2823;
    --surface3:       #35322b;

    --text:      #ecebe6;   /* 15.16:1 на фоне, 12.33:1 на пов2 */
    --text2:     #a8a296;   /* 7.13 на фоне, 5.80 на пов2, 5.04 на пов3 */
    --text3:     #8d887d;   /* не для текста */
    --text-inv:  #171613;

    --line:     #35322b;
    --line-inner:  #2a2823;
    --line2:    #827b6a;   /* к --surface 3.96:1 · --bg 4.30 · --surface2 3.50 · --surface3 3.04 */
    --edge:       #a8a296;

    --accent-main:        #97a6ee;   /* 7.76:1 на фоне, 5.60:1 на своей подложке */
    --accent-dark:    #b2bdf3;
    --accent-bg:    #2b2f4a;
    --accent-text:  #14161f;   /* 7.73:1 на акценте */
    --accent-ring:   0 0 0 3px rgba(151,166,238,.28);

    --ok:         #6fbf8c;   /* 5.87:1 на своём чипе */
    --ok-bg:     #24352b;
    --warn:       #dfa757;   /* 5.97:1 на своём чипе */
    --warn-bg:   #3a3122;
    --error:       #ef8f80;   /* 5.59:1 на своём чипе */
    --error-bg:   #402b27;

    --backdrop:      rgba(0,0,0,.62);

    --shadow:        none;
    --shadow-float:   0 4px 16px rgba(0,0,0,.45);
    --shadow-top:   0 -1px 0 var(--line);

    color-scheme: dark;
  }
}

:root[data-theme="dark"]{
  --bg:        #171613;
  --surface:        #1f1e1a;
  --surface2:       #2a2823;
  --surface3:       #35322b;

  --text:      #ecebe6;
  --text2:     #a8a296;
  --text3:     #8d887d;
  --text-inv:  #171613;

  --line:     #35322b;
  --line-inner:  #2a2823;
  --line2:    #827b6a;   /* к --surface 3.96:1 · --bg 4.30 · --surface2 3.50 · --surface3 3.04 */
  --edge:       #a8a296;

  --accent-main:        #97a6ee;
  --accent-dark:    #b2bdf3;
  --accent-bg:    #2b2f4a;
  --accent-text:  #14161f;
  --accent-ring:   0 0 0 3px rgba(151,166,238,.28);

  --ok:         #6fbf8c;
  --ok-bg:     #24352b;
  --warn:       #dfa757;
  --warn-bg:   #3a3122;
  --error:       #ef8f80;
  --error-bg:   #402b27;

  --backdrop:      rgba(0,0,0,.62);

  --shadow:        none;
  --shadow-float:   0 4px 16px rgba(0,0,0,.45);
  --shadow-top:   0 -1px 0 var(--line);

  color-scheme: dark;
}

/* ═══ 3. ОСНОВА ═══════════════════════════════════════════════════════════ */

*, *::before, *::after{ box-sizing: border-box; }

html{
  -webkit-text-size-adjust: 100%;
  font-size: 100%;
}

body{
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 var(--t3)/var(--lh) var(--font);
  letter-spacing: 0;
  /* Табличные цифры по всей системе: колонки чисел не пляшут нигде,
     ни в реестре, ни в плитке, ни в строке списка. */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;            /* страница по горизонтали не ездит никогда */
}

h1, h2, h3{
  margin: 0;
  line-height: var(--lh-heading);
  letter-spacing: -.01em;
  font-weight: 600;
}
h1{ font-size: var(--t6); }
h2{ font-size: var(--t5); }
h3{ font-size: var(--t4); letter-spacing: 0; line-height: var(--lh); }

p{ margin: 0 0 var(--p4); }
p:last-child{ margin-bottom: 0; }

a{ color: var(--accent-main); text-decoration: none; }
a:hover{ text-decoration: underline; }

img, svg{ max-width: 100%; }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible{
  outline: 2px solid var(--accent-main);
  outline-offset: 2px;
  border-radius: var(--r1);
}

/* Атрибут hidden сильнее любого display каркаса: экран прячет свои части
   именно им, и «спрятанное» поле не должно проступать из-за класса. */
[hidden]{ display: none !important; }

/* видно только программе чтения с экрана */
.sr{
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* число: не переносится (табличные цифры уже включены на body) */
.number{ font-variant-numeric: tabular-nums; white-space: nowrap; }

/* приглушённое служебное значение рядом с основным */
.muted{ color: var(--text2); font-size: var(--t2); }

/* артикул, номер строки ГПР — мелко и тихо, только там, где по нему ищут */
.sku{ color: var(--text2); font-size: var(--t0); letter-spacing: .02em; }

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

/* ═══ 4. ШАПКА ════════════════════════════════════════════════════════════
   Рисуется вызовом Шапка.нарисовать({экран:'…'}).

   Слева направо: разделы и марка · имя экрана · поиск по системе ·
   текущий объект · уведомления · тема · профиль с ролью.
   Текущий объект виден всегда — ошибка «завёл не в тот объект» невозможна.  */

.topbar{
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: var(--p2);
  min-height: 64px;
  padding: var(--p2) var(--p5);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

/* кнопка меню и марка системы: имя видно на каждом экране.
   Цель нажатия — квадрат 44×44 и не меньше. На телефоне марка спрятана,
   и без min-width кнопка сжималась до ширины трёх полосок: 30 px при
   заявленном пределе 44 (WCAG 2.5.5 / 2.5.8). Ширину держит min-width,
   а не отступы: отступы правит мобильное правило внизу файла. */
.topbar__menu{
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--p2);
  min-width: var(--target-topbar); min-height: var(--target-topbar);
  padding: 0 var(--p3);
  margin-left: calc(var(--p3) * -1);
  background: none; border: 0; border-radius: var(--r1);
  color: var(--text); font: inherit; cursor: pointer;
}
.topbar__menu:hover{ background: var(--surface2); }
.topbar__menu:active{ background: var(--surface3); }

.topbar__burger{
  position: relative; flex: 0 0 auto;
  display: block; width: 18px; height: 2px;
  background: currentColor; border-radius: 2px;
}
.topbar__burger::before, .topbar__burger::after{
  content: ""; position: absolute; left: 0;
  width: 18px; height: 2px; background: currentColor; border-radius: 2px;
}
.topbar__burger::before{ top: -6px; }
.topbar__burger::after{ top: 6px; }

.topbar__brand{
  font-size: var(--t3); font-weight: 600; letter-spacing: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.topbar__screen{
  min-width: 0;
  font-size: var(--t3); font-weight: 600; letter-spacing: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* молчит, пока крупный заголовок экрана виден в теле страницы */
.topbar__screen--quiet{
  opacity: 0; transform: translateY(3px);
  transition: opacity .16s ease, transform .16s ease;
}
body.scrolled .topbar__screen--quiet{ opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce){
  .topbar__screen--quiet{ transition: none; }
}

.topbar__spacer{ flex: 1 1 auto; min-width: 0; }

/* переключатель текущего объекта */
.object{ position: relative; flex: 0 1 auto; min-width: 0; display: flex; }

.object__button{
  display: inline-flex; align-items: center; gap: var(--p2);
  min-width: 0; min-height: var(--target-topbar); padding: 0 var(--p3);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line2); border-radius: var(--r1);
  font: 500 var(--t3)/1.2 var(--font); cursor: pointer;
  max-width: 62vw;
}
.object__button::before{
  content: ""; flex: 0 0 auto;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent-main);
}
.object__button[data-object="bayan"]::before{ background: var(--text3); }
.object__name{ min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.object__arrow{ color: var(--text2); font-size: var(--t0); }
.object__button:hover{ background: var(--surface2); }
.object__button:active{ background: var(--surface3); }

.object__menu{
  display: none; position: absolute; right: 0; top: calc(100% + var(--p2));
  min-width: 300px; padding: var(--p1);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r2); box-shadow: var(--shadow-float);
}
.object__menu[data-open="1"]{ display: block; }

.object__item{
  display: block; width: 100%; text-align: left;
  min-height: var(--target); padding: var(--p2) var(--p3);
  background: none; border: 0; border-radius: var(--r1);
  color: var(--text); font: 400 var(--t2)/1.4 var(--font); cursor: pointer;
}
.object__item:hover{ background: var(--surface2); }
.object__item b{ display: block; font-size: var(--t3); font-weight: 600; }
.object__item span{ color: var(--text2); }
.object__item[aria-checked="true"] b::after{
  content: " ✓"; color: var(--accent-main);
}

/* Тема живёт и в профиле; в самой шапке она стоит только там, где есть
   место, — иначе значки вытесняют поиск и объект. */
.topbar__theme{
  display: none; align-items: center; justify-content: center;
  min-width: var(--target-topbar); min-height: var(--target-topbar); padding: 0;
  background: none; border: 1px solid transparent; border-radius: var(--r1);
  color: var(--text2); font-size: var(--t4); cursor: pointer;
}
.topbar__theme:hover{ background: var(--surface2); color: var(--text); }
.topbar__theme:active{ background: var(--surface3); }

/* ── значок в шапке: лупа и колокол ─────────────────────────────────────── */
.topbar__icon{
  position: relative; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--target-topbar); height: var(--target-topbar); padding: 0;
  background: none; border: 1px solid transparent; border-radius: var(--r1);
  color: var(--text2); cursor: pointer;
}
.topbar__icon:hover{ background: var(--surface2); color: var(--text); }
.topbar__icon:active{ background: var(--surface3); }
.topbar__icon[aria-expanded="true"]{
  background: var(--accent-bg); color: var(--accent-main); border-color: var(--accent-main);
}

/* Число непрочитанного. Значение, а не украшение: сколько именно ждёт.
   Обводка цветом поверхности отделяет его от значка в обеих темах.        */
.topbar__count{
  position: absolute; top: 3px; right: 1px;
  display: none; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 5px;
  background: var(--error); color: var(--text-inv);
  border: 2px solid var(--surface); border-radius: var(--r-round);
  font-size: var(--t0); font-weight: 600; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.topbar__count[data-visible="1"]{ display: inline-flex; }

/* ═══ 4-б. ПОИСК ПО СИСТЕМЕ ═══════════════════════════════════════════════
   Одно поле на всю систему. Ищет по работам, нарядам, заявкам, материалам,
   местам, подрядчикам и документам; находки собраны по видам.
   Ctrl+K или косая черта — открыть с клавиатуры.                           */

.search{ position: relative; flex: 1 1 260px; min-width: 0; max-width: 420px; }

.search__bar{
  display: flex; align-items: center; gap: var(--p2);
  height: var(--target-topbar); padding: 0 var(--p3);
  background: var(--bg);
  border: 1px solid var(--line2); border-radius: var(--r1);
}
.search__bar:hover{ border-color: var(--text3); }
.search__bar:focus-within{
  background: var(--surface); border-color: var(--accent-main); box-shadow: var(--accent-ring);
}
.search__glyph{ flex: 0 0 auto; display: inline-flex; color: var(--text2); }
.search__input{
  flex: 1 1 auto; min-width: 0; height: 100%;
  background: none; border: 0; color: var(--text);
  font: 400 var(--t3)/1.4 var(--font);
}
.search__input:focus{ outline: none; }
.search__input:focus-visible{ outline: none; }
/* Подсказка здесь — единственное объяснение, что это за поле, поэтому
   она читается: --text2, а не --text3.                                  */
.search__input::placeholder{ color: var(--text2); opacity: 1; }
.search__input::-webkit-search-cancel-button{ cursor: pointer; }

.search__cancel{
  display: none; flex: 0 0 auto; align-items: center;
  min-height: var(--target-topbar); padding: 0 var(--p2);
  background: none; border: 0; border-radius: var(--r1);
  color: var(--accent-main); font: 500 var(--t3)/1.2 var(--font); cursor: pointer;
}

.findings{
  display: none;
  position: absolute; left: 0; right: 0; top: calc(100% + var(--p2));
  z-index: 50;
  max-height: min(70vh, 540px); overflow-y: auto; overscroll-behavior: contain;
  padding: var(--p2);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r2); box-shadow: var(--shadow-float);
}
.findings[data-open="1"]{ display: block; }

.findings__group + .findings__group{
  margin-top: var(--p3); padding-top: var(--p3);
  border-top: 1px solid var(--line-inner);
}
.findings__name{
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--p2); padding: 0 var(--p3) var(--p1);
  font-size: var(--t1); font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; color: var(--text2);
}
.findings__count{ letter-spacing: 0; text-transform: none; }

.finding{
  position: relative;
  display: flex; align-items: center; gap: var(--p3);
  min-height: var(--target); padding: var(--p2) var(--p3);
  border-radius: var(--r1);
  color: var(--text); text-decoration: none;
}
.finding:hover{ background: var(--surface2); text-decoration: none; }
/* Выбранное с клавиатуры несут три признака сразу: подложка, полоса слева
   и цвет имени, — цвет среди них не единственный.                         */
.finding[data-chosen="1"]{ background: var(--accent-bg); }
.finding[data-chosen="1"] .finding__name{ color: var(--accent-main); }
.finding[data-chosen="1"]::before{
  content: ""; position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 3px; border-radius: var(--r-round); background: var(--accent-main);
}
.finding__body{ flex: 1 1 auto; min-width: 0; }
.finding__name{
  display: block; font-size: var(--t3); font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.finding__where{
  display: block; margin-top: var(--p1);
  color: var(--text2); font-size: var(--t1); line-height: 1.4;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.finding__value{
  flex: 0 0 auto; max-width: 38%;
  color: var(--text2); font-size: var(--t1); text-align: right;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.findings__empty{
  padding: var(--p5) var(--p3); text-align: center;
  color: var(--text2); font-size: var(--t3);
}

/* ═══ 4-в. УВЕДОМЛЕНИЯ ════════════════════════════════════════════════════
   Те же события, что дают числа в меню: отчёт, акты, заявки, дефекты,
   вопросы, поставки, приёмка. Ничего сверх того, что система знает.        */

.feed-place{ position: relative; flex: 0 0 auto; }

.feed{
  display: none;
  position: absolute; right: 0; top: calc(100% + var(--p2));
  z-index: 50; width: min(400px, 92vw);
  max-height: min(72vh, 560px); overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r2); box-shadow: var(--shadow-float);
}
.feed[data-open="1"]{ display: block; }

.feed__top{
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--p3); padding: var(--p3) var(--p-card);
  background: var(--surface); border-bottom: 1px solid var(--line);
}
.feed__name{ font-size: var(--t3); font-weight: 600; }
.feed__count{ color: var(--text2); font-size: var(--t1); }

.feed-item{
  position: relative; display: flex;
  padding: var(--p3) var(--p-card) var(--p3) var(--p6);
  border-top: 1px solid var(--line-inner);
  color: var(--text); text-decoration: none;
}
.feed-item:first-child{ border-top: 0; }
.feed-item:hover{ background: var(--surface2); text-decoration: none; }
/* непрочитанное: точка слева, а не цвет строки */
.feed-item[data-new="1"]::before{
  content: ""; position: absolute; left: var(--p3); top: 20px;
  width: 7px; height: 7px; border-radius: 50%; background: var(--accent-main);
}
.feed-item__body{ flex: 1 1 auto; min-width: 0; }
.feed-item__kind{
  display: block; font-size: var(--t0); font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; color: var(--text2);
}
.feed-item__what{
  display: block; margin-top: var(--p1);
  font-size: var(--t3); font-weight: 500; line-height: 1.4;
}
.feed-item__where{
  display: block; margin-top: var(--p1);
  color: var(--text2); font-size: var(--t1); line-height: 1.4;
}
.feed-item__bottom{
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--p2); margin-top: var(--p2);
}
.feed-item__when{ color: var(--text2); font-size: var(--t1); }

/* ═══ 4-г. ПРОФИЛЬ И РОЛЬ ═════════════════════════════════════════════════
   Роль переключается здесь. Прежде выбор роли занимал весь стартовый экран
   и портал читался как выбор профиля в кинотеатре.                        */

.profile{ position: relative; flex: 0 0 auto; }

.profile__glyph{
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--target-topbar); height: var(--target-topbar); padding: 0;
  background: none; border: 0; border-radius: var(--r-round);
  color: inherit; cursor: pointer;
}
.profile__glyph:hover{ background: var(--surface2); }
.profile__glyph[aria-expanded="true"]{ background: var(--surface3); }
.profile__initials{
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--accent-bg); color: var(--accent-main);
  border: 1px solid var(--accent-main);
  font: 600 var(--t2)/1 var(--font); letter-spacing: .02em;
}

.profile__menu{
  display: none;
  position: absolute; right: 0; top: calc(100% + var(--p2));
  z-index: 50; width: min(340px, 92vw);
  max-height: min(78vh, 640px); overflow-y: auto; overscroll-behavior: contain;
  padding: var(--p3);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r2); box-shadow: var(--shadow-float);
}
.profile__menu[data-open="1"]{ display: block; }

.profile__who{
  display: flex; align-items: center; gap: var(--p3);
  padding: var(--p2) var(--p3) var(--p4);
}
.profile__glyph--quiet{
  width: 44px; height: 44px; flex: 0 0 auto; pointer-events: none;
}
.profile__body{ flex: 1 1 auto; min-width: 0; }
.profile__name{ display: block; font-size: var(--t3); font-weight: 600; }
.profile__position{ display: block; margin-top: var(--p1);
                color: var(--text2); font-size: var(--t2); }
.profile__object{ display: block; margin-top: var(--p1);
                color: var(--text2); font-size: var(--t1); }

.profile__group{
  margin: var(--p3) 0 var(--p1); padding: var(--p3) var(--p3) 0;
  border-top: 1px solid var(--line-inner);
  font-size: var(--t0); font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; color: var(--text2);
}

.profile__role{
  position: relative;
  display: flex; align-items: center; gap: var(--p3);
  width: 100%; min-height: var(--target); padding: var(--p2) var(--p3);
  background: none; border: 0; border-radius: var(--r1);
  color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.profile__role:hover{ background: var(--surface2); }
.profile__role:active{ background: var(--surface3); }
/* сейчас смотрим этой ролью: подложка, цвет имени и галочка */
.profile__role[aria-checked="true"]{ background: var(--accent-bg); }
.profile__role[aria-checked="true"] .profile__role-name{ color: var(--accent-main); }
.profile__role[aria-checked="true"]::after{
  content: "✓"; flex: 0 0 auto; color: var(--accent-main);
  font-size: var(--t3); font-weight: 600;
}
.profile__role-initials{
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--surface2); color: var(--text2);
  font-size: var(--t2); font-weight: 600;
}
.profile__role[aria-checked="true"] .profile__role-initials{
  background: var(--surface); color: var(--accent-main);
}
.profile__role-name{ display: block; font-size: var(--t3); font-weight: 500; }
.profile__role-sub{
  display: block; margin-top: var(--p1);
  color: var(--text2); font-size: var(--t1); line-height: 1.4;
}

.profile__item{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--p3); width: 100%;
  min-height: var(--target); padding: var(--p2) var(--p3);
  background: none; border: 0; border-radius: var(--r1);
  color: var(--text); font: 500 var(--t3)/1.2 var(--font);
  text-align: left; text-decoration: none; cursor: pointer;
}
.profile__item:hover{ background: var(--surface2); text-decoration: none; }
.profile__item-glyph{ flex: 0 0 auto; color: var(--text2); font-size: var(--t4); }

/* ── где что видно ─────────────────────────────────────────────────────────
   Поле поиска встаёт в строку, когда для него есть место; иначе остаётся
   лупа, разворачивающая поле на всю шапку.                               */
@media (max-width: 899px){
  .search{ display: none; }
}
@media (min-width: 900px){
  .topbar__search{ display: none; }
}
@media (min-width: 1100px){
  .topbar__theme{ display: inline-flex; }
}
/* имя экрана в шапке — только там, где оно не теснит поиск */
@media (max-width: 1279px){
  .topbar__screen{ display: none; }
}

/* развёрнутый поиск на телефоне: поле занимает шапку целиком */
.topbar[data-registry-search="1"] .search{
  display: block; position: absolute; z-index: 3;
  left: var(--p4); right: var(--p4); top: 50%;
  transform: translateY(-50%); max-width: none;
}
.topbar[data-registry-search="1"] .search__cancel{ display: inline-flex; }
.topbar[data-registry-search="1"] .topbar__menu,
.topbar[data-registry-search="1"] .topbar__screen,
.topbar[data-registry-search="1"] .object,
.topbar[data-registry-search="1"] .topbar__search,
.topbar[data-registry-search="1"] .feed-place,
.topbar[data-registry-search="1"] .topbar__theme,
.topbar[data-registry-search="1"] .profile{ visibility: hidden; }

/* ═══ 4-а. МЕНЮ РАЗДЕЛОВ ══════════════════════════════════════════════════
   Постоянная навигация. За столом — колонка слева, всегда на виду;
   на телефоне та же колонка выезжает по кнопке в шапке.
   Активный пункт помечен и цветом, и полосой слева — не только цветом.     */

.menu{
  position: fixed; left: 0; top: 0; bottom: 0; z-index: 60;
  width: var(--menu-width); max-width: 84vw;
  padding: var(--p4) var(--p3) var(--p8);
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface);
  border-right: 1px solid var(--line);
  transform: translateX(-100%);
  transition: transform .18s ease;
}
.menu[data-open="1"]{ transform: none; box-shadow: var(--shadow-float); }

/* Закрытое меню уезжает за левый край, но остаётся в дереве страницы:
   без этого правила семнадцать его ссылок стоят ПЕРВЫМИ в порядке Tab
   на каждом экране, и человек с клавиатуры семнадцать раз жмёт Tab
   по невидимому. visibility прячет и от Tab, и от чтения с экрана;
   она же выключается мгновенно при открытии и с задержкой при закрытии,
   чтобы уход панели оставался видимым.
   За столом (от 1100 px) колонка стоит всегда — правило туда не идёт. */
@media (max-width: 1099.98px){
  .menu{ visibility: hidden;
          transition: transform .18s ease, visibility 0s linear .18s; }
  .menu[data-open="1"]{ visibility: visible;
          transition: transform .18s ease, visibility 0s linear 0s; }
}

.menu__backdrop{
  position: fixed; inset: 0; z-index: 55;
  background: var(--backdrop);
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease;
}
.menu__backdrop[data-open="1"]{ opacity: 1; pointer-events: auto; }

.menu__top{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--p2); margin-bottom: var(--p5);
}
.menu__brand{
  display: inline-flex; align-items: center; gap: var(--p3);
  min-height: var(--target); padding: 0 var(--p3);
  color: var(--text); font-size: var(--t4); font-weight: 600;
  letter-spacing: 0; text-decoration: none;
}
.menu__brand:hover{ text-decoration: none; color: var(--accent-main); }
.menu__glyph{
  flex: 0 0 auto; width: 20px; height: 20px;
  background: var(--accent-main);
  clip-path: polygon(50% 0, 100% 34%, 50% 100%, 0 34%);
}
.menu__close{
  min-width: var(--target); min-height: var(--target); padding: 0;
  background: none; border: 0; border-radius: var(--r1);
  color: var(--text2); font-size: var(--t4); cursor: pointer;
}
.menu__close:hover{ background: var(--surface2); color: var(--text); }

.menu__role{
  display: block; margin-bottom: var(--p6);
  padding: var(--p3);
  background: var(--surface2); border-radius: var(--r1);
  color: var(--text); text-decoration: none;
}
.menu__role:hover{ background: var(--surface3); text-decoration: none; }
.menu__role-name{ display: block; font-size: var(--t3); font-weight: 600; }
.menu__role-sub{ display: block; margin-top: var(--p1);
                 color: var(--accent-main); font-size: var(--t1); font-weight: 500; }

.menu__section{ margin-bottom: var(--p5); }
.menu__section:last-child{ margin-bottom: 0; }
.menu__group{
  margin: 0 0 var(--p1); padding: 0 var(--p3);
  font-size: var(--t0); font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase; color: var(--text2);
}
.menu__item{
  position: relative;
  display: flex; align-items: center; gap: var(--p3);
  min-height: var(--target);
  padding: var(--p2) var(--p3);
  border-radius: var(--r1);
  color: var(--text); text-decoration: none;
}
.menu__body{ flex: 1 1 auto; min-width: 0; }
.menu__item:hover{ background: var(--surface2); text-decoration: none; }
.menu__item:active{ background: var(--surface3); }
.menu__item[aria-current="page"]{ background: var(--accent-bg); }
.menu__item[aria-current="page"]::before{
  content: ""; position: absolute; left: 0; top: 6px; bottom: 6px;
  width: 3px; border-radius: var(--r-round); background: var(--accent-main);
}
.menu__item[aria-current="page"] .menu__name{ color: var(--accent-main); }
.menu__name{ display: block; font-size: var(--t3); font-weight: 500; }
.menu__todo{ display: block; color: var(--text2); font-size: var(--t1);
              line-height: 1.4; }

/* Счётчик пункта меню. Число, а не значок: «7» говорит больше, чем точка.
   Цвет не единственный носитель — у срочного есть точка перед числом. */
.menu__count{
  flex: 0 0 auto;
  align-self: flex-start; margin-top: 1px;   /* к первой строке, а не к середине */
  display: inline-flex; align-items: center; gap: 4px;
  min-width: 24px; height: 22px; padding: 0 8px;
  background: var(--surface3); color: var(--text2);
  border-radius: var(--r-round);
  font-size: var(--t1); font-weight: 500; font-variant-numeric: tabular-nums;
}
.menu__count[data-error="1"]{ background: var(--error-bg); color: var(--error); }
.menu__count[data-error="1"]::before{
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: currentColor;
}
.menu__item[aria-current="page"] .menu__count[data-error="0"]{
  background: var(--surface); color: var(--accent-main);
}

/* подвал меню: чьё это и на каком объекте — мелко, один раз */
.menu__bottom{
  margin-top: var(--p6); padding: var(--p3);
  border-top: 1px solid var(--line-inner);
  color: var(--text2); font-size: var(--t0); line-height: 1.5;
}

/* за столом колонка стоит всегда, а кнопка и марка в шапке не нужны */
@media (min-width: 1100px){
  body.has-menu{ padding-left: var(--menu-width); }
  .menu{ transform: none; box-shadow: none; }
  .menu__backdrop{ display: none; }
  .menu__close{ display: none; }
  .topbar__burger, .topbar__brand{ display: none; }
  .topbar__menu{ display: none; }
}

/* ═══ 5. КОЛОНКА СТРАНИЦЫ ════════════════════════════════════════════════ */

.page{
  width: 100%;
  max-width: var(--width);
  margin: 0 auto;
  padding: var(--p6) var(--p5) var(--p8);
}
.page--narrow{ max-width: var(--width-narrow); }

/* За столом воздуха больше: заголовок отходит от шапки на 48, а не на 32.
   Заказчик читал прежнюю плотность как «мелко и тесно».                   */
@media (min-width: 900px){
  .page{ padding-top: var(--p7); }
}

/* ── заголовочная зона экрана ───────────────────────────────────────────
   Что человек видит первым: имя экрана, под ним одна строка сути,
   справа главное действие. Дальше — воздух в 32 px и работа.            */
.title{
  margin: 0 0 var(--p1);
  font-size: var(--t6); font-weight: 600;
  line-height: var(--lh-heading); letter-spacing: -.01em;
}
.subtitle{
  margin: 0 0 var(--p6);
  color: var(--text2); font-size: var(--t3); font-weight: 400;
}
.title:last-child{ margin-bottom: var(--p6); }
.title + .grid,
.title + .card,
.title + .list,
.title + .registry-wrap,
.title + .tile{ margin-top: var(--p6); }

/* ═══ 6. КАРТОЧКА И СЕТКА ════════════════════════════════════════════════
   Единый вид на всех экранах: граница 1 px, скругление 10, отступ 20,
   тени нет. Карточка отличается от фона поверхностью, а не тенью.        */

.card{
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  padding: var(--p-card);
  box-shadow: var(--shadow);
}
.card--quiet{ background: var(--surface2); border-color: transparent; }
.card--highlighted{ border-color: var(--accent-main); }
.card + .card{ margin-top: var(--p4); }

.card__header{
  display: flex; align-items: baseline; gap: var(--p3); flex-wrap: wrap;
  margin-bottom: var(--p4);
}
.card__name{ font-size: var(--t3); font-weight: 600; letter-spacing: 0; }
.card__where{ color: var(--text2); font-size: var(--t2); }

.grid{ display: grid; gap: var(--p4); }
.grid--2{ grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid--3{ grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid--4{ grid-template-columns: repeat(4, minmax(0,1fr)); }

@media (max-width: 900px){
  .grid--3, .grid--4{ grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (max-width: 560px){
  .grid--2, .grid--3, .grid--4{ grid-template-columns: minmax(0,1fr); }
}

/* разделитель смысловых частей — воздухом в 32 px, а не линией */
.section{ margin-top: var(--p6); }
.section__name{
  margin: 0 0 var(--p4);
  font-size: var(--t1); font-weight: 500;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--text2);
}
/* подпись группы, вставшая сразу за списком или карточкой, получает тот же
   воздух в 32 px: иначе группы слипаются в одну простыню */
.list + .section__name,
.card + .section__name,
.registry-wrap + .section__name,
.grid + .section__name{ margin-top: var(--p6); }

/* За столом воздух между смысловыми частями — 48, а не 32: на широком
   экране 32 читаются как один сплошной блок.                             */
@media (min-width: 900px){
  .section{ margin-top: var(--p7); }
  .list + .section__name,
  .card + .section__name,
  .registry-wrap + .section__name,
  .grid + .section__name{ margin-top: var(--p7); }
}

/* ═══ 7. КРУПНОЕ ЧИСЛО ═══════════════════════════════════════════════════
   Ставится там, где вопрос звучит «сколько всего?». Не таблица 12×9.       */

.tile{
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  padding: var(--p5);
  box-shadow: var(--shadow);
}
.tile__number{
  display: block;
  font-size: var(--t7); font-weight: 600;
  line-height: 1.1; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.tile--main .tile__number{ font-size: var(--t8); }
.tile__unit{ font-size: 15px; font-weight: 400; color: var(--text2);
             letter-spacing: 0; margin-left: var(--p1); }
.tile__name{
  display: block; margin-top: var(--p2);
  color: var(--text2); font-size: var(--t1); font-weight: 500;
  letter-spacing: .04em; text-transform: uppercase; line-height: 1.4;
}
.tile__bottom{ margin-top: var(--p3); font-size: var(--t2); color: var(--text2);
                line-height: 1.5; }

/* ═══ 8. СПИСОК И СТРОКА ═════════════════════════════════════════════════
   Три состояния строки, больше не нужно:
     .row           — ждёт меня
     .row--done   — сделано, приглушено, галочка
     .row--error     — требует внимания, полоса слева
   Состояние читается видом. Подписи «признак определён» не существует.      */

.list{
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.list--bare{ background: none; border: 0; box-shadow: none; border-radius: 0; }

.row{
  position: relative;
  display: flex; align-items: center; gap: var(--p4);
  min-height: var(--row);
  padding: var(--p3) var(--p-card);
  border-top: 1px solid var(--line-inner);
}
.list > .row:first-child, .row:first-child{ border-top: 0; }

a.row, button.row{
  width: 100%; text-align: left;
  background: none; border-left: 0; border-right: 0; border-bottom: 0;
  color: inherit; font: inherit; cursor: pointer;
}
a.row:hover, button.row:hover{ background: var(--surface2); text-decoration: none; }
a.row:active, button.row:active{ background: var(--surface3); }

/* Текст растёт, но не бесконечно: за 46rem число уезжает от своей строки
   так далеко, что глаз теряет связь между ними. Дальше растёт не текст,
   а пустое поле справа от числа. */
.row__body{ display: block; flex: 1 1 auto; min-width: 0; max-width: 46rem; }
.row__name{
  display: block;
  font-size: var(--t3); font-weight: 500; letter-spacing: 0;
  overflow: hidden; text-overflow: ellipsis;
}
.row__where{ display: block; margin-top: var(--p1);
            color: var(--text2); font-size: var(--t2); line-height: 1.4; }
.row__value{
  flex: 0 0 auto; text-align: right;
  font-size: var(--t4); font-weight: 600; font-variant-numeric: tabular-nums;
}
.row__value small{ display: block; font-size: var(--t1); font-weight: 400;
                    color: var(--text2); }
.row__arrow{ flex: 0 0 auto; color: var(--text2); font-size: var(--t4); }

.row--done{ background: var(--surface2); }
.row--done .row__name{ color: var(--text2); }
.row--done .row__name::after{
  content: " ✓"; color: var(--ok); font-weight: 600;
}

.row--error::before{
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: 3px; background: var(--error);
}

/* ═══ 9. ЧИП СОСТОЯНИЯ ═══════════════════════════════════════════════════
   Фон — 10 % цвета состояния, текст — цвет состояния, 13/500, скругление
   полное. Не яркая плашка. Текст чипа — ЗНАЧЕНИЕ («отстаёт на 12 дней»),
   а не термин. Цвет никогда не единственный носитель: есть значок.         */

.badge{
  display: inline-flex; align-items: center; gap: var(--p1);
  padding: var(--p1) 10px;
  border-radius: var(--r-round);
  background: var(--surface2); color: var(--text2);
  font-size: var(--t1); font-weight: 500; line-height: 1.4;
  white-space: nowrap;
}
.badge::before{ content: "•"; font-size: 1.1em; line-height: 1; }
.badge--ok  { background: var(--ok-bg);   color: var(--ok);   }
.badge--ok::before{ content: "✓"; }
.badge--warn{ background: var(--warn-bg); color: var(--warn); }
.badge--warn::before{ content: "▲"; font-size: .8em; }
.badge--error{ background: var(--error-bg); color: var(--error); }
.badge--error::before{ content: "■"; font-size: .75em; }
.badge--accent { background: var(--accent-bg);  color: var(--accent-main);  }
.badge--accent::before{ content: "•"; }
.badge--quiet{ background: none; color: var(--text2); padding-left: 0; }
.badge--quiet::before{ content: none; }

/* ═══ 10. КНОПКИ ═════════════════════════════════════════════════════════
   Одна главная кнопка на экран. 44 px обычная, 52 px главное действие,
   горизонтальный отступ 16. Вес 500 — не жирнее.                          */

.button{
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--p2);
  min-height: var(--target); padding: 0 var(--p4);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line2); border-radius: var(--r1);
  font: 500 var(--t3)/1.2 var(--font); letter-spacing: 0;
  text-decoration: none; text-align: center;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.button:hover{ background: var(--surface2); text-decoration: none; }
.button:active{ background: var(--surface3); }
/* Отключено: приглушённая поверхность и приглушённый текст. Контраст здесь
   ниже AA сознательно — WCAG выводит неактивные элементы из-под требования,
   а «выключено» обязано читаться как выключено с одного взгляда. */
.button[disabled], .button[aria-disabled="true"]{
  background: var(--surface2); color: var(--text3);
  border-color: var(--line); cursor: default; pointer-events: none;
}
/* Идёт отправка: цвета остаются, меняется только поведение и многоточие. */
.button[aria-busy="true"]{ cursor: progress; pointer-events: none; }
.button[aria-busy="true"]::after{ content: "…"; }

.button--primary{
  min-height: var(--target-primary);
  background: var(--accent-main); color: var(--accent-text); border-color: var(--accent-main);
}
.button--primary:hover{ background: var(--accent-dark); border-color: var(--accent-dark); }
.button--primary:active{ background: var(--accent-dark); }
.button--primary[disabled], .button--primary[aria-disabled="true"]{
  background: var(--surface2); color: var(--text3); border-color: var(--line);
}

.button--quiet{ background: none; border-color: transparent; color: var(--accent-main); }
.button--quiet:hover{ background: var(--accent-bg); }
.button--quiet:active{ background: var(--accent-bg); }

.button--danger{ color: var(--error); border-color: var(--error); background: var(--surface); }
.button--danger:hover{ background: var(--error-bg); }

.button--wide{ width: 100%; }
.button--large{ min-height: var(--target-primary); }

/* нет прав: кнопка видна, но не работает, и сказано почему одним словом */
.button--no-rights{
  background: var(--surface2); color: var(--text2);
  border-color: var(--line); cursor: default; pointer-events: none;
}
.button--no-rights::before{ content: "🔒"; font-size: .9em; }

/* закреплённая полоса с главным действием */
.bottom-bar{
  position: sticky; bottom: 0; z-index: 30;
  margin-top: var(--p6);
  padding: var(--p3) var(--p5) calc(var(--p3) + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 1px solid var(--line);
}
.bottom-bar__inner{
  max-width: var(--width-narrow); margin: 0 auto;
  display: flex; align-items: center; gap: var(--p3);
}
.bottom-bar__total{ flex: 1 1 auto; font-size: var(--t2); color: var(--text2); }

/* ═══ 11. ПОЛЯ ВВОДА ═════════════════════════════════════════════════════ */

.field{ display: block; margin-bottom: var(--p4); }
.field__name{
  display: block; margin-bottom: var(--p2);
  font-size: var(--t2); font-weight: 500; color: var(--text2);
}
.field__input{
  display: block; width: 100%;
  min-height: var(--target); padding: var(--p2) var(--p4);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line2); border-radius: var(--r1);
  font: 400 var(--t3)/1.4 var(--font);
}
.field__input::placeholder{ color: var(--text3); }
.field__input:hover{ border-color: var(--text3); }
.field__input:focus{
  border-color: var(--accent-main); outline: none; box-shadow: var(--accent-ring);
}
.field__input:focus-visible{ outline: none; }
.field__input[disabled]{
  background: var(--surface2); color: var(--text3); border-color: var(--line);
}
.field__input[aria-invalid="true"]{ border-color: var(--error); }
.field__input[aria-invalid="true"]:focus{
  box-shadow: 0 0 0 3px var(--error-bg);
}
/* подпись под полем — только служебная: единица, остаток, вчерашнее число */
.field__hint{ margin-top: var(--p2); font-size: var(--t1); color: var(--text2); }
.field__hint--error{ color: var(--error); font-weight: 500; }

select.field__input{ appearance: none; padding-right: var(--p7);
  background-image: linear-gradient(45deg, transparent 50%, var(--text2) 50%),
                    linear-gradient(135deg, var(--text2) 50%, transparent 50%);
  background-position: calc(100% - 22px) 50%, calc(100% - 16px) 50%;
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat;
}

/* крупный ввод числа с единицей — для объёмов */
.number-input{
  display: flex; align-items: stretch;
  border: 1px solid var(--line2); border-radius: var(--r1);
  background: var(--surface);
  overflow: hidden;
}
.number-input:hover{ border-color: var(--text3); }
.number-input:focus-within{ border-color: var(--accent-main); box-shadow: var(--accent-ring); }
.number-input__input{
  flex: 1 1 auto; width: 100%; min-width: 0;
  min-height: var(--target-primary); padding: var(--p2) var(--p4);
  background: none; border: 0; color: var(--text);
  font: 600 var(--t5)/1.2 var(--font); letter-spacing: -.01em;
  font-variant-numeric: tabular-nums; text-align: right;
}
.number-input__input:focus{ outline: none; }
.number-input__input::-webkit-outer-spin-button,
.number-input__input::-webkit-inner-spin-button{ appearance: none; margin: 0; }
.number-input__input[type=number]{ -moz-appearance: textfield; }
.number-input__unit{
  flex: 0 0 auto; display: flex; align-items: center;
  padding: 0 var(--p4);
  background: var(--surface2); color: var(--text2);
  font-size: var(--t3); font-weight: 500;
  border-left: 1px solid var(--line-inner);
}
.number-input--filled{ border-color: var(--ok); }
.number-input--filled .number-input__unit{ background: var(--ok-bg); color: var(--ok); }

/* быстрый выбор значения — вместо набора цифр */
.quick{ display: flex; flex-wrap: wrap; gap: var(--p2); margin-top: var(--p3); }
.quick__button{
  min-height: var(--target); padding: 0 var(--p4);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line2); border-radius: var(--r-round);
  font: 500 var(--t3)/1.2 var(--font); cursor: pointer;
}
.quick__button:hover{ background: var(--surface2); }
.quick__button:active{ background: var(--surface3); }
/* Выбранное помечается так же, как активный пункт меню: заливка акцентом
   остаётся только у главной кнопки действия. Носителей состояния три —
   фон, граница и цвет текста, — и цвет среди них не единственный.        */
.quick__button[aria-pressed="true"]{
  background: var(--accent-bg); color: var(--accent-main); border-color: var(--accent-main);
  font-weight: 600;
}
.quick__button[disabled]{
  background: var(--surface2); color: var(--text3);
  border-color: var(--line); pointer-events: none;
}

/* переключатель да/нет */
.switch{
  display: inline-flex; align-items: center; gap: var(--p2);
  min-height: var(--target); padding: 0 var(--p4);
  background: var(--surface); border: 1px solid var(--line2); border-radius: var(--r1);
  color: var(--text2); font: 500 var(--t3)/1.2 var(--font); cursor: pointer;
}
.switch:hover{ background: var(--surface2); }
.switch[aria-pressed="true"]{
  background: var(--warn-bg); color: var(--warn); border-color: var(--warn);
}

/* ═══ 12. ПЛОТНАЯ ТАБЛИЦА ════════════════════════════════════════════════
   Вертикальных линий нет. Горизонтальные — только между строками.
   Шапка без заливки: 13/500, вторичный цвет. Числа вправо, табличными.
   Строка 48 px. Прокрутка живёт внутри обёртки — страница не ездит.        */

.registry-wrap{
  overflow-x: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r2);
  box-shadow: var(--shadow);
}

.registry{
  width: 100%; border-collapse: collapse;
  font-size: var(--t3);
  font-variant-numeric: tabular-nums;
}
.registry th, .registry td{
  text-align: left; vertical-align: middle;
  white-space: nowrap;
  border-bottom: 1px solid var(--line-inner);
}
.registry th{
  position: sticky; top: 0; z-index: 1;
  height: 44px; padding: 0 var(--p4);
  background: var(--surface); color: var(--text2);
  font-size: var(--t1); font-weight: 500;
  letter-spacing: .04em; text-transform: uppercase;
  border-bottom: 1px solid var(--line);
}
.registry td{
  height: 48px; padding: var(--p1) var(--p4);
  font-weight: 400;
}
.registry tbody tr:last-child td{ border-bottom: 0; }
.registry tbody tr:hover{ background: var(--surface2); }
.registry td.number, .registry th.number{ text-align: right; }
.registry td:first-child{ font-weight: 500; white-space: normal; }
/* кнопка внутри строки реестра держит 44 px и укладывается в строку 48 */
.registry .button{ padding: 0 var(--p3); font-size: var(--t2); }
/* значение, которого нет: прочерк тише текста, но не пустая клетка */
.registry .missing{ color: var(--text2); }
/* значение, которое читается как проблема: отрицательный остаток, ноль цены */
.registry .bad{ color: var(--error); font-weight: 500; }

/* ═══ 13. ПУСТОЕ СОСТОЯНИЕ ═══════════════════════════════════════════════
   Одна строка и одна кнопка. Пустоту не объясняют — подсказывают шаг.      */

.empty{
  padding: var(--p7) var(--p5);
  text-align: center; color: var(--text2);
}
.empty__word{ font-size: var(--t4); font-weight: 500; color: var(--text); }
.empty__button{ margin-top: var(--p5); }

/* ═══ 14. КОРОТКОЕ ПОДТВЕРЖДЕНИЕ ДЕЙСТВИЯ ════════════════════════════════ */

.toast{
  position: fixed; left: 50%; bottom: var(--p7); z-index: 90;
  transform: translate(-50%, 12px);
  max-width: min(92vw, 520px);
  padding: var(--p3) var(--p5);
  background: var(--text); color: var(--surface);
  border-radius: var(--r2); box-shadow: var(--shadow-float);
  font-size: var(--t3); font-weight: 500;
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
}
.toast[data-visible="1"]{ opacity: 1; transform: translate(-50%, 0); }

/* ═══ 15. ПОДРОБНОСТИ ПО ЗАПРОСУ ═════════════════════════════════════════ */

.more{ margin-top: var(--p5); }
.more > summary{
  display: inline-flex; align-items: center; gap: var(--p2);
  min-height: var(--target); padding: 0 var(--p2) 0 0;
  color: var(--accent-main); font-size: var(--t3); font-weight: 500;
  cursor: pointer; list-style: none;
}
.more > summary::-webkit-details-marker{ display: none; }
.more > summary::before{ content: "▸"; font-size: .9em;
                             transition: transform .15s ease; }
.more[open] > summary::before{ transform: rotate(90deg); }
.more__body{ padding-top: var(--p3); }

/* ═══ 16. СЕМЬ ВЕЛИЧИН ОБЪЁМА — ЗАПЕРТЫЙ КОМПОНЕНТ ═══════════════════════
   Разрешён на двух экранах из тринадцати: приёмка и план-факт затрат.
   Всюду ещё показывают ОДНО число — сколько сделано.
   Вторая половина замка — в obschee.js, Сем.построить().                   */

.levels{ display: none; }

body[data-screen="priemka"]   .levels,
body[data-screen="plan-fakt"] .levels,
body[data-screen="vitrina"]   .levels{ display: block; }

.levels__path{
  display: flex; align-items: stretch; gap: var(--p1);
  overflow: hidden; border-radius: var(--r1);
}
.levels__step{
  flex: 1 1 0; min-width: 0;
  padding: var(--p3);
  background: var(--surface2);
  border-top: 3px solid var(--edge);
}
.levels__step[data-present="1"]{ background: var(--accent-bg); border-top-color: var(--accent-main); }
.levels__step[data-present="0"]{ opacity: .55; }
.levels__name{
  display: block; font-size: var(--t0); color: var(--text2);
  letter-spacing: .02em; line-height: 1.4;
}
.levels__value{
  display: block; margin-top: var(--p1);
  font-size: var(--t4); font-weight: 600; font-variant-numeric: tabular-nums;
}

@media (max-width: 720px){
  .levels__path{ flex-direction: column; }
  .levels__step{ display: flex; justify-content: space-between; align-items: baseline;
              border-top: 0; border-left: 3px solid var(--edge); }
  .levels__step[data-present="1"]{ border-left-color: var(--accent-main); }
}

/* ═══ 16-а. ДАЛЬШЕ ═══════════════════════════════════════════════════════
   Путь вперёд с каждого экрана. Стоит после задачи, отделён воздухом
   и тонкой чертой, набран тише основного: это не задача, это выход.       */

.next{
  margin-top: var(--p7);
  padding-top: var(--p5);
  border-top: 1px solid var(--line);
}
.next .section__name{ margin-bottom: var(--p3); }
.next .list{ background: var(--surface); border: 1px solid var(--line); }
.next .row__name{ font-weight: 500; }
.next .row__where{ font-size: var(--t1); }

/* ═══ 16-б. КТО ВЫ ════════════════════════════════════════════════════════
   Только для входной страницы. Карточка роли — крупная цель: должность,
   человек и одна строка о том, что его ждёт.                              */

.roles{ display: grid; gap: var(--p3); margin-top: var(--p6); }
@media (min-width: 720px){
  .roles{ grid-template-columns: repeat(2, minmax(0,1fr)); }
}

.role{
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--r2);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.role[data-self="1"]{ border-color: var(--accent-main); }

.role__primary{
  display: flex; align-items: center; gap: var(--p4);
  min-height: 88px; padding: var(--p4) var(--p-card);
  color: var(--text); text-align: left; text-decoration: none;
  font: inherit;
}
.role__primary:hover{ background: var(--surface2); text-decoration: none; }

/* остальные экраны этой роли: её дела за день, а не справочник для показа */
.role__screens{
  display: flex; flex-wrap: wrap; gap: var(--p2);
  padding: 0 var(--p-card) var(--p4);
}
.role__screen{
  display: inline-flex; align-items: center;
  min-height: var(--target); padding: 0 var(--p4);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line2); border-radius: var(--r-round);
  font-size: var(--t2); font-weight: 500; text-decoration: none;
}
.role__screen:hover{ background: var(--surface2); color: var(--text);
                   text-decoration: none; }

.role__glyph{
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--accent-bg); color: var(--accent-main);
  font-size: var(--t3); font-weight: 600; letter-spacing: 0;
}
.role__body{ flex: 1 1 auto; min-width: 0; }
.role__position{ display: block; font-size: var(--t4); font-weight: 600;
             letter-spacing: 0; }
.role__person{ display: block; margin-top: var(--p1);
            color: var(--text2); font-size: var(--t2); }
.role__waiting{
  display: block; margin-top: var(--p2);
  font-size: var(--t2); font-weight: 500; color: var(--text2);
}
.role__waiting[data-error="1"]{ color: var(--error); }
.role__waiting[data-error="1"]::before{ content: "■ "; font-size: .75em; }
.role__arrow{ flex: 0 0 auto; color: var(--text2); font-size: var(--t5); }

/* ═══ 17. МОБИЛЬНОЕ ══════════════════════════════════════════════════════ */

@media (max-width: 560px){
  :root{
    --t7: 22px;
    --t8: 28px;
    /* В поле палец в перчатке, солнце на экране и одна рука: цель нажатия
       растёт до 56, главное действие — до 64. Шапка при этом не растёт,
       у неё своя мера --target-topbar.                                       */
    --target:      56px;
    --target-primary: 64px;
    --row:     56px;
  }
  .topbar{ padding: var(--p2) var(--p4); gap: var(--p1); }
  /* на телефоне имя экрана дублирует заголовок под шапкой — убираем */
  .topbar__screen{ display: none; }
  /* и марка тоже: имя системы стоит первой строкой в выдвижном меню,
     а место в шапке телефона нужнее названию объекта — ошибка
     «завёл не в тот объект» дороже, чем не увидеть имя системы  */
  .topbar__brand{ display: none; }
  /* отступы меньше, но квадрат цели остаётся 44×44 — держит min-width выше */
  .topbar__menu{ padding: 0 var(--p2); margin-left: calc(var(--p2) * -1); }
  /* Кнопка объекта отдаёт место значкам, а не выталкивает их за край:
     max-width:100% позволяет ей сжаться внутри своей обёртки, имя
     обрезается многоточием.                                             */
  .object__button{ max-width: 100%; padding: 0 var(--p2); }
  .page{ padding: var(--p5) var(--p4) var(--p8); }
  .card{ padding: var(--p4); }
  .row{ padding: var(--p3) var(--p4); }
  .bottom-bar{ padding-left: var(--p4); padding-right: var(--p4); }
  .object__menu{ min-width: min(88vw, 320px); }
  /* панели шапки на телефоне встают во всю ширину, а не столбиком у края */
  .feed, .profile__menu{
    position: fixed; left: var(--p3); right: var(--p3); width: auto;
    top: calc(64px + var(--p2));
  }
}

/* печать: без шапки и закреплённых полос */
@media print{
  .topbar, .bottom-bar, .toast, .menu, .menu__backdrop{ display: none !important; }
  body.has-menu{ padding-left: 0; }
  .page{ max-width: none; padding: 0; }
  .card, .list, .registry-wrap{ box-shadow: none; }
}

/* ═══ ЗАМОК: действие, которого у роли нет ═════════════════════════════════
   Кнопка видна и объяснена, а не спрятана. Скрытая кнопка учит обходить
   систему — звонком, мессенджером, бумагой; объяснённая учит маршруту.   */
.lock{
  display: inline-flex; align-items: center; gap: var(--p2);
  margin-left: var(--p3);
  color: var(--text2); font-size: var(--t2);
}
.lock__glyph{ font-size: .95em; }

/* Карточка роли стала кнопкой, а была ссылкой: сбрасываем то,
   что браузер даёт кнопке по умолчанию. */
button.menu__role{
  width: 100%; text-align: left;
  font: inherit; border: 0; cursor: pointer;
}
