/*
Theme Name: Чембарисова
Description: Тема персонального сайта психолога Анастасии Чембарисовой. Прохладная база, тёплый акцент, одна колонка.
Author: melostnoi
Version: 0.1.0
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 8.2
Text Domain: chembarisova
*/

/* =========================================================================
   ТОКЕНЫ

   Именуются по роли, не по виду: --accent, а не --clay. Иначе при смене
   цвета имя начинает врать.

   Три состояния темы. Светлая палитра целиком живёт на голом :root —
   ни один цвет не определяется только внутри media-блока, иначе получается
   классический баг с нечитаемой страницей.
   ========================================================================= */

:root {
	/* Нейтральная шкала построена в OKLCH на одном тёплом тоне H=70.
	   Не кремовая бумага, а камень: тон 70° вместо 85° у кремовых шаблонов
	   и на 2 пункта светлоты плотнее — читается как плотная штукатурка,
	   а не как лист бумаги. */
	--surface:        #f5f0eb;
	--surface-band:   #ebe3db;   /* полоса секции: на 1.12:1 темнее фона */
	--surface-raised: #faf6f3;
	--surface-high:   #fefcfa;

	--ink:       #211c16;
	--ink-quiet: #666059;

	/* Акцент — глубокая жжёная сиена, а не средний терракот. У шаблонов
	   этой ниши глина светлотой около 0.63 и звучит как велнес-студия;
	   здесь 0.47 — тяжелее и спокойнее. Заодно на таком акценте белый
	   текст даёт 7.15:1, поэтому залитая кнопка работает без оговорок. */
	--accent:        #894432;
	--accent-strong: #733324;
	--accent-quiet:  rgba(137, 68, 50, .12);
	--link-underline: rgba(137, 68, 50, .7);   /* подчёркивание ссылок: 3.4:1 к фону, ссылка различима не только цветом */
	--cover-filter:  none;
	--on-accent:     #fefcfa;

	--rule: rgba(33, 28, 22, .14);

	/* Полоса фактов — свой токен, а не var(--ink). В тёмной теме --ink это
	   светлый цвет текста, и полоса превращалась в единственную почти белую
	   ленту во всю ширину под первым экраном — вспышку для того, кто открыл
	   сайт ночью. Тёмная тема не инверсия: там роль «самого сильного якоря»
	   играет самая светлая из тёмных поверхностей, а не белый. */
	--factbar-bg: var(--ink);
	--factbar-fg: var(--surface);

	--sans:  "Golos Text", ui-sans-serif, system-ui, sans-serif;
	--serif: "Cormorant", Georgia, "Times New Roman", serif;

	/* Шкала кегля. Fluid через clamp от пары «минимальный/максимальный вьюпорт»,
	   а не стопкой брейкпоинтов. Отношение крупнейшего к тексту — 4×. */
	--text-xs:   0.8125rem;
	--text-s:    0.9375rem;
	--text-base: clamp(1.0625rem, 0.35vw + 1rem, 1.125rem);
	--text-m:    clamp(1.25rem, 0.6vw + 1.1rem, 1.4rem);
	--text-l:    clamp(1.5rem, 1.4vw + 1.1rem, 2rem);
	--text-xl:   clamp(2rem, 3.4vw + 1rem, 2.75rem);
	/* Нижняя граница подобрана замером, а не на глаз: на колонке 295px
	   при 46px заголовок ломался на 6 строк с сиротой в 101px («почву»
	   отдельной строкой), при 42px — 5 строк, 227px и ровный рваный край
	   [122, 216, 222, 231, 294]. text-wrap: pretty пробовал, хуже:
	   вставляет строку в 83–91px в середину. */
	--text-2xl:  clamp(2.625rem, 6.4vw + 0.6rem, 4.5rem);

	/* Шкала отступов. Сырой 13px должно быть невозможно написать незаметно. */
	--space-3xs: 0.25rem;
	--space-2xs: 0.5rem;
	--space-xs:  0.75rem;
	--space-s:   1rem;
	--space-m:   1.5rem;
	--space-l:   2.5rem;
	--space-xl:  4rem;
	--space-2xl: 6rem;
	/* Сокращён после появления полос: раньше пустота была единственным
	   разделителем секций и несла всю работу, теперь делит её с фоном
	   и разной структурой. Было clamp(6rem, 12vw, 9rem). */
	--space-3xl: clamp(4.5rem, 9vw, 7rem);

	--measure: 63ch;      /* мера строки: одна колонка, читается как письмо */
	--page:    min(100% - var(--space-l) * 2, 74rem);

	--ease: cubic-bezier(.2, .6, .2, 1);
	--dur-in:  240ms;
	--dur-out: 160ms;     /* выход ~65% от входа */
}

/* Тёмная — самостоятельный контекст, а не инверсия: четыре уровня
   поверхности, глубина светлотой, а не тенями, база L≈9%, текст не #FFF.
   Акцент осветляется: тёмная глина на тёмном фоне дала бы 3.68:1. */
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		--surface:        #181410;
		--surface-band:   #25201a;
		--surface-raised: #2a251f;
		--surface-high:   #37312a;
		--ink:            #ebe7e2;
		--ink-quiet:      #a8a29b;
		--accent:         #d6886a;
		--accent-strong:  #e6a68a;
		--accent-quiet:   rgba(214, 136, 106, .15);
		--link-underline: rgba(230, 166, 138, .7);
		--cover-filter:   brightness(.86) saturate(.92);   /* светлые иллюстрации на тёмном фоне слепят; чуть приглушить */
		--on-accent:      #181410;
		--rule:           rgba(235, 231, 226, .16);
		--factbar-bg:     var(--surface-high);
		--factbar-fg:     var(--ink);
	}
}

:root[data-theme="dark"] {
	--surface:        #181410;
	--surface-band:   #25201a;
	--surface-raised: #2a251f;
	--surface-high:   #37312a;
	--ink:            #ebe7e2;
	--ink-quiet:      #a8a29b;
	--accent:         #d6886a;
	--accent-strong:  #e6a68a;
	--accent-quiet:   rgba(214, 136, 106, .15);
	--link-underline: rgba(230, 166, 138, .7);
	--cover-filter:   brightness(.86) saturate(.92);
	--on-accent:      #181410;
	--rule:           rgba(235, 231, 226, .16);
	--factbar-bg:     var(--surface-high);
	--factbar-fg:     var(--ink);
}

/* =========================================================================
   БАЗА
   ========================================================================= */

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

html { -webkit-text-size-adjust: 100%; }

body {
	margin: 0;
	background: var(--surface);   /* явный фон: прозрачный body занял бы чужой */
	color: var(--ink);
	font-family: var(--sans);
	font-size: var(--text-base);
	line-height: 1.65;
	font-feature-settings: "kern", "liga";
	-webkit-font-smoothing: antialiased;
}

/* =========================================================================
   СИСТЕМА ЗАГОЛОВКОВ

   Два слоя, и это единственное правило, по которому выбирается шрифт:
   СЕРИФ говорит — им набраны утверждения и обращения к человеку.
   ГРОТЕСК называет — им набраны подписи, шаги и функциональные ярлыки.

   Раньше система расползалась: h3 в одних секциях был серифом, в других
   гротеском при одном кегле; серифные заголовки, заданные классом на <p>,
   не попадали под правило h1,h2,h3 и набирались с normal-трекингом,
   так что один шрифт того же размера выглядел по-разному в соседних
   блоках. Интерлиньяж разъезжался на пять разных отношений.

   Трекинг и интерлиньяж теперь заданы по ярусам: чем крупнее кегль,
   тем плотнее набор — как и положено серифу.
   ========================================================================= */

