/*
  Базовые стили — mobile-first, от 360px. Цвет, шрифты и размеры — только через
  токены tokens.css (AGENTS.md, инвариант 9: без Tailwind, стили — CSS custom
  properties из токенов mvp.md). Подключение — _Layout.cshtml, после tokens.css
  и fonts.css.
*/

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-size: 100%; /* база — 16px, дальше всё в rem/em */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* clip, не hidden: без горизонтальной прокрутки на телефоне (AGENTS.md, инвариант 8), но в
     отличие от hidden не ломает position: sticky у боковой колонки (M8-1) — с hidden «липкий»
     элемент просто уезжает вместе со страницей вместо того, чтобы остаться на месте. */
  overflow-x: clip;
}

body {
  margin: 0;
  overflow-x: clip;
  /* Колонка на всю высоту окна — подвал прижат к низу на коротких страницах (M8-1: хаб
     /znacheniya, 404 и т.п.), растягивается только .site-main (flex: 1 0 auto ниже). dvh —
     с учётом скрывающейся адресной строки мобильного браузера; vh — фолбэк постарше. */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--text-body);
  font-weight: var(--font-weight-regular);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
  height: auto;
}

/* Типографика */

h1,
h2,
h3 {
  margin: 0 0 var(--space-4);
  font-family: var(--font-display);
  font-weight: var(--font-weight-regular);
  line-height: var(--leading-heading);
  color: var(--ink);
}

h1 {
  font-size: var(--text-h1);
}

h2 {
  font-size: var(--text-h2);
}

h3 {
  font-size: var(--text-h3);
}

h4,
h5,
h6 {
  margin: 0 0 var(--space-3);
  font-family: var(--font-text);
  font-size: var(--text-body);
  font-weight: var(--font-weight-semibold);
  color: var(--ink);
}

p {
  margin: 0 0 var(--space-4);
}

p:last-child {
  margin-bottom: 0;
}

small,
.text-small {
  font-size: var(--text-small);
}

.text-soft {
  color: var(--ink-soft);
}

code,
kbd,
samp,
.mono {
  font-family: var(--font-mono);
  font-size: var(--text-mono);
}

a {
  color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

a:hover {
  text-decoration-thickness: 2px;
}

/* Фокус — виден всегда с клавиатуры, не зависит от цвета линии
   (design-2026-09.md, раздел 6; AGENTS.md, инвариант 11) */

:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}

/* Skip-link — первый фокусируемый элемент страницы */

.skip-link {
  position: absolute;
  left: var(--space-3);
  top: -3rem;
  z-index: 1000;
  padding: var(--space-2) var(--space-4);
  background: var(--accent);
  color: var(--on-accent);
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-weight: var(--font-weight-medium);
  transition: top var(--transition-fast);
}

.skip-link:focus-visible {
  top: var(--space-3);
}

/* Рамка страницы (M8-1, решение 20 в mvp.md) — одна и та же ширина и боковые поля у шапки,
   основного содержимого и подвала: их левые (и правые) края совпадают на любой странице. Раньше
   у main был свой узкий дефолт (--content-width) и отдельный широкий модификатор
   .site-main--wide через ViewData["WideMain"] — из-за этого на десктопе шапка была шире
   контента. Теперь ширину внутри main задают сами страницы (примитивы раскладки ниже:
   .layout-main-aside, .reading-column, .layout-narrow — или локальная разметка страницы). */

.site-header__inner,
.site-main,
.site-footer__inner {
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.site-header {
  border-bottom: var(--line-width) solid var(--line);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-3);
  flex-wrap: nowrap; /* шапка — в одну строку и на 360 px (M8-1) */
}

