/* ─── Dropdown menus (.ds-ddm) ───────────────────────────────────────────────────
   Shared DS primitive: menu + select item rows, group headers, parts.
   Values:    site/tokens.css  (--ds-ddm-* geometry + --ds-* color/type)
   Consumers: site/qa/configs/dropdown-menu.js + future site/preview menu pages
   Source:    Figma Components — .ItemParts/Menu 734-7098, .ItemParts/Select 735-11363,
              .Parts/Label Item 731-24590, .Parts/Counter 734-7094, .Parts/Label Group Items 736-9155
   States:    data-attributes only (NO :hover/:active pseudo-classes)
   Sizes:     [data-size="sm" | "md"] on .ds-ddm (default md)
   NOTE:      Popup shadow / width / max-height are ORGANISM-level — deferred to wave 2.
   ─────────────────────────────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════════════
   CONTAINER
   ══════════════════════════════════════════════════════════════════════════ */

.ds-ddm {
  display:        flex;
  flex-direction: column;
  row-gap:        var(--ds-ddm-gap-y);
  background:     var(--ds-surface-neutral-overlay);   /* Figma Static/Surface/Neutral/Overlay (736:9718) — mirror-aware token (L#fff/LI#33373b/D#1c2023/DI#fff); was --ds-surface (nb-900, too dark/flat in D/LI) */
  border:         calc(var(--ds-comp-unit) * 0.25) solid var(--ds-stroke-low);  /* 1px Figma static/border/neutral-blue/low */
  border-radius:  var(--ds-ddm-md-radius);
  padding:        var(--ds-ddm-md-pad);
  box-shadow:     var(--ds-shadow-lg);                 /* Figma Shadow/lg — dropdown/popover elevation (dark→white glow) */
  box-sizing:     border-box;
  /* scroll: overflow enabled; max-height is set by the popover positioner (consumer), not the primitive */
  overflow-y:     auto;
  scrollbar-width: thin;                               /* overlay scrollbar (Figma Scrollbar: transparent track, nba-30 thumb) */
  scrollbar-color: var(--ds-nba-30) transparent;
}

.ds-ddm[data-size='sm'] {
  border-radius: var(--ds-ddm-sm-radius);
  padding:       var(--ds-ddm-sm-pad);
}

/* Overlay scrollbar (WebKit) — width SM=6px from --ds-scrollbar-width, pill thumb, no track */
.ds-ddm::-webkit-scrollbar       { width: var(--ds-scrollbar-width); }
.ds-ddm::-webkit-scrollbar-track { background: transparent; }
.ds-ddm::-webkit-scrollbar-thumb { background: var(--ds-nba-30); border-radius: var(--ds-radius-pill); }

/* ── Size custom-property bridges (consumed by item/group/parts below) ───────── */

.ds-ddm[data-size='md'],
.ds-ddm-item[data-size='md'] {
  --_item-gap:    var(--ds-ddm-md-item-gap);
  --_item-pad:    var(--ds-ddm-md-item-pad);
  --_item-radius: var(--ds-ddm-md-item-radius);
  --_group-px:    var(--ds-ddm-md-group-px);
  --_group-py:    var(--ds-ddm-md-group-py);
  --_label-gap:   var(--ds-ddm-md-label-gap);
  --_icon:        calc(var(--ds-comp-unit) * 6);  /* 24 — leading icon = checkbox size (Figma Icon/Width MD=24) */
  --_item-fs:     var(--ds-l1-size);          /* 16 */
  --_item-lh:     var(--ds-l1-lh);            /* 24 */
  --_group-fs:    var(--ds-l2-size);          /* 14 */
  --_group-lh:    var(--ds-l2-lh);            /* 20 */
  --_ctrl:        calc(var(--ds-comp-unit) * 6);  /* 24 — checkbox / single-check box */
}

