/* ═══════════════════════════════════════════════════════════════════════
   9APE — BASE · LAYOUT · COMPONENTS · UTILITIES
   Порядок секций фиксирован. Новое правило кладётся в свою секцию.
   ═══════════════════════════════════════════════════════════════════════ */

/* ─── 1. СБРОС ─────────────────────────────────────────────────────────*/

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

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

body {
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--t-base);
  line-height: var(--lh-3);
  letter-spacing: var(--tr-flat);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "ss01", "cv05";
}

img, svg, video { display: block; max-width: 100%; height: auto; }
button, input { font: inherit; color: inherit; background: none; border: 0; }

/* Прямой угол — закон системы. */
*, *::before, *::after { border-radius: 0 !important; }

:focus-visible { outline: var(--bd-2) solid var(--text); outline-offset: 3px; }
::selection { background: var(--text); color: var(--bg); }

/* ─── 2. ТИПОГРАФИКА ───────────────────────────────────────────────────
   Без цвета иерархию держит только размер и вес, поэтому ступени резкие. */

h1, h2, h3, h4 { line-height: var(--lh-2); letter-spacing: var(--tr-tight); font-weight: 620; text-wrap: balance; }
h1 { font-size: var(--t-2xl); }
h2 { font-size: var(--t-xl); }
h3 { font-size: var(--t-lg); }
h4 { font-size: var(--t-md); }

p { text-wrap: pretty; }
a { color: inherit; text-decoration: none; }

.num, time { font-variant-numeric: tabular-nums; }

/* Микроподпись: единственный элемент с разрядкой — ею и держится «дорого». */
.kicker {
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--text-4);
}

.lead { font-size: var(--t-md); color: var(--text-2); line-height: 1.5; }
.meta { font-size: var(--t-xs); color: var(--text-4); font-variant-numeric: tabular-nums; }

/* ─── 3. РАСКЛАДКА ─────────────────────────────────────────────────────*/

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }
.read { max-width: var(--wrap-read); }

.row { display: flex; align-items: center; gap: var(--s-3); }
.between { justify-content: space-between; }
.wrapf { flex-wrap: wrap; }

.stack > * + * { margin-block-start: var(--flow, var(--s-4)); }

.grid { display: grid; gap: var(--s-6); }
.g-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.g-lead { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }

@media (max-width: 980px) {
  .g-lead, .g-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .g-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .g-2, .g-3, .g-4, .g-lead { grid-template-columns: minmax(0, 1fr); }
}

/* ─── 4. ШАПКА ─────────────────────────────────────────────────────────
   Одна строка высотой 56px. Логотип, рубрики, тема — всё в ней.
   Отдельной полосы навигации нет: она съедала первый экран. */

.head {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(12px);
  border-block-end: var(--bd) solid var(--hair);
}

.head-in {
  height: 56px;
  display: flex;
  align-items: center;
  gap: var(--s-6);
}

.brand {
  font-size: var(--t-md);
  font-weight: 680;
  letter-spacing: var(--tr-tight);
  white-space: nowrap;
}

.brand i { font-style: normal; color: var(--text-4); }

.menu {
  display: flex;
  gap: var(--s-5);
  margin-inline-start: auto;
  overflow-x: auto;
  scrollbar-width: none;
}
.menu::-webkit-scrollbar { display: none; }

.menu a {
  font-size: var(--t-sm);
  font-weight: 520;
  color: var(--text-3);
  white-space: nowrap;
  padding-block: var(--s-2);
  border-block-end: var(--bd-2) solid transparent;
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}

.menu a:hover { color: var(--text); }
.menu a[aria-current] { color: var(--text); border-block-end-color: var(--text); }

.icon-btn {
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  border: var(--bd) solid var(--hair);
  color: var(--text-2);
  cursor: pointer;
  transition: border-color var(--fast) var(--ease), color var(--fast) var(--ease);
  flex: none;
}
.icon-btn:hover { border-color: var(--text); color: var(--text); }

/* ─── 5. ТИКЕР ─────────────────────────────────────────────────────────
   Тонкая полоса над шапкой. Единственное место, где цвет появляется
   постоянно — потому что там постоянно есть движение. */

.tape {
  border-block-end: var(--bd) solid var(--hair);
  overflow: hidden;
  background: var(--bg);
}

.tape-run {
  display: flex;
  gap: var(--s-6);
  width: max-content;
  padding-block: var(--s-2);
  animation: tape 60s linear infinite;
}
.tape:hover .tape-run { animation-play-state: paused; }
@keyframes tape { to { transform: translateX(-50%); } }

.tape-i {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s-2);
  font-size: var(--t-xs);
  color: var(--text-3);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tape-i b { color: var(--text); font-weight: 600; }

/* ─── 6. СЕКЦИЯ ────────────────────────────────────────────────────────*/

.sec { margin-block-start: var(--s-9); }

.sec-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block-end: var(--s-3);
  border-block-end: var(--bd-2) solid var(--text);
  margin-block-end: var(--s-6);
}

.sec-head h2 { font-size: var(--t-lg); }
.sec-head a { font-size: var(--t-xs); color: var(--text-3); }
.sec-head a:hover { color: var(--text); }

/* ─── 7. КАРТОЧКИ ──────────────────────────────────────────────────────
   Ни рамки, ни тени: карточку держат волосяная линия сверху и воздух.
   Это и есть переход от «дешёвого» к «редакционному». */

