/* ============================================================================
   Avatar — site/css/avatar.css

   ИСТОЧНИК ИСТИНЫ. Figma Components isVYOT7tW0RTaIofg7FAqM, страница «↳ Avatar»
   (1438:32096). Наборы: Single 2465:2150 (46 вариантов) · Group 2489:10047 (20) ·
   Pair 2489:10735 · .Item_Pair 2489:10665. Всё снято обходом Plugin API 2026-08-31:
   геометрия — из boundVariables и box-model узлов, цвета — резолвом valuesByMode по
   всем 4 модам коллекции Theme. Скриншот не участвовал ни в одном числе.

   ОСЬ РАЗМЕРОВ НЕ НА КАНВЕ. Все 46 вариантов набора и обе демо-рамки (Light/Dark)
   нарисованы в одном размере — 40px. Пять размеров живут ТОЛЬКО в таблице переменных,
   коллекция «❖ Avatar» (VariableCollectionId:2441:6300), моды XS/SM/MD/LG/XL. Искать
   ось по канве здесь бесполезно — ровно тот же случай, что был у Scrollbar.

        переменная Figma        XS     SM     MD     LG     XL
        Width-Height            24     32     40     48     56
        Square Radius            4      6      8     10     12
        Text Style/Size         12     12     14     16     18
        Text Style/Line Height  14     14     20     20     24
        Icon/Width-Height       16     20     24     24     32
        Icon/Stroke            1.5      2      2      2      2
        Stroke (кольцо)          1      1      2      2      2
        Dot/Width-Height         8     10     10     12     12
        Dot/Padding              0      2      2      4      4
        Gap (стек)              -8    -10    -12    -14    -16
        Item/Width-Height       16     20     24     32     40
        Item/Padding             0      1      2      0      0

   ДВЕ ПЕРЕМЕННЫЕ ОБЪЯВЛЕНЫ, НО ОСИ ЗА НИМИ НЕТ. Пересчёт привязок по всей странице:
   Width-Height 1012, Stroke 992, Square Radius 180, Icon/Width-Height 172, Text Style/*
   по 134, Icon/Stroke 86, Gap 48, Item/Width-Height 24, Item/Padding 16 — а
   Dot/Width-Height и Dot/Padding РОВНО 0. Кадр «Badge places» (2558:24930), собранный
   владельцем 2026-08-31 под этот вопрос, снял его окончательно: точка 8×8 и вынос 2 —
   ПОСТОЯННЫЕ на всех пяти размерах, ни одна из двух величин от размера не зависит.
   Пятиступенчатые ряды 8/10/10/12/12 и 0/2/2/4/4 в таблице переменных остаются, но
   элементу не соответствуют — таблица объявляет ось, которой у точки нет.
   Здесь стояло обратное: я вывел размер и вынос из этих двух рядов, потому что на MD они
   сходились с замером до единицы (внешний габарит 8+2×1=10 = Dot/Width-Height MD, вынос
   2 = Dot/Padding MD). Совпадение на одном размере — не ось; MD был единственным
   размером на канве, и вывод «раз сходится тут, значит ряд действует» оказался ложным
   в обе стороны сразу.

   ЦВЕТ. Ось Semantic — 8 семейств, и она существует ТОЛЬКО при Fiil=On, High contrast=Off.
   У Neutral сверх того есть Fiil=Off (прозрачный) и High contrast=On (белая заливка).
   Остальные семь семейств живут в одном сочетании — это не пробел, так собран набор.
   Text/<X>/Accent и Icon/<X>/Accent совпадают во всех 4 модах у всех семи семейств
   (28 из 28 ячеек), но разведены по ролям токенами -text и -icon: ряды совпадают по
   ступеням, а не по ролям, и расходятся они молча.

   APCA. Семь декоративных семейств проходят порог Lc≥45 во ВСЕХ четырёх темах: Light
   56–57, Dark 70–75, Light-Invert 68–72, Dark-Invert 54–55 (прогон tools/audit-apca-pairs.mjs
   2026-09-04, семь пар «подпись × заливка», ни одной освобождённой ячейки).
   ЗДЕСЬ СТОЯЛО ОБРАТНОЕ и это надо помнить: до 2026-09-04 Dark-Invert давала Lc 31–32,
   то есть провал, и семь пар держались в списке освобождённых. Владелец выбрал мягкий
   вариант — поднять ступень ТЕКСТА и иконки, заливки не трогать; 14 переменных в обеих
   тёмных инвертированных ветках tokens.css переписаны, макет поправлен там же.
   Абзац пережил починку на несколько часов — ровно тот случай, когда проза о токене
   протухает быстрее самого токена. Числа взяты из значений макета, не выведены; ядро
   расчёта проверено контролем (чёрное на белом 106, белое на чёрном 108).
   Neutral проходит везде (60–100), HC везде (103–106).

   ЧЕГО ЗДЕСЬ НЕТ. Состояний наведения/нажатия/фокуса у Аватара в макете нет вовсе —
   ни одной переменной состояния, ни одного варианта. Он статический: это опознавательный
   знак, а не орган управления. Если понадобится кликабельный — оборачивать в кнопку,
   а не наращивать состояния здесь.
   ============================================================================ */