.ds-ddm[data-size='sm'],
.ds-ddm-item[data-size='sm'] {
  --_item-gap:    var(--ds-ddm-sm-item-gap);
  --_item-pad:    var(--ds-ddm-sm-item-pad);
  --_item-radius: var(--ds-ddm-sm-item-radius);
  --_group-px:    var(--ds-ddm-sm-group-px);
  --_group-py:    var(--ds-ddm-sm-group-py);
  --_label-gap:   var(--ds-ddm-sm-label-gap);
  --_icon:        calc(var(--ds-comp-unit) * 5);  /* 20 — leading icon = checkbox size (Figma Icon/Width SM=20) */
  --_item-fs:     var(--ds-l2-size);          /* 14 */
  --_item-lh:     var(--ds-l2-lh);            /* 20 */
  --_group-fs:    var(--ds-l3-size);          /* 12 */
  --_group-lh:    var(--ds-l3-lh);            /* 16 */
  --_ctrl:        calc(var(--ds-comp-unit) * 5);  /* 20 — checkbox / single-check box */
}

/* Default (no data-size) → md geometry, so a bare .ds-ddm-item still renders. */
.ds-ddm-item:not([data-size]) {
  --_item-gap:    var(--ds-ddm-md-item-gap);
  --_item-pad:    var(--ds-ddm-md-item-pad);
  --_item-radius: var(--ds-ddm-md-item-radius);
  --_label-gap:   var(--ds-ddm-md-label-gap);
  --_icon:        calc(var(--ds-comp-unit) * 6);  /* 24 */
  --_item-fs:     var(--ds-l1-size);
  --_item-lh:     var(--ds-l1-lh);
  --_ctrl:        calc(var(--ds-comp-unit) * 6);
}

/* ══════════════════════════════════════════════════════════════════════════════
   GROUP HEADER  (.Parts/Label Group Items 736-9155)
   ══════════════════════════════════════════════════════════════════════════ */

.ds-ddm-group {
  padding:     var(--_group-py, var(--ds-ddm-md-group-py)) var(--_group-px, var(--ds-ddm-md-group-px));
  color:       var(--ds-text-tertiary);
  font-family: inherit;
  font-size:   var(--_group-fs, var(--ds-l2-size));
  line-height: var(--_group-lh, var(--ds-l2-lh));
  font-weight: 400;   /* Body style (designer-confirmed); группа легче пунктов (500) */
}

/* ══════════════════════════════════════════════════════════════════════════════
   ITEM ROW  (.ItemParts/Menu 734-7098 + .ItemParts/Select 735-11363)
   ══════════════════════════════════════════════════════════════════════════ */

.ds-ddm-item {
  display:       flex;
  align-items:   center;
  gap:           var(--_item-gap, var(--ds-ddm-md-item-gap));
  padding:       var(--_item-pad, var(--ds-ddm-md-item-pad));
  border-radius: var(--_item-radius, var(--ds-ddm-md-item-radius));
  background:    transparent;
  color:         var(--ds-text-primary);
  font-family:   inherit;
  font-size:     var(--_item-fs, var(--ds-l1-size));
  line-height:   var(--_item-lh, var(--ds-l1-lh));
  cursor:        pointer;
  box-sizing:    border-box;
  transition:    background var(--ds-dur-1) var(--ds-ease), color var(--ds-dur-1) var(--ds-ease);
}

/* ── Состояния пункта. Рампы ДВЕ, а не одна ─────────────────────────────────────
   Здесь стояло «neutral nba scale — shared by neutral + destructive», и это было
   неверно: макет разводит их по разным рампам. В светлых темах обе дают 0.20 и 0.40,
   поэтому разницы не видно; в тёмных нейтральная остаётся на 0.20/0.40, а деструктивная
   поднимается до 0.60/0.80. То есть наведение на «Удалить» в тёмной теме было втрое
   слабее задуманного. Подтверждено владельцем 2026-08-04 (Figma DropdownMenu/menuItem,
   строки Destructive|Hover и Destructive|Pressed → Fill/Negative (Blue)/Ghost/*). ── */

.ds-ddm-item[data-state='hover'] {
  background: var(--ds-nba-20);
}

.ds-ddm-item[data-state='pressed'] {
  background: var(--ds-nba-ghost-pressed);
}

/* Специфичность (0,3,0) против (0,2,0) у нейтральных правил выше — деструктивный выигрывает
   без !important и без dark-override: ролевая ступень несёт тёмную величину сама. */
