/* ============================================================
   Serg Store — дизайн-система «Liquid Glass»
   Общий фундамент витрины, кабинетов, тарифов и админки.
   Подключается ПЕРВЫМ: задаёт токены, базовые элементы и
   примитивы стекла. Компонентные стили — в файлах экранов.

   Zero-dep, только системные шрифты. Никаких инлайн-стилей:
   динамика (акцент темы, радиус кнопок) приходит из JS через
   setProperty на :root — имена переменных менять нельзя.
   ============================================================ */

:root {
  color-scheme: light;

  /* ---------- Типографика ----------
     Системный стек: SF Pro на Apple, Segoe UI Variable на Windows.
     Размеры текучие: одно правило обслуживает 320px и 2560px. */
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI Variable Text",
          "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-display: -apple-system, BlinkMacSystemFont, "SF Pro Display",
          "Segoe UI Variable Display", "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --text-xs:   clamp(11.5px, 0.28vw + 10.7px, 12.5px);
  --text-sm:   clamp(13px,   0.30vw + 12.1px, 14px);
  --text-base: clamp(15px,   0.32vw + 14.0px, 16px);
  --text-md:   clamp(16.5px, 0.42vw + 15.2px, 18px);
  --text-lg:   clamp(19px,   0.85vw + 16.3px, 24px);
  --text-xl:   clamp(24px,   1.60vw + 18.9px, 34px);
  --text-2xl:  clamp(30px,   2.60vw + 21.7px, 48px);

  --tracking-tight: -0.022em;
  --tracking-display: -0.032em;

  /* ---------- Шкала отступов (4px база) ---------- */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;
  --sp-5: 20px;  --sp-6: 24px;  --sp-8: 32px;  --sp-10: 40px;
  --sp-12: 48px; --sp-16: 64px; --sp-20: 80px;

  /* ---------- Радиусы ----------
     Крупнее, чем в «плоском» вебе: стекло читается как физический
     материал только на больших скруглениях (логика iOS/visionOS). */
  --r-xs: 10px;  --r-sm: 14px;  --r-md: 18px;
  --r-lg: 24px;  --r-xl: 30px;  --r-2xl: 38px;  --r-pill: 999px;

  /* ---------- Палитра (светлая) ---------- */
  --accent: #5423E7;
  /* R, G, B акцента через запятую — для rgba(var(--accent-rgb), α) в
     кнопках (.btn/.cta/.box button, см. storefront.css). color-mix() тут
     не подходит: getComputedStyle() сериализует его результат как
     color(srgb ...), а не rgba(...) — реальный контраст остаётся верным,
     но regex-парсер в research/check-a11y.mjs понимает только rgb()/rgba()
     и в этом случае не находит фон кнопки вовсе (ложный провал аудита).
     lib/render.js и storefront.js пересчитывают эту переменную вместе
     с --accent, когда владелец задаёт свой цвет. */
  --accent-rgb: 84, 35, 231;
  --accent-text: #ffffff;
  /* Акцент как ЦВЕТ ТЕКСТА. На светлом фоне это сам акцент (8:1), но на
     тёмном он даёт 2.6:1 — ниже порога AA, поэтому в тёмной схеме
     осветляется. Заливки продолжают использовать --accent. */
  --accent-ink: var(--accent);
  --bg: #F2F2F7;                       /* systemGroupedBackground */
  --card: #ffffff;
  --text: #12121a;
  --muted: #5c5c68;                    /* 6.4:1 на --card, 6.0:1 на --bg */
  --line: rgba(20, 20, 32, 0.10);
  --line-strong: rgba(20, 20, 32, 0.16);

  --ok: #128a4d;
  --warn: #9a5b00;
  --danger: #c22a2a;

  /* ---------- Стекло ----------
     Материал выводится из --card, а не из фиксированного белого: тему
     витрины задаёт владелец магазина (JS ставит --card/--text на :root),
     и стекло обязано следовать за ней, иначе светлая панель встретится
     со светлым текстом. Прозрачность вынесена отдельным токеном, чтобы
     экран мог усилить материал, не переписывая фон (см. .glass-strong). */
  --glass-alpha: 68%;
  --glass-alpha-strong: 84%;
  --glass-blur: 22px;
  --glass-blur-lg: 40px;
  --glass-sat: 175%;
  --glass-bg: color-mix(in srgb, var(--card) var(--glass-alpha), transparent);
  --glass-border: color-mix(in srgb, #fff 62%, transparent);
  --glass-border-soft: color-mix(in srgb, #fff 40%, transparent);

  /* Спекулярный блик: тонкая светлая кромка сверху + затухание вниз.
     Это то, что отличает «стекло» от «полупрозрачного прямоугольника». */
  --glass-specular: inset 0 1px 0 rgba(255, 255, 255, 0.75),
                    inset 0 -1px 0 rgba(255, 255, 255, 0.18);

  --shadow-1: 0 1px 2px rgba(18, 16, 38, 0.05), 0 6px 16px rgba(18, 16, 38, 0.06);
  --shadow-2: 0 2px 6px rgba(18, 16, 38, 0.06), 0 14px 34px rgba(18, 16, 38, 0.10);
  --shadow-3: 0 8px 20px rgba(18, 16, 38, 0.10), 0 30px 70px rgba(18, 16, 38, 0.16);

  --ring: 0 0 0 4px color-mix(in srgb, var(--accent) 32%, transparent);

  /* ---------- Liquid Glass Button ----------
     Общий «преломляющий» кант кнопок (виджет 21st.dev, адаптированный под
     токены темы владельца). Один составной box-shadow переиспользуется всеми
     кнопочными компонентами (.btn, .cta, .box button) через var(), поэтому
     сама разметка теней живёт в одном месте. Тёмная кромка на светлой
     подложке, светлая — на тёмной (см. переопределение ниже). */
  --glass-btn-ring:
    0 0 6px rgba(0, 0, 0, 0.03),
    0 2px 6px rgba(0, 0, 0, 0.08),
    inset 3px 3px 0.5px -3px rgba(0, 0, 0, 0.9),
    inset -3px -3px 0.5px -3px rgba(0, 0, 0, 0.85),
    inset 1px 1px 1px -0.5px rgba(0, 0, 0, 0.6),
    inset -1px -1px 1px -0.5px rgba(0, 0, 0, 0.6),
    inset 0 0 6px 6px rgba(0, 0, 0, 0.12),
    inset 0 0 2px 2px rgba(0, 0, 0, 0.06),
    0 0 12px rgba(255, 255, 255, 0.15);

  /* ---------- Движение ---------- */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-1: 0.16s;
  --dur-2: 0.28s;
  --dur-3: 0.44s;

  /* ---------- Каркас ---------- */
  --page-max: 480px;                   /* колонка витрины */
  --wide-max: 1080px;                  /* широкие экраны (тарифы, кабинет) */
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);

  /* Радиус кнопок задаётся темой магазина из JS. */
  --radius-btn: 14px;
  --radius-card: var(--r-lg);
}

/* ---------- Тёмная тема ----------
   Схему выбирает пользователь: /theme.js ставит на <html> data-theme со
   значением light или dark (разрешая «системную» в момент применения) и
   делает это синхронно в <head>, до первой отрисовки — иначе страница
   мигнёт светлым. Правило ниже — единственный источник тёмной палитры.

   Запасной вариант для случая, когда скрипт не отработал (ошибка сети,
   выключенный JS): системная схема через media-запрос по data-theme,
   которого ещё нет. Так тёмная тема остаётся доступной без JS.

   Меняем материал, а не только цвета: в темноте блик слабее, иначе
   кромка стекла «светится» неестественно ярко. */
/* Явный выбор пользователя (и «системная», уже разрешённая скриптом). */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0b0b0f;
  --card: #17171d;
  --text: #f4f4f7;
  --muted: #a1a1ad;
  --line: rgba(255, 255, 255, 0.12);
  --line-strong: rgba(255, 255, 255, 0.20);
  --glass-alpha: 66%;
  --glass-alpha-strong: 82%;
  --glass-border: rgba(255, 255, 255, 0.16);
  --glass-border-soft: rgba(255, 255, 255, 0.10);
  --glass-specular: inset 0 1px 0 rgba(255, 255, 255, 0.18),
                    inset 0 -1px 0 rgba(255, 255, 255, 0.05);
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 6px 16px rgba(0, 0, 0, 0.34);
  --shadow-2: 0 2px 6px rgba(0, 0, 0, 0.45), 0 14px 34px rgba(0, 0, 0, 0.42);
  --shadow-3: 0 8px 20px rgba(0, 0, 0, 0.5), 0 30px 70px rgba(0, 0, 0, 0.55);
  --accent-ink: color-mix(in srgb, var(--accent) 38%, #ffffff);
  --ok: #34c77b;
  --warn: #e0a02a;
  --danger: #ff6b6b;
  /* Тёмная схема: кромка светлая (преломление на тёмном стекле), внешнее
     свечение — чёрное, а не белое. */
  --glass-btn-ring:
    0 0 6px rgba(255, 255, 255, 0.04),
    0 2px 10px rgba(0, 0, 0, 0.4),
    inset 3px 3px 0.5px -3px rgba(255, 255, 255, 0.9),
    inset -3px -3px 0.5px -3px rgba(255, 255, 255, 0.85),
    inset 1px 1px 1px -0.5px rgba(255, 255, 255, 0.6),
    inset -1px -1px 1px -0.5px rgba(255, 255, 255, 0.6),
    inset 0 0 6px 6px rgba(255, 255, 255, 0.12),
    inset 0 0 2px 2px rgba(255, 255, 255, 0.06),
    0 0 14px rgba(0, 0, 0, 0.5);
}

/* Фолбэк без JS: пока атрибута нет, схему диктует система. Значения
   продублированы намеренно — в CSS нет способа переиспользовать блок
   объявлений в двух разных условиях, а вводить лишний слой переменных
   ради этого дороже, чем держать две копии рядом. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
    --bg: #0b0b0f;
    --card: #17171d;
    --text: #f4f4f7;
    --muted: #a1a1ad;
    --line: rgba(255, 255, 255, 0.12);
    --line-strong: rgba(255, 255, 255, 0.20);
    --glass-alpha: 66%;
    --glass-alpha-strong: 82%;
    --glass-border: rgba(255, 255, 255, 0.16);
    --glass-border-soft: rgba(255, 255, 255, 0.10);
    --glass-specular: inset 0 1px 0 rgba(255, 255, 255, 0.18),
                      inset 0 -1px 0 rgba(255, 255, 255, 0.05);
    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 6px 16px rgba(0, 0, 0, 0.34);
    --shadow-2: 0 2px 6px rgba(0, 0, 0, 0.45), 0 14px 34px rgba(0, 0, 0, 0.42);
    --shadow-3: 0 8px 20px rgba(0, 0, 0, 0.5), 0 30px 70px rgba(0, 0, 0, 0.55);
    --accent-ink: color-mix(in srgb, var(--accent) 38%, #ffffff);
    --ok: #34c77b;
    --warn: #e0a02a;
    --danger: #ff6b6b;
    --glass-btn-ring:
      0 0 6px rgba(255, 255, 255, 0.04),
      0 2px 10px rgba(0, 0, 0, 0.4),
      inset 3px 3px 0.5px -3px rgba(255, 255, 255, 0.9),
      inset -3px -3px 0.5px -3px rgba(255, 255, 255, 0.85),
      inset 1px 1px 1px -0.5px rgba(255, 255, 255, 0.6),
      inset -1px -1px 1px -0.5px rgba(255, 255, 255, 0.6),
      inset 0 0 6px 6px rgba(255, 255, 255, 0.12),
      inset 0 0 2px 2px rgba(255, 255, 255, 0.06),
      0 0 14px rgba(0, 0, 0, 0.5);
  }
}

/* ---------- Переключатель схемы ----------
   Сегментированный контрол: три состояния видны сразу, выбранное
   подсвечено заливкой, а не только цветом иконки. */

.theme-switch {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--card) 55%, transparent);
  border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(14px) saturate(var(--glass-sat));
  backdrop-filter: blur(14px) saturate(var(--glass-sat));
}

