/* ==========================================================================
   alamirov · кабинет

   App-only styles. Tokens, buttons, atmosphere and typography come from the
   landing page's stylesheet, mounted at /landing.css — duplicating the token
   block here is how two surfaces of one product start looking like two
   products.
   ========================================================================== */

/* The [hidden] attribute must actually hide things.
   The browser's own `[hidden] { display: none }` has almost no specificity,
   so any rule that sets `display` beats it — and `.btn` sets inline-flex,
   `.whoami` sets flex. The result was the guarantor-only "Очередь" link
   showing to every buyer, and the sign-out button showing on the signed-out
   screen. One line fixes the whole class of bug. */
[hidden] { display: none !important; }

/* Подпись для скринридера, невидимая глазом. Не `display: none` — то, что
   спрятано так, экранный диктор тоже не прочитает, и поле останется без
   названия. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Who you are signed in as. Its own class rather than the landing's .hours,
   which is hidden below 700px — the identity chip has to survive on a phone,
   because "which account am I in" is the question this service must never
   leave ambiguous. */
.whoami {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: .02em;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 46vw;
}

.signout {
  flex: none;
  padding: 10px 17px;
  font-size: 13.5px;
  border-radius: 12px;
}

@media (max-width: 480px) {
  .whoami { font-size: 11.5px; max-width: 40vw; }
  .signout { padding: 9px 13px; font-size: 12.5px; }
}

/* Узкий экран. У гаранта в шапке три вещи — кто вошёл, «Очередь» и
   «Выйти», — и вместе с подписью бренда они не помещались: кнопка выхода
   уезжала за край, страница начинала ездить вбок. Уступает подпись бренда
   (знак остаётся и ведёт туда же), а ник сжимается с многоточием, но не
   выталкивает кнопки. */
.masthead__aside { min-width: 0; }
.masthead__aside .whoami { flex: 0 1 auto; min-width: 0; }
@media (max-width: 560px) {
  .masthead__aside { gap: 8px; }
  .masthead__inner:has(.whoami:not([hidden])) .brand__lockup { display: none; }
}

.app {
  position: relative;
  z-index: 10;
  max-width: var(--shell);
  margin-inline: auto;
  padding: 56px var(--gutter) 120px;
}

.app__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 32px;
}

.app__title {
  margin-top: 14px;
  font-family: var(--font-display);
  font-size: clamp(28px, 3.4vw, 40px);
  font-weight: 700;
  letter-spacing: -.042em;
  line-height: 1.1;
}

.app__lede {
  max-width: 470px;
  margin-top: 16px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-3);
  text-wrap: pretty;
}

.app__hint { margin-top: 22px; font-size: 13.5px; color: var(--ink-4); }

.app__error,
.form__error {
  margin-top: 18px;
  padding: 13px 16px;
  border: 1px solid rgba(255, 122, 122, .4);
  border-radius: 12px;
  background: rgba(255, 122, 122, .1);
  font-size: 14px;
  color: #ffc2c2;
}

.backlink {
  display: inline-block;
  margin-bottom: 22px;
  font-size: 14px;
  color: var(--ink-3);
}
@media (hover: hover) and (pointer: fine) {
  .backlink:hover { color: #fff; }
}

/* Sign in ------------------------------------------------------------------ */

.signin {
  margin-top: 30px;
  padding: 26px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: linear-gradient(180deg, var(--fill-1), var(--fill-2));
}
.signin__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 30px;
}
.authform { display: flex; flex-direction: column; gap: 16px; }
.authform + .authform {
  padding-left: 30px;
  border-left: 1px solid var(--line);
}
.authform__title {
  margin-bottom: 2px;
  font-size: 20px;
  font-weight: 650;
  letter-spacing: -.025em;
}
.authform .btn { align-self: flex-start; margin-top: 2px; }
/* Согласие с документами при регистрации. Явная галочка, а не мелкий
   текст под кнопкой: обработка персональных данных требует согласия,
   которое человек действительно дал. */
.consent {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-3);
  cursor: pointer;
}
.consent a { color: var(--blue-400); text-decoration: underline; text-underline-offset: 3px; }
.consent__box {
  flex: none;
  width: 18px; height: 18px;
  margin: 2px 0 0;
  accent-color: var(--blue-400);
  cursor: pointer;
}

.signin__note {
  margin-top: auto;
  padding-top: 18px;
  max-width: 36ch;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-4);
}

@media (max-width: 720px) {
  .signin__grid { grid-template-columns: minmax(0, 1fr); }
  .authform + .authform {
    padding-top: 28px;
    padding-left: 0;
    border-top: 1px solid var(--line);
    border-left: 0;
  }
}

/* Forms -------------------------------------------------------------------- */

.newdeal {
  margin-bottom: 28px;
  padding: 26px 24px 24px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: linear-gradient(180deg, var(--fill-1), var(--fill-2));
}
.newdeal__row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}
.newdeal__actions { display: flex; gap: 12px; margin-top: 20px; flex-wrap: wrap; }
.newdeal__calc {
  margin-top: 14px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-4);
}
.newdeal__calc:empty { display: none; }