/* Ярус 1 — крупные утверждения. Один на экран. */
h1,
.opener__title {
	font-family: var(--serif);
	font-weight: 300;             /* края оси: 300 против 700 у гротеска */
	line-height: 1.08;
	letter-spacing: -0.015em;
	text-wrap: balance;
	margin: 0;
}
h1 { font-size: var(--text-2xl); }

/* Ярус 2 — заголовки секций и равные им по голосу. */
h2,
.section__lead,
.creed {
	font-family: var(--serif);
	/* 400, не 300: тонкий начерт при 24–32px на светлом фоне рассыпается
	   на Windows без сглаживания. 300 остаётся только у h1 — там кегль
	   достаточно крупный. */
	font-weight: 400;
	/* --text-l, а не --text-xl: на --text-xl заголовки секций выросли до
	   44px и сравнялись с заголовком обращения. Лестница должна быть
	   72 → 44 → 32 → 22, шаг примерно 1.5×. */
	font-size: var(--text-l);
	line-height: 1.2;
	letter-spacing: -0.01em;
	text-wrap: balance;
	margin: 0;
}

/* Ярус 3 серифный — короткие серифные врезки мелким кеглем. */

/* Ярус 3 гротескный — всё, что называет, а не говорит.
   Раньше .principle__term выпадал из этого ряда в сериф без причины. */
h3,
.topic__term,
.step__title,
.principle__term {
	font-family: var(--sans);
	font-weight: 700;
	font-size: var(--text-m);
	line-height: 1.32;
	letter-spacing: 0;
	text-wrap: balance;
	margin: 0;
}

p { margin: 0 0 var(--space-m); }
p:last-child { margin-bottom: 0; }

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

/* =========================================================================
   ССЫЛКИ И ФОКУС
   Никаких outline: none без замены — кольцо фокуса обязательно.
   ========================================================================= */

a {
	color: var(--accent-strong);
	text-decoration-color: var(--link-underline);
	text-underline-offset: 0.22em;
	text-decoration-thickness: 1px;
	transition: text-decoration-color var(--dur-in) var(--ease),
	            color var(--dur-in) var(--ease);
}
a:hover  { text-decoration-color: currentColor; }
a:active { color: var(--accent); }

:where(a, button, input, textarea, summary):focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 3px;
	border-radius: 2px;
}

/* На тач-устройствах hover не существует — ни одна подсказка не должна
   жить только в нём. Подчёркивание видно сразу. */
@media (hover: none), (pointer: coarse) {
	a { text-decoration-color: currentColor; }
}

/* =========================================================================
   РАСКЛАДКА
   Одна колонка. Не сетка карточек: блок «услуги» в виде трёх плиток с
   иконками превращает страницу психолога в прайс-лист.
   ========================================================================= */

.wrap { width: var(--page); margin-inline: auto; }
.measure { max-width: var(--measure); }

.section { padding-block: var(--space-3xl); }
.section + .section { border-top: 1px solid var(--rule); }

.section__lead { color: var(--ink); max-width: 30ch; }

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

/* =========================================================================
   ДВИЖЕНИЕ
   ========================================================================= */

@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;
	}
}

/* =========================================================================
   ШАПКА, ПОДВАЛ, СЛУЖЕБНОЕ
   ========================================================================= */

.skip {
	position: absolute;
	left: -9999px;
	top: var(--space-s);
	background: var(--surface-raised);
	color: var(--ink);
	padding: var(--space-2xs) var(--space-s);
	z-index: 10;
}
.skip:focus { left: var(--space-s); }

/* Отступ шапки сокращён, чтобы призыв в первом экране помещался над
   сгибом: при --space-l он оказывался на 748px при окне 720. */
.site-head { padding-block: var(--space-m); }
/* На узком экране шапка вставала столбиком высотой 214px и уводила
   первый экран вниз. Уточнение «в Telegram» прячется — рядом с именем
   психолога «Написать» однозначно. */
@media (max-width: 30rem) {
	.site-head__inner { gap: var(--space-s); }
	.btn__more { display: none; }
	.site-nav__list { gap: var(--space-s); }
	.site-nav .btn { padding-inline: var(--space-m); }
}
.site-head__inner {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-m);
	align-items: baseline;
	justify-content: space-between;
}
.site-head__name {
	font-family: var(--serif);
	font-size: var(--text-m);
	color: var(--ink);
	text-decoration: none;
	letter-spacing: 0.01em;
}
.site-head__name:hover { color: var(--accent-strong); }

.site-nav__list {
	display: flex;
	flex-wrap: wrap;
	/* center, а не stretch по умолчанию: оба <li> растягивались до 44px
	   по высоте кнопки, но ссылка «Статьи» (33px) прилипала к верху
	   своего li и её текст оказывался на 5.6px выше текста кнопки. */
	align-items: center;
	gap: var(--space-m);
	list-style: none;
	margin: 0;
	padding: 0;
	font-size: var(--text-s);
}
/* :not(.btn) обязателен: селектор «класс + элемент» специфичнее одного
   класса .btn и перекрашивал текст кнопки в цвет вторичного текста —
   контраст падал до 1.15:1, надпись становилась невидимой. */
.site-nav__list a:not(.btn) { color: var(--ink-quiet); text-decoration: none; }
.site-nav__list a:not(.btn):hover { color: var(--ink); }

.site-foot {
	border-top: 1px solid var(--rule);
	padding-block: var(--space-l);
	font-size: var(--text-s);
	color: var(--ink-quiet);
}
.site-foot__inner { display: flex; flex-wrap: wrap; gap: var(--space-m); justify-content: space-between; }
.site-foot p { margin: 0; }

/* =========================================================================
   ГЛАВНАЯ
   ========================================================================= */

/* Отступы сокращены: с прежними первый экран занимал 988px при окне 720,
   и призыв уходил за сгиб — главное действие сайта не было видно без
   прокрутки. */

/* Темы — определения, а не плитки. Волосяная линия вместо рамки. */
.topics { margin: var(--space-l) 0 0; display: grid; gap: 0; }
.topic {
	display: grid;
	gap: var(--space-2xs);
	padding-block: var(--space-m);
	border-top: 1px solid var(--rule);
	grid-template-columns: 1fr;
}
@media (min-width: 46rem) {
	.topic { grid-template-columns: minmax(0, 20ch) minmax(0, 46ch); gap: var(--space-l); align-items: start; }
}
.topic__term { font-weight: 700; color: var(--ink); }

.steps { margin: var(--space-l) 0 0; padding: 0; list-style: none; display: grid; gap: var(--space-m); }

/* =========================================================================
   SIGNATURE — уже начатое сообщение

   Не кнопка. Человек видит первую фразу уже написанной, и остаётся
   дописать одну свою — это снимает ровно тот барьер, который мешает.
   ========================================================================= */

/* Единственная точка конверсии на сайте. Стоит на полосе, чтобы читалась
   как отдельная зона действия, а не как ещё один абзац. */
.opener { max-width: 46rem; }
/* На главной обращение — финал страницы и звучит громче секций.
   На странице статьи оно опускается до яруса секций: иначе призыв
   кричал бы наравне с заголовком самой статьи (было 44 против 44). */
.opener__title { font-size: var(--text-l); max-width: 22ch; }
.home .opener__title { font-size: clamp(2rem, 3.2vw + 1rem, 2.75rem); }

.opener__link {
	display: block;
	margin-top: var(--space-l);
	text-decoration: none;
	color: var(--ink);
	max-width: 34rem;
}

