/* Биржа токенов — поверх дизайн-системы /static/style.css (токены оттуда).
   Отступы сведены к шкале 4px (--s1..--s9): правило округления — ближайшая
   ступень, при равном расстоянии вверх (6px → --s2, 9px → --s2, 10px → --s3,
   14px → --s4, 18px → --s5, 28px → --s7, 36px → --s8). Отклонение не больше 4px.
   Состояния (наведение / фокус / нажатие / недоступно) есть у каждого
   управляющего элемента — они собраны рядом с самим элементом. */
.xchg-body{display:block;min-height:100dvh;background:var(--bg);color:var(--text);
  font-family:var(--font);overflow-y:auto}

/* Один переход на всё, что откликается: цвет — ровно, transform — с перелётом */
.xchg-body :is(button,a,summary,input,select,textarea),
.x-mode-card,.x-offer{
  transition:background-color var(--dur-tap) var(--ease-out),
             border-color var(--dur-tap) var(--ease-out),
             color var(--dur-tap) var(--ease-out),
             transform var(--dur-tap) var(--ease-tap)}

/* ── Одна мера ширины на всю страницу ────────────────────────────────────
   Полосы во всю ширину экрана (баннер, дисклеймер, шапка) держат ВНУТРИ себя
   ту же колонку, что и содержимое: --x-measure. Иначе на широком мониторе
   заголовок «Биржа токенов» прижат к самому краю, а карточки — по центру,
   и ничто ни с чем не выравнивается. */
:root{ --x-measure:1200px }

.imp-banner{display:flex;align-items:center;justify-content:center;gap:var(--s4);
  background:var(--warn-soft);color:var(--warn);border-bottom:1px solid var(--border);
  padding:var(--s2) var(--s4);font-size:var(--t-sm)}
.x-disclaimer{background:var(--surface-2);border-bottom:1px solid var(--border);
  color:var(--muted);font-size:var(--t-sm);line-height:1.45}
.x-disclaimer-inner{max-width:var(--x-measure);margin:0 auto;
  padding:var(--s2) var(--s6);text-align:center}
.x-disclaimer b{color:var(--text);font-weight:600}
.x-disclaimer a{color:var(--accent);margin-left:6px}
.xchg-header{border-bottom:1px solid var(--border);
  background:var(--surface);position:sticky;top:0;z-index:var(--z-sticky)}
.xchg-header-inner{display:flex;align-items:center;gap:var(--s5);flex-wrap:wrap;
  max-width:var(--x-measure);margin:0 auto;padding:var(--s4) var(--s6)}
.xchg-brand{display:flex;align-items:center;gap:var(--s3)}
.xchg-logo{display:flex;align-items:center}
.xchg-logo img{display:block;width:auto;height:34px;max-width:190px}
.xchg-title{font-weight:650;font-size:var(--t-lg);letter-spacing:.2px}
.xchg-nav{display:flex;gap:6px;flex-wrap:wrap;flex:1;min-width:0;align-items:center}
.xchg-dd{position:relative}
.xchg-dd summary{list-style:none;cursor:pointer;user-select:none;
  font-size:var(--t-sm);font-weight:600;color:var(--muted);
  padding:var(--s2) var(--s7) var(--s2) var(--s3);border-radius:var(--r-md);
  border:1px solid var(--border);background:var(--surface-2);position:relative}
.xchg-dd summary::-webkit-details-marker{display:none}
.xchg-dd summary::marker{content:""}
.xchg-dd summary::after{content:"";position:absolute;right:var(--s3);top:50%;
  width:6px;height:6px;margin-top:-4px;border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;transform:rotate(45deg);opacity:.55}
.xchg-dd[open] summary{color:var(--accent);border-color:transparent;background:var(--accent-soft)}
.xchg-dd[open] summary::after{margin-top:-1px;transform:rotate(225deg);opacity:.75}
.xchg-dd summary:hover{color:var(--accent);border-color:var(--border-strong)}
.xchg-dd summary:focus-visible{outline:var(--ring) solid var(--accent);
  outline-offset:var(--ring-offset)}
.xchg-dd summary:active{transform:scale(var(--press))}
.xchg-dd summary[aria-disabled="true"]{opacity:.45;cursor:not-allowed;transform:none}
.xchg-dd.active > summary{color:var(--accent);border-color:transparent;background:var(--accent-soft)}
.xchg-dd-panel{position:absolute;top:calc(100% + 6px);left:0;z-index:var(--z-popover);
  min-width:min(240px,calc(100vw - 40px));padding:var(--s2);
  border-radius:var(--r-lg);background:var(--surface);
  border:1px solid var(--border);box-shadow:var(--e2);
  display:flex;flex-direction:column;gap:2px}
.xchg-nav .tab{border:1px solid transparent;background:transparent;color:var(--muted);
  padding:var(--s2) var(--s3);border-radius:var(--r-md);cursor:pointer;font-size:var(--t-sm);
  font-weight:550;text-align:left;width:100%}
