/* ============================================================================
   blog.css — стилі розділу /blog/ (вітрина + сторінка статті)
   ShockWave Trade · Фаза 1 плану plans/2026-08-14-blog-static-rebuild.md

   ЧОМУ ОКРЕМИЙ ФАЙЛ, А НЕ ІНЛАЙН, ЯК НА РЕШТІ САЙТУ
   Інлайновий CSS оптимальний для ОДНІЄЇ сторінки: економить запит, який усе одно
   зробили б. Розділ блогу — це десятки, згодом сотні документів; той самий CSS,
   вкладений у кожен, помножується на кількість сторінок і не кешується між ними.
   Тому: критичний мінімум (~4 КБ) інлайном у шаблоні, решта — цей файл із ?v=N.
   Білд-системи це не вводить (P3): деплой лишається копіюванням файлу як є.

   ПРАВИЛА, ЯКІ ТУТ НЕ МОЖНА ПОРУШУВАТИ
   · жодної ваги 700 — Montserrat підключений як «400 600», 700 браузер
     клампить до 600, і макет розійдеться з кодом (AC-019);
   · жодного кольору повз токени — усе нижче або наявний токен, або альфа-похідна
     від --text / --accent (AC-019);
   · контраст тіла й підписів ≥ 7:1 (AAA) — значення пораховані, див. :root (AC-018);
   · нових мережевих залежностей немає: шрифти локальні, Google Fonts не підключається.

   ПОРЯДОК РОЗДІЛІВ
   1. Шрифти · 2. Токени · 3. Базове · 4. Доступність · 5. Хедер · 6. Футер
   7. Вітрина · 8. Пагінація · 9. Стаття · 10. Тіло статті · 11. Блоки статті
   12. Адаптив · 13. prefers-reduced-motion
   ============================================================================ */


/* ===== 1. ШРИФТИ — лише локальні ============================================
   Ті самі файли й ті самі unicode-range, що в index.html / blog.html.
   Barlow з Google Fonts у новому розділі свідомо НЕ з'являється: зовнішній
   запит у критичному шляху рендеру заради шрифту, який тут ніде не вживається. */