.ds-avatar {
  /* MD — значения по умолчанию, ровно мод MD коллекции «❖ Avatar» */
  --_av-size:     calc(var(--ds-comp-unit) * 10);   /* 40 */
  --_av-r:        calc(var(--ds-comp-unit) * 2);    /* 8  · Square Radius */
  --_av-fs:       var(--ds-text-base);              /* 14 */
  --_av-lh:       calc(var(--ds-comp-unit) * 5);    /* 20 */
  --_av-icon:     calc(var(--ds-comp-unit) * 6);    /* 24 */
  /* ТОЛЩИНА ШТРИХА — В ЕДИНИЦАХ viewBox, А НЕ В ФИГМОВСКИХ. Иконка рисуется в viewBox 24
     и масштабируется до --_av-icon, поэтому видимая толщина = stroke-width × (икона / 24).
     До 2026-09-05 здесь и в четырёх размерных блоках стояли ФИГМОВСКИЕ числа (1.5 и 2), и
     три размера из пяти рисовались неверно — замерено в браузере, а не выведено:
     XS видимые 1.0 при макетных 1.5 · SM 1.667 при 2 · XL 2.667 при 2; MD и LG совпадали.
     Ровно та же ошибка, что однажды нашлась у Tabs, и лесенка --ds-icon-stroke-* заведена
     как раз под неё: её ступени уже пересчитаны под свои размеры иконки. */
  --_av-icon-sw:  var(--ds-icon-stroke-lg);         /* 2 при иконке 24 → видимые 2 · Icon/Stroke MD */
  --_av-ring:     calc(var(--ds-comp-unit) * 0.5);  /* 2  · Stroke */
  /* Точка НЕ масштабируется — постоянные на всех пяти размерах, см. кадр «Badge places». */
  --_av-dot-pad:  calc(var(--ds-comp-unit) * 0.5);  /* 2 — вынос за угол у квадрата; ядро 8 и кольцо 1 несёт Badge dot */

  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  box-sizing: border-box;
  width: var(--_av-size);
  height: var(--_av-size);
  border-radius: var(--_av-r);
  overflow: visible;      /* точка и кольцо выходят за габарит — обрезать нельзя */
  user-select: none;
}

