/* ─── Collapse ────────────────────────────────────────────────────────────────
   Values: site/tokens.css (кегль лейбла и описания — --ds-type-body-1/2-*; вся шкала --ds-type- и
     --ds-fw- с 2026-09-17 объявлена там же, прежняя вторая таблица site/css/typography.css удалена
     2026-09-22; реестр TOKENS-DEFINED-OUTSIDE-TOKENS-CSS) — новых токенов нет; цвета совпали с кодом 4/4 по модам, КРОМЕ
   Fill/Neutral-Blue/Outline/High Contrast — расхождение в Light Invert и Dark записано ниже
   Primary consumers: site/preview/collapse.html + src/components/Collapse/Collapse.tsx
   Figma: Components isVYOT7tW0RTaIofg7FAqM, страница «↳ Collapse» 2528:16904, набор 2872:24008
   States: data-attributes only (data-state hover|pressed ставит React)

   Размеры — из коллекции «❖ Collapse» (моды MD / SM), снятой Plugin API 2026-09-15.
   Ось размера живёт в таблице переменных, а не вариантом на канве: на канве все
   мастера в MD — тот же случай, что у Stepper и Scrollbar.

   Цвета — привязки макета и их токены (сверка значений по 4 модам: tokens.figma-truth.json
   против tools/ds-token-resolver.mjs, 2026-09-15):
     Fill/Neutral-Blue/Ghost/Hover                       → --ds-nba-20 (тождество 4/4, см. tokens.css)
     Fill/Neutral-Blue/Ghost/Pressed                     → --ds-nba-ghost-pressed
     Fill/Neutral-Blue/Outline/High Contrast (Default)   → --ds-fill-neutral-outline-hc — 4/4 с 2026-09-21:
       L #ffffff · LI #131316 · D #020304 · DI #ffffff. До этой даты токен отставал от макета в
       Light Invert и Dark (#222629 и #1c2023); починено одной правкой в tokens.css для всех
       потребителей (строка FILL-NEUTRAL-OUTLINE-HC-DRIFT-INVERT-DARK). Ролевой токен, а не
       --ds-surface-nb-base с совпавшими числами: это другая переменная макета.
     Fill/Neutral-Blue/Outline/Hover · /Pressed          → --ds-nba-outline-hover · --ds-nba-outline-pressed
     Static/Surface/Neutral-Blue/0 - Base (и Neutral/0)  → --ds-surface-nb-base (обе переменные равны 4/4)
     Static/Border/Neutral-Blue/Low                      → --ds-stroke-low
     Static/Text/Neutral-Blue/Primary                    → --ds-text-primary
     Icon/Neutral-Blue/Ghost/Default                     → --ds-text-neutral-ghost
     Text/Disable/Neutral (Blue) · Icon/Disable/…        → --ds-disabled-text · --ds-disabled-icon
   Все эти токены сами переключаются по темам, включая инверт, поэтому тёмного
   переопределения здесь нет — тот же третий путь, что у badge.css.

   ВЛОЖЕННОСТЬ. Макет показывает группу Collapse внутри контента другого Collapse —
   секция 2943:7405 «Example — Inner_group_collapses»: Ghost в Ghost и Ghost в Outline.
   Поэтому каждое правило, которое красит или раздвигает ЧАСТЬ блока, дотягивается до неё
   дочерним комбинатором (корень > шапка / контент / разделитель), а не пробелом. С пробелом
   состояние родителя уходило во все вложенные блоки: раскрытый Outline давал шапкам детей
   свою контрастную заливку и боковые 16 их контенту, ховер и кольцо фокуса родителя
   ложились на шапки детей, фокус на ребёнке обводил родителя, выключенный родитель серил
   лейблы детей. Найдено 2026-09-15, когда владелец прислал этот пример.
   ─────────────────────────────────────────────────────────────────────────── */