.xchg-nav .tab:hover:not(:disabled){background:var(--surface-2);color:var(--text)}
.xchg-nav .tab:focus-visible{outline:var(--ring) solid var(--accent);
  outline-offset:var(--ring-offset)}
.xchg-nav .tab:not(:disabled):active{transform:scale(var(--press))}
.xchg-nav .tab:disabled,.xchg-nav .tab[aria-disabled="true"]{opacity:.45;cursor:not-allowed;
  transform:none}
.xchg-nav .tab.on{background:var(--accent-soft);color:var(--accent);border-color:transparent}
.xchg-embed .xchg-brand .muted{display:none}
.xchg-user{display:flex;align-items:center;gap:var(--s3)}
.xchg-back{text-decoration:none;color:var(--muted);padding:var(--s2) var(--s3);border-radius:var(--r-md)}
.xchg-back:hover{background:var(--surface-2);color:var(--text)}
.xchg-back:focus-visible{outline:var(--ring) solid var(--accent);outline-offset:var(--ring-offset)}
.xchg-back:active{transform:scale(var(--press))}
.xchg-back[aria-disabled="true"]{opacity:.45;cursor:not-allowed;transform:none}
.xchg-main{max-width:var(--x-measure);margin:0 auto;padding:var(--s6)}
.xchg-toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);
  background:var(--surface-3);border:1px solid var(--border-strong,var(--border));
  color:var(--text);padding:var(--s3) var(--s5);border-radius:var(--r-md);z-index:var(--z-toast);
  box-shadow:var(--e2);font-size:var(--t-sm)}
.xchg-toast.err{border-color:var(--danger);color:var(--danger)}

/* Карточки/сетки */
.x-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:var(--s4)}
.x-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:var(--s4);display:flex;flex-direction:column;gap:var(--s3)}
.x-card h3{margin:0;font-size:var(--t-md);font-weight:640}
.x-sec{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:var(--s5);margin-bottom:var(--s5)}
.x-sec h2{margin:0 0 var(--s4);font-size:var(--t-lg);font-weight:650}
.x-sec h4{margin:var(--s4) 0 var(--s2);font-size:var(--t-sm);color:var(--muted);
  text-transform:uppercase;letter-spacing:.6px}
.x-row{display:flex;align-items:center;gap:var(--s3);flex-wrap:wrap}
.x-kv{display:flex;gap:var(--s2);align-items:baseline}
.x-kv b{font-size:var(--t-xl)}
.x-table{width:100%;border-collapse:collapse;font-size:var(--t-sm)}
.x-table th{text-align:left;color:var(--muted);font-weight:550;font-size:var(--t-xs);
  text-transform:uppercase;letter-spacing:.5px;padding:var(--s2) var(--s3);border-bottom:1px solid var(--border)}
.x-table td{padding:var(--s2) var(--s3);border-bottom:1px solid var(--border);vertical-align:middle}
.x-table tr:last-child td{border-bottom:none}
.x-empty{padding:var(--s8);text-align:center;color:var(--muted)}
.x-offer{display:flex;align-items:center;gap:var(--s2);justify-content:space-between;
  background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-md);
  padding:var(--s2) var(--s3)}
.x-offer:hover{border-color:var(--border-strong);background:var(--surface-3)}
.x-offer:focus-visible{outline:var(--ring) solid var(--accent);outline-offset:var(--ring-offset)}
/* Строка предложения часто содержит свою кнопку. :active достаётся и предку,
   поэтому сжимаем строку только тогда, когда нажали именно её, а не кнопку
   внутри — иначе весь ряд «приседает» при каждом клике по кнопке. */
.x-offer:active:not(:has(:active)){transform:scale(var(--press))}
.x-offer[aria-disabled="true"]{opacity:.45;cursor:not-allowed;transform:none}
.x-offer .price{font-weight:650}
.x-model-included{display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  padding:var(--s2) var(--s3);background:var(--surface-2);border-radius:var(--r-md);
  font-size:var(--t-sm)}
.x-model-included .chip{margin:0}
.x-cat-filter{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:var(--s4)}
.x-cart{position:sticky;bottom:0;background:var(--surface-3);border:1px solid var(--border);
  border-radius:var(--r-lg);padding:var(--s4);margin-top:var(--s5);
  box-shadow:var(--e3)}
.x-form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:var(--s3)}
.x-mode-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:var(--s3)}
.x-mode-card{border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s3);
  cursor:pointer;background:var(--surface-2)}
/* Карточка-выбор: при наведении приподнимается, как .model-card в ядре */
.x-mode-card:hover{border-color:var(--border-strong);background:var(--surface-3);
  transform:translateY(calc(-1 * var(--lift)))}
.x-mode-card:focus-visible{outline:var(--ring) solid var(--accent);outline-offset:var(--ring-offset)}
.x-mode-card:active{transform:scale(var(--press))}
.x-mode-card[aria-disabled="true"]{opacity:.45;cursor:not-allowed;transform:none}
.x-mode-card.on{border-color:var(--accent);background:var(--accent-soft)}
.x-mode-card b{display:block;margin-bottom:4px}
.x-key-once{font-family:var(--mono);word-break:break-all;background:var(--surface-2);
  border:1px dashed var(--accent);border-radius:var(--r-md);padding:var(--s3);margin:var(--s3) 0}
