/* LOOLA — каталог §10. Источник: theme/demo/catalog.html.
   Файл самодостаточный: токены, шапка, подвал и всё, что нужно витрине.
   Правки вносить в прототип и переносить сюда. */


/* ============================================================
   ТОКЕНИ — LOOLA-DESIGN-CODE.md v2.7 §2, без змін
   ============================================================ */
:root{
  --ink:#1A1A1A; --body:#2D2D2D; --soft:#555555; --muted:#767676;
  --canvas:#FFFFFF; --surface:#FFFFFF; --wash:#F6F6F6;
  --line:#E5E5E5; --line-strong:#949494; --on-dark:#FFFFFF;
  --scrim:rgba(26,26,26,.55);
  --accent:#1A1A1A; --accent-hover:#3D3D3D; --accent-pressed:#000000; --on-accent:#FFFFFF;
  --price-sale:#BE1128; --danger:#BE1128;
  --note:#3B4C8F;      /* колір нотаток прототипу, не інтерфейс */
  --st-quiet:#FFFFFF;  --on-st-quiet:#1A1A1A;
  --st-urgent:#1A1A1A; --on-st-urgent:#FFFFFF;
  --st-sale:#BE1128;   --on-st:#FFFFFF;   /* у резерві: знижку показує ціна */
  --font-display:'Montserrat',system-ui,sans-serif;
  --font-body:'Inter',system-ui,sans-serif;
  --hairline:1px; --focus-ring:2px; --icon-stroke:1.5;
  --r-xs:0px; --r-sm:2px; --r-md:4px; --r-pill:999px;
  --elevation:0 1px 2px rgba(0,0,0,.05), 0 12px 32px rgba(0,0,0,.10);
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px;
  --s-6:32px; --s-7:48px; --s-8:64px; --s-9:96px; --s-10:128px;
  --container:1440px; --gutter:24px; --pad-page:20px; --hd-h:64px;
  --ease:cubic-bezier(0.22,0.61,0.36,1); --ease-soft:ease-in-out; --ease-out:cubic-bezier(0,0,0.2,1);
  --t-fast:200ms; --t-media:200ms; --t-color:300ms; --t-panel:325ms; --t-reveal:400ms; --t-hover:500ms;
}
@media (min-width:768px){ :root{ --pad-page:48px } }
@media (min-width:1024px){ :root{ --pad-page:80px } }

*,*::before,*::after{ box-sizing:border-box }
html{ scroll-padding-top:calc(var(--hd-h) + var(--s-4)) }
body{ margin:0; background:var(--canvas); color:var(--body);
  font-family:var(--font-body); font-size:15px; line-height:1.6;
  -webkit-font-smoothing:antialiased; overflow-x:hidden }
body.locked{ overflow:hidden }
h1,h2,h3{ margin:0; font-weight:400; color:var(--ink) }
p{ margin:0 } img{ max-width:100%; display:block }
ul,ol{ margin:0; padding:0; list-style:none }
a{ color:var(--ink); text-decoration:none; transition:color var(--t-color) var(--ease-soft) }
:focus-visible{ outline:var(--focus-ring) solid var(--ink); outline-offset:2px }

.t-h1{ font-family:var(--font-display); font-weight:500; font-size:clamp(20px,2.6vw,26px);
  line-height:1.35; letter-spacing:.14em; text-transform:uppercase }
.t-label{ font-family:var(--font-display); font-weight:500; font-size:11px; line-height:1.5;
  letter-spacing:.18em; text-transform:uppercase }
.t-caption{ font-size:13px; line-height:1.45; color:var(--muted) }

.sticker{ display:inline-flex; align-items:center; padding:4px 8px;
  font-family:var(--font-display); font-weight:500; font-size:10px;
  letter-spacing:.14em; text-transform:uppercase; border-radius:var(--r-xs); white-space:nowrap }
.st-quiet { background:var(--st-quiet);  color:var(--on-st-quiet) }
.st-urgent{ background:var(--st-urgent); color:var(--on-st-urgent) }
.st-sale  { background:var(--st-sale);   color:var(--on-st) }

.btn{ --btn-h:44px; --btn-px:28px; --btn-fs:12px;
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  height:var(--btn-h); padding:0 var(--btn-px);
  font-family:var(--font-display); font-weight:500; font-size:var(--btn-fs);
  letter-spacing:.16em; text-transform:uppercase;
  border-radius:var(--r-sm); border:var(--hairline) solid transparent; cursor:pointer; white-space:nowrap;
  transition:background var(--t-hover) var(--ease-soft), color var(--t-hover) var(--ease-soft),
             border-color var(--t-hover) var(--ease-soft) }
