/* ══════════════════════════════════════════════════════════════════════
   SHELL — общая оболочка страниц XSL.

   Панель (/hub/panel) держала весь этот словарь у себя в <style>: рама,
   стеклянная карточка, заголовок с фиолетовой меткой, колодец, строка
   «ключ — значение», точка состояния. Хаб и дашборд Kwork писали своё —
   и выглядели как другой сайт. Здесь словарь вынесен один раз.

   Замечания, ради которых это не просто «перекрасить»:
     · СТЕКЛО без backdrop-filter. Замер на панели: 6.3 к/с против 59.1.
       Ощущение стекла держат три оставшиеся составляющие — просвет,
       светлая кромка сверху-слева, парные тени.
     · Заголовок раздела — МЕТКА, а не подчёркивание. Черта под текстом
       разрезает карточку пополам; вертикальная метка слева собирает.
     · Числа — tabular-nums везде, где они меняются в живую. Иначе строка
       дёргается на каждой секунде.
   ══════════════════════════════════════════════════════════════════════ */

/* ── рама ─────────────────────────────────────────────────────────── */
/* position/z-index обязательны: на дашборде фоном лежит <canvas> со
   спорами — position:fixed, z-index:0. Непозиционированный поток
   рисуется НИЖЕ позиционированных элементов, и содержимое ушло бы
   под холст целиком. */
.рама{max-width:1760px;margin:0 auto;padding:0 clamp(10px,2vw,22px) 64px;
      position:relative;z-index:1}

/* ── три колонки: рельс, поле, рельс ──────────────────────────────── */
/* minmax(0,1fr) обязателен: с 1fr центральная колонка берёт min-content
   своего содержимого, а внутри неё лента заказов и волны звука — они
   раздували сетку и выпихивали правый рельс за экран. */
.колонки{display:grid;grid-template-columns:var(--лев,320px) minmax(0,1fr) var(--прав,340px);
         gap:14px;align-items:start}
.колонки>*{min-width:0}
/* Сложенный рельс раскладывается КОЛОНКАМИ ТЕКСТА, а не сеткой.
   На сетке высоту ряда задаёт самая высокая карточка: рядом с воронкой
   в двенадцать строк «Темп» в две держал полтысячи пикселей пустоты, а
   четвёртая карточка уезжала на свой ряд одна. В многоколоночном потоке
   карточки просто перетекают и колонки выравниваются сами. */
/* Перелом на 1180, а не на 1400: при 300+340 на рельсы центру остаётся
   ещё 500 пикселей — заказ и плеер там читаются. Сложить раньше значит
   отдать ноутбучный экран под двухколоночную раскладку без нужды, а на
   хабе рельс из двух карточек оставлял третью колонку пустой. */
@media (max-width:1180px){
  .колонки{grid-template-columns:minmax(0,1fr) var(--прав,340px)}
  .колонки>.рельс-л{grid-column:1/-1;columns:310px 3;column-gap:14px}
  .колонки>.рельс-л>*{break-inside:avoid}
}
@media (max-width:1040px){
  .колонки{grid-template-columns:minmax(0,1fr)}
  .колонки>.рельс-л,.колонки>.рельс-п{grid-column:auto;columns:290px 2;column-gap:14px}
  .колонки>.рельс-л>*,.колонки>.рельс-п>*{break-inside:avoid}
}
/* Одна колонка — многоколоночный поток тут только мешает: он тасует
   порядок чтения. Ниже 700 всё встаёт в столбик как есть. */
@media (max-width:700px){
  .колонки>.рельс-л,.колонки>.рельс-п{columns:auto}
}

/* ── стеклянная карточка ──────────────────────────────────────────── */
/* container-type: от ширины карточки считается cqw — так часы и крупные
   числа меряются своей колонкой, а не вьюпортом. */
.бл{container-type:inline-size;
    position:relative;border-radius:14px;margin-bottom:12px;overflow:hidden;
    /* Плотность снижена 06.09.2026: под блоками теперь живёт сцена, и
       при .74/.86 её не было видно совсем. Размытие обязательно — без
       него текст ложится прямо на звёзды. В Chrome glass.js заменит его
       на настоящее преломление, остальным останется это. */
    background:linear-gradient(168deg,rgba(31,31,40,.60),rgba(15,15,20,.74));
    backdrop-filter:blur(14px) saturate(140%);
    -webkit-backdrop-filter:blur(14px) saturate(140%);
    border:1px solid rgba(202,166,255,.16);
    border-top-color:rgba(202,166,255,.30);
    border-left-color:rgba(202,166,255,.22);
    border-bottom-color:rgba(0,0,0,.34);
    box-shadow:0 16px 40px -26px rgba(0,0,0,.92),
               inset 0 1px 0 rgba(202,166,255,.26),
               inset 0 -1px 0 rgba(0,0,0,.30)}