.opener__bubble {
	display: block;
	padding: var(--space-m) var(--space-l);
	background: var(--surface-high);
	border: 1px solid var(--rule);
	/* Хвост справа-снизу: это реплика ПОСЕТИТЕЛЯ, исходящая. Раньше срез
	   стоял слева и по конвенции мессенджеров читался как входящее. */
	border-radius: 16px 16px 4px 16px;
	transition: border-color var(--dur-in) var(--ease),
	            box-shadow var(--dur-in) var(--ease);
}
.opener__link:hover .opener__bubble,
.opener__link:focus-visible .opener__bubble {
	border-color: var(--accent);
	box-shadow: 0 0 0 3px var(--accent-quiet);
}
.opener__link:active .opener__bubble { box-shadow: none; }

.opener__text { display: block; font-size: var(--text-m); line-height: 1.5; }

.opener__caret {
	display: inline-block;
	width: 2px;
	height: 1.1em;
	margin-left: 2px;
	vertical-align: text-bottom;
	background: var(--accent);
	animation: chb-caret 1.1s steps(1) infinite;
}
@keyframes chb-caret { 50% { opacity: 0; } }

/* Оформление берёт на себя .btn — здесь только положение. */
.opener__action { margin-top: var(--space-m); }

.opener__note { margin-top: var(--space-m); font-size: var(--text-s); color: var(--ink-quiet); }

/* =========================================================================
   СТАТЬИ
   ========================================================================= */

/* =========================================================================
   ЛЕНТА СТАТЕЙ

   Запись — это обложка плюс текст. Раньше лента шла голым текстом и
   читалась как оглавление, а не как чтение.
   ========================================================================= */

.entries { list-style: none; margin: var(--space-xl) 0 0; padding: 0; display: grid; gap: var(--space-xl); }
.entry { position: relative; padding: 0; border: 0; }
.entry__card { display: grid; gap: var(--space-m); align-items: start; }
@media (min-width: 44rem) {
	.entry__card { grid-template-columns: minmax(0, 15rem) minmax(0, 40rem); gap: var(--space-l); }
}

.entry__title { font-size: var(--text-l); color: var(--ink); }
/* Ссылка стоит только на заголовке, а кликабельна вся карточка через ::after:
   имя ссылки для читалки — один заголовок, а не обложка + дата + анонс
   (обложка в карточке декоративная, alt пустой). Кольцо фокуса — вокруг карточки. */
.entry__title a { color: inherit; text-decoration: none; }
.entry__title a::after { content: ""; position: absolute; inset: 0; border-radius: 14px; }
.entry:hover .entry__title a,
.entry__title a:focus-visible { color: var(--accent-strong); }
.entry__title a:focus-visible { outline: none; }
.entry__title a:focus-visible::after { outline: 2px solid var(--accent); outline-offset: 4px; }
.entry__meta { margin: var(--space-2xs) 0 0; font-size: var(--text-s); color: var(--ink-quiet); }
.entry__excerpt { margin-top: var(--space-s); color: var(--ink-quiet); }

/* -------------------------------------------------------------------------
   ОБЛОЖКА

   Раньше обложки в ленте были аркой того же силуэта, что портрет в первом
   экране. С появлением нарисованных обложек арка стала резать сцене верхние
   углы и спорить с прямоугольной обложкой на странице статьи, поэтому теперь
   и в ленте, и на статье один контур — прямоугольник с мягким скруглением.
   Арка осталась у портрета (.hero__photo), где она про человека.
   ------------------------------------------------------------------------- */

.cover {
	position: relative;
	overflow: hidden;
	aspect-ratio: 4 / 3;
	border-radius: 14px;
	background: var(--surface-band);
	transition: background-color var(--dur-in) var(--ease);
}
/* Точка кадрирования смещена вверх: у вертикальной обложки центральный
   кроп в горизонтальную рамку срезает лицо. 30% по вертикали — там, где
   лицо оказывается чаще всего. */
.cover__img { width: 100%; height: 100%; object-fit: cover; object-position: center 30%; display: block; filter: var(--cover-filter); }

.cover--typo { display: grid; place-items: center; }
.cover__glyph {
	font-family: var(--serif);
	font-weight: 300;
	font-size: clamp(4rem, 9vw, 6.5rem);
	line-height: 1;
	color: var(--accent);
	opacity: .38;
	transition: opacity var(--dur-in) var(--ease), transform var(--dur-in) var(--ease);
}
/* Три варианта: смещение литеры даёт ленте ритм, но остаётся
   предсказуемым — вариант выбирается по id записи, а не случайно. */
.cover--v0 .cover__glyph { transform: translate(-14%, 6%); }
.cover--v1 .cover__glyph { transform: translate(12%, -4%); }
.cover--v2 .cover__glyph { transform: translate(0, 10%); font-size: clamp(4.75rem, 11vw, 8rem); }

.entry:hover .cover { background: var(--surface-raised); }
.entry:hover .cover__glyph { opacity: .55; }
.entry:hover .cover--v0 .cover__glyph { transform: translate(-14%, 3%); }
.entry:hover .cover--v1 .cover__glyph { transform: translate(12%, -7%); }
.entry:hover .cover--v2 .cover__glyph { transform: translate(0, 7%); }

.prose > * + * { margin-top: var(--space-m); }
.prose p, .prose li { text-wrap: pretty; }   /* без висячих однословных строк */

/* Лид: первый абзац чуть крупнее — вход в текст, а не сразу стена. */
.prose > p:first-child {
	font-size: var(--text-m);
	line-height: 1.5;
	letter-spacing: -0.004em;
}

.prose ul, .prose ol { padding-left: 1.4em; }
.prose li + li { margin-top: var(--space-xs); }
.prose li { padding-left: 0.15em; }
.prose li::marker { color: var(--accent); font-weight: 500; }
.prose strong { font-weight: 600; }
.prose code {
	font-size: 0.9em;
	background: var(--surface-band);
	padding: 0.1em 0.35em;
	border-radius: 2px;
}
/* Широкое содержимое скроллится внутри себя — страница не едет вбок. */
.prose table, .prose pre { display: block; max-width: 100%; overflow-x: auto; }

/* Пагинация: каждый пункт — цель не меньше 44px, а не голая цифра в 9px
   шириной. Текущая страница — та же форма без ссылки, чтобы ряд не прыгал. */
.pager { margin-top: var(--space-xl); display: flex; flex-wrap: wrap; gap: var(--space-2xs); font-size: var(--text-s); }
.pager .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2.75rem;
	min-height: 2.75rem;
	padding: 0 .9rem;
	border: 1px solid var(--rule);
	border-radius: 999px;
	color: var(--ink);
	text-decoration: none;
	transition: border-color var(--dur-in) var(--ease), color var(--dur-in) var(--ease);
}
.pager a.page-numbers:hover,
.pager a.page-numbers:focus-visible { border-color: var(--accent); color: var(--accent-strong); }
.pager .current { border-color: var(--ink); color: var(--ink); }
.pager .dots { border: 0; min-width: 0; padding: 0 .25rem; color: var(--ink-quiet); }

.empty { margin-top: var(--space-xl); color: var(--ink-quiet); }
.empty__note { color: var(--ink-quiet); }

/* =========================================================================
   БЛОЧНАЯ РАЗМЕТКА

   WordPress оборачивает содержимое group-блока во внутренний контейнер
   .wp-block-group__inner-container. Из-за этого grid-раскладки получают
   одного потомка вместо нескольких и схлопываются. Прозрачно пропускаем
   обёртку там, где нужна сетка.
   ========================================================================= */