@font-face {
  font-family: 'Furore';
  src: url('/fonts/Furore.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/Montserrat-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/Montserrat-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/Montserrat-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/fonts/Montserrat-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* ===== 2. ТОКЕНИ ============================================================
   Верхній блок — точна копія :root із index.html / blog.html, без змін.
   Нижній — додані значення. Кожне або НЕ колір (довжина, кегль), або альфа-
   похідна від наявного --text. Нового кольору бренду не з'явилось (AC-019).

   Контрасти пораховані за WCAG 2.x з урахуванням накладення альфи на --bg:
     #ffffff                   → 19,80:1  AAA   (заголовки, <strong>)
     rgba(255,255,255,.92)     → 16,61:1  AAA   (h3)
     rgba(255,255,255,.87)     → 14,86:1  AAA   (тіло статті)
     rgba(255,255,255,.78)     → 11,96:1  AAA   (ліда)
     rgba(255,255,255,.62)     →  7,76:1  AAA   (підписи, дата, час читання)
     --accent #00FF00          → 14,43:1  AAA
   Чинний --text-muted (.55) дає 6,28:1 — це AA, не AAA, тому в статті він
   НЕ вживається для підписів; для них є --text-read-soft (.62). У вітрині
   --text-muted лишається: там опис 15px і його роль інша (§6.2 дизайн-документа). */

:root {
  --bg: #0a0a0a;
  --surface: #111111;
  --surface2: #1a1a1a;
  --accent: #00FF00;
  --accent-dim: rgba(0, 255, 0, 0.12);
  --accent-glow: rgba(0, 255, 0, 0.35);
  --text: #ffffff;
  --text-muted: rgba(255, 255, 255, 0.55);
  --border: rgba(0, 255, 0, 0.1);
  --border-hover: rgba(0, 255, 0, 0.3);
  --radius: 6px;
  --radius-lg: 14px;
  --glow: 0 0 28px rgba(0, 255, 0, 0.38);
  --glow-sm: 0 0 14px rgba(0, 255, 0, 0.22);
  --font-head: 'Furore', sans-serif;
  --font-body: 'Montserrat', sans-serif;

  /* --- додано для блогу --- */
  --text-read: rgba(255, 255, 255, 0.87);      /* тіло статті */
  --text-read-soft: rgba(255, 255, 255, 0.62); /* підписи, дата, крихти */
  --text-lead: rgba(255, 255, 255, 0.78);      /* ліда */
  --text-h3: rgba(255, 255, 255, 0.92);        /* h3 у тілі */
  --measure: 680px;                            /* довжина рядка, не колір */
  --fs-read: 18px;
  --lh-read: 1.75;
  --pad-x: 24px;                               /* поле контейнера, синхронне з адаптивом */
}

/* ДВА ЗНАЧЕННЯ, ЯКИХ ТУТ НЕМАЄ, І ЦЕ ОДНЕ РІШЕННЯ, А НЕ ДВА РІЗНІ.
   §9.1 пропонує --rule rgba(255,255,255,.08) для роздільників, §5.6 —
   зебрування рядків таблиці rgba(255,255,255,.02). Обидва значення одного
   класу: новий нейтральний білий, якого в дизайн-системі не було. AC-019
   забороняє вводити колір повз токени без рішення власника, тому не введено
   ЖОДНОГО: роздільники працюють на наявному --border, зебрування не робиться.
   Перша редакція відхилила --rule, але тихо додала --zebra — асиметрію знайшла
   звірка з дизайн-документом. Сторінка від цього трохи «зеленіша» і трохи
   пласкіша; обидва пункти чекають на одну відповідь. */


/* ===== 3. БАЗОВЕ ========================================================== */

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

/* scroll-padding-top — не косметика. Хедер position:fixed заввишки 68px, і без
   цього рядка КОЖЕН внутрішній якір (зміст, skip-link) кладе ціль рівно під
   нього. Виміряно до правки: hiddenPx=68, тобто заголовок розділу не видно
   зовсім. color-scheme:dark лікує світлу смугу прокрутки на чорному фоні. */
html {
  scroll-behavior: smooth;
  scroll-padding-top: 84px;
  color-scheme: dark;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  font-family: var(--font-body);
  font-size: 16px;
  letter-spacing: 0.01em;
  color: var(--text);
  background: var(--bg);
  line-height: 1.6;
  /* Успадковується всім деревом. Раніше тут стояв перелік тегів, і в нього не
     потрапив div — тобто .faq-answer лишався непокритим, і довгий URL у
     відповіді розпирав колонку. */
  overflow-wrap: break-word;
  /* overflow-x: hidden свідомо НЕ ставимо: він приховав би реальне
     переповнення і зробив би перевірку scrollWidth <= innerWidth (AC-020)
     безглуздою. Верстка мусить уміщатися насправді, а не візуально. */
}

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

a { color: var(--accent); text-decoration: none; transition: color 0.25s; }
a:hover { color: #33FF33; }

button {
  font-family: var(--font-head);
  font-size: 16px;
  letter-spacing: 0.06em;
  cursor: pointer;
  border: none;
  border-radius: var(--radius);
  transition: background-color 0.28s ease, color 0.28s ease, box-shadow 0.28s ease;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--pad-x);
}

/* СКИДАННЯ ВАГИ — не косметика, а виконання AC-019.
   Стандартна таблиця браузера дає h1…h6, th, strong і b вагу 700. Не написати
   font-weight у CSS недостатньо: вага все одно буде 700, просто не видно де.
   Montserrat підключений як «400 600» і 700 клампить до 600 — тобто на екрані
   вага правильна, а в коді брехлива; Furore ж має одне накреслення і на 700
   малює синтетичний жирний, тобто розмитий штрих. Тому вага проставлена явно.
   Перевірено в браузері: до цього правила обчислена вага дев'яти елементів
   дорівнювала 700. */
h1, h2, h3, h4, h5, h6, th, strong, b { font-weight: 600; }

/* Усе, що набрано Furore, отримує 400: у гарнітури просто немає іншої ваги. */
#nav a, .btn, .card-more, .pag-edge, .skip-link,
.blog-hero h1, .card-title, .article-title,
.takeaway h2, .related h2, .cta-band h2, .disclosure > summary { font-weight: 400; }


/* ===== 4. ДОСТУПНІСТЬ ===================================================== */

/* :focus-visible, а не :focus — інакше рамка спалахує при кліку мишею
   і команда «прибрати рамку» приходить наступного дня (§9.3). */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.skip-link {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2000;
  transform: translateY(-120%);
  padding: 12px 18px;
  background: var(--surface2);
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 0 0 var(--radius) 0;
  font-family: var(--font-head);
  font-size: 14px;
  letter-spacing: 0.06em;
  transition: transform 0.2s;
}
.skip-link:focus { transform: translateY(0); }


/* ===== 5. ХЕДЕР =========================================================== */
/* Розмітка й вигляд збігаються з blog.html навмисно: перехід між старим і новим
   розділом не має читатися як перехід на інший сайт. Свідома розбіжність одна:
   ніде немає ваги 700 — Furore має одне накреслення, тож 700 давав синтетичний
   жирний, тобто розмиття штриха на темному тлі, а не наголос. */

#header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 1000;
  background: rgba(10, 10, 10, 0.85);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0.85rem 0;
}

.logo { display: flex; align-items: center; flex-shrink: 0; }
.logo img { height: 40px; width: auto; }
/* Перемикач мови — СПРАВЖНІ посилання, не JS-тогл.
   Тогл віддав би український текст під lang="en" — рівно та помилка,
   заради виправлення якої робиться весь розділ. */
.lang-switcher { display: flex; gap: 4px; flex-shrink: 0; }
.lang-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  padding: 5px 10px;
  border-radius: 4px;
  border: 1px solid transparent;
  transition: color 0.2s, background 0.2s, border-color 0.2s;
}
.lang-link.active {
  color: var(--accent);
  border-color: var(--border);
  background: var(--accent-dim);
}
.lang-link:hover:not(.active) { color: var(--text); }

