/* ==========================================================================
   МКА «Защита правом» — Design System & Site Shell
   Единый файл стилей: токены, типографика, компоненты, layout, анимации.

   VISUAL 3.0 — карта архитектуры (документация, ничего физически не
   перемещено — секции остаются в исходном порядке, в котором были
   добавлены по этапам; перемещение блоков объёмом в сотни строк несёт
   риск незаметно поменять cascade-порядок при равной specificity, поэтому
   вместо реорганизации файла здесь зафиксирована его логическая карта):

   A. GLOBAL / FOUNDATION — не зависит от конкретной страницы:
      1. Design Tokens · 2. Reset · 3. Typography · 4. Layout primitives ·
      5. Buttons & links · 7. Animation utilities · 7.1 Motion vocabulary
      (секция "6. Cards" удалена на VISUAL 3.0 как полностью мёртвая —
      см. отчёт этапа; номер намеренно не занят заново, чтобы не
      переномеровывать все последующие секции без необходимости).

   B. SHARED COMPONENTS — переиспользуются на нескольких/всех страницах:
      8. Site Shell — Header (+ mobile menu, compact header) · 9. Hero
      (.hero — только index.html; .page-hero — общий паттерн для
      остальных страниц, определён внутри 10.5) · 11. Footer.
      Reveal/reveal-stagger/reduced-motion — внутри 7/7.1, а не отдельным
      блоком, т.к. это часть общей motion-системы, а не самостоятельный UI.

   C. PAGE-SPECIFIC — namespaced под конкретную страницу/раздел:
      9.5 About (index.html) · 9.6 Legal Help preview-аккордеон
      (index.html) · 10.5 Advokaty page · 10.6 Official Info page ·
      10.7 Urgent Call page · 10.8 Contacts page · 10.9 Publications hub
      (physически расположена после "11. Footer" — исторический порядок
      добавления, не переносилась) · 12. Legal Help full page ·
      "PUBLICATIONS 1.4.2 — Article page" (publication.html, ближе к концу
      файла, namespaced под .publication-page/.publication-detail/...).

   Один файл, не assets/css/sections.css (такого файла в проекте нет) —
   для текущего размера и объёма страниц отдельный файл не даёт выгоды
   и добавляет риск рассинхронизации cache-busting версий; см. отчёт
   VISUAL 3.0.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Фирменная палитра — Burgundy / Milk / Gold (Этап 7.5) */
  --c-black: #171313;
  --c-graphite: #111111;
  --c-burgundy: #520B12;
  --c-burgundy-void: #3A070C;
  --c-maroon: #520B12;
  --c-red: #650F18;
  --c-warm-white: #F3EDE2;
  --c-light: #E8DFD0;
  --c-gold: #B49352;
  --c-gold-light: #D1B66C;

  /* Семантические токены */
  --bg-page: var(--c-warm-white);
  --bg-surface: #FBF7F0;
  --bg-inverse: var(--c-burgundy);
  --bg-inverse-graphite: var(--c-graphite);

  --text-primary: var(--c-black);
  --text-muted: #625B53;
  --text-inverse: var(--c-warm-white);
  --text-inverse-muted: #C9B8AE;

  --accent: var(--c-red);
  --accent-deep: var(--c-maroon);
  --gold: var(--c-gold);
  --gold-light: var(--c-gold-light);

  --border-subtle: rgba(23, 19, 19, 0.12);
  --border-inverse: rgba(245, 241, 232, 0.16);
  --border-gold: rgba(180, 147, 82, 0.55);

  /* Мягкие тональные подложки для decorative placeholder-рамок
     (about/advokaty photo-frame, doc-card, map-placeholder) — вынесены
     в переменные, чтобы дальнейшая смена палитры не требовала правки
     каждого повторяющегося градиента по отдельности. */
  --tint-gold-soft: rgba(180, 147, 82, 0.08);
  --tint-ink-soft: rgba(23, 19, 19, 0.03);

  /* Отдельный, чуть более глубокий оттенок золота — только для
     focus-visible outline. Декоративный --gold (#B49352) на молочном фоне
     даёт ~2.5:1 (ниже WCAG non-text 3:1), поэтому для самого индикатора
     фокуса используется более контрастный тон из той же гаммы: ~3.4:1 на
     молочном и ~3.7:1 на глубоком бордовом. */
  --focus-ring: #9C7A3D;

  /* Тёмный тон той же золотой гаммы — только для текста, которому нужен
     WCAG AA 4.5:1 на --bg-page (у декоративного --gold там лишь ~2.5:1).
     PUBLICATIONS 1.4.6: используется исключительно для eyebrow-текста
     категории на publication.html (--gold сам по себе не меняется и
     продолжает использоваться в decorative-элементах). ~5.1:1 на
     --bg-page. */
  --gold-text: #7E5F27;

  /* Типографика */
  --font-display: "Fraunces", "Georgia", serif;
  --font-body: "Manrope", "Segoe UI", Arial, sans-serif;

  --fs-2xs: 0.75rem;
  --fs-xs: 0.8125rem;
  --fs-sm: 0.9375rem;
  --fs-base: 1rem;
  --fs-md: 1.125rem;
  --fs-lg: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);
  --fs-xl: clamp(1.5rem, 1.3rem + 1vw, 2rem);
  --fs-2xl: clamp(2rem, 1.6rem + 1.8vw, 2.75rem);
  --fs-3xl: clamp(2.5rem, 1.9rem + 2.8vw, 3.75rem);
  --fs-4xl: clamp(3rem, 2.1rem + 4.2vw, 5rem);

  --lh-tight: 1.08;
  --lh-snug: 1.25;
  --lh-normal: 1.5;
  --lh-relaxed: 1.7;

  --ls-tight: -0.01em;
  --ls-normal: 0;
  --ls-wide: 0.06em;
  --ls-widest: 0.18em;

  /* Пространство (база 4px) */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;
  --sp-10: 8rem;

  --section-pad-y: clamp(4rem, 3rem + 4vw, 8rem);

  /* Контейнер */
  --container-max: 1240px;
  --container-pad: clamp(1.25rem, 4vw, 3rem);

  /* Форма / радиусы — сдержанные, без "кругляшей" */
  --radius-sm: 2px;
  --radius-md: 3px;

  /* Тени — едва заметные, без "бутстрапной" тяжести */
  --shadow-sm: 0 1px 2px rgba(23, 19, 19, 0.06);
  --shadow-md: 0 12px 32px -16px rgba(23, 19, 19, 0.28);
  --shadow-gold: 0 0 0 1px rgba(180, 147, 82, 0.35);

  /* Переходы */
  --ease-standard: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 180ms;
  --dur-base: 320ms;
  --dur-slow: 620ms;

  /* Semantic motion tokens (ENGINE 1.1) — алиасы поверх --dur- и --ease- токенов выше, пока не подключены ни к одному правилу. */
  --motion-hover: var(--dur-fast) var(--ease-standard); /* hover/focus micro-interactions */
  --motion-nav: var(--dur-base) var(--ease-standard); /* navigation / accordion / UI state transitions */
  --motion-reveal: var(--dur-slow) var(--ease-standard); /* scroll reveal / entrance animation */
  --motion-page: var(--dur-base) var(--ease-in-out); /* будущие page transitions */

  --header-h: 84px;
}

/* --------------------------------------------------------------------------
   2. Reset
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100svh;
  overflow-x: hidden;
  background: var(--bg-page);
  color: var(--text-primary);
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

ul,
ol {
  list-style: none;
  padding: 0;
}

input,
textarea,
select {
  font: inherit;
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}

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

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

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  color: var(--text-primary);
  /* VISUAL REFINEMENT 4.4: VISUAL 2.7 включил hyphens:auto именно для
     защиты от overflow на узких mobile viewport — но браузерный словарь
     переноса для lang="ru" систематически рвёт слова по слогу
     ("Юридиче-ская", "Публика-ции" и т.д.) на КАЖДОЙ странице сайта, что
     по новому брифу недопустимо ни при каких условиях. Полный аудит (все
     h1-h3 + .publication-card__title, 375/390/430/1280px, 8 страниц + 2
     статьи) нашёл 73 случая переноса по слогам и подтвердил: единственная
     причина — это правило. hyphens:none убирает словарь переноса;
     overflow-wrap:normal (было break-word) означает, что при нехватке
     места слово ЦЕЛИКОМ уходит на следующую строку, а не разрывается ни
     по словарю, ни посимвольно — перенос теперь возможен только между
     словами. Каждый случай, где раньше "спасал" hyphens/break-word,
     перепроверен и при необходимости исправлен точечно (page-specific
     media query, тот же приём, что уже применялся для gold-axis padding
     на нескольких страницах) — см. QA VISUAL REFINEMENT 4.4. */
  hyphens: none;
  -webkit-hyphens: none;
  -ms-hyphens: none;
  overflow-wrap: normal;
  word-break: normal;
}

h1 { font-size: var(--fs-4xl); }
h2 { font-size: var(--fs-3xl); }
h3 { font-size: var(--fs-xl); }
h4 { font-size: var(--fs-md); }

p {
  color: var(--text-muted);
  line-height: var(--lh-relaxed);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--accent-deep);
}

.eyebrow::before {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--gold);
}

.lede {
  font-size: var(--fs-md);
  max-width: 60ch;
}

/* --------------------------------------------------------------------------
   4. Layout primitives
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

.section {
  padding-block: var(--section-pad-y);
  position: relative;
  scroll-margin-top: var(--header-h);
}

.section--tight {
  padding-block: calc(var(--section-pad-y) * 0.6);
}

.section--dark {
  background: var(--bg-inverse);
  color: var(--text-inverse);
}

.section--dark h1,
.section--dark h2,
.section--dark h3,
.section--dark h4 {
  color: var(--text-inverse);
}

.section--dark p {
  color: var(--text-inverse-muted);
}

.section--dark .eyebrow {
  color: var(--gold-light);
}

/* Едва заметное зерно на бордовых секциях — ощущение бумаги/материала без
   изображения-текстуры: несколько крошечных radial-gradient точек,
   повторяющихся паттерном, при очень низкой непрозрачности. Не влияет на
   читаемость и не добавляет запросов/веса страницы. */
.section--dark::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0.05;
  pointer-events: none;
  background-image:
    radial-gradient(circle at 1px 1px, var(--text-inverse) 1px, transparent 0);
  background-size: 3px 3px;
}

.section--dark > .container {
  position: relative;
  z-index: 1;
}

/* Urgent Call: отдельный, более глубокий винно-чёрный тон — страница
   должна визуально отличаться от остальных burgundy-секций сайта. */
.section--dark.section--void {
  background: var(--c-burgundy-void);
}

.section-head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  max-width: 46rem;
  margin-bottom: var(--sp-8);
}

.section-head--split {
  max-width: none;
  flex-direction: row;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-6);
}

@media (max-width: 720px) {
  .section-head--split {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Тонкая декоративная линия — фирменный графический приём */
.rule {
  border: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--border-gold), transparent 70%);
}

.rule--full {
  background: var(--border-subtle);
}

/* --------------------------------------------------------------------------
   5. Buttons & links
   -------------------------------------------------------------------------- */
.btn {
  --btn-fg: var(--text-primary);
  --btn-bg: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: 0.9rem 1.75rem;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  border-radius: var(--radius-sm);
  border: 1px solid currentColor;
  color: var(--btn-fg);
  background: var(--btn-bg);
  transition: background-color var(--dur-base) var(--ease-standard),
    color var(--dur-base) var(--ease-standard),
    border-color var(--dur-base) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard);
  white-space: nowrap;
}

.btn:hover,
.btn:focus-visible {
  transform: translateY(-1px);
}

.btn:active {
  transform: translateY(0);
}

.btn:disabled {
  opacity: 0.6;
  cursor: default;
  transform: none;
}

/* VISUAL 4.3: тот же паттерн, что и .footer__contact-link[aria-disabled]/
   .doc-card__action[aria-disabled] — до этого правила у .btn не было, и
   честно неактивная кнопка (urgentPhone/urgentMessenger = null) визуально
   ничем не отличалась от рабочей, а href="#" всё равно был кликабелен
   (aria-disabled сам по себе клик не блокирует) — эффект "кнопка без
   действия", прямо запрещённый брифом. pointer-events:none снимает и клик,
   и hover-эффекты; на другие страницы не влияет — сочетание .btn с
   aria-disabled="true" сейчас существует только на urgent-call.html. */
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: default;
  pointer-events: none;
}

/* VISUAL FIX 5.1.5: точечно только для .btn-primary — на urgent-call.html
   он лежит на тёмно-бордовом фоне секции, а .btn-primary задаёт
   border-color: var(--accent) (тот же цвет, что и заливка), поэтому при
   opacity:0.55 контур кнопки визуально сливается с фоном (замер: ~1.16:1,
   форма кнопки почти не читается отдельно от страницы — см. VISUAL AUDIT
   5.1.5). Светлый полупрозрачный контур — тот же RGB, что у --c-warm-white
   (текст кнопки), но с alpha, а не новый цвет в палитре — делает кромку
   различимой (после compounding с opacity:0.55 элемента — ~1.65:1),
   оставаясь явно приглушённым, не «активным» контуром. Общее правило
   .btn[aria-disabled="true"] (opacity/cursor/pointer-events) и другие
   disabled-компоненты (.footer__contact-link, .contact-method,
   .doc-card__action) не затронуты — селектор специфичен к .btn-primary. */
.btn-primary[aria-disabled="true"] {
  border-color: rgba(243, 237, 226, 0.35);
}

/* VISUAL 2.4: направленный fill-sweep вместо плоской смены background-
   color — только у .btn-primary (самый частый и заметный CTA сайта,
   «Вызвать адвоката 24/7»). Остальные варианты кнопок (outline/
   ghost-inverse) сознательно оставлены как есть — простая смена цвета
   там уже читается достаточно чётко, а sweep на каждой кнопке сайта
   выглядел бы механическим приёмом, а не точечным усилением главного
   действия. ::before выведен из flex-потока через position:absolute, на
   layout/CLS не влияет; isolation:isolate + z-index:-1 держат его строго
   под текстом кнопки, не переопределяя порядок в DOM. */
.btn-primary {
  --btn-fg: var(--c-warm-white);
  --btn-bg: var(--accent);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-color: var(--accent);
}

.btn-primary::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--accent-deep);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--motion-hover);
}

.btn-primary:hover::before,
.btn-primary:focus-visible::before {
  transform: scaleX(1);
}

.btn-primary:hover,
.btn-primary:focus-visible {
  border-color: var(--accent-deep);
}

.btn-outline {
  --btn-fg: var(--text-primary);
  border-color: var(--border-subtle);
}

.btn-outline:hover,
.btn-outline:focus-visible {
  border-color: var(--c-black);
}

.btn-ghost-inverse {
  --btn-fg: var(--text-inverse);
  border-color: var(--border-inverse);
}

.btn-ghost-inverse:hover,
.btn-ghost-inverse:focus-visible {
  border-color: var(--gold-light);
  color: var(--gold-light);
}

.link-underline {
  position: relative;
  padding-bottom: 0.15em;
  font-weight: 600;
}

.link-underline::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0.32);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-standard);
}

.link-underline:hover::after,
.link-underline:focus-visible::after {
  transform: scaleX(1);
}

/* --------------------------------------------------------------------------
   7. Animation utilities
   -------------------------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--dur-slow) var(--ease-standard),
    transform var(--dur-slow) var(--ease-standard);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.reveal-stagger > * {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--dur-slow) var(--ease-standard),
    transform var(--dur-slow) var(--ease-standard);
}

.reveal-stagger.is-visible > * {
  opacity: 1;
  transform: translateY(0);
}

/* Задержки 1–6 переиспользуются и для .legal-item (компактный stagger
   ниже, VISUAL 2.1) — единая таблица вместо двух параллельных наборов. */
.reveal-stagger.is-visible > *:nth-child(1),
.legal-list.reveal.is-visible > .legal-item:nth-child(1) { transition-delay: 0ms; }
.reveal-stagger.is-visible > *:nth-child(2),
.legal-list.reveal.is-visible > .legal-item:nth-child(2) { transition-delay: 90ms; }
.reveal-stagger.is-visible > *:nth-child(3),
.legal-list.reveal.is-visible > .legal-item:nth-child(3) { transition-delay: 180ms; }
.reveal-stagger.is-visible > *:nth-child(4),
.legal-list.reveal.is-visible > .legal-item:nth-child(4) { transition-delay: 270ms; }
.reveal-stagger.is-visible > *:nth-child(5),
.legal-list.reveal.is-visible > .legal-item:nth-child(5) { transition-delay: 360ms; }
.reveal-stagger.is-visible > *:nth-child(6),
.legal-list.reveal.is-visible > .legal-item:nth-child(6) { transition-delay: 450ms; }
/* VISUAL 2.1: расширение лестницы задержек до 9 позиций — понадобилось
   для «Юридическая помощь» (01–09, .legal-item); шаг после 6-го элемента
   сознательно сужен, чтобы весь список из 9 пунктов укладывался в
   ориентир ≤600ms общего stagger-бюджета (не длиннее одной случайной
   паузы «элемент → долгая пауза → элемент»). */