.btn-secondary{ background:transparent; color:var(--ink); border-color:var(--ink) }
.btn-secondary:hover{ background:var(--ink); color:var(--canvas) }
/* §7 · третій рівень — текстова кнопка */
.btn-ghost{ background:transparent; color:var(--ink); padding-inline:6px }
.btn-ghost:hover{ text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:4px }

/* ── Памʼятка прототипу ───────────────────────────────────── */


/* §11 · текучий контейнер до 1440 з полями сторінки, а не 1200 з полями всередині */
.wrap{ width:100%; max-width:var(--container); margin:0 auto; padding-inline:var(--pad-page) }
.crumbs{ padding:var(--s-3) 0 var(--s-3); font-size:13px; color:var(--muted) }
.crumbs a{ color:var(--muted) } .crumbs a:hover{ color:var(--ink) }
.crumbs span{ padding:0 var(--s-2) }

/* ============================================================
   ЗАГОЛОВОК КАТЕГОРІЇ + СОРТУВАННЯ
   Платформа віддає .products-title.with-sort-row — заголовок
   і сортування стоять в одному ряду.
   ============================================================ */
.cat-head{ display:flex; align-items:flex-end; justify-content:space-between;
  gap:var(--s-5); flex-wrap:wrap; padding-bottom:var(--s-4);
  border-bottom:var(--hairline) solid var(--line) }
.cat-head .count{ margin-top:var(--s-2); color:var(--muted); font-size:14px }
/* Сортування — своя кнопка з меню, а не <select>. Нативний список малює
   операційна система: у ньому не діють ні наш шрифт, ні токени, ні наведення,
   і поруч із пігулками він читається як чужий елемент. Кнопка зібрана на
   <details>, тому розкривається без JS і працює з клавіатури; скрипт лише
   закриває меню по кліку повз і по Esc.                                    */
.sort{ display:flex; align-items:center; gap:var(--s-3) }
.sort .t-label{ color:var(--muted) }
.sort-menu{ position:relative }
/* Кнопка вища за пігулку (44 проти 36) навмисно: сортування — основна дія
   ряду, а не ще один захід у шторку. */
.sort-btn{ height:44px; padding:0 var(--s-4); display:inline-flex; align-items:center;
  gap:var(--s-2); background:var(--surface); color:var(--ink); cursor:pointer;
  list-style:none; white-space:nowrap;
  border:var(--hairline) solid var(--line-strong); border-radius:var(--r-sm);
  font-family:var(--font-body); font-size:14px;
  transition:border-color var(--t-fast) var(--ease) }
.sort-btn::-webkit-details-marker{ display:none }
.sort-btn svg{ flex:0 0 12px; color:var(--muted);
  transition:transform var(--t-fast) var(--ease) }
.sort-btn:hover{ border-color:var(--ink) }
.sort-menu[open] .sort-btn{ border-color:var(--ink) }
.sort-menu[open] .sort-btn svg{ transform:rotate(180deg) }
/* Меню впритул під кнопкою і по її правому краю: так воно розкривається
   всередину сторінки, а не за край екрана. */
.sort-list{ position:absolute; top:100%; right:0; z-index:40;
  min-width:100%; width:max-content; margin:0; padding:0;
  background:var(--surface); border:var(--hairline) solid var(--line);
  border-radius:var(--r-sm); box-shadow:var(--elevation);
  animation:sort-in var(--t-fast) var(--ease) }
.sort-list a{ display:flex; align-items:center; min-height:32px; padding:0 var(--s-3);
  color:var(--body); font-size:14px; white-space:nowrap;
  transition:background-color var(--t-color) var(--ease-soft) }
.sort-list a:hover{ background:var(--wash); color:var(--ink) }
.sort-list a[aria-current]{ color:var(--ink) }
@keyframes sort-in{ from{ opacity:0; transform:translateY(-6px) } to{ opacity:1; transform:none } }

/* ============================================================
   ПОЛОСА ЗАХОДІВ — другий шар навігації
   Підпис завжди ПІД кадром, ніколи поверх (§13).
   ============================================================ */
.entry{ position:relative; margin-top:var(--s-4); margin-bottom:var(--s-5) }
.tiles{ display:grid; gap:var(--s-5) var(--s-4) }
.t6{ grid-template-columns:repeat(6,minmax(0,1fr)) }
.t3{ grid-template-columns:repeat(3,minmax(0,1fr)) }

