/* ПС-Фундаменты v2 — оформление по прототипу.
   Радиусы 2–3px, теней нет, разделение только линиями. */

:root{
  --paper:#F2F4F3; --surface:#FFFFFF; --surface2:#E9EDEB; --surface3:#DFE5E3;
  --ink:#191D1C; --ink2:#4A5453; --ink3:#67716D;
  --line:#D3DAD7; --line2:#B3BDB9;
  --accent:#0D5C63; --accentSoft:#DBEAEA; --accentInk:#083C41;
  /* Текст поверх акцентной заливки. В тёмной теме акцент светлый,
     и белым по нему не прочитать. */
  --onAccent:#FFFFFF;
  --water:#2E7FB8; --ok:#2E7D4F; --warn:#9C6414; --crit:#A33A2C;
  --warnSoft:#F6EBDA; --critSoft:#F6E2DE; --okSoft:#E2EFE7;
  --f-disp:"PT Sans Narrow",Arial Narrow,sans-serif;
  --f-ui:"IBM Plex Sans",-apple-system,Segoe UI,Roboto,sans-serif;
  --f-mono:"IBM Plex Mono",Consolas,monospace;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --paper:#111615; --surface:#1A2120; --surface2:#232B29; --surface3:#2B3432;
    --ink:#E7EDEB; --ink2:#A8B3B0; --ink3:#7B8682;
    --line:#2E3836; --line2:#44514E;
    --accent:#4FB3B8; --accentSoft:#16302F; --accentInk:#C3E8E9;
    --onAccent:#0B1413;
    --water:#5BA8DA; --ok:#5CB27C; --warn:#D69B4A; --crit:#D07364;
    --warnSoft:#33291A; --critSoft:#331F1C; --okSoft:#1B2E22;
  }
}
:root[data-theme="dark"]{
  --paper:#111615; --surface:#1A2120; --surface2:#232B29; --surface3:#2B3432;
  --ink:#E7EDEB; --ink2:#A8B3B0; --ink3:#7B8682;
  --line:#2E3836; --line2:#44514E;
  --accent:#4FB3B8; --accentSoft:#16302F; --accentInk:#C3E8E9;
  --onAccent:#0B1413;
  --water:#5BA8DA; --ok:#5CB27C; --warn:#D69B4A; --crit:#D07364;
  --warnSoft:#33291A; --critSoft:#331F1C; --okSoft:#1B2E22;
}

*{box-sizing:border-box}
body{margin:0;background:var(--paper);color:var(--ink);
  font:400 14.5px/1.55 var(--f-ui);-webkit-font-smoothing:antialiased}
a{color:var(--accent)}
h1{font:700 28px/1.15 var(--f-disp);margin:0 0 6px}
h2{font:700 17px/1.2 var(--f-disp);text-transform:uppercase;letter-spacing:.06em;
  margin:0 0 10px}
h3{font:700 15px/1.2 var(--f-disp);text-transform:uppercase;letter-spacing:.06em;
  margin:0}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ── Каркас ── */
.app{display:grid;grid-template-columns:252px 1fr;grid-template-rows:auto 1fr;
  min-height:100vh}
.top{grid-column:1/-1;display:flex;align-items:center;gap:14px;padding:9px 16px;
  background:var(--surface);border-bottom:1px solid var(--line);flex-wrap:wrap}
.brand{font:700 16px/1 var(--f-disp);letter-spacing:.02em;white-space:nowrap;
  color:inherit;text-decoration:none}
.brand:hover{color:var(--accent)}
.newcase{white-space:nowrap}
.brand span{color:var(--accent)}
.topcase{color:var(--ink2);font-size:13.5px}
.topcase b{color:var(--ink)}
.muted{color:var(--ink3)}
.spacer{flex:1}
.chip{font:400 12px/1.1 var(--f-mono);border:1px solid var(--line2);border-radius:2px;
  padding:4px 7px;color:var(--ink2);white-space:nowrap}
