/* =============================================================
   ui.css — слой примитивов.

   Компоненты shadcn/ui на ванильном CSS: та же анатомия, те же
   варианты, те же размеры. Вариант задаётся атрибутом
   data-variant, размер — data-size, состояние — data-state /
   data-active / aria-current, как в оригинале.

   База · Button · Separator · Accordion · Skeleton · Alert ·
   Empty · Tooltip · Typography

   Удалены как неиспользуемые на сайте (жили только в витрине):
   Badge, Card, Kbd, Spinner, Progress, Table, Toggle, Input,
   Breadcrumb, Sidebar, Sheet (боковой панели больше нет —
   вся навигация в верхней полосе).
   ============================================================= */

/* =============================================================
   БАЗА
   Сброс и типографические умолчания. Приехали из theme.css:
   слой токенов не должен содержать правил. styleguide.html
   подключает оба файла — справочник не пострадал.
   ============================================================= */
*,*::before,*::after{box-sizing:border-box}

html{
  height:100%;
  -webkit-text-size-adjust:100%;
  scroll-padding-top:calc(var(--topbar-h) + var(--space-4));
}

body{
  min-height:100%;
  margin:0;
  overflow-x:hidden;
  font-family:var(--font-sans);
  font-size:var(--text-sm);
  line-height:var(--leading-sm);
  font-weight:var(--weight-normal);
  color:var(--text);
  background:var(--surface-desk);   /* стол: он же виден в полях каркаса */
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}

/* как Preflight у Tailwind, на который опирается shadcn: заголовки
   не несут своего кегля — его задаёт компонент (.ui-prose и другие) */
h1,h2,h3,h4,h5,h6{margin:0;font-size:inherit;font-weight:inherit}
p,figure,blockquote,pre{margin:0}
ul,ol{margin:0;padding:0}

button,input,select,textarea{font:inherit;color:inherit}

:where(a){color:var(--brand)}

::selection{
  background:color-mix(in oklab, var(--brand) 22%, transparent);
  color:var(--text);
}

/* Полоса прокрутки — системная, только тоньше и в цвет темы. */
*{scrollbar-width:thin;scrollbar-color:var(--edge) transparent}

/* Скрыто для глаза, доступно для скринридера */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* -------------------------------------------------------------
   Фокус. Одно кольцо на весь интерфейс, одним токеном.
   Было: формула color-mix(--ring 50%, transparent), скопированная
   руками в трёх местах и дававшая на белом контраст 2.02 при
   заявленных в комментарии 4.92. Стало непрозрачное — 9.41.
   ------------------------------------------------------------- */
.ui-button:focus-visible,
.ui-accordion-trigger:focus-visible,
.ui-prose a:focus-visible{
  outline:var(--focus-ring);
  outline-offset:var(--focus-offset);
  z-index:var(--z-raised);
}

/* иконки — контур lucide: 24-я сетка, обводка 2, скруглённые концы */
.ui-button svg,
.ui-accordion-trigger svg,
.ui-empty-media svg,
.ui-alert svg{
  flex:0 0 auto;
  pointer-events:none;
  fill:none;
  stroke:currentColor;
  stroke-width:2;
  stroke-linecap:round;
  stroke-linejoin:round;
}

/* =============================================================
   BUTTON
   ============================================================= */
.ui-button{
  display:inline-flex;align-items:center;justify-content:center;
  flex-shrink:0;gap:var(--space-2);
  height:var(--control-h);padding:0 var(--space-4);
  border:1px solid transparent;border-radius:var(--radius-md);
  background:transparent;
  font-size:var(--text-sm);line-height:var(--leading-sm);
  font-weight:var(--weight-medium);
  white-space:nowrap;text-decoration:none;
  cursor:pointer;
  outline:none;
  transition:background-color var(--duration) var(--ease-in-out),
             color var(--duration) var(--ease-in-out),
             border-color var(--duration) var(--ease-in-out),
             box-shadow var(--duration) var(--ease-in-out),
             opacity var(--duration) var(--ease-in-out);
}
.ui-button svg{width:var(--icon);height:var(--icon)}
.ui-button:has(> svg){padding-inline:var(--space-3)}

.ui-button:disabled,
.ui-button[aria-disabled="true"]{pointer-events:none;opacity:.5}

/* ---- варианты ---- */
.ui-button,
.ui-button[data-variant="default"]{
  background:var(--brand);color:var(--text-on-brand);
}
.ui-button:hover,
.ui-button[data-variant="default"]:hover{
  background:var(--brand-press);
}