.бл:last-child{margin-bottom:0}
/* Световой кант по верхней кромке: свет идёт от одного источника слева.
   7 сентября 2026 кант переведён с фиолетового на платину: фиолетовая
   линия читается неоном, платиновая — гранью металла. Фиолетовый остался
   подмешанным в середине, чтобы кант не выпадал из палитры. */
.бл::before{content:"";position:absolute;top:0;left:0;right:0;height:1px;
    background:linear-gradient(90deg,var(--платина-грань),
               rgba(202,166,255,.13) 44%,transparent 76%);
    pointer-events:none;z-index:1}
.бл>h2,.бл>.заг{position:relative;display:flex;align-items:center;gap:9px;
       font:600 10px/1 var(--font-mono);letter-spacing:.18em;text-transform:uppercase;
       color:var(--violet-300);padding:13px 14px 11px}
.бл>h2::before,.бл>.заг::before{content:"";width:3px;height:11px;border-radius:2px;
       background:linear-gradient(180deg,var(--violet-600),var(--violet-700));
       box-shadow:0 0 10px rgba(156,89,255,.8);flex:0 0 auto}
.бл>h2 .n,.бл>.заг .n{margin-left:auto;color:var(--text-muted);letter-spacing:.04em;
       font-variant-numeric:tabular-nums}
.бл>h2 a.n:hover{color:var(--violet-300)}
.нутро{padding:0 14px 14px}

/* Разделитель внутри карточки — когда в одном блоке два смысловых куска. */
.межа{height:1px;background:var(--line);margin:12px -14px}

/* ── строка «ключ — значение» ─────────────────────────────────────── */
.строка{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
        font:12px/1.9 var(--font-mono);color:var(--text-secondary)}
.строка b{color:var(--text-primary);font-weight:500;font-variant-numeric:tabular-nums;
          text-align:right}
.строка+.строка{border-top:1px solid rgba(202,166,255,.055)}

/* ── точка состояния ──────────────────────────────────────────────── */
.точка{display:inline-block;width:7px;height:7px;border-radius:50%;flex:0 0 auto}
.точка.ок{background:var(--ok);box-shadow:0 0 7px rgba(61,220,151,.7)}
.точка.нет{background:var(--bad);box-shadow:0 0 7px rgba(255,68,56,.7)}
.точка.ждёт{background:var(--warn);box-shadow:0 0 7px rgba(255,197,61,.7)}
.точка.нз{background:var(--text-disabled)}

/* ── шкала ────────────────────────────────────────────────────────── */
.шкала{height:4px;border-radius:2px;background:var(--xsl-sunk);
       border:1px solid rgba(202,166,255,.07);overflow:hidden}
.шкала i{display:block;height:100%;border-radius:2px;
         background:linear-gradient(90deg,var(--violet-700),var(--violet-400));
         box-shadow:0 0 8px rgba(156,89,255,.55);
         transition:width .6s var(--ease-out)}

/* ── кнопка ───────────────────────────────────────────────────────── */
/* Вход мягче выхода: приходит плавно (200 мс ease-out), нажатие
   отзывается мгновенно (90 мс). Больше 250 мс на отклик уже читается
   как подтормаживание. */
.кн{font:11px var(--font-mono);letter-spacing:.04em;text-decoration:none;
    padding:9px 13px;border-radius:8px;background:var(--xsl-surface-2);
    border:1px solid var(--line);color:var(--text-primary);cursor:pointer;
    text-align:left;
    transition:background-color .2s var(--ease-out),border-color .2s var(--ease-out),
               color .2s var(--ease-out),scale .09s ease-in}
.кн:hover:not(:disabled){border-color:var(--violet-600);
    background:rgba(104,0,255,.16);color:var(--violet-200)}
.кн:active:not(:disabled){scale:.96}
.кн:disabled{opacity:.45;cursor:wait}
.кн:focus-visible{outline:2px solid var(--violet-400);outline-offset:2px}
.кн.главная{background:rgba(104,0,255,.30);border-color:var(--violet-600);
            color:var(--violet-200)}
.кн[aria-pressed="true"]{background:rgba(104,0,255,.30);
    border-color:var(--violet-600);color:var(--violet-200)}

/* ── поле ввода ───────────────────────────────────────────────────── */
.поле{padding:10px 13px;border-radius:8px;background:rgba(0,0,0,.35);
      border:1px solid var(--line);color:var(--text-primary);
      font:13px var(--font-body);outline:none;min-width:0;
      transition:border-color .2s var(--ease-out)}