/* Шаблоны условий.
   Кнопки, а не выпадающий список: вариантов четыре, и подпись под каждым
   объясняет выбор лучше, чем название. В свёрнутом select подписи не видно,
   а именно она отвечает на вопрос «а мой случай — это какой из них». */
.tpl { margin-top: 20px; }
.tpl__row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin-top: 10px;
}
.tpl__btn {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 13px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 14px;
  background: rgba(255, 255, 255, .03);
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color var(--t-hover) ease, background var(--t-hover) ease,
              transform var(--t-hover) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .tpl__btn:hover { border-color: rgba(var(--blue-rgb), .45); transform: translateY(-1px); }
}
.tpl__btn:active { transform: scale(.99); }
.tpl__btn:focus-visible {
  outline: none;
  border-color: var(--blue-400);
  box-shadow: 0 0 0 3px rgba(var(--blue-rgb), .22);
}
.tpl__btn--on {
  border-color: var(--blue-400);
  background: rgba(var(--blue-rgb), .13);
}
.tpl__btn-title { font-size: 14px; font-weight: 600; letter-spacing: -.015em; }
.tpl__btn-hint { font-size: 11.5px; line-height: 1.45; color: var(--ink-4); }

.tpl__note {
  margin-top: 10px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-4);
}
.tpl__note:empty { display: none; }

@media (max-width: 720px) {
  .tpl__row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.field { display: block; }
.field__label {
  display: block;
  margin-bottom: 8px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.field__input {
  width: 100%;
  padding: 13px 15px;
  border: 1px solid var(--line-strong);
  border-radius: 13px;
  background: rgba(255, 255, 255, .04);
  font-family: inherit;
  font-size: 15px;
  color: var(--ink-1);
  transition: border-color var(--t-hover) ease, box-shadow var(--t-hover) ease;
}
.field__input::placeholder { color: rgba(237, 240, 246, .3); }
.field__input:focus-visible {
  outline: none;
  border-color: var(--blue-400);
  box-shadow: 0 0 0 3px rgba(var(--blue-rgb), .22);
}
select.field__input { appearance: none; cursor: pointer; }

/* Deal list ---------------------------------------------------------------- */

.deals { display: flex; flex-direction: column; gap: 12px; }

.dealrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 20px;
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(180deg, var(--fill-1), var(--fill-2));
  color: inherit;
  transition: border-color var(--t-hover) ease, transform var(--t-hover) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .dealrow:hover { border-color: rgba(134, 179, 255, .38); transform: translateY(-2px); }
}
.dealrow:active { transform: scale(.995); }

/* Строка списка — указатель на сделку, а не сама сделка.
   С тех пор как условия стали многострочными, сюда попадает весь текст
   шаблона: одна строка выросла до 422px против 166px у остальных, и список
   перестал быть списком. Две строки — достаточно, чтобы узнать сделку. */
.dealrow__subject {
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -.015em;
  overflow-wrap: anywhere;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
  overflow: hidden;
}
.dealrow__meta {
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--ink-4);
}
.dealrow__amount {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -.035em;
  text-align: right;
  white-space: nowrap;
}

.empty {
  padding: 44px 26px;
  border: 1px dashed var(--line-strong);
  border-radius: 20px;
  text-align: center;
  color: var(--ink-4);
  font-size: 14.5px;
}

/* Status pill — the same colour language as the landing's deal card:
   blue agreed/held, gold in transit, green paid, red for the bad endings. */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border: 1px solid rgba(var(--pill-rgb, var(--blue-rgb)), .3);
  border-radius: 999px;
  background: rgba(var(--pill-rgb, var(--blue-rgb)), .12);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--pill-ink, var(--blue-300));
  white-space: nowrap;
}
.pill::before {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: currentColor;
}
[data-status="draft"]     { --pill-rgb: 237, 240, 246; --pill-ink: var(--ink-3); }
[data-status="agreed"]    { --pill-rgb: var(--blue-rgb); --pill-ink: var(--blue-300); }
[data-status="funded"]    { --pill-rgb: var(--blue-rgb); --pill-ink: var(--blue-300); }
[data-status="delivered"] { --pill-rgb: var(--gold-rgb); --pill-ink: var(--gold-200); }
[data-status="confirmed"] { --pill-rgb: var(--gold-rgb); --pill-ink: var(--gold-200); }
[data-status="paid"]      { --pill-rgb: var(--green-rgb); --pill-ink: var(--green-soft); }
[data-status="settled"]   { --pill-rgb: var(--green-rgb); --pill-ink: var(--green-soft); }
[data-status="refunded"]  { --pill-rgb: var(--green-rgb); --pill-ink: var(--green-soft); }
[data-status="dispute"]   { --pill-rgb: 255, 122, 122; --pill-ink: #ff9b9b; }
[data-status="cancelled"] { --pill-rgb: 237, 240, 246; --pill-ink: var(--ink-4); }
[data-status="expired"]   { --pill-rgb: 237, 240, 246; --pill-ink: var(--ink-4); }

/* Deal detail -------------------------------------------------------------- */

/* Объявленное отсутствие гаранта. Намеренно спокойный тон: это не тревога,
   а предупреждение, которое человек сделал заранее. Красным здесь пугать
   нечего — красное в этом интерфейсе означает спор. */
.away {
  margin-bottom: 16px;
  padding: 15px 18px;
  border: 1px solid rgba(var(--gold-rgb), .28);
  border-radius: 16px;
  background: rgba(var(--gold-rgb), .07);
}
.away__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--gold-200);
}
.away__why {
  margin-top: 5px;
  font-size: 13.5px;
  color: var(--ink-2);
}
.away__note {
  margin-top: 8px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-4);
}

