/* Шрифт бренда — Manrope, тот же, что на claip.ru: панель и сайт должны читаться
   одним продуктом. Файлами, а не base64 в CSS — браузер кэширует их отдельно и не
   перекачивает вместе с каждой правкой стилей. Хостим у себя: внешних запросов на
   публичной панели нет.

   Один переменный файл на весь диапазон 400–800: сайт набран весами 500 (текст),
   600 (кнопки) и 700 (заголовки), и статикой это было бы три закачки вместо одной.

   Чего лишились по сравнению с прежним набором: Onest (текст), Unbounded (дисплей)
   и IBM Plex Mono (подписи) ушли целиком. Моноширинного на сайте нет вообще — от
   него панель читалась консолью, а сайт продуктом; это и было главным расхождением. */
@font-face{font-family:'Manrope';font-style:normal;font-weight:400 800;font-display:swap;src:url(/static/fonts/manrope-400-800-0.woff2) format('woff2');unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116}
@font-face{font-family:'Manrope';font-style:normal;font-weight:400 800;font-display:swap;src:url(/static/fonts/manrope-400-800-1.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}

/* ==================== токены ====================
   Палитра снята с claip.ru пипеткой по живой странице, а не подобрана на глаз:
   фон #fafafa, подложка карточек #f4f5f5, заголовки #181a1b, основной текст
   #494f50, вторичный #61696b, акцент #0997fc.

   СИНИЙ РАЗДВОЕН, и это осознанно. Белый на сайтовом #0997fc даёт 3,07:1 —
   ниже нормы AA (4,5) для кнопочного кегля. Сайту это сходит с рук: там одна
   кнопка на экран воздуха, а тут кнопка — рабочий инструмент, по которому жмут
   весь день. Поэтому светлый --brand остаётся цветом акцента (иконка «вы здесь»,
   кольца, подсветки, полоски), а заливка кнопок и цвет ссылок берут --brand-deep
   #0668b0 (5,81:1). Одно семейство, узнаётся как сайт, но не слепнет.

   Роли остальных цветов прежние: янтарь = внимание, зелёный = готово, красный =
   сбой, steel = ждёт, muted = выключено. Подложка статуса 12% (у янтаря на
   светлом — 16%, иначе слепнет). Внутренний UI команды живёт на янтаре из прода
   (layout.html:9-13) — здесь янтарь отдан только предупреждениям.              */
:root{
  --paper:#fafafa; --surface:#fff; --sunk:#f4f5f5;
  --line:#e3e6e6; --line-hv:#c9cccc;
  /* граница ИНТЕРАКТИВНОГО контрола: 3,0:1 к белому (WCAG 1.4.11). У поля ввода
     фон совпадает с фоном страницы, и рамка — единственный признак, что это поле;
     на --line (1,2:1) поля были почти невидимы. Цена: интерфейс стал «обведённее» */
  --line-ctl:#8f9596;
  /* три ступени текста, как на сайте: заголовок почти чёрный, основной текст
     графитовый, вторичный светлее. Раньше ступеней было две (ink + muted), и
     абзацы шли той же чернотой, что заголовки — оттого панель выглядела жёстче */
  --ink:#181a1b; --body:#494f50; --muted:#61696b;
  --brand:#0997fc; --brand-deep:#0668b0; --brand-hv:#055a97; --on-brand:#fff;
  /* ВНИМАНИЕ — янтарь: зона ускорения на шкале, «в работе», сноски «пока не так» */
  --amber:#f0a02a; --amber-ink:#8a5512;
  --green:#1e7a43; --red:#c93b3b; --steel:#5a6580;
  /* Шрифт один на всё. --disp и --mono оставлены алиасами намеренно: они стоят в
     трёх десятках правил, и вычищать их сейчас значило бы менять типографику и
     разметку одним заходом. Имя `--mono` историческое — моноширинного в панели
     больше нет. */
  --ui:'Manrope',system-ui,-apple-system,sans-serif;
  --disp:var(--ui); --mono:var(--ui);
  /* лестница радиусов под сайт: у него карточка 20, кнопка 14. Прежняя
     (14/12/10/8/5) рядом с сайтом читалась мелко нарезанной */
  --r-obj:20px; --r-box:16px; --r-media:14px; --r-ctl:12px; --r-chip:8px;
  --sidebar:236px;
}

/* ==================== база ==================== */
*{box-sizing:border-box}
/* 16px и вес 500 — как на сайте. Было 15/400: рядом с сайтом панель выглядела
   мельче и жиже. Отрицательный трекинг тоже сайтовый (−0,16px при 16px) */
body{margin:0;background:var(--paper);color:var(--body);
     font:500 16px/1.5 var(--ui);letter-spacing:-.01em;-webkit-font-smoothing:antialiased}
h1,h2,h3{color:var(--ink)}
h1,h2,h3,p,ul{margin:0}
ul{padding:0;list-style:none}
a{color:var(--brand-deep);text-decoration:none}
a:hover{text-decoration:underline}
button{font:inherit;color:inherit;cursor:pointer}
img{display:block;max-width:100%}
/* фокус — на тёмном синем, а не на акцентном: у светлого к белому 3,07:1, и на
   белом поле кольцо еле видно */
:focus-visible{outline:2px solid var(--brand-deep);outline-offset:2px;border-radius:3px}
/* историческое имя: раньше класс включал моноширинный шрифт, теперь это просто
   «подпись» — вторичная строка того же шрифта. 14px, как вторичный текст сайта */
.mono{font:500 14px/1.45 var(--ui);color:var(--muted)}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.ico{width:18px;height:18px;flex:none;stroke:currentColor;fill:none;
     stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.ico.s{width:15px;height:15px}

/* до контента иначе десяток табов через сайдбар и верхнюю полосу */
.skip{position:fixed;left:10px;top:-70px;z-index:80;padding:10px 15px;background:var(--surface);
      border:1px solid var(--line);border-radius:var(--r-ctl);color:var(--ink);
      font:600 14px var(--ui);box-shadow:0 6px 20px rgba(20,25,40,.14);transition:top .15s}
.skip:focus{top:10px;text-decoration:none}

/* ==================== оболочка ==================== */
.shell{display:grid;grid-template-columns:var(--sidebar) 1fr;min-height:100vh}
.shell.narrow{--sidebar:64px}
.canvas{min-width:0;display:flex;flex-direction:column}
.canvas-body{padding:26px 32px 96px}
.wrap{max-width:1120px;margin:0 auto}
.wrap.tight{max-width:820px}

/* ---- верхняя полоса: где я, сколько кредитов, что нового ---- */
.topbar{position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:12px;
        min-height:57px;padding:0 20px 0 24px;background:var(--surface);
        border-bottom:1px solid var(--line)}
.crumbs{display:flex;align-items:center;gap:7px;min-width:0;flex:1;
        font:500 14.5px var(--ui);color:var(--muted);overflow:hidden}
.crumbs a{color:var(--muted);display:inline-flex;align-items:center;gap:6px;
          padding:3px 6px;border-radius:6px;white-space:nowrap}
.crumbs a:hover{color:var(--ink);background:var(--sunk);text-decoration:none}
.crumbs .now{color:var(--ink);font-weight:600;padding:3px 2px;
             white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.crumbs .sep{color:var(--line-hv);flex:none}
.tb-rest{display:flex;align-items:center;gap:10px;flex:none}
.tb-credits{display:flex;align-items:center;gap:9px;font:500 14px var(--ui);color:var(--muted)}
.tb-coins{display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:20px;
          background:var(--sunk);color:var(--ink);font:700 14px var(--ui)}
.tb-coins.low{background:rgba(201,59,59,.1);color:var(--red)}
.tb-div{width:1px;height:24px;background:var(--line);flex:none;margin:0 2px}
.iconbtn{position:relative;display:flex;align-items:center;justify-content:center;
         width:36px;height:36px;border:1px solid var(--line);border-radius:var(--r-ctl);
         background:var(--surface);color:var(--muted)}
.iconbtn:hover{border-color:var(--line-hv);color:var(--ink)}
.iconbtn.on{border-color:var(--line-hv);color:var(--ink);background:var(--sunk)}
.iconbtn .dot{position:absolute;right:7px;top:7px;width:7px;height:7px;border-radius:50%;
              background:var(--red);box-shadow:0 0 0 2px var(--surface)}

/* выпадашки полосы */
.pop{position:absolute;right:0;top:calc(100% + 8px);width:330px;max-width:calc(100vw - 28px);
     background:var(--surface);border:1px solid var(--line);border-radius:var(--r-box);
     box-shadow:0 14px 40px rgba(20,25,40,.16);z-index:40;overflow:hidden}
.pop h4{margin:0;padding:13px 15px 10px;font:600 11px var(--ui);color:var(--muted);
        letter-spacing:.08em;text-transform:uppercase;border-bottom:1px solid var(--line)}
.pop .body{max-height:340px;overflow-y:auto}
.pop .row{display:flex;gap:10px;padding:11px 15px;border-bottom:1px solid var(--line);
          font:500 14px/1.45 var(--ui)}
.pop .row:last-child{border-bottom:0}
.pop .row .ico{margin-top:1px}
.pop .row.ok .ico{color:var(--green)} .pop .row.err .ico{color:var(--red)}
.pop .row .when{display:block;margin-top:3px;font:500 12.5px var(--ui);color:var(--muted)}
.pop .none{padding:26px 15px;text-align:center;color:var(--muted);font-size:14px}
.pop .help{padding:13px 15px;font:500 14px/1.55 var(--ui);color:var(--body)}
.pop .help p{margin:0 0 9px} .pop .help p:last-child{margin:0}
.pop .help b{font-weight:600}
.tb-wrap,.popwrap{position:relative}
/* выпадашка профиля раскрывается ВВЕРХ и влево-в-край: она висит в подвале
   сайдбара, а он прижат к низу окна — вниз ей открываться некуда */
.pop.up{top:auto;bottom:calc(100% + 8px);left:0;right:auto;width:236px}
/* в развёрнутом сайдбаре имя и почта видны в самой кнопке прямо под попапом —
   шапка была бы вторым экземпляром той же строки; нужна она только когда
   сайдбар свёрнут до кружка и больше нигде не сказано, чей это аккаунт */
.pop .who{display:none}
.shell.narrow .pop .who{display:block;padding:12px 14px;border-bottom:1px solid var(--line);min-width:0}
.pop .who b{display:block;font:600 14px var(--ui);color:var(--ink)}
.pop .who small{display:block;margin-top:2px;font:500 12.5px var(--ui);color:var(--muted)}
.pop .who b,.pop .who small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pop .menu{padding:6px}
.pop .menu form{margin:0}
.pop .menu a,.pop .menu button{display:flex;align-items:center;gap:10px;width:100%;
     padding:9px 10px;border:0;border-radius:10px;background:none;color:var(--body);
     font:600 14px var(--ui);text-align:left}
.pop .menu a:hover,.pop .menu button:hover{background:var(--sunk);color:var(--ink);
     text-decoration:none}
.pop .menu .ico{color:var(--muted);flex:none}

/* ---- сайдбар ---- */
.side{position:sticky;top:0;align-self:start;height:100vh;display:flex;flex-direction:column;
      gap:4px;padding:18px 12px;background:var(--surface);border-right:1px solid var(--line)}
.brand{display:flex;align-items:center;gap:10px;padding:4px 8px 20px;color:var(--ink)}
.brand:hover{text-decoration:none;opacity:.82}
/* 24px, а не 20: в viewBox знака кружок выше букв, и буквы занимают ~69% высоты
   картинки против ~94% у прежней K-марки. При 20px вордмарк «Клайп» читался бы
   заметно мельче, чем до смены знака; 24px возвращает буквам прежний размер и
   заодно совпадает с шапкой внутренней панели. */
.brand svg{display:block;height:24px;width:auto;flex:none}
.brand .sub{font:600 10.5px var(--ui);color:var(--muted);letter-spacing:.1em;
            text-transform:uppercase;white-space:nowrap}
.navitem{display:flex;align-items:center;gap:11px;width:100%;padding:9px 11px;border:0;box-sizing:border-box;
         border-radius:var(--r-ctl);background:none;color:var(--muted);
         font:600 15px var(--ui);text-align:left;white-space:nowrap}
.navitem:hover{background:var(--sunk);color:var(--ink);text-decoration:none}
.navitem.on{background:var(--sunk);color:var(--ink)}
.navitem.on .ico{color:var(--brand-deep)}
.side .spacer{flex:1}
.side .foot{border-top:1px solid var(--line);padding-top:12px;margin-top:8px}
.collapse{display:flex;align-items:center;gap:11px;width:100%;padding:8px 11px;border:0;
          border-radius:var(--r-ctl);background:none;color:var(--muted);font:500 13.5px var(--ui)}
.collapse:hover{background:var(--sunk);color:var(--ink)}
/* ---- профиль в подвале сайдбара ----
   Кружок с инициалом + имя и почта. Почта нужна рядом с именем, а не вместо: у
   публичной панели вход по почте, и «под кем я сижу» человек сверяет именно по ней. */
.prof{display:flex;align-items:center;gap:10px;width:100%;min-width:0;padding:7px 9px;
      border:0;border-radius:var(--r-ctl);background:none;text-align:left}
.prof:hover,.prof.on{background:var(--sunk)}
.ava{flex:none;width:30px;height:30px;border-radius:50%;display:flex;align-items:center;
     justify-content:center;font:700 13px var(--ui);color:var(--brand-deep);
     background:color-mix(in srgb,var(--brand) 12%,var(--surface))}
.prof-t{display:flex;flex-direction:column;min-width:0;line-height:1.25}
.prof-t b{font:600 14px var(--ui);color:var(--ink)}
.prof-t small{font:500 12px var(--ui);color:var(--muted)}
.prof-t b,.prof-t small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.shell.narrow .navitem,.shell.narrow .collapse,
.shell.narrow .prof{justify-content:center;padding-left:0;padding-right:0}
.shell.narrow .navitem span,.shell.narrow .collapse span,
.shell.narrow .prof-t,.shell.narrow .brand .sub{display:none}
.shell.narrow .brand{justify-content:center;padding-left:0;padding-right:0}
.shell.narrow .brand svg{height:18px}
.scrim{display:none}

/* ==================== кнопки ==================== */
/* Геометрия кнопки — сайтовая: радиус 14 у крупной, вес 600, воздух по бокам
   заметно больше прежнего (было 9×16 при радиусе 8 — рядом с сайтом это читалось
   как кнопка из другой системы) */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;
     border:1px solid var(--line-ctl);background:var(--surface);color:var(--ink);
     padding:11px 19px;border-radius:var(--r-ctl);font:600 15px var(--ui);
     letter-spacing:-.01em;white-space:nowrap;transition:border-color .15s,background .15s}
.btn:hover{border-color:var(--ink)}
/* заливка — тёмный синий: на светлом #0997fc белая надпись даёт 3,07:1 (см. токены) */
.btn.primary{background:var(--brand-deep);border-color:var(--brand-deep);color:var(--on-brand)}
.btn.primary:hover{border-color:var(--brand-hv);background:var(--brand-hv)}
.btn.ghost{border-color:transparent;background:none;color:var(--muted)}
.btn.ghost:hover{background:var(--sunk);color:var(--ink);border-color:transparent}
.btn.danger{border-color:rgba(201,59,59,.4);color:var(--red);background:var(--surface)}
.btn.danger:hover{border-color:var(--red)}
.btn.small{padding:7px 13px;font-size:13.5px;border-radius:10px}
.btn.big{padding:14px 26px;font-size:16px;border-radius:14px}
/* сумма прямо на кнопке — тем же цветом, но тише: это уточнение, а не второе действие */
.btn-sub{padding-left:9px;margin-left:9px;border-left:1px solid rgba(255,255,255,.3);
         font:500 15px var(--ui);opacity:.85}
.btn:disabled{opacity:.45;cursor:not-allowed}
/* долг прода: .primary:disabled гасил фон, но opacity .45 стакался поверх — здесь снят */
.btn.primary:disabled{background:var(--sunk);border-color:var(--line);color:var(--muted);opacity:1}

/* ==================== поля ==================== */
.field{width:100%;background:var(--surface);border:1px solid var(--line-ctl);color:var(--ink);
       border-radius:var(--r-ctl);padding:11px 14px;font:500 16px/1.5 var(--ui);letter-spacing:-.01em}
.field[readonly]{background:var(--sunk);border-color:var(--line);color:var(--muted)}
.field::placeholder{color:var(--muted)}
.field:focus-visible{outline:none;border-color:var(--brand-deep);box-shadow:0 0 0 3px rgba(9,151,252,.24)}
textarea.field{min-height:88px;resize:vertical}
.lbl{display:block;margin:0 0 6px;font:600 11px var(--ui);color:var(--muted);
     letter-spacing:.07em;text-transform:uppercase}
.seg{display:inline-flex;padding:3px;gap:3px;background:var(--sunk);border-radius:var(--r-ctl)}
.seg button{border:0;background:none;color:var(--muted);padding:7px 15px;
            border-radius:9px;font:600 14px var(--ui)}
.seg button:hover{color:var(--ink)}
.seg button.on{background:var(--surface);color:var(--ink);box-shadow:0 1px 3px rgba(20,25,40,.09)}
.drop{display:flex;flex-direction:column;align-items:center;gap:8px;padding:34px 20px;
      border:1.5px dashed var(--line-hv);border-radius:var(--r-box);background:var(--surface);
      color:var(--muted);text-align:center}

/* ==================== карточки ====================
   Заливкой, а не обводкой — приём сайта: там карточка это #f4f5f5 на #fafafa,
   без рамки и без тени, форму держат радиус 20 и крупный внутренний отступ.
   Обводки остаются только у того, что нажимают и заполняют (кнопки, поля,
   выбираемые плитки) — там рамка не украшение, а признак контрола (1.4.11).
   Потеря: на плотных экранах границы карточек больше не режут пространство,
   и группировку теперь держат только отступы — их нельзя ужимать. */
.card{background:var(--sunk);border:1px solid var(--line);border-radius:var(--r-obj);padding:24px}
/* главное действие продукта — во всю ширину, чтобы его нельзя было не заметить.
   Обводкой, а не заливкой: сплошной индиговый блок такого размера давит на всё
   остальное. Цвет остаётся в рамке, иконке и стрелке — этого хватает. */
.addcta{display:flex;align-items:center;gap:18px;width:100%;padding:21px 25px;
        border:1.5px solid var(--brand);border-radius:var(--r-obj);
        background:var(--surface);color:var(--ink);text-align:left;
        transition:background .15s,border-color .15s,transform .15s}
.addcta:hover{background:color-mix(in srgb,var(--brand) 4%,var(--surface));
              border-color:var(--brand-hv)}
.addcta:active{transform:translateY(1px)}
.addcta .ring{width:46px;height:46px;flex:none;border-radius:50%;display:flex;
              align-items:center;justify-content:center;color:var(--brand-deep);
              background:color-mix(in srgb,var(--brand) 10%,var(--surface))}
.addcta .ring .ico{width:22px;height:22px;stroke-width:2}
.addcta .t{flex:1;min-width:0}
.addcta b{display:block;font:700 21px/1.2 var(--ui);letter-spacing:-.025em;color:var(--ink)}
.addcta small{display:block;margin-top:4px;font:500 14px/1.45 var(--ui);color:var(--muted)}
.addcta .arr{flex:none;color:var(--brand-deep)}

.addbox{position:relative;padding-right:52px}
.cardx{position:absolute;right:12px;top:12px;width:30px;height:30px;border:0;border-radius:7px;
       background:none;color:var(--muted);display:flex;align-items:center;justify-content:center}
.cardx:hover{background:var(--sunk);color:var(--ink)}
.panel{background:var(--sunk);border:1px solid var(--line);border-radius:var(--r-box);padding:20px}
.panel>h3{margin:0 0 12px;font:600 11px var(--ui);color:var(--muted);
          letter-spacing:.08em;text-transform:uppercase}
.emptystate{text-align:center;padding:48px 24px;color:var(--muted);
            border:1px solid var(--line);border-radius:var(--r-obj);background:var(--sunk)}
.emptystate b{display:block;margin-bottom:6px;color:var(--ink);
              font:700 18px var(--ui);letter-spacing:-.02em}

/* ==================== статусы и чипы ==================== */
.st{display:inline-flex;align-items:center;gap:6px;font:600 12px var(--ui);
    padding:3px 9px;border-radius:var(--r-chip)}
.st i{width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
/* резерв под queued/failed-бейджи — палитра ролей держится полной */
.st-wait{color:var(--steel);background:rgba(90,101,128,.12)}
/* янтарь на светлом фоне при 12% слепнет — здесь 16%, остальные роли 12% */
.st-work{color:var(--amber-ink);background:rgba(240,160,42,.16)}
.st-work i{animation:tally 1.1s ease-in-out infinite}
.st-done{color:var(--green);background:rgba(30,122,67,.12)}
.st-fail{color:var(--red);background:rgba(201,59,59,.12)}
.st-off{color:var(--muted)}
@keyframes tally{0%,100%{opacity:1}50%{opacity:.25}}
.tag{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:var(--r-chip);
     background:var(--sunk);color:var(--muted);font:600 12.5px var(--ui)}
.tag.ghost{background:none;border:1px solid var(--line-hv);font-weight:500}
/* «вне контракта» — приём из mockup-webui: пунктир + янтарь, весь смысл в title */
/* кнопка, а не span: пояснение должно открываться тапом и с клавиатуры,
   иначе на телефоне единственное объяснение поведения недостижимо */
.ghostchip{display:inline-block;padding:2px 8px;border:1px dashed var(--amber);
           border-radius:var(--r-chip);background:none;color:var(--amber-ink);
           font:500 11.5px var(--ui);cursor:help;vertical-align:middle}
.warnbox{display:flex;gap:9px;padding:11px 13px;border-radius:var(--r-ctl);
         background:rgba(240,160,42,.1);color:var(--amber-ink);font:500 14.5px/1.45 var(--ui)}
.warnbox.bad{background:rgba(201,59,59,.09);color:var(--red)}
.warnbox .ico{margin-top:2px;color:inherit}
.warnbox b{font-weight:700}

/* ==================== тосты ==================== */
/* снизу справа: сверху перекрывали рельс шагов. pointer-events:none — чтобы тост
   никогда не съедал клик по кнопке, над которой он всплыл */
.toasts{position:fixed;right:20px;bottom:20px;z-index:60;display:flex;flex-direction:column;
        gap:8px;max-width:380px;pointer-events:none}
.toast{background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--brand);
       border-radius:var(--r-ctl);padding:12px 15px;font:500 14.5px/1.45 var(--ui);
       box-shadow:0 8px 26px rgba(20,25,40,.14);animation:tin .2s ease-out}
.toast.ok{border-left-color:var(--green)}
.toast.err{border-left-color:var(--red)}
@keyframes tin{from{opacity:0;transform:translateX(12px)}}

/* ==================== окно подтверждения ==================== */
#modal[hidden]{display:none}
#modal .mask{position:fixed;inset:0;z-index:70;background:rgba(20,25,40,.42);
             animation:fadein .16s ease-out}
/* Центрируем флексом, а НЕ translate(-50%,-50%): иначе анимация появления
   перетирает центрирующий сдвиг, и окно выезжает из нижнего правого угла. */
#modal .dlgwrap{position:fixed;inset:0;z-index:71;display:flex;align-items:center;
                justify-content:center;padding:16px;pointer-events:none}