/* Стрічка з прокруткою — так у lululemon і Gymshark: плитки
   їдуть за край навіть на десктопі. Нова категорія просто
   стає в чергу, розкладка не ламається.                     */
.tscroll{ display:flex; gap:var(--s-4); overflow-x:auto; scroll-snap-type:x proximity;
  scrollbar-width:none; padding-bottom:var(--s-2);
  /* Стрічка лишається в межах контейнера — так само, як смуга
     фільтрів під нею. Раніше вона виходила за поля сторінки. */ }
.tscroll::-webkit-scrollbar{ display:none }
.tscroll .tile{ flex:0 0 168px; scroll-snap-align:start }

/* Текстовий ряд категорій — приём lululemon. Дешевий і
   розтягується нескінченно: нова категорія = нове слово.    */
.cat-links{ display:flex; flex-wrap:wrap; align-items:baseline;
  gap:0 var(--s-5); margin-bottom:var(--s-2) }
.cat-links a{ min-height:44px; display:inline-flex; align-items:center;
  font-size:15px; color:var(--soft) }
.cat-links a:hover{ color:var(--ink); text-decoration:underline;
  text-decoration-thickness:1px; text-underline-offset:4px }
.cat-links a[aria-current="page"]{ color:var(--ink); font-weight:500 }

/* видимість варіантів */
.tiles,.cat-links{ display:none }
body.entry-6 .t6{ display:grid }
body.entry-3 .t3{ display:grid }
body.entry-scroll .tscroll{ display:flex }
body.entry-mix .tscroll{ display:flex }
body.entry-mix .cat-links{ display:flex }
body.entry-off .entry{ display:none }
.tile{ display:block }
.tile-media{ aspect-ratio:4/5; background:var(--wash); border-radius:var(--r-xs); overflow:hidden }
.t3 .tile-media{ aspect-ratio:3/2 }
.tile-media img{ width:100%; height:100%; object-fit:cover }
.tile-name{ margin-top:var(--s-3); font-family:var(--font-display); font-weight:500;
  font-size:13px; letter-spacing:.16em; text-transform:uppercase; color:var(--ink) }
/* Поточний розділ у стрічці: підкреслення, а не заливка — плитка
   лишається кадром, а не перетворюється на кнопку. Саме тому поточної
   категорії немає в текстовому ряду вище. */
.tile.current .tile-name{ text-decoration:underline; text-decoration-thickness:1px;
  text-underline-offset:4px; color:var(--ink) }

.t3 .tile-name{ font-size:14px }
.tile-n{ margin-top:var(--s-1); font-size:13px; color:var(--muted) }
.tile:hover .tile-name{ text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:4px }

/* заглушка під ненятий кадр */
.ph{ display:flex; align-items:center; justify-content:center; text-align:center; height:100%;
  padding:var(--s-4); background:var(--wash); border:1px dashed var(--line-strong); border-radius:var(--r-xs) }
.ph > span{ max-width:30ch; font-size:12px; line-height:1.5; color:var(--muted) }
.ph b{ display:block; margin-bottom:var(--s-1); font-family:var(--font-display); font-weight:500;
  font-size:10px; letter-spacing:.16em; text-transform:uppercase; color:var(--soft) }

/* ============================================================
   ГОРИЗОНТАЛЬНИЙ РЯД ФІЛЬТРІВ (приём Alo)
   Липне під шапкою. Ліворуч — пігулки-заходи, праворуч —
   сортування. Повний набір живе у шторці, а не в панелі.
   ============================================================ */
.filterbar{ position:sticky; top:var(--hd-h); z-index:30;
  display:flex; align-items:center; gap:var(--s-3);
  padding:var(--s-3) 0; margin-top:var(--s-4);
  /* Ні смуга, ні стрічка за контейнер не виходять: інакше лінія
     під фільтрами стирчить ширше за сітку товарів. Знизу — повітря,
     без нього ряд злипається з першим рядом карток. */
  margin-bottom:var(--s-5);
  background:var(--canvas); border-bottom:var(--hairline) solid var(--line) }
.pills{ display:flex; align-items:center; gap:var(--s-2); min-width:0;
  overflow-x:auto; scrollbar-width:none }
.pills::-webkit-scrollbar{ display:none }
/* Форма контрола в системі одна — прямокутник із радіусом 2px.
   Кругла пігулка була єдиним круглим елементом серед квадратів
   і читалась як чужа. Тач-зона добирається до 44px псевдо-
   елементом, як у §7, щоб смуга лишалась заввишки 36px.       */