.ds-ddm-item[data-type='destructive'][data-state='hover'] {
  background: var(--ds-nba-neg-ghost-hover);
}

.ds-ddm-item[data-type='destructive'][data-state='pressed'] {
  background: var(--ds-nba-neg-ghost-pressed);
}

/* Выбранный + нажатый = Fill/Neutral-Blue/Ghost/Active. Здесь стоял НОМЕРНОЙ --ds-nba-50
   (0.50 светлые / 0.80 тёмные) — в светлых он совпадал с макетом, в тёмных давал 0.80
   против 0.60, то есть расхождение было ровно в двух темах из четырёх и потому выглядело
   мелочью. Ролевой --ds-nba-ghost-active заведён ещё 2026-08-04 при переводе оси
   выбранности на роли (Button, Tag, Chip, TGB) — DropdownMenu тогда в список не попал, и
   находка числилась закрытой, хотя этот вызов остался на номере. Токен даёт 4/4. */
.ds-ddm-item[data-selected][data-state='pressed'] {
  background: var(--ds-nba-ghost-active);
}

/* ── Disabled (no background change; just dim text) ──────────────────────────── */

.ds-ddm-item[data-disabled] {
  color:  var(--ds-disabled-text);
  cursor: default;
}

/* ── Destructive type — only the LABEL text turns red (not bg, not disabled) ──── */

.ds-ddm-item[data-type='destructive']:not([data-disabled]) .ds-ddm-label {
  color: var(--ds-neg-soft-text);   /* Text/Negative-Blue/Soft/Default (=Ghost/Hover): L#a70000/LI#ff9585/D#fe9485/DI#ae1610 — full ramp, no dark-override needed */
}
/* Destructive icon = Static/Icon/Negative/Accent (#d70000, brighter than label) — token self-ramps in all 4 themes */
.ds-ddm-item[data-type='destructive']:not([data-disabled]) .ds-ddm-item__icon {
  color: var(--ds-surface-neg-icon);
}

/* ══════════════════════════════════════════════════════════════════════════════
   LEADING ICON SLOT
   ══════════════════════════════════════════════════════════════════════════ */

.ds-ddm-item__icon {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  flex-shrink:     0;
  width:           var(--_icon, var(--ds-input-md-icon));
  height:          var(--_icon, var(--ds-input-md-icon));
  color:           var(--ds-icon-tertiary);   /* Static/Icon/Neutral-Blue/Tertiary #6b7175 — иконка светлее лейбла (иерархия) */  /* ряд Icon/*, не Text/*: значение то же в 4/4, роль верная */
}

.ds-ddm-item__icon svg {
  width:  100%;
  height: 100%;
}

/* ══════════════════════════════════════════════════════════════════════════════
   LABEL ITEM  (.Parts/Label Item 731-24590)
   ══════════════════════════════════════════════════════════════════════════ */

/* Label block: stacks label + optional caption; inline badge sits beside label text. */
.ds-ddm-label-block {
  display:        flex;
  flex-direction: column;
  flex:           1 1 auto;
  min-width:      0;
}

.ds-ddm-label {
  display:       flex;
  align-items:   center;
  gap:           var(--_label-gap, var(--ds-ddm-md-label-gap));
  flex:          1 1 auto;
  min-width:     0;
  color:         var(--ds-text-neutral-ghost);   /* Text/Neutral-Blue/Ghost/Default #222629 (флип→#fff в dark; контраст к surface во всех 4 темах) */
  font-weight:   500;
  font-size:     var(--_item-fs, var(--ds-l1-size));
  line-height:   var(--_item-lh, var(--ds-l1-lh));
}

