/* Theme-пресеты витрины. Подключается в storefront/_layout.html ПОСЛЕ
   storefront.css → переопределяет токены при равной/большей специфичности.
   Не Tailwind — править можно без пересборки storefront.css.

   :root = нейтральный светлый дефолт (для apex/404 без preset-* класса).
   Каждый .preset-<id> задаёт расширенный контракт:
     цвет:  --bg --surface --text --muted --accent --cta-bg --cta-text --tile-bg
     шрифт: --font (тело) --font-display (заголовки) --display-transform
            --display-weight --display-stretch
     форма: --radius (карточки) --btn-radius (кнопки)
   Инлайн style="--accent: …" на <body> (из partner.theme.accent_hex)
   рендерится ТОЛЬКО если партнёр задал свой акцент (см. _layout.html);
   иначе действует --accent самого пресета (Pop=неон, Arena=лайм).

   ⚠ --sf-err/--sf-ok/--sf-warn(+ -bg) (базовая формула — storefront.input.css
   :root) ПЕРЕОБЪЯВЛЕНЫ здесь заново в КАЖДОМ .preset-* блоке — не дубликат,
   а необходимость: custom-property var()-подстановка резолвится в скоупе
   элемента, где сам производный токен объявлен, а не в скоупе элемента-
   потребителя. Раз --sf-err объявлен только на :root, он навсегда
   «замораживается» на :root-значениях --text/--surface и не видит --text/
   --surface, переопределённые на <body class="preset-*">, даже если ниже
   по дереву кто-то читает var(--sf-err). Поэтому при добавлении нового
   .preset-<id> ОБЯЗАТЕЛЬНО скопировать туда же блок --sf-err/-ok/-warn(+-bg)
   (шаблон — в любом из существующих .preset-* ниже). */