.pill{ position:relative; flex:0 0 auto; height:36px; padding:0 var(--s-4);
  display:inline-flex; align-items:center; gap:var(--s-2);
  background:var(--surface); color:var(--soft); cursor:pointer;
  border:var(--hairline) solid var(--line-strong); border-radius:var(--r-sm);
  font-family:var(--font-display); font-weight:500; font-size:11px;
  letter-spacing:.16em; text-transform:uppercase; white-space:nowrap;
  transition:border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease) }
.pill::after{ content:''; position:absolute; inset:50% 0 auto; transform:translateY(-50%); height:44px }
.pill:hover{ color:var(--ink); border-color:var(--ink) }
.pill.has{ color:var(--ink); border-color:var(--ink); box-shadow:inset 0 0 0 1px var(--ink) }
.pill .n{ color:var(--ink) }
.pill .n::before{ content:'·'; margin-right:var(--s-2); color:var(--line-strong) }
.pill svg{ flex:0 0 12px; color:var(--muted) }
.filterbar .sort{ margin-left:auto; flex:0 0 auto }

/* ── Групи фільтрів (живуть у шторці) ─────────────────────── */
.fgroup + .fgroup{ margin-top:var(--s-5); padding-top:var(--s-5); border-top:var(--hairline) solid var(--line) }
/* Заголовок групи тримає висоту 44px замість власного відступу —
   так рядки груп ідуть однією сіткою з рядками значень. */
.fgroup > .t-label{ display:flex; align-items:center; min-height:44px; color:var(--soft) }
.ftiles{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:var(--s-2) }
.ftile{ min-height:44px; display:inline-flex; align-items:center; justify-content:center;
  background:transparent; color:var(--soft); cursor:pointer;
  border:var(--hairline) solid var(--line); border-radius:var(--r-sm);
  font-family:var(--font-body); font-weight:500; font-size:14px;
  transition:border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease) }
.ftile:hover{ color:var(--ink); border-color:var(--line-strong) }
.ftile[aria-pressed="true"]{ color:var(--ink); border-color:var(--ink); box-shadow:inset 0 0 0 1px var(--ink) }
.ftile:disabled{ cursor:not-allowed; color:var(--line-strong); border-color:var(--line) }
/* Рядок фільтра. Квадрат мальований, а не системний: нативний
   чекбокс малює операційна система, і в ньому не діють ні наші
   кольори, ні радіус 2px — поруч із рештою панелі він чужий.
   У прототипі всередині рядка лишається справжній <input>, у темі
   рядок — посилання, тому стан позначає aria-pressed.
   Поле під наведенням виходить за текст на 8px з обох боків —
   інакше підсвітка обривається рівно по літерах.              */
.flist li + li{ margin-top:var(--s-1) }
.frow{ display:flex; align-items:center; gap:var(--s-3); min-height:44px;
  margin:0 calc(-1 * var(--s-2)); padding:0 var(--s-2); border-radius:var(--r-sm);
  font-size:15px; color:var(--body); cursor:pointer;
  transition:background-color var(--t-color) var(--ease-soft), color var(--t-color) var(--ease-soft) }
.frow input{ position:absolute; width:1px; height:1px; opacity:0; margin:0 }
.fbox{ flex:0 0 18px; width:18px; height:18px;
  background-color:var(--surface); background-repeat:no-repeat;
  background-position:center; background-size:12px 12px;
  border:var(--hairline) solid var(--line-strong); border-radius:var(--r-sm);
  transition:background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease) }
.fname{ min-width:0 }
.flist .n{ margin-left:auto; padding-left:var(--s-3); font-size:13px; color:var(--muted) }
.frow:hover{ color:var(--ink); background:var(--wash) }
.frow:hover .fbox{ border-color:var(--ink) }
/* Стан «обрано». Правила розведені навмисно: якби :has стояв в одному
   списку з [aria-pressed], браузер без підтримки :has викинув би весь
   список — і в темі позначка зникла б зовсім.                        */