.topics > .wp-block-group__inner-container,
.topic  > .wp-block-group__inner-container,
.steps  > .wp-block-group__inner-container,
.step   > .wp-block-group__inner-container,
.marks  > .wp-block-group__inner-container,
.mark   > .wp-block-group__inner-container,
.facts  > .wp-block-group__inner-container,
.fact   > .wp-block-group__inner-container,
.faq__list > .wp-block-group__inner-container,
.principles > .wp-block-group__inner-container,
.about__body > .wp-block-group__inner-container {
	display: contents;
}

/* Вертикальный ритм внутри секции.

   Здесь стоял глухой сброс margin-block: 0 на всех детях. Он специфичнее
   (.section > .inner > * против .section__body) и убивал отбивки: блоки
   стояли вплотную, а .creed наезжал на абзац на 10px. Замеры контраста и
   переполнения такого не ловят — видно только глазами или замером зазоров.

   Сброс заменён на управляемый поток: обнуляем и тут же задаём шаг. */
.section > .wp-block-group__inner-container > * { margin-block: 0; }
.section > .wp-block-group__inner-container > * + * { margin-top: var(--space-l); }
/* Надзаголовок принадлежит следующему за ним заголовку — зазор меньше. */
.section > .wp-block-group__inner-container > .eyebrow + * { margin-top: var(--space-s); }
/* Абзац под заголовком секции — тоже теснее: это его продолжение. */
.section > .wp-block-group__inner-container > .section__lead + .section__body { margin-top: var(--space-m); }

.topic__desc {
	margin: 0;
	color: var(--ink-quiet);
}

/* =========================================================================
   ОБО МНЕ
   Портрет чёрно-белый — на прохладном фоне садится без спора с акцентом.
   ========================================================================= */

@media (min-width: 52rem) {
	.about__body { grid-template-columns: minmax(0, 24rem) minmax(0, 34rem); gap: var(--space-xl); }
}

/* Портретный кроп из горизонтального исходника: лицо крупнее и ближе,
   а это главный узел доверия на странице. object-position смещён вправо —
   в кадре она правее центра. */

.about__text > * + * { margin-top: var(--space-m); }

/* =========================================================================
   НАДЗАГОЛОВКИ, ФАКТЫ, ПРИНЦИПЫ
   ========================================================================= */

.eyebrow {
	margin: 0 0 var(--space-s);
	font-size: var(--text-xs);
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--ink-quiet);
}

.facts { margin-top: var(--space-l); display: grid; gap: var(--space-m); }
@media (min-width: 44rem) {
	.facts { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-l); max-width: 52rem; }
}
.fact { padding-top: var(--space-s); border-top: 1px solid var(--rule); }
.fact__value { margin: 0; font-family: var(--serif); font-size: var(--text-m); }
.fact__label { margin: var(--space-3xs) 0 0; font-size: var(--text-s); color: var(--ink-quiet); }

/* «Возможно, вы узнаёте себя» — номер и одна строка. */
.marks { margin-top: var(--space-l); display: grid; gap: var(--space-m); }
.mark {
	display: grid;
	grid-template-columns: 3.5rem minmax(0, 1fr);
	gap: var(--space-m);
	align-items: baseline;
	max-width: 60ch;
	padding-block: var(--space-2xs);
}
.mark__num { margin: 0; font-family: var(--serif); font-size: var(--text-l); line-height: 1; color: var(--accent); }
.mark__text { margin: 0; }

/* Шаги — номер, заголовок и пояснение. Номер занимает обе строки. */
.step {
	display: grid;
	grid-template-columns: 3.5rem minmax(0, 1fr);
	gap: var(--space-m);
	align-items: baseline;
	max-width: 60ch;
	column-gap: var(--space-m);
	row-gap: var(--space-3xs);
}
.step__num {
	font-family: var(--serif);
	font-size: var(--text-l);
	color: var(--accent);
	line-height: 1;
	margin: 0;
	grid-column: 1;
	grid-row: 1 / 3;
}
.step__title { grid-column: 2; grid-row: 1; margin: 0; }
.step__text {
	margin: 0;
	grid-column: 2;
	grid-row: 2;
	color: var(--ink-quiet);
}

.topic__kicker {
	margin: 0 0 var(--space-3xs);
	font-size: var(--text-xs);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ink-quiet);
}
/* Надзаголовок стоит ярлыком над строкой; название темы и пояснение —
   выровненная пара во второй строке сетки.

   Раньше пояснение растягивалось на обе строки и прижималось к верху,
   то есть выравнивалось по мелкому надзаголовку, а не по жирному названию.
   Якорь строки оказывался ниже первой строки пояснения и читался
   подчинённым — та же ошибка вертикального выравнивания пар, что была
   в шапке. */
@media (min-width: 46rem) {
	.topic { align-items: baseline; }
	.topic__kicker { grid-column: 1; grid-row: 1; }
	.topic__term   { grid-column: 1; grid-row: 2; }
	.topic__desc   { grid-column: 2; grid-row: 2; }
}

/* Квалификация — доказательство, а не сноска: раньше набиралась мелким
   серым и читалась как приписка. */
/* Регалии — тихий список под одной линейкой. Раньше у каждой строки была
   своя вертикальная черта слева: три «цитаты» подряд сразу под настоящей
   цитатой (.about__hard) — владелец назвал это некрасивым, и был прав. */
.credentials {
	margin-top: var(--space-l);
	padding: var(--space-s) 0 0;
	border-top: 1px solid var(--rule);
	list-style: none;
	display: grid;
	gap: var(--space-2xs);
	font-size: var(--text-s);
	color: var(--ink-quiet);
}
.credentials li { padding: 0; border: 0; }

/* =========================================================================
   ВОПРОСЫ
   Нативные <details>: без JS, доступны с клавиатуры, работают без плагинов.
   ========================================================================= */

.faq__list { margin-top: var(--space-l); max-width: 60ch; }
.wp-block-details { padding-block: var(--space-m); border-top: 1px solid var(--rule); }
.wp-block-details summary {
	cursor: pointer;
	font-weight: 500;
	list-style: none;
	display: flex;
	gap: var(--space-s);
	justify-content: space-between;
	align-items: baseline;
}
.wp-block-details summary::-webkit-details-marker { display: none; }
.wp-block-details summary::after {
	content: "+";
	color: var(--accent);
	font-size: var(--text-m);
	line-height: 1;
	flex: none;
}
.wp-block-details[open] summary::after { content: "−"; }
.wp-block-details summary:hover { color: var(--accent-strong); }
.wp-block-details p { margin: var(--space-s) 0 0; color: var(--ink-quiet); }

/* Пункт про экстренную помощь — раскрыт по умолчанию и отмечен. */
.faq__urgent { border-left: 2px solid var(--accent); padding-left: var(--space-m); }

/* Строка про экстренную помощь стоит отдельной полосой под остальным
   подвалом, а не сбоку: рядом со ссылкой она с ней конкурировала. */
.site-foot__urgent {
	order: 10;
	/* min-width, а не только flex-basis: базис задаёт лишь начальный размер,
	   а flex-shrink по умолчанию ужимает элемент обратно в общую строку. */
	flex-basis: 100%;
	min-width: 100%;
	margin-top: var(--space-m);
	padding-top: var(--space-m);
	border-top: 1px solid var(--rule);
	max-width: 68ch;
}

/* =========================================================================
   ЦЕЛИ НАЖАТИЯ

   WCAG 2.2 Target Size (Minimum) — 24×24 CSS px. Исключение для строчных
   ссылок здесь не работает: эти ссылки стоят отдельно, а не внутри
   предложения. Без отбивки они были 18px в высоту.
   ========================================================================= */

.site-nav__list a:not(.btn),
.site-foot__note a {
	display: inline-block;
	padding-block: var(--space-3xs);
}