.site-header__brand {
  /* Единственный, кому в шапке можно сжиматься (по умолчанию flex-shrink: 1) — у навигации и
     переключателя темы ниже flex-shrink: 0, у них фиксированный необходимый размер. min-width:0
     разрешает сжаться меньше текстового содержимого, overflow+ellipsis показывают «…», если
     длинное название бренда (Brand:Name из конфигурации) всё же не поместится. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: var(--font-display);
  font-size: 1.375rem;
  color: var(--ink);
  text-decoration: none;
}

/* Группа справа от логотипа — навигация персональных страниц (если есть) и переключатель темы.
   flex-shrink: 0 — на самой группе и на её детях ниже (.site-header__nav, .theme-toggle):
   без этого при нехватке места на 360 px flex сжимал бы кнопку темы уже её текста, и подпись
   вылезала бы за скруглённую рамку, а не переносилась (сам текст не переносится — white-space:
   nowrap). Сжимается только логотип слева (у него на этот случай свой text-overflow: ellipsis). */
.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

/* Навигация «Карта · Сегодня» (mvp.md, «Дизайн: поправки», п. 10) — только на персональных
   страницах, когда _Layout.cshtml получил ViewData["ChartNavId"] (см. docstring там же). */
.site-header__nav {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  gap: var(--space-2);
  font-size: var(--text-small);
  white-space: nowrap;
}

.site-header__nav-link {
  color: var(--ink-soft);
  text-decoration: none;
  padding: var(--space-1) 0;
}

.site-header__nav-link:hover {
  color: var(--ink);
}

/* Видимая отметка текущего пункта — не только aria-current="page" для скринридеров
   (AGENTS.md, инвариант 11: доступность), но и заметный глазом стиль. */
.site-header__nav-link[aria-current="page"] {
  color: var(--ink);
  font-weight: var(--font-weight-semibold);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.site-header__nav-sep {
  color: var(--ink-soft);
}

.site-main {
  flex: 1 0 auto; /* растягивается, подвал остаётся внизу окна на коротких страницах */
  /* Без этого — реальный баг (M8-1, приёмка): main лежит поперечным элементом flex-колонки
     body, а margin-inline: auto (общее правило выше) — это auto-отступы по поперечной оси.
     Flexbox отдаёт лишнее место именно им вместо стандартного stretch, поэтому шире width:auto
     не становится, а получает fit-content — ширину по своему содержимому (пока не упрётся в
     max-width). Из-за этого страницы с содержимым уже 72rem (например, старая колонка «Сегодня»
     или карта) получали main уже рамки и по центру, вместо полной ширины с полями по бокам —
     левый край съезжал вправо от логотипа. width: 100% в дополнение к max-width — фиксирует
     ширину контейнера прежде, чем считаются auto-отступы, и stretch больше не нужен. */
  width: 100%;
  padding-block: var(--space-6) var(--space-8);
}

.site-footer {
  flex-shrink: 0;
  border-top: var(--line-width) solid var(--line);
  margin-top: var(--space-8);
}

.site-footer__inner {
  padding-block: var(--space-5);
}

.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin: 0 0 var(--space-4);
  padding: 0;
  list-style: none;
  font-size: var(--text-small);
}

.site-footer__links a {
  color: var(--ink-soft);
}

.site-footer__disclaimer {
  margin: 0 0 var(--space-3);
  color: var(--ink-soft);
  font-size: var(--text-small);
}

.site-footer__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
  color: var(--ink-soft);
  font-size: var(--text-small);
}

.site-footer__badge {
  display: inline-block;
  padding: 0.1em 0.5em;
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  color: var(--ink);
}

@media (min-width: 64rem) {
  /* 1024px — «десктоп» по mvp.md */
  :root {
    --gutter: var(--space-6);
  }
}

/* Примитивы раскладки (M8-1, mvp.md «Дизайн: поправки», п. 10) — общие для задач M8-2…M8-4:
   страница карты, «Сегодня», SEO-статья, шеринг, юридические документы и /source. Размеры —
   токены tokens.css (--page-max, --reading-width, --content-width-narrow, --aside-min).
   Везде порядок в DOM = визуальный порядок: раскладка никогда не использует CSS order, поэтому
   фокус с клавиатуры идёт так же, как видно глазами. */