/* ── Root ───────────────────────────────────────────────────────────────────── */
.ds-collapse {
  /* MD */
  --_h:            calc(var(--ds-comp-unit) * 14);   /* Height 56 */
  --_py:           calc(var(--ds-comp-unit) * 3);    /* Top-Bottom 12 */
  --_gap:          calc(var(--ds-comp-unit) * 5);    /* Gap 20 */
  --_px:           calc(var(--ds-comp-unit) * 4);    /* Left-Right 16 — боковой отступ Outline и вынос ховера Ghost */
  --_radius:       calc(var(--ds-comp-unit) * 4);    /* Radius 16 */
  --_icon:         calc(var(--ds-comp-unit) * 6);    /* Icon/Size 24 */
  --_icon-stroke:  var(--ds-icon-stroke-lg);         /* 24px → визуальные 2px, Icon/Stroke макета = 2 */
  --_label-fs:     var(--ds-l1-size);                /* ↔ Control/Label/L1 — 16 */
  --_label-lh:     var(--ds-l1-lh);                  /* 24 */
  --_label-gap:    calc(var(--ds-comp-unit) * 2);    /* 8 — ❖ Dropdown menus «Label/Gap» через вложенный .Parts / Label Item; в ❖ Collapse такой переменной нет (use_figma 2026-09-24) */
  --_content-gap:  calc(var(--ds-comp-unit) * 4);    /* Content/Gap 16 */
  --_content-pt:   calc(var(--ds-comp-unit) * 3);    /* Content/Top 12 */
  --_content-pb:   calc(var(--ds-comp-unit) * 6);    /* Content/Bottom 24 */
  --_body-fs:      var(--ds-type-body-1-size);       /* ✦ Typography/Body/Body 1 — 16 */
  --_body-lh:      var(--ds-type-body-1-lh);         /* 24 */

  position:        relative;
  display:         flex;
  flex-direction:  column;
  box-sizing:      border-box;
  width:           100%;
  min-width:       calc(var(--ds-comp-unit) * 85);   /* 340 — «Минимальная ширина 340 px», спека § Размеры */
  font-family:     var(--ds-font);
  color:           var(--ds-text-primary);
}

.ds-collapse[data-size='sm'] {
  --_h:            calc(var(--ds-comp-unit) * 12);   /* 48 */
  --_py:           calc(var(--ds-comp-unit) * 1.5);  /* 6 */
  --_gap:          calc(var(--ds-comp-unit) * 4);    /* 16 */
  --_px:           calc(var(--ds-comp-unit) * 3);    /* 12 */
  --_radius:       calc(var(--ds-comp-unit) * 3);    /* 12 */
  --_icon:         calc(var(--ds-comp-unit) * 5);    /* 20 */
  --_icon-stroke:  var(--ds-icon-stroke-md);         /* 20px → визуальные 2px */
  --_label-fs:     var(--ds-l2-size);                /* ↔ Control/Label/L2 — 14 */
  --_label-lh:     var(--ds-l2-lh);                  /* 20 */
  --_label-gap:    calc(var(--ds-comp-unit) * 1.5);  /* 6 */
  --_content-gap:  calc(var(--ds-comp-unit) * 3.5);  /* 14 */
  --_content-pt:   calc(var(--ds-comp-unit) * 2);    /* 8 */
  --_content-pb:   calc(var(--ds-comp-unit) * 5);    /* 20 */
  --_body-fs:      var(--ds-type-body-2-size);       /* Body 2 — 14 */
  --_body-lh:      var(--ds-type-body-2-lh);         /* 20 */
}

/* ── Header ─────────────────────────────────────────────────────────────────── */
/* min-height, а не height: спека разрешает лейбл в две строки (§ Названия), а высота
   в макете задана фиксированной — фиксированная обрезала бы вторую строку. */
.ds-collapse__header {
  position:        relative;
  display:         flex;
  align-items:     center;
  gap:             var(--_gap);
  box-sizing:      border-box;
  min-height:      var(--_h);
  padding-block:   var(--_py);
}

/* Слой ховера Ghost. В макете это абсолютный узел «Fill» шириной шапки плюс Left-Right
   с каждой стороны (x = −16, w + 32) и радиусом Radius; красится ТОЛЬКО шапка — у
   раскрытого варианта заливка лежит на вложенной шапке 56 px, а общий «Fill» пустой.
   Вынос сделан самой шапкой — отрицательный margin-inline и равный ему padding-inline
   держат содержимое на месте, — а не псевдоэлементом: заливка и кольцо фокуса обязаны
   быть стилем НАСТОЯЩЕГО элемента. До 2026-09-15 здесь стоял ::before, и CI-проверка
   audit-focus-coverage --explorer читала тумблер фокуса немым: измеритель снимает
   computed-стиль элементов превью, псевдоэлементы он не видит. */