.theme-switch-btn {
  appearance: none;
  border: 0;
  cursor: pointer;
  /* 32px + отступы контейнера дают цель ≥ 24×24 CSS-пикселей (WCAG 2.5.8) */
  min-width: 34px;
  min-height: 32px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: var(--text-sm);
  line-height: 1;
  transition: background-color var(--dur-1) var(--ease-out),
              color var(--dur-1) var(--ease-out);
}

.theme-switch-btn:hover { color: var(--text); }

.theme-switch-btn[aria-checked="true"] {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent-ink);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #fff 35%, transparent);
}

.theme-switch-ico { font-size: 14px; }

/* ============================================================
   База
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100dvh;
  font-family: var(--font);
  font-size: var(--text-base);
  line-height: 1.5;
  color: var(--text);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Фоновая среда: две мягкие «ауры» из акцента магазина. Стеклу нужно
   что-то, что оно преломляет, — на плоской заливке материал не читается.
   Слой фиксирован и не участвует в скролле, поэтому не влияет на layout. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* Пятна компактные и насыщенные, центр экрана остаётся чистым:
     равномерная заливка «съедает» материал — панель перестаёт
     отличаться от подложки, и стекло читается как плоский блок. */
  background:
    radial-gradient(clamp(220px, 26vw, 520px) clamp(200px, 22vw, 460px) at 6% -4%,
      color-mix(in srgb, var(--accent) 40%, transparent), transparent 74%),
    radial-gradient(clamp(200px, 22vw, 440px) clamp(200px, 22vw, 440px) at 99% 2%,
      color-mix(in srgb, var(--accent) 30%, transparent), transparent 72%),
    radial-gradient(clamp(220px, 24vw, 480px) clamp(160px, 18vw, 360px) at 84% 98%,
      color-mix(in srgb, var(--accent) 20%, transparent), transparent 74%),
    radial-gradient(clamp(180px, 20vw, 380px) clamp(160px, 18vw, 340px) at 2% 92%,
      color-mix(in srgb, var(--accent) 18%, transparent), transparent 74%);
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  letter-spacing: var(--tracking-display);
  line-height: 1.12;
  text-wrap: balance;
}