/* Dynamic GPU topology.  It is deliberately DOM/CSS rather than a third-party
   canvas: no telemetry leaves the page and mobile users can inspect each shard. */
.gpu-group{background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-md);padding:var(--s3);margin:var(--s3) 0}
.gpu-group.degraded{border-color:var(--warn)}
.gpu-group-head{display:flex;gap:var(--s2);align-items:center;flex-wrap:wrap;margin-bottom:var(--s3)}
.gpu-lanes{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:var(--s3)}
.gpu-lane{border-left:2px solid var(--accent);padding-left:var(--s3);min-height:72px}
.gpu-lane-title{font-size:var(--t-xs);color:var(--muted);text-transform:uppercase;letter-spacing:.4px;margin-bottom:6px}
.gpu-node{display:flex;align-items:flex-start;gap:7px;padding:var(--s2);margin:5px 0;border:1px solid var(--border);border-radius:var(--r-sm);font-size:var(--t-sm)}
.gpu-node.online>span:first-child{color:var(--ok)}.gpu-node.offline>span:first-child{color:var(--warn)}
.gpu-node small{display:block;color:var(--muted);margin-top:2px}.gpu-node em{margin-left:auto;font-style:normal;color:var(--muted);font-size:var(--t-xs)}
.gpu-missing{border:1px dashed var(--border);border-radius:var(--r-sm);color:var(--muted);padding:var(--s2);font-size:var(--t-sm)}
/* Окно авторизации подписки — нативный <dialog>: бэкдроп, Esc, фокус-трап */
.x-dialog{border:1px solid var(--border);border-radius:var(--r-lg);background:var(--surface);
  color:var(--text);padding:var(--s5);max-width:560px;width:calc(100% - 32px)}
.x-dialog::backdrop{background:var(--scrim)}
.x-dialog-x{display:flex;justify-content:flex-end;margin:calc(-1 * var(--s3)) calc(-1 * var(--s3)) 0 0}
.x-step{display:flex;gap:var(--s3);align-items:flex-start;margin-bottom:var(--s4)}
.x-step-n{flex:0 0 26px;height:26px;border-radius:var(--r-full);background:var(--accent-soft);
  color:var(--accent);display:flex;align-items:center;justify-content:center;
  font-size:var(--t-xs);font-weight:650}
.x-step.done .x-step-n{background:var(--ok-soft);color:var(--ok)}
.x-authurl{display:block;word-break:break-all;background:var(--surface-2);
  border:1px solid var(--accent-line,var(--border));border-radius:var(--r-md);
  padding:var(--s3);margin:var(--s2) 0;font-family:var(--mono);font-size:var(--t-xs)}
.x-panel{background:var(--code-bg);border:1px solid var(--border);border-radius:var(--r-md);
  padding:var(--s3);font-family:var(--mono);font-size:var(--t-xs);white-space:pre-wrap;
  max-height:160px;overflow:auto;color:var(--muted)}
.x-md p{margin:0 0 10px;line-height:1.6}
.x-md h1{font-size:var(--t-xl)}
@media (max-width:760px){.xchg-main{padding:var(--s4)}.xchg-header{padding:var(--s3)}
  .xchg-header-inner{gap:var(--s3);padding:var(--s2) var(--s3)}.xchg-brand{flex:1 1 100%}
  .xchg-logo img{height:28px}.xchg-title{font-size:var(--t-md)}
  .x-disclaimer-inner{padding:var(--s2) var(--s4);font-size:var(--t-xs)}}

/* Пустые состояния: объясняют, что делать, а не просто «пусто» */
.x-empty-rich{padding:var(--s7) var(--s5);max-width:520px;margin:0 auto;text-align:center}
.x-empty-ico{font-size:44px;margin-bottom:var(--s3)}
.x-empty-rich h3{margin:0 0 var(--s2);color:var(--text);font-size:var(--t-lg)}
.x-empty-rich p{margin:0 0 var(--s4)}
.x-empty-rich .x-row{gap:var(--s3)}
.status-box.warn{border-color:var(--warn);color:var(--text)}
.status-box.ok{border-color:var(--ok)}

/* Плашка гостевого режима */
.x-anon-note{background:var(--accent-soft);color:var(--accent);border-radius:var(--r-md);
  padding:var(--s3) var(--s4);margin-bottom:var(--s4);font-size:var(--t-sm)}
.x-anon-note a{color:var(--accent);font-weight:600}
.xchg-login{text-decoration:none;padding:var(--s2) var(--s4);border-radius:var(--r-md);
  background:var(--accent-2);color:var(--accent-fg);font-weight:600}
.xchg-login:hover{background:var(--accent)}
.xchg-login:focus-visible{outline:var(--ring) solid var(--accent);outline-offset:var(--ring-offset)}
.xchg-login:active{background:var(--accent-press);transform:scale(var(--press))}
.xchg-login[aria-disabled="true"]{opacity:.45;cursor:not-allowed;transform:none}
