/* components.css — повторяемые элементы страницы.
   Шесть штук и ни одного седьмого без записи в DESIGN_SYSTEM.md.
   Секция не имеет права ввести собственный компонент. */

/* ---------- .btn — кнопка ----------
   На экране ровно один .btn--primary. Второе действие всегда .btn--ghost. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--as-s2);
  min-height: var(--as-ctrl-h);
  padding-inline: var(--as-ctrl-pad);
  border: var(--as-hairline) solid transparent;
  border-radius: var(--as-radius-control);
  font-size: var(--as-fs-btn);
  font-weight: var(--as-w-medium);
  letter-spacing: var(--as-tr-btn);
  line-height: var(--as-lh-flat);
  text-transform: uppercase;
  text-align: center;
  transition:
    background-color var(--as-dur-fast) var(--as-ease),
    border-color var(--as-dur-fast) var(--as-ease),
    color var(--as-dur-fast) var(--as-ease);
}

.btn--primary {
  background: var(--as-accent-500);
  color: var(--as-cream-50);
}

.btn--primary:hover {
  background: var(--as-accent-400);
  color: var(--as-base-900);
}

.btn--ghost {
  background: transparent;
  border-color: var(--as-line-on-dark);
  color: var(--as-text-on-dark);
}

.btn--ghost:hover {
  background: var(--as-base-700);
}

.on-light .btn--ghost {
  border-color: var(--as-line-on-light);
  color: var(--as-text-on-light);
}

.on-light .btn--ghost:hover {
  background: var(--as-cream-100);
}

.btn--sm {
  min-height: var(--as-ctrl-h-sm);
  padding-inline: var(--as-s5);
}

.btn[aria-disabled="true"],
.btn:disabled {
  opacity: var(--as-opacity-disabled);
  pointer-events: none;
}

/* ---------- Нажатое состояние переключателя ----------
   Состояние, объявленное в разметке, обязано быть видно на экране:
   aria-pressed — не подсказка скринридеру, а вид кнопки. Подложка активного
   состояния — --as-accent-soft, токен заведён ровно под этот случай.
   Приём тот же, что у наведения: цвет и граница, ни теней, ни сдвигов. */
.btn[aria-pressed="true"] {
  background: var(--as-accent-soft);
  border-color: var(--as-accent-400);
  color: var(--as-text-on-dark);
}

.btn[aria-pressed="true"]:hover {
  background: var(--as-accent-soft);
  border-color: var(--as-accent-500);
}

.on-light .btn[aria-pressed="true"] {
  border-color: var(--as-accent-500);
  color: var(--as-text-on-light);
}

.on-light .btn[aria-pressed="true"]:hover {
  background: var(--as-accent-soft);
  border-color: var(--as-accent-500);
}

/* ---------- .claim — статус утверждения ----------
   Несущий элемент бренда (BR-026), а не оговорка мелким шрифтом.
   Текст метки приходит из разметки; здесь только форма и цвет. */
.claim {
  display: inline-flex;
  align-items: center;
  gap: var(--as-s2);
  padding: var(--as-s1) var(--as-s3);
  border: var(--as-hairline) solid var(--as-line-on-dark);
  border-radius: var(--as-radius-control);
  font-size: var(--as-fs-micro);
  font-weight: var(--as-w-medium);
  letter-spacing: var(--as-tr-micro);
  line-height: var(--as-lh-flat);
  text-transform: uppercase;
  color: var(--as-text-on-dark-mute);
  white-space: nowrap;
}

.claim::before {
  content: "";
  width: var(--as-s2);
  height: var(--as-s2);
  border-radius: var(--as-radius-control);
  background: currentColor;
}

.claim[data-claim="fact"] {
  color: var(--as-text-on-dark);
  border-color: var(--as-line-on-dark);
}

.claim[data-claim="building"] {
  color: var(--as-accent-400);
  border-color: var(--as-accent-400);
}