.detail {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr);
  gap: 16px;
  align-items: start;
}

.card {
  padding: 28px 26px;
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 22px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .07), rgba(255, 255, 255, .022));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
}

.card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
}
.card__id {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: .06em;
  color: var(--ink-4);
}
.card__amount {
  margin-top: 20px;
  font-family: var(--font-display);
  font-size: clamp(30px, 4vw, 40px);
  font-weight: 700;
  letter-spacing: -.045em;
  font-variant-numeric: tabular-nums;
}
/* Условия сделки — документ, а не заголовок.
   Переносы строк здесь несут смысл: шаблон разбивает условия на «что
   передаётся», «что считается исполненным» и сроки. Без pre-wrap всё это
   схлопывается в сплошной абзац, и человек, которому сейчас нажимать
   «Принять условия», читает стену текста. */
.card__subject {
  margin-top: 10px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.split {
  display: flex;
  gap: 28px;
  flex-wrap: wrap;
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--line-soft);
}
.split__label { font-size: 11.5px; color: var(--ink-4); }
.split__value {
  margin-top: 5px;
  font-family: var(--font-mono);
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}
.split__value--gold { color: var(--gold-200); }

.actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }
.actions:empty { display: none; }

.waiting {
  margin-top: 22px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 13px;
  background: rgba(255, 255, 255, .03);
  font-size: 13.5px;
  color: var(--ink-3);
}

/* Досье контрагента под полем с ником. Спокойный тон по умолчанию: это
   справка, а не обвинение. Золотом — только когда аккаунт совсем новый,
   потому что это единственный признак, ради которого её и читают. */
.whois {
  grid-column: 1 / -1;
  margin-top: -4px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-4);
}
.whois--new {
  color: var(--gold-200);
}

/* Прогноз — отдельной строкой и тише основной: это справка, а не обещание. */
.waiting__usual {
  display: block;
  margin-top: 6px;
  font-size: 12.5px;
  color: var(--ink-4);
}

/* Timeline ----------------------------------------------------------------- */

.timeline { position: relative; padding-left: 22px; }
.timeline::before {
  content: "";
  position: absolute;
  top: 6px; bottom: 6px; left: 4px;
  width: 1px;
  background: linear-gradient(180deg,
    rgba(var(--blue-rgb), .5), rgba(var(--gold-rgb), .35), transparent);
}
.event { position: relative; padding: 0 0 20px; }
.event:last-child { padding-bottom: 0; }
.event::before {
  content: "";
  position: absolute;
  top: 5px; left: -22px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--bg);
  border: 1.5px solid var(--blue-500);
  box-shadow: 0 0 0 3px rgba(9, 11, 16, .9);
}
.event__title { font-size: 14px; font-weight: 600; letter-spacing: -.01em; }
.event__meta {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-4);
}
.event__note {
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-3);
  overflow-wrap: anywhere;
}

/* Chat ---------------------------------------------------------------------
   One stream: messages and deal events together, because an arbiter reading
   two separate lists has to line them up by hand. */

/* ==========================================================================
   Чат сделки

   Устроен как мессенджер, потому что люди в нём переписываются, а не читают
   отчёт: реплики одного человека подряд склеиваются в группу, хвостик есть
   только у последней, время стоит внутри пузыря, а между днями идёт подпись.
   Но это ещё и доказательство, поэтому две вещи здесь не как в мессенджере:
   системные предупреждения нельзя ни свернуть, ни пропустить, а отозванное
   сообщение оставляет видимый след.
   ========================================================================== */

.chat { display: flex; flex-direction: column; position: relative; }

.chat__stream {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 460px;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Отступ сверху — место для липкой подписи дня: без него она встаёт
     ровно на первую строку переписки. */
  padding: 6px 8px 4px 2px;
  margin-top: 18px;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .14) transparent;
}
.chat__stream::-webkit-scrollbar { width: 8px; }
.chat__stream::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .12);
  border-radius: 99px;
}

/* Подпись дня. Липкая: пролистывая длинный спор, всегда видно, к какому
   дню относится то, что сейчас на экране. */
.chat__day {
  position: sticky;
  top: 0;
  z-index: 2;
  align-self: center;
  margin: 14px 0 10px;
  padding: 4px 12px;
  border: 1px solid var(--line);
  border-radius: 99px;
  /* Непрозрачная: полупрозрачная плашка пропускает сквозь себя строку, над
     которой стоит, и обе становятся нечитаемыми. */
  background: #131826;
  box-shadow: 0 4px 14px rgba(2, 4, 12, .5);
  font-size: 11.5px;
  letter-spacing: .04em;
  color: var(--ink-4);
}