#nav ul { display: flex; gap: 2.5rem; list-style: none; }
#nav a {
  font-family: var(--font-head);
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-muted);
  transition: color 0.25s;
  padding: 2px 0;
}
#nav a:hover, #nav a.active { color: var(--accent); }

.burger {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  background: none;
  min-width: 44px;
  min-height: 44px;
  z-index: 1001;
}
.burger span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--text);
  border-radius: 2px;
  transition: transform 0.3s, opacity 0.3s;
}
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Прогрес читання — БЕЗ JavaScript: scroll-driven animation.
   ⚠️ @supports тут ОБОВ'ЯЗКОВИЙ, і ось чому. Перша редакція покладалася на те,
   що браузер без animation-timeline «просто не покаже смугу». Це виявилося
   неправдою: у шорткоді немає тривалості, тобто animation-duration = 0s, а
   fill-mode: both миттєво застосовує КІНЦЕВИЙ кадр. Firefox (фіча за прапорцем)
   малював постійну зелену смугу на всю ширину — «прочитано 100%» від першої
   секунди. Перевірено контрольним клоном без animation-timeline: width = 375px.
   Анімується transform, а не width: width змушує розкладку на кожен кадр
   прокрутки, transform іде повз основний потік.
   SEO-користі не має жодної (§7) — це чистий UX. */
@supports (animation-timeline: scroll()) {
  #reading-progress {
    position: fixed;
    top: 0; left: 0;
    height: 3px;
    width: 100%;
    transform-origin: 0 50%;
    background: linear-gradient(90deg, var(--accent), rgba(0, 255, 0, 0.4));
    z-index: 9999;
    animation: rp-grow linear both;
    animation-timeline: scroll(root block);
  }
  @keyframes rp-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}


/* ===== 6. ФУТЕР =========================================================== */

.blog-footer {
  background: var(--surface);
  border-top: 1px solid var(--border);
  padding: 2rem 0;
  margin-top: 80px;
}
.footer-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.footer-logo img { height: 36px; width: auto; }   /* width:auto обов'язковий:
   без нього атрибут width="144" із шаблону застосовується буквально і логотип
   у футері розтягується. Було й до переходу на SVG, просто з PNG менш помітно. */
