/* base.css — переменные :root, сброс, типографика, кнопки .btn*, .rnd, .badge и общие утилиты
   (.wrap, section, .sec-head, .chip, .ser), а также общие компоненты #toast, .skeleton, .sr-only,
   состояния :hover/:active/:focus-visible/disabled, prefers-reduced-motion и шрифт для [lang=ka].
   Владелец: команда «ядро». */

:root{
  /* Фирменные цвета эмблемы SMASH GEORGIA: синий #033E80 (10.5:1 на белом),
     красно-оранжевый #DA3E10 и молочно-белый фон. Оранжевый на белом даёт всего 4.49:1
     и WCAG AA для текста не проходит, поэтому для надписей и заливок с белым текстом
     взят --accent-d (5.45:1), а сам --accent живёт в графике: траектории, подчёркивания, штрихи. */
  --bg:#fff; --soft:#eff3f9; --line:#dfe6f0; --ink:#0c1524; --ink2:#4c5a70; --ink3:#616c85;  /* 5.26:1 на белом и 4.73:1 на --soft: на светлой подложке прежний #66718a давал 4.39 */
  --brand:#033E80; --brand2:#02295a; --brand3:#0a4f9c; --brand-soft:#e7eefa;
  --accent:#DA3E10; --accent-d:#c3360e; --accent-soft:#fdece6;
  --ok:#0a7a41; --ok-bg:#e7f7ee; --warn:#a25c00; --warn-bg:#fff4e2;
  --sale:#c3360e; --r:10px; --rl:16px;
  /* тень холоднее и мягче: подложка теперь синеватая */
  --sh:0 1px 2px rgba(3,62,128,.05),0 10px 28px rgba(3,62,128,.10);
  --maxw:1300px; --gut:24px; --hdr:118px;
  /* угол фирменных диагоналей — тот же наклон, что у следа волана на эмблеме */
  --skew:-11deg;
  --safeL:env(safe-area-inset-left,0px); --safeR:env(safe-area-inset-right,0px); --safeB:env(safe-area-inset-bottom,0px);
  /* алиасы под опечатки в чужих модулях (product.css, product.js, catalog.js, home.js) — не удалять,
     пока владельцы не заменят их на --ink2/--ink3/--soft */
  --ink-2:var(--ink2); --ink-3:var(--ink3); --bg-soft:var(--soft);
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html{-webkit-text-size-adjust:100%}
body{margin:0;font:15px/1.55 -apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",Roboto,Inter,Arial,sans-serif;color:var(--ink);background:var(--bg);overflow-x:hidden}
a{color:inherit;text-decoration:none}
img{max-width:100%;display:block}
button{font:inherit;cursor:pointer;border:0;background:none;color:inherit;padding:0}
input,select{font:inherit}
/* справа берём --safeR, слева --safeL: в ландшафте вырез бывает с любой стороны */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 max(var(--gut),var(--safeR)) 0 max(var(--gut),var(--safeL))}

/* ============ кнопки ============ */
/* Иерархия по бренду: .btn-buy — оранжевая заливка (главное действие и единственное крупное
   оранжевое пятно на экране), .btn-pre — синяя (предзаказ спокойнее покупки), .btn-ghost2 —
   белая с синей рамкой, .btn-primary/.btn-ghost живут только на тёмной подложке героя.
   Затемнение на hover/active делаем через brightness: новых hex мимо токенов не заводим.
   Вес 700, а не 800 из брифа: 800 системные шрифты округляют как попало (см. заметку ниже). */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:48px;padding:0 24px;border-radius:var(--r);font-weight:700;transition:.15s;font-size:15.5px}