.поле:focus{border-color:var(--violet-600)}
.поле::placeholder{color:var(--text-muted)}

/* ── вывод команды ────────────────────────────────────────────────── */
.вывод{margin-top:12px;padding:12px;border-radius:8px;background:rgba(0,0,0,.42);
       border:1px solid var(--line);font:12px/1.6 var(--font-mono);
       color:var(--text-secondary);white-space:pre-wrap;max-height:420px;overflow:auto}

/* ── подпись раздела вне карточки ─────────────────────────────────── */
.полоса{display:flex;align-items:center;gap:12px;margin:22px 0 12px;
        font:600 11px var(--font-mono);letter-spacing:.18em;text-transform:uppercase;
        color:var(--violet-300)}
.полоса::after{content:"";flex:1;height:1px;
        background:linear-gradient(90deg,rgba(104,0,255,.42),transparent)}

/* ── лента крупных чисел ──────────────────────────────────────────── */
/* Карточка оправдана, когда несёт содержимое; под одно число это лишняя
   рама. Лента даёт те же числа крупнее и в одну строку. */
.лента{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
       border:1px solid var(--line);border-radius:12px;overflow:hidden;
       background:linear-gradient(168deg,rgba(31,31,40,.60),rgba(15,15,20,.80))}
.лента>div{padding:17px 18px 15px;border-left:1px solid rgba(202,166,255,.075);
       min-width:0;position:relative}
.лента>div:first-child{border-left:none}
/* Перфорация плёнки в стыках. Не орнамент: она отмечает, что это ряд
   кадров, и берётся из ремесла студии, а не из библиотеки эффектов. */
.лента>div+div::before{content:"";position:absolute;left:-2px;top:14px;bottom:14px;
       width:3px;border-radius:2px;
       background:repeating-linear-gradient(to bottom,
                  rgba(202,166,255,.22) 0 3px, transparent 3px 9px)}
.лента span{display:block;font:10px var(--font-mono);letter-spacing:.18em;
            text-transform:uppercase;color:var(--text-muted);margin-bottom:8px}
/* Числа — главное на экране, поэтому они крупные и в металле:
   тот же материал, что у титра и у короны в логотипе. */
.лента b{display:block;font:400 clamp(1.9rem,3.1vw,2.7rem)/1 var(--font-mono);
         font-variant-numeric:tabular-nums;letter-spacing:0;
         background:linear-gradient(178deg,var(--металл-блик) 0%,
                    var(--металл) 44%,var(--металл-тень) 72%,var(--металл-блик) 100%);
         -webkit-background-clip:text;background-clip:text;color:transparent}