/* Опора — ОБЩИЙ part «.Parts / Caption» (Figma 612:22805, стр. «↳ Fields»), а не узлы меню.
   Caption там самостоятельный COMPONENT_SET на 4 варианта Validation и подключается по
   месту, там где нужен, — поэтому его нет ни в Menu 736:9718, ни в SingleSelect 823:2560,
   ни в MultiSelect 823:2608. Отсутствие в инстансе ≠ отсутствие опоры: обход этих трёх
   узлов (2026-07-28) сперва прочитан мною как «ground truth нет вовсе» — неверно, знаменатель
   был не тот. Спека part (Plugin API 2026-07-28): Inter Regular 12/16, itemSpacing 4 до
   иконки 16px, цвет по варианту — None Static/Text/Neutral-Blue/Secondary · Positive/Warning/
   Negative → соответствующий Accent. Наше правило = вариант None, значения совпадают 1:1.
   Валидационные варианты в меню не заводим: у пункта меню нет состояния валидации. */
.ds-ddm-caption {
  color:       var(--ds-text-secondary);
  font-weight: 400;
  font-size:   var(--ds-l3-size);   /* 12 */
  line-height: var(--ds-l3-lh);     /* 16 */
}

/* ── Inline badge inside label — REUSED .ds-badge (soft/neutral) ───────────────
   Colors/size/radius come from the DS Badge primitive (badge.css); it already
   handles all 4 themes. Bridge only the layout so it never grows/wraps the row. */

.ds-ddm-label .ds-badge {
  flex-shrink: 0;
}

/* Справка у лейбла пункта — «Show IconHelp#731:15» у .Parts / Label Item (731:24590).
   Фрейм IconHelp 16×24 с padding 4/0/4/0 = глиф 16 по центру строки в 24; вертикальный
   инсет здесь даёт align-items:center у .ds-ddm-label, отдельный padding не нужен.
   Цвет — --ds-icon-tertiary (= Static/Icon/Neutral-Blue/Tertiary; резолвится в те же
   #6b7175/#acb3bb/#d0d7de/#5b6063, что и --ds-text-tertiary соседней иконки — сверено
   резолвером по 4 темам, разницы нет, но роль здесь иконочная).
   Размер НЕ масштабируется по тиру: у Label Item в макете одна геометрия, глиф 16 в обоих
   вариантах Type. Лестница sm/md/lg была бы выдумана, а не измерена. */
.ds-ddm-icon-help {
  display:     inline-flex;
  align-items: center;
  flex-shrink: 0;
  color:       var(--ds-icon-tertiary);
}

.ds-ddm-icon-help svg {
  display:      block;
  width:        var(--ds-icon-sm);          /* 16 — Figma 731:24590 */
  height:       var(--ds-icon-sm);
  stroke-width: var(--ds-icon-stroke-sm);   /* 2.25 при viewBox 24 = визуальные 1.5 макета */
}

/* ══════════════════════════════════════════════════════════════════════════════
   COUNTER  (.Parts/Counter 734-7094) — right-aligned "5 из 56" / "56"
   ══════════════════════════════════════════════════════════════════════════ */

.ds-ddm-counter {
  flex-shrink: 0;
  margin-left: auto;
  color:       var(--ds-text-tertiary);
  font-size:   var(--ds-l3-size);   /* 12 */
  line-height: var(--ds-l3-lh);     /* 16 */
}

/* ══════════════════════════════════════════════════════════════════════════════
   SHORTCUT TAG — REUSED .ds-tag (outline / neutral / sm)
   The DS Tag primitive (tag.css) supplies the outline look, colors, disabled
   styling and all 4 themes. Bridge only the row layout: right-align + no shrink.
   ══════════════════════════════════════════════════════════════════════════ */

.ds-ddm-item > .ds-tag {
  flex-shrink: 0;
  margin-left: auto;
}

/* Shortcut tag + counter must not both claim margin-left:auto — when both exist,
   counter pushes right; the tag sits in normal flow. */
.ds-ddm-counter ~ .ds-tag,
.ds-ddm-item > .ds-tag ~ .ds-ddm-counter {
  margin-left: 0;
}

/* ══════════════════════════════════════════════════════════════════════════════
   SUB-TRIGGER CHEVRON  (chevron-right instead of shortcut)
   ══════════════════════════════════════════════════════════════════════════ */