.reveal-stagger.is-visible > *:nth-child(7),
.legal-list.reveal.is-visible > .legal-item:nth-child(7) { transition-delay: 500ms; }
.reveal-stagger.is-visible > *:nth-child(8),
.legal-list.reveal.is-visible > .legal-item:nth-child(8) { transition-delay: 540ms; }
.reveal-stagger.is-visible > *:nth-child(n+9),
.legal-list.reveal.is-visible > .legal-item:nth-child(n+9) { transition-delay: 570ms; }

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal-stagger > *,
  .hero__content.reveal > *,
  .section--void .page-hero__intro.reveal > *,
  section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > *,
  .legal-list.reveal > .legal-item,
  .eyebrow::before {
    opacity: 1;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   7.1 Motion vocabulary — VISUAL 2.1 (reveal variants)
   Расширяет .reveal/.reveal-stagger, не заменяя их: базовые правила выше
   остаются рабочими везде, где уже применяются сейчас. Ниже — точечные,
   более выразительные варианты для конкретных, уже существующих в HTML
   структур (новые HTML-классы не добавлялись — только более специфичные
   CSS-селекторы поверх уже имеющейся разметки):

     — editorial reveal: главные hero-блоки index.html (.hero__content) и
       urgent-call.html (.page-hero__intro внутри .section--void) — eyebrow
       → H1 → lede → CTA появляются последовательно, а не одним блоком;
       H1 — главный визуальный момент с наибольшей амплитудой и
       длительностью в диапазоне ~400–600ms.
     — compact reveal: плотный список «Юридическая помощь» (.legal-item,
       01–09) — построчный stagger с меньшей амплитудой, чем у карточных
       сеток (translateY 12px вместо 24px), та же длительность/easing,
       что и у остальных .reveal-stagger-элементов — единый ритм.
     — line-draw: золотая линия перед eyebrow (::before) — scaleX(0)→(1),
       transform-origin: left. Это motion уже существующего декоративного
       элемента, не новый визуальный объект. Никакого glow/pulse/цикла.

   Везде — только transform/opacity, единая --ease-standard. Для hero
   специально используются точечные ms-значения (не --dur-fast/base/slow):
   ни один из трёх существующих токенов не попадает в запрошенный для
   заголовка диапазон 400–600ms, а вводить новый глобальный --dur-токен
   ради одного сценария избыточно (задача прямо просит не трогать
   design-токены без необходимости). */

/* -- Line-draw: золотая линия перед eyebrow --
   VISUAL 2.2 fix: не все .eyebrow лежат внутри .reveal/.reveal-stagger
   (например, index.html — «Направления», «Команда», «Круглосуточно»,
   «Принципы работы», «Обратная связь» сидят в section-head без .reveal).
   Раньше scaleX(0) стоял безусловно на .eyebrow::before, из-за чего у
   таких eyebrow линия навсегда оставалась невидимой — .is-visible на
   родителе никогда не появлялся. Теперь скрытое/анимированное состояние
   включается ТОЛЬКО внутри .reveal/.reveal-stagger; вне них линия
   остаётся сразу видимой (как и до VISUAL 2.1). */
.eyebrow::before {
  transform-origin: left;
}

.reveal .eyebrow::before,
.reveal-stagger .eyebrow::before {
  transform: scaleX(0);
  transition: transform var(--dur-base) var(--ease-standard);
}

.reveal.is-visible .eyebrow::before,
.reveal-stagger.is-visible .eyebrow::before {
  transform: scaleX(1);
}

/* -- Editorial reveal: index.html hero -- */
.hero__content.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

.hero__content.reveal > .eyebrow,
.hero__content.reveal > h1,
.hero__content.reveal > .lede,
.hero__content.reveal > .hero__actions {
  opacity: 0;
  transition: opacity var(--ease-standard), transform var(--ease-standard);
}

.hero__content.reveal > .eyebrow { transform: translateY(8px); transition-duration: 320ms; transition-delay: 0ms; }
.hero__content.reveal > h1 { transform: translateY(24px); transition-duration: 520ms; transition-delay: 80ms; }
.hero__content.reveal > .lede { transform: translateY(14px); transition-duration: 420ms; transition-delay: 200ms; }
.hero__content.reveal > .hero__actions { transform: translateY(14px); transition-duration: 420ms; transition-delay: 260ms; }

.hero__content.reveal.is-visible > .eyebrow,
.hero__content.reveal.is-visible > h1,
.hero__content.reveal.is-visible > .lede,
.hero__content.reveal.is-visible > .hero__actions {
  opacity: 1;
  transform: translateY(0);
}

/* -- Editorial reveal: index.html hero, правая колонка (VISUAL 3.1) —
   продолжает ту же последовательность, что и .hero__content выше
   (eyebrow → h1 → lede → CTA), пятым и шестым шагом: герб+год, затем
   статы. Тот же приём (родитель сразу видим, transition только на
   детях), тот же .ease-standard, задержки продолжают каденцию 80мс. */
/* transform здесь — не entrance-эффект, а тот же --hero-parallax, что
   reveal-manager.js уже задаёт на .hero::before (JS не менялся —
   переменная наследуется от родителя .hero); другой множитель даёт
   лёгкую layered-глубину между фоновым тоном и editorial-якорем, а не
   два слоя, двигающихся синхронно. 0px без JS/при reduced-motion/на
   ≤640px — как и было. */
.hero__aside.reveal {
  opacity: 1;
  transform: translateY(calc(var(--hero-parallax, 0px) * -1.4));
  transition: none;
}

.hero__aside.reveal > .hero__mark,
.hero__aside.reveal > .hero__stats {
  opacity: 0;
  transition: opacity var(--ease-standard), transform var(--ease-standard);
}

.hero__aside.reveal > .hero__mark { transform: translateY(16px) scale(0.96); transition-duration: 560ms; transition-delay: 340ms; }
.hero__aside.reveal > .hero__stats { transform: translateY(14px); transition-duration: 420ms; transition-delay: 460ms; }

.hero__aside.reveal.is-visible > .hero__mark,
.hero__aside.reveal.is-visible > .hero__stats {
  opacity: 1;
  transform: translateY(0);
}

/* Золотая линия у года — тот же line-draw приём, что .eyebrow::before
   (scaleX 0→1, transform-origin уже задан выше при определении .hero__mark::before).
   ДОПОЛНЕНИЕ 5.0.3: линия снова left-aligned (left:0), translateX-компенсация
   для центрирования больше не нужна — обычный scaleX от левого края. */
.hero__aside.reveal > .hero__mark::before {
  transform: scaleX(0);
  transition: transform 420ms var(--ease-standard);
  transition-delay: 460ms;
}

.hero__aside.reveal.is-visible > .hero__mark::before {
  transform: scaleX(1);
}

/* -- Editorial reveal: urgent-call.html hero — точечно ограничено
   .section--void (уникальный модификатор именно этой страницы), чтобы не
   задеть .page-hero__intro на advokaty/contacts/official-info/publications,
   где используется обычный, нетронутый .reveal. -- */
.section--void .page-hero__intro.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

.section--void .page-hero__intro.reveal > .eyebrow,
.section--void .page-hero__intro.reveal > .urgent-badge,
.section--void .page-hero__intro.reveal > h1,
.section--void .page-hero__intro.reveal > .lede,
.section--void .page-hero__intro.reveal > .urgent-actions,
.section--void .page-hero__intro.reveal > .urgent-actions__note {
  opacity: 0;
  transition: opacity var(--ease-standard), transform var(--ease-standard);
}

.section--void .page-hero__intro.reveal > .eyebrow { transform: translateY(8px); transition-duration: 320ms; transition-delay: 0ms; }
.section--void .page-hero__intro.reveal > .urgent-badge { transform: translateY(10px); transition-duration: 360ms; transition-delay: 80ms; }
.section--void .page-hero__intro.reveal > h1 { transform: translateY(24px); transition-duration: 520ms; transition-delay: 200ms; }
.section--void .page-hero__intro.reveal > .lede { transform: translateY(14px); transition-duration: 420ms; transition-delay: 260ms; }
.section--void .page-hero__intro.reveal > .urgent-actions { transform: translateY(14px); transition-duration: 420ms; transition-delay: 320ms; }
.section--void .page-hero__intro.reveal > .urgent-actions__note { transform: translateY(10px); transition-duration: 360ms; transition-delay: 340ms; }

.section--void .page-hero__intro.reveal.is-visible > .eyebrow,
.section--void .page-hero__intro.reveal.is-visible > .urgent-badge,
.section--void .page-hero__intro.reveal.is-visible > h1,
.section--void .page-hero__intro.reveal.is-visible > .lede,
.section--void .page-hero__intro.reveal.is-visible > .urgent-actions,
.section--void .page-hero__intro.reveal.is-visible > .urgent-actions__note {
  opacity: 1;
  transform: translateY(0);
}

/* -- Editorial reveal: publications.html hero — VISUAL 2.5. Точечно
   ограничено через уникальный aria-labelledby секции (тот же приём, что
   .section--void у urgent-call — без добавления нового HTML-класса),
   чтобы не задеть .page-hero__intro на advokaty/contacts/official-info,
   где остаётся обычный, нетронутый .reveal. Тайминг идентичен hero
   index.html/urgent-call.html — тот же ритм, а не отдельная система. У
   этого hero нет CTA — 4 части: eyebrow → H1 → lede → уточняющая
   заметка (.publications-hero__note). -- */
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .eyebrow,
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > h1,
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .lede,
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .publications-hero__note {
  opacity: 0;
  transition: opacity var(--ease-standard), transform var(--ease-standard);
}

section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .eyebrow { transform: translateY(8px); transition-duration: 320ms; transition-delay: 0ms; }
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > h1 { transform: translateY(24px); transition-duration: 520ms; transition-delay: 80ms; }
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .lede { transform: translateY(14px); transition-duration: 420ms; transition-delay: 200ms; }
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .publications-hero__note { transform: translateY(10px); transition-duration: 360ms; transition-delay: 260ms; }

section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal.is-visible > .eyebrow,
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal.is-visible > h1,
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal.is-visible > .lede,
section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal.is-visible > .publications-hero__note {
  opacity: 1;
  transform: translateY(0);
}

/* -- Editorial reveal: publication.html article header (VISUAL 3.4) —
   breadcrumb → category → H1 → meta → lead, тот же словарь, что у
   остальных editorial-reveal блоков выше (translateY + opacity,
   --ease-standard, точечные ms вместо --dur-токенов). Breadcrumb — свой,
   более быстрый .reveal (не .publication-detail__header, отдельный
   sibling-элемент в разметке), значения подобраны так, чтобы он
   визуально завершался раньше, чем начинает проявляться category —
   ощущение последовательности без искусственной синхронизации через JS.
   Body/Sources/Related намеренно не участвуют (см. задание п.19 — тело
   статьи не должно появляться по частям). -- */
.publication-breadcrumb.reveal {
  transform: translateY(6px);
  transition-duration: 240ms;
}

.publication-detail__header.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

.publication-detail__header.reveal > .publication-detail__category,
.publication-detail__header.reveal > .publication-detail__title,
.publication-detail__header.reveal > .publication-detail__meta,
.publication-detail__header.reveal > .publication-detail__lead {
  opacity: 0;
  transition: opacity var(--ease-standard), transform var(--ease-standard);
}

.publication-detail__header.reveal > .publication-detail__category { transform: translateY(8px); transition-duration: 280ms; transition-delay: 60ms; }
.publication-detail__header.reveal > .publication-detail__title { transform: translateY(16px); transition-duration: 460ms; transition-delay: 120ms; }
.publication-detail__header.reveal > .publication-detail__meta { transform: translateY(10px); transition-duration: 360ms; transition-delay: 260ms; }
.publication-detail__header.reveal > .publication-detail__lead { transform: translateY(12px); transition-duration: 400ms; transition-delay: 340ms; }

.publication-detail__header.reveal.is-visible > .publication-detail__category,
.publication-detail__header.reveal.is-visible > .publication-detail__title,
.publication-detail__header.reveal.is-visible > .publication-detail__meta,
.publication-detail__header.reveal.is-visible > .publication-detail__lead {
  opacity: 1;
  transform: translateY(0);
}

/* -- Compact reveal: «Юридическая помощь» 01–09 (.legal-list) —
   построчный stagger вместо появления всего списка одним блоком.
   Длительность/easing — те же, что у .reveal-stagger, только меньшая
   амплитуда (это список компактных строк, не карточная сетка). Задержки
   берутся из общей лестницы .reveal-stagger.is-visible > *:nth-child(N)
   выше (расширенной до 9 позиций). -- */
.legal-list.reveal {
  opacity: 1;
  transform: none;
  transition: none;
}

.legal-list.reveal > .legal-item {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--dur-slow) var(--ease-standard),
    transform var(--dur-slow) var(--ease-standard);
}

.legal-list.reveal.is-visible > .legal-item {
  opacity: 1;
  transform: translateY(0);
}

/* -- Mobile: меньше displacement, короче длительность и stagger-задержки
   (390px — ориентир). Пороговое значение 640px переиспользует уже
   принятую в проекте mobile-границу (см. .publication-detail__title и
   .publication-detail__body h2 выше) — новый breakpoint не вводится,
   1180px не затронут. -- */
@media (max-width: 640px) {
  .reveal,
  .reveal-stagger > * {
    transform: translateY(10px);
    transition-duration: var(--dur-base);
  }

  .eyebrow::before {
    transition-duration: var(--dur-fast);
  }

  .hero__content.reveal > .eyebrow,
  .section--void .page-hero__intro.reveal > .eyebrow,
  section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .eyebrow {
    transform: translateY(6px);
    transition-duration: 220ms;
  }

  .section--void .page-hero__intro.reveal > .urgent-badge {
    transform: translateY(6px);
    transition-duration: 220ms;
    transition-delay: 30ms;
  }

  .hero__content.reveal > h1,
  .section--void .page-hero__intro.reveal > h1,
  section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > h1 {
    transform: translateY(14px);
    transition-duration: 340ms;
    transition-delay: 70ms;
  }

  .hero__content.reveal > .lede,
  .hero__content.reveal > .hero__actions,
  .section--void .page-hero__intro.reveal > .lede,
  .section--void .page-hero__intro.reveal > .urgent-actions,
  .section--void .page-hero__intro.reveal > .urgent-actions__note,
  section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .lede,
  section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .publications-hero__note {
    transform: translateY(10px);
    transition-duration: 260ms;
  }

  section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .lede { transition-delay: 110ms; }
  section[aria-labelledby="publications-hero-heading"] .page-hero__intro.reveal > .publications-hero__note { transition-delay: 150ms; }
  .hero__content.reveal > .lede { transition-delay: 110ms; }
  .hero__content.reveal > .hero__actions { transition-delay: 150ms; }
  .section--void .page-hero__intro.reveal > .lede { transition-delay: 130ms; }
  .section--void .page-hero__intro.reveal > .urgent-actions { transition-delay: 180ms; }
  .section--void .page-hero__intro.reveal > .urgent-actions__note { transition-delay: 190ms; }

  .legal-list.reveal > .legal-item {
    transform: translateY(8px);
    transition-duration: 260ms;
  }

  .reveal-stagger.is-visible > *:nth-child(2),
  .legal-list.reveal.is-visible > .legal-item:nth-child(2) { transition-delay: 40ms; }
  .reveal-stagger.is-visible > *:nth-child(3),
  .legal-list.reveal.is-visible > .legal-item:nth-child(3) { transition-delay: 80ms; }
  .reveal-stagger.is-visible > *:nth-child(4),
  .legal-list.reveal.is-visible > .legal-item:nth-child(4) { transition-delay: 120ms; }
  .reveal-stagger.is-visible > *:nth-child(5),
  .legal-list.reveal.is-visible > .legal-item:nth-child(5) { transition-delay: 160ms; }
  .reveal-stagger.is-visible > *:nth-child(6),
  .legal-list.reveal.is-visible > .legal-item:nth-child(6) { transition-delay: 200ms; }
  .reveal-stagger.is-visible > *:nth-child(7),
  .legal-list.reveal.is-visible > .legal-item:nth-child(7) { transition-delay: 230ms; }
  .reveal-stagger.is-visible > *:nth-child(8),
  .legal-list.reveal.is-visible > .legal-item:nth-child(8) { transition-delay: 260ms; }
  .reveal-stagger.is-visible > *:nth-child(n+9),
  .legal-list.reveal.is-visible > .legal-item:nth-child(n+9) { transition-delay: 285ms; }
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: -100%;
  left: var(--sp-4);
  z-index: 1000;
  background: var(--c-black);
  color: var(--text-inverse);
  padding: 0.75rem 1.25rem;
  border-radius: var(--radius-sm);
  transition: top var(--dur-fast) var(--ease-standard);
}

.skip-link:focus {
  top: var(--sp-4);
}

/* Тонкий индикатор прогресса прочтения страницы — 2px, compositor-friendly
   transform (без reflow), создаётся и обновляется в main.js. Это не
   декоративная анимация, а привязанный к реальному скроллу индикатор,
   поэтому не отключается в reduced-motion — он не двигается сам по себе. */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1001;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, var(--accent-deep), var(--gold));
  transform: scaleX(0);
  transform-origin: left;
  pointer-events: none;
}

/* ==========================================================================
   8. Site Shell — Header
   ========================================================================== */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
}

/* Полупрозрачный blur-фон вынесен в псевдоэлемент: если backdrop-filter
   висит на самом .site-header, он создаёт containing block для
   position:fixed потомков (мобильное меню) и ломает его позиционирование. */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgba(243, 237, 226, 0.86);
  backdrop-filter: saturate(140%) blur(10px);
  -webkit-backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-base) var(--ease-standard),
    box-shadow var(--dur-base) var(--ease-standard);
}

.site-header.is-scrolled::before {
  border-bottom-color: var(--border-subtle);
}

/* VISUAL 2.3: компактное состояние при значительной прокрутке
   (.is-compact, см. header-scroll.js) — только paint/transform-эффекты,
   ничего layout-critical. Высота .site-header (var(--header-h)) не
   меняется ни здесь, ни где-либо ещё в этом состоянии. */
.site-header.is-compact::before {
  box-shadow: var(--shadow-sm);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* HOTFIX (responsive header 1024px): чуть уже, чем стандартный --sp-6/
     --container-pad, — logo + 6 пунктов меню + CTA физически не помещаются
     в контейнер с исходными зазорами до ~1340px viewport. Точечно сужаем
     только сам header (не .container в целом — остальные секции сайта эту
     переменную не наследуют, т.к. правило скоуплено селектором
     .site-header .container). Визуально на 1440/1280/1200px изменение почти
     незаметно — header остаётся просторным. */
  gap: 20px;
  padding-inline: clamp(1.25rem, 3vw, 2rem);
  height: 100%;
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-shrink: 0;
}

.brand img {
  height: 52px;
  width: auto;
  transition: transform 220ms var(--ease-standard);
}

/* VISUAL 2.3: лёгкий scale логотипа в компактном состоянии — transform
   не влияет на layout/reflow соседних элементов шапки, логотип остаётся
   узнаваемым (0.88 — едва заметное уменьшение, не «схлопывание»). */
.site-header.is-compact .brand img {
  transform: scale(0.88);
}