/* ── Ось размера ─────────────────────────────────────────────────────────── */
.ds-avatar[data-size='xs'] {
  --_av-size:     calc(var(--ds-comp-unit) * 6);     /* 24 */
  --_av-r:        var(--ds-comp-unit);               /* 4  */
  --_av-fs:       var(--ds-text-xs);                 /* 12 */
  --_av-lh:       calc(var(--ds-comp-unit) * 3.5);   /* 14 */
  --_av-icon:     calc(var(--ds-comp-unit) * 4);     /* 16 */
  --_av-icon-sw:  var(--ds-icon-stroke-sm);          /* 2.25 при иконке 16 → видимые 1.5 · было 1.5 → видимые 1.0 */
  --_av-ring:     calc(var(--ds-comp-unit) * 0.25);  /* 1  */
}
.ds-avatar[data-size='sm'] {
  --_av-size:     calc(var(--ds-comp-unit) * 8);     /* 32 */
  --_av-r:        calc(var(--ds-comp-unit) * 1.5);   /* 6  */
  --_av-fs:       var(--ds-text-xs);                 /* 12 */
  --_av-lh:       calc(var(--ds-comp-unit) * 3.5);   /* 14 */
  --_av-icon:     calc(var(--ds-comp-unit) * 5);     /* 20 */
  --_av-icon-sw:  var(--ds-icon-stroke-md);          /* 2.4 при иконке 20 → видимые 2 · было 2 → видимые 1.667 */
  --_av-ring:     calc(var(--ds-comp-unit) * 0.25);  /* 1  */
}
.ds-avatar[data-size='lg'] {
  --_av-size:     calc(var(--ds-comp-unit) * 12);    /* 48 */
  --_av-r:        calc(var(--ds-comp-unit) * 2.5);   /* 10 — ступени 10 в шкале --ds-radius-* нет, лестница Аватара 4/6/8/10/12 своя */
  --_av-fs:       var(--ds-text-md);                 /* 16 */
  --_av-lh:       calc(var(--ds-comp-unit) * 5);     /* 20 */
  --_av-icon:     calc(var(--ds-comp-unit) * 6);     /* 24 */
  --_av-icon-sw:  var(--ds-icon-stroke-lg);          /* 2 при иконке 24 → видимые 2 · значение то же, форма приведена к лесенке */
  --_av-ring:     calc(var(--ds-comp-unit) * 0.5);   /* 2  */
}
.ds-avatar[data-size='xl'] {
  --_av-size:     calc(var(--ds-comp-unit) * 14);    /* 56 */
  --_av-r:        calc(var(--ds-comp-unit) * 3);     /* 12 */
  --_av-fs:       var(--ds-text-lg);                 /* 18 */
  --_av-lh:       calc(var(--ds-comp-unit) * 6);     /* 24 */
  --_av-icon:     calc(var(--ds-comp-unit) * 8);     /* 32 */
  /* СТУПЕНИ ЛЕСЕНКИ ПОД 32-ПИКСЕЛЬНУЮ ИКОНКУ НЕТ. --ds-icon-stroke-{sm,md,lg} пересчитаны
     под 16, 20 и 24; XL у Аватара — первый случай иконки 32 в системе. Видимые 2 при
     viewBox 24 требуют 2 × 24/32 = 1.5. Держу локальным calc, а не завожу --ds-icon-stroke-xl:
     tokens.css — защищённый путь, и новая ступень общей лесенки это решение владельца,
     а не побочная правка. Вопрос вынесен строкой реестра. Было 2 → видимые 2.667. */
  --_av-icon-sw:  calc(var(--ds-comp-unit) * 0.375); /* 1.5 при иконке 32 → видимые 2 */
  --_av-ring:     calc(var(--ds-comp-unit) * 0.5);   /* 2  */
}

/* ── Форма ───────────────────────────────────────────────────────────────── */
/* Square=Off в макете = Radius/Max. Круг — значение по умолчанию набора. */
.ds-avatar[data-shape='circle'] { --_av-r: var(--ds-radius-pill); }

/* ── Заливка и цвет содержимого ──────────────────────────────────────────── */
/* Fiil=Off — заливки нет вовсе (у корня варианта fills пустой), цвет содержимого
   остаётся Neutral/Primary. Ось Semantic при Fiil=Off в макете не существует. */
.ds-avatar { background: transparent; color: var(--ds-text-primary); }