.ds-ddm-chevron {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  flex-shrink:     0;
  margin-left:     auto;
  width:           var(--_icon, var(--ds-input-md-icon));
  height:          var(--_icon, var(--ds-input-md-icon));
  /* Шеврон стоит на Icon/Neutral-Blue/Ghost/Default — той же тёмной ступени, что и лейбл,
     а НЕ на Tertiary, как ведущая иконка (обход Plugin API 734:7098, 2026-08-06: #222629 ·
     #FFFFFF · #FFFFFF · #1C2023 по 4 модам). Здесь стояло --ds-icon-tertiary с припиской
     «роль верная» — ряд действительно был иконочный, но ступень чужая, и расхождение шло
     во всех четырёх темах. Ось «тот ли РЯД» этого не видит по построению: проверять ступень
     отдельно от ряда. */
  color:           var(--ds-icon-neutral-ghost);
}

.ds-ddm-chevron svg { width: 100%; height: 100%; }

/* Ведущая иконка выключенного пункта. Правила НЕ БЫЛО вовсе: у .ds-ddm-item__icon есть
   собственное объявление color, и оно перебивает наследование от .ds-ddm-item[data-disabled]
   — иконка не гасла ни в одной из четырёх тем (замер 2026-08-06, 20/20 ячеек оси).
   Макет до правки владельца биндил её на Border/Disable — единственный на весь файл случай
   глифа на рампе рамки (прочёс: 2 привязки против 1125 на Icon/Disable). Владелец выправил
   макет: теперь Icon/Disable/Neutral (Blue), тот же ряд и та же ступень, что у соседнего
   шеврона в этой же строке. Совпадает с --ds-disabled-icon 4/4. */
.ds-ddm-item[data-disabled] .ds-ddm-item__icon {
  color: var(--ds-disabled-icon);
}

/* Выключенный шеврон — Icon/Disable/Neutral (Blue), иконочная ступень выключенного:
   #AEB5BD · #AEB5BD · #91989D · #91989D. Здесь стоял --ds-disabled-text (#8F969B в светлых):
   ряды Icon/Disable и Text/Disable совпадают только в двух модах из четырёх, поэтому подмена
   выглядела исправной в тёмных темах и расходилась в светлых. */
.ds-ddm-item[data-disabled] .ds-ddm-chevron {
  color: var(--ds-disabled-icon);
}

/* Подпись выключенного пункта — Text/Disable/Neutral (Blue): #8F969B · #8F969B · #91989D ·
   #91989D, ровно то, во что резолвится --ds-disabled-text во всех четырёх темах.
   ТРЕТИЙ случай одного и того же дефекта в этом файле: у .ds-ddm-label собственное
   объявление color, и наследование от .ds-ddm-item[data-disabled] до него не доходит —
   подпись оставалась ступенью ПОКОЯ (#222629 в светлой, #FFFFFF в тёмной), то есть
   выключенный пункт выглядел обычным. Два соседа по строке (ведущая иконка и шеврон)
   починены сегодня же, потому что у них был якорь в снимке макета; у подписи якоря не
   было — снимок menuItem был снят без спуска в инстансы и нёс 2 роли из 6. Дефект
   держался ровно поэтому: узел, который никто не меряет, неотличим от сходящегося.
   Найден замером после того, как ось ожила (2026-08-06, 8 ячеек: 4 темы × 2 ветки
   хвостового слота). */
.ds-ddm-item[data-disabled] .ds-ddm-label {
  color: var(--ds-disabled-text);
}

/* Описание выключенного пункта — тот же токен, что у подписи. У МЕНЮ своей строки
   «выключено × описание» в макете НЕТ: выключенные варианты 734:7098 подставляют
   .Parts / Label Item с Type=Label, то есть описание там просто не нарисовано, а сам
   part оси Disabled не несёт вовсе (оси Type и Indicators). Поэтому взято не по аналогии
   «на глаз», а прочёсом ВСЕГО файла: 36 страниц из 36, текстовых узлов Caption* — 130,
   с привязкой 127, из них Static/Text/Neutral-Blue/Secondary 106 · Text/Disable/Neutral
   (Blue) 18 · три валидационных акцента по одному. Все 18 «выключенных» — строки
   Disabled=On у Checkbox / Radiobutton / Switcher, исключений ноль. Привязка сходится
   обоими концами: покойная ступень описания у меню (--ds-text-secondary) — ровно та же
   Static/Text/Neutral-Blue/Secondary, из которой эти 18 уходят в Disable.
   ГРАНИЦА ЧЕСТНОСТИ: это правило файла со знаменателем 18/18, а НЕ якорь самого меню —
   нарисованного случая у меню не существует, и как только он появится, сверять по нему. */