.лента em{display:block;font:10px var(--font-mono);color:var(--text-muted);
          font-style:normal;margin-top:6px;letter-spacing:.04em;
          overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.лента .плох b{color:var(--bad)}
.лента .жд b{color:var(--warn)}


/* ══ ШАПКА САЙТА ═══════════════════════════════════════════════════════
   Одна на все страницы. До 23.08 хаб и дашборд Kwork носили РАЗНЫЕ шапки:
   у одного 62 пикселя и моноширинная навигация, у другого 68, логотип
   вдвое крупнее и кнопки другой формы. Переходя по ссылке, попадаешь как
   будто на другой сайт — и навигации по студии из дашборда не было вовсе.

   Порядок частей важен: марка, навигация, состояние. Когда ссылки стояли
   ПОСЛЕ растягивающегося блока, они переносились на третью строку.       */
.hd{position:sticky;top:0;z-index:1000;display:flex;align-items:center;gap:24px;
    min-height:60px;padding:0 clamp(10px,2vw,22px);
    border-bottom:1px solid var(--line);
    /* backdrop-filter здесь не ставить: замерено — липкая шапка
       пересчитывает размытие фона на КАЖДЫЙ кадр прокрутки. Взамен
       поднята плотность заливки, на глаз разницы нет. */
    background:rgba(11,11,13,.94)}
 /* color/text-decoration обязательны: у дашборда нет своего сброса для
    <a>, и марка студии рисовалась синим подчёркнутым — браузерной
    ссылкой. На хабе тот же код выглядел правильно только потому, что
    сброс лежал в его собственном <style>. */
.hd-brand{display:flex;align-items:center;gap:12px;white-space:nowrap;flex:0 0 auto;
          color:inherit;text-decoration:none}
.hd-brand img{width:29px;height:29px;object-fit:contain}
.hd-brand span{display:flex;flex-direction:column;gap:2px}
.hd-brand b{font:700 14px var(--font-body);letter-spacing:.09em;text-transform:uppercase;
            color:var(--text-primary)}
.hd-brand i{font:normal 9.5px var(--font-mono);letter-spacing:.18em;
            text-transform:uppercase;color:var(--text-muted);font-style:normal}
.hd-nav{display:flex;align-items:center;gap:3px;margin-left:auto}
.hd-nav a{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 12px;
  border-radius:7px;font:11px var(--font-mono);letter-spacing:.09em;
  color:var(--text-secondary);border:1px solid transparent;text-decoration:none;
  transition:color .2s var(--ease-out),border-color .2s var(--ease-out),
             background-color .2s var(--ease-out)}
.hd-nav a:hover{color:var(--text-primary);border-color:var(--line-strong);
                background:rgba(202,166,255,.05)}
.hd-nav a[aria-current]{color:var(--violet-200);border-color:var(--line-strong);
                background:rgba(104,0,255,.18)}
.hd-nav a b{color:var(--bad);font-weight:500}
.живой{width:6px;height:6px;border-radius:50%;background:var(--ok);
       box-shadow:0 0 8px rgba(61,220,151,.7);animation:мигать 1.6s ease-in-out infinite}
@keyframes мигать{0%,100%{opacity:1}50%{opacity:.25}}
@media (prefers-reduced-motion:reduce){.живой{animation:none}}
.hd-right{display:flex;align-items:center;gap:11px;flex:0 0 auto}
.hd-right .штамп{font:11px var(--font-mono);color:var(--text-muted);white-space:nowrap;
                 font-variant-numeric:tabular-nums}
.hd-out{font:11px var(--font-mono);letter-spacing:.09em;color:var(--text-muted);
        text-decoration:none}
.hd-out:hover{color:var(--text-primary)}
.hd .точка{width:8px;height:8px}
.hd .бот{display:inline-flex;align-items:center;gap:7px;font:11px var(--font-mono);
         letter-spacing:.09em;color:var(--text-secondary);white-space:nowrap}
/* Порог поднят с 1320 до 1800 px, 7 сентября 2026. Разделов стало
   четырнадцать: строка меню занимает ~1050 px, и вместе с маркой и
   поиском шапка перестала помещаться уже на 1440 — поле поиска
   наезжало на «Консилиум · Терминал · Kwork». */
@media (max-width:1200px){
  .hd{flex-wrap:wrap;padding-block:10px;gap:11px}
  /* Перенос ссылок съедал на телефоне ПЯТЬ строк — весь первый экран
     уходил под меню, а титр начинался ниже сгиба. Одна строка с
     прокруткой: все тринадцать пунктов на месте, высота фиксирована.
     Края растворяются маской — это и есть подсказка, что строка едет. */
  .hd-nav{margin-left:0;order:3;width:100%;flex-wrap:nowrap;
          overflow-x:auto;overflow-y:hidden;scrollbar-width:none;
          -webkit-overflow-scrolling:touch;
          scroll-snap-type:x proximity;
          mask-image:linear-gradient(90deg,transparent 0,#000 14px,
                     #000 calc(100% - 22px),transparent 100%)}
  .hd-nav::-webkit-scrollbar{display:none}
  .hd-nav a{flex:0 0 auto;scroll-snap-align:start}
  .hd-right{margin-left:auto;flex-wrap:wrap;justify-content:flex-end}
}
/* На телефоне flex:0 0 auto держит правую группу неразрывной, и «Проверить
   сейчас» уезжала за край экрана — кнопку было видно наполовину, а нажать
   нельзя. Здесь она обязана переноситься. */
@media (max-width:700px){
  .hd-right{flex:1 1 100%;justify-content:flex-start;order:2;gap:8px}
  .hd-right .кн{padding:8px 10px}
  .hd-brand{flex:1 1 100%}
}

/* ── липкие рельсы ─────────────────────────────────────────────────────
   Только там, где центральная колонка ДЛИННЕЕ рельсов: на дашборде лента
   заказов уходит на восемь экранов, и обе боковые колонки кончаются на
   первом — дальше по бокам едет пустота. Внутренняя прокрутка здесь не
   лишний скролл, а способ не потерять из виду счёт и разведку.
   На коротких экранах выключено: рельс выше вьюпорта сам себе ловушка. */
@media (min-width:1041px) and (min-height:700px){
  .колонки.липкие>.рельс-л,.колонки.липкие>.рельс-п{
    position:sticky;top:70px;max-height:calc(100vh - 84px);
    overflow-y:auto;overscroll-behavior:contain;padding-right:3px;
    scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent}
}