/* Более плотные внутренние отступы шапки — только там, где виден полный
   горизонтальный набор пунктов меню (≥1181px, тот же порог, что и
   переключение на мобильное меню в HOTFIX выше — новый breakpoint не
   вводится). На мобильном/планшетном header (≤1180px, гамбургер-меню)
   свободного места и так немного — трогать не нужно (VISUAL 2.3, часть 5). */
@media (min-width: 1181px) {
  .site-header.is-compact .container {
    gap: 16px;
  }
}

.brand-text {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}

.brand-text strong {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 600;
  letter-spacing: var(--ls-tight);
}

.brand-text span {
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--text-muted);
}

.main-nav {
  display: flex;
  align-items: center;
  gap: var(--sp-7);
}

.main-nav__list {
  display: flex;
  align-items: center;
  /* HOTFIX (responsive header 1024px): --sp-6 (32px) — см. комментарий у
     .site-header .container выше; сужение зазора между пунктами меню —
     единственный по-настоящему заметный вклад в общую экономию ширины. */
  gap: 18px;
}

.main-nav__list a {
  position: relative;
  font-size: var(--fs-sm);
  font-weight: 600;
  padding-block: var(--sp-2);
}

.main-nav__list a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-base) var(--ease-standard);
}

.main-nav__list a:hover::after,
.main-nav__list a:focus-visible::after,
.main-nav__list a[aria-current="page"]::after {
  transform: scaleX(1);
}

/* CTA внутри .main-nav дублирует .header-actions и нужен только в мобильном меню */
.main-nav > .btn {
  display: none;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
}

/* HOTFIX (responsive header 1024px): точечно уже, чем базовый .btn
   (1.75rem/28px с каждой стороны) — .btn как класс не трогаем, он общий
   для hero/форм/CTA по всему сайту; сужаем только эту конкретную кнопку. */
.header-actions .btn-primary {
  padding-inline: 1.15rem;
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
}

.nav-toggle span {
  display: block;
  width: 20px;
  height: 1.5px;
  margin-inline: auto;
  background: var(--c-black);
  transition: transform var(--dur-base) var(--ease-standard),
    opacity var(--dur-base) var(--ease-standard);
}

.nav-toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(6.5px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-6.5px) rotate(-45deg);
}

/* HOTFIX (responsive header 1024px): breakpoint поднят с 960px до 1180px —
   даже после сужения зазоров/padding выше, полноценная горизонтальная
   навигация (6 пунктов + CTA «Вызвать адвоката 24/7») физически не
   помещается без переноса текста нигде ниже ~1150px viewport (измерено
   Playwright-диагностикой). 1180px даёт запас ~30px и держит переход к
   мобильному меню строго до появления клиппинга. На 1200/1280/1440px
   горизонтальная навигация не затронута. */
@media (max-width: 1180px) {
  .main-nav {
    position: fixed;
    inset: var(--header-h) 0 0 0;
    background: var(--bg-page);
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    padding: var(--sp-7) var(--container-pad);
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-standard),
      transform var(--dur-base) var(--ease-standard),
      visibility var(--dur-base);
  }

  .main-nav.is-open {
    opacity: 1;
    transform: translateY(0);
    visibility: visible;
    pointer-events: auto;
  }

  .main-nav__list {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    width: 100%;
  }

  .main-nav__list a {
    display: block;
    width: 100%;
    padding-block: var(--sp-4);
    font-size: var(--fs-lg);
    border-bottom: 1px solid var(--border-subtle);
  }

  .main-nav > .btn {
    display: inline-flex;
    margin-top: var(--sp-6);
    width: 100%;
  }

  .nav-toggle {
    display: flex;
  }

  .header-actions .btn-primary {
    display: none;
  }
}

/* ==========================================================================
   9. Hero
   ========================================================================== */
/* VISUAL 3.1.1: вертикальная посадка — раньше align-items:center на
   почти полноэкранной секции распределяло лишнее пространство поровну
   сверху и снизу (реально ~198px до eyebrow при 1440x900), из-за чего
   композиция читалась как "случайно подвешенная" в пустоте. flex-start
   + explicit top offset делают отступ до контента намеренным и
   контролируемым числом, а не побочным эффектом центрирования; остаток
   высоты уходит вниз, где просторность уместна и не мешает восприятию. */
.hero {
  position: relative;
  display: flex;
  align-items: flex-start;
  min-height: calc(100svh - var(--header-h));
  padding-block: clamp(5rem, 3rem + 6vw, 7.5rem) var(--sp-8);
  overflow: hidden;
  background: var(--bg-page);
}

/* VISUAL FIX 5.0.6 — анализ (см. .about ниже за фактической правкой): на
   типичных desktop-вьюпортах (1440×900, 1280×800) высота .hero задаётся
   не контентом+padding, а min-height:calc(100svh - var(--header-h)) —
   контент заканчивается на 683px, а секция всё равно тянется до 900px
   (measured: 152px "хвоста" на 1440×900 ещё до какого-либо padding).
   Из-за этого .hero padding-bottom НЕ влияет на фактическую нижнюю
   границу секции на таких вьюпортах — её уменьшение просто увеличивает
   тот же внутренний "хвост", не двигая .about ни на пиксель (проверено
   эмпирически). Поэтому здесь padding-bottom сознательно НЕ трогается —
   единственная реально работающая точка правки паузы — .about
   padding-top, единственное свойство, которое действительно определяет,
   где начинается видимый контент About относительно конца Hero. */

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(60% 50% at 82% 8%, rgba(101, 15, 24, 0.08), transparent 70%),
    radial-gradient(40% 40% at 8% 92%, var(--tint-gold-soft), transparent 70%);
  pointer-events: none;
  /* VISUAL 2.5: очень лёгкая глубина при скролле — JS (reveal-manager.js)
     задаёт --hero-parallax в пределах ~10px; без JS/при
     prefers-reduced-motion/на mobile переменная остаётся 0px (fallback),
     эффекта просто нет. .hero уже имеет overflow:hidden — сдвиг не
     создаёт видимых краёв. */
  transform: translateY(var(--hero-parallax, 0px));
}

.hero__grid {
  position: relative;
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: var(--sp-9);
  align-items: end;
}

.hero__content h1 {
  margin-top: var(--sp-5);
}

.hero__content .lede {
  margin-top: var(--sp-6);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
}

.hero__aside {
  display: flex;
  flex-direction: column;
  gap: var(--sp-6);
  padding-left: var(--sp-7);
  border-left: 1px solid var(--border-gold);
  /* Parallax-transform задан ниже, в .hero__aside.reveal (в разметке
     .hero__aside всегда несёт оба класса) — там же, где transition:none,
     чтобы не дублировать одно и то же правило в двух местах файла. */
}

/* VISUAL FIX 5.0.3: герб + год + золотая линия — единая ВЕРТИКАЛЬНАЯ
   композиция (герб малым акцентом НАД "2017"), а не строчная пара
   бок-о-бок, как раньше (VISUAL 3.1.1). DOM-порядок (герб, затем год)
   теперь совпадает с визуальным — .hero__year больше не нуждается в
   order:-1.
   ДОПОЛНЕНИЕ 5.0.3: margin-left:auto + align-items:center убраны — группа
   больше не центрируется в правой половине, а выравнивается по той же
   левой оси, что и .hero__stats ниже (оба — flex-column дети .hero__aside;
   .hero__mark имеет фиксированную width:fit-content, поэтому без
   margin-left:auto он естественно прижимается к началу cross-axis, т.е. к
   тому же левому краю content-box, откуда начинается текст в .hero__stats).
   Линия и герб/год теперь тоже left-aligned — left:0 у ::before достаточно,
   translateX-центрирование больше не нужно. */
.hero__mark {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-3);
  width: fit-content;
  padding-bottom: var(--sp-5);
}

.hero__crest {
  position: relative;
  z-index: 1;
  width: clamp(4rem, 2.5rem + 5vw, 6rem);
  height: auto;
}

.hero__mark::before {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 44px;
  height: 1px;
  background: var(--gold);
  transform-origin: left;
}

.hero__year {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.5rem + 3vw, 3.75rem);
  font-weight: 600;
  line-height: 1;
  color: var(--c-burgundy);
  opacity: 0.26;
  pointer-events: none;
}

.hero__stats {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--border-subtle);
}

.hero__stat {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.hero__stat strong {
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  color: var(--accent-deep);
}

.hero__stat span {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  letter-spacing: var(--ls-wide);
}

@media (max-width: 960px) {
  .hero__grid {
    grid-template-columns: 1fr;
  }

  .hero__aside {
    padding-left: 0;
    border-left: 0;
    border-top: 1px solid var(--border-gold);
    padding-top: var(--sp-6);
    flex-direction: column;
    gap: var(--sp-6);
  }

  .hero__mark {
    min-height: auto;
    padding-bottom: 0;
    margin-left: 0;
  }

  .hero__crest {
    width: clamp(3.25rem, 10vw, 4rem);
  }

  /* Год + золотая линия под ним — тот же принцип, что и в VISUAL 2.6
     (ghost-numeral не тащим на mobile/tablet): для диагональной
     композиции герб+год здесь просто не хватает места, а мелкая версия
     читалась бы как случайный обрывок текста поверх герба. Оставляем
     только герб — сам факт "2017" уже читается ниже, в .fact-rail. */
  .hero__year,
  .hero__mark::before {
    display: none;
  }

  .hero__stats {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--sp-7);
    padding-top: 0;
    border-top: 0;
  }
}

/* ==========================================================================
   9.5 About section — «О коллегии»
   ========================================================================== */
.about {
  padding-top: clamp(3rem, 2.4rem + 3vw, 6rem);
}

/* VISUAL FIX 5.0.6: единственная реальная точка правки перехода
   Hero → About — см. анализ у .hero выше (почему padding-bottom Hero там
   сознательно не тронут). На ≥1181px верхний padding секции (был 81.6px
   на 1440px, 76.8px на 1280px — по clamp) зафиксирован на var(--sp-7)
   (48px, тот же нижний предел, что и у самого clamp) — заметное сужение
   видимого зазора (measured: -33.6px на обеих ширинах), без изменения
   mobile/tablet-значений (там clamp не переопределяется — 1024px и уже
   меньше вне этого media query). */
@media (min-width: 1181px) {
  .about {
    padding-top: var(--sp-7);
  }
}

.about__grid {
  display: grid;
  grid-template-columns: 1.3fr 0.9fr;
  gap: var(--sp-9);
  align-items: start;
}

.about__intro {
  display: flex;
  flex-direction: column;
}

.about__blocks {
  display: flex;
  flex-direction: column;
  margin-top: var(--sp-4);
}

.about__block {
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  gap: var(--sp-5);
  padding-block: var(--sp-6);
  border-top: 1px solid var(--border-subtle);
}

.about__block:first-child {
  border-top: none;
  padding-top: var(--sp-2);
}

.about__index {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: 1.1;
  color: var(--gold);
  transition: transform var(--dur-base) var(--ease-standard),
    color var(--dur-base) var(--ease-standard);
}

.about__block:hover .about__index {
  color: var(--accent-deep);
  transform: translateX(3px);
}

.about__block h3 {
  font-size: var(--fs-lg);
  margin-bottom: var(--sp-3);
}

.about__block p {
  margin: 0;
}

.about__quote {
  margin: var(--sp-8) 0 0;
  padding-left: var(--sp-6);
  border-left: 2px solid var(--accent);
}

.about__quote p {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 500;
  line-height: var(--lh-snug);
  color: var(--text-primary);
  max-width: 42ch;
}

.about__quote cite {
  display: block;
  margin-top: var(--sp-5);
  font-style: normal;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.about__aside {
  display: flex;
  flex-direction: column;
  gap: var(--sp-8);
}

.fact-rail {
  display: flex;
  flex-direction: column;
}

.fact-rail__item {
  padding-block: var(--sp-5);
  border-top: 1px solid var(--border-subtle);
}

.fact-rail__item:first-child {
  border-top: none;
  padding-top: 0;
}

.fact-rail__item strong {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-2xl);
  font-weight: 600;
  line-height: 1;
  color: var(--accent-deep);
}

.fact-rail__item span {
  display: block;
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  max-width: 22ch;
}

.fact-rail__item--wide span {
  max-width: none;
}

.about__photo {
  margin: 0;
}

.about__photo-frame {
  position: relative;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--border-subtle);
  background: linear-gradient(155deg, var(--tint-gold-soft), var(--tint-ink-soft));
  display: flex;
  align-items: center;
  justify-content: center;
  /* VISUAL 2.5: тот же лёгкий parallax, что и .hero::before — editorial
     placeholder явно назван в задаче как допустимый кандидат. Сдвигается
     вся рамка целиком (рамка + corner-засечки), поэтому ничего не
     обрезается и не «отстаёт» от своей границы. */
  transform: translateY(var(--photo-parallax, 0px));
  padding: var(--sp-6);
  text-align: center;
}

.about__photo-frame::before,
.about__photo-frame::after {
  content: "";
  position: absolute;
  width: 26px;
  height: 26px;
  border: 1px solid var(--border-gold);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity var(--dur-slow) var(--ease-standard),
    transform var(--dur-slow) var(--ease-standard);
}

/* Золотые засечки мягко проявляются вместе с самим фото-плейсхолдером
   (тот же .reveal, что и на фото), а не отдельным механизмом. */
.about__photo.is-visible .about__photo-frame::before,
.about__photo.is-visible .about__photo-frame::after {
  opacity: 1;
  transform: scale(1);
}

.about__photo-frame::before {
  top: var(--sp-3);
  left: var(--sp-3);
  border-width: 1px 0 0 1px;
  transition-delay: 120ms;
}

.about__photo-frame::after {
  bottom: var(--sp-3);
  right: var(--sp-3);
  border-width: 0 1px 1px 0;
  transition-delay: 220ms;
}

.about__photo-frame span {
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
  max-width: 20ch;
}

.about__photo figcaption {
  margin-top: var(--sp-3);
  font-size: var(--fs-2xs);
  color: var(--text-muted);
}

@media (max-width: 960px) {
  .about__grid {
    grid-template-columns: 1fr;
    gap: var(--sp-7);
  }

  .about__quote p {
    max-width: none;
  }
}

@media (max-width: 480px) {
  .about__block {
    grid-template-columns: 2.25rem 1fr;
    gap: var(--sp-4);
  }
}

/* ==========================================================================
   9.6 Legal Help — editorial-list с раскрытием описания
   ========================================================================== */
.legal-list {
  margin-top: var(--sp-2);
  border-top: 1px solid var(--border-inverse);
}

.legal-item {
  border-bottom: 1px solid var(--border-inverse);
  transition: border-color var(--dur-base) var(--ease-standard);
}

/* VISUAL 2.4: разделительная линия строки теперь тоже часть общей
   hover/focus-системы (номер, заголовок и стрелка уже реагировали —
   строка в целом должна ощущаться одним объектом, не суммой независимых
   деталей). :has() покрывает случай, когда пункт остаётся раскрытым
   после клика (aria-expanded="true"), но фокус уже ушёл с кнопки. */
.legal-item:hover,
.legal-item:focus-within,
.legal-item:has(.legal-item__trigger[aria-expanded="true"]) {
  border-bottom-color: var(--border-gold);
}

.legal-item__trigger {
  display: flex;
  align-items: baseline;
  width: 100%;
  gap: var(--sp-5);
  padding-block: var(--sp-5);
  text-align: left;
  color: var(--text-inverse);
}

.legal-item__index {
  flex-shrink: 0;
  min-width: 2.25rem;
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  color: var(--gold-light);
  transition: color var(--dur-base) var(--ease-standard);
}

.legal-item__title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: var(--lh-snug);
  transition: color var(--dur-base) var(--ease-standard),
    letter-spacing var(--dur-base) var(--ease-standard);
}

.legal-item__arrow {
  flex-shrink: 0;
  font-size: var(--fs-lg);
  color: var(--text-inverse-muted);
  transition: transform var(--dur-base) var(--ease-standard),
    color var(--dur-base) var(--ease-standard);
}

.legal-item:hover .legal-item__index,
.legal-item:focus-within .legal-item__index,
.legal-item__trigger[aria-expanded="true"] .legal-item__index {
  color: var(--accent);
}

.legal-item:hover .legal-item__title,
.legal-item:focus-within .legal-item__title,
.legal-item__trigger[aria-expanded="true"] .legal-item__title {
  color: var(--gold-light);
  letter-spacing: 0.01em;
}

.legal-item:hover .legal-item__arrow,
.legal-item:focus-within .legal-item__arrow,
.legal-item__trigger[aria-expanded="true"] .legal-item__arrow {
  color: var(--accent);
  transform: translateX(6px);
}

/* Раскрытие описания через grid-template-rows: 0fr -> 1fr — плавно и без
   расчёта пиксельной высоты текста, соседние пункты списка не сдвигаются рывком */
.legal-item__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-slow) var(--ease-standard);
}

.legal-item__panel-inner {
  overflow: hidden;
}

.legal-item__desc {
  max-width: 58ch;
  padding-bottom: var(--sp-5);
  font-size: var(--fs-sm);
}

.legal-item:hover .legal-item__panel,
.legal-item:focus-within .legal-item__panel,
.legal-item__trigger[aria-expanded="true"] + .legal-item__panel {
  grid-template-rows: 1fr;
}

@media (max-width: 640px) {
  .legal-item__trigger {
    gap: var(--sp-3);
    padding-block: var(--sp-4);
  }

  .legal-item__title {
    font-size: var(--fs-md);
  }
}

/* ==========================================================================
   10.5 Advokaty page — Hero, featured-профили, каталог
   ========================================================================== */
.page-hero {
  padding-block: clamp(3.5rem, 2.6rem + 4vw, 7rem) clamp(2.5rem, 2rem + 2vw, 4rem);
}

.page-hero__intro {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  max-width: 46rem;
}

.page-hero h1 {
  margin-top: var(--sp-4);
}

/* VISUAL 3.2: hero каталога адвокатов — усиление editorial-языка,
   привязанное к тому же словарю приёмов, что и hero главной (тонкая gold
   line как вертикальная композиционная ось + приглушённая ghost-
   типографика), но НЕ копия композиции index.html (там герб+год как
   отдельный визуальный блок справа, здесь — вертикальная ось слева от
   текста и один приглушённый numeral на фоне). Скоуп строго #catalog-hero
   — .page-hero/.page-hero__intro переиспользуются другими страницами
   (urgent-call.html, publications.html и т.д. — их трогать нельзя). */