.btn-primary{background:#fff;color:var(--brand)}
.btn-primary:hover{transform:translateY(-1px);box-shadow:0 10px 24px rgba(2,41,90,.38)}
.btn-ghost{border:1.5px solid rgba(255,255,255,.5);color:#fff}
.btn-ghost:hover{background:rgba(255,255,255,.16);border-color:#fff}
.btn-buy{background:var(--accent-d);color:#fff}
.btn-buy:hover{filter:brightness(.9)}
.btn-pre{background:var(--brand);color:#fff}
/* .btn-ghost2 в исходнике стоял в самом конце файла, но конфликтов по специфичности у него нет:
   .btn-buy/.btn-pre никогда не встречаются на том же элементе — перенос в base безопасен */
.btn-ghost2{background:#fff;border:1.5px solid var(--brand);color:var(--brand)}
.btn-ghost2:hover{background:var(--brand-soft)}

/* состояния кнопок: порядок важен — блоки идут после всех .btn-*:hover, специфичность та же */
.btn:active{transform:scale(.98)}
.btn-pre:hover{background:var(--brand2)}
.btn-buy:active,.btn-pre:active{filter:brightness(.85)}
/* двойное кольцо: видно и на белой, и на синей, и на тёмной подложке */
.btn:focus-visible,.rnd:focus-visible,.chip:focus-visible{outline:none;box-shadow:0 0 0 2px #fff,0 0 0 4px var(--brand)}
/* блокировка — последним среди .btn*, чтобы гасить hover-эффекты */
.btn:disabled,.btn[aria-disabled=true]{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none;filter:none}
.btn:disabled:hover,.btn[aria-disabled=true]:hover{transform:none;box-shadow:none;filter:none}

/* общее кольцо фокуса с нулевой специфичностью (:where) — чужие outline:none со своим кольцом остаются в силе */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* ============ секции и их заголовки (общие для home, catalog и статических страниц) ============ */
section{padding:56px 0}
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin-bottom:24px;flex-wrap:wrap}
.sec-head h2{font-size:clamp(22px,2.6vw,29px);margin:0;letter-spacing:-.8px;line-height:1.1;font-weight:700;position:relative}
/* фирменный штрих-диагональ под заголовком. Висит в отступе ПОД боксом h2, поэтому высоту
   ничего не меняет — важно для .cathead/.pagehead, где h2 стоит в одном ряду с круглой кнопкой */
.sec-head h2::after{content:"";position:absolute;left:0;bottom:-11px;width:44px;height:5px;background:var(--accent);
  transform:skewX(var(--skew));clip-path:polygon(14% 0,100% 0,100% 100%,0 100%)} /* левый конец заострён, как след удара на эмблеме */
/* отступ подзаголовка увеличен на высоту штриха: строка описания на него не наезжает */
.sec-head p{margin:18px 0 0;color:var(--ink2);font-size:14.5px}
.sec-head a{color:var(--brand);font-weight:700;font-size:14.5px;white-space:nowrap}
.sec-head a:hover{color:var(--brand2);text-decoration:underline;text-underline-offset:3px}
.sec-head a:active{opacity:.7}

/* ============ мелкие общие утилиты ============ */
/* .ico — контурные иконки из shared.js: ставятся в строку рядом с текстом */
svg.ico{display:inline-block;vertical-align:-3px;flex:none}

/* .ser — надпись серии: сейчас только карточки «Рекомендуем» на главной (home.js); из каталога и товара убрана (BLOCK3 §6, §9) */
.ser{font-size:10.5px;text-transform:uppercase;letter-spacing:.9px;color:var(--brand3);font-weight:700}
/* .badge — ярлык наличия: карточка каталога и блок покупки. Мелкие подписи по брифу — uppercase с разрядкой */
.badge{font-size:11px;font-weight:700;padding:4px 10px;border-radius:99px;text-transform:uppercase;letter-spacing:.5px;white-space:nowrap}
.b-stock{background:var(--ok-bg);color:var(--ok)}   /* в наличии — зелёный, 4.89:1 */
.b-order{background:var(--warn-bg);color:var(--warn)} /* под заказ — янтарный, 4.74:1 */
.b-custom{background:var(--ink);color:#fff}         /* произвольный текст из админки, 18.5:1 */
.b-sale{background:var(--accent-d);color:#fff}      /* скидка — фирменный оранжевый, 5.45:1 */

/* .chip — и фильтры каталога, и ссылки внизу статических страниц. Мягкая синяя пилюля:
   на белой странице её видно без тяжёлой рамки, а сама рамка проявляется на hover */
.chip{display:inline-flex;align-items:center;gap:8px;background:var(--brand-soft);border:1.5px solid var(--line);border-radius:99px;
  padding:7px 13px;font-size:13.5px;color:var(--brand);transition:.15s;cursor:pointer}
a.chip:hover,button.chip:hover{border-color:var(--brand3);color:var(--brand2)}
a.chip:active,button.chip:active{transform:scale(.97)}
/* крестик внутри чипа: тап-зона больше самого символа, отрицательные поля держат чип компактным */
.chip button{color:var(--brand3);font-size:15px;line-height:1;display:inline-grid;place-items:center;
  min-width:32px;min-height:32px;margin:-8px -13px -8px -6px;padding:0 4px;border-radius:99px;transition:.15s}
/* снять фильтр — действие «стирающее», поэтому крестик на hover уходит в оранжевый */
.chip button:hover{color:var(--accent-d);background:var(--accent-soft)}
.chip button:active{transform:scale(.9)}

/* круглые кнопки навигации «назад»/«крупнее» */
.rnd{width:42px;height:42px;border-radius:50%;background:#fff;color:var(--brand);display:grid;place-items:center;
  border:1.5px solid var(--line);box-shadow:0 2px 10px rgba(3,62,128,.12);cursor:pointer;transition:.15s;padding:0}
/* сдвиг влево на hover убран: у кнопок «вперёд»/«крупнее» он читался как сбой */
.rnd:hover{background:var(--brand-soft);border-color:var(--brand3)}
.rnd:active{transform:scale(.94)}
.rnd:disabled,.rnd[aria-disabled=true]{opacity:.45;cursor:not-allowed;transform:none}

/* ============ фирменные заготовки для остальных модулей ============ */
/* .kicker — надзаголовок секции. Ставится ПЕРЕД <h2> внутри .sec-head>div:
   <span class="kicker">Хиты клуба</span><h2>…</h2>. Штрих слева рисует псевдоэлемент,
   в разметке нужен только сам span. На тёмной подложке добавляют .inv (текст белеет, штрих остаётся). */
.kicker{display:flex;align-items:center;gap:8px;margin-bottom:9px;font-size:11px;line-height:1;font-weight:700;
  text-transform:uppercase;letter-spacing:1.2px;color:var(--accent-d)}
.kicker::before{content:"";width:16px;height:3px;flex:none;background:var(--accent);transform:skewX(var(--skew))}
.kicker.inv{color:#fff}

/* .streaks — декоративный слой «след волана»: пустой <span class="streaks"></span> первым ребёнком
   ТЁМНОГО блока (герой, CTA-полоса, подвал). Родителю нужен position:relative, содержимому —
   свой position:relative;z-index:1 (как у .hero .wrap). Слой не ловит клики и не занимает
   :before/:after самого блока. Мера из брифа: один слой на экран, не на карточках и не под мелким текстом.
   След затухает влево градиентом, ось вращения у правого края — длину полос можно менять, не сдвигая хвост. */
.streaks{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
.streaks::before,.streaks::after{content:"";position:absolute;right:-8%;height:13px;border-radius:7px;
  transform:rotate(var(--skew));transform-origin:100% 50%;background:linear-gradient(90deg,transparent,var(--accent))}
.streaks::before{top:30%;width:46%;opacity:.85}
.streaks::after{top:52%;width:28%;opacity:.5}
/* .streaked — тот же мотив одним классом, когда добавить span в разметку нельзя.
   Диагональ рисует ::after самого блока, поэтому блок не должен занимать свой ::after */
.streaked{position:relative;overflow:hidden}
.streaked::after{content:"";position:absolute;right:-8%;top:32%;width:44%;height:13px;border-radius:7px;
  pointer-events:none;transform:rotate(var(--skew));transform-origin:100% 50%;
  background:linear-gradient(90deg,transparent,var(--accent));opacity:.85}

/* ============ страховочный слой состояний для чужих компонентов ============
   Карточки (.card), плитки (.cat), ссылки ленты категорий и подвала свои :active/:focus-visible
   получили у владельцев — их здесь нет. Ниже только то, чего у владельцев до сих пор НЕТ:
   бургер, оба переключателя языка, кнопки цвета и размера, крестик карточки, опция фильтра,
   стрелки полноэкранного просмотра и мелочь формы. Правила намеренно живут в base.css —
   он грузится первым, поэтому любое правило владельца той же специфичности перебьёт наше,
   и слой сам собой исчезнет, когда владельцы заведут состояния у себя (см. NEEDS в отчёте).
   Специфичность повышена только там, где чужое правило той же силы стоит позже по каскаду. */
/* каркас: бургер, компактный язык, ряд языка в шапке, список языков, крестик ящика */
.burger:hover{background:var(--soft)}
.burger:active{transform:scale(.94)}
.langmini:hover{background:var(--soft)}
.langmini:active{transform:scale(.96)}
.lang button:hover{background:var(--soft);color:var(--ink)}
/* у скрытого ряда #lang transform не вычисляется — отклик ещё и цветом, как у .catrow a */
.lang button:active{transform:scale(.96);background:var(--brand-soft);color:var(--brand)}
.langpop button:hover{background:var(--soft)}
.dhead .close:hover{background:var(--brand-soft)}
.dhead .close:active{transform:scale(.94)}
.dcontacts a:hover{background:var(--soft)}
.dfoot a:hover{color:var(--ink)}
.dfoot a:active{opacity:.65}
/* товар: цвет, размер, крестик, кнопка таблицы размеров, «подробнее», миниатюра галереи */
.colors button:hover{background:var(--soft);border-color:var(--brand3)}
.colors button:active{transform:scale(.97)}
.sizes .szrow button:active:not(.na){transform:scale(.96)}
.pd-nav .close:active{transform:scale(.94)}
.pd-nav .pd-lang button:active{opacity:.6}
.pd-szbtn:active{transform:scale(.97)}
.pd-more:active{opacity:.7}
/* у .rnd.zoom своя полупрозрачная подложка, и она перебивает .rnd:hover — возвращаем отклик */
.rnd.zoom:hover{background:#fff;border-color:var(--brand3)}
.gal .thumbs .th:hover{border-color:var(--brand3)}
.gal .thumbs .th:active{transform:scale(.94)}
/* стрелки полноэкранного просмотра: у них свой transform, поэтому .rnd:active до них не достаёт */
.lb .lb-prev:active,.lb .lb-next:active{transform:translateY(-50%) scale(.94)}
/* каталог: опция фильтра (обычная строка и чипс размера), крестик шторки */
.fopt:active{background:var(--soft)}
.fg-size .fopt:active{background:var(--soft);transform:scale(.97)}
.filters .fhead .close:hover{background:var(--brand-soft)}
.filters .fhead .close:active{transform:scale(.94)}
/* форма заявки и статические страницы */
.pf-qty button:hover{background:var(--soft)}
.pf-qty button:active{transform:scale(.94)}
.pf-item-x:active{transform:scale(.9)}
.pf-add:active{opacity:.7}
.soc-a:active{opacity:.7}

/* Шрифтовые веса: в проекте разрешены только 400/500/600/700 — 550/650/750/800 системные шрифты
   округляют как попало (Roboto на Android даёт из 800 почти 900). Блок-перебивка из base.css
   удалена: владельцы модулей заменили веса у себя, тест run_visual.js сканирует всё дерево. */

/* ============ смена маршрута ============ */
/* короткий проявляющий переход вместо мгновенной подмены #app. Высоты не меняет —
   transform и opacity сдвигов макета не дают, CLS не растёт. Класс ставит drawBase(). */
/* только opacity: transform на #app делает его точкой отсчёта для position:fixed, и липкая
   панель цены на телефоне на время анимации уезжала в конец документа */
@keyframes pgIn{from{opacity:0}}
#app.pg-in{animation:pgIn .18s ease}
/* модалка и шторки выезжают снизу — общий кадр для product.css/catalog.css/form.css */
@keyframes sheetUp{from{transform:translateY(100%)}}
@keyframes fadeIn{from{opacity:0}}

/* ============ общие компоненты ============ */
/* #toast — создаётся в shared.js: div#toast[role=status], класс .on снимается через 2.6 с.
   z-index 200 закреплён за тостом: новым оверлеям выше 199 не подниматься. */
#toast{position:fixed;left:50%;bottom:calc(24px + var(--safeB));transform:translate(-50%,12px);opacity:0;
  pointer-events:none;z-index:200;max-width:min(92vw,440px);padding:12px 18px;border-radius:var(--r);
  background:var(--brand2);color:#fff;font-size:14px;line-height:1.4;text-align:center;box-shadow:var(--sh);
  transition:opacity .2s,transform .2s}
#toast.on{opacity:1;transform:translate(-50%,0)}

/* ============ экраны ядра: скелет загрузки, «не загрузилось», «товар не найден» ============ */
/* Раньше core.js вставлял их из JS (<style id="core-css">) — переехали сюда целиком. */
/* Пустой #app (первый кадр, до того как core.js вставит скелет) держит высоту экрана.
   Иначе подвал рисуется сразу под шапкой, а через полсекунды уезжает вниз — это и был
   весь CLS витрины (0.53). Правило работает только пока в #app ничего нет. */
#app:empty{min-height:100vh;min-height:100dvh}

/* Скелет держит высоту первого экрана. Раньше он был ниже вьюпорта, подвал попадал в первый
   кадр и уезжал вниз, когда приходил каталог: весь CLS витрины (0.53 на телефоне) был этим
   одним сдвигом. 100vh — запасной вариант для браузеров без dvh. */
.core-skel{max-width:1180px;margin:0 auto;padding:26px 16px;min-height:100vh;min-height:100dvh}
.core-skel .sk-h{height:34px;width:min(320px,60%);border-radius:10px;margin-bottom:22px}
.core-skel .sk-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(160px,1fr))}
.core-skel .sk-c{border-radius:var(--r);overflow:hidden}
.core-skel .sk-c i{display:block;height:150px}
.core-skel .sk-c u{display:block;height:13px;margin:10px 10px 0;border-radius:6px;text-decoration:none}
.core-skel .sk-c u.s{width:55%;margin-bottom:12px}
/* перелив холодный: синеватая подложка --brand-soft и белая волна по ней */
.core-skel .sk-h,.core-skel .sk-c i,.core-skel .sk-c u{background:var(--brand-soft);
  background-image:linear-gradient(90deg,var(--brand-soft) 0%,var(--bg) 50%,var(--brand-soft) 100%);background-size:300% 100%;
  animation:core-sh 1.25s ease-in-out infinite}
@keyframes core-sh{0%{background-position:100% 0}100%{background-position:-100% 0}}
.core-err,.core-nf{max-width:560px;margin:56px auto;padding:0 18px;text-align:center}
.core-err b,.core-nf b{display:block;font-size:21px;line-height:1.3;margin-bottom:10px}
.core-err p,.core-nf p{color:var(--ink2);margin:0 0 18px}
.core-err button,.core-nf button{cursor:pointer}
.core-err .core-ch{margin-top:18px;font-size:14px;color:var(--ink2)}
/* запасные контакты на экране ошибки — той же пилюлей, что и .chip */
.core-err .core-ch a{display:inline-block;margin:6px 6px 0;padding:8px 14px;border-radius:999px;
  border:1.5px solid var(--line);background:var(--brand-soft);text-decoration:none;color:var(--brand)}

/* .skeleton — заглушка на время загрузки (p/<id>.json и т.п.) */
.skeleton{position:relative;overflow:hidden;background:var(--brand-soft);border-radius:var(--r);color:transparent!important;pointer-events:none}
.skeleton::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.75),transparent);animation:sk-shine 1.3s infinite}
@keyframes sk-shine{to{transform:translateX(100%)}}

/* .sr-only — текст только для скринридеров */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* грузинский: веб-шрифт не подключаем (ARCHITECTURE §15). Noto Sans Georgian в списке — только
   если он уже стоит в системе (Android, Linux); иначе браузер берёт свой системный грузинский.
   :is берёт специфичность самого тяжёлого аргумента — трекинг снимается независимо от порядка файлов */
html[lang=ka] body{font-family:"Noto Sans Georgian",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif}
html[lang=ka] :is(h1,h2,h3,h4,.logo,.facts b,.buybox .p b,.card .price b,.mobuy .pp b,.pf-title){letter-spacing:0}

/* ============ tablet ============ */
@media(max-width:1080px){
  :root{--gut:20px}
}

/* ============ phone ============ */
@media(max-width:760px){
  :root{--gut:16px;--hdr:100px}
  section{padding:30px 0}
  .sec-head{margin-bottom:14px}
  /* заголовок и ссылка «все» — в одну строку: на телефоне ссылка отдельной строкой съедала
     44 px перед каждой лентой. Шапки каталога и статических страниц не трогаем */
  .sec-head:not(.cathead):not(.pagehead){flex-wrap:nowrap;align-items:flex-end}
  .sec-head:not(.cathead):not(.pagehead)>div{flex:1 1 auto;min-width:0}
  .sec-head:not(.cathead):not(.pagehead)>div p{display:-webkit-box;-webkit-line-clamp:2;
    -webkit-box-orient:vertical;overflow:hidden}
  .sec-head:not(.cathead):not(.pagehead)>a{flex:0 0 auto}
  /* тап-зоны не меньше 44×44 */
  .rnd{width:44px;height:44px}
  .chip{min-height:44px;padding:9px 14px}
  .chip button{min-width:44px;min-height:44px;margin:-9px -14px -9px -6px}
  /* страховка по тап-зонам за чужие файлы (NEEDS(product) и NEEDS(layout) в отчёте):
     переключатель языка в карточке товара был 40×42 — пилюлю растим до 46, кнопку до 44×44;
     .sheet в селекторе только ради специфичности: правило product.css стоит позже */
  .sheet .pd-nav .pd-lang{height:46px;border-radius:23px}
  .sheet .pd-nav .pd-lang button{min-width:44px;height:44px}
  /* ссылки в подвале бургер-меню были 42 px высотой */
  .drawer .dfoot a{display:flex;align-items:center;min-height:44px}
  /* чтобы тост не лёг на нижнюю панель покупки в карточке товара */
  body:has(#modal.on,#pf.on) #toast{bottom:calc(88px + var(--safeB))}

  /* скелет повторяет форму главной: блок героя во всю ширину и два ряда карточек 4:5.
     Раньше тут было восемь абстрактных плиток — по ним нельзя было угадать, что грузится */
  .core-skel{padding:0 0 26px}
  .core-skel .sk-h{height:232px;width:100%;border-radius:0;margin-bottom:16px}
  .core-skel .sk-grid{grid-template-columns:1fr 1fr;gap:12px;padding:0 var(--gut)}
  .core-skel .sk-c i{height:auto;aspect-ratio:4/5}
  .core-skel .sk-c:nth-child(n+5){display:none}
}

/* ============ уважение к настройке «меньше движения» ============ */
/* единственное место с !important: нужно перебить анимации во всех модулях разом */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important}
}