@media (pointer: coarse) {
	.site-nav__list a:not(.btn),
	.site-foot__note a { padding-block: var(--space-2xs); }
}

/* =========================================================================
   РИТМ СТРАНИЦЫ

   До этого пять секций из семи имели идентичную структуру: надзаголовок →
   серифный заголовок → абзац → двухколоночный список. На странице в 3600px
   ничто не отмечало продвижение, и читатель терял место.

   Две секции уходят на утопленный фон полосой во всю ширину. Полоса
   рисуется тенью с клипом, а не через 100vw: vw включает ширину полосы
   прокрутки и даёт горизонтальный скролл.
   ========================================================================= */

.section--sunken {
	background: var(--surface-band);
	box-shadow: 0 0 0 100vmax var(--surface-band);
	clip-path: inset(0 -100vmax);
	border-top: 0;
}
.section--sunken + .section { border-top: 0; }

/* Принципы работы — сетка 2×2, а не тот же список тем.
   Смысл разный, значит и форма должна отличаться. */
.principles { margin-top: var(--space-l); display: grid; gap: var(--space-l); }
@media (min-width: 44rem) {
	.principles { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-l) var(--space-xl); max-width: 60rem; }
}
.principle { padding-top: var(--space-s); border-top: 1px solid var(--rule); }

.principle__desc { margin: var(--space-2xs) 0 0; color: var(--ink-quiet); }

/* =========================================================================
   ПРИЗЫВ, ДОСТУПНЫЙ СРАЗУ

   Единственное действие сайта раньше стояло только внизу: кто уходил на
   40% страницы, не видел его вообще. Ссылка в шапке видна всегда, ссылка
   в первом экране ловит тех, кто уже готов. Плавающей кнопки нет
   намеренно — она бы спорила с направлением.
   ========================================================================= */

/* Отдельный токен вторичного текста на полосе больше не нужен: новая
   шкала даёт там 4.99:1 против прежних 4.62. */

/* =========================================================================
   ПОЯВЛЕНИЕ

   Одна оркестрованная последовательность при загрузке первого экрана
   плюс сдержанное проявление секций при прокрутке. Без JS.

   Безопасность по умолчанию: анимация идёт ОТ скрытого состояния К
   естественному. Если она не отработает — не поддерживается, отключена
   или сокращена — содержимое остаётся видимым. Обратный порядок
   (спрятать в CSS, показать скриптом) оставляет пустую страницу при
   любом сбое, поэтому так не делаем.
   ========================================================================= */

@keyframes chb-rise {
	from { opacity: 0; transform: translateY(10px); }
	to   { opacity: 1; transform: none; }
}

.hero .eyebrow,
.hero__title,
.hero__lead,
.hero__actions {
	animation: chb-rise 620ms var(--ease) both;
}
/* Сдвиг 45 мс на элемент: читается как одно движение, а не пять отдельных. */
.hero .eyebrow  { animation-delay:   0ms; }
.hero__title {
	max-width: 17ch;
	animation-delay: 45ms;
}
.hero__lead {
	margin-top: var(--space-l);
	font-size: var(--text-m);
	color: var(--ink-quiet);
	animation-delay: 90ms;
}
.hero__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-s);
	margin-top: var(--space-l);
	animation-delay: 135ms;
}

/* Секции ниже сгиба — на scroll-driven timeline, тоже без скриптов.
   Где view() не поддерживается, блок целиком не применяется и секции
   просто видны. */
@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.section > .wp-block-group__inner-container > .eyebrow,
		.section > .wp-block-group__inner-container > .section__lead,
		.section > .wp-block-group__inner-container > .section__body,
		.opener__title,
		.opener__link {
			animation: chb-rise 700ms var(--ease) both;
			animation-timeline: view();
			animation-range: entry 5% cover 22%;
		}
	}
}

/* Триада с talk2mind.com — короткое обещание, набранное крупно.
   Заодно даёт секции подхода собственный визуальный маркер. */
.creed {
	color: var(--accent-strong);
	max-width: 24ch;
}

/* Готовность говорить о тяжёлом — сильный сигнал доверия, поэтому
   выделен, а не растворён в общем тексте. */
.about__hard {
	padding-left: var(--space-m);
	border-left: 2px solid var(--accent);
	color: var(--ink);
}

/* =========================================================================
   ОТЗЫВЫ

   Текстом, а не скриншотами: скриншот не читают ни скринридеры, ни
   поисковики. Оформлены как цитаты с висячей кавычкой — форма, которой
   больше нигде на странице нет, поэтому секция не сливается с соседями.
   ========================================================================= */

.reviews { margin-top: var(--space-l); display: grid; gap: var(--space-l); }
@media (min-width: 50rem) {
	.reviews { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xl); max-width: 66rem; }
}

/* Каждый отзыв — приподнятая карточка на полосе. Это единственное место
   на странице, где говорит не Анастасия, и чужие голоса должны читаться
   как отдельные предметы, а не как продолжение её текста. Карточки здесь
   уместны по смыслу — это дискретные высказывания разных людей, — тогда
   как в остальных секциях они превратили бы страницу в прайс-лист. */
.review {
	position: relative;
	display: flex;
	flex-direction: column;   /* подпись прижимается к низу карточки, см. cite */
	margin: 0;
	padding: var(--space-l) var(--space-l) var(--space-m);
	background: var(--surface-high);
	border: 1px solid var(--rule);
	border-radius: 4px 16px 16px 16px;
}
/* Кавычки — обычные, в самом тексте: „…“. Отдельный декоративный знак
   в углу (бледный, вчетверо крупнее текста) был не к месту: вплотную к
   тексту — наезжал, поднятый над ним — висел одинокой «галочкой».
   Открывающая — перед первым абзацем, закрывающая — после последнего. */
.review p:first-of-type::before { content: "„"; }
.review p:last-of-type::after  { content: "“"; }
.review p { margin: 0 0 var(--space-m); }
.review cite {
	display: block;
	/* auto сверху: в сетке карточки одной высоты, и у короткого отзыва
	   подпись иначе висела посреди пустоты. */
	margin-top: auto;
	padding-top: var(--space-s);
	border-top: 1px solid var(--rule);
	font-style: normal;
	font-size: var(--text-s);
	color: var(--ink-quiet);
}

.reviews > .wp-block-group__inner-container { display: contents; }

/* =========================================================================
   ПЕРВЫЙ ЭКРАН С ПОРТРЕТОМ

   Лицо в первом экране — сильный двигатель доверия для персональной
   практики. Фотография одна, поэтому она стоит здесь, где работает
   больше всего, а секция «обо мне» держится на типографике: дважды
   одно и то же изображение было бы повтором.

   На мобильной текст и призыв идут ПЕРЕД фотографией — иначе снимок
   уводит кнопку за сгиб.
   ========================================================================= */

.hero {
	padding-block: clamp(var(--space-m), 4vh, var(--space-2xl)) var(--space-2xl);
	display: grid;
	gap: var(--space-xl);
	align-items: center;
}
@media (min-width: 56rem) {
	.hero {
		grid-template-columns: minmax(0, 1fr) minmax(0, 19rem);
		gap: var(--space-2xl);
		align-items: center;
	}
}
/* Промежуточные ширины (896–1280): экран уже двухколоночный, а заголовок
   ещё на максимальных 72px — в колонке 544px помещалось по 7 знаков, и
   первая строка оставалась «Когда в». Здесь кегль растёт вместе с окном
   (7.2vw − 1.2rem: 45px при 896, 54px при 1024, 72px к 1280 — без скачка на
   верхней границе), а колонка с фото уже на 4rem, чтобы тексту досталось
   больше. Ниже 56rem заголовок на всю ширину и живёт по общей шкале. */