p { text-wrap: pretty; }

button, input, select, textarea { font-family: inherit; font-size: inherit; }

img, svg, video { max-width: 100%; }

/* Цены и счётчики не должны «прыгать» при пересчёте. */
.num, .card-price, .modal-price, .quote-total, .stat-value {
  font-variant-numeric: tabular-nums;
}

::selection {
  background: color-mix(in srgb, var(--accent) 28%, transparent);
  color: var(--text);
}

/* Единое кольцо фокуса на всех экранах: видимое на стекле и на карточке. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

/* ============================================================
   Примитивы стекла
   ============================================================ */

.glass,
.glass-strong {
  position: relative;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-specular), var(--shadow-2);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-sat));
}

.glass-strong {
  --glass-alpha: var(--glass-alpha-strong);
  -webkit-backdrop-filter: blur(var(--glass-blur-lg)) saturate(var(--glass-sat));
  backdrop-filter: blur(var(--glass-blur-lg)) saturate(var(--glass-sat));
}

/* Диагональный блик поверх материала. Оставлен отдельным классом:
   он рисуется псевдоэлементом, а значит стоит кадр композитинга. */
.glass-sheen::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(140deg,
    rgba(255, 255, 255, 0.34) 0%,
    rgba(255, 255, 255, 0.06) 34%,
    transparent 62%);
}