.footer-copy { font-size: 13px; color: var(--text-muted); letter-spacing: 0.06em; }
.footer-social {
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--surface2);
  color: var(--text-muted);
  border: 1px solid var(--border);
  transition: background 0.25s, color 0.25s, box-shadow 0.25s;
}
.footer-social:hover { background: var(--accent); color: #000; box-shadow: var(--glow-sm); }


/* ===== 7. ВІТРИНА — напрям «Редакція» ====================================== */

.blog-hero {
  background: var(--surface);
  padding: 130px 0 64px;
  border-bottom: 1px solid var(--border);
}

.section-label {
  display: inline-block;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-dim);
  border: 1px solid var(--border);
  border-radius: 40px;
  padding: 5px 14px;
  margin-bottom: 1rem;
}

.blog-hero h1 {
  font-family: var(--font-head);
  text-wrap: balance;
  font-size: clamp(2rem, 4vw, 3rem);
  color: var(--text);
  line-height: 1.1;
  margin-bottom: 0.75rem;
}

.blog-hero p {
  font-size: 16px;
  color: var(--text-muted);
  max-width: 560px;
  line-height: 1.65;
}

.blog-list-section { padding: 64px 0 24px; }

/* Уся картка — ОДНЕ посилання. Окремі лінки на фото, заголовок і «Читати →»
   дали б екранному читачеві три однакові цілі поспіль (§9.3). */
.card {
  display: block;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  color: inherit;
  transition: border-color 0.25s, box-shadow 0.25s, transform 0.25s;
}
.card:hover {
  color: inherit;
  border-color: var(--border-hover);
  box-shadow: var(--glow-sm);
  transform: translateY(-3px);
}

.card-media {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--surface2);
  border-bottom: 1px solid var(--border);
}
.card-media img { width: 100%; height: 100%; object-fit: cover; }

/* Заглушка замість битої <img>, коли зображення немає (AC-005).
   Той самий розмір і той самий радіус — верстка не зсувається. */
.media-fallback {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--surface2), var(--surface));
}
.media-fallback img { width: 22%; max-width: 120px; opacity: 0.12; }

.card-body { padding: 18px 20px 22px; }

.card-meta {
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--text-read-soft);
  margin-bottom: 10px;
}

.card-title {
  font-family: var(--font-head);
  text-wrap: balance;
  font-size: 17px;
  line-height: 1.35;
  color: var(--text);
  margin-bottom: 10px;
}

.card-desc {
  font-size: 15px;
  line-height: 1.6;
  color: var(--text-muted);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-more {
  display: inline-block;
  margin-top: 14px;
  font-family: var(--font-head);
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}

/* Головна картка. Показується лише коли статей ≥ 7 — інакше сітка під нею
   виглядає обрубком (§3.1). Умову виконує генератор, CSS її не знає. */
/* minmax(0,1fr), а не 1fr: у 1fr мінімум треку = min-content, і нерозривне
   слово (довгий URL) розпирало б колонку. Зараз від цього рятує ще й
   overflow:hidden на .card, але покладатися на побічний ефект — погана угода. */
.card-featured { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); margin-bottom: 32px; }
.card-featured .card-media { border-bottom: 0; border-right: 1px solid var(--border); height: 100%; }
.card-featured .card-body { padding: 32px 34px; display: flex; flex-direction: column; justify-content: center; }
.card-featured .card-title { font-size: 28px; line-height: 1.25; }
.card-featured .card-desc { font-size: 16px; -webkit-line-clamp: 4; line-clamp: 4; }

.card-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}


/* ===== 8. ПАГІНАЦІЯ — справжні <a href>, не JS-кнопки (AC-014) ============= */

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 56px 0 0;
  flex-wrap: wrap;
}

/* ≥44×44 — вимога до розміру цілі торкання (§9.3). Чинна пагінація в blog.html
   має 40px, і це відома невідповідність, яку тут не повторюємо. */
.pag-link, .pag-current, .pag-gap {
  min-width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 8px;
  font-size: 14px;
  font-family: var(--font-body);
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-read-soft);
  transition: color 0.2s, border-color 0.2s;
}
.pag-link:hover { color: var(--accent); border-color: var(--accent); }
.pag-current {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
  font-weight: 600;
}
.pag-gap { border-color: transparent; background: none; }
.pag-edge { font-family: var(--font-head); font-size: 13px; letter-spacing: 0.08em; }