/* ── Self-host шрифты (woff2 в app/static/fonts/, CSP-safe, без CDN) ────────── */
@font-face { font-family: "Plus Jakarta Sans"; src: url("/static/fonts/PlusJakartaSans-Variable.woff2") format("woff2"); font-weight: 200 800; font-display: swap; }
@font-face { font-family: "Figtree"; src: url("/static/fonts/Figtree-Variable.woff2") format("woff2"); font-weight: 300 900; font-display: swap; }
@font-face { font-family: "Manrope"; src: url("/static/fonts/Manrope-Variable.woff2") format("woff2"); font-weight: 200 800; font-display: swap; }
@font-face { font-family: "Overpass Mono"; src: url("/static/fonts/OverpassMono-Variable.woff2") format("woff2"); font-weight: 300 700; font-display: swap; }
@font-face { font-family: "Archivo"; src: url("/static/fonts/Archivo-Variable.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "Inter"; src: url("/static/fonts/Inter-Variable.woff2") format("woff2"); font-weight: 100 900; font-display: swap; }
@font-face { font-family: "Shrikhand"; src: url("/static/fonts/Shrikhand-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Oswald"; src: url("/static/fonts/Oswald-Variable.woff2") format("woff2"); font-weight: 200 700; font-display: swap; }
/* Unbounded — кириллический жирный дисплей ТОЛЬКО для кириллицы Pop-темы.
   Shrikhand (латиница) кириллицы не имеет; unicode-range держит Unbounded строго
   на кириллице, латиница остаётся на Shrikhand как задумано дизайном.
   font-weight 600 800: при --display-weight:400 браузер клампит к 600 = жирный. */
@font-face { font-family: "Unbounded"; src: url("/static/fonts/Unbounded-Cyrillic.woff2") format("woff2"); font-weight: 600 800; font-display: swap; unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; }
@font-face { font-family: "Unbounded"; src: url("/static/fonts/Unbounded-CyrillicExt.woff2") format("woff2"); font-weight: 600 800; font-display: swap; unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; }
/* Archivo Expanded — статический Black (900), только latin/latin-ext (fw-teardown
   Creator, 2026-07-10). Кириллицы НЕ содержит (проверено на живом FW-магазине и
   в Google Fonts) — --font-display падает на Unbounded выше по стеку для
   кириллических символов (unicode-range у Unbounded это уже гарантирует). */
@font-face { font-family: "Archivo Expanded"; src: url("/static/fonts/ArchivoExpanded-Black.woff2") format("woff2"); font-weight: 900; font-style: normal; font-display: swap; }

:root {
  --bg: #ffffff;
  --surface: #ffffff;
  --text: #171717;
  --muted: #525252;
  --accent: #0F0F0F;
  --cta-bg: #000000;
  --cta-text: #ffffff;
  --tile-bg: #efefef;
  --font: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: "Geist", ui-sans-serif, system-ui, sans-serif;
  --display-transform: none;
  --display-weight: 700;
  --display-stretch: normal;
  --radius: 0.375rem;
  --btn-radius: 0.375rem;
}

/* Базовый page-gutter секций (эталон FW: .wrapper, hero/rich-text styles.css
   — padding-right/left:16px, @media(min-width:640px) 32px). До сих пор
   .store-container не нёс ни одного правила вне .preset-oasis/.preset-creator
   — на остальных пресетах (gallery/craft/drop/pop/arena) текст секций упирался
   в край экрана на узких вьюпортах. Специфичность здесь (0,1,0) ниже, чем у
   .preset-oasis .store-container / .preset-creator .store-container (0,2,0,
   свои паддинги 16/32 при 768px по их FW-спеке) — те продолжают побеждать
   независимо от порядка правил. [data-section-full] .store-container.store-
   container в storefront.css — тоже (0,2,0) и грузится ДО presets.css —
   аналогично побеждает по специфичности и снимает паддинги для full-width. */
.store-container {
  padding-left: 16px;
  padding-right: 16px;
}
@media (min-width: 640px) {
  .store-container {
    padding-left: 32px;
    padding-right: 32px;
  }
}

.preset-gallery {
  --bg: #ffffff; --surface: #ffffff; --text: #0a0a0a; --muted: #6b6b6b;
  --accent: #000000; --cta-bg: #000000; --cta-text: #ffffff; --tile-bg: #efefef;
  --font: "Figtree", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Plus Jakarta Sans", "Figtree", sans-serif;
  --display-transform: none; --display-weight: 700; --display-stretch: normal;
  --radius: 0px; --btn-radius: 0px;
  --sf-err: color-mix(in srgb, #ff5c5c 55%, var(--text) 45%);
  --sf-ok: color-mix(in srgb, #10b981 55%, var(--text) 45%);
  --sf-warn: color-mix(in srgb, #d97706 55%, var(--text) 45%);
  --sf-err-bg: color-mix(in srgb, var(--sf-err) 14%, var(--surface));
  --sf-ok-bg: color-mix(in srgb, var(--sf-ok) 14%, var(--surface));
  --sf-warn-bg: color-mix(in srgb, var(--sf-warn) 14%, var(--surface));
}

/* Oasis — 1:1 клон FW-темы Oasis (fw-teardown, 2026-07-10). Токены — зеркало
   .preset-gallery (тот же белый/чёрный/Figtree/Plus Jakarta), отличия:
   --tile-bg сероватее (≈ rgba(0,0,0,.1) на белом = оригинальный fw-фон под
   фото товара) и --display-weight:600 (Plus Jakarta Sans 600, не 700).
   Структурные оверрайды (жёсткие px для сетки/фото/кнопок/хедера/hero/
   футера, которые нельзя доверить var(--card-gap) и т.п. — см. комментарий
   там) — отдельным блоком в конце файла, после generic-правил. */
.preset-oasis {
  --bg: #ffffff; --surface: #ffffff; --text: #000000; --muted: #6b6b6b;
  --accent: #000000; --cta-bg: #000000; --cta-text: #ffffff; --tile-bg: #e6e6e6;
  --font: "Figtree", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Plus Jakarta Sans", "Figtree", sans-serif;
  --display-transform: none; --display-weight: 600; --display-stretch: normal;
  --radius: 0px; --btn-radius: 0px;
  --sf-err: color-mix(in srgb, #ff5c5c 55%, var(--text) 45%);
  --sf-ok: color-mix(in srgb, #10b981 55%, var(--text) 45%);
  --sf-warn: color-mix(in srgb, #d97706 55%, var(--text) 45%);
  --sf-err-bg: color-mix(in srgb, var(--sf-err) 14%, var(--surface));
  --sf-ok-bg: color-mix(in srgb, var(--sf-ok) 14%, var(--surface));
  --sf-warn-bg: color-mix(in srgb, var(--sf-warn) 14%, var(--surface));
}

/* Creator — 1:1 клон FW-темы Creator (fw-teardown, 2026-07-10). Токены —
   та же тёмная палитра, что Drop (bg/surface/text/accent идентичны — оба
   near-black с D8D7D1), отличия: --tile-bg прозрачный (товар лежит прямо на
   фоне страницы, а не на плашке), дисплейный шрифт Archivo Expanded (не
   Archivo) + Unbounded-фолбэк для кириллицы, --display-weight:900 (см.
   комментарий у самой переменной ниже — почему это безопасно для Unbounded),
   --display-stretch:normal (файл уже статически «expanded» — в отличие от
   Drop, где стретч 125% симулируется на вариативном Archivo). Структурные
   оверрайды (hero-коллаж/карточка/футер/заголовок коллекции) — отдельным
   блоком в конце файла. */
.preset-creator {
  --bg: #161616; --surface: #1E1E1E; --text: #D8D7D1; --muted: #8F8E89;
  --accent: #D8D7D1; --cta-bg: #D8D7D1; --cta-text: #161616; --tile-bg: transparent;
  --font: "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Archivo Expanded", "Unbounded", sans-serif;
  /* --display-weight:900 (было 800, раунд 4 фикс, pixel-parity — метрики
     home/pdp/cart дают 900 везде). Безопасно для кириллицы:
     Unbounded объявлен с font-weight:600 800 (см. @font-face выше), запрос
     900 клампится к тому же 800 — рендер не меняется, только computed-
     style теперь честно 900. На латинице Archivo Expanded Black — 900. */
  --display-transform: uppercase; --display-weight: 900; --display-stretch: normal;
  --radius: 0px; --btn-radius: 0px;
  --sf-err: color-mix(in srgb, #ff5c5c 55%, var(--text) 45%);
  --sf-ok: color-mix(in srgb, #10b981 55%, var(--text) 45%);
  --sf-warn: color-mix(in srgb, #d97706 55%, var(--text) 45%);
  --sf-err-bg: color-mix(in srgb, var(--sf-err) 14%, var(--surface));
  --sf-ok-bg: color-mix(in srgb, var(--sf-ok) 14%, var(--surface));
  --sf-warn-bg: color-mix(in srgb, var(--sf-warn) 14%, var(--surface));
}

.preset-craft {
  --bg: #F4F1EB; --surface: #FBF9F5; --text: #4C3C2F; --muted: #8A7867;
  --accent: #4C3C2F; --cta-bg: #4C3C2F; --cta-text: #F4F1EB; --tile-bg: #EAE5DA;
  --font: "Overpass Mono", ui-monospace, "Cascadia Code", Consolas, monospace;
  --font-display: "Manrope", ui-sans-serif, system-ui, sans-serif;
  --display-transform: none; --display-weight: 700; --display-stretch: normal;
  --radius: 0px; --btn-radius: 0px;
  --sf-err: color-mix(in srgb, #ff5c5c 55%, var(--text) 45%);
  --sf-ok: color-mix(in srgb, #10b981 55%, var(--text) 45%);
  --sf-warn: color-mix(in srgb, #d97706 55%, var(--text) 45%);
  --sf-err-bg: color-mix(in srgb, var(--sf-err) 14%, var(--surface));
  --sf-ok-bg: color-mix(in srgb, var(--sf-ok) 14%, var(--surface));
  --sf-warn-bg: color-mix(in srgb, var(--sf-warn) 14%, var(--surface));
}

.preset-drop {
  --bg: #161616; --surface: #1E1E1E; --text: #D8D7D1; --muted: #8F8E89;
  --accent: #D8D7D1; --cta-bg: #D8D7D1; --cta-text: #161616; --tile-bg: #222222;
  --font: "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Archivo", "Inter", sans-serif;
  --display-transform: uppercase; --display-weight: 900; --display-stretch: 125%;
  --radius: 0px; --btn-radius: 0px;
  --sf-err: color-mix(in srgb, #ff5c5c 55%, var(--text) 45%);
  --sf-ok: color-mix(in srgb, #10b981 55%, var(--text) 45%);
  --sf-warn: color-mix(in srgb, #d97706 55%, var(--text) 45%);
  --sf-err-bg: color-mix(in srgb, var(--sf-err) 14%, var(--surface));
  --sf-ok-bg: color-mix(in srgb, var(--sf-ok) 14%, var(--surface));
  --sf-warn-bg: color-mix(in srgb, var(--sf-warn) 14%, var(--surface));
}

.preset-pop {
  --bg: #ffffff; --surface: #ffffff; --text: #0a0a0a; --muted: #5a5a5a;
  --accent: #EDFF80; --cta-bg: var(--accent); --cta-text: #000000; --tile-bg: #E6E6E6;
  --font: "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Shrikhand", "Unbounded", "Inter", cursive;
  --display-transform: none; --display-weight: 400; --display-stretch: normal;
  --radius: 0px; --btn-radius: 0px;
  --sf-err: color-mix(in srgb, #ff5c5c 55%, var(--text) 45%);
  --sf-ok: color-mix(in srgb, #10b981 55%, var(--text) 45%);
  --sf-warn: color-mix(in srgb, #d97706 55%, var(--text) 45%);
  --sf-err-bg: color-mix(in srgb, var(--sf-err) 14%, var(--surface));
  --sf-ok-bg: color-mix(in srgb, var(--sf-ok) 14%, var(--surface));
  --sf-warn-bg: color-mix(in srgb, var(--sf-warn) 14%, var(--surface));
}

.preset-arena {
  --bg: #1C1D21; --surface: #26272C; --text: #ffffff; --muted: rgba(255,255,255,0.6);
  --accent: #CCE52F; --cta-bg: var(--accent); --cta-text: #1C1D21;
  --tile-bg: rgba(255,255,255,0.08);
  --font: "Inter", ui-sans-serif, system-ui, sans-serif;
  --font-display: "Oswald", "Inter", sans-serif;
  --display-transform: none; --display-weight: 600; --display-stretch: normal;
  --radius: 0.75rem; --btn-radius: 100px;
  --sf-err: color-mix(in srgb, #ff5c5c 55%, var(--text) 45%);
  --sf-ok: color-mix(in srgb, #10b981 55%, var(--text) 45%);
  --sf-warn: color-mix(in srgb, #d97706 55%, var(--text) 45%);
  --sf-err-bg: color-mix(in srgb, var(--sf-err) 14%, var(--surface));
  --sf-ok-bg: color-mix(in srgb, var(--sf-ok) 14%, var(--surface));
  --sf-warn-bg: color-mix(in srgb, var(--sf-warn) 14%, var(--surface));
}

/* ── Generic-правила, читающие переменные пресета ──────────────────────────── */

/* Заголовочный шрифт. Только h1/h2 и явный .sf-display, чтобы не трогать
   мелкие h3 (имена товаров остаются на body-шрифте). */
[class*="preset-"] h1,
[class*="preset-"] h2,
[class*="preset-"] .sf-display {
  font-family: var(--font-display, var(--font));
  text-transform: var(--display-transform, none);
  font-weight: var(--display-weight, 700);
  font-stretch: var(--display-stretch, normal);
}

/* CTA-кнопка: фон/текст из пресета (Pop/Arena — акцент-неон/лайм + тёмный текст,
   Drop — светлая, Gallery — чёрная). Специфичность (0,2,0) > .btn-primary (0,1,0). */
[class*="preset-"] .btn-primary {
  background: var(--cta-bg, var(--accent));
  color: var(--cta-text, #ffffff);
}

/* Радиус кнопок управляется пресетом отдельно от карточек (Arena — пилюли). */
[class*="preset-"] .btn-primary,
[class*="preset-"] .btn-outline {
  border-radius: var(--btn-radius, var(--radius));
}

/* Плитка товара под мокап: отдельный фон, чтобы изделие не «висело» на тёмных
   темах. Навешивается на .sf-surface плитки в _group_card.
   --tile-op — непрозрачность подложки (ползунок «Прозрачность фона фото»
   кабинета печатает 100−N%); без него подложка сплошная, как раньше. */
.sf-tile {
  background: color-mix(in srgb, var(--tile-bg, var(--surface)) var(--tile-op, 100%), transparent);
}

/* Лого по центру для Arena (cart остаётся справа абсолютом). */
.preset-arena header .store-container { position: relative; justify-content: center; }
.preset-arena header .store-container > a[aria-label="Открыть корзину"] {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
}

/* ── fw-teardown №9, §5.4 — редактор витрины: Product cards / Photography /
   Social links. Токены рендерятся как CSS custom properties на <body>
   (_layout.html, из partner.theme.*) — здесь только читаем их. Файл
   подключается ПОСЛЕ storefront.css (см. шапку файла), поэтому любое
   правило тут при равной специфичности перебивает Tailwind-утилиты
   (aspect-square, gap-*, mt-*) без правки собранного storefront.css. ──── */

/* Photography: аспект фото + скругление углов плитки карточки и главного
   фото PDP. Дефолты (1/1, 0px) совпадают с прежним aspect-square/без
   радиуса — партнёр без кастомизации не видит разницы. */
.sf-tile,
.pdp-photo {
  aspect-ratio: var(--photo-ratio, 1 / 1);
  /* Фолбэк — радиус самой темы, а не 0: до 2026-08-08 это правило целиком
     съедалось оборванным комментарием выше и никогда не применялось, поэтому
     плитки жили на --radius пресета. Возвращаем его как значение по умолчанию,
     иначе «оживление» правила само по себе сделало бы углы острыми. */
  border-radius: var(--card-radius, var(--radius, 0px));
}

/* Product cards: единый зазор между карточками во всех гридах витрины
   (домашняя/хиты/категория/коллекция — класс sf-grid добавлен на каждый).
   Дефолт 16px — тот же, что уже был на мобильном gap-4/gap-x-4. */
.sf-grid { gap: var(--card-gap, 16px); }

/* Product cards: размер карточки. card-regular — статус-кво (без правил
   здесь, Tailwind-дефолты как раньше). card-compact — плотнее упаковка. */
.card-compact .sf-tile { padding: 0.375rem; }
.card-compact .sf-card h3 { font-size: 0.8125rem; line-height: 1.3; }
.card-compact .sf-card > div + div { margin-top: 0.5rem; }

/* Product cards: показ цветовых свотчей. Разметки самих свотчей на карточке
   пока нет (отдельная нереализованная фича) — класс готов на будущее,
   сейчас no-op (партнёр видит тумблер, но скрывать нечего). */
.hide-swatches .sf-swatches { display: none; }

/* Product cards: скрыть бейдж акции/дропа («Скоро»/«Тираж идёт»/«Завершён» —
   .sf-promo-badge в _group_card.html). Бейджи sold-out/«+N вариантов» — это
   товарная информация, не промо — остаются видимыми при любом значении. */
.hide-badges .sf-promo-badge { display: none; }

/* Product cards: подпись под фото (имя/цена/свотчи — див-сосед .sf-tile).
   Выравнивание и гарнитура из кабинета; фолбэк здесь = прежний вид базовых
   пресетов (текст слева, шрифт наследуется). Живые темы Oasis/Creator ниже
   по каскаду читают тот же --card-align со своим фолбэком (по центру) —
   партнёрский выбор побеждает в обоих случаях. */
[class*="preset-"] .sf-tile + div {
  text-align: var(--card-align, left);
  font-family: var(--card-ff, inherit);
}

/* Раскладка карточек («Центрировать карточки» / «Подпись поверх фото») живёт в
   конце файла — темы задают свои отступы подписи той же специфичностью. */

/* Product cards: второе фото при наведении. Owner-decision fw-teardown №9
   §6.2 — фича временно ДРЕМЛЕТ (fw-teardown витрина-плитка, под-этап A):
   плитка теперь показывает одну картинку — готовую одежду спереди
   (group.front_mockup_url или print_url), второго <img> для свапа в
   разметке нет (нет фото спины). Тумблер card_show_hover_photo сохранён
   на будущее — под-этап B вернёт настоящий hover-свап перёд→спина, когда
   появятся фото спины, и этот класс снова станет активным. Правило ниже
   той же специфичности, что базовый .group-hover-swap:hover в
   storefront.css, и стоит позже в каскаде (presets.css подключается
   вторым тегом <link>) → по умолчанию гасит свап; .card-hover-photo
   переопределяет обратно при явном opt-in. */
@media (hover: hover) {
  .group-hover-swap:hover > img:first-child { opacity: 1; }
  .group-hover-swap:hover > img:last-child { opacity: 0; }
  .card-hover-photo .group-hover-swap:hover > img:first-child { opacity: 0; }
  .card-hover-photo .group-hover-swap:hover > img:last-child { opacity: 1; }
}

/* Соцсети в футере (_footer.html + _social_icons.html). Пустой список —
   блок не рендерится вовсе (Jinja {% if %}), эти правила лечат только
   размер/hover уже отрисованных иконок. */
.sf-social-links a { display: inline-flex; align-items: center; justify-content: center; }
.sf-social-links svg { display: block; }

/* ── Oasis (fw-teardown, 2026-07-10) — структурные оверрайды, раунд 1: главная +
   /collections/all. Цветовые/шрифтовые токены — в блоке .preset-oasis выше;
   здесь — то, что нельзя выразить одними токенами: жёсткие px вместо
   var(--card-gap)/var(--photo-ratio)/var(--btn-radius), которые иначе
   управляются партнёрскими слайдерами кабинета (fw-teardown №9) и НЕ
   гарантируют точные цифры FW-оригинала. Секция размещена ПОСЛЕ generic-
   блока выше (.btn-primary/.sf-tile/.sf-grid и т.д.) НАМЕРЕННО: часть правил
   ниже той же специфичности (0,2,0), что и генерик-правила — при равенстве
   выигрывает порядок в каскаде, а не место рядом с .preset-oasis-токенами.
   Всё строго под .preset-oasis — ноль влияния на другие пресеты. */

/* Контейнер: full-width БЕЗ max-width (в отличие от остальных пресетов, где
   .store-container теперь несёт только базовый page-gutter 16/32@640px —
   см. правило у :root в начале файла). Паддинги здесь 16/32@768px — Oasis
   держит свой FW-контракт брейкпоинта, специфичность (0,2,0) побеждает
   базовое (0,1,0) независимо от порядка правил. */
.preset-oasis .store-container {
  max-width: none;
  padding-left: 16px;
  padding-right: 16px;
}
@media (min-width: 768px) {
  .preset-oasis .store-container {
    padding-left: 32px;
    padding-right: 32px;
  }
}

/* Карточка товара: фото 3:4 (перекрывает var(--photo-ratio) от партнёрского
   слайдера «Пропорции фото» — в Oasis всегда 3:4 по FW-спеке), плоское поле
   без hairline-ring/тени, острые углы (radius:0 уже из токена, здесь border/
   shadow явно гасим — .sf-surface на этом же div даёт border+box-shadow).
   Hover-лифт карточки (translateY+shadow, общий для остальных пресетов)
   тоже гасим — Oasis плоский, никакой тени даже на hover. */
.preset-oasis .sf-tile {
  aspect-ratio: var(--photo-ratio, 3 / 4);
  box-shadow: none;
  border: none;
  border-radius: var(--card-radius, 0);
}
.preset-oasis .sf-card:hover {
  transform: none;
  box-shadow: none;
}
/* Описание карточки (имя/цена/свотчи) — по центру, имя 16px. У div'а под
   фото в _group_card.html нет своего класса-крючка — цепляемся за соседство
   с .sf-tile (сама разметка НЕ меняется ни в одном пресете). */
.preset-oasis .sf-tile + div {
  text-align: var(--card-align, center);
}
.preset-oasis .sf-tile + div h3 {
  font-size: 16px;
}
.preset-oasis .sf-tile + div .sf-swatches {
  justify-content: center;
}

/* Сетка товаров: 32px везде (перекрывает var(--card-gap) от партнёрского
   слайдера «Зазор между карточками» — в Oasis всегда 32px по FW-спеке). */
.preset-oasis .sf-grid {
  gap: var(--card-gap, 32px);
}

/* Заголовок страницы (.sf-page-title — «All Products» на /collections/all,
   а заодно cart/checkout/thanks: единая типографика в рамках пресета,
   намеренно не сузили селектор). 28px мобайл → 40px десктоп по FW-спеке. */
.preset-oasis .sf-page-title {
  font-size: 28px;
}
@media (min-width: 768px) {
  .preset-oasis .sf-page-title {
    font-size: 40px;
  }
}

/* Кнопки: primary — сплошная чёрная, secondary (.btn-outline) — прозрачная
   с рамкой 2px; острые углы (--btn-radius:0 из токена + explicit ниже —
   .btn-radius и .btn-outline делят (0,2,0) с generic-правилом, побеждает
   порядок в каскаде), без uppercase. Hover — просто opacity (FW-семантика),
   а НЕ translateY-lift + усиленная тень остальных пресетов (сырой CSS в
   storefront.input.css, тоже (0,2,0) на .btn-primary:hover — гасим явно). */
.preset-oasis .btn-primary,
.preset-oasis .btn-outline {
  min-height: 48px;
  padding: 0 16px;
  border-width: 2px;
  border-style: solid;
  border-radius: 0;
  font-weight: 700;
  font-size: 16px;
  line-height: 1.5;
  text-transform: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: none;
}
.preset-oasis .btn-primary {
  background: var(--cta-bg);
  color: var(--cta-text);
  border-color: var(--cta-bg);
}
.preset-oasis .btn-outline {
  background: transparent;
  color: var(--text);
  border-color: var(--text);
}
.preset-oasis .btn-primary:hover,
.preset-oasis .btn-outline:hover {
  transform: none;
  box-shadow: none;
  filter: none;
  opacity: 0.8;
}
.preset-oasis .btn-outline:hover {
  opacity: 0.6;
}
.preset-oasis .btn-primary:active,
.preset-oasis .btn-outline:active {
  transform: none;
}

/* Хедер: одна строка (лого слева / нав по центру / корзина справа) — грид на
   .sf-oasis-header__row (крючки из _header.html, ветка preset_id=='oasis';
   остальные пресеты рендерят прежнюю двухрядную разметку без этих классов —
   правило здесь пустое для них). Фон/граница уже плоские через саму
   разметку (inline style в шаблоне) — тут только геометрия грида. */
/* Грид хедера общий для обоих FW-пресетов, которые используют разметку
   .sf-oasis-header__* (_header.html, ветка preset_id in ('oasis','creator')).
   Высоту/шрифты каждый пресет доопределяет у себя (у Creator — 89px ниже). */
.preset-oasis .sf-oasis-header__row,
.preset-creator .sf-oasis-header__row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  column-gap: 16px;
  height: 85px;
}
.preset-oasis .sf-oasis-header__logo,
.preset-creator .sf-oasis-header__logo { grid-column: 1; justify-self: start; }
.preset-oasis .sf-oasis-header__nav,
.preset-creator .sf-oasis-header__nav {
  grid-column: 2;
  display: flex;
  align-items: center;
  gap: 20px;
  overflow-x: auto;
  white-space: nowrap;
}
.preset-oasis .sf-oasis-header__cart,
.preset-creator .sf-oasis-header__cart { grid-column: 3; justify-self: end; }

/* Hero: заголовок 64px по центру (мобайл 28px), паддинг секции 70/70,
   контент max-width 933px. Крючки — в _hero.html, ветка preset_id=='oasis'. */
.preset-oasis .sf-oasis-hero__inner {
  padding-top: 70px;
  padding-bottom: 70px;
}
.preset-oasis .sf-oasis-hero__content {
  max-width: 933px;
}
.preset-oasis h1[data-theme-hero-title] {
  font-size: 28px;
  line-height: 1.2;
}
@media (min-width: 768px) {
  .preset-oasis h1[data-theme-hero-title] {
    font-size: 64px;
  }
}

/* Hero → каталог (раунд 3, полиш 2026-07-11): у FW-темы oasis секция
   каталога следует СРАЗУ за hero (секция категорий между ними отключена),
   поэтому собственный верхний отступ каталога складывается с нижним отступом
   hero в заметный «провал». Поджимаем ТОЛЬКО верх каталога — FW-мереную
   геометрию самого hero не трогаем. На прочих пресетах между hero и каталогом
   есть tile-row категорий, там обычный отступ уместен → гейт по пресету.
   ⚠ Creator НЕ входит сюда (раунд 4, pixel-parity): nikkykash-метрика для той
   же структуры даёт свои 36/48, а не поджатые.
   Обновлено 2026-08-11: базовый отступ каталога теперь py-9 sm:py-12
   (36/48 на 640px, эталон FW), а не прежние py-12 md:py-16 (48/64 на 768px) —
   поджатие снизу остаётся тем же приёмом, только считается от новых чисел.
   Брейкпоинт здесь тоже переведён на 640px, чтобы поджатие включалось
   одновременно с самим отступом, а не на 128px позже. */
.preset-oasis #catalog {
  padding-top: 12px;
}
@media (min-width: 640px) {
  .preset-oasis #catalog {
    padding-top: 20px;
  }
}

/* Секция «Хиты» на главной (раунд 2, fw-teardown 2026-07-10): заголовок +
   CTA «Смотреть все» в одну строку (flex/justify-between/items-center уже
   на самом div в _section_featured.html, здесь только зазор), заголовок
   40px desktop / 28px mobile — как .sf-page-title, отдельный хук-класс,
   чтобы не тянуть 40px на реальный .sf-page-title (cart/checkout и т.п.). */
.preset-oasis .sf-oasis-featured__header {
  gap: 16px;
}
.preset-oasis .sf-oasis-featured__title {
  font-size: 28px;
  line-height: 1.2;
}
@media (min-width: 768px) {
  .preset-oasis .sf-oasis-featured__title {
    font-size: 40px;
  }
}

/* Футер: паддинг-топ 44 / низ 14, обе строки прижаты влево, ссылки НАД
   копирайтом. Реордер БЕЗ изменения разметки _footer.html: первый div внутри
   .store-container уже flex flex-col md:flex-row md:justify-between —
   форсим всегда-колонку+влево, а order:-1 у <nav> поднимает ссылки над
   строкой бренд/копирайт (копирайт уже на sf-muted — приглушён по спеке). */
.preset-oasis footer .store-container {
  padding-top: 44px;
  padding-bottom: 14px;
}
.preset-oasis footer .store-container > div:first-child {
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-start;
  gap: 16px;
}
.preset-oasis footer .store-container > div:first-child > nav {
  order: -1;
}

/* ── apex-prose ───────────────────────────────────────────────────────────────
   Типографика тела статейных apex-страниц (apex/_article.html → .apex-prose).
   Plain CSS (НЕ Tailwind) — правится без пересборки storefront.css, не
   пёрджится. Все цвета через токены пресета → корректно и на classic.
   Только базовая ритмика; страничные агенты могут добавлять utility-классы. */
.apex-prose { line-height: 1.7; }
.apex-prose > * + * { margin-top: 1.15em; }
.apex-prose h2 {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.25;
  margin-top: 2em;
}
.apex-prose h3 {
  font-size: 1.2rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-top: 1.6em;
}
.apex-prose p,
.apex-prose ul,
.apex-prose ol { color: var(--text); }
.apex-prose ul,
.apex-prose ol { padding-left: 1.4em; }
.apex-prose ul { list-style: disc; }
.apex-prose ol { list-style: decimal; }
.apex-prose li + li { margin-top: 0.4em; }
.apex-prose a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.apex-prose strong { font-weight: 600; }

/* ── Coming Soon-сплэш (fw-teardown №13, §5.3) ──────────────────────────────
   Plain CSS (НЕ Tailwind) — правится без пересборки storefront.css.
   coming_soon.html — standalone-шаблон (не extends _layout.html), поэтому
   переиспользует только токены пресета (--bg/--surface/--text/--muted/
   --accent/--radius) + .sf-surface/.sf-input/.btn-primary/.sf-social-links,
   уже определённые в storefront.css. */
.sf-cs { min-height: 100vh; padding: 24px; }
.sf-cs__card {
  width: 100%;
  max-width: 30rem;
  padding: 40px 32px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}
.sf-cs__logo img { max-height: 48px; max-width: 220px; object-fit: contain; }
.sf-cs__logo-text { font-size: 1.25rem; font-weight: 700; }
.sf-cs__headline { font-size: 1.75rem; line-height: 1.2; margin: 0; }
.sf-cs__subheadline { margin: 0; font-size: 0.9375rem; line-height: 1.5; }

.sf-cs__countdown {
  padding: 10px 20px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.sf-cs__form {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-top: 4px;
}
.sf-cs__form .sf-input { flex: 1 1 220px; padding: 0.65rem 0.85rem; }
.sf-cs__form .btn-primary { flex: 0 0 auto; }
.sf-cs__form-msg { flex-basis: 100%; margin: 0; font-size: 0.8125rem; color: var(--muted); }
.sf-cs__form-msg.is-err { color: #dc2626; }

/* Honeypot: невидимо людям, доступно ботам, которые заполняют все поля
   формы вслепую (не display:none/visibility:hidden — некоторые боты их
   игнорируют, offscreen-приём надёжнее). */
.sf-cs__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.sf-cs__visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
}

.sf-cs__socials { justify-content: center; margin-top: 4px; }

/* ── Creator (fw-teardown, 2026-07-10) — структурные оверрайды, раунд 1:
   главная + /collections/all. Цветовые/шрифтовые токены — в блоке
   .preset-creator выше; здесь — геометрия, которую нельзя выразить одними
   токенами (жёсткие px спеки FW-оригинала: контейнер/hero-коллаж/карточка/
   хедер/футер/заголовок коллекции). Всё строго под .preset-creator — ноль
   влияния на другие пресеты, включая Oasis (его классы sf-oasis-… и
   структурный блок выше не переиспользуются, кроме .sf-oasis-header__row —
   геометрия хедера намеренно расширена на Creator ниже).

   ⚠ Не писать в CSS-комментарии глоб-паттерны вида sf-oasis-* со слэшем
   следом: пара «звёздочка + слэш» закрывает комментарий досрочно, и
   следующее за ним правило браузер выбрасывает как мусор. Именно так
   правило .store-container ниже месяц не доезжало до мобильной витрины. */

/* Контейнер: сам по себе full-width, паддинги 16/32 — так у эталона живут
   хедер, футер, hero и товарные сетки ГЛАВНОЙ (все они на 3072px тянутся во
   всю ширину: header__grid / footer__inner / col-grid = viewport − 2×32).

   ⚠ Но контент внутренних страниц у эталона НЕ full-width: он лежит в
   .container.wrapper с max-width:1440px и центрируется. На вьюпорте ровно
   1440 этот потолок неотличим от full-width — а слепки снимали именно на
   1440, поэтому потолок и потеряли: на широком мониторе владельца карточка
   товара и коллекции растягивались во всю ширину. Потому потолки ниже —
   и потому в capture_fw.py добавлен вьюпорт wide=3072. */
.preset-creator .store-container {
  max-width: none;
  padding-left: 16px;
  padding-right: 16px;
}
@media (min-width: 768px) {
  .preset-creator .store-container {
    padding-left: 32px;
    padding-right: 32px;
  }
}

/* Потолок контента внутренних страниц (эталон: .container.wrapper = 1440px,
   центрирован; проверено на wide-слепках collections/pdp/cart). Корзина,
   чекаут и контакты держат свои, более узкие потолки в per-page CSS
   (1136 / 1160 / 664) — здесь только страницы без собственного. */
.preset-creator .sf-creator-wrap,
.preset-creator .sf-creator-collection,
.preset-creator .sf-pdp-hero-pad,
.preset-creator .sf-pdp-related-pad,
.preset-creator .sf-creator-upsell {
  max-width: 1440px;
  margin-left: auto;
  margin-right: auto;
}

/* Хедер: геометрия .sf-oasis-header__row переиспользуется (крючки общие с
   Oasis, разметка идентична — см. _header.html), но высота другая (89px
   против 85px у Oasis) и фон/border задаются в самом шаблоне (var(--bg),
   без рамки) — здесь только высота грида. Текстовое лого — дисплейный
   шрифт 30px uppercase (крючок [data-theme-logo-fallback], общий для всех
   пресетов, здесь переопределяем размер/шрифт). Нав — Inter 400 (обычный,
   не font-medium) по FW-спеке. */
.preset-creator .sf-oasis-header__row {
  height: 89px;
}
@media (max-width: 767px) {
  /* nikkykash mobile: header rect=0,0 390x64 — было 89px без мобильного
     сужения (раунд 4 фикс, pixel-parity). */
  .preset-creator .sf-oasis-header__row {
    height: 64px;
  }
}
.preset-creator [data-theme-logo-fallback] {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  text-transform: uppercase;
  font-size: 30px;
  letter-spacing: 0;
  /* nikkykash desktop: line-height 36px @ font-size 30px (ratio 1.2) —
     раунд 4 фикс, наследовался Tailwind text-xl (28px). */
  line-height: 1.2;
}
.preset-creator .sf-oasis-header__nav a {
  font-weight: 400;
}

/* Кнопки: primary сплошная (bg/text из токенов --cta-bg/--cta-text),
   secondary (.btn-outline) прозрачная с рамкой 2px, острые углы, БЕЗ
   uppercase текста кнопки (спека описывает только заголовки как uppercase).
   Базовый размер (--base у FW): 48px/0 16px. Hero-CTA — модификатор
   --large: 56px/0 20px (см. .sf-creator-hero__cta ниже). Копия геометрии
   Oasis (тот же FW-контракт кнопок), пересобранная под .preset-creator,
   чтобы не зависеть от каскадного порядка между двумя классами пресетов. */
.preset-creator .btn-primary,
.preset-creator .btn-outline {
  min-height: 48px;
  padding: 0 16px;
  border-width: 2px;
  border-style: solid;
  border-radius: 0;
  font-weight: 700;
  font-size: 16px;
  line-height: 1.5;
  text-transform: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: none;
}
.preset-creator .btn-primary {
  background: var(--cta-bg);
  color: var(--cta-text);
  border-color: var(--cta-bg);
}
.preset-creator .btn-outline {
  background: transparent;
  color: var(--text);
  border-color: var(--text);
}
.preset-creator .btn-primary:hover,
.preset-creator .btn-outline:hover {
  transform: none;
  box-shadow: none;
  filter: none;
  opacity: 0.8;
}
.preset-creator .btn-outline:hover { opacity: 0.6; }
.preset-creator .btn-primary:active,
.preset-creator .btn-outline:active { transform: none; }

/* Hero: секция padding 48px 0, контейнер flex 2 колонки max-width 91.5%.
   Левая колонка 50% (100% если нет hero-фото — модификатор --full), правая
   50% с коллажем. Крючки — в _hero.html, ветка preset_id == 'creator'. */
.preset-creator .sf-creator-hero {
  padding: 48px 0;
}
.preset-creator .sf-creator-hero__inner {
  display: flex;
  align-items: center;
  max-width: 91.5%;
  margin: 0 auto;
  flex-wrap: wrap;
}
.preset-creator .sf-creator-hero__left {
  flex: 0 0 50%;
  max-width: 50%;
  padding: 0 32px;
  position: relative;
  z-index: 1;
  box-sizing: border-box;
}
.preset-creator .sf-creator-hero__left--full {
  flex: 0 0 100%;
  max-width: 100%;
}
.preset-creator .sf-creator-hero__title {
  font-size: 48px;
  line-height: 1.1;
  text-align: left;
  margin: 0;
}
.preset-creator .sf-creator-hero__subtitle {
  margin: 16px 0 0;
  text-align: left;
  color: var(--muted);
}
.preset-creator .sf-creator-hero__cta-wrap {
  margin-top: 32px;
}
.preset-creator .sf-creator-hero__cta.btn-primary {
  /* Крупный вариант CTA. Множители темы (аккордеон «Кнопки») применяем и
     здесь — у правила специфичность (0,3,0), общий блок в конце файла его
     не перебивает, и без calc ползунки «Высота/Ширина» обошли бы hero-кнопку. */
  min-height: calc(56px * var(--btn-h, 1));
  padding: 0 calc(20px * var(--btn-w, 1));
}
.preset-creator .sf-creator-hero__right {
  flex: 0 0 50%;
  max-width: 50%;
  margin-top: 48px;
  box-sizing: border-box;
}

/* Hero-коллаж: обёртка шире колонки (125%, сдвиг -25% влево), внутри —
   квадрат с двумя наклонённым фото + полупрозрачная подложка (var(--text)
   6% opacity). Оба фото — object-fit:cover, без радиуса. Фото №2
   отсутствует в разметке, если partner.theme.hero_image_2_url не задан
   (см. _hero.html) — .collage__img--2 просто не рендерится, подложка +
   фото №1 остаются. */
.preset-creator .sf-creator-collage-wrap {
  width: 125%;
  left: -25%;
  position: relative;
  padding: 0 16px;
  box-sizing: border-box;
}
.preset-creator .sf-creator-collage {
  position: relative;
  padding-bottom: 64.5%;
}
.preset-creator .sf-creator-collage__bg {
  position: absolute;
  inset: 0;
  background: var(--text);
  opacity: 0.06;
  transition: transform 1s ease;
}
.preset-creator .sf-creator-collage__img {
  position: absolute;
  overflow: hidden;
  /* Hover-анимация коллажа — чистый CSS transition + :hover ниже (точная
     копия FW Creator theme.scss.css, НЕ mousemove-параллакс). */
  transition: transform 600ms ease;
  will-change: transform;
}
.preset-creator .sf-creator-collage__img img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 0;
  display: block;
}
/* ⚠ padding-bottom в процентах считается от ШИРИНЫ containing block
   (.sf-creator-collage), а не от собственной ширины элемента. Пропорция фото
   2:3 у FW даёт 548.5px при ширине коллажа 791.5px = 69.3% (а не 150.3%,
   как если бы процент брался от ширины самого фото). */
.preset-creator .sf-creator-collage__img--1 {
  left: 23.4%;
  top: -7.5%;
  width: 46.1%;
  padding-bottom: 69.3%;
  transform: rotate(-10deg);
}
.preset-creator .sf-creator-collage__img--2 {
  left: 59.8%;
  top: 20.6%;
  width: 31.1%;
  padding-bottom: 46.8%;
  transform: rotate(15deg);
}
/* Hover-анимация — точная копия FW Creator (theme.scss.css): при наведении на
   ВЕСЬ коллаж подложка ужимается, оба фото масштабируются и доворачиваются.
   Значения 1:1 с FW: bg scale(0.97); фото1 scale(1.03) rotate(-15deg);
   фото2 scale(1.15) rotate(20deg). Чистый CSS, без JS. */
.preset-creator .sf-creator-collage:hover .sf-creator-collage__bg {
  transform: scale(0.97);
}
.preset-creator .sf-creator-collage:hover .sf-creator-collage__img--1 {
  transform: scale(1.03) rotate(-15deg);
}
.preset-creator .sf-creator-collage:hover .sf-creator-collage__img--2 {
  transform: scale(1.15) rotate(20deg);
}
@media (prefers-reduced-motion: reduce) {
  /* Без движения: гасим transition и держим hover на базовых трансформах. */
  .preset-creator .sf-creator-collage__img,
  .preset-creator .sf-creator-collage__bg {
    transition: none;
  }
  .preset-creator .sf-creator-collage:hover .sf-creator-collage__bg {
    transform: none;
  }
  .preset-creator .sf-creator-collage:hover .sf-creator-collage__img--1 {
    transform: rotate(-10deg);
  }
  .preset-creator .sf-creator-collage:hover .sf-creator-collage__img--2 {
    transform: rotate(15deg);
  }
}
/* Мобильный (FW: заголовок и кнопка по центру, коллаж под ними, в пределах
   ширины экрана). ⚠ В flex-column `flex: 0 0 100%` задаёт ВЫСОТУ, не ширину,
   а `align-items: center` от десктопа ужимает колонки по контенту — правая
   колонка схлопывалась в точку. Поэтому здесь явные width:100% + align: stretch
   и коллаж возвращается в границы колонки (width:100%, left:0). */
@media (max-width: 767px) {
  .preset-creator .sf-creator-hero__inner {
    flex-direction: column;
    align-items: stretch;
    max-width: 100%;
  }
  .preset-creator .sf-creator-hero__left,
  .preset-creator .sf-creator-hero__left--full,
  .preset-creator .sf-creator-hero__right {
    flex: 0 0 auto;
    width: 100%;
    max-width: 100%;
  }
  /* 16px (было 32px наследованное от десктопного .sf-creator-hero__left) —
     nikkykash mobile: hero__heading rect x=16 — тот же гаттер, что и у
     остального контента (раунд 4 фикс). */
  .preset-creator .sf-creator-hero__left,
  .preset-creator .sf-creator-hero__left--full {
    padding: 0 16px;
  }
  /* 48px (было 32px) — nikkykash mobile: buttons-container bottom 250 →
     hero__collage top 298 (раунд 4 фикс, pixel-parity). */
  .preset-creator .sf-creator-hero__right { margin-top: 48px; }
  .preset-creator .sf-creator-hero__title { font-size: 36px; text-align: center; }
  .preset-creator .sf-creator-hero__subtitle { text-align: center; }
  .preset-creator .sf-creator-hero__cta-wrap {
    display: flex;
    justify-content: center;
  }
  .preset-creator .sf-creator-collage-wrap {
    width: 100%;
    left: 0;
  }
  /* Длинное текстовое лого не должно ломаться на три строки в 3-колоночном гриде. */
  .preset-creator [data-theme-logo-fallback] { font-size: 18px; }
}

/* Карточка товара: фото 3:4, фон прозрачный (--tile-bg уже transparent через
   токен — .sf-tile { background: var(--tile-bg) } общий на все пресеты),
   плоское поле без hairline/тени/радиуса, hover без лифта (как Oasis —
   Creator тоже плоский FW-стиль). Описание — по центру, имя 16px Inter 400. */
.preset-creator .sf-tile {
  aspect-ratio: var(--photo-ratio, 3 / 4);
  box-shadow: none;
  border: none;
  border-radius: var(--card-radius, 0);
  /* Фото встык с краями тайла, без внутреннего инсета (FW: tile__item img
     rect == container rect). _group_card.html несёт Tailwind p-2 (общий для
     всех пресетов, не гейтить) — гасим только здесь (раунд 4 фикс). */
  padding: 0;
}
.preset-creator .sf-card:hover {
  transform: none;
  box-shadow: none;
}
/* FW-спека: a.tile { padding-bottom: 40px } — у FW это внешний анкор карточки
   (фото + описание внутри одного <a>), у нас эквивалент — .sf-card (внешний
   <a>), а не .sf-tile (внутренний фото-бокс). Даёт итоговые 72px между рядами
   грида (32px gap + 40px), как в оригинале. */
.preset-creator .sf-card {
  padding-bottom: 40px;
}
.preset-creator .sf-tile + div {
  /* mt-3 в шаблоне (Tailwind, 12px) остаётся для остальных пресетов; здесь
     гасим его до 0, иначе он складывается с padding-top:24px ниже → 36px
     вместо 24px между фото и названием (раунд 2 фикс). */
  margin-top: 0;
  text-align: var(--card-align, center);
  padding: 24px 0 12px;
}
.preset-creator .sf-tile + div h3 {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.2;
}
.preset-creator .sf-tile + div .sf-swatches {
  justify-content: center;
}

/* Сетка товаров: 32px везде (перекрывает var(--card-gap) слайдера кабинета —
   в Creator всегда 32px по FW-спеке, как в Oasis). */
.preset-creator .sf-grid {
  gap: var(--card-gap, 32px);
}

/* Заголовок страницы /collections/all: 40px, по центру, margin-bottom 64px
   (десктоп; мобильные 36px/32px — раунд 4 фикс, ниже). */
.preset-creator .sf-page-title {
  font-size: 40px;
  line-height: 1.2;
  text-align: center;
  margin-bottom: 64px;
  /* Перебивает -0.025em базового .sf-page-title (storefront.input.css) —
     тот же приём, что уже стоит на .pdp-title (раунд 2 фикс, был забыт здесь). */
  letter-spacing: normal;
}
@media (max-width: 767px) {
  /* nikkykash mobile /collections/all: heading 36px, margin-bottom до сетки
     32px (heading y=91 h=86 → bottom=177; col-grid y=209) — раунд 4 фикс. */
  .preset-creator .sf-page-title {
    font-size: 36px;
    margin-bottom: 32px;
  }
}

/* Футер: всё содержимое по центру (footer--center по спеке), ссылки над
   копирайтом — тот же реордер-приём, что у Oasis (order:-1 на <nav>),
   но с center вместо flex-start. Разметка _footer.html не меняется. */
.preset-creator footer .store-container {
  padding-top: 20px;
  padding-bottom: 10px;
}
/* На мобиле эталон поджимает футер сильнее десктопа. */
@media (max-width: 767px) {
  .preset-creator footer .store-container {
    padding-top: 15px;
    padding-bottom: 8px;
  }
}
.preset-creator footer .store-container > div:first-child {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 12px;
}
.preset-creator footer .store-container > div:first-child > nav {
  order: -1;
  justify-content: center;
}
.preset-creator footer .sf-social-links {
  justify-content: center;
}
.preset-creator footer .mt-4.text-xs.sf-muted,
.preset-creator footer .sm\:hidden.mt-4.text-xs.sf-muted {
  text-align: center;
}

/* ===== Раунд 2: PDP + корзина + чекаут (docs/2026-07-10-creator-fw-template-spec.md) =====
   Точечные структурные оверрайды захардкоженных не-токенных мест. Токен-блок .preset-creator
   выше уже даёт тёмный фон/острые углы/шрифты — здесь только то, что токенами не покрывается. */

/* Общий уплощатель — чинит и cart-сводку, и панели чекаута одним правилом. */
.preset-creator .sf-surface { box-shadow: none; }
.preset-creator .sf-surface-flat { box-shadow: none; }

/* PDP: фото-бокс — прозрачный фон, без рамки/тени, пропорция 3:4 как у FW. */
.preset-creator .pdp-photo {
  aspect-ratio: var(--photo-ratio, 3 / 4);
  background: transparent;
  box-shadow: none;
  border: none;
}

/* PDP: стрелки галереи — инлайн style на элементе, поэтому !important (единственное место). */
.preset-creator .carousel-prev,
.preset-creator .carousel-next {
  border-radius: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
}

/* PDP: заголовок товара — дисплейный шрифт, uppercase, крупный кегль как у FW h1.
   Раунд 4 фикс (pixel-parity): было 40px/32px, метрика даёт 48px десктоп /
   40px мобайл (nikkykash product-info__title: 48px/900/lh57.6 desktop,
   40px/900/lh48 mobile — оба lh/fontSize = 1.2, unitless line-height
   масштабирует обе точки одной строкой). letter-spacing:normal перебивает
   Tailwind tracking-tight на h1 в group.html (эталон — letterSp:normal). */
.preset-creator .pdp-title {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  text-transform: uppercase;
  font-size: 48px;
  line-height: 1.2;
  letter-spacing: normal;
}
@media (max-width: 640px) {
  .preset-creator .pdp-title { font-size: 40px; }
}

/* PDP: цена — мелкая, не крупная (перебивает text-3xl). */
.preset-creator .pdp-price {
  font-size: 16px;
  font-weight: 400;
}

/* PDP: аккордеоны — плоские, без боксовой рамки-плашки, hairline снизу. */
.preset-creator details.sf-surface-flat {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--sf-hairline);
  border-radius: 0;
  padding-left: 0;
  padding-right: 0;
}
.preset-creator details.sf-surface-flat > summary {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: var(--display-weight);
}

/* Корзина: qty-степпер — острые углы (перебивает rounded-md). */
.preset-creator .qty-stepper {
  border-radius: 0;
}

/* Корзина: пустое состояние — по центру. */
.preset-creator .cart-empty {
  text-align: center;
}

/* Чекаут: заголовки секций — дисплейный uppercase, как остальные панели темы. */
.preset-creator .sf-panel-title {
  font-family: var(--font-display);
  text-transform: uppercase;
  font-weight: var(--display-weight);
}

/* ===== Раунд 2: PDP + корзина + чекаут (docs/2026-07-10-oasis-fw-template-spec.md) =====
   Зеркало раунда-2 Creator, но с типографикой/палитрой Oasis. Два отличия от Creator:
   фото товара — на светло-сером --tile-bg (не прозрачном); заголовки — через токен
   var(--display-transform) (=none у Oasis), НЕ хардкод uppercase. */

/* Общий уплощатель — чинит и cart-сводку, и панели чекаута одним правилом. */
.preset-oasis .sf-surface { box-shadow: none; }
.preset-oasis .sf-surface-flat { box-shadow: none; }

/* PDP: фото-бокс — светло-серое поле --tile-bg, без рамки/тени, пропорция 3:4 как у FW. */
.preset-oasis .pdp-photo {
  aspect-ratio: var(--photo-ratio, 3 / 4);
  background: color-mix(in srgb, var(--tile-bg) var(--tile-op, 100%), transparent);
  box-shadow: none;
  border: none;
}

/* PDP: стрелки галереи — инлайн style на элементе, поэтому !important (единственное место). */
.preset-oasis .carousel-prev,
.preset-oasis .carousel-next {
  border-radius: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
}

/* PDP: заголовок товара — дисплейный шрифт, transform из токена (Oasis = none), крупный кегль как у FW h1. */
.preset-oasis .pdp-title {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  text-transform: var(--display-transform);
  font-size: 40px;
  line-height: 1.2;
}
@media (max-width: 640px) {
  .preset-oasis .pdp-title { font-size: 32px; }
}

/* PDP: аккордеоны — плоские, без боксовой рамки-плашки, hairline снизу. */
.preset-oasis details.sf-surface-flat {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--sf-hairline);
  border-radius: 0;
  padding-left: 0;
  padding-right: 0;
}
.preset-oasis details.sf-surface-flat > summary {
  font-family: var(--font-display);
  text-transform: var(--display-transform);
  font-weight: var(--display-weight);
}

/* Корзина: qty-степпер — острые углы (перебивает rounded-md). */
.preset-oasis .qty-stepper {
  border-radius: 0;
}

/* Чекаут: заголовки секций — дисплейный шрифт, transform из токена. */
.preset-oasis .sf-panel-title {
  font-family: var(--font-display);
  text-transform: var(--display-transform);
  font-weight: var(--display-weight);
}

/* ══════════════════════════════════════════════════════════════════════════
   Style-аккордеон кабинета (паритет с FW «Style», 2026-08-07).
   Цвета/шрифты приходят inline-переменными на <body> (см. storefront/
   _layout.html) и работают сами; здесь — только то, чему нужны правила:
   фоновая картинка, стиль кнопок, стиль полей, высота логотипа.
   ══════════════════════════════════════════════════════════════════════════ */

/* Фон страницы: картинка фиксирована за контентом, поверх неё — вуаль цветом
   --bg с прозрачностью --bg-overlay (0% = картинка как есть). Псевдоэлементы
   body: фон самого body рисуется ниже них, контент — выше. */
.has-bg-image::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  background-image: var(--bg-image);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}
.has-bg-image.bg-mode-tile::before {
  background-size: auto;
  background-repeat: repeat;
}
/* «Плитка с прокруткой»: тот же паттерн, но слой не фиксирован — absolute
   растягивается на всю высоту body и уезжает вместе с контентом. */
.has-bg-image.bg-mode-tile-scroll { position: relative; min-height: 100vh; }
.has-bg-image.bg-mode-tile-scroll::before {
  position: absolute;
  background-size: auto;
  background-repeat: repeat;
}
.has-bg-image::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--bg);
  /* --bg-overlay — голое число 0..90 (не проценты): calc(40% / 100%) браузеры
     не считают, деление в calc() допустимо только на число. */
  opacity: calc(var(--bg-overlay, 0) / 100);
}
/* Иначе секции с собственной заливкой закроют картинку целиком. */
.has-bg-image main,
.has-bg-image header,
.has-bg-image footer { background: transparent; }


/* Поля ввода: свой радиус + «заливка» вместо контура. */
.sf-input,
.sf-input:where(input, textarea, select) { border-radius: var(--input-radius, var(--radius)); }
.input-style-filled .sf-input {
  background: color-mix(in srgb, var(--text) 8%, var(--surface));
  border-color: transparent;
}

/* Логотип шапки: высота из темы (--logo-h), ширина по пропорции. */
[data-theme-logo] { height: var(--logo-h, 2rem); width: auto; }

/* ── Шрифты: регистр и масштаб (аккордеон «Шрифты», паритет с FW «Fonts») ─────
   Регистр заголовков идёт через уже существующий --display-transform (правило
   [class*="preset-"] h1/h2/.sf-display выше) — здесь только текст и «акцент».

   Масштаб — zoom, а не font-size: кегль задаётся Tailwind-утилитами прямо на
   элементах (text-4xl и т.п.), домножить их множителем из каскада нечем, а
   zoom в каскаде font-size не участвует и потому ничего не перебивает.
   Масштаб основного текста — корневой font-size на <html> (см. _layout.html).
   ponytail: zoom заодно тянет отступы элемента — для заголовка это желаемое. */
body[class*="preset-"] { text-transform: var(--body-transform, none); }

[class*="preset-"] h1,
[class*="preset-"] h2,
[class*="preset-"] .sf-display,
[class*="preset-"] .pdp-title { zoom: var(--heading-scale, 1); }

/* «Акцентный» шрифт FW — кнопки и подписи-лейблы. Значения по умолчанию
   (inherit / none / 1) оставляют вид витрины ровно таким, как до аккордеона. */
[class*="preset-"] .btn-primary,
[class*="preset-"] .btn-outline,
[class*="preset-"] .sf-label {
  font-family: var(--font-accent, inherit);
  text-transform: var(--accent-transform, none);
  zoom: var(--accent-scale, 1);
}

/* ── Кнопки: два независимых набора (подтабы FW «Primary/Secondary button») ───
   .btn-primary читает --btn-*, .btn-outline — --btn2-* (обе переменные группы
   печатаются на <body> из темы, см. storefront/_layout.html).

   Блок стоит ПОСЛЕДНИМ в файле осознанно: у него та же специфичность (0,2,0),
   что у правил .preset-oasis/.preset-creator .btn-*, и выигрывает он порядком
   в каскаде — иначе ползунки темы не могли бы перебить пресет (именно поэтому
   до 2026-08-07 «Скругление» в кабинете не давало никакого эффекта).

   Базовые значения (48px высота, 16px боковые поля, кегль 16px, рамка 2px)
   совпадают с обоими живыми пресетами, а дефолты темы — единичные множители,
   поэтому витрина партнёра, не трогавшего раздел, выглядит как прежде. */
[class*="preset-"] .btn-primary,
[class*="preset-"] .btn-outline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-style: solid;
  line-height: 1.5;
}
[class*="preset-"] .btn-primary {
  min-height: calc(48px * var(--btn-h, 1));
  padding: 0 calc(16px * var(--btn-w, 1));
  font-size: calc(16px * var(--btn-t, 1));
  border-width: var(--btn-outline, 2px);
  border-radius: var(--btn-radius, 0px);
  font-family: var(--btn-ff, var(--font-accent, inherit));
  text-transform: var(--btn-tt, var(--accent-transform, none));
}
[class*="preset-"] .btn-outline {
  min-height: calc(48px * var(--btn2-h, 1));
  padding: 0 calc(16px * var(--btn2-w, 1));
  font-size: calc(16px * var(--btn2-t, 1));
  border-width: var(--btn2-outline, 2px);
  border-radius: var(--btn2-radius, 0px);
  font-family: var(--btn2-ff, var(--font-accent, inherit));
  text-transform: var(--btn2-tt, var(--accent-transform, none));
}

/* Источник цвета кнопки (селект «Цвет» = FW Colors): акцент витрины, основной
   текст или цвет подложки. Дальше форма решает, куда его класть — в заливку
   или в рамку с текстом. */
.btn-color-accent .btn-primary { --btn-c: var(--cta-bg, var(--accent)); --btn-on: var(--cta-text, var(--surface)); }
.btn-color-text .btn-primary { --btn-c: var(--text); --btn-on: var(--surface); }
.btn-color-surface .btn-primary { --btn-c: var(--surface); --btn-on: var(--text); }
.btn2-color-accent .btn-outline { --btn-c: var(--cta-bg, var(--accent)); --btn-on: var(--cta-text, var(--surface)); }
.btn2-color-text .btn-outline { --btn-c: var(--text); --btn-on: var(--surface); }
.btn2-color-surface .btn-outline { --btn-c: var(--surface); --btn-on: var(--text); }

/* Форма и заливка (селект «Форма и заливка» = FW Shape and fill). */
.btn-style-filled .btn-primary {
  background: var(--btn-c);
  color: var(--btn-on);
  border-color: var(--btn-c);
}
.btn-style-outline .btn-primary,
.btn-style-text .btn-primary {
  background: transparent;
  color: var(--btn-c);
  box-shadow: none;
}
.btn-style-outline .btn-primary { border-color: var(--btn-c); }
.btn-style-text .btn-primary { border-color: transparent; }
.btn2-style-filled .btn-outline {
  background: var(--btn-c);
  color: var(--btn-on);
  border-color: var(--btn-c);
}
.btn2-style-outline .btn-outline,
.btn2-style-text .btn-outline {
  background: transparent;
  color: var(--btn-c);
  box-shadow: none;
}
.btn2-style-outline .btn-outline { border-color: var(--btn-c); }
.btn2-style-text .btn-outline { border-color: transparent; }

/* ── Раскладка карточек товара (панель FW Product cards) ──────────────────────
   Оба режима выключены по умолчанию, поэтому витрина без них выглядит как
   прежде. Блок стоит в конце файла НАМЕРЕННО: правила тем на «див-сосед
   .sf-tile» имеют ту же специфичность (0,2,0), и при равенстве решает порядок
   (та же ловушка, что вскрылась на скруглении кнопок 2026-08-07). */

/* «Центрировать карточки» — центрирует неполный последний ряд. Grid с долевыми
   колонками этого не умеет (треки тянутся на всю ширину), поэтому в этом режиме
   сетка переключается на flex с теми же долями ширины: полные ряды выглядят
   ровно как прежде, а хвост из 1–3 карточек встаёт по центру. */
.cards-centered .sf-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.cards-centered .sf-grid > * { width: calc(50% - var(--card-gap, 16px) / 2); }
@media (min-width: 768px) {
  .cards-centered .sf-grid > * { width: calc(25% - var(--card-gap, 32px) * 3 / 4); }
}

/* «Подпись поверх фото» — имя/цена ложатся на низ снимка. Градиент из цвета
   подложки, чтобы текст читался на любом мокапе. */
.cards-overlay .sf-card { position: relative; }
.cards-overlay .sf-tile + div {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  margin: 0;
  padding: 24px 12px 12px;
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--surface) 92%, transparent),
    transparent
  );
}