.msg {
  display: flex;
  flex-direction: column;
  max-width: 78%;
  align-self: flex-start;
}
.msg--mine { align-self: flex-end; align-items: flex-end; }
/* Реплика внутри группы прижимается к предыдущей. */
.msg--grouped { margin-top: 0; }
.msg:not(.msg--grouped) { margin-top: 10px; }

.msg__bubble {
  position: relative;
  padding: 9px 13px 7px;
  border: 1px solid var(--line-soft);
  border-radius: 16px;
  background: rgba(255, 255, 255, .05);
  font-size: 14px;
  line-height: 1.48;
}
.msg__text {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  /* Место под часы в последней строке, чтобы они не наезжали на текст. */
  padding-right: 42px;
}
.msg--mine .msg__bubble {
  border-color: rgba(var(--blue-rgb), .3);
  background: rgba(var(--blue-rgb), .15);
}

/* Углы: у группы скруглён только внешний контур, как в мессенджерах. */
.msg--mine .msg__bubble { border-bottom-right-radius: 6px; }
.msg:not(.msg--mine) .msg__bubble { border-bottom-left-radius: 6px; }
.msg--tail.msg--mine .msg__bubble { border-bottom-right-radius: 16px; }
.msg--tail:not(.msg--mine) .msg__bubble { border-bottom-left-radius: 16px; }
.msg--grouped.msg--mine .msg__bubble { border-top-right-radius: 6px; }
.msg--grouped:not(.msg--mine) .msg__bubble { border-top-left-radius: 6px; }

/* Часы внутри пузыря: они нужны постоянно, а отдельной строкой под каждым
   сообщением занимали бы вдвое больше места, чем сам текст. */
.msg__clock {
  position: absolute;
  right: 12px;
  bottom: 6px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1;
  color: var(--ink-4);
  pointer-events: none;
}

/* Вложения ---------------------------------------------------------------- */

.files { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 7px; }
.files__shot {
  display: block;
  max-width: 220px;
  border-radius: 11px;
  overflow: hidden;
  line-height: 0;
}
.files__shot img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 260px;
  object-fit: cover;
  transition: transform var(--t-hover) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .files__shot:hover img { transform: scale(1.02); }
}

.files__doc {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px 9px 9px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(255, 255, 255, .04);
  color: inherit;
}
.files__icon {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  flex: none;
  border-radius: 9px;
  background: rgba(var(--blue-rgb), .18);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--blue-300);
}
.files__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.files__name {
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 190px;
}
.files__size { font-family: var(--font-mono); font-size: 10.5px; color: var(--ink-4); }

/* Поднос перед отправкой -------------------------------------------------- */

.tray { display: flex; flex-wrap: wrap; gap: 8px; }
.tray:empty { display: none; }
.tray:not(:empty) { margin-bottom: 10px; }

.tray__item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 6px 6px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: rgba(255, 255, 255, .045);
  font-size: 12.5px;
}
.tray__shot { width: 30px; height: 30px; border-radius: 7px; object-fit: cover; }
.tray__doc {
  display: grid;
  place-items: center;
  width: 30px; height: 30px;
  border-radius: 7px;
  background: rgba(var(--blue-rgb), .18);
  font-size: 9px;
  font-weight: 700;
  color: var(--blue-300);
}
.tray__name {
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ink-3);
}
.tray__drop {
  width: 20px; height: 20px;
  flex: none;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .09);
  color: var(--ink-3);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .tray__drop:hover { background: rgba(255, 122, 122, .22); color: #ffc2c2; }
}

/* «Новые сообщения» — когда человек отлистал вверх.
   Дёрнуть его вниз при каждом обновлении нельзя: он читает историю, а не
   ждёт новостей. Кнопка сообщает, что внизу что-то есть, и не мешает. */