#catalog-hero .container {
  position: relative;
}

#catalog-hero .page-hero__intro {
  padding-left: var(--sp-6);
  border-left: 2px solid var(--border-gold);
}

#catalog-hero .page-hero__mark {
  position: absolute;
  right: 0;
  bottom: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(6rem, 3rem + 14vw, 12rem);
  line-height: 1;
  color: var(--c-burgundy);
  opacity: 0.05;
  pointer-events: none;
  user-select: none;
}

@media (max-width: 860px) {
  /* На узких viewport под текстом не остаётся горизонтального запаса —
     крупный ghost-numeral начинает наезжать на .lede, а не читаться как
     фоновый акцент. Убираем целиком, как и "2017" в hero главной на
     mobile — тот же принцип: decoration не переживает нехватку места. */
  #catalog-hero .page-hero__mark {
    display: none;
  }
}

/* -- Featured-профиль (председатель / заместитель) -- */
.advokat-featured {
  padding-block: var(--section-pad-y);
  border-top: 1px solid var(--border-subtle);
  scroll-margin-top: var(--header-h);
}

.advokat-featured__grid {
  display: grid;
  grid-template-columns: 0.8fr 1.2fr;
  gap: var(--sp-9);
  align-items: start;
}

.advokat-photo-frame {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border: 1px solid var(--border-subtle);
  background: linear-gradient(155deg, var(--tint-gold-soft), var(--tint-ink-soft));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-6);
  text-align: center;
}

/* LAWYERS CONTENT 1.0: раньше photoFrame() в advokaty.js рендерил только
   текстовый placeholder — правил под реальный <img> не было. Padding
   убирается только когда внутри реальное фото (:has(img)), чтобы текстовый
   placeholder не потерял отступы. object-fit:cover заполняет уже
   существующую рамку 3:4, ничего в самой рамке не меняя. */
.advokat-photo-frame:has(img) {
  padding: 0;
}

.advokat-photo-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  /* LAWYERS CONTENT 1.1: лёгкий micro-zoom при hover/focus — та же
     механика и тот же motion-token (--motion-hover), что уже используют
     .btn:hover и другие hover-состояния сайта, никакой новой библиотеки. */
  transition: transform var(--motion-hover);
}

.advokat-photo-frame:hover img,
.advokat-photo-frame:focus-within img {
  transform: scale(1.035);
}

/* Уголки-засечки должны оставаться поверх фото (у .advokat-card__photo-inner
   ниже это не нужно — там :has(span) сам отключает засечки, как только
   вместо placeholder рендерится <img>, см. комментарий VISUAL 2.2 ниже). */
.advokat-photo-frame::before,
.advokat-photo-frame::after {
  z-index: 1;
}

.advokat-photo-frame::before,
.advokat-photo-frame::after {
  content: "";
  position: absolute;
  width: 26px;
  height: 26px;
  border: 1px solid var(--border-gold);
  /* VISUAL 2.2: тот же reveal-tie, что уже есть у .about__photo-frame —
     засечки мягко проявляются вместе с самим .reveal-элементом (у
     advokaty.js .advokat-photo-frame уже несёт класс .reveal сам по
     себе), а не показываются статично сразу. Одна и та же visual
     language для обоих photo-frame компонентов сайта. */
  opacity: 0;
  transform: scale(0.6);
  transition: opacity var(--dur-slow) var(--ease-standard),
    transform var(--dur-slow) var(--ease-standard),
    border-color var(--motion-hover);
}

/* LAWYERS CONTENT 1.1: тот же лёгкий hover-акцент на золоте, что и в
   остальном сайте (например .about__block:hover .about__index) — уголки
   чуть светлеют при наведении/фокусе на фото, подтверждая интерактивность
   без нового визуального языка. */
.advokat-photo-frame:hover::before,
.advokat-photo-frame:hover::after,
.advokat-photo-frame:focus-within::before,
.advokat-photo-frame:focus-within::after {
  border-color: var(--gold-light);
}

.advokat-photo-frame.is-visible::before,
.advokat-photo-frame.is-visible::after {
  opacity: 1;
  transform: scale(1);
}

.advokat-photo-frame::before {
  top: var(--sp-3);
  left: var(--sp-3);
  border-width: 1px 0 0 1px;
  transition-delay: 120ms;
}

.advokat-photo-frame::after {
  bottom: var(--sp-3);
  right: var(--sp-3);
  border-width: 0 1px 1px 0;
  transition-delay: 220ms;
}

.advokat-photo-frame span {
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
  max-width: 18ch;
}

/* VISUAL FIX 5.0.3: .advokat-photo-frame — прямой grid-item
   .advokat-featured__grid (0.8fr 1.2fr, п.4 задания). Чтобы подпись с
   регистрационным номером легла именно ПОД фото (а не заняла вторую
   колонку вместо .advokat-featured__body), фото и подпись обёрнуты в общий
   flex-column-контейнер — единственный первый grid-item, как и раньше.
   Используется только на странице отдельного профиля (renderProfile() в
   advokaty.js) — featured-блоки председателя/заместителя в каталоге эту
   обёртку не получают и не менялись. */
.advokat-profile__photo-col {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.advokat-profile__reg-caption {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  font-style: italic;
}

.advokat-featured__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}

.advokat-featured__position {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--accent-deep);
}

.advokat-featured__name {
  margin-top: var(--sp-1);
  font-size: var(--fs-2xl);
}

/* LAWYERS CONTENT 1.1: renderFeatured() в advokaty.js — общий шаблон для
   председателя и заместителя (HTML/JS не менялись — оба блока уже имеют
   собственный id). Председатель получает более высокий визуальный статус
   точечными CSS-переопределениями поверх той же разметки: крупнее имя
   (главный типографический акцент), более читаемая должность, чуть больше
   пространства сверху, на этом фоне не тронутый .advokat-featured —
   заместитель и обычные карточки остаются как были. Тонкая золотая верхняя
   линия — статусный маркер, тот же приём/токен, что и .rule/.eyebrow::before
   по всему сайту, не новый декоративный элемент.
   ДОПОЛНЕНИЕ 5.0.5: раньше председатель ещё и получал свою, более широкую
   колонку фото (1.15fr 1fr вместо базовых 0.8fr 1.2fr) БЕЗ max-width, а
   заместитель — базовую узкую колонку (0.8fr) но с жёстким max-width:20rem
   на фото. Из-за разных источников ограничения ширины (grid-column vs
   max-width) фото председателя выходило почти вдвое крупнее (543×725px на
   1440px), а у заместителя между узкой рамкой-плейсхолдером и текстовой
   колонкой образовывался пустой разрыв ~195px — асимметрия была
   геометрической случайностью, а не осознанным решением (см. VISUAL AUDIT
   5.0, P2). Теперь оба блока используют ОДНУ и ту же геометрию grid/фото
   (унаследовано от базовых .advokat-featured__grid/.advokat-photo-frame
   ниже, никаких блочных override для фото/сетки не осталось ни у
   председателя, ни у заместителя) — статус председателя выражается только
   типографикой/space/gold-line ниже, не размером фото. */
/* VISUAL 3.2: full-width 2px gold border заменён на короткий editorial-
   акцент (позиция gold rule — единственное, что меняется; сама идея
   "gold = статусный маркер" сохранена). Структурная граница секции
   остаётся тонкой (1px subtle), как у обычного .advokat-featured — не
   нужно двух конкурирующих золотых линий подряд. */
#chairman-block.advokat-featured {
  padding-block: calc(var(--section-pad-y) * 1.15) var(--section-pad-y);
  border-top: 1px solid var(--border-subtle);
  position: relative;
}

#chairman-block.advokat-featured::before {
  content: "";
  position: absolute;
  top: -1px;
  left: var(--container-pad);
  width: 96px;
  height: 2px;
  background: var(--gold);
}

#chairman-block .advokat-featured__body {
  gap: var(--sp-6);
}

#chairman-block .advokat-featured__position {
  font-size: var(--fs-md);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

#chairman-block .advokat-featured__name {
  font-size: var(--fs-3xl);
}

#chairman-block .lede {
  font-size: var(--fs-md);
  line-height: var(--lh-relaxed);
}

/* VISUAL 3.2, п.5: у заместителя пока нет реального фото (photo: null в
   advokaty-data.js) — задание прямо запрещает визуально "маскировать"
   это под председателя. renderFeatured() в advokaty.js рендерит один и
   тот же шаблон для обоих блоков — различие целиком в CSS: заместитель
   ощутимо тише (приглушённые цвета, меньше имя), но структура (eyebrow →
   имя → роль → meta) не ломается — блок не выглядит "сломанным", просто
   явно вторичным. ДОПОЛНЕНИЕ 5.0.5: собственный max-width у фото убран —
   рамка-плейсхолдер теперь той же ширины, что и у председателя (базовая
   grid-колонка), без сиротского пустого промежутка перед текстом. */
#deputy-block .eyebrow {
  color: var(--text-muted);
}

#deputy-block .advokat-featured__position {
  color: var(--text-muted);
}

#deputy-block .advokat-featured__name {
  font-size: var(--fs-xl);
  color: var(--text-muted);
}

.advokat-meta {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--border-subtle);
}

.advokat-meta__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm);
}

.advokat-meta__row dt {
  min-width: 12rem;
  font-weight: 600;
  color: var(--text-primary);
}

.advokat-meta__row dd {
  margin: 0;
  color: var(--text-muted);
  font-style: italic;
}

@media (max-width: 860px) {
  .advokat-featured__grid {
    grid-template-columns: 1fr;
    gap: var(--sp-6);
  }

  .advokat-photo-frame {
    max-width: 22rem;
  }
}

/* -- Каталог остальных адвокатов -- */
.advokat-catalog {
  padding-block: var(--section-pad-y);
  border-top: 1px solid var(--border-subtle);
}

/* VISUAL 3.2: раньше auto-fill/minmax(240px,1fr) на 1024px давал 3
   колонки — при ровно 4 реальных карточках это оставляло одну "сироткой"
   на отдельной строке (не masonry, но и не единая система, как требует
   задание). Явные брейкпоинты 4 → 2 → 1 (те же пороги, что уже использует
   #chairman-block/.advokat-featured-grid — новый брейкпоинт не вводится)
   гарантируют, что ровно 4 карточки всегда образуют полные ряды.
   VISUAL FIX 5.1.1: та же идея (полные ряды выглядят системно), но теперь
   без предположения "количество карточек кратно 4" — с появлением
   плейсхолдер-карточек их стало 14, и CSS Grid (repeat(4,1fr)) всегда
   прижимает неполный последний ряд к левому краю, оставляя 2 пустые
   колонки справа. display:flex + flex-wrap:wrap + justify-content:center
   — стандартный, независимый от количества элементов приём: на ПОЛНОМ
   ряду flex-basis в сумме с gap'ами точно равен 100% ширины (столбцы
   визуально идентичны прежней grid-раскладке, эффект центрирования на
   них нулевой), а на НЕПОЛНОМ последнем ряду justify-content:center сам
   центрирует оставшиеся карточки — без nth-child, JS-вычислений или
   ручных правок под текущие 14. Когда карточек станет 16 (кратно 4),
   последний ряд просто станет полным сам по себе — это же правило
   ничего не потребует менять. */
.advokat-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-8) var(--sp-6);
  margin-top: var(--sp-2);
}

.advokat-card {
  display: flex;
  flex-direction: column;
  flex: 0 0 100%;
  gap: var(--sp-4);
  color: var(--text-primary);
}

@media (min-width: 560px) {
  .advokat-card {
    flex-basis: calc((100% - var(--sp-6)) / 2);
  }
}

@media (min-width: 861px) {
  .advokat-card {
    flex-basis: calc((100% - 3 * var(--sp-6)) / 4);
  }
}

.advokat-card__photo {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border: 1px solid var(--border-subtle);
}

.advokat-card__photo-inner {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  text-align: center;
  background: linear-gradient(155deg, var(--tint-gold-soft), var(--tint-ink-soft));
  transition: transform var(--dur-slow) var(--ease-standard);
}

/* VISUAL 2.2: те же corner-засечки, что у .advokat-photo-frame/
   .about__photo-frame — только пока карточка реально в placeholder-
   состоянии (рендерится <span>, а не <img> — см. photoFrame() в
   advokaty.js). :has() делает это автоматически самоснимающимся: как
   только у адвоката появится фото и JS отрендерит <img> вместо <span>,
   рамка перестанет показываться сама, без дополнительной правки CSS. */
.advokat-card__photo-inner:has(span)::before,
.advokat-card__photo-inner:has(span)::after {
  content: "";
  position: absolute;
  width: 18px;
  height: 18px;
  border: 1px solid var(--border-gold);
  pointer-events: none;
}

.advokat-card__photo-inner:has(span)::before {
  top: var(--sp-2);
  left: var(--sp-2);
  border-width: 1px 0 0 1px;
}

.advokat-card__photo-inner:has(span)::after {
  bottom: var(--sp-2);
  right: var(--sp-2);
  border-width: 0 1px 1px 0;
}

.advokat-card__photo-inner span {
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* LAWYERS CONTENT 1.0: реальное фото заполняет уже существующую
   3:4-рамку (.advokat-card__photo уже имеет overflow:hidden) — padding
   убирается только когда внутри <img>, текстовый placeholder не задет. */
.advokat-card__photo-inner:has(img) {
  padding: 0;
}

.advokat-card__photo-inner img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

/* ДОПОЛНЕНИЕ 5.0.3 (правка 2): justify-content:space-between убран — с
   появлением второго child'а (.advokat-card__reg) он растягивал бы номер
   карточки и регистрационный номер по разным краям строки. Нужны рядом,
   на одной строке, поэтому justify-content не задаётся (flex-start по
   умолчанию). */
.advokat-card__meta {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
}

.advokat-card__index {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--gold);
}

.advokat-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  border-top: 1px solid var(--border-subtle);
  padding-top: var(--sp-3);
  position: relative;
}

.advokat-card__name {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: var(--lh-snug);
  transition: color var(--dur-base) var(--ease-standard);
}

/* ДОПОЛНЕНИЕ 5.0.3 (правка 2): регистрационный номер — на одной строке с
   номером карточки, внутри .advokat-card__meta (не отдельной строкой выше
   или ниже). Стиль не менялся — тот же italic+muted идиом, что и
   .advokat-meta__row dd для этого же типа данных. Рендерится только когда в
   advokaty-data.js есть реальный номер (см. advokaty.js regNumberLine()) —
   карточки без подтверждённого номера просто не получают этот span, никакой
   номер не придумывается. */
.advokat-card__reg {
  font-size: var(--fs-xs);
  line-height: var(--lh-normal);
  color: var(--text-muted);
  font-style: italic;
}

.advokat-card__role {
  /* Самый тихий уровень иерархии в .advokat-card__body — мельче ФИО. */
  font-size: var(--fs-2xs);
  line-height: var(--lh-normal);
  color: var(--text-muted);
}

.advokat-card__arrow {
  position: absolute;
  right: 0;
  top: var(--sp-3);
  font-size: var(--fs-md);
  color: var(--text-muted);
  transition: transform var(--dur-base) var(--ease-standard),
    color var(--dur-base) var(--ease-standard);
}

.advokat-card__body::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 0;
  height: 1px;
  background: var(--accent);
  transition: width var(--dur-base) var(--ease-standard);
}

.advokat-card:hover .advokat-card__photo-inner,
.advokat-card:focus-visible .advokat-card__photo-inner {
  transform: scale(1.04);
}

.advokat-card:hover .advokat-card__body::before,
.advokat-card:focus-visible .advokat-card__body::before {
  width: 100%;
}

.advokat-card:hover .advokat-card__name,
.advokat-card:focus-visible .advokat-card__name {
  color: var(--accent-deep);
}

/* LAWYERS CONTENT 1.2: карточка адвоката без реального фото рендерится как
   <div>, а не <a> (advokaty.js), поэтому не кликабельна — стрелка уже не
   выводится в разметке, здесь только нейтрализуются hover-эффекты,
   рассчитанные на интерактивную карточку (иначе курсор/наведение намекали
   бы на несуществующую ссылку). */
.advokat-card--static {
  cursor: default;
}

.advokat-card--static:hover .advokat-card__photo-inner {
  transform: none;
}

.advokat-card--static:hover .advokat-card__body::before {
  width: 0;
}

.advokat-card--static:hover .advokat-card__name {
  color: var(--text-primary);
}

.advokat-card:hover .advokat-card__arrow,
.advokat-card:focus-visible .advokat-card__arrow {
  transform: translateX(5px);
  color: var(--accent);
}

.advokat-empty-state {
  position: relative;
  /* grid-column больше не действует (.advokat-grid — flex, VISUAL FIX
     5.1.1), но безвредна как leftover; flex-basis:100% — тот же эффект
     "на всю ширину ряда" для flex-контекста. */
  grid-column: 1 / -1;
  flex-basis: 100%;
  margin-top: var(--sp-6);
  padding: var(--sp-7);
  border: 1px dashed var(--border-subtle);
  background: linear-gradient(155deg, var(--tint-gold-soft), var(--tint-ink-soft));
  color: var(--text-muted);
  font-size: var(--fs-sm);
  max-width: 60ch;
}

/* VISUAL 2.2: тот же line-accent, что у .eyebrow::before — тонкая
   золотая черта над текстом вместо «серого» пустого блока. */
.advokat-empty-state::before {
  content: "";
  display: block;
  width: 28px;
  height: 1px;
  margin-bottom: var(--sp-4);
  background: var(--gold);
}

/* ==========================================================================
   10.6 Official Info page — реквизиты, документы, адвокатское сообщество
   ========================================================================== */
/* Hero: тот же editorial-словарь, что и у hero advokaty.html/publications.
   html/legal-help.html — вертикальная gold-ось слева от текста +
   приглушённый ghost-numeral справа. Скоуп строго по уникальному
   aria-labelledby секции — .page-hero/.page-hero__intro переиспользуются
   другими страницами (urgent-call.html, contacts.html и т.д.). */
section[aria-labelledby="official-info-hero-heading"] .container {
  position: relative;
}