.ds-avatar[data-fill] {
  background: var(--ds-surface-nb-high);   /* Static/Surface/Neutral-Blue/3 - High */
  color: var(--ds-text-primary);           /* Static/Text/Neutral-Blue/Primary */
}
.ds-avatar[data-fill][data-semantic='gold']   { background: var(--ds-surface-gold-high);   color: var(--ds-surface-gold-text); }
.ds-avatar[data-fill][data-semantic='dodger'] { background: var(--ds-surface-dodger-high); color: var(--ds-surface-dodger-text); }
.ds-avatar[data-fill][data-semantic='sage']   { background: var(--ds-surface-sage-high);   color: var(--ds-surface-sage-text); }
.ds-avatar[data-fill][data-semantic='violet'] { background: var(--ds-surface-violet-high); color: var(--ds-surface-violet-text); }
.ds-avatar[data-fill][data-semantic='coral']  { background: var(--ds-surface-coral-high);  color: var(--ds-surface-coral-text); }
.ds-avatar[data-fill][data-semantic='pink']   { background: var(--ds-surface-pink-high);   color: var(--ds-surface-pink-text); }
.ds-avatar[data-fill][data-semantic='olive']  { background: var(--ds-surface-olive-high);  color: var(--ds-surface-olive-text); }

/* High contrast=On. В макете есть только у Neutral и перекрывает семантику —
   поэтому правило стоит НИЖЕ семи семейств и без :not(), это осознанный порядок. */
.ds-avatar[data-fill][data-hc] {
  background: var(--ds-surface-nb-hc);     /* Static/Surface/Neutral-Blue/High Contrast */
  color: var(--ds-text-primary);
}

/* Disabled=On. В макете есть только у Neutral без высокого контраста (8 вариантов:
   Square × Type Initials/Icon × Fiil). Правила стоят НИЖЕ семейств и HC намеренно: если
   вызывающий передал семантику вместе с disabled, выключенность перекрывает её — сочетания
   в макете нет, а приглушённый знак не должен выглядеть цветным. */
.ds-avatar[data-disabled] { color: var(--ds-disabled-text); }            /* Text/Disable/Neutral (Blue) */
.ds-avatar[data-fill][data-disabled] {
  background: var(--ds-disabled-fill);     /* Fill/Disable/Neutral (Blue) */
  color: var(--ds-disabled-text);
}

/* ── Содержимое ──────────────────────────────────────────────────────────── */
.ds-avatar-initials {
  font-family: inherit;
  font-size: var(--_av-fs);
  line-height: var(--_av-lh);
  font-weight: 500;                  /* Figma Inter Medium — узел Text набора Single */
  color: inherit;
  white-space: nowrap;
}