.claim[data-claim="planned"] {
  color: var(--as-text-on-dark-mute);
  border-style: dashed;
}

/* «Со слов» — четвёртое значение легенды. Первые три говорят о типе утверждения,
   это — об источнике: переписка без документа. Уверенность источника тремя
   значениями не выражалась вовсе (D01). Пунктир занят, поэтому точки —
   и точка метки полая: подтверждения ещё нет. */
.claim[data-claim="stated"] {
  color: var(--as-text-on-dark-mute);
  border-style: dotted;
}

.claim[data-claim="stated"]::before {
  background: transparent;
  box-shadow: inset 0 0 0 1px currentColor;
}

.on-light .claim {
  color: var(--as-text-on-light-mute);
  border-color: var(--as-line-on-light);
}

.on-light .claim[data-claim="fact"] {
  color: var(--as-text-on-light);
}

.on-light .claim[data-claim="building"] {
  color: var(--as-accent-500);
  border-color: var(--as-accent-500);
}

.on-light .claim[data-claim="stated"] {
  color: var(--as-text-on-light-mute);
}

/* ---------- .slot — место будущего медиа ----------
   Слот несёт три вещи: что за кадр, в каком размере, какой статус (R37i).
   Серых прямоугольников на странице нет. */
.slot {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--as-s2);
  padding: var(--as-pad-plane);
  aspect-ratio: var(--as-ratio-wide);
  background: var(--as-base-700);
  border: var(--as-hairline) solid var(--as-line-on-dark);
  border-radius: var(--as-radius-flat);
  overflow: hidden;
}

.slot--tall { aspect-ratio: var(--as-ratio-tall); }
.slot--square { aspect-ratio: var(--as-ratio-square); }
.slot--bleed { aspect-ratio: auto; min-height: var(--as-bleed-h); }

.on-light .slot {
  background: var(--as-cream-100);
  border-color: var(--as-line-on-light);
}

.slot__what {
  position: relative;
  z-index: var(--as-z-media);
  font-size: var(--as-fs-lead);
  line-height: var(--as-lh-lead);
  font-weight: var(--as-w-medium);
  max-width: var(--as-measure);
}

.slot__meta {
  position: relative;
  z-index: var(--as-z-media);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--as-s3);
  font-size: var(--as-fs-micro);
  letter-spacing: var(--as-tr-micro);
  text-transform: uppercase;
  color: var(--as-text-on-dark-mute);
}

.on-light .slot__meta {
  color: var(--as-text-on-light-mute);
}

/* Чертёжная штриховка — единственный несущий фон слота (приём Дом Дау) */
.slot::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: repeating-linear-gradient(
    135deg,
    var(--as-line-on-dark) 0,
    var(--as-line-on-dark) 1px,
    transparent 1px,
    transparent var(--as-s5)
  );
  pointer-events: none;
}

.on-light .slot::before {
  background-image: repeating-linear-gradient(
    135deg,
    var(--as-line-on-light) 0,
    var(--as-line-on-light) 1px,
    transparent 1px,
    transparent var(--as-s5)
  );
}

/* ---------- .rule — разделитель ----------
   Единственный тип линии на странице. Либо отделяет, либо указывает. */
.rule {
  display: block;
  width: 100%;
  height: var(--as-rule-weight);
  border: 0;
  background: var(--as-line-on-dark);
}

.on-light .rule {
  background: var(--as-line-on-light);
}

.rule--vertical {
  width: var(--as-rule-weight);
  height: auto;
  align-self: stretch;
}

/* ---------- .marker — микро-метка блока ----------
   «01 / МЕСТО». Держит ритм и заменяет декор. */
.marker {
  display: flex;
  align-items: center;
  gap: var(--as-s3);
  font-size: var(--as-fs-micro);
  font-weight: var(--as-w-medium);
  letter-spacing: var(--as-tr-micro);
  line-height: var(--as-lh-flat);
  text-transform: uppercase;
  color: var(--as-text-on-dark-mute);
}