@media (min-width: 56rem) and (max-width: 80rem) {
	.hero { grid-template-columns: minmax(0, 1fr) minmax(0, 15rem); }
	.hero__title { font-size: clamp(2.75rem, 7.2vw - 1.2rem, 4.5rem); }
}
.hero__text > * + * { margin-top: 0; }

/* -------------------------------------------------------------------------
   СЛОЁНАЯ КОМПОЗИЦИЯ

   Раньше портрет стоял отдельной картинкой в своей колонке — это была
   расстановка, а не композиция. Теперь три слоя: подложка уходит за
   правый край, на ней арка с портретом, поверх — пузырь реплики.

   Подложка вытянута тенью со сдвигом и обрезана по вертикали клипом.
   Через 100vw делать нельзя: vw включает ширину полосы прокрутки
   и даёт горизонтальный скролл. Тень на раскладку не влияет вовсе.
   ------------------------------------------------------------------------- */

.hero__media { position: relative; }

.hero__media::before {
	content: "";
	position: absolute;
	inset: var(--space-m) 0 var(--space-m) 0;
	background: var(--surface-band);
	border-radius: 4px;
	box-shadow: 50vmax 0 0 50vmax var(--surface-band);
	clip-path: inset(0 -100vmax 0 0);
	z-index: 0;
}
@media (min-width: 56rem) {
	.hero__media::before { inset: var(--space-l) 0 var(--space-l) var(--space-l); }
}

.hero__photo { margin: 0; }   /* блок изображения добавляет отступ снизу; карточка рассчитана на ноль */
.hero__photo img {
	display: block;
	width: 100%;
	max-width: 21rem;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	object-position: 58% 26%;
	border-radius: 50% 50% 4px 4px / 34% 34% 4px 4px;
}

/* Пузырь реплики поверх портрета. Форма та же, что у блока обращения
   внизу страницы: скруглён со всех сторон, кроме одного угла. */
/* Смещения слоёв — только там, где первый экран становится двухколоночным.
   На узком экране карточка с отрицательным левым отступом упиралась
   в край экрана. */
.hero__card {
	position: relative;
	z-index: 2;
	margin: calc(var(--space-l) * -1) auto 0;
	max-width: 17rem;
	padding: var(--space-s) var(--space-m);
	background: var(--surface-high);
	border: 1px solid var(--rule);
	/* Хвост слева-снизу: это слова Анастасии, входящее сообщение. */
	border-radius: 14px 14px 14px 4px;
	font-size: var(--text-s);
	line-height: 1.45;
	color: var(--ink);
}
@media (min-width: 56rem) {
	.hero__card { margin: calc(var(--space-xl) * -1) 0 0 calc(var(--space-l) * -1); }
}

.hero > .wp-block-group__inner-container,
.hero__text > .wp-block-group__inner-container { display: contents; }

/* Портрет входит последним в общей последовательности появления. */
.hero__photo {
	margin: 0;
	position: relative;
	z-index: 1;
	animation: chb-rise 620ms var(--ease) both;
	animation-delay: 225ms;
}

/* «Обо мне» без фотографии — одна колонка, текст ведёт. */
.about__body {
	margin-top: var(--space-l);
	display: block;
	gap: var(--space-l);
	align-items: start;
}
.about__text { max-width: var(--measure); }

/* =========================================================================
   КНОПКА

   До этого единственное действие сайта было текстовой ссылкой и читалось
   как сноска. Для страницы, вся задача которой — довести до сообщения,
   это было главным промахом.

   Белый на --accent даёт 7.15:1, поэтому заливка работает без оговорок.
   ========================================================================= */

.btn {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
	padding: var(--space-xs) var(--space-l);
	background: var(--accent);
	color: var(--on-accent);
	border: 1px solid transparent;
	border-radius: 999px;
	font-family: var(--sans);
	font-size: var(--text-s);
	font-weight: 500;
	line-height: 1.2;
	text-decoration: none;
	transition: background-color var(--dur-in) var(--ease),
	            transform var(--dur-out) var(--ease);
}
.btn:hover  { background: var(--accent-strong); color: var(--on-accent); }
.btn:active { transform: translateY(1px); }
.btn .arrow { display: inline-block; transition: transform var(--dur-in) var(--ease); }
.btn:hover .arrow { transform: translateX(3px); }

/* Горизонтальный отступ --space-l, а не --space-xl: при 64px с каждой
   стороны на колонке 295px тексту оставалось 167px и кнопка ломалась
   на четыре строки. */
.btn--lg { padding: var(--space-s) var(--space-l); font-size: var(--text-base); }

/* Вторая, тихая кнопка — контур вместо заливки. Смелость тратится
   в одном месте, поэтому заливка только у главного действия. */
.btn--quiet {
	background: transparent;
	color: var(--accent-strong);
	border-color: var(--accent);
}
.btn--quiet:hover { background: var(--accent-quiet); color: var(--accent-strong); }

/* Курсивный акцент внутри заголовка — на ключевой фразе, одной на страницу. */
.hero__title em {
	font-style: italic;
	color: var(--accent);
}

/* =========================================================================
   ПОЛОСА ФАКТОВ

   Тёмная полоса во всю ширину сразу под первым экраном: якорь, который
   держит страницу и разом отвечает на «сколько это стоит и как долго».
   Раньше факты стояли тихим текстом и терялись.
   ========================================================================= */

.factbar {
	background: var(--factbar-bg);
	color: var(--factbar-fg);
	box-shadow: 0 0 0 100vmax var(--factbar-bg);
	clip-path: inset(0 -100vmax);
	padding-block: var(--space-l);
	margin-block: 0;
}
.factbar__grid { display: grid; gap: var(--space-m); }
@media (min-width: 46rem) {
	.factbar__grid { grid-template-columns: auto repeat(3, minmax(0, 1fr)); gap: var(--space-xl); align-items: baseline; }
}
.factbar__lead {
	font-family: var(--serif);
	font-weight: 300;
	font-size: var(--text-m);
	line-height: 1.28;
	letter-spacing: -0.005em;
	margin: 0;
	color: var(--factbar-fg);
	max-width: 16ch;
}
/* Значение заметно крупнее подписи: раньше «70 €» и «50 минут» были тем же
   15px, что и подписи под ними, и самый частый вопрос — цена — визуально
   не был отвечен. */
.factbar__value { margin: 0; font-weight: 700; font-size: var(--text-m); line-height: 1.2; color: var(--factbar-fg); }
.factbar__label { margin: var(--space-3xs) 0 0; font-size: var(--text-s); color: var(--factbar-fg); opacity: .72; }

.factbar > .wp-block-group__inner-container,
.factbar__grid > .wp-block-group__inner-container,
.fact > .wp-block-group__inner-container { display: contents; }

/* Секция «обо мне» снова с фотографией — но другой, не той, что в первом
   экране. Раньше изображение было одно, и повтор был бы заметен. */
@media (min-width: 52rem) {
	.about__body { display: grid; grid-template-columns: minmax(0, 20rem) minmax(0, 34rem); gap: var(--space-xl); align-items: start; }
}
.about__photo {
	margin: 0 0 var(--space-l);
}
.about__photo img {
	width: 100%;
	max-width: 20rem;
	aspect-ratio: 3 / 4;
	object-fit: cover;
	object-position: 62% 22%;
	border-radius: 4px;
}
@media (min-width: 52rem) { .about__photo { margin-bottom: 0; } }

