/* Reset + базовая типографика поверх tokens.css */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  line-height: var(--lh-normal);
  color: var(--text-primary);
  background: var(--bg-body);
  -webkit-font-smoothing: antialiased;
  /* Резиновый оттяг браузера при скролле до края — то, что сильнее всего
     выдаёт "это открыто в браузере, а не в приложении" на телефоне.
     contain — гасит именно оттяг всей страницы, но не мешает вложенным
     областям (модалки, .sotiks-tree и т.п.) прокручиваться и упираться в
     свой собственный край как обычно. */
  overscroll-behavior-y: contain;
  /* Синяя/серая вспышка при тапе на iOS/Android — свои :active-состояния
     заданы у .btn/.card и т.п. по всему UI-киту, системная подсветка поверх
     них только мешает. */
  -webkit-tap-highlight-color: transparent;
}

/* Разрешённая браузерами навигация между документами через View Transitions
   (Chrome/Edge 126+, без единой строчки JS — Safari/Firefox тихо
   игнорируют неизвестное правило) — обычный переход по ссылке между
   страницами сайта плавно перекрёстно затухает вместо жёсткого "мигания"
   белым между загрузками. Тот же API (document.startViewTransition),
   которым уже пользуется переключатель темы (sotiks-dark-mode/assets/js/
   toggle.js) для кругового reveal — тут просто его декларативная
   MPA-версия, без ручного вызова. */
@view-transition {
  navigation: auto;
}
/* Страховка: в блочных темах цвет фона страницы нередко сохранён отдельно
   от файлов темы — через Появление → Редактор → Стили (wp_global_styles в
   базе), рендерится как отдельный <style id="global-styles-inline-css">
   ПОЗЖЕ этого файла в <head> и при той же специфичности (обычный `body{}`)
   побеждает по порядку каскада, даже если там просто зафиксирован белый
   пресетный цвет, а не var(--bg-body). !important здесь узко — работает
   только при активной тёмной теме, светлую ничем не перекрывает. */
html[data-theme="dark"] body {
  background: var(--bg-body) !important;
  color: var(--text-primary) !important;
}

/*
 * [hidden] — браузерная UA-таблица стилей задаёт [hidden]{display:none} с
 * самым низким приоритетом каскада: ЛЮБОЕ авторское правило с display:
 * (а у большинства компонентов UI-кита оно есть — .btn{display:inline-flex},
 * .badge, .card и т.д.) всегда его перебивает, независимо от специфичности
 * и даже без !important с авторской стороны — дело в происхождении
 * правила (author beats UA), не в specificity. Практический эффект:
 * <button class="btn ..." hidden> (или el.hidden = true в JS) — кнопка
 * остаётся видна, хотя атрибут hidden честно проставлен. Этот баг находили
 * и чинили точечно уже несколько раз в разных плагинах (.kanban,
 * .kanban-col--archive, .stk-checklist-body в sotiks-tasks) — здесь один
 * общий фикс на уровне самого UI-кита, а не на каждый компонент отдельно.
 */
[hidden] { display: none !important; }

/* Индикатор "потяни, чтобы обновить" (assets/js/pull-to-refresh.js) — сам
   элемент создаётся и позиционируется через transform из JS, тут только
   внешний вид кружка и анимация спиннера/готовности. В покое сдвинут на
   64px вверх за экран (совпадает с REST_OFFSET в JS) — раньше состояние
   покоя было ровно на top:0 и оставалось видимым/"зависшим", если что-то
   ещё (топбар) переставало его перекрывать, например при автоскрытии
   топбара на скролле. */
.sotiks-ptr-indicator {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translate(-50%, -64px);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--bg-surface);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-sm, 0 1px 3px rgba(0,0,0,.15));
  z-index: 2000;
  pointer-events: none;
}
.sotiks-ptr-indicator svg { width: 18px; height: 18px; }
.sotiks-ptr-indicator.is-ready { color: var(--brand, #2563eb); }
.sotiks-ptr-indicator.is-spinning svg { animation: sotiks-ptr-spin .6s linear infinite; }
@keyframes sotiks-ptr-spin { to { transform: rotate(360deg); } }

img, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }
h1, h2, h3, h4, p { margin: 0; }
button { cursor: pointer; background: none; border: none; }

h1 { font-size: var(--fs-3xl); font-weight: 700; line-height: var(--lh-tight); }
h2 { font-size: var(--fs-2xl); font-weight: 700; line-height: var(--lh-tight); }
h3 { font-size: var(--fs-xl); font-weight: 600; line-height: var(--lh-tight); }

.text-muted { color: var(--text-muted); }
.text-secondary { color: var(--text-secondary); }
.text-sm { font-size: var(--fs-sm); }
.text-xs { font-size: var(--fs-xs); }

:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
  transition: box-shadow var(--dur-fast) var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  .page-content { animation: none; }
  .btn:not(:disabled):active { transform: none; }
  .bottom-nav-item:active { transform: none; }
  .checkbox::after { transition: none; }
}

/* тонкий скроллбар для панелей */
.scroll-thin { scrollbar-width: thin; scrollbar-color: var(--border-default) transparent; }
.scroll-thin::-webkit-scrollbar { width: 6px; height: 6px; }
.scroll-thin::-webkit-scrollbar-thumb { background: var(--border-default); border-radius: var(--radius-pill); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