#modal .dlg{pointer-events:auto;width:400px;max-width:100%;background:var(--surface);
            border:1px solid var(--line);border-radius:var(--r-box);padding:22px;
            box-shadow:0 20px 60px rgba(20,25,40,.28);animation:dlgin .16s ease-out}
@keyframes fadein{from{opacity:0}}
@keyframes dlgin{from{opacity:0;transform:translateY(10px) scale(.98)}}
#modal h3{font:700 20px/1.25 var(--ui);letter-spacing:-.025em}
#modal p{margin-top:9px;color:var(--muted);font-size:15px;line-height:1.55}
#modal .dlg-acts{display:flex;justify-content:flex-end;gap:10px;margin-top:20px}

/* ==================== заголовки страниц ====================
   Плотный набор — главная примета сайта: там h1 идёт трекингом −0,04em при
   интерлиньяже 1,15, а h2 — −0,035em при 1,06. Прежние −0,01em и 1,15/1,3
   рядом с ним выглядели разреженными.                                       */
.head{margin:0 0 24px}
.head h1{font:700 34px/1.12 var(--disp);letter-spacing:-.03em}
.head .sub{margin-top:8px;color:var(--muted);font-size:15.5px}
.sect{display:flex;align-items:baseline;gap:12px;margin:38px 0 16px}
.sect h2{font:700 20px/1.25 var(--ui);letter-spacing:-.025em}
.sect .cnt{font:500 14px var(--ui);color:var(--muted)}
.sect .rest{margin-left:auto}