section[aria-labelledby="official-info-hero-heading"] .page-hero__intro {
  padding-left: var(--sp-6);
  border-left: 2px solid var(--border-gold);
}

section[aria-labelledby="official-info-hero-heading"] .page-hero__mark {
  position: absolute;
  right: 0;
  bottom: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(6rem, 3rem + 14vw, 12rem);
  line-height: 1;
  color: var(--c-burgundy);
  opacity: 0.05;
  pointer-events: none;
  user-select: none;
}

@media (max-width: 860px) {
  section[aria-labelledby="official-info-hero-heading"] .page-hero__mark {
    display: none;
  }
}

/* VISUAL 4.1 fix: тот же случай, что уже встречался на publications.html
   ("Публикации") и legal-help.html ("Юридическая помощь") — левый
   padding золотой оси у узких viewport оставляет слишком мало места для
   "Официальная информация" (оба слова длинные), и hyphens:auto переносит
   оба по слогам. Порог здесь совпадает с legal-help.html (проверено
   вплоть до 480px) — убираем ось только там, где перенос реально
   возникал. */
@media (max-width: 480px) {
  section[aria-labelledby="official-info-hero-heading"] .page-hero__intro {
    padding-left: 0;
    border-left: 0;
  }
}

/* VISUAL REFINEMENT 4.4: тот же случай, что и на legal-help.html — оба
   слова "Официальная информация" при базовом --fs-4xl не помещаются в
   свою строку на 400/390/375/360px без hyphens:auto. Scoped уменьшение
   именно этого H1, перенос на 2 строки сохраняется. */
@media (max-width: 480px) {
  section[aria-labelledby="official-info-hero-heading"] h1 {
    font-size: clamp(2.4rem, 2rem + 2vw, 3.1rem);
  }
}

/* -- Реквизиты: editorial definition list (VISUAL 4.1) --
   Раньше dt (label) был визуально главным (bold, --text-primary), а dd
   (само значение — то, ради чего люди приходят на эту страницу: ОГРН,
   ИНН и т.д.) — приглушённым. Задание прямо просит "быстрое сканирование"
   реквизитов — переставлена иерархия: label теперь маленький uppercase-
   маркер (как eyebrow), значение — крупный, чёткий, основной акцент.
   Верхняя граница блока — gold (один из трёх выбранных editorial-приёмов
   страницы, наравне с нумерацией документов и thin gold separators). */
.requisites {
  margin-top: var(--sp-2);
  max-width: 54rem;
  border-top: 2px solid var(--border-gold);
}

.requisites__row {
  display: grid;
  grid-template-columns: 15rem 1fr;
  align-items: baseline;
  gap: var(--sp-4) var(--sp-6);
  padding-block: var(--sp-5);
  border-bottom: 1px solid var(--border-subtle);
}

.requisites__row dt {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.requisites__row dd {
  margin: 0;
  font-size: var(--fs-md);
  color: var(--text-primary);
}

/* ОГРН/ИНН/КПП — регистрационные номера, которые посетитель обычно
   сверяет/копирует: табличные цифры (tabular-nums) держат разряды на
   одной сетке, не меняя саму типографику (шрифт/размер — прежние). Три
   строки выбраны позиционно (4-я/5-я/6-я строка списка), а не новым
   классом в разметке — порядок реквизитов уже зафиксирован и не
   меняется отдельной командой. */
.requisites__row:nth-child(4) dd,
.requisites__row:nth-child(5) dd,
.requisites__row:nth-child(6) dd {
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

@media (max-width: 640px) {
  .requisites__row {
    grid-template-columns: 1fr;
    gap: var(--sp-1);
  }
}

/* -- Документы -- */
/* VISUAL REFINEMENT 4.4: "Регистрационные" (16 букв) — самое длинное слово
   заголовка на сайте; без hyphens:auto не помещается в свою строку на
   430/400/390/375/360px. Обычный H2, не hero — своего gold-axis padding
   нет, поэтому нужна только компактная ширина шрифта. */
@media (max-width: 480px) {
  #documents-heading {
    font-size: clamp(2rem, 1.7rem + 1.6vw, 2.5rem);
  }
}

/* VISUAL REFINEMENT 4.4.1: auto-fit (не auto-fill) — с ровно 4 документами
   auto-fill мог оставлять пустые grid-треки на широком desktop (колонки
   резервировались под несуществующий 5-й элемент); auto-fit схлопывает
   незанятые треки, поэтому 4 карточки всегда делят весь доступный ряд
   без чужого пустого места справа. */
.doc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--sp-7) var(--sp-6);
  margin-top: var(--sp-2);
}

.doc-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  color: var(--text-primary);
  transition: transform var(--motion-hover);
}

/* VISUAL 4.1, п.9-10: очень лёгкий "lift" всей карточки вместо тяжёлой
   тени — тот же --shadow-md, что уже определён в токенах как "едва
   заметный, без bootstrap-тяжести". Только для реальных, кликабельных
   документов (:not(--placeholder)) — placeholder не является ссылкой,
   и hover-подъём на нём читался бы как ложный намёк на интерактивность. */
.doc-card:not(.doc-card--placeholder):hover,
.doc-card:not(.doc-card--placeholder):focus-visible {
  transform: translateY(-2px);
}

.doc-card__index {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--gold-text);
}

.doc-card__preview {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border: 1px solid var(--border-subtle);
  background: linear-gradient(155deg, var(--tint-gold-soft), var(--tint-ink-soft));
  transition: box-shadow var(--motion-hover);
}

.doc-card:not(.doc-card--placeholder):hover .doc-card__preview,
.doc-card:not(.doc-card--placeholder):focus-visible .doc-card__preview {
  box-shadow: var(--shadow-md);
}

/* VISUAL 4.1, п.9: реальные сканы — формат, близкий к A4 (0.7), рамка
   preview — 3:4 (0.75). object-fit:cover в этом случае немного обрезал
   бы низ скана (подпись/печать) — заменено на contain: изображение
   целиком, без кадрирования и без искажения пропорций; тонкие поля по
   бокам заливаются тем же тонированным градиентом фона рамки, что и у
   пустого placeholder — не выглядят "пустым браком". */
.doc-card__preview img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform var(--dur-slow) var(--ease-standard);
}

.doc-card:hover .doc-card__preview img,
.doc-card:focus-visible .doc-card__preview img {
  transform: scale(1.04);
}

.doc-card__preview-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-5);
  text-align: center;
}

.doc-card__preview-empty span {
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
  max-width: 18ch;
}

.doc-card--placeholder .doc-card__preview {
  border-style: dashed;
}

/* VISUAL 2.2: те же corner-засечки, что у photo-frame-компонентов — этот
   документ визуально остаётся частью той же серии карточек (см. два
   реальных .doc-card рядом), не отдельным «недоделанным» блоком. Не
   имитирует скан документа — только рамка вокруг уже существующей
   подписи «Документ будет добавлен». */
.doc-card--placeholder .doc-card__preview::before,
.doc-card--placeholder .doc-card__preview::after {
  content: "";
  position: absolute;
  width: 18px;
  height: 18px;
  border: 1px solid var(--border-gold);
  pointer-events: none;
}

.doc-card--placeholder .doc-card__preview::before {
  top: var(--sp-3);
  left: var(--sp-3);
  border-width: 1px 0 0 1px;
}

.doc-card--placeholder .doc-card__preview::after {
  bottom: var(--sp-3);
  right: var(--sp-3);
  border-width: 0 1px 1px 0;
}

.doc-card__badge {
  display: inline-flex;
  align-self: flex-start;
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--gold);
  border: 1px solid var(--border-gold);
  padding: 0.2rem 0.6rem;
}

.doc-card__title {
  position: relative;
  padding-top: var(--sp-3);
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 500;
  line-height: var(--lh-snug);
}

/* Тонкая gold-линия, раскрывающаяся под заголовком при hover/focus —
   тот же приём "растущей снизу линии", что и .category-card__body::before
   /.publication-card__body::before, третий из трёх выбранных editorial-
   приёмов страницы (thin gold separators). Только для реальных
   документов — на placeholder ссылки нет. */
.doc-card__title::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--border-subtle);
}

.doc-card:not(.doc-card--placeholder):hover .doc-card__title::before,
.doc-card:not(.doc-card--placeholder):focus-visible .doc-card__title::before {
  background: var(--gold);
}

.doc-card__type {
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.doc-card__action {
  margin-top: var(--sp-1);
}

.doc-card__action[aria-disabled="true"] {
  display: inline-block;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-style: italic;
}

/* -- Адвокатское сообщество: editorial list (VISUAL 4.1) --
   Раньше — два одинаковых боксовых блока в сетке ("[name][text][button]",
   именно то, чего просило избегать задание). Теперь — тот же язык
   номерного editorial-списка, что и .direction-list на legal-help.html:
   номер + тонкий разделитель между пунктами вместо рамки на каждый.
   Цвета — inverse (та же тёмная секция .section--dark, что и раньше). */
.chamber-list {
  margin-top: var(--sp-2);
  border-top: 1px solid var(--border-inverse);
}

.chamber-item {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: var(--sp-5);
  padding-block: var(--sp-7);
  border-bottom: 1px solid var(--border-inverse);
  transition: border-color var(--motion-nav);
}

.chamber-item:hover,
.chamber-item:focus-within {
  border-bottom-color: var(--border-gold);
}

.chamber-item__index {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: 1.1;
  color: var(--gold-light);
}

.chamber-item__name {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 500;
  margin-bottom: var(--sp-3);
}

.chamber-item__desc {
  margin: 0 0 var(--sp-4);
  max-width: 48ch;
}

.chamber-item__link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

/* Реальный span, а не ::after: .link-underline уже занимает ::after
   этого элемента под линию подчёркивания — второй ::after конфликтовал бы
   с ней (побеждает лишь свойство content, position/transform остаются
   от .link-underline, и стрелка рендерится как обрезанный артефакт). */
.chamber-item__arrow-icon {
  display: inline-block;
  transition: transform var(--dur-base) var(--ease-standard);
}

.chamber-item:hover .chamber-item__arrow-icon,
.chamber-item:focus-within .chamber-item__arrow-icon {
  transform: translate(2px, -2px);
}

@media (max-width: 480px) {
  .chamber-item {
    grid-template-columns: 2.25rem 1fr;
    gap: var(--sp-4);
    padding-block: var(--sp-6);
  }
}

/* ==========================================================================
   10.7 Urgent Call page — «Срочный выезд адвоката»
   ========================================================================== */
/* VISUAL 4.3, п.4: по брифу hero не должен занимать весь mobile viewport
   декоративным воздухом — .page-hero (padding-block) переиспользуется
   другими страницами, поэтому здесь только scoped-уменьшение отступов
   именно этого hero (H1/24/7/CTA остаются исходного размера, сокращается
   только пустое пространство сверху/снизу). */
section[aria-labelledby="urgent-hero-heading"] {
  padding-block: clamp(2.5rem, 2rem + 3vw, 5rem) clamp(2rem, 1.6rem + 1.5vw, 3rem);
}

/* VISUAL 4.3: заменяет прежний .live-badge (маленький uppercase-бейдж с
   пульсирующей точкой после lede). По брифу "24/7" — один из главных
   элементов hero, воспринимаемый как режим доступности, а не рекламный
   badge; пульсацию явно запрещено использовать ("не pulse/flashing/
   heartbeat/glow"). Заменено крупной статичной типографикой (сильный
   editorial-приём #1) + тонкой gold-линией (тот же приём "тонкая линия",
   что и .final-cta__phone::before рядом), без анимации точки. Перемещено
   перед h1 (было после lede) — по брифу иерархия hero: 24/7 → H1 → lead → CTA. */
.urgent-badge {
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid rgba(201, 184, 174, 0.28);
}

.urgent-badge__number {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.35rem + 2vw, 2.75rem);
  font-weight: 600;
  line-height: 1;
  color: var(--gold-light);
}

.urgent-badge__label {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-inverse-muted);
}

.urgent-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin-top: var(--sp-7);
}

.urgent-actions__note {
  margin-top: var(--sp-4);
  max-width: 46ch;
  font-size: var(--fs-xs);
  color: var(--text-inverse-muted);
  font-style: italic;
}

/* -- Когда нужен срочный выезд -- */
/* VISUAL 4.3: по брифу — editorial rows (номер + текст), как у .step ниже
   (тот же приём "номерная ось 01-04", editorial-приём #2, переиспользован
   для двух списков страницы, а не два разных приёма). Было: 2-колоночная
   сетка с маленьким квадратным маркером — быстро сканируется, но не
   соответствует "01/02/03/04"-формату из брифа; текст ситуаций не менялся,
   только разметка/маркер. */
.situation-grid {
  display: flex;
  flex-direction: column;
  margin-top: var(--sp-2);
}

.situation-item {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: var(--sp-5);
  padding-block: var(--sp-5);
  border-top: 1px solid var(--border-subtle);
}

.situation-item:first-child {
  border-top: none;
  padding-top: var(--sp-2);
}

.situation-item__index {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: 1.1;
  color: var(--gold);
}

.situation-item p {
  margin: 0;
  align-self: center;
  color: var(--text-primary);
  font-size: var(--fs-md);
  line-height: var(--lh-snug);
}

@media (max-width: 480px) {
  .situation-item {
    grid-template-columns: 2.5rem 1fr;
    gap: var(--sp-4);
  }
}

/* -- Что делает дежурный адвокат -- */
.steps-list {
  display: flex;
  flex-direction: column;
  margin-top: var(--sp-2);
}

.step {
  display: grid;
  grid-template-columns: 3.5rem 1fr;
  gap: var(--sp-5);
  padding-block: var(--sp-6);
  border-top: 1px solid var(--border-subtle);
}

.step:first-child {
  border-top: none;
  padding-top: var(--sp-2);
}

.step__index {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 600;
  line-height: 1;
  color: var(--gold);
  transition: transform var(--dur-base) var(--ease-standard),
    color var(--dur-base) var(--ease-standard);
}

.step:hover .step__index {
  color: var(--accent-deep);
  transform: scale(1.08);
}

.step__title {
  margin: 0;
  align-self: center;
  font-size: var(--fs-md);
  font-weight: 700;
  line-height: var(--lh-snug);
  color: var(--text-primary);
}

@media (max-width: 480px) {
  .step {
    grid-template-columns: 2.5rem 1fr;
    gap: var(--sp-4);
  }
}

/* -- Важно -- */
.important-panel {
  max-width: 56rem;
  padding: var(--sp-7) var(--sp-8);
  border-left: 3px solid var(--accent);
  background: var(--bg-surface);
}

.important-panel__lead {
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 500;
  line-height: var(--lh-snug);
  max-width: 30ch;
}

.important-panel p + p {
  margin-top: var(--sp-4);
  max-width: 60ch;
}

@media (max-width: 640px) {
  .important-panel {
    padding: var(--sp-6);
  }
}

/* -- Финальный CTA -- */
.final-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-6);
}

.final-cta h2 {
  max-width: 22ch;
}

.final-cta__phone {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-6) var(--sp-8);
  border: 1px dashed var(--border-gold);
}

/* VISUAL 2.2: тот же line-accent, что у .eyebrow::before/
   .advokat-empty-state — светлее (--gold-light), т.к. элемент на тёмном
   бордовом фоне (та же логика, что у .section--dark .eyebrow). */
.final-cta__phone::before {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--gold-light);
}

.final-cta__phone-label {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--gold-light);
}

.final-cta__phone-value {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 1rem + 1vw, var(--fs-xl));
  color: var(--text-inverse);
}

.final-cta .urgent-actions {
  justify-content: center;
}

/* ==========================================================================
   10.8 Contacts page — «Контакты и обратная связь»
   ========================================================================== */
/* VISUAL 4.2: компактный hero — короче, чем .page-hero по умолчанию (тот
   же класс использует и главная), и с более узкой/тонкой gold-осью, чем
   ghost-numeral-приём advokaty/legal-help/official-info/publications —
   контакты сознательно не повторяют тот же композиционный приём буквально.
   Scoped через #contacts-hero, чтобы не задеть .page-hero/.page-hero__intro
   на других страницах. */
#contacts-hero {
  padding-block: clamp(2.5rem, 2rem + 2vw, 4rem) clamp(2rem, 1.6rem + 1.5vw, 3rem);
}

#contacts-hero .page-hero__intro {
  padding-left: var(--sp-4);
  border-left: 1px solid var(--border-gold);
}

@media (max-width: 480px) {
  /* Тот же паттерн, что и на publications/legal-help/official-info: узкий
     viewport + padding-left от gold-оси сужают доступную ширину настолько,
     что hyphens:auto (глобальное правило h1-h4) переносит первое слово
     H1 посередине слога — снимаем ось только на этой ширине. */
  #contacts-hero .page-hero__intro {
    padding-left: 0;
    border-left: 0;
  }
}

.contact-grid {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: var(--sp-9);
  align-items: start;
}

.contact-list {
  display: flex;
  flex-direction: column;
}

.contact-list__item {
  display: grid;
  grid-template-columns: 2.75rem 1fr;
  gap: var(--sp-5);
  padding-block: var(--sp-6);
  border-top: 1px solid var(--border-subtle);
}

.contact-list__item:first-child {
  border-top: none;
  padding-top: var(--sp-2);
}

.contact-list__index {
  display: inline-block;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: 1.1;
  color: var(--gold);
  transition: transform var(--dur-base) var(--ease-standard),
    color var(--dur-base) var(--ease-standard);
}

.contact-list__item:hover .contact-list__index {
  color: var(--accent-deep);
  transform: translateX(3px);
}

.contact-list__label {
  display: block;
  margin-bottom: var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.contact-list__value {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--text-primary);
}

.contact-list__value--placeholder {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  font-style: italic;
  color: var(--text-muted);
}

/* VISUAL 2.2: маленький статусный маркер вместо решения через новый
   текст — сигнализирует «значение ожидается», не добавляя слов. */
.contact-list__value--placeholder::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: var(--sp-2);
  background: var(--gold);
  border-radius: 50%;
  vertical-align: middle;
}

/* Вторая (уточняющая) строка под основным значением — например, ближайшее
   метро под адресом (Этап 9.2). Не заменяет основной .contact-list__value,
   а идёт следом, поэтому получает небольшой верхний отступ. */