/* «Основная + боковая колонка» — одна колонка до 768 px, с 768 px — две колонки ≈ 7:5 с разумным
   минимумом у боковой (--aside-min). Какой ребёнок в DOM идёт первым — тот и слева: обычно это
   .layout-main-aside__main (карта, «Сегодня», SEO-статья, шеринг — боковая справа), но для
   юридических документов и /source боковая (навигация) в DOM идёт первой и должна остаться
   слева — для этого модификатор --aside-start меняет местами ширины колонок, а не порядок
   элементов. */
.layout-main-aside {
  display: grid;
  gap: var(--space-6);
}

@media (min-width: 48rem) {
  /* 768 px — mvp.md «Десктоп и планшет» */
  .layout-main-aside {
    grid-template-columns: minmax(0, 7fr) minmax(var(--aside-min), 5fr);
    align-items: start;
  }

  .layout-main-aside__main {
    grid-column: 1;
  }

  .layout-main-aside__aside {
    grid-column: 2;
  }

  /* Ведущая боковая колонка (список документов, оглавление) — не доля 7:5, а узкая
     фиксированная ширина: список ссылок не должен раздуваться вместе с окном так же, как
     карточки боковой панели карты/итога. Единственные потребители --aside-start сейчас —
     юридические документы и /source, обоим нужна именно такая, лёгкая по виду навигация
     (см. правила .legal__nav в legal.css). */
  .layout-main-aside--aside-start {
    grid-template-columns: minmax(var(--aside-min), var(--aside-nav-max)) minmax(0, 1fr);
  }

  .layout-main-aside--aside-start .layout-main-aside__aside {
    grid-column: 1;
  }

  .layout-main-aside--aside-start .layout-main-aside__main {
    grid-column: 2;
  }

  /* Модификатор «липкая боковая» — остаётся на экране при прокрутке основной колонки, только от
     768 px (на мобиле одна колонка, «липкость» не нужна и мешала бы прокрутке страницы). Внутри
     себя боковая колонка прокручивается, если не помещается по высоте окна. */
  .layout-main-aside__aside--sticky {
    position: sticky;
    top: var(--space-6);
    max-height: calc(100dvh - var(--space-6) * 2);
    overflow-y: auto;
  }

  /* «Большая тройка» (.big-three, css/chart.css) переключается на 3 колонки от 40rem viewport
     сама по себе, не зная о ширине своего контейнера. В узкой боковой колонке (≈ --aside-min…
     5fr) это слишком тесно — карточка с длинным заголовком вроде «Асцендент в Раке» не
     помещается. Пока эта раскладка не нужна самой странице карты (см. задачу M8-2), здесь —
     точечный, более специфичный селектор поверх chart.css, без правки самого файла. */
  .layout-main-aside__aside .big-three {
    grid-template-columns: 1fr;
  }

  /* Шеринг (Views/Share/Index.cshtml) — колесо главное на странице, а .chart__wheel-wrap из
     chart.css ограничивает его 28rem вне зависимости от того, сколько места есть в основной
     колонке (этот файл правим только правилом summary — сама раскладка карты ещё будет
     переделана в M8-2). Составной селектор — специфичнее одного класса .chart__wheel-wrap, чтобы
     выигрывать независимо от того, что site.css подключён раньше chart.css. Ширина не только от
     колонки, но и от доступной высоты окна (колесо квадратное) — чтобы оно целиком помещалось в
     первый экран вместе с заголовком и вступлением над ним (≈ 14rem: шапка + h1 + абзац + отступы). */
  .chart__wheel-wrap.share-wheel {
    max-width: none;
    width: min(100%, calc(100dvh - 14rem));
    margin-inline: 0;
  }
}

/* «Колонка чтения» — связный текст (итог по карте, SEO-статья, юридический документ) не шире
   40rem (65–75 знаков в строке), даже если колонка, в которой он лежит, шире. */