.chip.env{border-color:var(--accent);color:var(--accent);background:var(--accentSoft)}
.dot{display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--ok);margin-right:5px;vertical-align:middle}
.dot.off{background:var(--ink3)}

/* ── Рельс шагов ── */
.rail{background:var(--surface);border-right:1px solid var(--line)}
.railinner{padding:14px 0;display:flex;flex-direction:column;min-height:0}
/* Таблица результатов бывает в несколько экранов, и прежде переход
   на соседний шаг требовал долистать страницу до конца. Меню держится
   у верха окна и прокручивается само, если шагов больше, чем помещается. */
@media (min-width:821px){
  .railinner{position:sticky;top:0;max-height:100vh;overflow-y:auto}
}
.railhd{font:700 12px/1.1 var(--f-disp);text-transform:uppercase;letter-spacing:.09em;
  color:var(--ink3);padding:0 14px 10px}
.step{display:grid;grid-template-columns:26px 1fr;gap:8px;align-items:baseline;
  width:100%;text-align:left;background:none;border:0;border-left:3px solid transparent;
  padding:7px 12px;cursor:pointer;color:inherit;font:inherit;text-decoration:none}
.step:hover{background:var(--surface2)}
.step[aria-current="true"]{border-left-color:var(--accent);background:var(--accentSoft)}
.step .n{font:500 12.5px/1 var(--f-mono);color:var(--ink2)}
.step[aria-current="true"] .n{color:var(--accent)}
.step .t{font:600 14px/1.3 var(--f-ui)}
.step .s{display:block;font-size:12px;color:var(--ink2);font-weight:400}
.step .badge{margin-top:3px}
.railfoot{margin-top:auto;padding-top:10px;border-top:1px solid var(--line)}

main{padding:18px 20px 28px;min-width:0}
.lede{color:var(--ink2);max-width:80ch;margin:0 0 16px}

/* ── Панели ── */
.panel{background:var(--surface);border:1px solid var(--line);border-radius:3px;
  margin-bottom:14px}