.frow[aria-pressed="true"]{ color:var(--ink) }
.frow:has(input:checked){ color:var(--ink) }
.frow[aria-pressed="true"] .fbox, .frow input:checked ~ .fbox{
  background-color:var(--ink); border-color:var(--ink);
  background-image:url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27%23fff%27%20stroke-width%3D%273%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27m5%2013%205%205L20%207%27%2F%3E%3C%2Fsvg%3E") }
/* Клавіатурний фокус у прототипі ловить сам input, тому обводку малюємо
   на рядку. У темі рядок — посилання, і його ловить загальне правило. */
.frow:has(input:focus-visible){ outline:var(--focus-ring) solid var(--ink); outline-offset:2px }
.fprice{ display:flex; align-items:center; gap:var(--s-2) }
.fprice input{ width:100%; height:44px; padding:0 var(--s-3); font-family:var(--font-body); font-size:14px;
  color:var(--ink); background:var(--surface);
  border:var(--hairline) solid var(--line-strong); border-radius:var(--r-sm) }
.fprice input:focus{ outline:none; border-color:var(--ink); box-shadow:inset 0 0 0 1px var(--ink) }
.fprice span{ color:var(--muted) }

/* Активні фільтри над сіткою. Відбиті від лінії смуги, інакше
   тег торкається межі й читається як частина смуги.          */
.applied{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--s-2);
  margin:var(--s-5) 0 }
.applied .tag{ display:inline-flex; align-items:center; gap:var(--s-2); min-height:36px;
  padding:0 var(--s-3); font-size:14px; color:var(--ink);
  border:var(--hairline) solid var(--ink); border-radius:var(--r-sm); background:transparent }
/* У прототипі хрестик — кнопка, у темі — посилання (знімає фільтр
   переходом за адресою). Вигляд у них один. */
.applied .tag button, .applied .tag a{ position:relative; background:none; border:0; padding:0; cursor:pointer;
  color:var(--muted); font-size:16px; line-height:1; display:grid; place-items:center;
  width:20px; height:20px }
/* тач-зона 44px без зміни вигляду — §7 */
.applied .tag button::after, .applied .tag a::after{ content:''; position:absolute; inset:50% auto auto 50%;
  transform:translate(-50%,-50%); width:44px; height:44px }
.applied .tag button:hover, .applied .tag a:hover{ color:var(--ink) }
.applied .reset{ background:none; border:0; padding:0 var(--s-2); cursor:pointer;
  font-family:var(--font-display); font-weight:500; font-size:11px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--soft);
  text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:4px }
.applied .reset:hover{ color:var(--ink) }

/* ============================================================
   §10 · СІТКА Й КАРТКА
   ============================================================ */
.grid{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:var(--s-6) var(--s-4) }

.card{ position:relative; display:block }
/* Кадр товару 2:3 — рівно як знімок (1200×1800), тому не ріжеться
   нічого. На Shop-Express вибору не було: платформа рахує пропорції
   десятими частками і вміла тільки 7:10, і зрізала по 43px зверху й
   знизу — голову та кросівки. Тут обмеження немає.                 */
.card-media{ position:relative; aspect-ratio:2/3; background:var(--wash);
  border-radius:var(--r-xs); overflow:hidden }
.card-media img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover }
/* §10 · другий кадр кросфейдом. Платформа вже віддає його
   як span.image-additional з opacity:0 — потрібен лише перехід. */
.shot-alt{ opacity:0; transition:opacity var(--t-media) var(--ease-soft) }
/* Клавіатурі — :focus-visible, а не :focus-within (чому — у коментарі
   біля @media (hover:hover) нижче). Двома правилами, а не списком через
   кому: браузер, який не знає :has(), викинув би список цілком. */
.card:focus-visible .shot-alt{ opacity:1 }
.card:has(:focus-visible) .shot-alt{ opacity:1 }
/* §10 · фото не масштабується при наведенні — зум ламає сітку */

/* §8 · нижній лівий кут: верх кадру — обличчя й груди моделі,
   низ — підлога й кросівки */
.card-stickers{ position:absolute; left:var(--s-3); bottom:var(--s-3); z-index:2;
  display:flex; flex-direction:column; align-items:flex-start; gap:var(--s-1);
  transition:opacity var(--t-media) var(--ease-soft) }
/* ряд розмірів виїжджає в той самий кут — етикетка поступається місцем */
.card:focus-visible .card-stickers{ opacity:0 }
.card:has(:focus-visible) .card-stickers{ opacity:0 }
.card-wish{ position:absolute; top:var(--s-2); right:var(--s-2); z-index:2;
  width:44px; height:44px; display:grid; place-items:center;
  background:none; border:0; cursor:pointer; color:var(--ink) }
.card-wish:hover{ color:var(--soft) }
.card-wish[aria-pressed="true"] svg{ fill:var(--ink) }