.chat__new {
  position: absolute;
  right: 26px;
  bottom: 108px;
  z-index: 4;
  padding: 8px 14px;
  border: 1px solid rgba(var(--blue-rgb), .4);
  border-radius: 99px;
  background: rgba(20, 28, 48, .94);
  -webkit-backdrop-filter: blur(10px);
          backdrop-filter: blur(10px);
  box-shadow: 0 10px 26px rgba(2, 4, 12, .5);
  font: inherit;
  font-size: 12.5px;
  color: var(--blue-300);
  cursor: pointer;
  animation: appRise 260ms var(--ease-out) both;
}
@media (hover: hover) and (pointer: fine) {
  .chat__new:hover { border-color: var(--blue-400); color: #fff; }
}
@media (prefers-reduced-motion: reduce) {
  .chat__new { animation: none; }
}

/* Строка ввода ------------------------------------------------------------ */

.chat__row { display: flex; align-items: flex-end; gap: 10px; }

.chat__clip {
  width: 42px; height: 42px;
  flex: none;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: rgba(255, 255, 255, .04);
  color: var(--ink-3);
  font-size: 21px;
  line-height: 1;
  cursor: pointer;
  transition: border-color var(--t-hover) ease, color var(--t-hover) ease;
}
@media (hover: hover) and (pointer: fine) {
  .chat__clip:hover { border-color: var(--blue-400); color: #fff; }
}
.chat__clip:focus-visible {
  outline: none;
  border-color: var(--blue-400);
  box-shadow: 0 0 0 3px rgba(var(--blue-rgb), .22);
}

.chat__form--busy { opacity: .6; pointer-events: none; }

/* Кнопка «вниз» ----------------------------------------------------------
   Появляется, только когда человек ушёл вверх по переписке. Постоянная
   кнопка на этом месте закрывала бы последнее сообщение — то самое, ради
   которого её нажимают. */
.chat__down {
  position: absolute;
  right: 18px;
  bottom: 104px;
  z-index: 3;
  width: 38px; height: 38px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: rgba(16, 21, 33, .92);
  -webkit-backdrop-filter: blur(10px);
          backdrop-filter: blur(10px);
  color: var(--ink-2);
  cursor: pointer;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity var(--t-hover) ease, transform var(--t-hover) var(--ease-out);
}
.chat__down::before {
  content: "";
  width: 9px; height: 9px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}
.chat__down--on { opacity: 1; transform: none; pointer-events: auto; }
@media (hover: hover) and (pointer: fine) {
  .chat__down--on:hover { border-color: var(--blue-400); color: #fff; }
}

/* Просмотр картинки ------------------------------------------------------
   В споре фотографию сначала рассматривают, и заставлять для этого лезть в
   папку загрузок — лишний шаг там, где человек торопится. */
.viewer {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 40px;
  background: rgba(5, 7, 12, .92);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 220ms var(--ease-out), visibility 220ms;
}
.viewer--open { opacity: 1; visibility: visible; }
.viewer__img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 12px;
  box-shadow: 0 30px 90px rgba(0, 0, 0, .6);
}
.viewer__save {
  position: absolute;
  right: 24px; bottom: 24px;
  padding: 10px 18px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: rgba(16, 21, 33, .9);
  font-size: 13.5px;
  color: var(--ink-1);
}
@media (hover: hover) and (pointer: fine) {
  .viewer__save:hover { border-color: var(--blue-400); }
}

/* Перетаскивание файла на переписку. */
.chat--drop::after {
  content: "Отпустите — файл приложится";
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  border: 2px dashed rgba(var(--blue-rgb), .5);
  border-radius: 20px;
  background: rgba(10, 14, 24, .82);
  font-size: 14px;
  color: var(--blue-300);
}

.msg__meta {
  margin-top: 5px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--ink-4);
}

/* A withdrawn message still shows: hiding the fact would be its own lie. */
.msg--hidden .msg__bubble {
  border-style: dashed;
  background: transparent;
  color: var(--ink-4);
  font-style: italic;
}

/* System notes and deal events run full width — they are addressed to
   everyone, not said by anyone. */
/* Событие сделки — служебная строка по центру, как «X вошёл в группу» в
   мессенджерах: это не чья-то реплика, а отметка на ленте времени. */
.msg--system, .msg--event { max-width: 100%; align-self: stretch; }
.msg--event { margin-top: 6px; }
.msg--event .msg__meta { display: none; }
.msg--system .msg__bubble {
  border-color: rgba(var(--gold-rgb), .3);
  background: rgba(var(--gold-rgb), .07);
  color: var(--gold-200);
  font-size: 13px;
}
.msg--event .msg__bubble {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 8px;
  border-color: transparent;
  background: transparent;
  padding: 3px 0;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: .04em;
  color: var(--ink-4);
}
.msg--event .msg__text { padding-right: 0; margin: 0; }
.msg__at { font-size: 10.5px; color: rgba(237, 240, 246, .34); }

.msg__flags {
  margin-top: 6px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.flag {
  padding: 2px 8px;
  border: 1px solid rgba(255, 122, 122, .4);
  border-radius: 6px;
  background: rgba(255, 122, 122, .12);
  font-size: 10.5px;
  color: #ffc2c2;
}

/* «Отозвать» — действие по наведению, как в мессенджерах.
   Постоянная строка под каждым своим сообщением занимала места столько же,
   сколько само сообщение, и предлагала стереть написанное чаще, чем это
   вообще уместно в переписке, которая служит доказательством.

   Не `display: none`: спрятанное так недоступно и с клавиатуры, а отозвать
   сообщение должен мочь и тот, кто не пользуется мышью. Поэтому прозрачность
   плюс возврат по `:focus-within`. */
.msg__withdraw {
  margin-top: 4px;
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 11px;
  color: var(--ink-4);
  cursor: pointer;
  text-decoration: underline;
  opacity: 0;
  transition: opacity var(--t-hover) ease, color var(--t-hover) ease;
}
@media (hover: hover) and (pointer: fine) {
  .msg:hover .msg__withdraw { opacity: 1; }
  .msg__withdraw:hover { color: #ffc2c2; }
}
/* На тач-экранах наведения нет — там кнопка видна всегда. */
@media (hover: none) {
  .msg__withdraw { opacity: .75; }
}
.msg__withdraw:focus-visible {
  opacity: 1;
  outline: 2px solid var(--blue-400);
  outline-offset: 2px;
  border-radius: 4px;
}
@media (hover: hover) and (pointer: fine) {
  .msg__withdraw:hover { color: #ff9b9b; }
}

/* Колонка, а не ряд: внутри теперь поднос с приложенными файлами и строка
   ввода. Горизонтальным флексом они вставали рядом, и поле ввода
   сдавливалось до двух строк с обрезанной подсказкой. */
.chat__form {
  display: flex;
  flex-direction: column;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
}
.chat__input {
  flex: 1;
  min-width: 0;
  min-height: 46px;
  max-height: 140px;
  padding: 13px 15px;
  border: 1px solid var(--line-strong);
  border-radius: 13px;
  background: rgba(255, 255, 255, .04);
  font-family: inherit;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--ink-1);
  resize: vertical;
}
/* Подсказка — одной строкой с многоточием. В узком поле она переносилась
   на вторую строку, а поле высотой в одну строку показывало от неё обрезок. */
.chat__input::placeholder {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat__input:focus-visible {
  outline: none;
  border-color: var(--blue-400);
  box-shadow: 0 0 0 3px rgba(var(--blue-rgb), .22);
}
.chat__send { flex: none; }
.chat__closed {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
  font-size: 13px;
  color: var(--ink-4);
}

.chat__export {
  margin-top: 12px;
  font-size: 12.5px;
  color: var(--ink-3);
}

@media (max-width: 700px) {
  .msg { max-width: 92%; }
  /* Кнопка отправки живёт в строке ввода. Старое `width: 100%` писалось
     под прежнюю раскладку и в строке сжимало поле до одной буквы —
     писать в чат с телефона было нельзя. Теперь поле с «+» — первой
     строкой, кнопка — второй, на всю ширину, под большой палец. */
  .chat__row { flex-wrap: wrap; }
  .chat__send { flex: 1 0 100%; }
}

/* Arbitration form --------------------------------------------------------- */

.arb { margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line-soft); }
.arb__title {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: rgba(223, 196, 139, .82);
  margin-bottom: 14px;
}
.arb .field + .field { margin-top: 12px; }

/* Responsive --------------------------------------------------------------- */

@media (max-width: 1000px) {
  .detail { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 700px) {
  .newdeal__row { grid-template-columns: minmax(0, 1fr); }
  .app { padding-top: 36px; }
  .dealrow { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .dealrow__amount { text-align: left; }
  .actions .btn { flex: 1 1 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .dealrow:hover, .dealrow:active { transform: none; }
}

/* Stages, integrity and hints ----------------------------------------------
   Added with the Ф10 screens: the backend for these shipped first, and a
   feature nobody can reach from a browser is a feature that does not exist. */

.field__hint {
  display: block;
  margin-top: 7px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-4);
}

.stages { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }

.stage {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 16px;
  border: 1px solid var(--line-soft);
  border-radius: 14px;
  background: rgba(255, 255, 255, .03);
}
.stage__title { font-size: 14.5px; font-weight: 600; letter-spacing: -.01em; }
.stage__meta {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--ink-4);
}
.stage__actions { display: flex; gap: 8px; flex-wrap: wrap; }
.stage__btn { padding: 9px 15px; font-size: 13px; border-radius: 11px; }

/* Status shows in the border, so a glance down the list reads as progress. */
[data-stage="confirmed"], [data-stage="paid"] { border-color: rgba(var(--green-rgb), .35); }
[data-stage="delivered"] { border-color: rgba(var(--gold-rgb), .35); }
[data-stage="disputed"]  { border-color: rgba(255, 122, 122, .4); }
[data-stage="refunded"]  { border-color: var(--line); opacity: .65; }

/* The integrity line is the service's central claim, so it is stated plainly
   rather than tucked into a tooltip. */
.integrity {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  margin-top: 14px;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: 13px;
  font-size: 13px;
  color: var(--ink-3);
}
.integrity--ok { border-color: rgba(var(--green-rgb), .3); background: rgba(var(--green-rgb), .06); }
.integrity--broken {
  border-color: rgba(255, 122, 122, .45);
  background: rgba(255, 122, 122, .1);
  color: #ffc2c2;
}
.integrity__mark { color: var(--green-soft); font-weight: 700; }
.integrity__link { color: var(--blue-400); }

/* The guarantor's books, read straight off the ledger.
   Four numbers that must always be looked at together — how much has flowed
   through, what was earned on it, what is physically held, and what is owed
   to other people. Held and owed sit last and adjacent on purpose: the gap
   between them is the guarantor's own money, and seeing "в кассе" smaller
   than "обязательства" should be immediately alarming. */
.facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin-top: 26px;
}
.fact {
  padding: 17px 18px 16px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: linear-gradient(180deg, var(--fill-1), var(--fill-2));
}
.fact__label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.fact__value {
  margin-top: 9px;
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Money that is not the guarantor's: held on behalf of the parties. */
.fact:nth-child(4) .fact__value { color: var(--gold-200); }

@media (max-width: 860px) {
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 420px) {
  .fact__value { font-size: 19px; }
}

/* Книги гаранта — пять чисел. С появлением резерва их стало пять в сетке
   на четыре, и «Обязательства» уехали на вторую строку одни — прочь от
   «В кассе», хотя весь смысл ряда в том, чтобы эти два числа стояли
   рядом. На широком экране — один ряд, на узком резерв встаёт отдельной
   строкой, а касса и обязательства остаются парой. */
.facts--desk { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.facts--desk .fact__value { font-size: clamp(18px, 1.7vw, 22px); }
@media (max-width: 1100px) {
  .facts--desk { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .facts--desk .fact:nth-child(3) { grid-column: 1 / -1; }
}
/* Золотом — чужие деньги, обязательства перед сторонами. Резерв встал
   третьим, и общее правило «четвёртая карточка — золотая» перекрасило
   кассу вместо них. */
.facts--desk .fact:nth-child(4) .fact__value { color: inherit; }
.facts--desk .fact:nth-child(5) .fact__value { color: var(--gold-200); }

/* Публичные карточки (профиль, проверка) несут порядок суммы — «200 тыс –
   1 млн ₽». Одной строкой он вылезал из карточки на средних ширинах и
   наезжал на соседнюю на телефоне. Здесь перенос разрешён; в книгах
   гаранта — нет, там только суммы. */
.facts:not(.facts--desk) .fact__value { white-space: normal; text-wrap: balance; line-height: 1.2; }

/* Тревоги в кабинете гаранта.
   Стоят выше очереди намеренно: всё остальное на экране — работа, а это
   аварии, и читать их после списка задач поздно. */
.alarms:empty { display: none; }
.alarms { display: flex; flex-direction: column; gap: 10px; margin-top: 22px; }

.alarm {
  padding: 16px 18px;
  border: 1px solid rgba(var(--gold-rgb), .4);
  border-radius: 14px;
  background: rgba(var(--gold-rgb), .08);
  font-size: 14px;
  line-height: 1.55;
  color: var(--gold-200);
  white-space: pre-wrap;
}
.alarm--critical {
  border-color: rgba(255, 122, 122, .5);
  background: rgba(255, 122, 122, .09);
  color: #ffc2c2;
}
.js .alarm { animation: appRise 380ms var(--ease-out) both; }

/* Поиск по сделкам. */
.finder {
  display: flex;
  gap: 10px;
  margin-top: 26px;
  flex-wrap: wrap;
}
.finder__input { flex: 1 1 260px; }
.finder__results:empty { display: none; }
.finder__results { margin-top: 16px; }

@media (prefers-reduced-motion: reduce) {
  .js .alarm { animation: none; }
}

/* Desk rows carry their urgency in the border. */
[data-severity="critical"] { border-color: rgba(255, 122, 122, .5); }
[data-severity="warning"]  { border-color: rgba(var(--gold-rgb), .4); }

/* ==========================================================================
   Движение

   Кабинет до этого был неподвижен: ноль анимаций против десяти на лендинге —
   две поверхности одного продукта выглядели как два продукта. Но добавлять
   движение ради движения здесь нечего: это экран, где человек ждёт чужих
   денег. Каждая анимация ниже отвечает на вопрос, который иначе остаётся без
   ответа.

   Токены берутся из лендинга (--ease-out, --t-*), а не заводятся заново.
   ========================================================================== */

/* «Оно вообще грузится?»
   Раньше на время запроса экран был пуст, и на медленной связи это читалось
   как поломка. Скелет занимает то же место, что придёт, — поэтому при
   появлении данных ничего не прыгает. */

.skel {
  border: 1px solid var(--line);
  border-radius: 18px;
  background: linear-gradient(180deg, var(--fill-1), var(--fill-2));
  position: relative;
  overflow: hidden;
}
.skel--row { height: 86px; margin-bottom: 12px; }
.skel--card { height: 240px; }

/* Блик пробегает раз в 1.6 с — достаточно, чтобы отличить «грузится» от
   «зависло», и недостаточно, чтобы раздражать. */
.js .skel::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%,
              rgba(255, 255, 255, .05) 45%, transparent 70%);
  transform: translateX(-100%);
  animation: skelSweep 1.6s var(--ease-in-out) infinite;
}
@keyframes skelSweep { to { transform: translateX(100%); } }

/* «Что-то появилось».
   Шаг между строками маленький и обрывается на шестой: каскад на двадцати
   сделках превращается в ожидание, а не в изящество. */
.js .rise { animation: appRise 380ms var(--ease-out) both; }
.js .rise:nth-child(2) { animation-delay: 40ms; }
.js .rise:nth-child(3) { animation-delay: 80ms; }
.js .rise:nth-child(4) { animation-delay: 120ms; }
.js .rise:nth-child(5) { animation-delay: 160ms; }
.js .rise:nth-child(n+6) { animation-delay: 200ms; }
@keyframes appRise {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}

/* «Что именно изменилось?»
   После действия карточка перерисовывается целиком, и то, что статус сдвинулся,
   легко пропустить — а это единственное, ради чего кнопку нажимали. Плашка
   один раз подсвечивается: не мигает, не дёргается, просто на секунду
   становится заметнее остального. */
.js .pill--changed { animation: pillLand 900ms var(--ease-out) both; }
@keyframes pillLand {
  0%   { transform: scale(.9); box-shadow: 0 0 0 0 rgba(var(--pill-rgb, var(--blue-rgb)), .5); }
  35%  { transform: scale(1.04); box-shadow: 0 0 0 7px rgba(var(--pill-rgb, var(--blue-rgb)), 0); }
  100% { transform: none; box-shadow: 0 0 0 0 rgba(var(--pill-rgb, var(--blue-rgb)), 0); }
}

/* «Мой клик дошёл?»
   Кнопка и раньше блокировалась, но выглядела просто погасшей — неотличимо
   от сломанной. Теперь она честно показывает, что запрос в пути. */
.btn.is-busy {
  position: relative;
  color: transparent !important;
  pointer-events: none;
}
.btn.is-busy::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 15px; height: 15px;
  margin: -8px 0 0 -8px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--ink-1);
  animation: btnSpin 640ms linear infinite;
}
@keyframes btnSpin { to { transform: rotate(360deg); } }

/* Новое сообщение в чате приходит снизу — оттуда же, откуда его пишут. */
.js .msg--fresh { animation: msgIn 320ms var(--ease-out) both; }
@keyframes msgIn {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: none; }
}

/* Форма создания сделки — единственное, что раскрывается по клику. */
.js .newdeal:not([hidden]) { animation: appRise 300ms var(--ease-out) both; }

@media (prefers-reduced-motion: reduce) {
  .js .skel::after,
  .js .rise,
  .js .pill--changed,
  .js .msg--fresh,
  .js .newdeal:not([hidden]) { animation: none; }
  .js .rise, .js .msg--fresh { opacity: 1; transform: none; }
  /* Спиннер остаётся: он не украшение, а единственный признак, что запрос
     ещё в пути. Но крутится медленнее, без мельтешения. */
  .btn.is-busy::after { animation-duration: 1.4s; }
}

/* ==========================================================================
   3D-объекты в продукте

   Правила те же, что на лендинге: объект помогает понять экран или его здесь
   нет. Разница в дозировке — в кабинете человек работает, а не знакомится,
   и картинка, которую видишь двадцатый раз за день, должна быть тише.
   ========================================================================== */

.o3d-wrap { position: relative; pointer-events: none; }

.o3d {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 18px 40px rgba(var(--blue-rgb), .18));
}