.contact-list__value--secondary {
  margin-top: var(--sp-1);
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--text-muted);
}

/* VISUAL 4.2: email — единственный по-настоящему "actionable" пункт
   контактного стека (адрес — факт, метро — уточнение), поэтому получает
   отдельный акцент: тот же .contact-list__value (Fraunces, тот же размер,
   чтобы не создавать лишний уровень иерархии), но золотой text-color
   (--gold-text — контрастный вариант для текста, не декоративный --gold)
   и .link-underline вместо обычного текста. Специально не увеличен и не
   оформлен как кнопка — по брифу email должен оставаться строкой текста. */
.contact-list__value--email {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-2);
  color: var(--gold-text);
  cursor: pointer;
}

.contact-list__value--email[aria-disabled="true"] {
  color: var(--text-muted);
  font-style: italic;
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  cursor: default;
  pointer-events: none;
}

.contact-list__email-arrow {
  display: inline-block;
  font-family: var(--font-body);
  transition: transform var(--dur-base) var(--ease-standard);
}

.contact-list__value--email:hover .contact-list__email-arrow,
.contact-list__value--email:focus-visible .contact-list__email-arrow {
  transform: translateX(3px);
}

/* VISUAL REFINEMENT 4.4: заменяет прежний .messenger-links/.messenger-link
   (3 icon-контейнера разного размера, цветные брендовые SVG) — по брифу
   все 5 способов связи (Телефон/Telegram/WhatsApp/MAX/E-mail) должны быть
   ОДНОЙ editorial-системой: одинаковый размер (grid, не auto-width по
   контенту), только текст/типографика + номерной маркер, без цветных
   иконок. */
.contact-methods {
  margin-top: var(--sp-8);
}

.contact-methods__label {
  display: block;
  margin-bottom: var(--sp-4);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.contact-methods__grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--sp-3);
}

/* VISUAL CORRECTION 4.4.4: финальная композиция — горизontальная compact
   button (logo | тонкий разделитель | номер+название | стрелка), а не
   вертикальная колонка. Рамка + небольшой radius теперь допустимы явно
   (это button/link, не content-card, поэтому corner-засечка из 4.4.3
   убрана — рамка+radius уже читаются как границы кнопки, дублировать
   декоративный приём не нужно). border-radius — var(--radius-md), тот же
   токен, что и у .btn/.form-row input, ничего нового не вводится. */
.contact-method {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.95rem 0.8rem;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  transition: border-color var(--dur-base) var(--ease-standard),
    background-color var(--dur-base) var(--ease-standard);
}

.contact-method:hover,
.contact-method:focus-visible {
  border-color: var(--border-gold);
  background: var(--bg-surface);
}

/* VISUAL CORRECTION 4.4.4: по прямому указанию — Telegram/WhatsApp/MAX
   теперь в оригинальных фирменных цветах (было: единый currentColor/
   grayscale в 4.4.2-4.4.3). Цвета Telegram/WhatsApp — те же официальные
   оттенки, что уже использовались в самой первой реализации этого блока
   (.messenger-link__icon--telegram/whatsapp, до VISUAL 4.2), просто
   перенесены сюда — не изобретены заново. MAX — тот же файл без фильтра. */
.contact-method__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
}

.contact-method__icon svg {
  width: 100%;
  height: 100%;
}

.contact-method__icon--phone svg,
.contact-method__icon--email svg {
  fill: var(--text-muted);
}

.contact-method__icon--telegram svg {
  fill: #26A5E4;
}

.contact-method__icon--whatsapp svg {
  fill: #25D366;
}

.contact-method__icon--max img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.contact-method__divider {
  flex-shrink: 0;
  width: 1px;
  align-self: stretch;
  background: var(--border-subtle);
}

.contact-method__text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  flex: 1;
}

.contact-method__index {
  font-family: var(--font-display);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1;
  color: var(--gold);
}

.contact-method__label {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.contact-method__arrow {
  flex-shrink: 0;
  margin-left: auto;
  padding-left: 0.4rem;
  font-family: var(--font-body);
  color: var(--gold);
  opacity: 0.7;
  transition: transform var(--dur-base) var(--ease-standard),
    opacity var(--dur-base) var(--ease-standard);
}

.contact-method:hover .contact-method__arrow,
.contact-method:focus-visible .contact-method__arrow {
  transform: translateX(3px);
  opacity: 1;
}

/* Честно неактивные способы связи (Телефон/Telegram/WhatsApp/MAX, пока
   соответствующие значения в site-config.js — null): приглушены и
   исключены из клика/hover — тот же паттерн, что и .btn[aria-disabled]
   на urgent-call.html. E-mail с реальным значением остаётся полноценно
   кликабельным и визуально отличается только состоянием, не размером. */
.contact-method[aria-disabled="true"] {
  opacity: 0.5;
  cursor: default;
  pointer-events: none;
}

@media (max-width: 900px) {
  .contact-methods__grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 600px) {
  .contact-methods__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* -- Карта: реальный embed Яндекс.Карт (Этап 9.1) внутри того же
   .map-frame, что раньше держал заглушку — сетка контактов не менялась.
   Виджет конструктора рендерит фиксированный <iframe width height>;
   ограничиваем его шириной колонки и включаем height:auto, чтобы
   пропорционально уменьшался на узких экранах без горизонтального
   overflow (тот же приём, что и для картинок max-width:100%). -- */
.map-frame {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  height: 100%;
}

/* VISUAL 4.2: небольшая uppercase-подпись над картой — тот же язык, что и
   .contact-list__label слева (тонкий gold-разделитель-приём #3, не новый),
   чтобы карта читалась частью той же композиции, а не отдельно вставленным
   iframe. Рамка — тот же --border-gold, что и у hero-оси, без border-radius
   (в системе крупные editorial-рамки всегда прямоугольные, см. doc-card). */
.map-frame__label {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.map-embed {
  overflow: hidden;
  border: 1px solid var(--border-gold);
}

.map-embed iframe {
  display: block;
  width: 100%;
  max-width: 580px;
  height: auto;
  aspect-ratio: 580 / 440;
  border: 0;
}

/* На узких экранах пропорция 580:440 даёт слишком низкую карту (~260px
   при ширине колонки ~350px) — виджет Яндекс.Карт сам отрисовывается под
   размер iframe (это не статичное изображение), поэтому здесь можно
   просто задать нормальную визуальную высоту без искажений. */
@media (max-width: 960px) {
  .map-embed iframe {
    aspect-ratio: auto;
    height: 380px;
  }
}

@media (max-width: 960px) {
  .contact-grid {
    grid-template-columns: 1fr;
    gap: var(--sp-7);
  }
}

/* -- Форма обращения -- */
/* CONTACTS 4.2.1 / VISUAL REFINEMENT 4.4.1: форма была визуально
   растянута — межстрочный ритм (gap между .form-row), внутренний padding
   полей и высота textarea уменьшены точечно. После повторного визуального
   аудита (не только DOM-assertions) значения уменьшены ещё раз — только
   числа ниже, селекторы/структура те же. */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  max-width: 42rem;
  margin-top: var(--sp-2);
}

.contact-form.is-urgent {
  padding: var(--sp-6);
  border: 1px solid var(--border-gold);
  background: linear-gradient(155deg, rgba(101, 15, 24, 0.06), transparent 60%);
}

.form-row {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

fieldset.form-row {
  border: 0;
  padding: 0;
  margin: 0;
}

.form-row > label,
.form-row > legend {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.required-mark {
  margin-left: 0.2em;
  color: var(--accent-deep);
}

/* VISUAL 4.2: underline-поля вместо закрашенной рамки-«коробки» — editorial
   form language по брифу (тонкая линия вместо heavy border+radius box).
   Видимый focus обеспечивается не только сменой цвета/толщины нижней линии,
   но и общим сайтовым :focus-visible { outline: 2px solid var(--focus-ring) }
   (см. начало файла) — он не переопределяется и продолжает работать здесь. */
.form-row input[type="text"],
.form-row input[type="tel"],
.form-row input[type="email"],
.form-row textarea {
  padding: 0.4rem 0.1rem;
  font: inherit;
  font-size: var(--fs-sm);
  color: var(--text-primary);
  background: transparent;
  border: none;
  border-bottom: 2px solid var(--border-subtle);
  border-radius: 0;
  transition: border-color var(--dur-base) var(--ease-standard);
}

.form-row input[type="text"]:focus-visible,
.form-row input[type="tel"]:focus-visible,
.form-row input[type="email"]:focus-visible,
.form-row textarea:focus-visible {
  border-bottom-color: var(--gold);
}

.form-row textarea {
  min-height: 5.25rem;
  resize: vertical;
}

.form-hint {
  font-size: var(--fs-2xs);
  font-weight: 500;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text-muted);
}

.radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-6);
  margin-top: var(--sp-1);
}

.radio-option {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: 500;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text-primary);
}

.radio-option input {
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--accent);
}

.radio-option__icon {
  width: 18px;
  height: 18px;
  object-fit: contain;
}

.urgent-hint {
  display: none;
  margin-top: var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--accent-deep);
}

.contact-form.is-urgent .urgent-hint {
  display: block;
}

.consent-row {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
}

.consent-row input {
  flex-shrink: 0;
  width: 1.1rem;
  height: 1.1rem;
  margin-top: 0.2rem;
  accent-color: var(--accent);
}

.consent-row label {
  font-size: var(--fs-xs);
  font-weight: 500;
  text-transform: none;
  letter-spacing: normal;
  line-height: var(--lh-normal);
  color: var(--text-muted);
}

.form-status {
  padding: var(--sp-4) var(--sp-5);
  font-size: var(--fs-sm);
  border: 1px dashed var(--border-gold);
  color: var(--text-muted);
}

.form-status[hidden] {
  display: none;
}

.form-status.is-error {
  border-style: solid;
  border-color: var(--accent);
  color: var(--accent-deep);
}

/* Honeypot-поле антиспама (Этап 8): скрыто визуально, из скринридеров и
   из порядка табуляции — реальные пользователи никогда его не видят. */
.form-honeypot {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* CONTACTS 4.2.1 / VISUAL REFINEMENT 4.4.1: .section--tight — общий класс
   (используется и на других страницах), поэтому не трогаем его напрямую.
   Сокращаем только смежные края #contact-form-section/#urgent-reminder —
   доведено с 0.39 до 0.26 после повторного визуального аудита (разрыв
   форма → "Нужен адвокат срочно?" всё ещё читался как чрезмерный), не
   трогая верхний отступ формы и нижний отступ urgent-блока перед footer. */
#contact-form-section {
  padding-bottom: calc(var(--section-pad-y) * 0.26);
}

#urgent-reminder {
  padding-top: calc(var(--section-pad-y) * 0.26);
}

/* -- Нужен адвокат срочно (внутри контактов) -- */
.urgent-note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-6);
  padding: var(--sp-7) var(--sp-8);
  border-left: 3px solid var(--accent);
  background: var(--bg-surface);
}

.urgent-note__text {
  max-width: 46rem;
}

.urgent-note h2 {
  margin-bottom: var(--sp-2);
}

@media (max-width: 720px) {
  .urgent-note {
    flex-direction: column;
    align-items: flex-start;
    padding: var(--sp-6);
  }
}

/* ==========================================================================
   11. Footer
   ========================================================================== */
/* VISUAL 2.6: до этого footer был единственным крупным блоком сайта без
   единого штриха фирменного языка — ни золотой линии, ни Fraunces,
   только Manrope и стандартная тёмная 4-колоночная раскладка. Тонкая
   верхняя линия (тот же градиент, что и .rule — не новый приём) и
   Fraunces у brand-подписи ниже (.footer__brand p) — минимальный, но
   ощутимый мостик к остальной странице, а не переработка компоновки. */
.site-footer {
  position: relative;
  background: var(--bg-inverse-graphite);
  color: var(--text-inverse-muted);
  padding-block: var(--sp-8) var(--sp-6);
}

.site-footer::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--border-gold), transparent 70%);
}

.footer__top {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--sp-7);
  padding-bottom: var(--sp-7);
  border-bottom: 1px solid var(--border-inverse);
}

.footer__brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
}

.footer__brand img {
  /* align-items:flex-start (above) stops the default flex "stretch" from
     forcing this image to the column's full width and squashing it flat */
  height: 56px;
  width: auto;
  max-width: 100%;
}

.footer__brand p {
  max-width: 32ch;
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--text-inverse);
}

/* VISUAL 2.7: тот же золотой штрих, что стоит перед каждым eyebrow по
   всему сайту (.eyebrow::before, 28×1px) — footer до этого был
   единственным крупным блоком, где Fraunces-подпись не была связана с
   этим сквозным приёмом (только верхняя line-rule + сам шрифт, Этап
   VISUAL 2.6). Ничего нового не изобретено — тот же токен, тот же
   размер, только --gold-light вместо --gold (тёмный фон footer). */
.footer__brand p::before {
  content: "";
  display: block;
  width: 28px;
  height: 1px;
  margin-bottom: var(--sp-3);
  background: var(--gold-light);
}

.footer__heading {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--gold-light);
  margin-bottom: var(--sp-4);
}

.footer__list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.footer__list a {
  font-size: var(--fs-sm);
  transition: color var(--dur-fast) var(--ease-standard);
}

.footer__list a:hover,
.footer__list a:focus-visible {
  color: var(--text-inverse);
}

.footer__contacts {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.footer__contact-link[aria-disabled="true"] {
  cursor: default;
  opacity: 0.55;
}

.footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding-top: var(--sp-6);
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wide);
}

.footer__legal {
  display: flex;
  gap: var(--sp-5);
}

@media (max-width: 860px) {
  .footer__top {
    grid-template-columns: 1fr 1fr;
  }

  .footer__bottom {
    flex-direction: column;
    align-items: flex-start;
  }
}

@media (max-width: 540px) {
  .footer__top {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   10.9 Publications page — hero note, category grid, empty state
   (VISUAL 3.0: renumbered from 10.8 — Contacts page above already used that
   number; this block sits after "11. Footer" in file order for historical/
   chronological reasons — not physically moved, see architecture note at
   top of file, to avoid any cascade-order risk from relocating ~900 lines)
   ========================================================================== */
/* VISUAL 3.6: hero каталога публикаций — тот же editorial-словарь, что и
   у hero каталога адвокатов (VISUAL 3.2): тонкая gold-ось слева от текста
   + приглушённый ghost-numeral справа. Скоуп строго по уникальному
   aria-labelledby секции (тот же приём, что уже использует editorial-
   reveal чуть выше) — .page-hero/.page-hero__intro переиспользуются
   другими страницами (urgent-call.html, advokaty.html, contacts.html,
   official-info.html), их трогать нельзя. */
section[aria-labelledby="publications-hero-heading"] .container {
  position: relative;
}

section[aria-labelledby="publications-hero-heading"] .page-hero__intro {
  padding-left: var(--sp-6);
  border-left: 2px solid var(--border-gold);
}

section[aria-labelledby="publications-hero-heading"] .page-hero__mark {
  position: absolute;
  right: 0;
  bottom: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(6rem, 3rem + 14vw, 12rem);
  line-height: 1;
  color: var(--c-burgundy);
  opacity: 0.05;
  pointer-events: none;
  user-select: none;
}

@media (max-width: 860px) {
  section[aria-labelledby="publications-hero-heading"] .page-hero__mark {
    display: none;
  }
}

/* VISUAL 3.6 fix: на 375/390px левый padding золотой оси (32px) уже
   достаточен, чтобы однословный H1 "Публикации" (в отличие от, например,
   "Адвокаты коллегии" на advokaty.html — там перенос идёт между словами)
   не помещался в одну строку и переносился по слогам ("Публика-ции").
   При 430px и шире слово уже помещается — порог 400px оставляет ось
   везде, где переноса не возникает, и убирает её только там, где он
   реально возникал. */
@media (max-width: 400px) {
  section[aria-labelledby="publications-hero-heading"] .page-hero__intro {
    padding-left: 0;
    border-left: 0;
  }
}

/* VISUAL REFINEMENT 4.4: без hyphens:auto "Публикации" перестаёт
   помещаться в свою строку только на самых узких экранах (~360px и уже) —
   небольшая точечная поправка размера именно здесь. */
@media (max-width: 370px) {
  section[aria-labelledby="publications-hero-heading"] h1 {
    font-size: clamp(2.6rem, 2.2rem + 2vw, 3.2rem);
  }
}

.publications-hero__note {
  margin-top: var(--sp-5);
  max-width: 52ch;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  font-style: italic;
}

/* -- Category grid: editorial "buttons" with typographic cover placeholders --
   Каждая карточка — полноценная ссылка (см. §11 Accessibility плана
   PUBLICATIONS 1.0): номер, cover-заглушка, название, описание, стрелка.
   Cover пока без реальных фото — крупная полупрозрачная цифра поверх
   тонированного градиента и золотых уголков (тот же приём, что и
   .advokat-photo-frame), чтобы позже заменить на реальное editorial-фото
   простой заменой .category-card__cover-inner на <img>, без переверстки. */
.category-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-7) var(--sp-6);
  margin-top: var(--sp-2);
}

@media (max-width: 1024px) {
  .category-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 640px) {
  .category-grid {
    grid-template-columns: 1fr;
  }
}

.category-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  color: var(--text-primary);
}

.category-card__cover {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--border-subtle);
}

.category-card__cover-inner {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  padding: var(--sp-5);
  background: linear-gradient(155deg, var(--tint-gold-soft), var(--tint-ink-soft));
  transition: transform var(--dur-slow) var(--ease-standard);
}

.category-card__cover::before,
.category-card__cover::after {
  content: "";
  position: absolute;
  z-index: 1;
  width: 22px;
  height: 22px;
  border: 1px solid var(--border-gold);
  pointer-events: none;
}

.category-card__cover::before {
  top: var(--sp-3);
  left: var(--sp-3);
  border-width: 1px 0 0 1px;
}

.category-card__cover::after {
  bottom: var(--sp-3);
  right: var(--sp-3);
  border-width: 0 1px 1px 0;
}

.category-card__cover-index {
  font-family: var(--font-display);
  font-size: clamp(3rem, 2.4rem + 3vw, 4.5rem);
  line-height: 1;
  font-weight: 600;
  color: var(--c-burgundy);
  opacity: 0.16;
}