.ds-collapse[data-variant='ghost'] > .ds-collapse__header {
  margin-inline:   calc(var(--_px) * -1);
  padding-inline:  var(--_px);
  border-radius:   var(--_radius);
  background:      transparent;
  transition:      background-color var(--ds-dur-1) var(--ds-ease);
}
.ds-collapse[data-variant='ghost'][data-state='hover'] > .ds-collapse__header {
  background:      var(--ds-nba-20);
}
.ds-collapse[data-variant='ghost'][data-state='pressed'] > .ds-collapse__header {
  background:      var(--ds-nba-ghost-pressed);
}

/* ── Heading (необязательная обёртка h2–h6) ───────────────────────────────────── */
.ds-collapse__heading {
  display:         flex;
  flex:            1 1 auto;
  min-width:       0;
  margin:          0;
  font:            inherit;
}

/* ── Trigger ────────────────────────────────────────────────────────────────── */
/* Кнопка — шеврон слева, лейбл и бейдж. ::after растянут на всю шапку: кликабельна
   вся шапка, кроме переключателя и кнопки действия (спека img/3), и без вложения
   интерактивных элементов в <button>. */
.ds-collapse__trigger {
  appearance:      none;
  display:         flex;
  flex:            1 1 auto;
  align-items:     center;
  gap:             var(--_gap);
  min-width:       0;
  margin:          0;
  padding:         0;
  border:          0;
  background:      none;
  font:            inherit;
  color:           inherit;
  text-align:      start;
  cursor:          pointer;
  outline:         none;
}
.ds-collapse__trigger::after {
  content:         '';
  position:        absolute;
  inset:           0;
}
.ds-collapse__trigger:disabled {
  cursor:          default;
}

.ds-collapse__label-group {
  display:         flex;
  align-items:     center;
  gap:             var(--_label-gap);
  min-width:       0;
}

.ds-collapse__label {
  min-width:       0;
  font-size:       var(--_label-fs);
  line-height:     var(--_label-lh);
  font-weight:     500;                              /* ✦ Typography/Label/Weight — Medium */
  color:           var(--ds-text-primary);
  overflow-wrap:   anywhere;                         /* не обрезать смысл — спека § «Не сокр...» */
}

/* ── Chevron ────────────────────────────────────────────────────────────────── */
.ds-collapse__chevron {
  display:         inline-flex;
  flex:            none;
  width:           var(--_icon);
  height:          var(--_icon);
  color:           var(--ds-text-neutral-ghost);
}
.ds-collapse__chevron svg {
  width:           100%;
  height:          100%;
  stroke-width:    var(--_icon-stroke);
}

/* ── Actions (переключатель, кнопка) ─────────────────────────────────────────── */
/* Над растянутым ::after триггера, иначе клик по ним раскрывал бы блок. */
.ds-collapse__actions {
  position:        relative;
  z-index:         1;
  display:         flex;
  flex:            none;
  align-items:     center;
  gap:             var(--_gap);
}

/* ── Content ────────────────────────────────────────────────────────────────── */
.ds-collapse__content {
  display:         flex;
  flex-direction:  column;
  gap:             var(--_content-gap);
  padding-top:     var(--_content-pt);
  padding-bottom:  var(--_content-pb);
  font-size:       var(--_body-fs);
  line-height:     var(--_body-lh);
  font-weight:     400;                              /* ✦ Typography/Body/Weight — Regular */
  color:           var(--ds-text-primary);
}
.ds-collapse__content[hidden] {
  display:         none;
}

/* ── Divider ────────────────────────────────────────────────────────────────── */
/* Ghost: в макете узел абсолютный и прижат к низу блока (y = h − 1), высоту не добавляет. */
.ds-collapse[data-variant='ghost'] > .ds-collapse__divider {
  position:        absolute;
  left:            0;
  right:           0;
  bottom:          0;
}