/* ===== 9. СТАТТЯ — напрям «Лонгрід» ======================================= */

.article-top { padding: 108px 0 0; }

/* Крихти. Той самий масив даних, що йде в BreadcrumbList — розбіжність між
   видимим і розміченим є помилкою розмітки, а не дрібницею (AC-012). */
.breadcrumbs { margin-bottom: 20px; }
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; }
.breadcrumbs li { font-size: 13px; color: var(--text-read-soft); display: flex; gap: 8px; }
/* Порожній альт-текст після косої: гліф лишається видимим, але читач екрана
   його не озвучує. Інакше в назві крихт з'являється «›» між кожною ланкою. */
.breadcrumbs li + li::before { content: '›' / ''; color: var(--text-read-soft); }
.breadcrumbs a { color: var(--text-read-soft); }
.breadcrumbs a:hover { color: var(--accent); }
.breadcrumbs [aria-current="page"] { color: var(--text-read); }

/* Герой — LCP-елемент. width/height у розмітці обов'язкові (AC-004):
   без них картинка «стрибає» і CLS, який зараз нуль, стає проблемою. */
.article-hero {
  aspect-ratio: 16 / 9;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--surface2);
}
.article-hero img { width: 100%; height: 100%; object-fit: cover; }

/* Підпису під героєм тут немає навмисно: єдине джерело тексту — alt_photo_*,
   а підпис, який дослівно дублює alt, це шум і для читача, і для екранного
   читача (§5.7). З'явиться окрема колонка з осмисленим підписом — з'явиться
   й стиль; вигадувати його «про запас» = код заради коду. */

/* Колонка 680px. Montserrat 18px дає ≈72 символи в рядку — усередині робочої
   смуги 65–75 (§5.2). Це і є головний захід проти втоми від темної теми. */
.measure { max-width: var(--measure); margin: 0 auto; }

.article-head { padding-top: 40px; }

.article-meta {
  font-size: 13px;
  letter-spacing: 0.06em;
  color: var(--text-read-soft);
  margin-bottom: 14px;
}
.article-meta > * + *::before { content: '·' / ''; margin: 0 8px; }

/* Мобільний кегль H1 — 26px, і це вибір між двома суперечливими місцями
   дизайн-документа: §5.3 каже 28/1.2, §9.2 каже 26. Взято §9.2 як пізніший
   і узгоджений із рештою таблиці брейкпойнтів. Раніше вибір був зроблений
   мовчки — тепер він названий. */
.article-title {
  font-family: var(--font-head);
  text-wrap: balance;
  font-size: clamp(1.9rem, 4vw, 2.75rem);
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: var(--text);
  margin-bottom: 0.6em;
}

.article-lead {
  font-size: 20px;
  line-height: 1.65;
  color: var(--text-lead);
  margin-bottom: 1.6em;
}


/* ===== 10. ТІЛО СТАТТІ ==================================================== */
/* Шкала §5.3 дизайн-документа. Селектори навмисно прив'язані до .article-body:
   генератор кладе туди санітизований HTML із білого списку тегів, і будь-який
   тег поза списком сюди просто не потрапляє. */

.article-body {
  font-size: var(--fs-read);
  line-height: var(--lh-read);
  color: var(--text-read);
  letter-spacing: 0.005em; /* світле на темному оптично злипається (§6.2, захід 5) */
}

.article-body p { margin: 0 0 1.4em; text-wrap: pretty; }

.article-body h2,
.article-body h3 { position: relative; font-family: var(--font-body); }

.article-body h2 {
  font-size: 26px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--text);
  margin: 2.6em 0 0.7em;
}

/* Вертикальна риска ліворуч. Різниці 26 проти 18 замало, щоб рівень
   зчитувався периферійним зором під час прокрутки (§5.4). */
.article-body h2::before {
  content: '';
  position: absolute;
  left: -1.1em;
  top: 0.16em;
  width: 3px;
  height: 1em;
  background: var(--accent);
}