.on-light .marker {
  color: var(--as-text-on-light-mute);
}

.marker__num {
  color: var(--as-accent-400);
}

.on-light .marker__num {
  color: var(--as-accent-500);
}

.marker::after {
  content: "";
  flex: 1 1 auto;
  height: var(--as-rule-weight);
  background: var(--as-line-on-dark);
}

.on-light .marker::after {
  background: var(--as-line-on-light);
}

/* ---------- .field — поле формы ---------- */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--as-s2);
}

.field__label {
  font-size: var(--as-fs-micro);
  letter-spacing: var(--as-tr-micro);
  text-transform: uppercase;
  color: var(--as-text-on-dark-mute);
}

.on-light .field__label {
  color: var(--as-text-on-light-mute);
}

.field__control {
  width: 100%;
  min-height: var(--as-ctrl-h);
  padding: var(--as-s3) 0;
  background: transparent;
  border: 0;
  border-bottom: var(--as-hairline) solid var(--as-line-on-dark);
  border-radius: 0;
  color: var(--as-text-on-dark);
  font-size: var(--as-fs-lead);
  transition: border-color var(--as-dur-fast) var(--as-ease);
}

.on-light .field__control {
  border-bottom-color: var(--as-line-on-light);
  color: var(--as-text-on-light);
}

.field__control::placeholder {
  color: var(--as-text-on-dark-mute);
}

.on-light .field__control::placeholder {
  color: var(--as-text-on-light-mute);
}

.field__control:hover {
  border-bottom-color: var(--as-accent-400);
}

.field__note {
  font-size: var(--as-fs-micro);
  color: var(--as-text-on-dark-mute);
}

.on-light .field__note {
  color: var(--as-text-on-light-mute);
}

.field[data-state="error"] .field__control {
  border-bottom-color: var(--as-accent-400);
}

.field[data-state="error"] .field__note {
  color: var(--as-accent-400);
}

.on-light .field[data-state="error"] .field__note {
  color: var(--as-accent-500);
}

/* Флажок — тот же .field, а не седьмой компонент: размер, акцент и вид ошибки
   живут здесь, рядом с остальными состояниями поля. */
.field__check {
  flex: 0 0 auto;
  width: var(--as-s5);
  height: var(--as-s5);
  margin: 0;
  accent-color: var(--as-accent-400);
}

.on-light .field__check {
  accent-color: var(--as-accent-500);
}

.field[data-state="error"] .field__check {
  outline: var(--as-hairline) solid var(--as-accent-400);
  outline-offset: var(--as-focus-offset);
}

.on-light .field[data-state="error"] .field__check {
  outline-color: var(--as-accent-500);
}

/* ---------- .entry — повторяемая карточка ----------
   Одна и та же фигура на всей странице: метка → имя → текст → .claim.
   Блоки собирали её каждый у себя; отличались только шагом, поэтому шаг —
   единственный модификатор. Карточки блоков 05 и 07 переезжают сюда же. */
.entry {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--as-s3);
}

.entry--tight { gap: var(--as-s2); }
.entry--loose { gap: var(--as-s5); }

/* Скрытие карточки — общее правило [hidden] в base.css. Своего здесь нет. */

/* ---------- Видимая заглушка ----------
   Пустое место, которое ждёт своего таска, обязано быть видно.
   Заглушка не притворяется отсутствием блока и называет, чего не хватает. */
[data-placeholder]:empty::before {
  content: "Заглушка · " attr(data-placeholder);
  display: block;
  padding: var(--as-s3) var(--as-s4);
  border: var(--as-hairline) dashed var(--as-line-on-dark);
  border-radius: var(--as-radius-flat);
  font-size: var(--as-fs-micro);
  font-weight: var(--as-w-medium);
  letter-spacing: var(--as-tr-micro);
  line-height: var(--as-lh-flat);
  text-transform: uppercase;
  color: var(--as-text-on-dark-mute);
}