.ds-avatar-icon {
  width: var(--_av-icon);
  height: var(--_av-icon);
  flex: 0 0 auto;
  stroke: currentColor;              /* Static/Icon/<Semantic>/Accent = цвет корня */
  stroke-width: var(--_av-icon-sw);
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Иконочный ряд ведут токены -icon, а не -text: ряды совпадают 4/4, но роли разные.
   currentColor выше берёт -text; здесь роль возвращается на своё имя. */
.ds-avatar[data-fill][data-semantic='gold']   .ds-avatar-icon { stroke: var(--ds-surface-gold-icon); }
.ds-avatar[data-fill][data-semantic='dodger'] .ds-avatar-icon { stroke: var(--ds-surface-dodger-icon); }
.ds-avatar[data-fill][data-semantic='sage']   .ds-avatar-icon { stroke: var(--ds-surface-sage-icon); }
.ds-avatar[data-fill][data-semantic='violet'] .ds-avatar-icon { stroke: var(--ds-surface-violet-icon); }
.ds-avatar[data-fill][data-semantic='coral']  .ds-avatar-icon { stroke: var(--ds-surface-coral-icon); }
.ds-avatar[data-fill][data-semantic='pink']   .ds-avatar-icon { stroke: var(--ds-surface-pink-icon); }
.ds-avatar[data-fill][data-semantic='olive']  .ds-avatar-icon { stroke: var(--ds-surface-olive-icon); }
.ds-avatar[data-fill][data-hc] .ds-avatar-icon { stroke: var(--ds-icon-primary); }
/* Иконка выключенного — своя ступень Icon/Disable, не текстовая: в светлых темах
   #aeb5bd против #8f969b у инициалов. Две формы: с заливкой вес (0,4,0) и порядок перебивают
   правила семейств выше, без заливки правил семейств нет и хватает (0,3,0). */
.ds-avatar[data-fill][data-disabled] .ds-avatar-icon,
.ds-avatar[data-disabled] .ds-avatar-icon { stroke: var(--ds-disabled-icon); }  /* Icon/Disable/Neutral (Blue) */

/* Фото, флаг и логотип занимают всю плитку и обрезаются её же радиусом.
   Заливки под ними в макете нет — у вариантов Photo/Flag/Logotype fills пустой. */
.ds-avatar-photo,
.ds-avatar-flag,
.ds-avatar-logo {
  width: 100%;
  height: 100%;
  border-radius: inherit;
  object-fit: cover;
  display: block;
}
/* …и снять саму заливку корня. Комментарий выше утверждал «заливки нет» с самого начала, а
   код её рисовал: Fiil по умолчанию On, и data-fill красил плитку под картинкой во всех
   4 темах (замер 2026-09-24 на витрине). Видно это на логотипе с прозрачностью и по краю
   скругления. Макет: у Type=Photo/Flag/Logotype fills пустой при Fiil=On — набор Single
   2465:2150, 6 вариантов из 6. Вес (0,3,0) — как у правил семейств, high contrast и
   выключенного выше; перевешивает порядком. */
.ds-avatar[data-fill]:is([data-type='photo'], [data-type='flag'], [data-type='logo']) {
  background: transparent;
}

/* ── Кольцо-разделитель (булев проп Border) ──────────────────────────────── */
/* Отдельный слой, а не border на корне: в макете это самостоятельный узел Border с
   обводкой OUTSIDE, то есть кольцо лежит СНАРУЖИ габарита и не съедает содержимое.
   border на корне при box-sizing:border-box сжал бы содержимое — тот же класс, что
   запрет менять border-width на состояниях. */
.ds-avatar-ring {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: 0 0 0 var(--_av-ring) var(--ds-border-group-separator);
  pointer-events: none;
}

/* ── Точка (булев проп Badge) ────────────────────────────────────────────── */
/* ТОЧКА НЕ МАСШТАБИРУЕТСЯ. Ядро 8, кольцо 1, вынос 2 — постоянные на всех пяти размерах.
   Источник — кадр «Badge places» (2558:24930), собранный владельцем 2026-08-31 именно под
   этот вопрос: десять инстансов, пять размеров × два типа содержимого, все Square=On.
   Замер по всем десяти: точка везде 8×8, левый край 18/26/34/42/50 при ширине 24/32/40/48/56
   (то есть правый край всегда на 2 правее плитки), верх везде −2, обводка везде 1 OUTSIDE.

   ЧТО ЗДЕСЬ СТОЯЛО ДО ЭТОГО И ПОЧЕМУ ЭТО БЫЛО НЕВЕРНО. Я вывел размер точки из переменной
   Dot/Width-Height (8/10/10/12/12) и вынос из Dot/Padding (0/2/2/4/4), потому что обе
   объявлены пятиступенчатой осью в коллекции «❖ Avatar». Обе на канве не привязаны ни к
   одному узлу, и это было записано честно — но вывод из ненайденной привязки я всё равно
   сделал, и он оказался ложным в обе стороны: точка не растёт вовсе. Таблица переменных
   объявляет ось, которой у элемента нет.

   ПОСАДКА. У круга точка стоит ЗАПОДЛИЦО во внутренний угол описанного квадрата (замер
   набора 2465:2150, вариант Square=Off: x=32 при ширине 40, y=0), у квадрата вынесена
   наружу на --_av-dot-pad. Прежняя редакция ставила transform: translate(50%,-50%), то есть
   сажала точку ЦЕНТРОМ на угол — это не совпадало ни с одной из двух форм. */
/* РАЗМЕР, ЗАЛИВКУ И КОЛЬЦО НЕСЁТ BADGE (2026-09-14). Точка — компонент Badge
   (variant dot, semantic brand), как в макете: мастер «Single» 2465:2150 собирает её
   инстансом набора Dot 164:26490, 38 из 38, все Semantic=Brand · Disable=Off. Прежде здесь
   стояла собственная копия — 8×8, --ds-brand-500, кольцо тенью Group-separator; у самого
   Badge кольца при этом не было, и одна деталь макета жила в двух местах по-разному.
   Значения не изменились: --ds-surface-brand-accent алиасит --ds-brand-500, ядро 8 и кольцо 1
   те же. Здесь остаётся только посадка в угол — layout, цвета примитива не перекрашиваются. */
.ds-avatar-dot {
  position: absolute;
  top: 0;
  right: 0;
  pointer-events: none;
}
.ds-avatar[data-shape='square'] > .ds-avatar-dot {
  top: calc(-1 * var(--_av-dot-pad));
  right: calc(-1 * var(--_av-dot-pad));
}

/* ── Стек (набор Group) ──────────────────────────────────────────────────── */
/* itemSpacing отрицательный — аватары наезжают друг на друга. Разделяет их кольцо
   Group-separator, поэтому у детей стека оно обязано быть включено. */
/* Наезд задан ОТРИЦАТЕЛЬНЫМ ПОЛЕМ, а не gap. Причина не стилистическая: свойство gap
   отрицательных значений не принимает вовсе — браузер отбрасывает объявление целиком,
   и плитки встают встык. Первая редакция этого файла писала gap: var(--_av-gap) и
   выглядела правильно; замер шага дал 40 при ожидаемых 28. Глазами это читается как
   «наезд просто небольшой», числом — как отсутствующий. */
.ds-avatar-group {
  --_av-gap: calc(var(--ds-comp-unit) * -3);       /* -12 · MD */
  display: inline-flex;
  align-items: center;
}
/* Соседство ЛЮБЫХ прямых детей, а не перечень однотипных пар. Здесь стояло
   «.ds-avatar + .ds-avatar, .ds-avatar-pair + .ds-avatar-pair», и у смешанной
   группы — аватар рядом с парой — отрицательного отступа не было вовсе: плитки
   вставали встык, наезда не возникало. Нашёл стенд 2026-09-06; дефект старый, его
   не вносила правка порядка наложения, но и мой замер его не покрыл — в витрине
   смешанных групп нет, поэтому 25 ячеек из 25 сошлись, ничего не сказав об этом
   случае. Перечень типов ломался бы заново при появлении любого нового ребёнка;
   соседство как таковое не ломается. В макете основание то же: отрицательный шаг
   у Group (2489:10793) задан itemSpacing контейнера и к типу детей не привязан. */
.ds-avatar-group > * + * {
  margin-left: var(--_av-gap);
}
.ds-avatar-group[data-size='xs'] { --_av-gap: calc(var(--ds-comp-unit) * -2); }    /* -8  */
.ds-avatar-group[data-size='sm'] { --_av-gap: calc(var(--ds-comp-unit) * -2.5); }  /* -10 */
.ds-avatar-group[data-size='lg'] { --_av-gap: calc(var(--ds-comp-unit) * -3.5); }  /* -14 */
.ds-avatar-group[data-size='xl'] { --_av-gap: calc(var(--ds-comp-unit) * -4); }    /* -16 */

/* Порядок наложения: КАЖДЫЙ СЛЕДУЮЩИЙ перекрывает предыдущего — поправлено 2026-09-06
   по прямому указанию владельца. Здесь стояла убывающая лесенка z-index 5→1, а
   рядом — обоснование, выведенное из положения элементов на канве. ОНО НЕВЕРНО и
   приводится только как запись ошибки, не как довод: положение на канве к порядку
   наложения отношения не имеет. Верное основание снято чтением узла: у Figma дети
   хранятся СЗАДИ НАПЕРЁД, и при itemReverseZIndex=false (а у мастера Group
   2489:10793 именно false) верхним рисуется ПОСЛЕДНИЙ ребёнок; снимок того же узла
   показывает «+5» поверх последнего аватара. ГРАНИЦА, названная стендом и верная:
   это ВНЕШНЯЯ проверка, репозиторием она не доказывается — воспроизводится только
   повторным чтением узла через Plugin API, канвы у нас на диске нет.
   Лесенки больше нет: документный порядок уже даёт нужное — позиционированные
   соседи с z-index:auto рисуются в порядке следования. isolation изолирует
   внутренние z-index пары (её кружки несут 1 и 2), иначе они всплыли бы в общий
   контекст наложения группы и перемешались с соседями. */
.ds-avatar-group > .ds-avatar,
.ds-avatar-group > .ds-avatar-pair { position: relative; isolation: isolate; }

/* ── Пара (набор Pair) ───────────────────────────────────────────────────── */
/* Плитка размера аватара, внутри два кружка Item/Width-Height: задний в правом
   верхнем углу, передний в левом нижнем, оба с отступом Item/Padding от края. */
.ds-avatar-pair {
  /* --_av-size объявлен ЗДЕСЬ, а не только в размерных правилах. Первая редакция задала
     его лишь для xs/sm/lg/xl, и у MD — единственного размера без своего правила —
     width: var(--_av-size) остался без значения: плитка вышла шириной 0, а дети,
     будучи абсолютом, продолжали рисоваться на своих местах. Внешне почти незаметно,
     числом — ноль. Ровно тот случай, когда «по умолчанию» значит «не объявлено». */
  --_av-size:     calc(var(--ds-comp-unit) * 10);   /* 40 · MD */
  --_av-item:     calc(var(--ds-comp-unit) * 6);    /* 24 · MD */
  --_av-item-pad: calc(var(--ds-comp-unit) * 0.5);  /* 2  · MD */
  position: relative;
  display: inline-block;
  flex: 0 0 auto;
  width: var(--_av-size);
  height: var(--_av-size);
}
.ds-avatar-pair[data-size='xs'] { --_av-size: calc(var(--ds-comp-unit) * 6);  --_av-item: calc(var(--ds-comp-unit) * 4);  --_av-item-pad: 0px; }
.ds-avatar-pair[data-size='sm'] { --_av-size: calc(var(--ds-comp-unit) * 8);  --_av-item: calc(var(--ds-comp-unit) * 5);  --_av-item-pad: calc(var(--ds-comp-unit) * 0.25); }
.ds-avatar-pair[data-size='lg'] { --_av-size: calc(var(--ds-comp-unit) * 12); --_av-item: calc(var(--ds-comp-unit) * 8);  --_av-item-pad: 0px; }
.ds-avatar-pair[data-size='xl'] { --_av-size: calc(var(--ds-comp-unit) * 14); --_av-item: calc(var(--ds-comp-unit) * 10); --_av-item-pad: 0px; }

.ds-avatar-pair > .ds-avatar {
  position: absolute;
  --_av-size: var(--_av-item);
  --_av-ring: calc(var(--ds-comp-unit) * 0.25);     /* 1 — у пары кольцо всегда 1px */
}
.ds-avatar-pair > .ds-avatar:nth-child(1) { top: var(--_av-item-pad); right: var(--_av-item-pad); z-index: 1; }
.ds-avatar-pair > .ds-avatar:nth-child(2) { bottom: var(--_av-item-pad); left: var(--_av-item-pad); z-index: 2; }