.reading-column {
  max-width: var(--reading-width);
}

/* «Узкая центрированная колонка» — формы и одноэкранные страницы (404, 500, fake door,
   устаревшая ссылка бота, «Изменить данные», «Удалить мои данные»): по центру рамки, а не во
   всю ширину. */
.layout-narrow {
  max-width: var(--content-width-narrow);
  margin-inline: auto;
}

/* Кнопки */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-5);
  border: var(--line-width) solid transparent;
  border-radius: var(--radius-md);
  font: inherit;
  font-weight: var(--font-weight-medium);
  text-decoration: none;
  cursor: pointer;
  transition: filter var(--transition-fast), background-color var(--transition-fast);
  -webkit-appearance: none;
  appearance: none;
}

.btn--primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.btn--primary:hover {
  filter: brightness(1.08);
}

.btn--primary:active {
  filter: brightness(0.94);
}

.btn--secondary {
  background: transparent;
  border-color: var(--accent);
  color: var(--accent);
}

.btn--secondary:hover {
  background: var(--surface);
}

/* Заглушки M5 (шеринг, «Полный разбор» — задание M2-3) используют disabled, а не мёртвую
   ссылку: без этого правила .btn--secondary выглядит как обычная активная кнопка. */
.btn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

.btn--secondary:disabled:hover {
  background: transparent;
}

/* Поля форм */

label {
  display: block;
  margin-bottom: var(--space-2);
  color: var(--ink-soft);
  font-size: var(--text-small);
}

input[type="text"],
input[type="email"],
input[type="search"],
input[type="tel"],
input[type="date"],
input[type="time"],
textarea,
select {
  width: 100%;
  min-height: 44px;
  padding: var(--space-3);
  background: var(--surface);
  color: var(--ink);
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 1rem;
}

input::placeholder,
textarea::placeholder {
  color: var(--ink-soft);
  opacity: 1;
}

.checkbox {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--ink);
  cursor: pointer;
}

.checkbox input[type="checkbox"] {
  width: 1.25rem;
  height: 1.25rem;
  /* Только левый/правый отступ: браузерный UA-стиль даёт чекбоксу несимметричный margin
     (больше слева) — из-за него квадрат чекбокса не совпадал с левым краем текстовых полей
     формы (M8-1). Вертикальный margin не трогаем — .landing-form__consent сам подвинул чекбокс
     по верху для двухстрочной подписи (landing.css), это должно остаться как есть. */
  margin-inline: 0;
  accent-color: var(--accent);
}

/* Маркер раскрытия <details> — общий для всех summary (FAQ на лендинге, «Расширенный вид» на
   карте и т.п., M8-1). Не полагаемся на псевдоэлемент ::marker: он рисуется только пока summary
   остаётся display: list-item (умолчание браузера) и пропадает, если странице нужен
   display: flex — например, чтобы прижать строку к min-height: 44px и выровнять текст по
   центру (см. правила summary в landing.css и chart.css). Свой шеврон на ::before работает в
   обоих случаях, потому что не зависит от display самого summary. */
details > summary {
  list-style: none;
}

details > summary::-webkit-details-marker {
  display: none; /* Safari рисует свой треугольник отдельно от ::marker — прячем и его */
}

details > summary::before {
  content: "";
  flex-shrink: 0;
  width: 0;
  height: 0;
  margin-right: var(--space-3);
  border-style: solid;
  border-width: 0.32em 0 0.32em 0.42em;
  border-color: transparent transparent transparent var(--accent);
  transition: transform var(--transition-fast);
}

details[open] > summary::before {
  transform: rotate(90deg);
}

/* Карточки — волосяная граница вместо тени */

.card {
  background: var(--surface);
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  box-shadow: var(--shadow);
}

/* Строка-кнопка с глифом и подписью — список планет/аспектов на карте, активные транзиты на
   «Сегодня» (M1-4): общий компонент, чтобы не дублировать стиль в css/chart.css и css/today.css. */