.ds-ddm-item[data-disabled] .ds-ddm-caption {
  color: var(--ds-disabled-text);
}

/* ══════════════════════════════════════════════════════════════════════════════
   SELECT — MULTI CONTROL — REUSED .ds-check (.ItemParts/Select 735-11363)
   The bare Check primitive (checkbox.css) supplies the square, fill, tick glyph,
   hover/checked/indeterminate/disabled states and all 4 themes. Its own
   [data-size] maps the ctrl to 24 (md) / 20 (sm) — identical to the menu's --_ctrl
   ladder — so NO size override is needed; bridge only row layout. */

.ds-ddm-item > .ds-check {
  flex-shrink: 0;
}

/* ══════════════════════════════════════════════════════════════════════════════
   SELECT — SINGLE RIGHT CHECK  (shown when checked)
   ══════════════════════════════════════════════════════════════════════════ */

.ds-ddm-check {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  flex-shrink:     0;
  margin-left:     auto;
  width:           var(--_ctrl, calc(var(--ds-comp-unit) * 6));   /* 24 / sm 20 */
  height:          var(--_ctrl, calc(var(--ds-comp-unit) * 6));
  color:           var(--ds-text-primary);
}

.ds-ddm-check svg { width: 100%; height: 100%; }

.ds-ddm-item[data-disabled] .ds-ddm-check {
  color: var(--ds-disabled-text);
}

/* ══════════════════════════════════════════════════════════════════════════════
   SELECT — LOADING STATE
   ══════════════════════════════════════════════════════════════════════════ */

.ds-ddm-item[data-state='loading'] {
  cursor: progress;
}
/* Загрузка. Здесь стояло «icon + label muted → Tertiary», и неверны были обе половины.
   ИКОНКИ в этой строке нет вовсе: макет (736:9288) кладёт в ведущий слот дочерний Spinner,
   а circle-dashed из строки убран — правило красило элемент, которого в состоянии нет, и
   было инертным (у .ds-spinner собственные токены кольца, currentColor он берёт только
   при data-tone=inherit, а это режим Button).
   ПОДПИСЬ приглушена не до Tertiary, а до ступени ВЫКЛЮЧЕННОГО: Text/Disable/Neutral (Blue)
   = #8F969B · #8F969B · #91989D · #91989D. Прежний --ds-icon-tertiary расходился с макетом
   во ВСЕХ четырёх темах. Правило оставлено явным, хотя React и помечает загрузку как
   data-disabled (isDisabled = disabled || loading): статический потребитель этого атрибута
   не ставит, а состояние обязано выглядеть одинаково в обоих слоях. */
.ds-ddm-item[data-state='loading'] .ds-ddm-label {
  color: var(--ds-disabled-text);
}

/* ══════════════════════════════════════════════════════════════════════════════
   DARK MODE
   Здесь стоял α-подъём нейтрального пункта: hover 0.20→0.60, pressed 0.40→0.80.
   УДАЛЁН 2026-08-04 вместе с такой же надбавкой у кнопки — по решению владельца
   «сделать как в макете». Подъём не просто расходился с макетом: он поднимал
   нейтральный пункт РОВНО до величин деструктивного (0.60 и 0.80), то есть стирал
   различие, ради которого заведены --ds-nba-neg-ghost-*. Замер показал это прямо:
   до удаления оба типа пункта давали в тёмной 0.60.
   Прочие цвета меню несут темо-адаптивные токены и переключаются сами.
   Подпись деструктивного пункта закрыта полной рампой --ds-neg-soft-text.
   ══════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   ══════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .ds-ddm-item {
    transition-duration: 0.01ms !important;
    animation-duration:  0.01ms !important;
  }
  /* The reused .ds-check carries its own reduced-motion rule (checkbox.css). */
}