/* VISUAL 3.6: категории переиспользуют ту же editorial-cover систему
   вариантов, что и .publication-card__cover (PUBLICATIONS 3.3) — тот же
   data-category, уже существующий в разметке .category-card с самого
   Этапа 1.0. Раньше "разнообразие" обложек категорий держалось на
   бессмысленной nth-child-ротации угла градиента; теперь вариант несёт
   реальный смысл и совпадает с обложками публикаций этой же категории —
   единая система "категория → публикация", не вторая параллельная.
   В отличие от .publication-card__cover (там data-category — на самом
   cover, добавлено в PUBLICATIONS 3.3), здесь атрибут — на родительском
   .category-card (задан ещё на Этапе 1.0), поэтому селектор идёт через
   родителя, а не через :is() на самом .category-card__cover. */
.category-card:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
) .category-card__cover {
  border-color: transparent;
}

.category-card:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
) .category-card__cover-inner {
  background: var(--c-burgundy);
}

.category-card:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
) .category-card__cover-index {
  color: var(--c-warm-white);
  opacity: 0.18;
}

.category-card:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
) .category-card__cover::before,
.category-card:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
) .category-card__cover::after {
  border-color: var(--gold-light);
}

/* Вариант 2 — ivory (дефолт, Гражданское/Семейное право) — без
   переопределений, базовые стили выше уже дают этот вид. */

/* VISUAL REFINEMENT 4.4: тот же consolidation, что и у
   .publication-card__cover выше (см. комментарий там) — "категория →
   обложка публикации" остаётся единой системой, поэтому объединение
   вариантов сделано одинаково в обоих компонентах. */
.category-card:is(
  [data-category="nasledstvo-i-nedvizhimost"],
  [data-category="sudebnaya-praktika"],
  [data-category="trudovoe-pravo"],
  [data-category="bankrotstvo-i-arbitrazh"]
) .category-card__cover {
  border-color: var(--border-gold);
}

.category-card:is(
  [data-category="nasledstvo-i-nedvizhimost"],
  [data-category="sudebnaya-praktika"],
  [data-category="trudovoe-pravo"],
  [data-category="bankrotstvo-i-arbitrazh"]
) .category-card__cover-index {
  opacity: 0.2;
}

.category-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  border-top: 1px solid var(--border-subtle);
  padding-top: var(--sp-4);
  position: relative;
}

.category-card__body::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 0;
  height: 1px;
  background: var(--accent);
  transition: width var(--dur-base) var(--ease-standard);
}

.category-card__number {
  font-family: var(--font-display);
  font-size: var(--fs-xs);
  color: var(--gold);
}

.category-card__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  transition: color var(--dur-base) var(--ease-standard);
}

/* VISUAL 3.6, п.5: количество материалов — вторичная строка под
   названием, не конкурирует по весу с title (не UI-badge, а тихая
   editorial-подпись). Заполняется в publications.js из VISIBLE_DATA. */
.category-card__count {
  font-size: var(--fs-2xs);
  letter-spacing: var(--ls-wide);
  color: var(--text-muted);
}

.category-card__desc {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.category-card__arrow {
  position: absolute;
  right: 0;
  top: var(--sp-2);
  font-size: var(--fs-md);
  color: var(--text-muted);
  transition: transform var(--dur-base) var(--ease-standard),
    color var(--dur-base) var(--ease-standard);
}

.category-card:hover .category-card__cover-inner,
.category-card:focus-visible .category-card__cover-inner {
  transform: scale(1.045);
}

.category-card:hover .category-card__body::before,
.category-card:focus-visible .category-card__body::before {
  width: 100%;
}

.category-card:hover .category-card__title,
.category-card:focus-visible .category-card__title {
  color: var(--accent-deep);
}

.category-card:hover .category-card__arrow,
.category-card:focus-visible .category-card__arrow {
  transform: translateX(5px);
  color: var(--accent);
}

/* Активная категория (PUBLICATIONS 1.2, filter state) — золотая рамка
   вокруг cover + постоянно видимая golden-линия, вместо hover-only
   поведения выше. transition через --motion-nav (ENGINE 1.1): это смена
   состояния UI-контрола, а не hover-микровзаимодействие и не reveal.
   VISUAL 3.6, п.7: active обозначен НЕ только цветом — рамка cover
   становится вдвое толще (1px → 2px), появляется постоянная
   gold-линия под названием и текстовый маркер "Показано" — три
   независимых от цвета признака одновременно. */
.category-card.is-active .category-card__cover {
  border-width: 2px;
  border-color: var(--gold);
  transition: border-color var(--motion-nav), border-width var(--motion-nav);
}

.category-card.is-active .category-card__body::before {
  width: 100%;
  height: 2px;
}

.category-card.is-active .category-card__title {
  color: var(--accent-deep);
}

.category-card.is-active .category-card__number::after {
  content: " · показано";
  font-family: var(--font-body);
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--text-muted);
}

/* -- Publication grid + toolbar (поиск/сортировка) + карточка публикации --
   VISUAL 3.6, п.8: toolbar переведён с "dashboard"-стиля (полнобордюрные
   input/select, скруглённые углы) на editorial-грамотику остального
   сайта — underline-поля вместо boксов, тонкая нижняя линия секции вместо
   рамки, поиск крупнее и на --font-display (заметнее), сортировка —
   мельче и явно вторична. Функциональность (см. publications.js) не
   тронута — только визуальный слой. */
.publication-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: var(--sp-6) var(--sp-8);
  margin-top: var(--sp-6);
  padding-bottom: var(--sp-5);
  border-bottom: 1px solid var(--border-subtle);
}

.publication-toolbar__field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.publication-toolbar__field label {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.publication-toolbar__field input[type="search"],
.publication-toolbar__field select {
  padding: 0.75rem 0;
  font: inherit;
  color: var(--text-primary);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--border-subtle);
  border-radius: 0;
  transition: border-color var(--motion-nav);
}

.publication-toolbar__field input[type="search"] {
  min-width: 22rem;
  font-family: var(--font-display);
  font-size: var(--fs-md);
}

.publication-toolbar__field select {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.publication-toolbar__field input[type="search"]:hover,
.publication-toolbar__field select:hover {
  border-color: var(--border-gold);
}

.publication-toolbar__field input[type="search"]:focus-visible,
.publication-toolbar__field select:focus-visible {
  border-color: var(--gold);
}

@media (max-width: 640px) {
  .publication-toolbar {
    gap: var(--sp-5);
  }

  .publication-toolbar__field input[type="search"] {
    min-width: 0;
    width: 100%;
  }

  .publication-toolbar__field select {
    width: 100%;
  }
}

.publication-toolbar__status {
  margin-top: var(--sp-4);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.publication-toolbar__clear {
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: 700;
  text-decoration: underline;
  color: var(--accent-deep);
}

.publication-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: var(--sp-7) var(--sp-6);
  margin-top: var(--sp-6);
  /* VISUAL 3.3: номер на обложке — позиция карточки в ТЕКУЩЕМ отрисованном
     списке (после поиска/фильтра/сортировки), не постоянный ID публикации.
     counter-increment живёт на .publication-card ниже. */
  counter-reset: pub-index;
}

.publication-empty-state {
  grid-column: 1 / -1;
  padding: var(--sp-8) var(--sp-7);
  border: 1px dashed var(--border-subtle);
  text-align: center;
}

.publication-empty-state p {
  margin: 0 auto;
  max-width: 46ch;
  font-size: var(--fs-md);
  color: var(--text-muted);
}

/* Карточка публикации: тот же визуальный грамматический приём, что и
   .advokat-card/.doc-card/.category-card (cover + hover-scale, gold-line,
   arrow nudge) — сознательно не изобретается новый язык. Hover/focus —
   через --motion-hover (ENGINE 1.1): это micro-interaction, а не смена
   состояния UI и не reveal. */
.publication-card__link {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  color: var(--text-primary);
}

/* -- VISUAL 3.3: editorial-cover система --------------------------------
   Обложка строится целиком из уже существующих данных (category), без
   новых изображений: верх — категория (текст, из уже вычисленного в JS
   categoryTitle), центр/фон — крупный приглушённый номер публикации в
   ТЕКУЩЕМ списке (CSS counter — см. .publication-grid/.publication-card
   выше, JS не пересчитывает), низ — тонкая gold rule + маленький
   редакционный маркер "ЗП". Цветовой режим (одна из 3-4 заранее заданных
   вариаций) выбирается атрибутом data-category, который уже был
   добавлен в разметку renderCard() (publications.js) — сам JS-pipeline
   (поиск/фильтр/сортировка/routing) не тронут. */
.publication-card__cover {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--border-subtle);
  counter-increment: pub-index;
}

.publication-card__cover-inner {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: var(--sp-5);
  background: linear-gradient(155deg, var(--tint-gold-soft), var(--tint-ink-soft));
  transition: transform var(--motion-hover);
}

.publication-card__cover-category {
  max-width: 16ch;
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--gold-text);
}

.publication-card__cover-number {
  align-self: flex-end;
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1;
  font-size: clamp(3rem, 2.2rem + 4vw, 4.75rem);
  color: var(--c-burgundy);
  opacity: 0.14;
  transition: transform var(--motion-hover);
}

.publication-card__cover-number::before {
  content: counter(pub-index, decimal-leading-zero);
}

/* Низ обложки: тонкая gold rule + маленький редакционный маркер —
   независимые от .cover-inner слои (не масштабируются вместе с
   hover-zoom фона, остаются на месте как "печать издания"). */
.publication-card__cover::before,
.publication-card__cover::after {
  position: absolute;
  z-index: 1;
  pointer-events: none;
}

.publication-card__cover::before {
  content: "ЗП";
  right: var(--sp-5);
  bottom: calc(var(--sp-4) + 10px);
  font-family: var(--font-display);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--ls-wide);
  color: var(--gold-text);
  opacity: 0.85;
}

.publication-card__cover::after {
  content: "";
  left: var(--sp-5);
  right: var(--sp-5);
  bottom: var(--sp-4);
  height: 1px;
  background: var(--gold);
  opacity: 0.55;
}

/* Вариант 1 — burgundy field: категории с наибольшим "весом" (уголовные/
   административные дела). Тёмное поле — самый контрастный из режимов. */
.publication-card__cover:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
) {
  border-color: transparent;
}

.publication-card__cover:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
) .publication-card__cover-inner {
  background: var(--c-burgundy);
}

.publication-card__cover:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
) .publication-card__cover-category {
  color: var(--gold-light);
}

.publication-card__cover:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
) .publication-card__cover-number {
  color: var(--c-warm-white);
  opacity: 0.16;
}

.publication-card__cover:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
)::before {
  color: var(--gold-light);
  opacity: 0.9;
}

.publication-card__cover:is(
  [data-category="ugolovnoe-pravo"],
  [data-category="administrativnoe-pravo"]
)::after {
  background: var(--gold-light);
  opacity: 0.7;
}

/* Вариант 2 — ivory / light editorial (дефолт, без переопределений):
   Гражданское право, Семейное право — базовые стили выше уже дают этот
   вид, отдельный селектор не нужен. */

/* VISUAL REFINEMENT 4.4: прежние "Вариант 3" (плотная 2px бордовая рамка)
   и "Вариант 4" (диагональный line-pattern фон) объединены в один
   restrained вариант — по брифу весь grid должен читаться единой серией
   (единая рамка/типографика/нумерация/gold rule/маркер «ЗП», разница
   между категориями — вторичная), а 4 визуально разных режима на 8
   категорий уже воспринимались как "разные дизайн-системы", особенно
   из-за рамки другой толщины. Теперь: та же ширина рамки (1px), что и у
   дефолтного варианта выше — отличие только в цвете рамки (gold, не
   нейтральный serый) и цвете подписи категории; наследственные/судебные
   и трудовые/банкротные категории вместе используют этот один вариант
   (бриф явно разрешает нескольким категориям делить один variant). */
.publication-card__cover:is(
  [data-category="nasledstvo-i-nedvizhimost"],
  [data-category="sudebnaya-praktika"],
  [data-category="trudovoe-pravo"],
  [data-category="bankrotstvo-i-arbitrazh"]
) {
  border-color: var(--border-gold);
}

.publication-card__cover:is(
  [data-category="nasledstvo-i-nedvizhimost"],
  [data-category="sudebnaya-praktika"],
  [data-category="trudovoe-pravo"],
  [data-category="bankrotstvo-i-arbitrazh"]
) .publication-card__cover-category {
  color: var(--accent-deep);
}

.publication-card__cover:is(
  [data-category="nasledstvo-i-nedvizhimost"],
  [data-category="sudebnaya-praktika"],
  [data-category="trudovoe-pravo"],
  [data-category="bankrotstvo-i-arbitrazh"]
) .publication-card__cover-number {
  opacity: 0.2;
}

/* Обратная совместимость: publication.js рендерит "похожие публикации"
   на странице статьи через ту же .publication-card разметку, но более
   старым, независимым renderRelatedCard() — там нет data-category и нет
   .cover-category/.cover-number, только исходная .cover-index (этот файл
   на этом этапе намеренно не трогается, п.18 задания). .cover-inner
   выше стал flex-column/space-between (был flex-row/flex-end) — без этого
   правила одинокий .cover-index "убегал" бы в левый верхний угол вместо
   исходного нижнего правого. margin-top:auto + align-self:flex-end
   возвращают его на место. Editorial-вариации (data-category) там не
   работают — деградация до дефолтного ivory-варианта, не поломка. */
.publication-card__cover-index {
  margin-top: auto;
  align-self: flex-end;
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.9rem + 1.8vw, 3rem);
  line-height: 1;
  font-weight: 600;
  color: var(--c-burgundy);
  opacity: 0.16;
}

.publication-card__badge {
  position: absolute;
  top: var(--sp-3);
  right: var(--sp-3);
  z-index: 1;
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--gold);
  background: var(--bg-page);
  border: 1px solid var(--border-gold);
  padding: 0.2rem 0.6rem;
}

.publication-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  border-top: 1px solid var(--border-subtle);
  padding-top: var(--sp-4);
  position: relative;
}

.publication-card__body::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 0;
  height: 1px;
  background: var(--accent);
  transition: width var(--motion-hover);
}

.publication-card__category {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--gold);
}

.publication-card__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: var(--lh-snug);
  transition: color var(--motion-hover);
}

.publication-card__excerpt {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.publication-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  font-size: var(--fs-2xs);
  color: var(--text-muted);
}

.publication-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

.publication-card__tags li {
  font-size: var(--fs-2xs);
  color: var(--text-muted);
  border: 1px solid var(--border-subtle);
  padding: 0.15rem 0.55rem;
}

.publication-card__arrow {
  align-self: flex-start;
  font-size: var(--fs-md);
  color: var(--text-muted);
  transition: transform var(--motion-hover), color var(--motion-hover);
}

.publication-card__link:hover .publication-card__cover-inner,
.publication-card__link:focus-visible .publication-card__cover-inner {
  transform: scale(1.04);
}

/* Interaction depth обложки (п.12 задания): номер слегка сдвигается,
   низовая gold rule чуть удлиняется — оба независимы от zoom фона выше
   (не вложены в .cover-inner), никакого вращения/glow/бесконечной
   анимации. */
.publication-card__cover::after {
  transition: transform var(--motion-hover);
  transform-origin: left;
}

.publication-card__link:hover .publication-card__cover-number,
.publication-card__link:focus-visible .publication-card__cover-number {
  transform: translate(-3px, -3px);
}

.publication-card__link:hover .publication-card__cover::after,
.publication-card__link:focus-visible .publication-card__cover::after {
  transform: scaleX(1.05);
}

.publication-card__link:hover .publication-card__body::before,
.publication-card__link:focus-visible .publication-card__body::before {
  width: 100%;
}

.publication-card__link:hover .publication-card__title,
.publication-card__link:focus-visible .publication-card__title {
  color: var(--accent-deep);
}

.publication-card__link:hover .publication-card__arrow,
.publication-card__link:focus-visible .publication-card__arrow {
  transform: translateX(5px);
  color: var(--accent);
}

/* --------------------------------------------------------------------------
   PUBLICATIONS 1.4.2 — Article page (publication.html)
   Все правила ниже namespaced под .publication-page / .publication-detail /
   .publication-breadcrumb / .publication-sources / .publication-related-*,
   чтобы не задеть остальные страницы. Переиспользует существующие токены,
   .publication-card__* (карточки «Читайте также») и .publication-grid —
   новый визуальный язык не изобретается. Брейкпоинты — те же max-width,
   что уже используются в файле (960/720/640/560).
   -------------------------------------------------------------------------- */
.publication-page__inner {
  max-width: 47rem;
  margin-inline: auto;
}

/* -- Breadcrumb -- */
.publication-breadcrumb {
  margin-bottom: var(--sp-6);
}

.publication-breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.publication-breadcrumb li {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.publication-breadcrumb li:not(:last-child)::after {
  content: "→";
  color: var(--border-gold);
}

.publication-breadcrumb a {
  color: var(--text-muted);
  transition: color var(--motion-hover);
}

.publication-breadcrumb a:hover,
.publication-breadcrumb a:focus-visible {
  color: var(--accent-deep);
}

.publication-breadcrumb [aria-current="page"] {
  color: var(--text-primary);
  font-weight: 600;
}

@media (max-width: 640px) {
  .publication-breadcrumb [aria-current="page"] {
    display: inline-block;
    max-width: 55vw;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
  }
}

/* -- Article header -- */
.publication-detail__category {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  /* PUBLICATIONS 1.4.6: --gold-text (не --gold) — текст eyebrow должен
     проходить WCAG AA 4.5:1 на --bg-page, декоративный --gold этого не
     даёт (~2.5:1). Разделительная линия ниже остаётся на --gold —
     некстовый декоративный элемент, не подпадает под тот же критерий. */
  color: var(--gold-text);
}

.publication-detail__category::before {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--gold);
}

/* VISUAL 3.4: чуть уже, чем вся читательская колонка (47rem) — заметно
   более "designed" editorial-мера для заголовка, отдельная от меры
   основного текста (общепринятый приём: крупный заголовок держат уже,
   чем body). Глобальный h1 (font-family/hyphens/etc.) не тронут —
   только локальный max-width/margin поверх него. */