.ui-button[data-variant="secondary"]{
  background:var(--surface-sunk);color:var(--text);
}
.ui-button[data-variant="secondary"]:hover{
  background:var(--surface-press);
}

.ui-button[data-variant="outline"]{
  background:var(--surface-page);color:var(--text);
  border-color:var(--edge);
  box-shadow:var(--shadow-xs);
}
.ui-button[data-variant="outline"]:hover{
  background:var(--surface-hover);
}

.ui-button[data-variant="ghost"]{background:transparent;color:var(--text)}
.ui-button[data-variant="ghost"]:hover{background:var(--surface-hover)}

.ui-button[data-variant="link"]{
  background:transparent;color:var(--brand);
  height:auto;padding:0;
  text-underline-offset:4px;
}
.ui-button[data-variant="link"]:hover{background:transparent;text-decoration:underline}

.ui-button[data-variant="destructive"]{
  background:var(--danger-solid);color:var(--text-on-danger);
}
.ui-button[data-variant="destructive"]:hover{
  background:color-mix(in oklab, var(--danger-solid) 90%, var(--shade));
}
.ui-button[data-variant="destructive"]:focus-visible{
  outline-color:var(--danger);
}

/* ---- размеры: на сайте живут sm и icon-sm ---- */
.ui-button[data-size="sm"]{height:var(--row-h);padding-inline:var(--space-3);gap:var(--space-1_5)}
.ui-button[data-size="sm"]:has(> svg){padding-inline:var(--space-2_5)}

.ui-button[data-size^="icon"]{padding:0;width:var(--control-h);height:var(--control-h)}
.ui-button[data-size="icon-sm"]{width:var(--row-h);height:var(--row-h)}

/* =============================================================
   SEPARATOR
   ============================================================= */
.ui-separator{
  flex-shrink:0;border:0;margin:0;
  background:var(--line);
  height:1px;width:100%;
}
.ui-separator[data-orientation="vertical"]{height:100%;width:1px;align-self:stretch}

/* =============================================================
   ACCORDION
   Собран на <details>/<summary>: нативное раскрытие, работает
   без JS, доступно с клавиатуры.
   ============================================================= */
.ui-accordion{display:flex;flex-direction:column}

.ui-accordion-item{border-bottom:1px solid var(--line)}
.ui-accordion-item:last-child{border-bottom:0}

.ui-accordion-trigger{
  list-style:none;cursor:pointer;
  display:flex;align-items:flex-start;justify-content:space-between;
  gap:var(--space-4);
  padding-block:var(--space-4);
  border-radius:var(--radius-md);
  font-size:var(--text-sm);line-height:var(--leading-sm);
  font-weight:var(--weight-medium);
  text-align:left;color:var(--text);
  outline:none;
  transition:color var(--duration) var(--ease-in-out);
}
.ui-accordion-trigger::-webkit-details-marker{display:none}
.ui-accordion-trigger:hover{text-decoration:underline;text-underline-offset:4px}

.ui-accordion-chevron{
  width:var(--icon);height:var(--icon);flex-shrink:0;
  translate:0 2px;
  color:var(--text-muted);
  transition:transform var(--duration) var(--ease-in-out);
}
.ui-accordion-item[open] > .ui-accordion-trigger .ui-accordion-chevron{transform:rotate(180deg)}

.ui-accordion-content{
  padding-bottom:var(--space-4);
  font-size:var(--text-sm);
}

/* =============================================================
   SKELETON
   ============================================================= */
.ui-skeleton{
  border-radius:var(--radius-md);
  background:var(--surface-press);   /* наведение слишком тихо для заглушки */
  animation:ui-pulse var(--duration-pulse) cubic-bezier(.4,0,.6,1) infinite;
}
@keyframes ui-pulse{50%{opacity:.5}}

/* =============================================================
   ALERT
   ============================================================= */
.ui-alert{
  display:grid;grid-template-columns:0 1fr;gap:0 var(--space-3);
  align-items:start;
  width:100%;padding:var(--space-3) var(--space-4);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  background:var(--surface-page);color:var(--text);
  font-size:var(--text-sm);line-height:var(--leading-sm);
  list-style:none;   /* алерт вставляется голым <li> в меню панели */
}
.ui-alert:has(> svg){grid-template-columns:var(--icon) 1fr}
.ui-alert > svg{width:var(--icon);height:var(--icon);translate:0 2px;color:currentColor}
.ui-alert-title{
  grid-column-start:2;
  min-height:var(--icon);font-weight:var(--weight-medium);
}
.ui-alert-description{
  grid-column-start:2;
  display:grid;gap:var(--space-1);
  color:var(--text-muted);
}
/* была белая карточка на почти белой панели: 1.07 к подложке,
   граница 1.27, тени нет — видимым оставался только красный текст */