.item {
  display: grid;
  gap: var(--s-3);
  padding-block-start: var(--s-4);
  border-block-start: var(--bd) solid var(--hair);
}

.item:hover .item-title { text-decoration: underline; text-underline-offset: 4px; }

.item-title {
  font-size: var(--t-md);
  font-weight: 600;
  line-height: var(--lh-2);
  letter-spacing: var(--tr-tight);
}

.item-row { display: grid; grid-template-columns: 1fr auto; gap: var(--s-4); align-items: start; }

/* Главный материал: число во всю ширину — это и есть обложка.
   Никаких картинок-заглушек. */
.hero { display: grid; gap: var(--s-5); }

.hero-num {
  font-size: var(--t-3xl);
  font-weight: 640;
  line-height: 0.82;
  letter-spacing: -0.055em;
  font-variant-numeric: tabular-nums;
}

.hero-num sup { font-size: 0.26em; vertical-align: super; color: var(--text-3); margin-inline-start: 0.08em; }

.hero h1 { font-size: var(--t-xl); max-width: 22ch; }

/* ─── 8. ДАННЫЕ ────────────────────────────────────────────────────────*/

.val { font-variant-numeric: tabular-nums; font-weight: 620; letter-spacing: var(--tr-tight); }
.val-lg { font-size: var(--t-lg); }
.val-xl { font-size: var(--t-xl); }

/* Дельта — единственный цветной элемент интерфейса. */
.d { font-variant-numeric: tabular-nums; font-weight: 600; font-size: var(--t-sm); white-space: nowrap; }
.d-up { color: var(--up); }
.d-dn { color: var(--down); }
.d-fl { color: var(--text-4); }

/* ─── 9. СТРОКА СПИСКА ─────────────────────────────────────────────────*/

.line {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: var(--s-5);
  padding-block: var(--s-4);
  border-block-start: var(--bd) solid var(--hair);
  transition: background var(--fast) var(--ease);
}

.line:hover { background: var(--surface-2); }
.line-q { font-weight: 520; min-width: 0; }
.line-q small { display: block; color: var(--text-4); font-size: var(--t-xs); font-weight: 400; margin-block-start: 2px; }

@media (max-width: 600px) {
  .line { grid-template-columns: 1fr auto; gap: var(--s-3); }
  .line .spark { display: none; }
}

/* ─── 10. ТАБЛИЦА ──────────────────────────────────────────────────────*/

.tbl { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }

.tbl th {
  text-align: start;
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--text-4);
  padding-block: var(--s-3);
  border-block-end: var(--bd-2) solid var(--text);
}

.tbl td { padding-block: var(--s-4); border-block-end: var(--bd) solid var(--hair); }
.tbl tr:hover td { background: var(--surface-2); }
.tbl .end { text-align: end; }

/* ─── 11. КНОПКИ ───────────────────────────────────────────────────────*/

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-5);
  border: var(--bd) solid var(--text);
  font-size: var(--t-sm);
  font-weight: 560;
  cursor: pointer;
  transition: background var(--fast) var(--ease), color var(--fast) var(--ease);
}

.btn:hover { background: var(--text); color: var(--bg); }
.btn-solid { background: var(--text); color: var(--bg); }
.btn-solid:hover { background: transparent; color: var(--text); }

/* ─── 12. ПОДПИСКА ─────────────────────────────────────────────────────*/

.sub {
  border-block: var(--bd-2) solid var(--text);
  padding-block: var(--s-8);
}

.sub input {
  width: 100%;
  padding-block: var(--s-3);
  border-block-end: var(--bd) solid var(--text);
  font-size: var(--t-md);
}
.sub input::placeholder { color: var(--text-4); }

/* ─── 13. ФУТЕР ────────────────────────────────────────────────────────*/

.foot { margin-block-start: var(--s-10); border-block-start: var(--bd) solid var(--hair); padding-block: var(--s-8) var(--s-6); }
.foot h5 { font-size: var(--t-2xs); letter-spacing: var(--tr-wide); text-transform: uppercase; color: var(--text-4); font-weight: 600; margin-block-end: var(--s-3); }
.foot ul { list-style: none; padding: 0; display: grid; gap: var(--s-2); }
.foot a { font-size: var(--t-sm); color: var(--text-2); }
.foot a:hover { color: var(--text); }

.foot-end {
  margin-block-start: var(--s-8);
  padding-block-start: var(--s-4);
  border-block-start: var(--bd) solid var(--hair);
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
  flex-wrap: wrap;
  font-size: var(--t-xs);
  color: var(--text-4);
}

/* ─── 14. ГРАФИКИ ──────────────────────────────────────────────────────*/

.chart { width: 100%; height: auto; }
.spark { width: 76px; height: 26px; flex: none; }

/* Same sparkline, full width — for an article, where the chart is the point
   rather than a hint at the end of a row. A modifier, not a second class:
   two definitions of "sparkline" would drift apart the first time either is
   touched. */
.spark-full {
  width: 100%;
  height: 200px;
  flex: initial;
  color: var(--ch-line);
  border-block: var(--bd) solid var(--hair);
  padding-block: var(--s-2);
}

.ch-tick { font-size: 10px; font-weight: 500; fill: var(--text-4); font-family: var(--mono); }