/* Волосяная линия-разделитель: 0.5px там, где экран это умеет. */
.hairline { border-bottom: 1px solid var(--line); }
@media (min-resolution: 2dppx) {
  .hairline { border-bottom-width: 0.5px; }
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   Деградация материала

   Стекло — украшение, а не носитель смысла. Каждый сценарий, где
   backdrop-filter недоступен или нежелателен, получает плотную
   поверхность с тем же контрастом текста.
   ============================================================ */

/* 1. Браузер без backdrop-filter (или отключённый на слабом железе). */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass, .glass-strong {
    background: color-mix(in srgb, var(--card) 94%, var(--bg));
  }
}

/* 2. Пользователь просил меньше прозрачности (iOS Reduce Transparency). */
@media (prefers-reduced-transparency: reduce) {
  .glass, .glass-strong {
    background: var(--card);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .glass-sheen::after { display: none; }
  body::before { opacity: 0.35; }
  /* Преломление кнопок (.btn/.cta/.box button, см. storefront.css,
     pricing.css, offline.css) — тот же принцип: убираем размытие/искажение,
     заливка остаётся плотной, кромка — обычной тенью. */
  .btn, .cta, .box button {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* 3. Повышенный контраст: кромка становится настоящей границей. */
@media (prefers-contrast: more) {
  :root {
    --line: rgba(20, 20, 32, 0.28);
    --line-strong: rgba(20, 20, 32, 0.45);
    --glass-alpha: 0.94;
    --glass-alpha-strong: 0.98;
    --glass-border: var(--line-strong);
  }
  body::before { opacity: 0.25; }
}

/* 4. Меньше движения — убираем всё, кроме мгновенной смены состояния. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* 5. Печать: ни стекла, ни аур. */
@media print {
  body::before { display: none; }
  .glass, .glass-strong {
    background: #fff;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}