.tap-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 44px;
  padding: var(--space-3);
  background: var(--surface);
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.tap-row:hover {
  background: var(--bg);
}

.tap-row.is-selected {
  border-color: var(--accent);
  font-weight: var(--font-weight-semibold);
}

.tap-row__glyphs {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
  color: var(--ink-soft);
}

.tap-row__label {
  font-size: var(--text-small);
}

/* Переключатель темы (wwwroot/js/theme.js) */

.theme-toggle {
  display: inline-flex;
  flex-shrink: 0; /* см. комментарий у .site-header__actions в этом файле (M8-1) */
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-md);
  color: var(--ink);
  font: inherit;
  font-size: var(--text-small);
  white-space: nowrap;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.theme-toggle:hover {
  background: var(--surface);
}

/* Солнце/Луна — спрайтовые глифы (wwwroot/img/glyphs.svg), а не Unicode (AGENTS.md, инвариант
   10); currentColor берёт цвет из color здесь, как и остальные тематизируемые глифы спрайта
   (см. докстринг wheel.css). Виден только один — тот, что соответствует текущей теме; переключает
   их та же логика на :root[data-theme]/@media, что красит токены в tokens.css, без участия JS. */
.theme-toggle__icon {
  flex-shrink: 0;
  width: 1.125rem;
  height: 1.125rem;
  color: var(--accent);
}

.theme-toggle__icon--dark {
  display: none;
}

:root[data-theme="dark"] .theme-toggle__icon--light {
  display: none;
}

:root[data-theme="dark"] .theme-toggle__icon--dark {
  display: block;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle__icon--light {
    display: none;
  }

  :root:not([data-theme="light"]) .theme-toggle__icon--dark {
    display: block;
  }
}

/* ≈400px — на 360/390 px шапка с навигацией «Карта · Сегодня» не оставляет переключателю места
   на подпись целиком (M8-1, приёмка: правый край кнопки вылезал за поле). Подпись прячем визуально
   (не display: none и не aria-hidden) — доступное имя кнопки остаётся тем же текстом, что видят
   на широких экранах, просто через тот же приём, что .visually-hidden в expert.css. */
@media (max-width: 24.9375rem) {
  .theme-toggle__label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

/* Витрина токенов (/prototype/tokens) — общие классы, могут пригодиться и вне неё */

.stack > * + * {
  margin-top: var(--space-6);
}

.token-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: var(--space-4);
}

.swatch {
  overflow: hidden;
  background: var(--surface);
  border: var(--line-width) solid var(--line);
  border-radius: var(--radius-md);
}

.swatch__color {
  height: 4rem;
}

.swatch__meta {
  padding: var(--space-3);
}

.swatch__name {
  display: block;
  font-weight: var(--font-weight-medium);
  color: var(--ink);
}

.swatch__value {
  display: block;
  margin-top: var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--text-mono);
  color: var(--ink-soft);
}

/* Заглушка главной страницы (Views/Home/Index.cshtml) */

.hero {
  padding-block: var(--space-6) var(--space-4);
}

.hero__note {
  color: var(--ink-soft);
}

/* Уведомление о cookie и Метрике (wwwroot/js/cookie-notice.js) — задание M6-1. В обычном потоке
   документа (не position: fixed), поэтому никогда не перекрывает контент на мобиле; скрыта
   атрибутом hidden, пока JS не решит её показать. */

.cookie-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2) var(--space-4);
  padding: var(--space-3) var(--gutter);
  background: var(--surface);
  border-bottom: var(--line-width) solid var(--line);
  color: var(--ink);
  font-size: var(--text-small);
  text-align: center;
}

.cookie-notice[hidden] {
  display: none;
}

.cookie-notice__text {
  margin: 0;
}

.cookie-notice__ok {
  flex-shrink: 0;
}

/* Уважаем системную настройку «меньше анимации» */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