/* §10 · ряд розмірів виїжджає знизу, тільки де наведення існує */
.card-quick{ position:absolute; left:0; right:0; bottom:0; z-index:2; display:none; gap:6px;
  justify-content:center; padding:10px;
  background:var(--surface); border-top:var(--hairline) solid var(--line) }
.card-quick span{ min-width:34px; height:28px; display:inline-flex; align-items:center; justify-content:center;
  font-size:13px; color:var(--soft); border:var(--hairline) solid var(--line); border-radius:var(--r-sm) }
.card-quick span.off{ color:var(--muted); border-color:var(--line); position:relative; overflow:hidden }
.card-quick span.off::after{ content:''; position:absolute; inset:0; opacity:.55;
  background:linear-gradient(to top right,transparent calc(50% - .5px),
    currentColor calc(50% - .5px), currentColor calc(50% + .5px), transparent calc(50% + .5px)) }

/* §5 · імʼя товару — спокійний підпис, не заголовок */
.card-title{ margin-top:var(--s-3); font-weight:400; font-size:15px; line-height:1.5; color:var(--ink) }

/* Наведення зібране тут і тільки для миші: на дотику ховера немає —
   тап лишає :hover на картці, і після «назад» вона стоїть розкрита.
   Раніше поруч із :hover у кожному правилі стояв :focus-within — на
   десктопі картка залипала так само: повертаючись «назад», браузер
   віддає фокус посиланню, з якого пішли, і картка лишалася розкритою,
   доки не клацнеш повз. :focus-visible так не робить — фокус від миші
   він не показує, а клавіатурі все віддають правила вище. */
@media (hover:hover) and (pointer:fine){
  .card-quick{ display:flex; opacity:0; transform:translateY(100%);
    transition:opacity var(--t-media) var(--ease-soft), transform var(--t-panel) var(--ease-out) }
  .card:hover .shot-alt{ opacity:1 }
  .card:hover .card-stickers{ opacity:0 }
  .card:hover .card-quick{ opacity:1; transform:none }
  .card:focus-visible .card-quick{ opacity:1; transform:none }
  .card:has(:focus-visible) .card-quick{ opacity:1; transform:none }
  .card:hover .card-title{ text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:4px }
}
/* розшифровка — поле «Розширена назва», платформа кладе її в p.name-details */
.card-details{ margin-top:var(--s-1); font-size:13px; line-height:1.45; color:var(--muted);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden }
.card-price{ margin-top:var(--s-2); font-weight:500; font-size:15px; color:var(--ink);
  font-variant-numeric:tabular-nums }
/* .was і .is-sale тут були з прототипу: WooCommerce друкує <del>/<ins>,
   і на картку клас is-sale ніхто не вішає. Знижку малює база. */

/* ── Догрузка й пагінація ─────────────────────────────────── */
.more{ margin-top:var(--s-7); display:flex; flex-direction:column; align-items:center; gap:var(--s-5) }
.more .progress{ width:min(280px,60%); height:1px; background:var(--line); position:relative }
/* Поки вантажиться наступна порція — кнопка гасне й не приймає клік.
   Смугу прогресу не анімуємо: це геометрія, а за §1 рухаються тільки
   transform і opacity. */
.more.is-loading [data-more-btn]{ opacity:.5; pointer-events:none }
.more .progress i{ position:absolute; inset:0 auto 0 0; width:52%; background:var(--ink) }
.pager{ display:flex; gap:var(--s-2); align-items:center }
.pager a{ min-width:44px; height:44px; display:inline-flex; align-items:center; justify-content:center;
  font-size:14px; color:var(--soft); border:var(--hairline) solid transparent; border-radius:var(--r-sm) }
.pager a:hover{ color:var(--ink) }
.pager a[aria-current="page"]{ color:var(--ink); border-color:var(--ink) }

/* ── Опис категорії ───────────────────────────────────────────
   Стоїть ПІД сіткою: спершу товар, текст — якщо потрібного не знайшлось.
   Розмітка приходить із опису категорії (.cat-intro), тому оформлюємо
   не клас, а те, що всередині: заголовок, абзаци, список.

   Блок іде на всю ширину сітки, а всередині ділиться на дві колонки:
   абзац ліворуч, перелік праворуч. Одна вузька колонка на 72ch висіла
   стовпчиком біля лівого краю й розтягувала низ сторінки; у дві колонки
   той самий текст стає вдвічі нижчим, а рядок лишається читабельним —
   на всю ширину рядок був би на 160 знаків.                       */