.js .o3d {
  opacity: 0;
  transform: translateY(14px) scale(.98);
  transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out);
}
.js .o3d.is-in { opacity: 1; transform: none; }

/* Дыхание — 5px за 8 секунд. В рабочем экране амплитуда ещё меньше, чем на
   лендинге: здесь на объект смотрят фоном, и всё заметное отвлекает. */
.js .o3d.is-in { animation: o3dFloat 8s var(--ease-in-out) infinite alternate; }
@keyframes o3dFloat {
  from { transform: translateY(0); }
  to   { transform: translateY(-5px); }
}

/* Публичные страницы: объект над заголовком, по центру колонки. */
.o3d-wrap--page { max-width: 260px; margin: 0 0 26px; }
/* Подпись раздела над объектом не должна лежать на его кромке. */
.eyebrow + .o3d-wrap--page { margin-top: 14px; }
.o3d-wrap--narrow { max-width: 190px; }

/* Очередь гаранта: весы стоят справа от заголовка, не над ним — иначе они
   отодвигают вниз то, ради чего экран открывают. */
.o3d-wrap--desk {
  position: absolute;
  top: -10px; right: 0;
  width: 240px;
  opacity: .6;
}
.view[data-view="desk"] { position: relative; }

/* Пустой кабинет: единственный экран, где объекту есть куда встать во весь
   рост — дальше его закроет список сделок. */