.on-light [data-placeholder]:empty::before {
  border-color: var(--as-line-on-light);
  color: var(--as-text-on-light-mute);
}

/* ---------- Шапка ----------
   Живёт здесь, а не в sections.css: она повторяемый элемент, а не блок. */
.header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: var(--as-z-header);
  height: var(--as-header-h);
  display: flex;
  align-items: center;
  background: transparent;
  border-bottom: var(--as-hairline) solid transparent;
  transition:
    background-color var(--as-dur-fast) var(--as-ease),
    border-color var(--as-dur-fast) var(--as-ease);
}

.header[data-scrolled="true"] {
  background: var(--as-base-900);
  border-bottom-color: var(--as-line-on-dark);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--as-s5);
  width: 100%;
}

/* Лого — текстовое начертание: файлов логотипа в комплекте нет (BR-031) */
.header__logo {
  font-size: var(--as-fs-btn);
  font-weight: var(--as-w-semibold);
  letter-spacing: var(--as-tr-micro);
  text-transform: uppercase;
  white-space: nowrap;
}

.header__nav {
  display: flex;
  align-items: center;
  gap: var(--as-s6);
}

.header__link {
  font-size: var(--as-fs-micro);
  font-weight: var(--as-w-medium);
  letter-spacing: var(--as-tr-micro);
  text-transform: uppercase;
  color: var(--as-text-on-dark-mute);
  transition: color var(--as-dur-fast) var(--as-ease);
}

.header__link:hover {
  color: var(--as-text-on-dark);
}

/* Кнопка мобильного меню. На десктопе её нет. */
.header__burger {
  display: none;
  min-height: var(--as-ctrl-h-sm);
  min-width: var(--as-ctrl-h-sm);
  align-items: center;
  justify-content: center;
  color: var(--as-text-on-dark);
  font-size: var(--as-fs-micro);
  letter-spacing: var(--as-tr-micro);
  text-transform: uppercase;
}

/* ---------- .rail — горизонтальная лента ----------
   Одна форма на все места, где кадры не влезают в ширину экрана: nowrap,
   родная инерция, scroll-snap по кадрам и спрятанная полоса прокрутки.
   Стрелок и точек нет — о продолжении сообщает видимый край следующего
   кадра, поэтому кадр уже контейнера (--as-frame-sm).
   Модификатор --bleed дотягивает ленту до края экрана: край следующего
   кадра начинается от края, а не от поля страницы. */