.ch-legend { display: flex; gap: var(--s-5); margin-block-start: var(--s-3); font-size: var(--t-xs); color: var(--text-3); }
.ch-legend span { display: inline-flex; align-items: center; gap: var(--s-2); }
.ch-legend b { color: var(--text); font-variant-numeric: tabular-nums; font-weight: 600; }
.ch-legend i { width: 14px; height: 2px; background: var(--ch-line); }
.ch-legend i.alt { background: var(--ch-2); }

/* ─── 15. УТИЛИТЫ ──────────────────────────────────────────────────────
   Набор классов, которым собирается страница без единой новой строчки CSS.

   ЗАКОН: любое значение здесь берётся из шкалы в tokens.css. Класса с
   произвольным числом (.mt-13, .w-347) в этом файле не появится никогда —
   именно так утилитарный слой превращается в свалку и перестаёт быть
   системой. Нужен размер, которого нет в шкале, — значит либо он не нужен,
   либо шкала неполна, и правится шкала.

   Порядок разделов: поток → расстояния → выравнивание → размеры →
   типографика → цвет → линии → положение → адаптив.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── поток ────────────────────────────────────────────────────────────*/

.block   { display: block; }
.iblock  { display: inline-block; }
.flex    { display: flex; }
.iflex   { display: inline-flex; }
.none    { display: none; }
.col     { flex-direction: column; }
.grow    { flex: 1 1 auto; min-width: 0; }
.fixed-w { flex: none; }