.empty--art { display: grid; justify-items: center; gap: 18px; padding: 38px 26px 42px; }
.empty--art .o3d { max-width: 300px; }
.empty__text { margin: 0; max-width: 380px; }

@media (max-width: 860px) {
  .o3d-wrap--desk { display: none; }
}
@media (max-width: 520px) {
  .o3d-wrap--page { max-width: 200px; }
  .empty--art .o3d { max-width: 220px; }
}

@media (prefers-reduced-motion: reduce) {
  .js .o3d { opacity: 1; transform: none; transition: none; }
  .js .o3d.is-in { animation: none; }
}

/* Окно кода подтверждения. Появляется на всём, что двигает деньги, поэтому
   выглядит спокойно и не как ошибка: это обычный шаг, а не сбой. */
.codeask {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(4, 6, 10, .72);
}
.codeask__box {
  width: min(360px, 100%);
  padding: 24px;
  border: 1px solid rgba(var(--gold-rgb), .28);
  border-radius: 18px;
  background: var(--bg-top);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
}
.codeask__title {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-1);
}
.codeask__hint {
  margin-top: 6px;
  font-size: 12.5px;
  color: var(--ink-4);
}
.codeask__input {
  width: 100%;
  margin-top: 16px;
  padding: 12px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: rgba(255, 255, 255, .04);
  color: var(--ink-1);
  font-family: var(--font-mono);
  font-size: 20px;
  letter-spacing: .28em;
  text-align: center;
}
.codeask__input:focus {
  outline: 2px solid rgba(var(--gold-rgb), .5);
  outline-offset: 2px;
}
.codeask__row {
  display: flex;
  gap: 10px;
  margin-top: 16px;
}
.codeask__row .btn { flex: 1; }

/* Профиль: заголовок «Отзывы» стоял вплотную к карточкам с цифрами и
   читался их подписью, а не началом нового раздела. */
.facts + .section__title { margin-top: 52px; margin-bottom: 18px; }
