/* Product detail page only. Depends on tokens.css + base.css. */

/* ============ NAV OVERRIDE (solid, not transparent-over-hero) ============ */
.nav{position:sticky;top:0;background:rgba(255,255,255,.88);backdrop-filter:blur(18px) saturate(1.4);box-shadow:0 1px 0 var(--line)}

/* ============ BREADCRUMB ============ */
.crumb{padding:22px 0 8px;font-family:'JetBrains Mono',monospace;font-size:11.5px;letter-spacing:.1em;color:var(--silver);display:flex;gap:9px;flex-wrap:wrap}
.crumb a:hover{color:var(--ink)}
.crumb span{opacity:.45}

/* ============ PDP LAYOUT ============ */
.pdp{display:grid;grid-template-columns:1.15fr .85fr;gap:clamp(28px,4vw,64px);padding-bottom:clamp(48px,6vw,80px)}

/* --- gallery --- */
.gal{position:sticky;top:92px;align-self:start}
.gal__main{position:relative;aspect-ratio:1/.9;background:linear-gradient(155deg,#F8F9FA 0%,#E4E8EB 100%);border-radius:var(--r-xl);display:grid;place-items:center;padding:6%;overflow:hidden}
.gal__main svg{width:82%;height:auto;transition:transform .5s var(--ease)}
.gal__main:hover svg{transform:scale(1.04)}

/* ФОТОГРАФІЯ поводиться інакше за намальовану графіку, і саме тому все нижче.
   Рамка навколо кадру бралася з padding:6% і градієнта — вони існують, щоб
   намальований силует не торкався країв. Фото ж має заповнювати картку
   повністю: воно вже має власний фон, і поле навколо нього читається як брак.
   :has, а не клас із JS: стан цілком видно з розмітки, і другий спосіб його
   виразити — це другий спосіб із ним розійтися. */
.gal__main:has(.gal__view.on .gal__photo){padding:0;background:var(--mist)}
.gal__photo{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .5s var(--ease);
}
/* Збільшення при наведенні писалося лише для svg, тож із фотографією підказка
   «наведіть, щоб збільшити» обіцяла те, чого не відбувалося. */
.gal__main:hover .gal__photo{transform:scale(1.04)}
@media (prefers-reduced-motion:reduce){
  .gal__main:hover .gal__photo,.gal__main:hover svg{transform:none}
}
/* Кадр заповнює рамку цілком.
   #galViews — елемент сітки .gal__main, і без розтягування він стискався до
   розміру вмісту: фото ставало меншим за рамку, а по краях лишалася сіра
   смуга тла. Саме її було видно як «рамку навколо фото» — не бордер, а
   порожнє місце. Круглі кути дає сама рамка: у неї overflow:hidden. */
.gal__stage{width:100%;height:100%}
.gal__view{display:none;place-items:center;width:100%;height:100%}
.gal__view.on{display:grid}
/* Обгортка навколо намальованої графіки — та, що несе role="img". Для фото її
   немає, тож правила мусять діяти в обох випадках. */
.gal__frame{display:contents}
.gal__tag{position:absolute;top:20px;left:20px;height:28px;padding:0 14px;border-radius:var(--pill);background:var(--volt);color:#fff;font-family:'JetBrains Mono',monospace;font-size:10px;letter-spacing:.14em;text-transform:uppercase;display:inline-flex;align-items:center}
.gal__zoom{position:absolute;bottom:20px;right:20px;height:38px;padding:0 17px;
  border:0;border-radius:var(--pill);background:rgba(255,255,255,.88);
  backdrop-filter:blur(8px);box-shadow:0 2px 10px rgba(23,26,32,.12);
  font-family:'JetBrains Mono',monospace;font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--graphite);cursor:pointer;
  display:flex;align-items:center;gap:8px;transition:background .16s var(--ease)}
.gal__zoom:hover{background:#fff}
.thumbs{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-top:12px}
.thumb{aspect-ratio:1;background:var(--mist);border-radius:var(--r-md);border:2px solid transparent;display:grid;place-items:center;padding:12%;transition:border-color .18s var(--ease),background .18s var(--ease);overflow:hidden}
/* Те саме для мініатюр: поле навколо намальованого силуету доречне, навколо
   фотографії — ні. */
.thumb:has(.thumb__photo){padding:0}
.thumb__photo{width:100%;height:100%;object-fit:cover;display:block}
.thumb:hover{background:var(--cloud)}
.thumb.on{border-color:var(--graphite);background:#fff}
.thumb svg{width:100%;height:auto}

/* --- info column --- */
.info{display:flex;flex-direction:column;gap:22px;padding-top:4px}
.info__sku{font-family:'JetBrains Mono',monospace;font-size:11.5px;letter-spacing:.12em;color:var(--silver)}
.info h1{font-size:clamp(28px,3.4vw,42px);font-weight:600;line-height:1.05;margin-top:8px}
.rating{display:flex;align-items:center;gap:10px;font-size:13.5px;color:var(--silver);margin-top:12px}
.stars{display:flex;gap:2px}
.info__lede{font-size:16px;line-height:1.6;color:var(--silver);max-width:46ch}

.priceRow{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.priceRow b{font-family:'Outfit',sans-serif;font-size:38px;font-weight:600;line-height:1}
.priceRow s{color:var(--silver);font-size:19px}
/* --go-ink, а не --go: tokens.css прямо каже, що --go на --go-bg дає 3,93:1
   і не проходить AA для дрібного тексту — заради цього --go-ink і заведено
   (5,21 на цьому ж тлі). Та сама пара кольорів, що на картці в сітці. */
.priceRow em{font-style:normal;background:var(--go-bg);color:var(--go-ink);font-size:12.5px;font-weight:700;padding:5px 12px;border-radius:var(--pill)}
.priceRow small{width:100%;color:var(--silver);font-size:13px;font-family:'JetBrains Mono',monospace}

/* --- option groups ---
   These are <fieldset><legend> with native radios inside the labels. They were
   <button>s carrying selection in a CSS class only, which meant a screen reader
   announced every choice identically whether it was picked or not. Radios also
   bring arrow-key navigation within the group for free.
   The visual is unchanged: the input is hidden and :has(:checked) does the work. */
.opt{border:0;padding:0;margin:0}
.opt__lbl{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:11px;width:100%;padding:0}
.opt__lbl span{font-family:'JetBrains Mono',monospace;font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--silver)}
.opt__lbl b{font-family:'Outfit',sans-serif;font-size:15px;font-weight:600}
.opt__row{display:flex;gap:10px;flex-wrap:wrap}

/* Never display:none — that removes the radio from the tab order entirely. */
.sw input,.pick input{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}

/* --ctrl-line, не --line. Це видима межа елемента керування — кружечок
   кольору й пігулка розміру, — а --line дає 1,26:1 на білому, тобто пряме
   невиконання 1.4.11. Помітно це лише тому, що всередині нічого немає: у
   .sw колір товару, у .pick текст, і межа тут єдине, що каже, де саме
   починається натискна ділянка. */
.sw{width:52px;height:52px;border-radius:var(--pill);position:relative;border:2px solid var(--ctrl-line);padding:4px;cursor:pointer;
  display:block;transition:border-color .18s var(--ease),transform .18s var(--ease)}
.sw i{display:block;width:100%;height:100%;border-radius:var(--pill)}
.sw:hover{transform:scale(1.06)}
.sw:has(input:checked){border-color:var(--graphite)}
.sw:has(input:focus-visible){outline:3px solid var(--volt);outline-offset:3px}

.pick{height:50px;padding:0 22px;border-radius:var(--pill);border:1.5px solid var(--ctrl-line);background:#fff;font-size:14.5px;font-weight:600;cursor:pointer;
  position:relative;display:inline-flex;align-items:center;gap:9px;transition:border-color .18s var(--ease),background .18s var(--ease),color .18s var(--ease)}
.pick:hover{border-color:var(--graphite)}
.pick:has(input:checked){background:var(--graphite);border-color:var(--graphite);color:#fff}
.pick:has(input:focus-visible){outline:3px solid var(--volt);outline-offset:3px}
.pick small{font-family:'JetBrains Mono',monospace;font-size:11px;opacity:.6}

/* --- fitment box (signature) --- */
.fitbox{border-radius:var(--r-lg);padding:22px;background:var(--graphite);color:#fff}
.fitbox__t{display:flex;align-items:center;gap:10px;font-family:'Outfit',sans-serif;font-size:16px;font-weight:600;margin-bottom:15px}
.fitbox__form{display:grid;grid-template-columns:1fr 1fr auto;gap:9px}
.fsel{position:relative}
.fsel select{-webkit-appearance:none;appearance:none;width:100%;height:50px;padding:0 36px 0 17px;background:rgba(255,255,255,.09);
  border:1px solid rgba(255,255,255,.18);border-radius:var(--pill);color:#fff;font-size:14.5px;font-weight:600;cursor:pointer}
.fsel select:focus{border-color:#fff;outline:none}
.fsel option{color:#111;background:#fff}
.fsel::after{content:'';position:absolute;right:18px;top:20px;width:8px;height:8px;border-right:2px solid rgba(255,255,255,.6);border-bottom:2px solid rgba(255,255,255,.6);transform:rotate(45deg);pointer-events:none}
.fitbox .btn{height:50px;padding:0 26px}
.verdict{display:none;align-items:center;gap:13px;padding:15px 18px;border-radius:var(--r-md);font-size:14.5px;font-weight:600;line-height:1.4}
.verdict.on{display:flex}
.verdict--yes{background:rgba(18,138,75,.18);color:#5FE3A1}
.verdict--no{background:rgba(227,25,55,.16);color:#FF8B9E}
.verdict button{margin-left:auto;font-size:12px;font-weight:600;text-decoration:underline;opacity:.75;white-space:nowrap}

/* --- buy row --- */
.buy{display:flex;gap:12px;align-items:stretch}
.stepper{display:flex;align-items:center;gap:2px;border:1.5px solid var(--line);border-radius:var(--pill);padding:3px;flex:none}
.stepper button{width:42px;height:52px;border-radius:var(--pill);display:grid;place-items:center;font-size:19px;transition:background .16s var(--ease)}
.stepper button:hover{background:var(--mist)}
.stepper span{min-width:30px;text-align:center;font-family:'JetBrains Mono',monospace;font-size:15px}
/* Was a <span>; now a real input so the value is announced and typeable.
   Spinners hidden — the − / + buttons are the visual control. */
.stepper input{width:44px;text-align:center;font-family:'JetBrains Mono',monospace;font-size:15px;
  border:0;background:none;-moz-appearance:textfield;appearance:textfield}
.stepper input::-webkit-outer-spin-button,
.stepper input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.fit-err{color:var(--volt);font-size:13px;font-weight:600;margin-top:10px}
.fit-err:empty{display:none}
.buy .btn{flex:1}

.assure{display:flex;flex-direction:column;gap:11px;padding-top:4px}
.assure div{display:flex;align-items:center;gap:11px;font-size:14px;color:var(--silver)}
.assure svg{flex:none}
.assure b{color:var(--ink);font-weight:700}

/* ============ DETAIL SECTIONS ============ */
.sec{padding:clamp(52px,6vw,86px) 0}
.sec--mist{background:var(--mist)}
.sec__h{font-size:clamp(24px,3vw,36px);font-weight:600;margin-bottom:30px}

.cols{display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,4vw,60px)}
.prose p{font-size:16.5px;line-height:1.7;color:var(--silver);margin-bottom:16px;max-width:56ch}
.prose p strong{color:var(--ink);font-weight:700}

.spectable{width:100%;border-collapse:collapse;background:#fff;border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow-1)}
.spectable tr{border-bottom:1px solid var(--line)}
.spectable tr:last-child{border-bottom:0}
.spectable th{text-align:left;padding:15px 22px;font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--silver);font-weight:400;width:52%}
.spectable td{padding:15px 22px;font-family:'Outfit',sans-serif;font-size:15.5px;font-weight:600;text-align:right}

.boxlist{list-style:none;display:flex;flex-direction:column;gap:13px}
.boxlist li{display:flex;gap:13px;align-items:flex-start;font-size:15.5px;line-height:1.5}
.boxlist svg{flex:none;margin-top:3px}

.install{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:26px}
.icard{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:24px}
.icard span{font-family:'JetBrains Mono',monospace;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--silver);display:block;margin-bottom:9px}
.icard b{font-family:'Outfit',sans-serif;font-size:21px;font-weight:600;display:block}
.icard p{font-size:13.5px;color:var(--silver);margin-top:6px;line-height:1.5}

/* --- reviews --- */
.rev{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:26px;display:flex;flex-direction:column;gap:12px}
.rev p{font-size:15px;line-height:1.6;color:var(--silver)}

/* --- related --- */
.rel{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.rcard{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;transition:transform .22s var(--ease),box-shadow .22s var(--ease),border-color .22s var(--ease)}
.rcard:hover{transform:translateY(-6px);box-shadow:var(--shadow-2);border-color:transparent}
.rcard__img{aspect-ratio:1/.86;background:linear-gradient(160deg,#F7F8F9,#E7EAEC);display:grid;place-items:center;padding:20px}
.rcard__img svg{width:72%}
.rcard__img:has(.art__photo){padding:0}
.rcard__b{padding:18px 20px 22px}
.rcard__b span{font-family:'JetBrains Mono',monospace;font-size:11px;color:var(--silver)}
.rcard__b b{font-family:'Outfit',sans-serif;font-size:16.5px;font-weight:600;display:block;margin:6px 0 12px;line-height:1.25}
.rcard__b em{font-style:normal;font-family:'Outfit',sans-serif;font-size:20px;font-weight:600}

/* --- sticky buy bar --- */
.stickybar{position:fixed;left:0;right:0;bottom:var(--cc-h);z-index:75;background:rgba(255,255,255,.94);backdrop-filter:blur(18px);
  box-shadow:0 -1px 0 var(--line),0 -12px 40px rgba(15,17,18,.07);
  /* visibility, or #stickyAdd is a focusable invisible "Add to cart" from load */
  transform:translateY(110%);visibility:hidden;
  transition:transform .34s var(--ease),visibility 0s linear .34s}
.stickybar.on{transform:translateY(0);visibility:visible;
  transition:transform .34s var(--ease),visibility 0s}
.stickybar__in{max-width:var(--maxw);margin:0 auto;padding:14px var(--pad);display:flex;align-items:center;justify-content:space-between;gap:18px}
.stickybar__l{display:flex;align-items:center;gap:16px;min-width:0}
.stickybar__l svg{width:48px;height:48px;flex:none;background:var(--mist);border-radius:var(--r-sm);padding:6px}
/* Тепер тут буває і справжнє фото, і схема — однакового розміру, інакше
   панель стрибає у висоту залежно від того, чи є в товару знімок. */
.stickybar__l img{width:48px;height:48px;flex:none;object-fit:cover;border-radius:var(--r-sm);display:block}
.stickybar__l>span:first-child{flex:none;display:block}
.stickybar__l b{font-family:'Outfit',sans-serif;font-size:16px;font-weight:600;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stickybar__l span{font-family:'JetBrains Mono',monospace;font-size:11.5px;color:var(--silver)}
.stickybar__r{display:flex;align-items:center;gap:16px}
.stickybar__r b{font-family:'Outfit',sans-serif;font-size:22px;font-weight:600}

/* --- toast --- */
.toast{position:fixed;bottom:calc(24px + var(--cc-h));left:50%;transform:translate(-50%,140%);z-index:90;background:var(--graphite);color:#fff;
  padding:15px 26px;border-radius:var(--pill);font-size:14.5px;font-weight:600;box-shadow:var(--shadow-3);
  visibility:hidden;
  transition:transform .34s var(--ease),visibility 0s linear .34s;display:flex;align-items:center;gap:10px}
.toast.on{transform:translate(-50%,0);visibility:visible;
  transition:transform .34s var(--ease),visibility 0s}
.toast__x{margin-left:4px;color:#fff;opacity:.7;font-size:18px;line-height:1}
.toast__x:hover{opacity:1}

/* --- footer --- */
.foot{background:var(--graphite);color:#fff;padding:clamp(48px,6vw,74px) 0 32px}
.foot__grid{display:grid;grid-template-columns:1.6fr repeat(3,1fr);gap:40px}
.foot__brand p{color:rgba(255,255,255,.55);font-size:14.5px;line-height:1.6;max-width:34ch;margin-top:16px}
.foot h4{font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:rgba(255,255,255,.45);margin-bottom:16px;font-weight:400}
.foot ul{list-style:none;display:flex;flex-direction:column;gap:11px}
.foot ul a{color:rgba(255,255,255,.82);font-size:14.5px}
.foot ul a:hover{color:#fff}
.foot__bar{margin-top:48px;padding-top:24px;border-top:1px solid rgba(255,255,255,.13);display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap;font-size:12.5px;color:rgba(255,255,255,.45);font-family:'JetBrains Mono',monospace}

/* --- reveal ---
   .js, а не голий .rv — та сама причина, що в base.css: opacity:0 прибирає
   пікселі й НЕ прибирає з порядку табуляції, тож без скриптів таб заходив у
   невидимий блок разом із невидимим фокусним кільцем. Без цієї приставки
   виправлення в base.css сюди не діставало б: місцеве .rv лишалося б чинним
   саме тоді, коли .js немає. */
.js .rv{opacity:0;transform:translateY(20px);transition:opacity .7s var(--ease),transform .7s var(--ease)}
.js .rv.in{opacity:1;transform:none}
.js .rv:focus-within{opacity:1;transform:none;transition:none}

/* ============ RESPONSIVE ============ */
@media(max-width:1080px){
  .rel{grid-template-columns:repeat(2,1fr)}
  .revs{grid-template-columns:1fr}
  .foot__grid{grid-template-columns:1fr 1fr}
}
@media(max-width:900px){
  .pdp{grid-template-columns:1fr}
  .gal{position:static}
  /* visibility:hidden поруч із opacity:0, і не для краси. Прозорість прибирає
     пікселі, pointer-events — мишу, а порядок табуляції не чіпає жодне з них:
     закрите меню лишалося пасткою з чотирьох невидимих посилань, крізь яку
     людина з клавіатурою проходила з невидимим кільцем фокусу. Те саме
     правило вже стояло в home.css і не було перенесене сюди.

     transition окремим переліком, а не `all`: visibility мусить перемикатися
     ПІСЛЯ згасання (затримка .26s) і НЕГАЙНО при відкритті — інакше меню
     зʼявляється, коли анімація вже скінчилася. */
  .nav__links{position:fixed;top:70px;left:12px;right:12px;background:#fff;border-radius:var(--r-lg);flex-direction:column;padding:12px;box-shadow:var(--shadow-3);opacity:0;pointer-events:none;visibility:hidden;transform:translateY(-10px);
    transition:opacity .26s var(--ease),transform .26s var(--ease),visibility 0s linear .26s}
  .nav__links.on{opacity:1;pointer-events:auto;visibility:visible;transform:none;
    transition:opacity .26s var(--ease),transform .26s var(--ease),visibility 0s}
  .nav__links a{padding:14px 18px;font-size:16px}
  .burger{display:grid}
  .cols{grid-template-columns:1fr}
  .install{grid-template-columns:1fr}
}
@media(max-width:620px){
  .fitbox__form{grid-template-columns:1fr}
  .rel{grid-template-columns:1fr 1fr;gap:12px}
  .rcard__b b{font-size:14.5px}
  .buy{flex-wrap:wrap}
  .buy .btn{width:100%;flex:auto}
  .stickybar__l span,.stickybar__r b{display:none}
  .foot__grid{grid-template-columns:1fr}
  .priceRow b{font-size:32px}
}
@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition-duration:.01ms!important}
  /* .js .rv, а не .rv: приховування тепер має вагу (0,2,0), і рядок на
     (0,1,0) програв би йому — тобто «менше руху» лишав би блок схованим
     назавжди. Копія тут застаріла ще до цього (канонічна в base.css), але
     мовчки зламатися вона встигла б. */
  .js .rv{opacity:1;transform:none}
  html{scroll-behavior:auto}
}

/* ============ ПОКУПКА ЧАСТИНАМИ ============
   Стоїть після кнопки купівлі, поруч з умовами доставки й повернення. Тон
   стриманий навмисно: це обовʼязкове розкриття умов, а не друга кнопка, і
   змагатися за увагу з «У кошик» воно не повинне. */
.parts{background:var(--mist);border-radius:var(--r-md);padding:18px 20px;margin-top:18px}
.parts__h{font-family:'Outfit',sans-serif;font-size:16px;margin:0 0 6px}
.parts__tag{font-size:14px;color:var(--silver);margin:0 0 10px;line-height:1.55}
.parts__fig{font-size:15px;font-weight:600;margin:0 0 8px;line-height:1.5}
/* .legal приходить із pages.css; тут лише розкладка всередині картки. */
.parts__legal{margin-top:12px;padding-top:12px}
.parts__legal p{margin:0 0 7px}
.parts__legal p:last-child{margin-bottom:0}
/* Підзаголовки банку — його ж слова, тож виділяються вагою, а не розміром:
   зменшувати їх означало б опустити частину тексту нижче за дозволену межу. */
.parts__legalh{font-weight:600;color:var(--ink)}
.parts__spec{margin:0 0 9px;padding-left:18px}
.parts__spec li{margin-bottom:3px}
.parts__cta{font-size:14px;margin:0 0 8px;color:var(--go-ink)}
.parts__cta[hidden]{display:none}
.parts__terms{margin:0;font-size:13.5px}
.parts__terms a{text-decoration:underline;text-underline-offset:3px;color:var(--silver)}
.parts__terms a:hover{color:var(--ink)}
/* Розмір ПОКАЗУ тут; width/height у розмітці — розміри файлу.
   height:auto лишається явно, хоч tokens.css його вже дає глобально: це
   рівно та властивість, чия відсутність розплющує знак, і мовчки. Плашка
   #121211 запечена в растр (RGB, без альфа-каналу), тож CSS-фон під нею
   нічого не давав би — а background-color ще й перший у списку того, що
   примусові кольори знімають. */
.parts__logo{width:132px;height:auto;margin:0 0 12px}

@media(forced-colors:active){
  .parts{border:1px solid CanvasText}
  /* Сам растр примусові кольори не чіпають — білий напис на #121211 лишається
     читабельним за будь-якої теми. Зникає тло КАРТКИ: воно стає Canvas, а під
     темною темою Canvas чорний і сходиться з плашкою знака майже впритул, тож
     у логотипа не лишається краю. Контур його повертає.
     Не forced-color-adjust:none — нічому тут не треба зберігати колір, а
     вимкнувши підлаштування, ми виписали б і власний CanvasText-контур із
     палітри користувача, тобто скасували б саме те, що щойно додали. */
  .parts__logo{outline:1px solid CanvasText;outline-offset:-1px}
}


/* Підзаголовок розділу опису. Менший за «У комплекті» поруч, бо той відкриває
   інший блок, а ці — рівні один одному всередині одного тексту. */
.prose__h{font-family:'Outfit',sans-serif;font-size:17px;font-weight:600;
  margin:22px 0 8px;letter-spacing:-.01em}
.prose__h:first-child{margin-top:0}

/* Підпис під намальованим кадром. Не попередження — ілюстрація законна, вона
   просто не є знімком цього примірника; тон нейтральний, а несе все слово.
   Позиція знизу кадру, у потоці сітки: .gal__view — grid, тож підпис стає
   другим рядком і нічого не перекриває. */
.gal__drawn{
  margin:10px 0 0;font-size:12.5px;line-height:1.4;
  color:var(--silver);text-align:center;
}
.gal__drawn[hidden]{display:none}

/* ============ ПИТАННЯ ПРО ТОВАР ============ */

.qlist{list-style:none;padding:0;margin:0 0 34px;display:grid;gap:16px}
.qitem{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-md);padding:18px 20px}
.qitem__meta{margin:0 0 8px;font-size:13px;color:var(--silver)}
.qitem__q{margin:0 0 12px;font-size:16px;line-height:1.55}
.qitem__a{margin:0;font-size:15.5px;line-height:1.6;color:var(--silver);
  padding-left:16px;border-left:2px solid var(--line)}

/* «Питання» / «Відповідь Volta Shop» — справжній текст, а не оформлення. Хто автор,
   на слух інакше не дізнатися: відступ і рамка ліворуч існують лише для очей. */
.qitem__tag{
  display:inline-block;margin-right:8px;
  font-family:'JetBrains Mono',monospace;font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--silver);
}
.qitem__a .qitem__tag{color:var(--ink)}

/* Картка форми. Ширина обмежена не для краси: рядок уводу на всю сторінку
   змушує вести очима туди й назад, а поле для імені завширшки 1100 px ще й
   бреше про те, скільки туди треба написати. */
.qask{background:var(--mist);border-radius:var(--r-lg);padding:30px 32px;max-width:620px}
.qask__h{font-family:'Outfit',sans-serif;font-size:21px;font-weight:600;margin:0 0 22px}

/* ── Поля ─────────────────────────────────────────────────────────────────
   Ці правила довелося написати тут, а не взяти з pages.css: .field2 живе
   ТІЛЬКИ там, а product.html підключає product.css. Форма приїхала на
   сторінку з браузерними рамками в один піксель і підписами збоку — тобто
   виглядала як помилка, хоча кожен клас у розмітці був на місці.
   Спільний файл для обох сторінок був би правильніший, але переносити базу
   форм між таблицями заради одного блоку — це змінити вигляд checkout,
   order і cart наосліп. */
.qask .field2{display:flex;flex-direction:column;margin-bottom:20px}
.qask label{font-size:13.5px;font-weight:600;margin-bottom:8px}

/* «необовʼязково» — не частина назви поля, а примітка до неї, і читається
   саме так: тихіше, ніж підпис, і не жирним. */
.lbl-opt{color:var(--silver);font-weight:400;font-size:12.5px;
  font-family:'JetBrains Mono',monospace;letter-spacing:.04em;
  margin-left:8px;padding:2px 8px;border-radius:var(--pill);background:var(--cloud)}

.qask input,
.qask textarea{
  width:100%;font:inherit;font-size:15.5px;color:var(--ink);
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-sm);
  padding:14px 16px;min-height:52px;
  /* Тінь усередину замість зовнішньої: поле лежить на світлому тлі картки, і
     зовнішня тінь тут читалася б як підняття, а поле вводу нічого не піднімає. */
  box-shadow:inset 0 1px 2px rgba(23,26,32,.04);
  transition:border-color .15s, box-shadow .15s}

.qask textarea{min-height:120px;resize:vertical;line-height:1.55}

/* Наведення й фокус — це різні речі, і показувати їх однаково означає не
   показувати жодного. Рамка фокуса лишається глобальна (tokens.css), тут
   тільки колір межі, щоб поле не блимало двома кольорами одночасно. */
.qask input:hover,
.qask textarea:hover{border-color:var(--silver)}
.qask input:focus,
.qask textarea:focus{border-color:var(--graphite);
  box-shadow:inset 0 1px 2px rgba(23,26,32,.04), 0 0 0 3px rgba(23,26,32,.07)}
.qask input:focus:not(:focus-visible),
.qask textarea:focus:not(:focus-visible){outline:none}

.qask input[aria-invalid="true"],
.qask textarea[aria-invalid="true"]{border-color:var(--volt-ink);
  box-shadow:inset 0 1px 2px rgba(23,26,32,.04), 0 0 0 3px rgba(227,25,55,.1)}

.qask .hint{color:var(--silver);font-size:13px;line-height:1.5;margin:8px 0 0}

/* Порожній абзац помилки не має займати місця — інакше під кожним полем
   лишається діра, розміром із помилку, якої немає. :empty робить це без
   другого атрибута, який треба не забути зняти. */
.qask .fielderr{color:var(--volt-ink);font-size:13.5px;font-weight:600;margin:8px 0 0}
.qask .fielderr:empty{display:none}

.qask .formerr{background:var(--volt-bg);color:var(--volt-ink);border-radius:var(--r-sm);
  padding:13px 16px;font-size:14.5px;line-height:1.5;margin:0 0 20px}

.qask button[type="submit"]{margin-top:4px}

/* На вузькому екрані кнопка на всю ширину: у неї найбільша ціль дотику на
   сторінці, і різати її до тексту немає причини. */
@media (max-width:520px){
  .qask{padding:24px 20px;border-radius:var(--r-md)}
  .qask button[type="submit"]{width:100%}
}

/* Підтвердження стає на місце форми. Не сповіщення, що зникає: це єдиний слід
   того, що питання надіслано, і він має лишатися доти, доки людина на сторінці. */
.qsent{padding:4px 0}
.qsent p{margin:0 0 8px;line-height:1.55}
.qsent p:last-child{margin-bottom:0;color:var(--silver)}

/* ---- оцінка під назвою ---- */
.rating{display:flex;align-items:center;gap:10px;margin-top:10px;flex-wrap:wrap}
.stars{display:inline-flex;gap:2px;line-height:0}
.rating__n{font-size:14.5px;font-weight:600}
.rating__c{font-size:13.5px;color:var(--silver)}

/* Зірки намальовані кольором, і в режимі високої контрастності Windows усі
   SVG стають однією фарбою — п'ять однакових фігур замість оцінки. Число
   поруч лишається, і в цьому режимі воно єдине щось значить. */
@media(forced-colors:active){ .stars{display:none} }

/* ============ ЗБІЛЬШЕНЕ ФОТО ============ */

.lbox__scrim{position:fixed;inset:0;z-index:180;background:rgba(15,17,18,.86);
  backdrop-filter:blur(4px)}
.lbox__scrim[hidden]{display:none}

.lbox{position:fixed;inset:0;z-index:181;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:16px;padding:56px 20px 24px}
.lbox[hidden]{display:none}

/* Кадр не більший за екран у жодному вимірі: збільшене фото, яке треба
   гортати, — це не збільшене фото, а сторінка. */
.lbox__stage{display:flex;align-items:center;justify-content:center;
  max-width:min(1100px,100%);max-height:calc(100vh - 190px)}
.lbox__img{max-width:100%;max-height:calc(100vh - 190px);
  width:auto;height:auto;object-fit:contain;border-radius:var(--r-md);display:block}
.lbox__art{width:min(560px,80vw);display:grid;place-items:center}
.lbox__art svg{width:100%;height:auto}

.lbox__cap{color:#C9CCCF;font-size:13px;text-align:center;margin:0}
.lbox__cap[hidden]{display:none}

.lbox__x{position:absolute;top:16px;right:16px;width:44px;height:44px;
  border:0;border-radius:var(--pill);background:rgba(255,255,255,.14);color:#fff;
  display:grid;place-items:center;cursor:pointer}
.lbox__x:hover{background:rgba(255,255,255,.24)}

.lbox__nav{display:flex;align-items:center;gap:18px}
.lbox__nav[hidden]{display:none}
.lbox__arw{min-height:44px;padding:0 20px;border:0;border-radius:var(--pill);
  background:rgba(255,255,255,.14);color:#fff;font:inherit;font-size:13.5px;
  font-weight:600;cursor:pointer}
.lbox__arw:hover{background:rgba(255,255,255,.24)}
.lbox__n{color:#C9CCCF;font-family:'JetBrains Mono',monospace;font-size:12px}

/* Рамка фокуса на темному тлі: червона з tokens.css на майже чорному видно
   гірше, ніж треба, тож тут вона біла. Товщина й відступ ті самі. */
.lbox :focus-visible{outline:3px solid #fff;outline-offset:3px}

/* У режимі високої контрастності напівпрозорі підкладки зникають разом із
   кнопками, які вони малюють. Повертаємо їм межу. */
@media(forced-colors:active){
  .lbox__x,.lbox__arw{border:1px solid ButtonBorder;background:ButtonFace;color:ButtonText}
}

/* ============ ХАРАКТЕРИСТИКИ: ЗАГОЛОВОК ТАБЛИЦІ Й РОЗКРИТТЯ ============ */

/* caption видимий, а не .sr-only. Він і є назвою групи: читалка промовляє
   його при переході по таблицях, а зряча людина бачить, де закінчується
   «Батарея» і починаються «Порти». Заголовком <h3> це коштувало б зайвих
   рядків у структурі документа поруч із тими, що вже малює renderDetail(). */
.spectable caption{caption-side:top;text-align:left;font-family:'Outfit',sans-serif;
  font-size:15px;font-weight:600;padding:18px 22px 6px}
.spectable + .spectable{margin-top:14px}

/* Дві колонки, тож таблиця складається до 320 px сама. display:block тут НЕ
   застосовуємо ніде: він знищує звʼязок заголовка рядка зі значенням, тобто
   ламає рівно те, заради чого це таблиця. Горизонтальної прокрутки з
   role="region" теж не треба — це була б зайва зупинка табуляції заради
   таблиці, яка чудово переноситься. */
@media(max-width:620px){
  .spectable th,.spectable td{width:auto;padding:13px 15px}
  .spectable td{overflow-wrap:anywhere}
  .spectable caption{padding:15px 15px 5px}
}

/* Розкриття — нативний <details>, за зразком .faq. Він дає клавіатуру,
   оголошення стану й пошук по сторінці; кнопка з aria-expanded і схованими
   рядками останнього не вміє. */
.specmore{margin-top:16px;border-top:1px solid var(--line)}
.specmore summary{cursor:pointer;padding:17px 4px;list-style:none;display:flex;
  align-items:center;justify-content:space-between;gap:16px;
  font-family:'Outfit',sans-serif;font-size:15px;font-weight:600}
.specmore summary::-webkit-details-marker{display:none}
.specmore summary::after{content:"+";font-size:22px;color:var(--silver);flex:none;line-height:1}
.specmore[open] summary::after{content:"\2212"}
.specmore summary:hover{color:var(--volt-ink)}
.specmore[open] > div{padding-bottom:6px}

/* ============ КАЛЬКУЛЯТОР ЧАСУ РОБОТИ ============ */
.calc{display:grid;gap:20px;max-width:74ch}
.calc__set{border:0;padding:0;margin:0}
.calc__row{display:flex;gap:10px;flex-wrap:wrap}

/* Пігулка приладу вища за звичайну .pick: у ній два рядки — назва й вати. */
.pick--calc{height:auto;min-height:50px;padding:9px 20px;flex-direction:column;
  align-items:flex-start;gap:2px;line-height:1.25}
.pick--calc small{opacity:.72}
.pick--calc:has(input:checked) small{opacity:.85}

.calc__out{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);
  padding:22px 24px}
.calc__load{font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--silver)}
.calc__time{font-family:'Outfit',sans-serif;font-size:clamp(24px,4vw,30px);
  font-weight:600;margin-top:8px;line-height:1.2}

/* Ліва смуга плюс слово «Перевантаження» на місці часу плюс речення з обома
   числами. Колір тут четвертий сигнал, а не перший.

   --warn, а НЕ --volt: синій тепер акцент бренду, тобто колір кнопки «купити».
   Пофарбувати ним попередження означало б, що тривога виглядає точно як
   заклик до дії, і жодне з двох значень уже не читається. Токен --warn для
   того й заведений окремо. */
.calc__warn{margin-top:14px;padding:14px 16px;border-radius:var(--r-md);
  background:var(--warn-bg);border-left:4px solid var(--warn);
  color:var(--warn);font-size:14px;font-weight:600;line-height:1.5}

/* ============ КЛЮЧОВІ ЧИСЛА ============
   На місці, де стояла коробка перевірки сумісності, і з тим самим темним тлом:
   це так само перше, за чим сюди приходять, і воно так само має вирізнятися
   з-поміж решти сторінки.

   <dl> у сітку. Пара в <div>, щоб підпис і значення трималися разом при
   переносі — без обгортки grid розкладає dt і dd як окремі елементи, і на
   вузькому екрані «Пікова» опиняється під числом від «Потужність». */
.keynums{border-radius:var(--r-lg);padding:22px;background:var(--graphite);color:#fff}
.keynums dl{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:18px}
.keynums dt{font-family:'JetBrains Mono',monospace;font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:rgba(255,255,255,.62);margin-bottom:5px}
.keynums dd{font-family:'Outfit',sans-serif;font-size:23px;font-weight:600;line-height:1.1}
.keynums dd small{font-size:13px;font-weight:400;color:rgba(255,255,255,.72)}

/* --volt-on-dark, а не --volt: акцент розрахований на світле тло і на графіті
   дає близько двох до одного. Окремий токен заведено саме для цього випадку. */
.keynums__more{display:inline-block;margin-top:18px;font-size:14px;font-weight:600;
  color:var(--volt-on-dark);text-decoration:underline;text-underline-offset:3px}
.keynums__more:hover{color:#fff}