.article-body h3 {
  font-size: 20px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--text-h3);
  margin: 1.9em 0 0.5em;
}
.article-body h3::before {
  content: '';
  position: absolute;
  left: -1.1em;
  top: 0.2em;
  width: 2px;
  height: 1em;
  background: var(--text-read-soft);
}

.article-body strong { font-weight: 600; color: var(--text); }
.article-body em { font-style: italic; }

/* Списки: стандартний disc на темному тлі губиться. Ромб — перегук із логотипом. */
.article-body ul { list-style: none; padding-left: 1.4em; margin: 0.4em 0 1.4em; }
.article-body ol { list-style: none; counter-reset: n; padding-left: 1.9em; margin: 0.4em 0 1.4em; }
.article-body li { position: relative; margin-bottom: 0.55em; }

.article-body ul > li::before {
  content: '';
  position: absolute;
  left: -1.4em;
  top: 0.62em;
  width: 6px; height: 6px;
  background: var(--accent);
  transform: rotate(45deg);
}
.article-body ol > li::before {
  counter-increment: n;
  content: counter(n) '.';
  position: absolute;
  left: -1.9em;
  font-family: var(--font-head);
  font-size: 0.85em;
  color: var(--accent);
}

/* Посилання в тексті. #00FF00 посеред абзацу на 18px кричить: кожне посилання
   перетягує погляд і рве рядок. Тому колір успадковується, видимість дає
   підкреслення, а повна зелена ідентичність — лише при наведенні (§5.8). */
.article-body a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid rgba(0, 255, 0, 0.45);
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.article-body a:hover,
.article-body a:focus-visible {
  color: var(--accent);
  border-bottom-color: var(--accent);
  background: var(--accent-dim);
}

/* Таблиця. Обгортку .table-wrap ставить генератор навколо КОЖНОЇ <table>,
   і разом із нею — tabindex="0" role="region" aria-label (див. контракт у
   шаблоні): без tabindex горизонтальний скрол недосяжний з клавіатури в
   Safari і Firefox, тобто половина таблиці для такого користувача не існує
   (WCAG 2.1.1). Без самої обгортки таблиця на 4 колонки ламає верстку на
   375px (AC-020). -webkit-overflow-scrolling прибрано — no-op з iOS 13. */
.table-wrap {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  margin: 2em 0;
}
.article-body table {
  width: 100%;
  border-collapse: collapse;
  font-size: 16px;
  line-height: 1.55;
}
/* Порівняльна таблиця не має стискатися до нечитабельного — на вузькому екрані
   чесніше прокрутити її вбік, ніж зламати стовпці (§5.6). */
.table-wrap table { min-width: 460px; }

/* Запобіжник на випадок таблиці, яка проскочила повз обгортку генератора.
   Без нього одна забута <table> дає горизонтальний скрол на всю сторінку —
   тобто рівно те, що забороняє AC-020. Перевірено: без цього правила
   scrollWidth на 375px був 476 замість 375.
   ⚠️ Ціна запобіжника: display:block знімає з таблиці роль table у Blink і
   WebKit, тобто рядки й комірки перестають озвучуватись. Це аварійний режим,
   а не альтернатива обгортці — обгортка лишається обов'язковою. */
.article-body > table { display: block; overflow-x: auto; }
.article-body th {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: left;
  color: var(--accent);
  background: var(--surface2);
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.article-body td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  color: var(--text-read);
}


/* ===== 11. БЛОКИ СТАТТІ =================================================== */

/* «Коротко» — найцінніший елемент для цитування в AI-пошуку: LLM піднімає
   атомарні твердження з початку документа (§7). Тому він над змістом. */
.takeaway {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 20px 22px;
  margin: 0 0 1.8em;
}
.takeaway h2 {
  font-family: var(--font-head);
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 12px;
}
.takeaway ul { list-style: none; }
.takeaway li {
  position: relative;
  padding-left: 20px;
  margin-bottom: 8px;
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-read);
}
.takeaway li:last-child { margin-bottom: 0; }
.takeaway li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.62em;
  width: 6px; height: 6px;
  background: var(--accent);
  transform: rotate(45deg);
}