/* =========================================================================
   СТРАНИЦА СТАТЬИ

   Заголовок статьи набирался в 72px — тем же размером, что главное
   заявление главной. Но статья это документ, а не манифест: её заголовок
   должен подчиняться заголовку сайта, а не спорить с ним.

   h3 при 22.4px почти не отличался от текста в 18px. Разводим не только
   размером, но и отбивкой сверху: одного веса мало.
   ========================================================================= */

/* Правило по всем внутренним страницам, а не только по .article__head:
   на списке статей заголовок лежит без обёртки и оставался в 72px. */
body:not(.home) h1 {
	font-size: clamp(2rem, 3.2vw + 1rem, 2.75rem);
	max-width: 22ch;
}

.article__head {
	margin-bottom: var(--space-l);
}
.article__head .entry__meta { margin-top: var(--space-s); }

/* Обращение после статьи: статья закончилась — линейка — приглашение.
   Отступ сверху крупнее отступа между абзацами в разы, иначе призыв
   читается как ещё один абзац текста. */
.article__opener {
	margin-top: var(--space-3xl);
	padding-top: var(--space-xl);
	border-top: 1px solid var(--rule);
}

/* Подпись под заголовком статьи: имя обычным цветом текста, дата — тихим.
   Разделитель декоративный и скрыт от читалок. */
.byline { color: var(--ink); }
.entry__meta-sep { margin: 0 .35em; }

.site-foot__sep { margin: 0 .5em; color: var(--ink-quiet); }

/* «Поделиться в Telegram» — тихая строка после текста статьи. */
.share { margin-top: var(--space-l); font-size: var(--text-s); }
.share__link { color: var(--accent-strong); }

/* «Читать дальше» — две другие статьи между текстом и обращением. Список
   с линейками, а не карточки: это продолжение чтения, а не витрина. */
.more {
	margin-top: var(--space-2xl);
	max-width: var(--measure);
}
.more__list {
	list-style: none;
	margin: var(--space-s) 0 0;
	padding: 0;
	border-top: 1px solid var(--rule);
}
.more__item { border-bottom: 1px solid var(--rule); }
.more__link {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: baseline;
	gap: var(--space-2xs) var(--space-m);
	padding: var(--space-s) 0;
	color: var(--ink);
	text-decoration: none;
}
.more__name {
	font-family: var(--serif);
	font-size: var(--text-m);
	line-height: 1.25;
	transition: color var(--dur-in) var(--ease);
}
.more__date {
	font-size: var(--text-s);
	color: var(--ink-quiet);
	white-space: nowrap;
}
.more__link:hover .more__name,
.more__link:focus-visible .more__name { color: var(--accent-strong); }

/* -------------------------------------------------------------------------
   ГЛАВНАЯ: ПОСЛЕДНИЕ СТАТЬИ

   Три свежие записи обложками вперёд — та же пара «обложка + текст», что в
   ленте, но в ряд: на главной это приглашение читать, а не оглавление.
   Список рисует блок chembarisova/latest (functions.php), обложки те же
   .cover, поэтому лента и главная не расходятся.
   ------------------------------------------------------------------------- */
.latest__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-l); }
@media (min-width: 46rem) {
	.latest__list { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-l); }
}
.latest .entry__card { grid-template-columns: none; gap: var(--space-s); }
/* Заголовки как в ленте: серифом и без жирности, иначе h3 берёт стиль подзаголовка статьи. */
.latest .entry__title { font-family: var(--serif); font-weight: 400; font-size: var(--text-l); line-height: 1.2; }
.latest .entry__excerpt {
	margin-top: var(--space-xs);
	font-size: var(--text-s);
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.latest__all { margin: var(--space-l) 0 0; }
.latest__all a { color: var(--accent-strong); }

/* -------------------------------------------------------------------------
   СТРАНИЦА «НЕ НАЙДЕНО»

   Тот же приём, что у заглушек обложек: крупная лёгкая литера серифом в
   акцентном цвете на четверть силы. Не иллюстрация и не «упс», а типографика
   сайта; ниже три свежие статьи тем же блоком, что на главной, — тупика нет.
   ------------------------------------------------------------------------- */
.notfound__glyph {
	margin: var(--space-m) 0 0;
	font-family: var(--serif);
	font-weight: 300;
	font-size: clamp(6rem, 18vw, 12rem);
	line-height: .9;
	letter-spacing: -0.03em;
	color: var(--accent);
	opacity: .38;
	user-select: none;
}
.notfound__title { margin-top: var(--space-s); }
.notfound__text { margin-top: var(--space-m); font-size: var(--text-m); color: var(--ink-quiet); }
.notfound__links { margin-top: var(--space-l); display: flex; flex-wrap: wrap; gap: var(--space-xs) var(--space-l); }
.notfound__links a { color: var(--accent-strong); }
.notfound__latest .latest { margin-top: var(--space-l); }

/* Блоки редактора внутри статьи: картинка с подписью, разделитель,
   выравнивание. Без этого они рисуются дефолтами библиотеки блоков и
   выглядят чужими на странице. */
.prose figure { margin: var(--space-l) 0; }
.prose img { display: block; max-width: 100%; height: auto; border-radius: 4px; }
.prose figcaption {
	margin-top: var(--space-xs);
	font-size: var(--text-s);
	color: var(--ink-quiet);
	text-align: left;
}
.prose hr,
.prose .wp-block-separator {
	width: 6rem;
	margin: var(--space-xl) 0;
	border: 0;
	border-top: 1px solid var(--rule);
	opacity: 1;
}
.prose .has-text-align-center { text-align: center; }
.prose .has-text-align-right  { text-align: right; }

/* Заголовки внутри статьи. Раньше h2 был кеглем ленты (1.5–2rem) и терялся
   между абзацами того же серого; теперь он на ярус крупнее, с короткой
   терракотовой чертой сверху — так глаз находит начало раздела ещё до чтения.
   h3 — тоже сериф, но без черты и меньше: подраздел, а не новая глава. */
.prose h2 {
	margin-top: var(--space-2xl);
	font-size: clamp(1.75rem, 1.25vw + 1.25rem, 2.25rem);   /* 28–36px: на ярус ниже заголовка статьи */
	font-weight: 400;
	line-height: 1.15;
	letter-spacing: -0.01em;
	max-width: 30ch;
	text-wrap: balance;
}
.prose h2::before {
	content: "";
	display: block;
	width: 2.25rem;
	height: 2px;
	margin-bottom: var(--space-m);
	background: var(--accent);
}
.prose h2 + * { margin-top: var(--space-s); }
.prose h3 {
	margin-top: var(--space-xl);
	font-family: var(--serif);
	font-weight: 400;
	font-size: clamp(1.375rem, 0.5vw + 1.2rem, 1.625rem);   /* 22–26px */
	line-height: 1.2;
	letter-spacing: -0.005em;
	max-width: 34ch;
	text-wrap: balance;
}
.prose h3 + * { margin-top: var(--space-xs); }
/* Цитата — как выноска: сериф крупнее текста, черта акцентом. */
.prose blockquote {
	margin: var(--space-l) 0;
	padding-left: var(--space-m);
	border-left: 2px solid var(--accent);
	font-family: var(--serif);
	font-size: clamp(1.3rem, 0.5vw + 1.1rem, 1.5rem);   /* 21–24px: между лидом и h3 */
	line-height: 1.3;
	color: var(--ink);
}
.prose blockquote > * + * { margin-top: var(--space-s); }
/* В узкой колонке рваный правый край и дыры между словами лечит перенос. */
@media (max-width: 40rem) {
	.prose p, .prose li { hyphens: auto; -webkit-hyphens: auto; }
}

/* Страница статьи — единственная, где справа от колонки ничего нет: на
   главной левую колонку уравновешивает фото, а здесь она висела у левого
   края с пустой половиной экрана. Поэтому здесь всё держит одну ось по
   центру: обложка чуть шире колонки, под ней заголовок, текст, «поделиться»,
   другие статьи и обращение той же ширины. На телефоне разницы нет. */
.single .cover,
.single .article__head,
.single .prose,
.single .share,
.single .more,
.single .article__opener { margin-inline: auto; }
.single .share,
.single .article__opener { max-width: var(--measure); }
/* Лестница на странице статьи: заголовок 48 → h2 36 → h3 26 → лид 22 → текст 18.
   Заголовок статьи — на всю ширину колонки, а не 22ch: длинные названия
   («…почему друзья не появляются сами») рвались на три коротких строки.
   48px, а не 56: при 56 название в 60 знаков всё равно не влезало в две
   строки колонки, а лестница 48 → 36 держится и весом (300 против 400). */
.single .article__head h1 {
	font-size: clamp(2.25rem, 2.2vw + 1.25rem, 3rem);
	max-width: none;
	text-wrap: balance;
}

/* Обложка на самой странице статьи — шире колонки, но не ниже 3:2: иллюстрации
   помощника рисуются под 4:3, и полоса 16:7 срезала бы у них верх и низ.
   Контур здесь прямоугольный с мягким скруглением, а не арка: арка — рифма к
   портрету и ритм ленты, а широкой сцене-иллюстрации она резала верхние углы
   (окно, полку) и читалась как недоделка. */
.single .cover {
	aspect-ratio: 3 / 2;
	max-width: 48rem;   /* на шаг шире колонки текста, но заголовок остаётся в первом экране */
	margin-bottom: var(--space-l);
	border-radius: 14px;
}

/* На главной кнопка в шапке — контурная: залитая уже стоит в первом экране
   в 150px ниже, и два одинаковых залитых «Написать в Telegram» рядом
   размывали акцент. На внутренних страницах шапка остаётся залитой —
   там она единственный призыв наверху. */
.home .site-nav .btn {
	background: transparent;
	color: var(--accent-strong);
	border-color: var(--accent);
}
.home .site-nav .btn:hover { background: var(--accent-quiet); color: var(--accent-strong); }

/* =========================================================================
   СВЕТ

   Вместо зерна — пятно чистого света (почти белого, без жёлтого: тёплый
   оттенок владелец читал как желтизну), которое медленно плывёт по
   поверхности за содержимым (цикл 22 с туда-обратно). Оно только прибавляет
   света и не может выглядеть «грязно», как выглядит любая фактура с тёмными
   крапинами; текст, карточки и фото лежат выше и не меняются. Три версии
   зерна (разброс до 7,7 уровня, до 6 к/с, всё замерено в canvas) владелец
   назвал беспокойными и грязноватыми — история в README.

   Слой: body::before с z-index -1 в изолированном контексте body — выше
   фона html, ниже всего содержимого. Двигается transform: композитор, без
   перерисовки. При prefers-reduced-motion пятно стоит на месте.
   ========================================================================= */
:root { --glow: rgba(255, 253, 250, .9); }
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) { --glow: rgba(255, 246, 236, .09); }
}
:root[data-theme="dark"] { --glow: rgba(255, 246, 236, .09); }