.publication-detail__title {
  margin-top: var(--sp-4);
  max-width: 34ch;
  font-size: var(--fs-2xl);
}

.publication-detail__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-5);
  margin-top: var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.publication-detail__status-badge {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--gold);
  border: 1px solid var(--border-gold);
  padding: 0.2rem 0.6rem;
}

/* VISUAL 3.4: lead — раньше это была bordered-карточка с фоном и
   decorative corners (тот же приём, что .advokat-photo-frame). Задание
   прямо запрещает "превращать lead в карточку"/"большой background box" —
   заменено на редакционный приём "короткая gold rule + просторный
   типографический абзац", без рамки/подложки/уголков. */
.publication-detail__lead {
  margin-top: var(--sp-7);
  padding-top: var(--sp-6);
  max-width: 42rem;
}

.publication-detail__lead::before {
  content: "";
  display: block;
  width: 40px;
  height: 1px;
  margin-bottom: var(--sp-5);
  background: var(--gold);
}

.publication-detail__lead p {
  margin: 0;
  max-width: none;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-style: italic;
  color: var(--text-primary);
  line-height: var(--lh-relaxed);
}

/* -- Article body typography (контент из pub.content) -- */
/* VISUAL FIX 5.0.2: .publication-page__inner (родитель) — 47rem (752px),
   без собственного max-width у __body строка достигала ~85 символов —
   слишком широко для юридического editorial-текста. max-width:70ch — та
   же техника, что уже применена у .publication-detail__lead (42rem) и
   .publication-detail__title (34ch), просто ещё один локальный override
   поверх родителя, не новый приём. ch считается от текущего font-size
   этого блока (--fs-md), поэтому единица переживёт любые будущие правки
   размера шрифта без ручного пересчёта в rem/px. Margin-inline не
   добавлялся намеренно: header/lead/category уже выровнены по левому
   краю .publication-page__inner (не центрированы), и body должен
   продолжать тот же левый "gutter", а не создавать смещение по центру. */
.publication-detail__body {
  max-width: 44rem;
  margin-top: var(--sp-8);
  font-size: var(--fs-md);
  line-height: var(--lh-relaxed);
}

.publication-detail__body > *:first-child {
  margin-top: 0;
}

.publication-detail__body p {
  margin: 0 0 var(--sp-5);
  color: var(--text-primary);
}

.publication-detail__body h2 {
  margin-top: var(--sp-8);
  margin-bottom: var(--sp-4);
  padding-top: var(--sp-6);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--fs-xl);
}

.publication-detail__body h3 {
  margin-top: var(--sp-6);
  margin-bottom: var(--sp-3);
  font-size: var(--fs-md);
}

.publication-detail__body ul,
.publication-detail__body ol {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-5);
  padding-left: 1.35em;
  color: var(--text-primary);
}

.publication-detail__body ul {
  list-style: disc;
}

.publication-detail__body ol {
  list-style: decimal;
}

.publication-detail__body li {
  line-height: var(--lh-relaxed);
}

.publication-detail__body li > ul,
.publication-detail__body li > ol {
  margin-top: var(--sp-2);
}

.publication-detail__body strong {
  color: var(--text-primary);
  font-weight: 700;
}

.publication-detail__body em {
  font-style: italic;
}

.publication-detail__body a {
  color: var(--accent-deep);
  text-decoration: underline;
  text-underline-offset: 0.15em;
  transition: color var(--motion-hover);
}

.publication-detail__body a:hover,
.publication-detail__body a:focus-visible {
  color: var(--accent);
}

.publication-detail__body blockquote {
  margin: var(--sp-6) 0;
  padding: var(--sp-5) var(--sp-6);
  border-left: 2px solid var(--gold);
  background: var(--bg-surface);
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-style: italic;
  color: var(--text-primary);
}

.publication-detail__body blockquote p:last-child {
  margin-bottom: 0;
}

.publication-detail__body hr {
  border: 0;
  height: 1px;
  background: var(--border-subtle);
  margin: var(--sp-7) 0;
}

/* Таблицы: обёрнуты в .table-scroll скриптом (структурная обёртка,
   текст не изменяется) — безопасный горизонтальный скролл на mobile
   вместо горизонтального overflow всей страницы. */
.publication-detail__body .table-scroll {
  position: relative;
  overflow-x: auto;
  margin: var(--sp-6) 0;
  border: 1px solid var(--border-subtle);
  -webkit-overflow-scrolling: touch;
}

/* PUBLICATIONS 1.4.6: лёгкая тень у правого края — единственный visual
   affordance того, что таблица шире контейнера и прокручивается
   горизонтально (актуально на mobile, где ячейки не переносятся).
   Класс .table-scroll--scrollable добавляется из publication.js только
   когда scrollWidth реально больше clientWidth (то есть никогда на
   desktop/tablet, где таблица помещается целиком) и убирается через
   .table-scroll--at-end, когда пользователь докрутил до конца — так
   индикатор не остаётся постоянным тяжёлым элементом. Ширина и
   непрозрачность подобраны так, чтобы не перекрывать текст — это лишь
   тонкая подсказка у самого края, а не сплошная плашка. */
.publication-detail__body .table-scroll::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 22px;
  background: linear-gradient(to right, transparent, rgba(23, 19, 19, 0.16));
  opacity: 0;
  transition: opacity var(--motion-hover);
  pointer-events: none;
}

.publication-detail__body .table-scroll--scrollable::after {
  opacity: 1;
}

.publication-detail__body .table-scroll--scrollable.table-scroll--at-end::after {
  opacity: 0;
}

.publication-detail__body table {
  width: 100%;
  min-width: 480px;
  border-collapse: collapse;
  font-size: var(--fs-sm);
}

.publication-detail__body th,
.publication-detail__body td {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--border-subtle);
  text-align: left;
  vertical-align: top;
  color: var(--text-primary);
}

.publication-detail__body th {
  font-family: var(--font-display);
  font-weight: 600;
  background: var(--bg-surface);
  white-space: nowrap;
}

/* -- Sources -- */
.publication-detail__sources {
  margin-top: var(--sp-9);
  padding-top: var(--sp-7);
  border-top: 1px solid var(--border-subtle);
}

/* PUBLICATIONS 1.4.6: «Официальные источники» / «Читайте также» — оба
   page-level H2 на publication.html — наследовали общий h2 (--fs-3xl,
   до 60px), из-за чего визуально перевешивали H1 статьи (--fs-2xl, до
   44px). Точечный override только по этим двум id (#sources-title,
   #related-heading существуют только на publication.html) — заметно,
   но однозначно вторично по отношению к H1, глобальный h2 не тронут. */
#sources-title,
#related-heading {
  font-size: clamp(1.75rem, 1.3rem + 1.6vw, 2.5rem);
}

/* VISUAL 3.4: короткая gold rule под заголовком "Официальные источники" —
   тот же editorial-маркер, что и .publication-detail__category::before,
   явно отделяет блок источников от остального текста статьи. */
#sources-title {
  padding-bottom: var(--sp-4);
  border-bottom: 2px solid var(--gold);
  display: inline-block;
}

@media (max-width: 640px) {
  #sources-title,
  #related-heading {
    font-size: clamp(1.375rem, 1.1rem + 0.8vw, 1.75rem);
  }
}

.publication-sources {
  margin-top: var(--sp-5);
  display: flex;
  flex-direction: column;
}

.publication-sources__item {
  padding: var(--sp-4) 0;
  border-top: 1px solid var(--border-subtle);
}

.publication-sources__item:first-child {
  border-top: 0;
  padding-top: 0;
}

.publication-sources__name {
  display: block;
  font-weight: 600;
  color: var(--text-primary);
  margin-bottom: var(--sp-1);
}

.publication-sources__detail {
  display: block;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  margin-bottom: var(--sp-2);
}

.publication-sources__link {
  display: inline-block;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--accent-deep);
}

.publication-sources__link:hover,
.publication-sources__link:focus-visible {
  color: var(--accent);
}

.publication-sources__no-link {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  font-style: italic;
}

.publication-sources__empty {
  margin-top: var(--sp-4);
  color: var(--text-muted);
}

/* -- Actuality -- */
.publication-actuality {
  margin-top: var(--sp-6);
  padding: var(--sp-4) var(--sp-5);
  border-left: 2px solid var(--gold);
  background: var(--bg-surface);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

/* -- Related publications: полноширинная секция, переиспользует
   .publication-grid / .publication-card__* без новых правил. -- */
.publication-related-section {
  border-top: 1px solid var(--border-subtle);
}

/* -- Disclaimer -- */
.publication-detail__disclaimer {
  margin-top: var(--sp-7);
  padding-top: var(--sp-5);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

/* -- Empty / error states (slug отсутствует или не найден) -- */
.publication-page__empty {
  padding: var(--sp-9) var(--sp-6);
  border: 1px dashed var(--border-subtle);
  text-align: center;
}

.publication-page__empty h1 {
  font-size: var(--fs-xl);
  margin-bottom: var(--sp-4);
}

.publication-page__empty p {
  max-width: 46ch;
  margin: 0 auto var(--sp-6);
  color: var(--text-muted);
  font-size: var(--fs-md);
}

@media (max-width: 640px) {
  .publication-detail__title {
    font-size: var(--fs-xl);
  }

  .publication-detail__lead {
    padding: var(--sp-5);
  }

  .publication-detail__body h2 {
    font-size: var(--fs-lg);
  }
}

/* ==========================================================================
   12. Legal Help page — VISUAL 4.0 (editorial accordion redesign)
   ========================================================================== */
/* Hero: тот же editorial-словарь, что и у hero advokaty.html («05») и
   publications.html («08») — вертикальная gold-ось слева от текста +
   приглушённый ghost-numeral справа, здесь «09» (число направлений ниже
   на этой же странице). Скоуп строго по уникальному aria-labelledby
   секции — .page-hero/.page-hero__intro переиспользуются другими
   страницами (urgent-call.html, advokaty.html, contacts.html,
   official-info.html), их трогать нельзя. */
section[aria-labelledby="legal-help-hero-heading"] .container {
  position: relative;
}

section[aria-labelledby="legal-help-hero-heading"] .page-hero__intro {
  padding-left: var(--sp-6);
  border-left: 2px solid var(--border-gold);
}

section[aria-labelledby="legal-help-hero-heading"] .page-hero__mark {
  position: absolute;
  right: 0;
  bottom: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(6rem, 3rem + 14vw, 12rem);
  line-height: 1;
  color: var(--c-burgundy);
  opacity: 0.05;
  pointer-events: none;
  user-select: none;
}

@media (max-width: 860px) {
  section[aria-labelledby="legal-help-hero-heading"] .page-hero__mark {
    display: none;
  }
}

/* VISUAL 4.0 fix: у "Юридическая помощь" первое слово длиннее, чем
   "Публикации" (у publications.html тот же фикс срабатывал только до
   400px) — тот же левый padding золотой оси уже на 430px даёт перенос по
   слогам ("Юридиче-ская"), не только на 375/390. Порог здесь шире по
   той же причине и тем же принципом: убираем ось только там, где перенос
   реально возникал (проверено вплоть до 480px), оставляем везде, где
   слово помещается уже одним словом на строку. */
@media (max-width: 480px) {
  section[aria-labelledby="legal-help-hero-heading"] .page-hero__intro {
    padding-left: 0;
    border-left: 0;
  }
}

/* VISUAL REFINEMENT 4.4: с hyphens:none слово "Юридическая" (первое слово
   H1) при базовом --fs-4xl уже не помещается в свою строку на 400/390/375/
   360px (даже после снятия gold-axis padding выше) — раньше это "решалось"
   переносом по слогам, что теперь запрещено. Единственный оставшийся
   вариант — сузить именно этот H1 на этих ширинах (scoped, не глобальный
   --fs-4xl); перенос на 2 строки остаётся, само слово целиком помещается
   на своей строке при всех протестированных ширинах вплоть до 360px. */
@media (max-width: 480px) {
  section[aria-labelledby="legal-help-hero-heading"] h1 {
    font-size: clamp(2.5rem, 2.1rem + 2vw, 3.2rem);
  }
}

/* VISUAL 4.0: раньше все 9 направлений были одним всегда-развёрнутым
   grid-блоком (номер + заголовок + описание + 4 задачи + CTA, ~64px
   padding сверху/снизу на каждый — читалось как "9 карточек подряд").
   Теперь используется ТА ЖЕ accordion-механика, что уже работает на
   index.html (#legal-help, .legal-item__trigger + assets/js/modules/
   accordion-manager.js — JS не менялся, .direction-item__trigger несёт
   класс .legal-item__trigger вторым, чтобы существующий querySelectorAll
   подхватил кнопки на этой странице автоматически). Закрытая строка —
   только номер + название + стрелка; описание/задачи/CTA раскрываются по
   hover/focus (desktop) или клику/Enter/Space (в т.ч. mobile) —
   постоянное "закреплённое" состояние держит JS через aria-expanded,
   как и в оригинальном механизме. Цвета отличаются от index.html
   (там .section--dark, здесь светлая страница) — переиспользованы
   --gold/--gold-text/--accent/--accent-deep вместо --gold-light. */
.direction-list {
  margin-top: var(--sp-2);
  border-top: 1px solid var(--border-subtle);
}

.direction-item {
  border-bottom: 1px solid var(--border-subtle);
  transition: border-color var(--motion-nav);
}

.direction-item:hover,
.direction-item:focus-within,
.direction-item:has(.direction-item__trigger[aria-expanded="true"]) {
  border-bottom-color: var(--border-gold);
}

.direction-item__trigger {
  display: flex;
  align-items: baseline;
  width: 100%;
  gap: var(--sp-5);
  padding-block: var(--sp-5);
  text-align: left;
  color: var(--text-primary);
}

.direction-item__index {
  flex-shrink: 0;
  min-width: 2.75rem;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  color: var(--gold-text);
  transition: color var(--motion-nav), transform var(--motion-nav);
}

.direction-item__title {
  flex: 1;
  min-width: 0;
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: 500;
  line-height: var(--lh-snug);
  transition: color var(--motion-nav), letter-spacing var(--motion-nav);
}

/* Первое направление (01, уголовная защита) — едва заметно тяжелее
   остальных: оно первое в уже утверждённом порядке, не "специализация
   коллегии" и не отдельная hero-карточка (см. задание, п.9). */
.direction-item:first-child .direction-item__title {
  font-weight: 600;
}

.direction-item__arrow {
  flex-shrink: 0;
  font-size: var(--fs-lg);
  color: var(--text-muted);
  transition: transform var(--motion-nav), color var(--motion-nav);
}

.direction-item:hover .direction-item__index,
.direction-item:focus-within .direction-item__index,
.direction-item__trigger[aria-expanded="true"] .direction-item__index {
  color: var(--accent-deep);
  transform: translateX(3px);
}

.direction-item:hover .direction-item__title,
.direction-item:focus-within .direction-item__title,
.direction-item__trigger[aria-expanded="true"] .direction-item__title {
  color: var(--accent-deep);
  letter-spacing: 0.01em;
}

.direction-item:hover .direction-item__arrow,
.direction-item:focus-within .direction-item__arrow,
.direction-item__trigger[aria-expanded="true"] .direction-item__arrow {
  color: var(--accent);
  transform: translateX(5px);
}

/* Раскрытие через grid-template-rows: 0fr → 1fr — тот же приём, что и у
   .legal-item__panel (плавно, без расчёта пиксельной высоты текста,
   соседние пункты списка не дёргаются).
   VISUAL 4.0 fix: overflow:hidden на .panel-inner скрывает контент
   визуально, но ссылки внутри (.link-underline) сами по себе оставались
   в Tab-порядке даже в закрытом состоянии — клавиатурный фокус "исчезал"
   в невидимой области. visibility:hidden решает это (в отличие от
   overflow, реально убирает потомков из последовательности фокуса), с
   задержкой на закрытие, равной длительности схлопывания — чтобы контент
   не пропадал раньше, чем закончится анимация. */
.direction-item__panel {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows var(--motion-reveal), visibility 0s linear var(--dur-slow);
}

.direction-item__panel-inner {
  overflow: hidden;
}

.direction-item:hover .direction-item__panel,
.direction-item:focus-within .direction-item__panel,
.direction-item__trigger[aria-expanded="true"] + .direction-item__panel {
  grid-template-rows: 1fr;
  visibility: visible;
  transition: grid-template-rows var(--motion-reveal), visibility 0s linear 0s;
}

.direction-item__desc {
  max-width: 62ch;
  margin: 0 0 var(--sp-5);
  padding-top: var(--sp-1);
}

/* Список типовых задач — компактный square-marker приём (6px акцентный
   квадрат перед строкой) для списка внутри направления. */
.direction-item__tasks {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-6);
  padding: 0;
  list-style: none;
  max-width: 54ch;
}

.direction-item__tasks li {
  position: relative;
  padding-left: var(--sp-5);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  line-height: var(--lh-normal);
}

.direction-item__tasks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 6px;
  height: 6px;
  background: var(--accent);
}

.direction-item__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2) var(--sp-7);
  padding-bottom: var(--sp-6);
}

/* Единственное направление (01, уголовное) получает второй,
   визуально более "тревожный" контекстный переход на срочный выезд —
   остальные 8 направлений такой ссылки не имеют, чтобы CTA-иерархия
   не превращалась в 9 одинаковых кнопок. */
.direction-item__urgent {
  color: var(--accent-deep);
}

/* VISUAL 4.0, п.16: reduced-motion отключает саму анимацию раскрытия и
   hover-сдвиги, но НЕ меняет модель взаимодействия — контент остаётся
   accordion-панелью (открывается по клику/hover/focus), просто мгновенно,
   без transition. Ничего не прячется через opacity — это тот же
   grid-template-rows механизм, что и в обычном режиме. */
@media (prefers-reduced-motion: reduce) {
  .direction-item__panel,
  .direction-item__index,
  .direction-item__title,
  .direction-item__arrow,
  .direction-item {
    transition: none;
  }
}

@media (max-width: 480px) {
  .direction-item__trigger {
    gap: var(--sp-3);
    padding-block: var(--sp-4);
  }

  .direction-item__index {
    min-width: 2.25rem;
  }

  .direction-item__title {
    font-size: var(--fs-md);
  }
}