.cat-outro{ margin:var(--s-8) 0; padding-top:var(--s-6);
  border-top:var(--hairline) solid var(--line);
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--s-5) var(--s-7); align-items:start }
/* Текст приходить з опису категорії загорнутим у .cat-intro — обгортка
   розчиняється, інакше в колонках лежала б вона одна, а не абзац і перелік */
.cat-outro .cat-intro{ display:contents }
.cat-outro h2{ grid-column:1 / -1;
  font-family:var(--font-display); font-weight:500; font-size:16px;
  line-height:1.5; letter-spacing:.16em; text-transform:uppercase; color:var(--ink) }
.cat-outro p{ font-size:16px; line-height:1.7; color:var(--soft) }
/* У «Нове» і Sale переліку немає — абзац сам займає обидві колонки */
.cat-outro p:only-child{ grid-column:1 / -1 }
.cat-outro ul{ display:grid; gap:var(--s-3) }
.cat-outro li{ position:relative; padding-left:var(--s-5);
  font-size:15px; line-height:1.6; color:var(--body) }
/* риска замість крапки: круглий маркер — єдина куля серед прямих кутів */
.cat-outro li::before{ content:''; position:absolute; left:0; top:.7em;
  width:12px; height:var(--hairline); background:var(--line-strong) }
/* Посилання в тексті — підкреслені, як на інформаційних сторінках:
   колір ink ледь темніший за body, без лінії їх не відрізнити від тексту */
.cat-outro a{ text-decoration:underline; text-decoration-thickness:1px; text-underline-offset:3px }

/* ── Обране ───────────────────────────────────────────────────
   Сітка та картки ті самі, що в каталозі. Своє тут — тільки
   порожній екран і примітка про те, де живе список.           */
.wish-empty{ display:grid; justify-items:start; gap:var(--s-5);
  margin-top:var(--s-7); padding-bottom:var(--s-7) }
/* display у класі перебиває браузерне [hidden]{display:none} — повертаємо */
.wish-empty[hidden], .grid[hidden]{ display:none }
.wish-note{ margin-top:var(--s-7); padding-top:var(--s-5);
  border-top:var(--hairline) solid var(--line) }

/* ── Кнопки прокрутки стрічки ─────────────────────────────────
   Круглі кнопки поверх стрічки по краях, а не окремим рядом:
   ряд забирав висоту й відсував товар. Ховаються, коли стрічка
   вміщається цілком, і гаснуть на межі прокрутки.              */
/* центрування трансформом, а не відступом: -22px не лягає у шкалу §11 */
.entry-nav{ position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  width:44px; height:44px; display:grid; place-items:center; padding:0;
  background:var(--surface); color:var(--ink);
  border:var(--hairline) solid var(--line-strong); border-radius:var(--r-pill);
  box-shadow:var(--elevation); cursor:pointer;
  transition:color var(--t-color) var(--ease-soft), border-color var(--t-fast) var(--ease) }
.entry-nav:hover{ border-color:var(--ink) }
.entry-nav[disabled]{ color:var(--line-strong); border-color:var(--line); cursor:default; box-shadow:none }
/* поле сторінки широке, тому кнопки виносяться за край стрічки —
   так вони не закривають плитку */
.entry-nav.prev{ left:calc(var(--pad-page) * -0.5) }
.entry-nav.next{ right:calc(var(--pad-page) * -0.5) }

/* ── Відступ до підвалу ───────────────────────────────────────
   Пагінація впритул до підвала читається як обрив сторінки. Але й
   128px повітря під нею — це порожній екран на телефоні, тому 64.  */
.more{ margin-bottom:var(--s-8) }



/* ── Шторка фільтрів на вузьких ───────────────────────────── */
.drawer{ position:fixed; inset:0; z-index:70; pointer-events:none; visibility:hidden;
  transition:visibility 0s linear var(--t-panel) }
.drawer.open{ pointer-events:auto; visibility:visible; transition-delay:0s }
.drawer .veil{ position:absolute; inset:0; background:var(--scrim); opacity:0;
  transition:opacity var(--t-panel) var(--ease-out) }
.drawer.open .veil{ opacity:1 }
.drawer .panel{ position:absolute; top:0; bottom:0; left:0; width:min(440px,92%);
  background:var(--surface); border-right:var(--hairline) solid var(--line);
  transform:translateX(-100%); transition:transform var(--t-panel) var(--ease-out);
  display:flex; flex-direction:column }
.drawer.open .panel{ transform:none }
.drawer-head{ flex:0 0 auto; display:flex; align-items:center; justify-content:space-between;
  gap:var(--s-4); padding:var(--s-4) var(--s-5);
  border-bottom:var(--hairline) solid var(--line) }