/* .grid и .g-2…4 объявлены в разделе 3; здесь только то, чего там нет */
.g-1     { grid-template-columns: minmax(0, 1fr); }
.g-5     { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.g-6     { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.g-side  { grid-template-columns: minmax(0, 1fr) minmax(0, 300px); }
.g-auto  { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.span-2  { grid-column: span 2; }
.span-3  { grid-column: span 3; }
.span-all{ grid-column: 1 / -1; }

/* ── расстояния: только ступени шкалы ─────────────────────────────────*/

.gap-1 { gap: var(--s-1); }  .gap-2 { gap: var(--s-2); }
.gap-3 { gap: var(--s-3); }  .gap-4 { gap: var(--s-4); }
.gap-5 { gap: var(--s-5); }  .gap-6 { gap: var(--s-6); }
.gap-7 { gap: var(--s-7); }  .gap-0 { gap: 0; }

.mt-1 { margin-block-start: var(--s-1); }
.mt-2 { margin-block-start: var(--s-2); }
.mt-3 { margin-block-start: var(--s-3); }
.mt-4 { margin-block-start: var(--s-4); }
.mt-5 { margin-block-start: var(--s-5); }
.mt-6 { margin-block-start: var(--s-6); }
.mt-7 { margin-block-start: var(--s-7); }
.mt-8 { margin-block-start: var(--s-8); }
.mt-0 { margin-block-start: 0; }

.mb-1 { margin-block-end: var(--s-1); }
.mb-2 { margin-block-end: var(--s-2); }
.mb-3 { margin-block-end: var(--s-3); }
.mb-4 { margin-block-end: var(--s-4); }
.mb-5 { margin-block-end: var(--s-5); }
.mb-6 { margin-block-end: var(--s-6); }
.mb-7 { margin-block-end: var(--s-7); }
.mb-8 { margin-block-end: var(--s-8); }
.mb-0 { margin-block-end: 0; }

.p-2 { padding: var(--s-2); }  .p-3 { padding: var(--s-3); }
.p-4 { padding: var(--s-4); }  .p-5 { padding: var(--s-5); }
.p-6 { padding: var(--s-6); }  .p-0 { padding: 0; }

.px-3 { padding-inline: var(--s-3); }  .px-4 { padding-inline: var(--s-4); }
.px-5 { padding-inline: var(--s-5); }  .px-6 { padding-inline: var(--s-6); }
.py-2 { padding-block: var(--s-2); }   .py-3 { padding-block: var(--s-3); }
.py-4 { padding-block: var(--s-4); }   .py-5 { padding-block: var(--s-5); }
.py-6 { padding-block: var(--s-6); }   .py-7 { padding-block: var(--s-7); }

/* .stack задаёт вертикальный ритм; шаг переопределяется своей переменной,
   а не отступами у детей — иначе ритм расползается по всей разметке */
.flow-2 { --flow: var(--s-2); }  .flow-3 { --flow: var(--s-3); }
.flow-4 { --flow: var(--s-4); }  .flow-5 { --flow: var(--s-5); }
.flow-6 { --flow: var(--s-6); }  .flow-7 { --flow: var(--s-7); }

/* ── выравнивание ─────────────────────────────────────────────────────*/

.i-start    { align-items: flex-start; }
.i-center   { align-items: center; }
.i-end      { align-items: flex-end; }
.i-base     { align-items: baseline; }
.i-stretch  { align-items: stretch; }

.j-start    { justify-content: flex-start; }
.j-center   { justify-content: center; }
.j-end      { justify-content: flex-end; }
.j-between  { justify-content: space-between; }

.self-start { align-self: start; }
.self-end   { align-self: end; }

/* ── размеры ──────────────────────────────────────────────────────────*/

.full   { width: 100%; }
.h-full { height: 100%; }
.narrow { max-width: var(--wrap-read); }
.m-tight{ max-width: var(--measure-tight); }
.m-txt  { max-width: var(--measure); }
.m-read { max-width: var(--measure-read); }
.sq     { aspect-ratio: 1; }
.wide-16{ aspect-ratio: 16 / 9; }
.cover-fit { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── типографика ──────────────────────────────────────────────────────*/

.t-2xs  { font-size: var(--t-2xs); }
.t-xs   { font-size: var(--t-xs); }
.t-sm   { font-size: var(--t-sm); }
.t-base { font-size: var(--t-base); }
.t-md   { font-size: var(--t-md); }
.t-lg   { font-size: var(--t-lg); }
.t-xl   { font-size: var(--t-xl); }
.t-2xl  { font-size: var(--t-2xl); }
.t-3xl  { font-size: var(--t-3xl); }

.fw-5 { font-weight: 500; }  .fw-6 { font-weight: 600; }
.fw-7 { font-weight: 700; }  .fw-8 { font-weight: 800; }

.mono    { font-family: var(--mono); }
.upper   { text-transform: uppercase; }
.tight   { letter-spacing: var(--tr-tight); }
.flat    { letter-spacing: var(--tr-flat); }
.wide    { letter-spacing: var(--tr-wide); }
.lh-1    { line-height: var(--lh-1); }
.lh-2    { line-height: var(--lh-2); }
.lh-3    { line-height: var(--lh-3); }
.tabular { font-variant-numeric: tabular-nums; }
.balance { text-wrap: balance; }
.pretty  { text-wrap: pretty; }
.center  { text-align: center; }
.end     { text-align: end; }
.nowrap  { white-space: nowrap; }

/* Обрезка по строкам: длинное название не имеет права ломать сетку */
.cut-1, .cut-2, .cut-3 {
  display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
}
.cut-1 { -webkit-line-clamp: 1; }
.cut-2 { -webkit-line-clamp: 2; }
.cut-3 { -webkit-line-clamp: 3; }

/* ── цвет ─────────────────────────────────────────────────────────────*/

.t-1  { color: var(--text); }
.t-2  { color: var(--text-2); }
.t-3  { color: var(--text-3); }
.t-4  { color: var(--text-4); }
.t-up { color: var(--up); }
.t-dn { color: var(--down); }

.bg-surface { background: var(--surface); }
.bg-field   { background: var(--bg); }
.bg-ink     { background: var(--ink); color: var(--bg); }

/* ── линии ────────────────────────────────────────────────────────────*/

.rule-t    { border-block-start: var(--bd) solid var(--hair); }
.rule-b    { border-block-end:   var(--bd) solid var(--hair); }
.rule-hard { border-block-end:   var(--bd-2) solid var(--hair-hard); }
.no-rule   { border: 0; }

/* ── положение ────────────────────────────────────────────────────────*/

.rel     { position: relative; }
.abs     { position: absolute; }
.sticky  { position: sticky; top: var(--s-4); z-index: var(--z-sticky); }
.z-head  { z-index: var(--z-head); }
.z-over  { z-index: var(--z-over); }

/* ── служебное ────────────────────────────────────────────────────────*/

.sr { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); }
.clickable { cursor: pointer; }
.no-select { user-select: none; }

/* ── адаптив ──────────────────────────────────────────────────────────
   Два порога, оба совпадают с --bp-* в tokens.css. Больше порогов — больше
   мест, где раскладка расходится сама с собой. */

@media (max-width: 980px) {
  .hide-md { display: none; }
  .g-side  { grid-template-columns: minmax(0, 1fr); }
  .g-5, .g-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
  .hide-sm { display: none; }
  .show-sm { display: block; }
  .g-5, .g-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sm-col  { flex-direction: column; align-items: flex-start; }
  .sm-full { width: 100%; }
}
@media (min-width: 701px) { .show-sm { display: none; } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ─── 15b. ЧЕГО НЕ ХВАТАЛО ─────────────────────────────────────────────
   Дописано после аудита: каждая утилита здесь появилась потому, что без неё
   в разметке уже стоял инлайн-стиль. Это не «на будущее» — это закрытие
   конкретных дыр, через которые в проект лезли произвольные числа.

   Правило прежнее: значения только из шкалы. Единственное исключение —
   меры в ch, они привязаны к кеглю, а не к сетке отступов.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── списки ───────────────────────────────────────────────────────────
   Сброс маркеров писался инлайном трижды подряд. */
.bare { list-style: none; margin: 0; padding: 0; }

/* ── мера строки в символах ───────────────────────────────────────────
   Длина строки задаётся кеглем, а не сеткой: 18ch у заголовка и 18ch у
   подписи — это разная физическая ширина, и так и должно быть. */
.ch-18 { max-width: 18ch; }
.ch-22 { max-width: 22ch; }
.ch-30 { max-width: 30ch; }
.ch-38 { max-width: 38ch; }
.ch-46 { max-width: 46ch; }
.w-3ch { width: 3.5ch; }        /* колонка под дельту: ±NN не прыгает */

/* ── трекинг ──────────────────────────────────────────────────────────
   Раньше межбуквенные писались числами прямо в компонентах. */
.tr-tight { letter-spacing: var(--tr-tight); }
.tr-flat  { letter-spacing: var(--tr-flat); }
.tr-wide  { letter-spacing: var(--tr-wide); }
.tr-wider { letter-spacing: 0.2em; }
.tr-none  { letter-spacing: 0; }

/* ── кегль вне шкалы ──────────────────────────────────────────────────
   Крупные числа на витрине живут по своим правилам: это не текст, а
   изображение цифры. Отдельная ступень, а не clamp по месту. */
.t-num { font-size: var(--t-num); line-height: var(--lh-1); }
.pct   { font-size: .3em; }              /* знак процента при крупном числе */
.place-mid { align-content: center; }    /* содержимое по центру сетки */
.line-2 { grid-template-columns: 1fr auto; }

/* ── прозрачность и наложение ─────────────────────────────────────────*/
.o-0  { opacity: 0; }
.o-40 { opacity: .4; }
.o-70 { opacity: .7; }
.o-100 { opacity: 1; }

/* ── переполнение ─────────────────────────────────────────────────────*/
.ovf-hidden { overflow: hidden; }
.ovf-x      { overflow-x: auto; scrollbar-width: none; }
.ovf-x::-webkit-scrollbar { display: none; }

/* ── движение ─────────────────────────────────────────────────────────
   Только transform и opacity — остальное вызывает пересчёт раскладки. */
.tr-fast { transition: transform var(--fast) var(--ease), opacity var(--fast) var(--ease); }
.tr-mid  { transition: transform var(--mid) var(--ease), opacity var(--mid) var(--ease); }
.lift:hover { transform: translateY(-1px); }
.press:active { transform: translateY(1px); }

/* ── состояния ────────────────────────────────────────────────────────
   Аналог hover: из Tailwind. Полного набора префиксов у нас нет и не
   нужно: в монохроме на наведении меняются три вещи — яркость текста,
   подчёркивание и линия. */
.hov-ink:hover      { color: var(--text); }
.hov-under:hover    { text-decoration: underline; text-underline-offset: 3px; }
.hov-rule:hover     { border-color: var(--text); }

/* ── адаптив: ступени, а не один порог ────────────────────────────────
   Префиксы вида md:g-2 в CSS без сборщика не сделать, поэтому явные
   классы под самые частые перестроения. Пороги те же, что в --bp-*. */
@media (max-width: 980px) {
  .md-1   { grid-template-columns: minmax(0, 1fr); }
  .md-2   { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .md-col { flex-direction: column; align-items: flex-start; }
  .md-hide { display: none; }
  .md-full { width: 100%; max-width: none; }
}

@media (max-width: 700px) {
  .sm-1    { grid-template-columns: minmax(0, 1fr); }
  .sm-col  { flex-direction: column; align-items: flex-start; }
  .sm-hide { display: none; }
  .sm-start { text-align: start; }
  .sm-t-sm { font-size: var(--t-sm); }
}

/* ─── 16. КРОПМАРКИ ────────────────────────────────────────────────────
   Типографский приём: блок обозначен четырьмя уголками, рамки нет вовсе.
   Восемь фоновых градиентов вместо псевдоэлементов — так уголки не мешают
   содержимому и работают на любом фоне. */

.crop {
  --m: 20px;              /* длина уголка */
  --w: 1px;               /* толщина */
  --off: 7px;             /* вынос наружу: уголки стоят на поле, не на плашке */
  position: relative;
  padding: var(--s-4);
  background-color: var(--surface);
}

/* Кропмарки живут на псевдоэлементе с отрицательным inset — поэтому они
   отстоят от плашки и читаются как метки реза на печатном листе, а не как
   рамка блока. */
.crop::after {
  content: "";
  position: absolute;
  inset: calc(var(--off) * -1);
  pointer-events: none;
  background-image:
    linear-gradient(var(--mark), var(--mark)), linear-gradient(var(--mark), var(--mark)),
    linear-gradient(var(--mark), var(--mark)), linear-gradient(var(--mark), var(--mark)),
    linear-gradient(var(--mark), var(--mark)), linear-gradient(var(--mark), var(--mark)),
    linear-gradient(var(--mark), var(--mark)), linear-gradient(var(--mark), var(--mark));
  background-repeat: no-repeat;
  background-size:
    var(--m) var(--w), var(--w) var(--m),
    var(--m) var(--w), var(--w) var(--m),
    var(--m) var(--w), var(--w) var(--m),
    var(--m) var(--w), var(--w) var(--m);
  background-position:
    left top, left top,
    right top, right top,
    left bottom, left bottom,
    right bottom, right bottom;
}

.crop-tight { padding: var(--s-3); }
.crop-lg { padding: var(--s-5); }

/* Карточка каталога: подпись сверху, заголовок капсом, данные внизу.
   Порядок как в печатной картотеке — сначала откуда, потом что. */
.card {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--s-5);
  min-height: 230px;
  transition: background var(--fast) var(--ease);
}

.card:hover { background-color: var(--surface); }

.card-top {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  font-family: var(--mono);
  font-size: var(--t-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
}

.card-h {
  font-size: var(--t-lg);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-wrap: balance;
}

.card-h.big { font-size: var(--t-xl); }

.card-bot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-4);
  font-family: var(--mono);
  font-size: var(--t-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
}

/* Число как обложка: заполняет карточку так же, как в референсе — арт. */
.card-num {
  font-size: clamp(44px, 7vw, 86px);
  font-weight: 700;
  line-height: 0.84;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
  align-self: center;
  justify-self: end;
}

/* ─── 17. МАСТХЕД ──────────────────────────────────────────────────────
   Вордмарк разнесён по краям экрана: это не логотип в углу, а полоса
   типографики во всю ширину. */

/* Two rows: wordmark alone, then navigation and status side by side under
   it. The wordmark is deliberately smaller than the reference's — theirs is
   a two-word lockup spanning the full width, ours is four characters and at
   that size would read as a shouty logo rather than a masthead. */
.masthead {
  display: grid;
  gap: var(--s-2);
  padding-block: var(--s-3) var(--s-2);
  border-block-end: var(--bd) solid var(--mark);
}

/* First row: the label sits right against the wordmark, sharing its
   baseline, the way a strapline hangs off a masthead in print. Centring it
   on the full width left it floating in dead space — attached to the logo
   it reads as part of the lockup. */
/* Flex with baseline alignment, not grid with end alignment.
   The wordmark scales with clamp(), so its box height changes with the
   viewport — anything aligned to that box needs a different nudge at every
   width, which is exactly the trap the previous version fell into. Baseline
   is computed by the browser from the glyphs themselves and holds at any
   size, with no magic numbers. */
/* Три колонки: знак слева, строчка о сайте по центру полосы, служебное
   справа. Центр считает сетка, а не отступы — подпись стоит по середине
   экрана независимо от длины знака и того, что справа. */
.mast-top {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--s-4);
}

.mast-word {
  font-family: var(--font-display);
  font-size: clamp(34px, 5.2vw, 68px);
  font-weight: 800;
  line-height: 0.82;
  letter-spacing: var(--tr-tight);
  text-transform: uppercase;
}

/* Second row. Navigation left, status right — the same split the reference
   uses under its lockup. */
.mast-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  flex-wrap: wrap;
}

/* The label shares the wordmark's baseline. Its own box is centred around
   that line by the padding, so the brackets sit symmetrically above and
   below the letters' feet rather than hanging under them. */
.mast-mid {
  justify-self: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-2xs);
  letter-spacing: 0.2em;      /* шире --tr-wide: подпись читается как знак */
  color: var(--text-3);
  text-align: center;
  padding: 0.6em var(--s-5);
  border-inline: var(--bd) solid var(--mark);
  white-space: nowrap;
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
}

/* Источники в той же строке, отделены точкой-разделителем и приглушены:
   первое — что делаем, второе — откуда цифры. */
.mast-mid small {
  font-size: 0.85em;
  letter-spacing: var(--tr-wide);
  color: var(--text-4);
}
.mast-mid small::before { content: "·"; margin-inline-end: var(--s-3); }

.mast-nav {
  display: flex;
  gap: var(--s-5);
  font-family: var(--mono);
  font-size: var(--t-2xs);
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  overflow-x: auto;
  scrollbar-width: none;
}

.mast-side {
  font-family: var(--mono);
  font-size: var(--t-2xs);
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  text-align: end;
  white-space: nowrap;
}

.mast-nav::-webkit-scrollbar { display: none; }
.mast-nav a { color: var(--text-3); white-space: nowrap; }
.mast-nav a:hover, .mast-nav a[aria-current] { color: var(--text); }

.mast-meta {
  font-family: var(--mono);
  font-size: var(--t-2xs);
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  color: var(--text-3);
  text-align: end;
  white-space: nowrap;
}

@media (max-width: 760px) {
  .masthead { flex-wrap: wrap; }
  .mast-mid { display: none; }
  .mast-word { font-size: clamp(46px, 17vw, 96px); }
}

/* ─── 18. СЕТКА КАТАЛОГА ───────────────────────────────────────────────
   Неравные плитки, как в печатном развороте: главный материал занимает
   два столбца и два ряда, остальные встают вокруг. */

.cat-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-4);
}