/* ==================== объекты ==================== */
.objgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(292px,1fr));gap:14px}
.objcard{display:grid;grid-template-columns:84px 1fr;gap:14px;text-align:left;width:100%;color:var(--ink);
         padding:14px;background:var(--surface);border:1px solid var(--line-hv);
         border-radius:var(--r-obj);transition:background .15s,border-color .15s}
/* Белая с рамкой, а не заливкой: карточка объекта — ссылка, а обводка в этом файле
   означает «это нажимают». Заодно чинится главная её беда — серая заливка давала
   к фону 1,05:1, и край карточки пропадал (замечено Романом на живой панели).
   Ховер уводит фон в серый: на белом ходе рамка одна не даёт заметной реакции. */
.objcard:hover{text-decoration:none;background:var(--sunk);border-color:var(--line-ctl)}
.objcard .cov{aspect-ratio:9/16;border-radius:var(--r-media);overflow:hidden;background:#e6e8e8}
.objcard .cov img{width:100%;height:100%;object-fit:cover}
.objcard .nm{font:700 16px/1.25 var(--ui);letter-spacing:-.02em;color:var(--ink)}
.objcard .meta{margin-top:5px;font:500 13.5px var(--ui);color:var(--muted)}
.objcard .price{margin-top:auto;padding-top:8px;font:600 15px var(--ui);color:var(--ink)}
.objcard .bd{display:flex;flex-direction:column;min-width:0}
.objcard .foot{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}

/* ==================== кадры 9:16 ==================== */
.frames{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:10px}
.frame{position:relative;aspect-ratio:9/16;border-radius:var(--r-media);overflow:hidden;
       background:var(--sunk);border:1px solid var(--line);padding:0;
       transition:opacity .15s,filter .15s,box-shadow .15s}
.cell{min-width:0}
.frame-pick{position:absolute;inset:0;width:100%;height:100%;border:0;padding:0;background:none}
.frame img{width:100%;height:100%;object-fit:cover}
.frame:hover{border-color:var(--line-hv)}
.cell[draggable="true"]{cursor:grab}
.cell[draggable="true"]:active{cursor:grabbing}
.frame.fixed{cursor:default}
.frame.fixed:hover{border-color:var(--line)}
/* «выбран» — это НОРМА (отбор по умолчанию весь), а норму не подсвечивают:
   иначе на шаге 2 десять янтарных колец забивают единственную primary.
   Выключенный кадр и так безошибочно читается серым. */
.frame.off{opacity:.42;filter:grayscale(1)}
.frame .ord{position:absolute;left:5px;top:5px;min-width:19px;height:19px;padding:0 6px;
            display:flex;align-items:center;justify-content:center;border-radius:4px;
            background:rgba(20,21,24,.72);color:#fff;font:500 10.5px var(--mono)}
.frame .mark{position:absolute;right:5px;top:5px;width:19px;height:19px;border-radius:50%;
             display:flex;align-items:center;justify-content:center;
             background:rgba(20,21,24,.72);color:#fff}
.frame.off .mark{background:rgba(20,21,24,.55)}
.frame.drag{opacity:.35}
.frame.over{box-shadow:inset 0 0 0 2px var(--brand)}
.strip{display:flex;gap:8px;overflow-x:auto;padding-bottom:4px}
.strip .frame{flex:0 0 84px}
.capline{grid-column:1/-1;display:flex;align-items:center;gap:10px;margin:3px 0;
         color:var(--muted);font:500 12.5px var(--ui)}
.capline::before,.capline::after{content:"";flex:1;height:1px;background:var(--line)}

/* ---- кадры оживают ---- */
.shots{display:grid;grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:9px}
.shot{position:relative;aspect-ratio:9/16;border-radius:var(--r-media);overflow:hidden;
      background:var(--sunk);border:1px solid var(--line)}
.shot img{width:100%;height:100%;object-fit:cover;transition:filter .3s,opacity .3s}
.shot.queued img{filter:grayscale(1);opacity:.45}
.shot.working img{filter:grayscale(.5);opacity:.75}
.shot.failed img{filter:grayscale(1);opacity:.4}
.shot.failed{border-color:var(--red)}
.shot .ord{position:absolute;left:5px;top:5px;min-width:19px;height:19px;padding:0 5px;
           display:flex;align-items:center;justify-content:center;border-radius:4px;
           background:rgba(20,21,24,.72);color:#fff;font:500 10.5px var(--mono)}
.shot .badge{position:absolute;right:5px;top:5px;width:21px;height:21px;border-radius:50%;
             display:flex;align-items:center;justify-content:center;background:var(--surface)}
.shot.done .badge{background:var(--green);color:#fff}
.shot.failed .badge{background:var(--red);color:#fff}
.shot .spin{width:11px;height:11px;border-radius:50%;border:2px solid var(--line);
            border-top-color:var(--brand);animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ==================== ШКАЛА РОЛИКА — сигнатура ====================
   Один объект через весь визард: сегменты = кадры, дорожка = озвучка,
   засечки = субтитры, заливка = сборка. Человек не считает знаки —
   он видит, как озвучка вылезает за плёнку.                                       */
.reel{margin:0}
/* при переборе дорожку поджимаем, чтобы хвосту было куда торчать внутри блока,
   а не за край экрана — иначе метафора «вылезло» ломает вёрстку */
.reel.spill .reel-track{width:80%}
/* Кадры — в своей пропорции 9:16 и подряд. Раньше они растягивались на всю
   ширину полосой в 40 px: от вертикального кадра оставался случайный
   горизонтальный срез, и понять, что войдёт в ролик, было нельзя. */
.reel-strip{display:flex;gap:5px;margin-bottom:11px;overflow-x:auto;padding-bottom:3px}
.reel-mini{position:relative;flex:0 0 42px;aspect-ratio:9/16;border-radius:6px;
           overflow:hidden;background:var(--sunk) center/cover no-repeat;
           border:1px solid var(--line)}
.reel-mini i{position:absolute;left:3px;top:3px;width:14px;height:14px;border-radius:3px;
             background:rgba(20,21,24,.72);color:#fff;font:500 9px/14px var(--mono);
             text-align:center;font-style:normal}
.reel-mini.past{opacity:.42}
.reel-more{flex:0 0 auto;align-self:center;padding-left:4px;font:500 12.5px var(--ui);
           color:var(--muted)}
.reel-track{position:relative;height:10px;margin-top:6px;border-radius:5px;background:var(--sunk)}
.reel-fill{position:absolute;left:0;top:0;bottom:0;border-radius:5px;background:var(--green);
           transition:width .25s ease}
.reel-fill.warn{background:var(--amber)}
.reel-fill.over{background:var(--red)}
.reel-tail{position:absolute;top:0;bottom:0;left:100%;border-radius:0 5px 5px 0;
           background:repeating-linear-gradient(45deg,var(--red) 0 3px,rgba(201,59,59,.35) 3px 7px)}
.reel-cap{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px;margin-top:9px;
          font:500 13.5px var(--ui);color:var(--muted)}
.reel-cap b{color:var(--ink);font-weight:700}
.reel-cap .warn{color:var(--amber-ink)}
.reel-cap .bad{color:var(--red)}

/* ==================== рельс визарда ==================== */
.rail{display:flex;align-items:flex-start;margin:0 0 26px}
.rstep{flex:1 1 0;display:flex;flex-direction:column;align-items:center;gap:7px;
       border:0;background:none;padding:0;min-width:0;position:relative}
.rstep .dot{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;
            justify-content:center;background:var(--surface);border:2px solid var(--line);
            color:var(--muted);font:700 14px var(--ui);position:relative;z-index:1;
            transition:border-color .2s,background .2s,color .2s}
.rstep .cap{font:600 13px var(--ui);color:var(--muted);text-align:center;
            line-height:1.25;max-width:11ch}
.rstep::before,.rstep::after{content:"";position:absolute;top:14px;height:2px;background:var(--line)}
.rstep::before{left:0;right:50%;margin-right:19px}
.rstep::after{left:50%;right:0;margin-left:19px}
.rstep:first-child::before,.rstep:last-child::after{display:none}
.rstep.done .dot{background:var(--green);border-color:var(--green);color:#fff}
.rstep.done::before,.rstep.done::after{background:var(--green)}
/* номер внутри точки — ТЕКСТ: светлый акцент дал бы 3,07:1, берём тёмный */
.rstep.now .dot{border-color:var(--brand-deep);color:var(--brand-deep);
                box-shadow:0 0 0 4px rgba(9,151,252,.18)}
.rstep.now .cap{color:var(--ink);font-weight:700}
/* открытый, но не текущий шаг — обычный вид и курсор;
   закрытый — приглушён, чтобы «дальше нельзя» читалось до клика */
.rstep.can{cursor:pointer}
.rstep.can:hover .dot{border-color:var(--line-hv)}
.rstep.can:hover .cap{color:var(--ink)}
.rstep.locked{cursor:not-allowed}
.rstep.locked .dot{opacity:.5}
.rstep.locked .cap{opacity:.6}
.railmini{display:none;margin:0 0 20px}
.miniprog{height:6px;border-radius:3px;background:var(--sunk);overflow:hidden}
.miniprog i{display:block;height:100%;border-radius:3px;background:var(--green)}

/* ==================== тело шага ==================== */
.step h2{font:700 24px/1.15 var(--disp);letter-spacing:-.03em}
.step .lead{margin-top:8px;color:var(--muted);font-size:15.5px;max-width:62ch}
.stepno{display:block;margin-bottom:6px;font:700 11.5px var(--ui);color:var(--amber-ink);
        letter-spacing:.14em;text-transform:uppercase}
.blk{margin-top:22px}
.stepfoot{display:flex;align-items:center;flex-wrap:wrap;gap:12px;margin-top:26px;
          padding-top:20px;border-top:1px solid var(--line)}
.stepfoot .rest{margin-left:auto;display:flex;align-items:center;flex-wrap:wrap;gap:12px}
.stepfoot .note{font:500 13.5px var(--ui);color:var(--muted)}

/* ---- шаг 3: текст ---- */
.txtgrid{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.vo{position:relative}
.vo textarea{min-height:132px;font:500 16px/1.6 var(--ui)}
.charcnt{margin-top:7px;font:500 13.5px var(--ui);color:var(--muted)}
.charcnt.warn{color:var(--amber-ink)}
.charcnt.bad{color:var(--red);font-weight:500}

/* ---- шаг 4: голоса ---- */
.voices{display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:11px}
.voicecell{display:flex;align-items:center;gap:11px;padding:13px;background:var(--surface);
           border:1px solid var(--line);border-radius:var(--r-box)}
.voicecell:hover{border-color:var(--line-hv)}
.voicecell.on{border-color:var(--brand);box-shadow:inset 0 0 0 1px var(--brand)}
.voice{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:2px;min-height:34px;
       border:0;background:none;padding:0;text-align:left}
.voice .nm{font:600 15px var(--ui);color:var(--ink)}
.voice .who{font:500 13px var(--ui);color:var(--muted)}
.vok{flex:none;color:var(--green);display:flex}
.play{width:32px;height:32px;flex:none;border-radius:50%;border:1px solid var(--line);
      background:var(--sunk);color:var(--ink);display:flex;align-items:center;justify-content:center}
.play:hover{border-color:var(--line-hv)}
.play.on{background:var(--brand);border-color:var(--brand);color:var(--on-brand)}
.voicecell.playing{border-color:var(--brand)}
.wave{display:flex;align-items:flex-end;gap:2px;height:22px;flex:0 0 74px;overflow:hidden}
.wave span{flex:1 1 0;min-width:0;height:30%;background:var(--brand);border-radius:1px;
           transition:height .09s linear}

/* ---- шаг 5: субтитры ---- */
.subs{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px}
.subopt{padding:9px;background:var(--surface);border:1px solid var(--line);
        border-radius:var(--r-box);width:100%}
.subopt:hover{border-color:var(--line-hv)}
.subopt.on{border-color:var(--brand);box-shadow:inset 0 0 0 1px var(--brand)}
.subopt .nm{margin-top:9px;font:600 14px var(--ui);color:var(--ink)}
.subprev{position:relative;aspect-ratio:9/16;border-radius:var(--r-media);overflow:hidden;
         background:var(--sunk)}
.subprev img{width:100%;height:100%;object-fit:cover}
.subprev .txt{position:absolute;left:7%;right:7%;bottom:12%;text-align:center;
              font:800 12px/1.3 var(--ui);color:#fff}
.subprev .txt em{font-style:normal;display:inline-block}
.subprev.clean .txt{text-shadow:0 2px 7px rgba(0,0,0,.9),0 0 2px rgba(0,0,0,.8)}
.subprev.boxed .txt em{background:rgba(12,13,15,.86);padding:2px 6px;border-radius:4px;margin:1px 0}
.subprev.boxed-fill .txt{background:rgba(12,13,15,.86);padding:6px 7px;border-radius:6px}
.subprev.karaoke .txt{text-shadow:0 2px 7px rgba(0,0,0,.9)}
.subprev.karaoke .hi{color:var(--amber)}

/* ---- шаг 6: сборка + результат ---- */
.render{display:flex;flex-direction:column;align-items:center;gap:16px;padding:34px 20px;
        background:var(--surface);border:1px solid var(--line);border-radius:var(--r-box)}
.render .pct{font:700 46px var(--disp);letter-spacing:-.035em;color:var(--ink)}
.render .what{font:500 14.5px var(--ui);color:var(--muted)}
.result{display:grid;grid-template-columns:230px 1fr;gap:24px;align-items:start}
.result .poster{position:relative;aspect-ratio:9/16;border-radius:var(--r-box);overflow:hidden;
                background:var(--sunk);border:1px solid var(--line)}
.result .poster img{width:100%;height:100%;object-fit:cover}
.playbig{position:absolute;inset:0;margin:auto;width:56px;height:56px;border-radius:50%;
         border:0;background:rgba(255,255,255,.92);color:var(--ink);
         display:flex;align-items:center;justify-content:center;
         box-shadow:0 6px 20px rgba(0,0,0,.28)}
.copyrow{display:flex;align-items:flex-start;gap:10px;padding:11px 0;border-top:1px solid var(--line)}
.copyrow .k{flex:0 0 92px;font:600 11px var(--ui);color:var(--muted);
            letter-spacing:.06em;text-transform:uppercase;padding-top:2px}
.copyrow .v{flex:1;min-width:0;font-size:15px;line-height:1.5}

/* ==================== ролики ==================== */
/* ширина фиксированная, а не 1fr: при auto-fill+1fr две карточки на широком экране
   растягивались до 211×375 и подавляли всё вокруг */
.vidgrid{display:grid;grid-template-columns:repeat(auto-fill,168px);gap:16px;justify-content:start}
.vid .poster{position:relative;aspect-ratio:9/16;border-radius:var(--r-media);overflow:hidden;
             background:var(--sunk);border:1px solid var(--line)}
.vid .poster img{width:100%;height:100%;object-fit:cover}
.vid .ver{position:absolute;left:7px;top:7px;padding:2px 7px;border-radius:4px;
          background:rgba(20,21,24,.74);color:#fff;font:500 10.5px var(--mono)}
.vid .nm{margin-top:9px;font:600 15px/1.3 var(--ui);letter-spacing:-.015em;color:var(--ink)}
.vid .meta{margin-top:5px;font:500 13px var(--ui);color:var(--muted)}
.vid .acts{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}

/* ==================== адаптив ==================== */
/* базовое правило .burger обязано стоять ДО медиазапроса: у них одна
   специфичность, и победит тот, кто ниже — иначе бургер не спрячется */
.burger{display:none;align-items:center;justify-content:center;width:36px;height:36px;flex:none;
        border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--surface)}

@media(max-width:900px){
  .shell{grid-template-columns:1fr}
  .side{position:fixed;left:0;top:0;bottom:0;width:264px;z-index:50;height:100dvh;
        transform:translateX(-100%);transition:transform .2s ease;box-shadow:0 0 40px rgba(20,25,40,.2)}
  .shell.open .side{transform:none}
  .shell.open .scrim{display:block;position:fixed;inset:0;z-index:40;background:rgba(20,25,40,.36)}
  .shell.narrow{--sidebar:0px}
  .shell.narrow .navitem span,.shell.narrow .collapse span,
  .shell.narrow .brand .sub{display:revert}
  .shell.narrow .navitem,.shell.narrow .collapse,.shell.narrow .brand{justify-content:flex-start;padding-left:11px}
  .canvas-body{padding:16px 16px 90px}
  .topbar{padding:0 12px;gap:8px}
  .burger{display:flex}
  /* цепочку целиком не втиснуть — обрезанное «Ст…» хуже, чем её отсутствие:
     оставляем только текущее место, назад ведут бургер и кнопка шага */
  .crumbs a,.crumbs .sep{display:none}
  .crumbs .now{font-size:15px}
  .tb-credits>span,.tb-txt{display:none}   /* остаются монета с числом и «+» */
  .tb-rest{gap:7px}
  .tb-div{display:none}
  .btn.small{padding:6px 9px}
  .rail{display:none}
  .railmini{display:block}
  .result{grid-template-columns:1fr}
  .result .poster{max-width:230px}
  .txtgrid{grid-template-columns:1fr}
  .head h1{font-size:24px}
  .toasts{left:14px;right:14px;bottom:14px;max-width:none}
  /* на телефоне две крупные плитки в ряд: и «Интерьер» влезает целиком,
     и попасть пальцем проще, чем в четыре узких */
  .frames{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
  .shots{grid-template-columns:repeat(auto-fill,minmax(96px,1fr))}
  .subs{grid-template-columns:repeat(auto-fill,minmax(132px,1fr))}
  .vidgrid{grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}
  .stepfoot .rest{width:100%;margin-left:0}
  .stepfoot .rest .btn.big{flex:1}
  .btn.big{white-space:normal;text-align:center}
  .btn-sub{padding-left:0;margin-left:0;border-left:0;display:block;width:100%}
  .addcta{padding:16px 18px;gap:14px}
  .addcta b{font-size:17px}
  .addcta .arr{display:none}
}

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

/* ==================== дополнения боевой панели ====================
   Всё выше — CSS прототипа как есть (минус правила демо-панели: в проде её нет).
   Ниже — то, чего в прототипе быть не могло: он рисовал один экран и прятал
   элементы перерисовкой innerHTML, а здесь страницы серверные и прячутся
   атрибутом hidden.                                                            */

/* .addcta и .objcard объявлены через display — UA-правило [hidden]{display:none}
   у них проигрывает по специфичности, и «свёрнутая» форма оставалась бы видимой */
[hidden]{display:none!important}

/* Список объектов приходит без картинок (list_houses отдаёт HouseData), поэтому
   на месте обложки — значок: пустой серый прямоугольник читается как «не
   загрузилось», а значок честно говорит «превью нет». */
.objcard .cov.none{display:flex;align-items:center;justify-content:center;color:var(--line-hv)}
.objcard .cov.none .ico{width:22px;height:22px}

/* Стрелка на кнопке сворачивания смотрит туда, куда поедет сайдбар. Прототип
   перерисовывал значок из JS; здесь оба лежат в разметке, а показывается тот,
   что подходит текущему состоянию — так стрелка верна ещё до загрузки скрипта. */
.side-ico-narrow{display:none}
.shell.narrow .side-ico-open{display:none}
.shell.narrow .side-ico-narrow{display:block}

/* строка «голос записан» с кнопкой прослушивания (мастер, шаг 4) */
.voicedone{display:flex;align-items:center;gap:12px}
.voicedone .play{flex:none;width:34px;height:34px;border-radius:50%;
                 border:1px solid var(--line);background:var(--surface);cursor:pointer;
                 display:flex;align-items:center;justify-content:center;color:var(--ink)}
.voicedone .play:hover{border-color:var(--line-hv)}

/* причина, по которой кадр не ожил, живёт в подсказке на значке: красная рамка без
   объяснения заставляла гадать, а плашка поверх кадра закрывала саму фотографию.
   Значок фокусируемый — иначе подсказка недоступна с клавиатуры и на тач-экране */
.shot{position:relative}
.shot .badge[title]{cursor:help}
.shot .badge[title]:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* ЗАПРОС В РАБОТЕ. Класс .busy ставился с самого начала, но правил под него не было —
   человек нажимал «попробовать ещё раз», подтверждал и не видел ровно ничего.
   Полоса поверх шага переживает перерисовку (шаг рисуется заново на каждый ответ),
   в отличие от спиннера внутри конкретной кнопки. */
.step{position:relative}
.step.busy{cursor:progress}
.step.busy::before{content:"";position:absolute;left:0;right:0;top:-1px;height:3px;
  border-radius:3px;background:linear-gradient(90deg,transparent,var(--amber),transparent);
  background-size:40% 100%;background-repeat:no-repeat;animation:busybar 1.1s ease-in-out infinite;z-index:2}
/* кнопки гасим, но не через pointer-events на всём шаге: текст должен оставаться
   выделяемым, а ссылки — рабочими */
.step.busy .btn,.step.busy .frame,.step.busy .voicecell,.step.busy .subopt{
  pointer-events:none;opacity:.55}
@keyframes busybar{0%{background-position:-40% 0}100%{background-position:140% 0}}
@media (prefers-reduced-motion:reduce){
  .step.busy::before{animation:none;background:var(--amber);background-size:100% 100%}
}

/* плеер результата: вертикаль 9:16, высота ограничена окном — иначе на ноутбуке
   ролик уезжает под сгиб и кнопки скачивания не видно */
.player{display:block;width:100%;max-width:270px;aspect-ratio:9/16;max-height:60vh;
        background:#000;border-radius:var(--r-media);border:1px solid var(--line)}
.result .player{max-width:300px}
.poster .player{max-width:100%;max-height:none;border:0;border-radius:0}
button.playbig{border:0;cursor:pointer}

/* ==================== заголовок внутри карточки ====================
   Был инлайном `font:700 16px` в двух шаблонах — при смене шкалы такие
   вкрапления молча остаются на старом кегле, поэтому вынесены в класс. */
.cardh{font:700 18px/1.3 var(--ui);letter-spacing:-.02em;color:var(--ink)}

/* ==================== экран кредитов ====================
   ЭТИХ ПРАВИЛ НЕ БЫЛО ВООБЩЕ: credits.html с самого выката ссылался на
   .balance-card/.bignum/.ledger/.lrow/.lkind/.lamount/.lrest/.ldate/.hint/
   .empty, а в CSS не существовало ни одного из них — экран показывал
   некрупный столбик неразмеченного текста вместо баланса и выписки.
   Найдено при сверке панели с сайтом; к самой сверке отношения не имеет.  */
.balance-card{display:flex;flex-wrap:wrap;gap:24px;align-items:center}
.balance-card>div:first-child{flex:0 0 auto;min-width:132px}
/* цифра баланса — по сайтовой шкале крупных чисел (там 34–44px, трекинг −0,03em) */
.bignum{font:700 44px/1 var(--ui);letter-spacing:-.035em;color:var(--ink);margin-top:4px}
.balance-card .hint{flex:1;min-width:240px;font-size:15px;line-height:1.5;color:var(--body)}
.balance-card .hint b{color:var(--ink);font-weight:700}
.warn{color:var(--red)}
.lead{font-size:15.5px;line-height:1.55;color:var(--body)}

/* выписка: строка = что / сколько / остаток / когда. Сетка, а не флекс —
   суммы должны стоять в колонку, иначе взгляд не сравнивает их между собой */
.ledger{padding:6px 24px}
.lrow{display:grid;grid-template-columns:1fr auto 108px 92px;gap:12px;align-items:baseline;
      padding:13px 0;border-bottom:1px solid var(--line)}
.lrow:last-child{border-bottom:0}
.lkind{font:600 15px var(--ui);color:var(--ink);min-width:0}
.lamount{font:700 16px var(--ui);letter-spacing:-.01em;text-align:right;font-variant-numeric:tabular-nums}
.lamount.plus{color:var(--green)}
.lamount.minus{color:var(--ink)}
.lrest,.ldate{text-align:right;white-space:nowrap}
.empty{color:var(--muted);text-align:center;padding:28px}

@media(max-width:640px){
  /* на телефоне четыре колонки не встают: остаток и дата уходят под строку */
  .lrow{grid-template-columns:1fr auto;gap:4px 12px}
  .lrest,.ldate{text-align:left;font-size:13px}
  .lrest{grid-column:1}
  .ldate{grid-column:2;text-align:right}
  .bignum{font-size:38px}
}


/* ==================== чего в CSS не было вовсе ====================
   Мастер рисуется из wizard.js, и часть его разметки никогда не имела правил:
   .objhead/.thumb/.objname/.tags (карточка объекта на шаге 1), .volabel/.voact
   (строка над полем текста — подпись наезжала на кнопку «Переписать»), .segs
   (плёнка кадров в шкале), .coverflag/.paidflag (метки на кадре). Найдено
   сверкой всех классов разметки со всеми селекторами файла.                 */

/* шаг 1: карточка объекта */
.objhead{display:flex;align-items:center;gap:16px}
.objhead .thumb{flex:0 0 54px;aspect-ratio:9/16;border-radius:10px;overflow:hidden;
                background:#e6e8e8}
.objhead .thumb img{width:100%;height:100%;object-fit:cover}
.objname{font:700 19px/1.25 var(--ui);letter-spacing:-.025em;color:var(--ink)}
.tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
/* тег внутри карточки — на белом: у карточки теперь та же заливка, что у тега,
   и на ней он растворялся */
.card .tag,.objcard .tag{background:var(--surface);border:1px solid var(--line)}
.card .tag.ghost,.objcard .tag.ghost{background:none;border-color:var(--line-hv)}

/* шаг 3: подпись и кнопка над полем — в одну строку, а не друг на друге */
.volabel{display:flex;align-items:center;justify-content:space-between;
         flex-wrap:wrap;gap:8px 12px;margin-bottom:8px}
.volabel .lbl{margin:0}
.voact{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.voact .mono{white-space:nowrap}

/* шкала: кадры плёнкой. До заморозки длительность считается по числу кадров,
   и сегменты показывают ровно их — по одному на кадр */
.segs{display:flex;gap:3px;height:10px}
.segs i{flex:1 1 0;min-width:2px;border-radius:3px;background:var(--brand);opacity:.85}

/* метки на кадре: «обложка» у первого, галочка у уже оплаченного */
.coverflag{position:absolute;left:5px;bottom:40px;padding:2px 7px;border-radius:6px;
           background:rgba(20,21,24,.74);color:#fff;font:600 10.5px var(--ui);
           letter-spacing:.02em}
.paidflag{position:absolute;right:5px;top:5px;width:20px;height:20px;border-radius:50%;
          display:flex;align-items:center;justify-content:center;
          background:var(--green);color:#fff}

/* «что на кадре» в мастере — это <select class="kind"> ВНУТРИ кадра, а стили
   контрола лежали под именем .kindsel, которого в разметке нет: селект получал
   правила чипа `.frame .kind` (тёмная плашка, кегль 9px) и обрезался. Чип и
   контрол теперь разведены по тегу. */
.frame span.kind{position:absolute;left:5px;bottom:5px;padding:1px 5px;border-radius:4px;
                 background:rgba(20,21,24,.72);color:#fff;font:600 9.5px var(--ui);
                 letter-spacing:.05em;text-transform:uppercase}
.frame select.kind{position:absolute;left:5px;right:5px;bottom:5px;width:auto;
                   padding:6px 24px 6px 9px;border-radius:9px;border:1px solid var(--line-ctl);
                   background:var(--surface);color:var(--ink);font:600 12px var(--ui);
                   appearance:none;-webkit-appearance:none;cursor:pointer;
                   background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2361696b' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
                   background-repeat:no-repeat;background-position:right 7px center;background-size:13px}
.frame select.kind:hover{border-color:var(--ink)}

/* ==================== экран входа ====================
   Вход и регистрация — единственное, что человек видит ДО панели. Каркас у них
   свой (templates/auth/base.html): без сайдбара, кредитов и хлебных крошек —
   все их ссылки до логина вели бы обратно на /login. От публичной панели взято
   ровно то, что делает их одним продуктом с сайтом: светлый фон, Manrope,
   индиго, геометрия полей и кнопок.

   Карточка здесь БЕЛАЯ с мягкой тенью, а не заливкой --sunk, как остальные
   .card: на пустом экране #f4f5f5 к #fafafa даёт 1,03:1 — форма бы растворилась
   в фоне. Внутри панели этой проблемы нет, там границу держит соседний контент,
   поэтому общий .card трогать не стали. */
.authpage{min-height:100vh;display:flex;flex-direction:column;align-items:center;
          justify-content:center;gap:26px;padding:40px 20px}
.authbrand{display:inline-flex;color:var(--ink)}
.authbrand:hover{opacity:.82;text-decoration:none}
.authbrand .brand-logo{display:block;height:30px;width:auto}
.authcard{width:100%;max-width:392px;padding:28px;background:var(--surface);
          border:1px solid var(--line);border-radius:var(--r-obj);
          box-shadow:0 10px 34px rgba(20,25,40,.07)}
/* отступ снизу держит ЗАГОЛОВОК, а подзаголовок подтягивается к нему обратным
   margin: на входе подзаголовка нет вовсе, и правило `h1{margin-bottom:6px}` посадило
   бы «Вход» вплотную к первому полю */
.authcard h1{margin:0 0 20px;font:700 24px/1.25 var(--ui);letter-spacing:-.02em}
.authcard .lede{margin:-14px 0 20px;font:500 14.5px/1.45 var(--ui);color:var(--muted)}
.authcard .warnbox{margin:0 0 18px}
/* колонкой с равным шагом: у формы входа нет ни одной пары полей, которую стоило
   бы посадить в строку, а разнобой отступов на трёх полях сразу читается */
.authform{display:flex;flex-direction:column;gap:14px}
.authform .btn{width:100%;margin-top:4px}
.authfoot{margin:0;text-align:center;font:500 14px var(--ui);color:var(--muted)}

/* телефон: карточка во всю ширину, воздух сверху меньше — иначе форма уезжает
   под клавиатуру, и до кнопки «Войти» приходится скроллить */
@media (max-width:520px){
  .authpage{justify-content:flex-start;padding:32px 16px;gap:20px}
  .authcard{padding:22px 18px}
}