.drawer-body{ flex:1 1 auto; overflow-y:auto; padding:var(--s-5) }
.drawer-foot{ flex:0 0 auto; display:flex; gap:var(--s-3);
  padding:var(--s-4) var(--s-5) calc(var(--s-4) + env(safe-area-inset-bottom,0px));
  border-top:var(--hairline) solid var(--line); background:var(--surface) }
/* §1, закон 1 · суцільна заливка в системі одна, і це кнопка
   покупки. У шторці фільтрів головна дія — контурна, а
   другорядна — текстова, щоб ієрархія лишилась читною.      */
.drawer-foot .btn-apply{ flex:1 1 auto }
.drawer-foot .btn-ghost{ flex:0 0 auto }

/* ============================================================
   АДАПТИВ
   ============================================================ */
@media (max-width:1023px){
  .grid{ grid-template-columns:repeat(3,minmax(0,1fr)) }
  .t6{ grid-template-columns:repeat(3,minmax(0,1fr)) }
  /* Дві колонки опису мають сенс, поки колонка ширша за 40 знаків */
  .cat-outro{ grid-template-columns:minmax(0,1fr) }
}
@media (max-width:739px){
  .grid{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--s-5) var(--s-3) }
  .cat-head{ align-items:flex-start }
  /* ряд фільтрів: пігулки прокручуються вбік, сортування тисне підпис */
  .filterbar{ gap:var(--s-2) }
  .sort .t-label{ display:none }
  /* Текстовий ряд категорій: дев'ять розділів у стовпчик з'їдають 220px
     першого екрана. Ряд їде вбік так само, як стрічка плиток під ним. */
  .cat-links{ flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none;
    margin-inline:calc(var(--pad-page) * -1); padding-inline:var(--pad-page);
    scroll-padding-inline:var(--pad-page) }
  .cat-links::-webkit-scrollbar{ display:none }
  .cat-links a{ white-space:nowrap }
  /* Ряд фільтрів на телефоні — два рівних контролі, обидва видно одразу.
     Сортування не можна ховати в горизонтальну прокрутку: це основна дія,
     її не шукають гортанням, і частина покупців її просто не знайде.
     Пігулки характеристик тут зайві — що саме обрано, показує ряд плашок
     нижче, а стрибок до групи це один дотик у шторці. */
  .pills{ flex:1 1 auto; overflow:visible }
  .pills .pill:not(.pill-all){ display:none }
  .pill-all{ flex:1 1 auto; justify-content:center }
  .filterbar .sort{ flex:1 1 auto; min-width:0 }
  .sort-menu{ flex:1 1 auto; min-width:0 }
  /* Підпис прибраний, тому назву сортування тримає сама кнопка:
     розкидаємо текст і галочку по краях, щоб вона читалась як поле. */
  .sort-btn{ width:100%; padding:0 var(--s-3); justify-content:space-between }
  .ftiles{ grid-template-columns:repeat(3,minmax(0,1fr)) }
  .t6{ grid-template-columns:repeat(2,minmax(0,1fr)) }
  .t3{ grid-template-columns:minmax(0,1fr) }
  .t3 .tile-media{ aspect-ratio:2/1 }
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{ animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important }
}

/* Шторка фильтров и панель навигации — один компонент дизайн-кода, но
   у фильтров панель шире, а прокручивается тело, не панель целиком.
   Правило заперто на id: header-footer.css грузится последним и иначе
   перебил бы ширину своей, 400px. */
#filtersDrawer .panel{ width:min(440px,92%); overflow-y:visible }

/* Разбивка по страницам: прототип помечает текущую страницу как
   .pager a[aria-current="page"], а WordPress отдаёт <span class="current">.
   Разметка платформы, не дизайн — поэтому правило живёт в теме. */
.pager .page-numbers{ min-width:44px; height:44px;
  display:inline-flex; align-items:center; justify-content:center;
  font-size:14px; color:var(--soft);
  border:var(--hairline) solid transparent; border-radius:var(--r-sm) }
.pager .page-numbers:hover{ color:var(--ink) }
.pager .page-numbers.current{ color:var(--ink); border-color:var(--ink) }
.pager .page-numbers.dots{ min-width:auto; border:0; color:var(--muted) }

/* Ціна зі знижкою переїхала в базу (header-footer.css): вона є не
   тільки в каталозі, і друга копія правила вже розійшлася — на
   сторінці товару червоніли обидві ціни. */