/* Зміст і FAQ — на <details>, а не на JS.
   Це не стилістичний вибір: вміст закритого <details> присутній у сирому HTML,
   тобто краулер і LLM його бачать, а клавіатурна доступність з'являється
   безкоштовно. JS-акордеон не дає ні першого, ні другого. */
.disclosure {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  margin: 0 0 1.8em;
}
.disclosure > summary {
  list-style: none;
  cursor: pointer;
  padding: 14px 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-head);
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure > summary::before {
  content: '▸' / '';
  color: var(--accent);
  transition: transform 0.2s;
  display: inline-block;
}
.disclosure[open] > summary::before { transform: rotate(90deg); }
.disclosure > summary:hover { color: var(--accent); }

.toc ol { list-style: none; counter-reset: t; padding: 0 0 16px; }
.toc li { counter-increment: t; margin-bottom: 8px; font-size: 16px; }
.toc li::before {
  content: counter(t) '.';
  color: var(--accent);
  font-family: var(--font-head);
  font-size: 0.85em;
  margin-right: 8px;
}
.toc a { color: var(--text-read); border-bottom: 1px solid transparent; }
.toc a:hover { color: var(--accent); }

.faq-section { margin: 2.6em 0 0; }
.faq-section > h2 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 26px;
  line-height: 1.3;
  color: var(--text);
  margin-bottom: 0.8em;
}
.faq-item { border-bottom: 1px solid var(--border); border-top: 0; margin: 0; }
.faq-item:first-of-type { border-top: 1px solid var(--border); }
.faq-item > summary {
  text-transform: none;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: 0;
  line-height: 1.45;
  padding: 16px 0;
}
.faq-answer {
  font-size: 16px;
  line-height: 1.7;
  color: var(--text-read);
  padding: 0 0 18px;
}

/* CTA всередині тексту — дія на піку інтересу, а не в кінці, куди дочитує
   третина читачів (§7). */
.cta-inline {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg, var(--surface2), var(--surface));
  padding: 24px 26px;
  margin: 2.4em 0;
  text-align: center;
}
.cta-inline p { font-size: 17px; color: var(--text); margin-bottom: 16px; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 12px 26px;
  font-family: var(--font-head);
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #000;
  background: var(--accent);
  border-radius: var(--radius);
  border: 1px solid var(--accent);
  transition: box-shadow 0.25s, background 0.25s, color 0.25s;
}
.btn:hover { color: #000; box-shadow: var(--glow); }

.related { margin-top: 72px; }
.related h2 {
  font-family: var(--font-head);
  font-size: 15px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-read-soft);
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 28px;
}

.cta-band {
  margin-top: 72px;
  background: var(--surface);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 44px 0;
  text-align: center;
}
.cta-band h2 {
  font-family: var(--font-head);
  font-size: clamp(1.3rem, 3vw, 1.9rem);
  line-height: 1.25;
  color: var(--text);
  margin-bottom: 18px;
}


/* ===== 12. АДАПТИВ — брейкпойнти §9.2, жодного нового ====================== */

@media (min-width: 1440px) {
  .container { max-width: 1320px; }
}

/* Сітка 3 → 2. Поле контейнера тут ЩЕ 24px — саме тому картка на 1099 виходить
   514px, як приписує §9.2. У першій редакції --pad-x падав до 20px уже тут, і
   картка виходила 517,5px: розбіжність із документом, яку знайшла звірка. */
@media (max-width: 1099px) {
  .card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Головна картка втрачає привілей раніше за сітку: на 899 дві колонки по 430px
   уже не дають їй виглядати «головною».
   height:auto тут обов'язковий: інакше height:100% з десктопного правила
   перебиває aspect-ratio, і картка БЕЗ обкладинки схлопується до висоти знака —
   тобто верстка зсувається рівно в тому випадку, заради якого заглушка й
   існує (AC-005). */
@media (max-width: 899px) {
  .card-featured { grid-template-columns: minmax(0, 1fr); }
  .card-featured .card-media { border-right: 0; border-bottom: 1px solid var(--border); height: auto; }
  .card-featured .card-body { padding: 22px 24px 26px; }
  .card-featured .card-title { font-size: 22px; }
}

/* 859, а не 860. §9.2 віддає смугу 860–899 повному меню, а бургер починається
   нижче — на рівно 860 бургер з'являвся на піксель зарано.
   Тут же --pad-x стає 20px: §9.2 приписує це смузі 768–859, а не 1100.
   Меню відкривається інлайновим скриптом шаблону (addEventListener,
   aria-expanded, Escape) — не фреймворком і не білдом. */
@media (max-width: 859px) {
  :root { --pad-x: 20px; }

  #nav { display: none; }
  #nav.open {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0; left: 0; right: 0;
    background: rgba(10, 10, 10, 0.97);
    padding: 90px 24px 40px;
    border-bottom: 1px solid var(--border);
    z-index: 999;
  }
  #nav.open ul { flex-direction: column; gap: 1.5rem; align-items: center; }
  #nav.open a { font-size: 15px; }
  .burger { display: flex; }
}