/* ── Outline ────────────────────────────────────────────────────────────────── */
.ds-collapse[data-variant='outline'] {
  border-radius:   var(--_radius);
  overflow:        hidden;                           /* clipsContent у раскрытого мастера */
  background:      var(--ds-fill-neutral-outline-hc);
}
/* Рамка — наложенным слоем, а не border: в макете обводка внутренняя и высоту не
   добавляет (закрытый блок ровно 56), а border дал бы 58. Слой лежит поверх заливки
   шапки, как внутренняя обводка Figma. */
.ds-collapse[data-variant='outline']::after {
  content:         '';
  position:        absolute;
  inset:           0;
  z-index:         2;
  border:          calc(var(--ds-comp-unit) * 0.25) solid var(--ds-stroke-low);  /* Stroke/stroke-12,5 (1) — 1px */
  border-radius:   inherit;
  pointer-events:  none;
}
.ds-collapse[data-variant='outline'] > .ds-collapse__header,
.ds-collapse[data-variant='outline'] > .ds-collapse__content {
  padding-inline:  var(--_px);
}

/* Закрытый: заливку несёт весь блок. */
.ds-collapse[data-variant='outline'][data-state='hover']:not([data-open]) {
  background:      var(--ds-nba-outline-hover);
}
.ds-collapse[data-variant='outline'][data-state='pressed']:not([data-open]) {
  background:      var(--ds-nba-outline-pressed);
}

/* Раскрытый: блок — базовая поверхность, заливку состояния несёт шапка. */
.ds-collapse[data-variant='outline'][data-open] {
  background:      var(--ds-surface-nb-base);
}
.ds-collapse[data-variant='outline'][data-open] > .ds-collapse__header {
  background:      var(--ds-fill-neutral-outline-hc);
  transition:      background-color var(--ds-dur-1) var(--ds-ease);
}
.ds-collapse[data-variant='outline'][data-open][data-state='hover'] > .ds-collapse__header {
  background:      var(--ds-nba-outline-hover);
}
.ds-collapse[data-variant='outline'][data-open][data-state='pressed'] > .ds-collapse__header {
  background:      var(--ds-nba-outline-pressed);
}

/* ── Disabled ───────────────────────────────────────────────────────────────── */
.ds-collapse[data-disabled] > .ds-collapse__header .ds-collapse__label {
  color:           var(--ds-disabled-text);
}
.ds-collapse[data-disabled] > .ds-collapse__header .ds-collapse__chevron {
  color:           var(--ds-disabled-icon);
}
/* У выключенного Outline в макете нет заливки, рамка остаётся Static/Border/Neutral-Blue/Low. */
.ds-collapse[data-variant='outline'][data-disabled] {
  background:      transparent;
}

/* ── Focus ──────────────────────────────────────────────────────────────────── */
/* Фокуса в макете нет — кольцо системное, --ds-focus-ring. Ghost: по форме слоя ховера
   (шапка с выносом); Outline: по рамке блока. [data-focus-visible] ставит компонент и
   тумблер Focus в State Explorer (цель — корень .ds-collapse); :has — для статичных демо,
   и смотрит он только в СВОЮ шапку: иначе фокус на вложенном блоке обводил бы родителя. */
.ds-collapse[data-variant='ghost'][data-focus-visible] > .ds-collapse__header,
.ds-collapse[data-variant='ghost'] > .ds-collapse__header:has(.ds-collapse__trigger:focus-visible) {
  box-shadow:      var(--ds-focus-ring);
}
.ds-collapse[data-variant='outline'][data-focus-visible],
.ds-collapse[data-variant='outline']:has(> .ds-collapse__header .ds-collapse__trigger:focus-visible) {
  box-shadow:      var(--ds-focus-ring);
}

/* ── Reduced motion ─────────────────────────────────────────────────────────── */
/* Раскрытие мгновенное всегда (reversible → 0 ms). Анимируется только цвет ховера. */
@media (prefers-reduced-motion: reduce) {
  .ds-collapse[data-variant='ghost'] > .ds-collapse__header,
  .ds-collapse[data-variant='outline'][data-open] > .ds-collapse__header {
    transition:    none;
  }
}