.ui-alert[data-variant="destructive"]{
  color:var(--danger);
  background:var(--danger-soft);
  border-color:var(--danger);
}
.ui-alert[data-variant="destructive"] .ui-alert-description{
  color:color-mix(in oklab, var(--danger) 85%, var(--text));
}

/* =============================================================
   EMPTY
   ============================================================= */
.ui-empty{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:var(--space-6);min-width:0;
  padding:var(--space-6);
  border-radius:var(--radius-lg);
  text-align:center;text-wrap:balance;
}
.ui-empty-header{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);max-width:24rem}
.ui-empty-media{
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
  width:var(--control-h-lg);height:var(--control-h-lg);margin-bottom:var(--space-2);
  border:1px solid var(--line);border-radius:var(--radius-lg);
  background:var(--surface-sunk);color:var(--text-muted);
}
.ui-empty-media svg{width:var(--icon-lg);height:var(--icon-lg)}
.ui-empty-title{font-size:var(--text-lg);line-height:var(--leading-lg);font-weight:var(--weight-medium)}
.ui-empty-description{font-size:var(--text-sm);line-height:var(--leading-prose);color:var(--text-muted)}
.ui-empty-content{
  display:flex;flex-direction:column;align-items:center;gap:var(--space-4);
  width:100%;max-width:24rem;min-width:0;
  font-size:var(--text-sm);text-wrap:balance;
}

/* =============================================================
   TOOLTIP
   Подсказка на CSS: триггер несёт data-tooltip="текст".
   Якорь задаётся атрибутом, потому что обе подсказки верхней
   полосы обрезались контейнерами (.app-inset{overflow-x:clip}
   и body{overflow-x:hidden}): тема на 20px справа, кнопка
   панели на 27px слева.
   ============================================================= */
.ui-tooltip-trigger{position:relative}
.ui-tooltip-trigger::after{
  content:attr(data-tooltip);
  position:absolute;top:calc(100% + var(--space-2));left:50%;
  z-index:var(--z-tooltip);
  translate:-50% 0;
  width:max-content;
  max-width:min(14rem, calc(100vw - 2 * var(--space-3)));
  padding:var(--space-1_5) var(--space-3);
  border-radius:var(--radius-md);
  background:var(--text);color:var(--surface-page);
  font-size:var(--text-xs);line-height:1.125rem;font-weight:var(--weight-normal);
  text-wrap:balance;
  opacity:0;pointer-events:none;
  scale:.95;
  transition:opacity var(--duration) var(--ease-out), scale var(--duration) var(--ease-out);
}
.ui-tooltip-trigger[data-tooltip-align="start"]::after{left:0;translate:0}
.ui-tooltip-trigger[data-tooltip-align="end"]::after{left:auto;right:0;translate:0}

/* показ по наведению — только там, где есть настоящий курсор:
   на тач-экране первое касание иначе уходит в показ подсказки */
@media (hover:hover) and (pointer:fine){
  .ui-tooltip-trigger:hover::after{opacity:1;scale:1;transition-delay:var(--delay-tooltip)}
}
.ui-tooltip-trigger:focus-visible::after{opacity:1;scale:1}

/* =============================================================
   TYPOGRAPHY (.ui-prose)
   Оформление любого Markdown: и страницы группы, и разделов
   панели. Кегль наследуется от контейнера, всё внутри считается
   в em — поэтому один класс работает и в мелкой панели, и в
   основной колонке.

   Ритм собран на токенах --flow-*. Было 13 разных отступов, и
   межабзацный 12px вдвое меньше межстрочного 27.2px: абзацы не
   читались как абзацы.
   ============================================================= */
.ui-prose{color:var(--text);line-height:var(--leading-prose);text-wrap:pretty}
.ui-prose > *:first-child{margin-top:0}
.ui-prose > *:last-child{margin-bottom:0}

.ui-prose p{margin:0 0 var(--flow-p)}

.ui-prose h1,.ui-prose h2,.ui-prose h3,
.ui-prose h4,.ui-prose h5,.ui-prose h6{
  margin:var(--flow-h-top) 0 var(--flow-h-bot);
  font-weight:var(--weight-semibold);
  line-height:var(--leading-tight);
  color:var(--text);
  text-wrap:balance;
  hyphens:none;
}
/* трекинг — оптическая поправка на крупный кегль; ниже 24px
   поправлять нечего, а на кириллице подрезка смыкает счётные
   просветы (и, ш, щ, м, н, п, ц) в частокол */