@media (max-width: 767px) {
  html { scroll-padding-top: 76px; }

  .blog-hero { padding: 100px 0 44px; }
  .blog-list-section { padding: 44px 0 16px; }
  .card-grid { grid-template-columns: 1fr; gap: 20px; }

  .article-top { padding-top: 92px; }
  .article-head { padding-top: 28px; }

  /* Єдиний елемент, якому дозволено вийти за поля контейнера. Обчислення від
     токена, а не число: у першій редакції тут стояли -20px і -16px, які треба
     було вручну тримати рівними --pad-x у кожному брейкпойнті. Рівно там і
     виникає горизонтальний скрол, коли одне з двох забудуть змінити. */
  .article-hero {
    margin-inline: calc(-1 * var(--pad-x));
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }

  .article-lead { font-size: 18px; line-height: 1.7; }
  .article-body { font-size: 17px; line-height: 1.7; }
  .article-body h2 { font-size: 22px; }
  .article-body h3 { font-size: 18px; }

  /* Риска H2/H3 переїжджає всередину колонки. Без цього на 375px вона стає на
     -4px від краю в'юпорта і просто ЗНИКАЄ — браузер не скролить вліво, вміст
     обрізається. Перевірка scrollWidth <= innerWidth цього класу дефектів не
     ловить узагалі, тому тут потрібен розрахунок, а не вимір. */
  .article-body h2, .article-body h3 { padding-left: 0.8em; }
  .article-body h2::before, .article-body h3::before { left: 0; }

  /* Мобільна колонка §5.3: таблиця 15/1.5, шапка таблиці й підписи — 12px. */
  .article-body table { font-size: 15px; line-height: 1.5; }
  .article-body th { font-size: 12px; }
  .article-meta { font-size: 12px; }

  .article-body ul { padding-left: 1.2em; }
  .article-body ul > li::before { left: -1.2em; }

  .footer-inner { flex-direction: column; text-align: center; gap: 0.75rem; }
  .related, .cta-band, .blog-footer { margin-top: 56px; }
}

/* §9.2, смуга 480–599: опис картки скорочується до 2 рядків. Головна картка
   теж — інакше її власне правило (специфічність 0,2,0) виграє в .card-desc
   незалежно від порядку, і на телефоні вона лишалася б із чотирма. */
@media (max-width: 599px) {
  .card-desc,
  .card-featured .card-desc { -webkit-line-clamp: 2; line-clamp: 2; }
}

@media (max-width: 479px) {
  :root { --pad-x: 16px; }

  .article-title { font-size: 26px; }
  .card-featured .card-title { font-size: 20px; }
  .takeaway { padding: 16px 18px; }
  .cta-inline { padding: 20px 18px; }
}

/* Низький в'юпорт — останній рядок таблиці §9.2. Документ пише «≤820, як
   зараз», але «як зараз» у blog.html насправді 760px. Беремо факт, а не текст. */
@media (max-height: 760px) {
  .blog-hero { padding: 90px 0 40px; }
  .blog-list-section { padding: 44px 0 16px; }
}


/* ===== 13. prefers-reduced-motion ========================================= */
/* Не «пом'якшуємо» анімації, а прибираємо: користувач із вестибулярним
   розладом просить їх не показувати, а не показувати повільніше (AC-021). */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  #reading-progress { display: none; }

  .card:hover { transform: none; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