.cat-grid > .span-2 { grid-column: span 2; }
.cat-grid > .row-2 { grid-row: span 2; }

@media (max-width: 1000px) {
  .cat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
  .cat-grid { grid-template-columns: minmax(0, 1fr); }
  .cat-grid > .span-2 { grid-column: span 1; }
}

/* ─── 19. ЧЁРНАЯ ПОЛОСА ────────────────────────────────────────────────
   Шапка — плашка чернил во всю ширину, а вордмарк на ней набран цветом
   фона страницы. Приём печатного каталога: буквы кажутся вырезанными. */

.bar {
  background: var(--ink);
  color: var(--bg);
  padding-block: var(--s-3);
}

.bar .mast-word { color: var(--bg); }
.bar .mast-mid { color: #8d8c88; border-color: #3a3936; }
.bar .mast-nav a { color: #9d9c98; }
.bar .mast-nav a:hover, .bar .mast-nav a[aria-current] { color: var(--bg); }
.bar .mast-meta { color: #8d8c88; }
.bar .btn-tg { color: #9d9c98; }
.bar .btn-tg:hover { color: var(--bg); }
.bar .masthead { border: 0; padding-block: 0; }

/* Инверсная карточка: одна на разворот, держит внимание вместо цвета. */
.card-ink {
  background: var(--ink);
  color: var(--bg);
  --mark: #4a4945;
}
.card-ink .card-top, .card-ink .card-bot { color: #9d9c98; }
.card-ink:hover { background: #1d1d1a; }
.card-ink .d-up { color: #6fe0a4; }
.card-ink .d-dn { color: #ff8878; }

/* ─── 20. ПОЛНАЯ ШИРИНА ────────────────────────────────────────────────
   Референс не знает контейнера: вордмарк упирается в края экрана, сетка
   каталога идёт от кромки до кромки. Контейнер тут читался бы как
   «сайт на шаблоне», а нам нужен разворот. */

.bleed { width: 100%; padding-inline: clamp(12px, 1vw, 16px); }

.bar .bleed { padding-inline: clamp(10px, 1vw, 16px); }

/* Вордмарк во всю полосу: кегль считается от ширины экрана, а не от шкалы. */
.mast-word { font-size: clamp(56px, 14.5vw, 210px); line-height: 0.74; }

.mast-mid {
  white-space: nowrap;      /* «PREDICTION MARKETS» не имеет права переноситься */
  align-self: flex-end;
  margin-block-end: 0.35em;
  letter-spacing: 0.3em;
  border: 0;
  padding: 0;
  position: relative;
  padding-inline: var(--s-4);
}

/* та же подпись, взятая в кропмарки — как в референсе */
.mast-mid::before, .mast-mid::after {
  content: "";
  position: absolute;
  top: -6px; bottom: -6px;
  width: 7px;
  border: var(--bd) solid currentColor;
}
.mast-mid::before { left: 0; border-inline-end: 0; }
.mast-mid::after { right: 0; border-inline-start: 0; }

/* Карточки становятся выше: в референсе воздух внутри блока — половина эффекта. */
.card { aspect-ratio: 1; }
.cat-grid > .row-2 { aspect-ratio: auto; }

@media (max-width: 760px) {
  .card { aspect-ratio: 1; }
  .cat-grid > .row-2 { min-height: 380px; }
}

/* ─── 21. БЛОК ПОСТА ───────────────────────────────────────────────────
   Раскладка как в референсе: подпись сверху, заголовок под ней слева,
   визуал прижат в нижний правый угол, мета — в нижнем левом. Между
   заголовком и визуалом воздух, и он тут работает как часть композиции. */

.post {
  display: grid;
  grid-template-rows: auto auto 1fr auto;
  gap: var(--s-3);
  aspect-ratio: 1;
}

.post-h {
  font-size: clamp(19px, 1.5vw, 30px);
  font-weight: 700;
  line-height: 0.96;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  max-width: 18ch;
}

.post-lead .post-h { font-size: clamp(30px, 3.1vw, 58px); max-width: 14ch; }

/* Визуал стоит на месте обложки: прижат вправо, занимает нижнюю часть. */
.post-art {
  align-self: end;
  justify-self: end;
  display: grid;
  justify-items: end;
  gap: var(--s-2);
  max-width: 76%;
}

.post-art .num-big {
  font-size: clamp(46px, 5.4vw, 104px);
  font-weight: 700;
  line-height: 0.8;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
}

.post-art .chart { width: 100%; max-width: 320px; }

.post-foot {
  display: flex;
  justify-content: space-between;
  gap: var(--s-3);
  font-family: var(--mono);
  font-size: var(--t-2xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-3);
}

@media (max-width: 760px) {
  .post { aspect-ratio: 4 / 3; }
  .post-art { max-width: 100%; }
}

/* Плашка поста лежит на более тёмном поле — как в референсе. Кропмарки при
   этом остаются на самой плашке, а не на фоне. */
.crop.card-ink { background-color: var(--ink); }
.cat-grid { gap: var(--s-5); }

/* ─── 22. КОМПАКТНАЯ ШАПКА ─────────────────────────────────────────────
   Именованная сетка: три колонки, две строки.

       word  mid   tg
       nav   mid   upd

   Раскладка описана областями, а не порядком в разметке — поэтому кнопка
   гарантированно стоит на линии знака, а время на линии навигации, и это
   не зависит от того, в каком порядке элементы лежат в HTML.
   ═══════════════════════════════════════════════════════════════════════ */

.bar-tight .masthead {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas:
    "word mid tg"
    "nav  mid upd";
  align-items: center;
  column-gap: var(--s-5);
  row-gap: var(--s-3);
  padding-block: var(--s-1) 0;
  border: 0;
}

/* Оптический вынос влево: у глифа есть собственный боковой пробел, из-за
   него буквы не доходят до кромки плашки. Значение в em, поэтому держится
   при любом кегле. */
.bar-tight .mast-word {
  grid-area: word;
  justify-self: start;
  align-self: end;
  font-size: clamp(34px, 4.2vw, 62px);
  line-height: 0.86;
  letter-spacing: var(--tr-tight);
  margin-inline-start: -0.055em;
}

.bar-tight .mast-nav {
  grid-area: nav;
  justify-self: start;
  padding: 0;
  gap: clamp(12px, 1.8vw, 30px);
}

/* Центральная колонка занимает обе строки и стоит ровно по центру экрана:
   боковые колонки равны по 1fr, поэтому середина не съезжает от того, что
   слева навигация, а справа одна кнопка. */
.bar-tight .mast-mid {
  grid-area: mid / mid / mid / mid;
  grid-row: 1;                /* первая строка: на высоте знака, не всей шапки */
  justify-self: center;
  align-self: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--t-2xs);
  letter-spacing: 0.2em;      /* шире --tr-wide: строка читается как знак */
  color: var(--text-3);
  text-align: center;
  white-space: nowrap;
  padding: 0.15em var(--s-4);
  border-inline: var(--bd) solid var(--mark);
}

.btn-tg, .btn-tg-empty {
  grid-area: tg;
  justify-self: end;
  align-self: center;         /* по центру знака, а не по его нижней кромке */
}

.bar-tight .mast-meta {
  grid-area: upd;
  justify-self: end;
  padding: 0;
  white-space: nowrap;
}

/* Кнопка канала. Обводка, а не заливка: заливка тянула бы внимание с числа
   на карточке, а число здесь главное. */
.btn-tg {
  display: inline-block;
  font-family: var(--mono);
  font-size: var(--t-2xs);
  letter-spacing: var(--tr-wide);
  text-transform: uppercase;
  padding: var(--s-2) var(--s-4);
  border: var(--bd) solid currentColor;
  white-space: nowrap;
  transition: color var(--fast) var(--ease);
}

@media (max-width: 980px) {
  .bar-tight .masthead {
    grid-template-columns: 1fr auto;
    grid-template-areas: "word tg" "nav upd";
  }
  .bar-tight .mast-mid { display: none; }
}

@media (max-width: 700px) {
  .bar-tight .masthead {
    grid-template-columns: 1fr;
    grid-template-areas: "word" "nav" "tg";
  }
  .bar-tight .mast-meta { display: none; }
  .btn-tg { justify-self: start; }
}

/* ─── 23. ЗАСТАВКА СТУДИИ ──────────────────────────────────────────────
   Один экран: знак, строка, «press start». Никакой шапки — навигации пока
   нет, а пустая полоса сверху обещает разделы, которых не существует, и
   читается как недоделка. Шапка появится, когда игр станет две.

   Палитра прежняя, серая: монохром плюс пиксель — это ранние чёрно-белые
   игры, а не кислотный ретро-шаблон. Цвет по-прежнему принадлежит данным,
   поэтому здесь его нет вовсе.
   ────────────────────────────────────────────────────────────────────────*/

.hold {
  position: relative;
  min-height: 100dvh;
  display: grid;
  place-content: center;
  padding: var(--gutter);
  overflow: hidden;
}

/* Сетка точек — фон, из которого «собран» экран. Рисуется градиентом, а не
   картинкой: ноль запросов, и шаг привязан к --px, поэтому не разъезжается
   с остальной пиксельной геометрией. */
/* Точка --n-06, а не --hair: волосяная ступень задана против светлой
   карточки, а здесь фон — само серое поле, и на нём она пропадает вовсе.
   Точка в две клетки, не в одну: одиночный пиксель съедается масштабом
   экрана и виден не у всех. */
.hold::before {
  content: "";
  position: absolute;
  inset: calc(var(--px) * -8);
  background-image: radial-gradient(var(--n-06) 2px, transparent 2px);
  background-size: var(--px-4) var(--px-4);
  opacity: 0.5;
  pointer-events: none;
}

.hold > * { position: relative; }

/* Канвас «Жизни» — между сеткой точек и текстом. Не в ::before, потому что
   псевдоэлементу нельзя отдать canvas, и не поверх содержимого: фон обязан
   оставаться фоном. */
.hold-life {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.hold-word {
  font-family: var(--font-pixel);
  font-size: clamp(28px, 1rem + 5vw, 76px);
  line-height: var(--lh-1);
  letter-spacing: 0;              /* пиксельный шрифт уже несёт свой ритм */
  color: var(--ink);
  text-transform: uppercase;

  /* Ступенчатая тень вместо размытой: тень пиксельной игры — это смещённая
     копия, а не градиент. Шаг равен клетке, поэтому край остаётся чётким. */
  text-shadow: var(--px) var(--px) 0 var(--n-07);
}

.hold-sub {
  margin-top: var(--s-5);
  font-family: var(--font-pixel);
  font-size: clamp(8px, 0.5rem + 0.4vw, 11px);
  line-height: 1.9;
  letter-spacing: 0.06em;
  color: var(--text-2);
  text-transform: uppercase;
}

/* «Press start» — не кнопка, а приглашение, как на экране запуска. Мигает
   ступенями, без плавности: плавное затухание сразу читается как современный
   интерфейс и ломает всю отсылку. */
.hold-start {
  display: inline-block;
  margin-top: var(--s-7);
  padding: var(--px-2) var(--px-4);
  border: 0;
  background: var(--ink);
  color: var(--n-01);
  font-family: var(--font-pixel);
  font-size: clamp(9px, 0.5rem + 0.5vw, 13px);
  text-transform: uppercase;
  text-decoration: none;
  box-shadow: var(--px) var(--px) 0 var(--n-08);
  animation: hold-blink 1.2s steps(1, end) infinite;
}

.hold-start:hover,
.hold-start:focus-visible {
  animation: none;
  transform: translate(var(--px), var(--px));
  box-shadow: 0 0 0 var(--n-08);   /* «вдавливается» на свою же тень */
}

@keyframes hold-blink {
  0%, 60%  { opacity: 1; }
  61%, 100% { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
  .hold-start { animation: none; }
}