.rail {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.rail::-webkit-scrollbar {
  display: none;
}

.rail > * {
  flex: 0 0 auto;
  scroll-snap-align: start;
}

.rail--bleed {
  margin-inline: calc(var(--as-gutter-sm) * -1);
  padding-inline: var(--as-gutter-sm);
}

/* Мобильное меню — панель, а не выпадашка */
.menu {
  position: fixed;
  inset: 0;
  z-index: var(--as-z-menu);
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: var(--as-s5);
  padding: var(--as-gutter-sm);
  background: var(--as-base-900);
}

.menu[data-open="true"] {
  display: flex;
}

/* Ниже 600px панель — единственный способ перейти по разделам, поэтому её
   пункт держит ту же область нажатия, что и остальные управляющие элементы:
   кегль h2 при интерлиньяже текста даёт строку около 35px, этого мало. */
.menu__link {
  display: flex;
  align-items: center;
  min-height: var(--as-ctrl-h-sm);
  font-size: var(--as-fs-h2);
  font-weight: var(--as-w-medium);
  letter-spacing: var(--as-tr-head);
  text-transform: uppercase;
}

.menu__close {
  position: absolute;
  inset-block-start: var(--as-gutter-sm);
  inset-inline-end: var(--as-gutter-sm);
  min-height: var(--as-ctrl-h-sm);
  min-width: var(--as-ctrl-h-sm);
  font-size: var(--as-fs-micro);
  letter-spacing: var(--as-tr-micro);
  text-transform: uppercase;
}

/* Закреплённая нижняя панель — одно действие, только на телефоне */
.sticky-cta {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: var(--as-z-sticky);
  display: none;
  align-items: center;
  gap: var(--as-s4);
  min-height: var(--as-sticky-h);
  padding: var(--as-s3) var(--as-gutter-sm);
  background: var(--as-base-800);
  border-top: var(--as-hairline) solid var(--as-line-on-dark);
  transform: translate3d(0, 100%, 0);
  transition: transform var(--as-dur-fast) var(--as-ease);
  /* Уехавшая за край панель не просто не видна — её нет:
     иначе её ссылка остаётся в порядке табуляции и человек
     с клавиатуры попадает в пустоту под экраном. */
  visibility: hidden;
}

.sticky-cta[data-visible="true"] {
  transform: translate3d(0, 0, 0);
  visibility: visible;
}

.sticky-cta .btn {
  flex: 1 1 auto;
}

/* Футер */
.footer {
  background: var(--as-base-800);
  border-top: var(--as-hairline) solid var(--as-line-on-dark);
  padding-block: var(--as-rhythm-tight);
  color: var(--as-text-on-dark-mute);
  font-size: var(--as-fs-micro);
  letter-spacing: var(--as-tr-body);
}

/* ---------- Раскрываемая позиция ----------
   Состояние аккордеона объявлено в aria-expanded — значит, оно обязано быть
   видно и глазом. Указатель нарисован тем же волоском, что и остальные линии
   страницы: ни иконки, ни кружка, ни тени. Поворот не анимируется — §7
   оставляет в движении только прозрачность и одно смещение; меняется цвет. */
[data-accordion-trigger]::after {
  content: "";
  flex: 0 0 auto;
  align-self: center;
  margin-inline-start: auto;
  width: var(--as-s3);
  height: var(--as-s3);
  border-right: var(--as-hairline) solid currentColor;
  border-bottom: var(--as-hairline) solid currentColor;
  transform: rotate(45deg);
  transition: border-color var(--as-dur-fast) var(--as-ease);
}

[data-accordion-trigger][aria-expanded="true"]::after {
  transform: rotate(-135deg);
  border-color: var(--as-accent-400);
}

.on-light [data-accordion-trigger][aria-expanded="true"]::after {
  border-color: var(--as-accent-500);
}

/* Укачивание: смена состояния становится мгновенной, а не исчезает.
   Своих длительностей здесь нет — только те, что уже есть в motion.css. */
@media (prefers-reduced-motion: reduce) {
  .btn,
  [data-accordion-trigger]::after {
    transition: none;
  }

  /* Закреплённая панель не выезжает снизу: появляется и исчезает
     видимостью. Трансформация снята в обоих состояниях — под reduce
     движения не остаётся ни одного, а не «поменьше» (R12.1). */
  .sticky-cta,
  .sticky-cta[data-visible="true"] {
    transform: none;
    transition: none;
  }
}

/* ---------- Свёрнутое до первого кадра ----------
   Панели интерактивов стоят в разметке раскрытыми — без скрипта страница
   обязана читаться целиком, и hidden там не появляется. Но сворачивает их
   filters.js на DOMContentLoaded, а нарисовать браузер вправе раньше:
   человек уже читает, и блок схлопывается под ним. Приём тот же, что
   у появления: инлайн-скрипт в <head> ставит класс на <html> до первой
   отрисовки, эти два правила читаются сразу, а filters.js снимает класс
   в том же кадре, в котором расставил hidden. Модуль не поднялся — класс
   снимает страховка на load, и содержимое остаётся видимым.

   Что именно свёрнуто, объявляет сама разметка: у слоёв виден первый
   (они накопительные, и стартовый уровень — нижний), у аккордеона —
   тот раздел, что помечен data-accordion-default="open". */
html.as-panels [data-layer-panel] ~ [data-layer-panel] {
  display: none;
}

html.as-panels [data-accordion-item]:not([data-accordion-default="open"]) [data-accordion-panel] {
  display: none;
}