.ui-prose h1{font-size:var(--prose-h1);letter-spacing:-.014em}
.ui-prose h2{font-size:var(--prose-h2)}
.ui-prose h3{font-size:var(--prose-h3)}
.ui-prose h4,.ui-prose h5,.ui-prose h6{font-size:1em}

.ui-prose ul,.ui-prose ol{margin:0 0 var(--flow-p);padding-left:var(--flow-indent)}
.ui-prose li{margin:0 0 var(--flow-li)}
.ui-prose li::marker{color:var(--text-muted)}
.ui-prose ul ul,.ui-prose ol ol,.ui-prose ul ol,.ui-prose ol ul{margin:var(--flow-li) 0 0}
.ui-prose li.task{list-style:none;margin-left:calc(-1 * var(--flow-indent))}
.ui-prose li.task input{margin:0 .45em 0 0;accent-color:var(--brand)}

.ui-prose a{
  color:var(--brand);
  text-decoration:underline;
  text-underline-offset:4px;
  text-decoration-thickness:1px;
  text-decoration-color:color-mix(in oklab, var(--brand) 40%, transparent);
  border-radius:var(--radius-sm);
  transition:text-decoration-color var(--duration) var(--ease-in-out);
}
.ui-prose a:hover{text-decoration-color:currentColor}

.ui-prose strong{font-weight:var(--weight-semibold);color:var(--text)}

.ui-prose code{
  font-family:var(--font-mono);font-size:var(--prose-code);
  padding:.125em .35em;border-radius:var(--radius-sm);
  background:var(--surface-sunk);color:var(--text);
  hyphens:none;
}
.ui-prose pre{
  margin:0 0 var(--flow-p);padding:.75em 1em;overflow-x:auto;
  border:1px solid var(--line);border-radius:var(--radius-lg);
  background:var(--surface-sunk);
  font-size:var(--prose-code);line-height:var(--leading-prose);
  hyphens:none;
}
.ui-prose pre code{padding:0;background:none;font-size:1em}

.ui-prose blockquote{
  margin:0 0 var(--flow-p);padding:.5em 0 .5em 1em;
  border-left:2px solid var(--edge);   /* было --line 1.27, цитата не читалась */
  color:var(--text-muted);
}

.ui-prose hr{border:0;border-top:1px solid var(--line);margin:var(--flow-block) 0}

/* Таблицу оборачивает .ui-prose-scroll (markdown.js). Без обёртки
   таблица шире колонки не прокручивалась, а обрезалась:
   body{overflow-x:hidden} плюс .app-inset{overflow-x:clip}.
   Проверено: 5 столбцов на экране 375px — пятый был недостижим. */
.ui-prose-scroll{
  overflow-x:auto;
  margin:0 0 var(--flow-p);
  overscroll-behavior-x:contain;
}
/* внутри обёртки таблица меряется по содержимому, а не по колонке:
   при width:100% браузер сжимал её до ширины колонки, а неразрывное
   «28.09.2026» вылезало из ячейки — прокрутки не возникало,
   и правый столбец пропадал молча */
.ui-prose-scroll > table{margin:0;width:max-content;min-width:100%}
.ui-prose table{
  width:100%;border-collapse:collapse;
  margin:0 0 var(--flow-p);font-size:var(--prose-small);
}
.ui-prose th,.ui-prose td{
  padding:.5em .6em;text-align:left;vertical-align:top;
  border-bottom:1px solid var(--line);
  hyphens:none;
}
.ui-prose th{font-weight:var(--weight-medium);color:var(--text)}
.ui-prose tbody tr:last-child td{border-bottom:0}

.ui-prose img{max-width:100%;height:auto;border-radius:var(--radius-md)}

/* формула отдельным блоком */
.ui-prose .eq{
  margin:var(--flow-block) 0;text-align:center;
  overflow-x:auto;overflow-y:hidden;
  hyphens:none;
}
.ui-prose .katex{color:inherit}
.ui-prose .katex-display{margin:0 !important}

/* =============================================================
   ДВИЖЕНИЕ: уважение к системной настройке
   Универсальным блоком, а не списком селекторов: прежние два
   списка отстали от кода (не покрывали пять переходов), гасили
   только длительность, и задержка подсказки 250ms переживала
   выключенное движение.
   ============================================================= */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    transition-delay:0s !important;
    scroll-behavior:auto !important;
  }
}