html { background: var(--surface); }
body { background: transparent; position: relative; isolation: isolate; }
body::before {
	content: "";
	position: fixed;
	z-index: -1;
	top: 50%;
	left: 50%;
	width: 110vmax;
	height: 110vmax;
	margin: -55vmax 0 0 -55vmax;
	border-radius: 50%;
	background: radial-gradient(closest-side, var(--glow), transparent 66%);
	pointer-events: none;
	transform: translate(-18vmax, -12vmax);
	will-change: transform;
}
@keyframes chb-glow-drift {
	from { transform: translate(-18vmax, -12vmax); }
	to   { transform: translate(16vmax, 14vmax); }
}
@media (prefers-reduced-motion: no-preference) {
	body::before { animation: chb-glow-drift 22s cubic-bezier(.45, 0, .55, 1) infinite alternate; }
}
@media (prefers-contrast: more) { body::before { display: none; } }

/* Тем, кто просит повышенный контраст, зерно не нужно; на печати тоже. */
@media print {
	body::before { display: none; }
	/* Печатают статью, а не сайт: чёрный текст на белом, без шапки-навигации,
	   кнопок, обращения в Telegram и соседних статей. Адреса внешних ссылок
	   выписываются в скобках — на бумаге по ним не кликнуть. */
	html { background: #fff; }
	body { color: #000; font-size: 11pt; line-height: 1.45; }
	.skip, .site-nav, .theme-toggle, .hero__actions, .hero__card,
	.article__opener, .more, .opener, .pager,
	.site-foot a[href*="t.me"] { display: none !important; }
	.wrap { max-width: none; padding-inline: 0; }
	.section { padding-block: 1.5rem; }
	.section--sunken { background: none; box-shadow: none; clip-path: none; }
	.site-head { padding: 0 0 .75rem; border-bottom: 1px solid #000; }
	a { color: inherit; text-decoration: underline; }
	.prose a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 90%; }
	h1, h2, h3 { break-after: avoid; }
	p, li, blockquote { orphans: 3; widows: 3; }
	.cover { max-width: 60mm; }
}

/* Системным контролам — полосе прокрутки, выделению, полям — тоже нужна тёмная
   тема: без color-scheme они остаются светлыми, и тёмная тема читается как инверсия.
   Три состояния, как у токенов. */
:root { color-scheme: light; }
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) { color-scheme: dark; }
}
:root[data-theme="dark"] { color-scheme: dark; }

/* =========================================================================
   ПЕРЕКЛЮЧАТЕЛЬ ТЕМЫ

   Иконка показывает то, что получишь по клику: в светлой — луну, в тёмной —
   солнце. Правила зеркалят структуру токенов темы: три состояния, дефолт
   на голом :root, системная тёмная под :root:not([data-theme="light"]),
   явная тёмная под :root[data-theme="dark"].

   Кнопка появляется только при .js на <html> — без скрипта контрола нет.
   Цель нажатия 44px при видимой иконке 20px.
   ========================================================================= */

.theme-toggle { display: none; }
.js .theme-toggle[hidden] { display: flex; }   /* снимаем hidden стилем; flex, а не inline-flex: строчный бокс сел бы на базовую линию и уехал вверх на ~3px */

.theme-toggle {
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	margin: -10px 0;                 /* визуально 24px, цель — 44px */
	background: transparent;
	border: 0;
	border-radius: 999px;
	color: var(--ink-quiet);
	cursor: pointer;
	transition: color var(--dur-in) var(--ease), background-color var(--dur-in) var(--ease);
}
.theme-toggle:hover  { color: var(--ink); background: var(--accent-quiet); }
.theme-toggle:active { transform: translateY(1px); }

/* Какая иконка видна. Дефолт — светлая тема, показываем луну. */
/* Правила иконок с родительским классом: раньше общее .theme-toggle svg
   { display: block } шло позже и специфичнее и показывало обе иконки сразу. */
.theme-toggle .theme-toggle__sun  { display: none; }
.theme-toggle .theme-toggle__moon { display: block; }
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) .theme-toggle .theme-toggle__sun  { display: block; }
	:root:not([data-theme="light"]) .theme-toggle .theme-toggle__moon { display: none; }
}
:root[data-theme="dark"] .theme-toggle .theme-toggle__sun  { display: block; }
:root[data-theme="dark"] .theme-toggle .theme-toggle__moon { display: none; }