.panel .hd{padding:9px 12px;border-bottom:1px solid var(--line);
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.panel .bd{padding:12px}
.panel .bd.tight{padding:0}
.hint{font-size:12.5px;color:var(--ink2)}
.legend{padding:10px 12px;border-top:1px solid var(--line);font-size:12.5px;
  color:var(--ink2);line-height:1.5}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.soil{display:grid;grid-template-columns:minmax(0,1fr) 336px;gap:14px}
@media (max-width:1080px){.grid2,.soil{grid-template-columns:1fr}}
/* ── Узкий экран ──
   Рельс шагов — единственный путь между шагами конвейера. Прежде он на
   телефоне просто скрывался, и экран оставался без выхода: перейти с
   «Грунтов» на «Подбор» было нечем. Теперь он убирается в выдвижную
   панель, которую открывает кнопка в шапке. */
.railbtn{display:none}
.scrim{display:none}
@media (max-width:820px){
  .app{grid-template-columns:1fr}
  .railbtn{display:inline-flex}
  .rail{position:fixed;z-index:40;inset:0 auto 0 0;width:min(84vw,282px);
    overflow-y:auto;transform:translateX(-102%);transition:transform .18s ease}
  .app.railopen .rail{transform:none;box-shadow:2px 0 14px rgba(0,0,0,.22)}
  .app.railopen .scrim{display:block;position:fixed;inset:0;z-index:30;
    background:rgba(0,0,0,.38)}
  /* Палец промахивается по строке в 32 px: на узком экране шаги выше. */
  .step{padding:11px 14px}
  .top{gap:9px;padding:8px 12px}
  /* Имя кейса уходит на свою строку: иначе оно вытесняет метки экземпляра
     и агента, по которым видно, в каком из двух порталов идёт работа. */
  .topcase{order:5;flex-basis:100%}
  main{padding:14px 13px 24px}
}
@media (max-width:520px){
  .levelswitch{order:6}
  .brand{font-size:15px}
}

/* ── Таблицы ── */
.tablewrap{overflow-x:auto}
table{border-collapse:collapse;width:100%;font-size:13.5px}
th{font:700 12.5px/1.3 var(--f-disp);text-transform:uppercase;letter-spacing:.04em;
  color:var(--ink2);text-align:left;padding:9px 10px;border-bottom:1px solid var(--line);
  white-space:nowrap}
/* Обозначения величин регистрозависимы: E — модуль деформации, e —
   коэффициент пористости. Приведение к верхнему регистру делает две разные
   колонки неразличимыми. */
th.sym{text-transform:none;font-family:var(--f-mono);font-size:13px;
  letter-spacing:0;color:var(--ink2)}
td{padding:8px 10px;border-bottom:1px solid var(--line);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tr.pick{cursor:pointer}
tr.pick:hover{background:var(--surface2)}
tr.on{background:var(--accentSoft)}
.num{text-align:right;font-family:var(--f-mono);font-variant-numeric:tabular-nums}
.dim{color:var(--ink3)}
.absent{opacity:.68}
dl.kv{display:grid;grid-template-columns:auto 1fr;gap:6px 14px;margin:0}
dl.kv dt{color:var(--ink2);font-size:13px}
dl.kv dd{margin:0;font-size:13.5px}

/* ── Поля ── */
input,select{font:400 13.5px/1.35 var(--f-mono);color:var(--ink);background:var(--surface);
  border:1px solid var(--line2);border-radius:2px;padding:4px 7px;
  font-variant-numeric:tabular-nums}
input:focus,select:focus{border-color:var(--accent);outline:none}
label.f{display:block;font:700 12px/1.1 var(--f-disp);text-transform:uppercase;
  letter-spacing:.06em;color:var(--ink3);margin-bottom:4px}
.field{margin-bottom:9px}
.field input,.field select{width:100%}
.unit{font-size:12px;color:var(--ink2);margin-left:5px;font-weight:400;text-transform:none;letter-spacing:0}
input.cell{width:100%;border-color:transparent;background:transparent;text-align:right;
  font-size:13px;padding:5px 6px}
input.cell:hover{border-color:var(--line)}
input.cell.err{border-color:var(--crit);background:var(--critSoft)}
input.cell.warn{border-color:var(--warn);background:var(--warnSoft)}
input.cell.empty{border:1px dashed var(--crit)}

/* ── Кнопки ── */
.btn{display:inline-block;font:600 13.5px/1.3 var(--f-ui);background:var(--accent);
  color:var(--onAccent);border:1px solid var(--accent);border-radius:2px;
  padding:5px 12px;cursor:pointer;text-decoration:none}
/* Прозрачная кнопка красится акцентом, а не цветом «поверх акцента»:
   иначе в тёмной теме на ней оказывался тёмный текст на тёмном фоне
   и надпись пропадала. */
.btn.ghost{background:transparent;color:var(--accent)}
.btn.sm{padding:4px 9px;font-size:12.5px}
.btn:disabled{opacity:.5;cursor:not-allowed}

/* ── Плашки и сообщения ── */
.badge{display:inline-block;font:500 12px/1.15 var(--f-mono);border:1px solid var(--line2);
  border-radius:2px;padding:3px 6px;color:var(--ink2)}
.badge.ok{border-color:var(--ok);color:var(--ok);background:var(--okSoft)}
.badge.v{border-color:var(--warn);color:var(--warn);background:var(--warnSoft)}
.badge.crit{border-color:var(--crit);color:var(--crit);background:var(--critSoft)}
.note{background:var(--surface2);border-left:3px solid var(--accent);padding:11px 13px;
  margin:12px 0;font-size:13.5px;line-height:1.55;color:var(--ink)}
.note.warn{border-left-color:var(--warn)}
.note.crit{border-left-color:var(--crit)}
.w{display:grid;grid-template-columns:auto 1fr;gap:10px;border-left:3px solid var(--line2);
  padding:9px 11px;margin-bottom:7px;font-size:13px;background:var(--surface2)}
.w.warn{border-left-color:var(--warn);background:var(--warnSoft)}
.w.crit{border-left-color:var(--crit);background:var(--critSoft)}
.w .code{font:500 12px/1.4 var(--f-mono);color:var(--ink2);white-space:nowrap}
.w .addr{color:var(--ink2);font-size:12px}
.vfix{margin-left:6px}
tr.crit td{background:var(--critSoft)}
.swatch{display:inline-block;width:9px;height:9px;border-radius:1px;
  margin-right:5px;vertical-align:middle;border:1px solid rgba(0,0,0,.15)}


/* ── Переключатель представлений плана ── */
.viewswitch{display:flex;gap:0;border:1px solid var(--line2);border-radius:3px;
  overflow:hidden}
.viewbtn{padding:5px 12px;font:600 12.5px/1.3 var(--f-ui);color:var(--ink2);
  text-decoration:none;background:var(--surface);border-right:1px solid var(--line)}
.viewbtn:last-child{border-right:0}
.viewbtn:hover{background:var(--surface2)}
.viewbtn.on{background:var(--accent);color:var(--onAccent)}

/* ── Легенда групп ── */
.chips{display:flex;flex-wrap:wrap;gap:6px 14px}
.chip-legend{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;
  color:var(--ink2)}
.chip-legend i{width:12px;height:12px;border-radius:2px;display:inline-block;
  flex:0 0 auto}
/* Значок легенды повторяет символ на плане: заливка — колонна, кольцо —
   пробуренная выработка, перекрестье — намеченная точка бурения. Одного
   цвета мало: зелёный кружок и красная мишень означают разное. */
.chip-legend i.mark-ring{background:none;border:2.5px solid currentColor;
  border-radius:50%}
.chip-legend i.mark-cross{background:none;border:2px solid currentColor;
  border-radius:50%;position:relative}
.chip-legend i.mark-cross::before,.chip-legend i.mark-cross::after{content:"";
  position:absolute;background:currentColor}
.chip-legend i.mark-cross::before{left:-3px;right:-3px;top:50%;height:1.5px;
  transform:translateY(-50%)}
.chip-legend i.mark-cross::after{top:-3px;bottom:-3px;left:50%;width:1.5px;
  transform:translateX(-50%)}
.chip-legend b{font-family:var(--f-mono);font-size:11.5px;color:var(--ink3);
  font-weight:500}


/* ── Прокрутка и масштаб плана ──
   Площадка на сотню колонн в окно не помещается: сжатая по ширине она
   превращается в кашу, где подписи неразличимы. Поэтому план можно
   увеличить и прокрутить, а не только разглядывать целиком. */
.planzoom{display:flex;align-items:center;gap:6px;padding:0 0 8px;
  font-size:12.5px;color:var(--ink3)}
.planzoom button{font:inherit;font-family:var(--f-ui);min-width:28px;height:26px;
  padding:0 8px;border:1px solid var(--line);background:var(--surface);
  color:var(--ink2);border-radius:6px;cursor:pointer}
.planzoom button:hover{border-color:var(--accent);color:var(--accent)}
.planzoom button.ghost{font-size:12px}
.planzoom-value{font-family:var(--f-mono);font-size:11.5px;min-width:44px;
  text-align:center}
.planzoom .hint{margin-left:auto}
.planview{overflow:auto;max-height:74vh;border:1px solid var(--line);
  border-radius:8px;background:var(--surface)}
.planview.grabbing{cursor:grabbing}
.planinner{width:100%;transition:width .12s ease-out}
.planinner svg{display:block}
@media (max-width:720px){.planzoom .hint{display:none}}

.topcase a{color:inherit;text-decoration:none}
.topcase a:hover b{color:var(--accent)}

/* ── Выбор объекта на плане ── */
.planzoom-check{display:inline-flex;align-items:center;gap:5px;font-size:12.5px;
  color:var(--ink2);cursor:pointer;margin-left:4px}
.planzoom-check input{width:auto;margin:0}
.planinner .pick{cursor:pointer}
.planinner .pick:hover{stroke-width:3}
.planinner .pick.on{stroke:var(--ink);stroke-width:3}
.planpick{margin-top:10px;border:1px solid var(--line);border-radius:8px;
  background:var(--surface2)}
.planpick-head{display:flex;align-items:center;gap:10px;padding:8px 12px;
  border-bottom:1px solid var(--line);font-size:13px}
.planpick-head .spacer{flex:1}
.planpick-link{font-size:12.5px}
.planpick-close{border:0;background:none;color:var(--ink3);cursor:pointer;
  font-size:14px;line-height:1;padding:2px 4px}
.planpick-close:hover{color:var(--accent)}
.planpick-body{padding:8px 12px}
.planpick-body .kv{margin:0}

/* Каркас триангуляции: заливку получает только треугольник выбранной
   колонны — по нему и читается её разрез. */
.planinner .tri.on{fill-opacity:.16;stroke-opacity:1;stroke-width:2;
  stroke-dasharray:none}
.planinner [data-kind="well"].vertex{stroke-width:4}

/* ── Документы проекта ── */
.dochd{display:flex;align-items:center;gap:12px;margin-bottom:14px;font-size:13px}
.dochd .spacer{flex:1}
.doc{max-width:820px;font-size:14px;line-height:1.62;color:var(--ink)}
.doc h2{font-size:20px;margin:26px 0 10px;padding-top:10px;
  border-top:1px solid var(--line)}
.doc h3{font-size:16px;margin:20px 0 8px}
.doc h4,.doc h5,.doc h6{font-size:14px;margin:16px 0 6px;color:var(--ink2)}
.doc p{margin:0 0 11px}
.doc ul{margin:0 0 11px 20px;padding:0}
.doc li{margin:3px 0}
.doc hr{border:0;border-top:1px solid var(--line);margin:22px 0}
.doc code{font-family:var(--f-mono);font-size:12.5px;background:var(--surface3);
  padding:1px 5px;border-radius:4px}
.doc pre{background:var(--surface2);border:1px solid var(--line);border-radius:8px;
  padding:11px 13px;overflow-x:auto;margin:0 0 13px}
.doc pre code{background:none;padding:0;font-size:12.5px;line-height:1.5}
.doc table{font-size:13px}
.doc .tablewrap{margin:0 0 14px}
.doc a{color:var(--accent)}

/* ── Шаг «Грунты»: план и разрез рядом ──
   Разрез — ответ на вопрос «что под этим фундаментом», и смотреть его
   нужно не уходя с плана: инженер тыкает в колонны и сравнивает. */
.soilrow{display:grid;grid-template-columns:340px minmax(0,1fr);gap:14px;
  align-items:start}
.soilrow > .stack{display:flex;flex-direction:column;gap:14px;min-width:0}
#column-detail{transition:opacity .12s}
#column-detail.loading{opacity:.45}
.planinner .pick.chosen{stroke:var(--ink);stroke-width:3.5}
.kv.tight dt,.kv.tight dd{padding:2px 0}
@media (max-width:1080px){.soilrow{grid-template-columns:1fr}}

/* ── Версии документов ── */
.docvers{display:flex;align-items:center;gap:6px;margin:0 0 14px;font-size:12.5px;
  color:var(--ink2);flex-wrap:wrap}
.docver{display:inline-block;min-width:24px;text-align:center;padding:2px 7px;
  border:1px solid var(--line);border-radius:4px;text-decoration:none;
  color:var(--ink2);font-family:var(--f-mono);font-size:12px}
.docver:hover{border-color:var(--accent);color:var(--accent)}
.docver.on{background:var(--accent);color:var(--onAccent);border-color:var(--accent)}
.docdiff-form{display:flex;align-items:center;gap:8px;margin-bottom:14px;
  flex-wrap:wrap;font-size:13px}
.docdiff-form select{width:auto;min-width:210px}
.diff{font-family:var(--f-mono);font-size:12.5px;line-height:1.5;overflow-x:auto}
.diff .dl{padding:1px 12px;white-space:pre-wrap;border-left:3px solid transparent}
.diff .dl.same{color:var(--ink3)}
.diff .dl.add{background:var(--okSoft);border-left-color:var(--ok);color:var(--ink)}
.diff .dl.del{background:var(--critSoft);border-left-color:var(--crit);color:var(--ink)}
.diff .dl.at{color:var(--ink3);background:var(--surface2);margin:6px 0;
  font-size:11.5px}

/* ── График выбора конструкции ── */
.frontchart{border:1px solid var(--line);border-radius:8px;background:var(--surface);
  padding:8px 10px;margin:4px 0 10px}
.frontchart svg{display:block}
.frontchart circle{cursor:default}

/* План одинаков на всех шагах: во всю ширину, со своим отступом снизу. */
.planpanel{margin-bottom:14px}

/* Колонка грида по умолчанию не уже своего содержимого, из-за чего широкая
   таблица распирает её и вылезает за край. min-width:0 возвращает колонке
   заданную ширину, а лишнее уезжает в собственную прокрутку таблицы. */
.grid2 > *,.soil > *,.soilrow > *{min-width:0}

/* ── Уровень подробности ── */
.levelswitch{display:inline-flex;border:1px solid var(--line);border-radius:6px;
  overflow:hidden;margin:0}
.levelbtn{font:500 12px/1 var(--f-ui);padding:5px 10px;border:0;
  background:transparent;color:var(--ink2);cursor:pointer}
.levelbtn:hover{color:var(--accent)}
.levelbtn.on{background:var(--accent);color:var(--onAccent)}

/* ── Правка расстановки выработок ── */
.planinner.editing{cursor:crosshair}
.planinner.editing .pick[data-kind="proposed"]{cursor:grab}
.planinner.editing .pick[data-kind="proposed"]:hover circle{stroke-width:3.5}
.planinner .pick.moving{cursor:grabbing}
.planinner .pick.moving circle{stroke-width:4}
.warnline{color:var(--warn)}

/* ── Документ задания ── */
.survey-doc{max-width:860px}
.survey-doc h2{font-size:17px}
.survey-doc .kv{margin:0 0 12px}
.survey-plan{border:1px solid var(--line);border-radius:8px;padding:8px;
  margin:6px 0 4px;background:var(--surface)}
.survey-sign{display:flex;gap:40px;flex-wrap:wrap;margin-top:34px;
  font-size:13px;color:var(--ink2)}
@media print{
  .rail,.top,.noprint,.legend{display:none!important}
  .app{display:block}
  main{padding:0}
  .survey-doc{max-width:none}
  .panel,.survey-plan{break-inside:avoid}
  body{background:#fff;color:#000}
}

/* ── Вход ── */
.loginpage{display:flex;align-items:center;justify-content:center;min-height:100vh;
  background:var(--paper)}
.loginbox{width:340px;background:var(--surface);border:1px solid var(--line);
  border-radius:10px;padding:26px 24px}
.loginbox .brand{font:700 22px/1 var(--f-disp);letter-spacing:.04em;
  text-transform:uppercase;color:var(--ink);margin-bottom:2px}
.loginbox .brand span{color:var(--accent)}
.loginbox .hint{margin:0 0 16px;font-size:12.5px;color:var(--ink3)}
.loginbox .field{margin-bottom:12px}
.loginbox input[type=text],.loginbox input[type=password]{width:100%}
