/* ============ Hodlometer design system ============
   Палитра построена на Radix Colors 3 (github.com/radix-ui/colors), значения вкопированы
   хексами — рантайм-зависимости нет, шкала и шаг указаны в комментарии у каждой группы.
   Шкалы: slate (нейтрали), teal (бренд), jade/red/amber (статусы),
   indigo→cyan→slate→amber→tomato (термометр гейджа).
   Ступени Radix: 3 — мягкий фон, 5/6 — границы, 9 — насыщенная заливка,
   10 — hover-заливка, 11 — текст на мягком фоне, 12 — основной текст.

   Здесь живут ТОКЕНЫ (:root + тёмная тема) и компоненты, которые есть только в KURS
   (графики, прогнозы, портфель, админка). Всё, что видно на обоих движках — шапка,
   подвал, карточка, кнопка, чип, таблица, лонгрид, фокус — в assets/css/components.css.
   :root целиком уезжает в тему /learn/ через wp-theme/sync.mjs: новые значения добавлять
   токенами сюда, а не хардкодом в theme.css. */
:root {
  /* нейтрали — slate 1…12 */
  --bg: #f0f0f3;          /* slate 3 */
  --card: #ffffff;
  --card-2: #f9f9fb;      /* slate 2 */
  --ink: #1c2024;         /* slate 12 */
  --ink2: #60646c;        /* slate 11 */
  --muted: #686c75;       /* между slate 10 и 11: slate 10 даёт на белом 3.8:1 — ниже AA */
  --line: #e0e1e6;        /* slate 5 */
  --line-soft: #e8e8ec;   /* slate 4 */

  /* бренд — teal */
  --brand: #007c6b;       /* teal 11, на полтона темнее: teal 11 как есть даёт на --bg 4.0:1 */
  --brand-2: #12a594;     /* teal 9 — акцент в графиках и прогресс-барах */
  --brand-ink: #0d3d38;   /* teal 12 */
  --brand-bg: #e0f8f3;    /* teal 3 */
  --focus: #007c6b;       /* = --brand: teal 7 давал 1.83:1 на фоне, кольцо фокуса требует 3:1 */
  --brand-hover: #0d3d38; /* teal 12 — заливка кнопки на hover (в тёмной, наоборот, светлеет) */
  --brand-solid: var(--brand);  /* заливка primary-кнопки: в светлой теме = --brand */
  --on-solid: #ffffff;    /* текст поверх насыщенных заливок (.btn, .btn.danger, аватар) */

  /* монеты — внешние бренд-цвета, вне шкал Radix */
  --btc: #DD7A00;
  --btc-soft: #F7931A;
  --eth: #5A68D6;
  --eth-soft: #6472E0;

  /* статусы — jade / red / amber, ступени 11 (текст) и 3 (фон).
     У jade и amber ступень 11 не дотягивает до 4.5:1 на своей же ступени 3 — притемнены. */
  --up: #1d7a61;
  --up-bg: #e6f7ed;
  --down: #ce2c31;
  --down-bg: #feebec;
  --warn: #9c5c00;
  --warn-bg: #fff7c2;
  --neutral-bg: #f0f0f3;  /* slate 3 */

  /* Термометр Hodlometer Index: 1 Deep Freeze → 5 Overheated. Расходящаяся порядковая
     шкала: холод → нейтраль → тепло. Ступени пере-шагнуты в D3a по измерениям, а не на глаз
     (OKLCH-светлота, контраст к обеим поверхностям, симуляция протан/дейтан):
       z3 8b8d98 → 80838d  ΔL к z2 0.015→0.049, к белой карточке 3.30→3.78:1, CVD 7.3→8.5
       z4 ffc53d → ef5f00  L .854→.662: янтарь давал 1.58:1 к белой карточке («Warm» пропадал
                           в светлой теме) и 11.15:1 к тёмной — кричал громче белого числа
       z5 e54d2e → d13415  L .627→.566, держит разрыв светлоты от нового z4
     `-ink` — текст чипа на своём `-bg`, все пять пар ≥4.8:1 в обеих темах; z4 переехал
     с янтарной пары Radix на оранжевую. */
  --therm-1: #3e63dd; --therm-1-bg: #edf2fe; --therm-1-ink: #3a5bc7;  /* indigo */
  --therm-2: #00a2c7; --therm-2-bg: #def7f9; --therm-2-ink: #0f748d;  /* cyan   */
  --therm-3: #80838d; --therm-3-bg: #f0f0f3; --therm-3-ink: #60646c;  /* slate  */
  --therm-4: #ef5f00; --therm-4-bg: #ffefd6; --therm-4-ink: #b04300;  /* orange */
  --therm-5: #d13415; --therm-5-bg: #feebe7; --therm-5-ink: #c53013;  /* tomato */

  /* Палитра серий графиков. Серия — это ЛИБО актив (носит токен актива), ЛИБО метрика
     (носит --data-line): смысл в этом случае несут зоны. Третьего не дано.
     --brand/--brand-2 в графиках запрещены: бренд-цвет означает «интерактивное». */
  --data-btc: var(--btc);
  --data-eth: var(--eth);
  --data-line: var(--ink2);      /* сама метрика: Mayer, F&G */
  --data-line-2: var(--ink);     /* вторая серия того же типа */
  --data-ref: var(--muted);      /* опорные линии, всегда пунктир 4 4 */
  --data-grid: var(--line-soft);
  --data-axis: var(--line);

  /* Тон чипа AI-источника. Имя токена — ключ источника в БД (`gemini`), а не подпись:
     публично он называется «AI» (карта — SRC_NAMES в app.js). */
  --gemini-bg: #edf2fe; --gemini-ink: #3a5bc7;   /* indigo 3 / 11 */

  --tip-bg: #1c2024; --tip-ink: #ffffff; --tip-muted: #b0b4ba;

  /* Радиусы — четыре, больше быть не должно: карточка / контрол / инлайн / пилюля.
     Мобильного оверрайда 14px нет: карточка одного радиуса на всех ширинах. */
  --radius: 16px;      /* карточка */
  --radius-s: 10px;    /* кнопка, поле, поповер, вложенная поверхность */
  --radius-xs: 6px;    /* инлайн-код, свотч, конец полосы */
  --radius-pill: 999px;

  /* Высоты кликабельных элементов — ровно три */
  --control-h: 40px;
  --control-h-sm: 32px;
  --control-h-xs: 24px;

  /* Тени: покой, наведение на карточку, поповер, активный сегмент. Пятой нет. */
  --shadow: 0 1px 2px rgba(28, 32, 36, .05), 0 10px 28px -16px rgba(28, 32, 36, .14);
  --shadow-hover: var(--shadow), 0 0 0 1px var(--line);
  --shadow-pop: 0 2px 6px -2px rgba(28, 32, 36, .10), 0 14px 34px -10px rgba(28, 32, 36, .26);
  --shadow-inset-sm: 0 1px 3px rgba(28, 32, 36, .14);

  /* Движение: две длительности на всё интерактивное. Было четыре почти неразличимых
     (.15/.16/.18/.2). Третья, --dur-slow, нужна ровно одному сценарию — затуханию
     подсветки :target в глоссарии: её задача не «отреагировать», а дать глазу время
     найти термин среди 47 и уйти, не оставив цветного пятна на странице. */
  --dur-fast: 120ms;
  --dur: 200ms;
  --dur-slow: 1200ms;
  --ease: cubic-bezier(.2, .8, .3, 1);
  --font: "Inter Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  /* Space Grotesk без кириллицы: русские заголовки автоматически падают на Inter */
  --font-display: "Space Grotesk", "Inter Variable", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Типографическая шкала — одна на оба движка, девять ступеней и ни одного значения вне
     таблицы. До D3a рядом с шестью токенами жили 25 захардкоженных кеглей, из них 13 ступеней
     с шагом 0.5px между 11 и 17 — иерархии это не давало, разнобой давало.
     Полоса 13.5–16.5 схлопнута в --fs-sm 13 / --fs-base 15 / --fs-h3 17.
     Значения на узких экранах переопределяются в components.css (переопределяем токены,
     а не правила); ступени применяются там же, здесь — только источник правды. */
  --fs-4xl: 60px;       --lh-4xl: 1;       /* только .err-code */
  --fs-3xl: 44px;       --lh-3xl: 1.05;    /* hero-число, ровно одно на экран */
  --fs-2xl: 34px;       --lh-2xl: 1.1;     /* значение показания (.read-val) */
  --fs-xl: 26px;        --lh-xl: 1.15;     /* значение KPI (.stat-value), .hv-clock .num */
  --fs-h1: 40px;        --lh-h1: 1.1;
  --fs-h1-hero: 46px;   /* единственное исключение: герой главной */
  --fs-h2: 24px;        --lh-h2: 1.25;
  --fs-lg: 20px;        --lh-lg: 1.35;     /* h3 лонгрида, .gloss-term, название зоны гейджа */
  --fs-h3: 17px;        --lh-h3: 1.35;     /* заголовок карточки */
  --fs-prose: 17px;     --lh-prose: 1.7;   /* лонгрид */
  --fs-base: 15px;      --lh-base: 1.5;    /* интерфейс: сюда 14 / 14.5 / 15.5 / 16 */
  --fs-sm: 13px;        --lh-sm: 1.5;      /* мета, подписи: сюда 13.5 */
  --fs-xs: 12px;        --lh-xs: 1.3;      /* чипы, надзаголовки, th: сюда 11.5 / 12.5 */
  --fs-2xs: 11px;       --lh-2xs: 1.2;     /* только засечки осей SVG */

  /* Отступы: шкала 4px. Значений вне неё быть не должно — до D3a в трёх файлах жили
     57 различных padding и ~24 значения gap. Вёрстка использует семантические алиасы
     ниже, а не числа; на узких экранах переопределяются сами алиасы (components.css). */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
  --space-5: 20px;  --space-6: 24px;  --space-7: 32px;  --space-8: 40px;
  --space-9: 48px;  --space-10: 56px; --space-11: 64px; --space-12: 80px;

  --gap-grid: var(--space-4);        /* шаг между карточками, оба движка */
  --pad-card: var(--space-5);        /* внутренние поля карточки */
  --space-section: var(--space-10);  /* между секциями: было 26px при gap 16 — макро-ритма
                                        не возникало, страница читалась одной текстурой.
                                        Отношение к внутрисеточному шагу должно быть ≥3× */
  --space-block: var(--space-3);     /* надзаголовок → содержимое */
  --space-cta: var(--space-7);       /* содержимое секции → хвостовое действие. Строго между
                                        --gap-grid (16) и --space-section (56): при 16 CTA
                                        читается третьей карточкой ряда, при 56 — новой
                                        секцией. 16 : 32 : 56 = 1 : 2 : 3.5 */
  --space-page-top: var(--space-8);  /* шапка → h1, одинаково в обоих движках */

  /* Две ширины на весь сайт, третьей быть не должно */
  --measure-prose: 720px;   /* колонка чтения */
  --measure-full: 1140px;   /* содержимое .wrap за вычетом паддингов */
  /* Боковик с оглавлением: 720 + 48 (gap --space-9) + 260 = 1028 ≤ 1140. Третьей
     колонкой чтения не является — это служебная полоса, а не текст. */
  --side: 260px;

  color-scheme: light;
}

/* ---------- Тёмная тема (slate dark / teal dark и т.д.) ---------- */
:root[data-theme="dark"] {
  --bg: #111113;          /* slate dark 1 */
  --card: #18191b;        /* slate dark 2 */
  --card-2: #212225;      /* slate dark 3 */
  --ink: #edeef0;         /* slate dark 12 */
  --ink2: #b0b4ba;        /* slate dark 11 */
  --muted: #8b8f98;       /* между slate dark 10 и 11: 10 даёт на --card-2 3.8:1 */
  --line: #2e3135;        /* slate dark 5 */
  --line-soft: #272a2d;   /* slate dark 4 */

  --brand: #0eb39e;       /* teal dark 10 */
  --brand-2: #0bd8b6;     /* teal dark 11 */
  --brand-ink: #adf0dd;   /* teal dark 12 */
  --brand-bg: #0d2d2a;    /* teal dark 3 */
  --focus: #0eb39e;       /* = --brand: teal dark 7 давал 2.91:1 */
  --brand-hover: #0bd8b6; /* teal dark 11 */
  /* Заливка primary-кнопки на ступень темнее ссылки: teal dark 10 делал кнопку
     вторым по яркости пятном тёмного экрана. Ступень 9 держит 5.55:1 к --on-solid
     (порог 4.5) и перестаёт спорить с содержимым. Ссылки и кольцо фокуса при этом
     остаются на ступени 10 — им яркость нужна. */
  --brand-solid: #12a594; /* teal dark 9 */
  --on-solid: #06201d;    /* тёмный текст поверх ярких заливок */

  --btc: #F7931A;
  --btc-soft: #FFB04D;
  --eth: #8E9BF5;
  --eth-soft: #A3ADF8;

  --up: #1fd8a4;
  --up-bg: #0f2e22;
  --down: #ff9592;
  --down-bg: #3b1219;
  --warn: #ffca16;
  --warn-bg: #302008;
  --neutral-bg: #212225;

  /* Термометр: ступень 9 у Radix одинакова в обеих темах, поэтому четыре из пяти зон
     совпадают со светлыми. Своя ступень нужна только нейтрали (#7c8087 — 4.44:1
     к тёмной карточке против 3.43:1 у прежнего #696e77). */
  --therm-1: #3e63dd; --therm-1-bg: #182449; --therm-1-ink: #9eb1ff;
  --therm-2: #00a2c7; --therm-2-bg: #082c36; --therm-2-ink: #4ccce6;
  --therm-3: #7c8087; --therm-3-bg: #212225; --therm-3-ink: #b0b4ba;
  --therm-4: #ef5f00; --therm-4-bg: #331e0b; --therm-4-ink: #ffa057;
  --therm-5: #d13415; --therm-5-bg: #391714; --therm-5-ink: #ff977d;

  --gemini-bg: #182449; --gemini-ink: #9eb1ff;

  --tip-bg: #2e3135; --tip-ink: #edeef0; --tip-muted: #b0b4ba;

  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 10px 28px -16px rgba(0, 0, 0, .7);
  --shadow-pop: 0 2px 6px -2px rgba(0, 0, 0, .5), 0 14px 34px -10px rgba(0, 0, 0, .75);
  --shadow-inset-sm: 0 1px 3px rgba(0, 0, 0, .5);
  color-scheme: dark;
}

/* Моноширинные цифры — ровно четыре места: таблицы, определения, засечки осей и мета.
   На --fs-xl и выше — пропорциональные: на display-числах tabular разрежает «25.4»
   и число рассыпается. Класс .num остаётся, но теперь он значит только «выровнять вправо». */
table.tbl, .kv dd, .chart-tick, .meta-row, .comp-meta, .spark-axis, .provenance {
  font-variant-numeric: tabular-nums;
}

/* ---------- Сетки ---------- */
.grid { display: grid; gap: var(--gap-grid); }
/* У grid-элемента `min-width` по умолчанию `auto` = его min-content: карточка с широкой
   таблицей растягивает колонку шире экрана, и страница едет вбок (нашлось смоуком P6 на
   /tools/halving при 375px). Ноль возвращает право сжиматься, а прокрутку берёт на себя
   .tbl-wrap внутри карточки. */
.grid > * { min-width: 0; }
.grid-cards { grid-template-columns: repeat(4, 1fr); }
.grid-2 { grid-template-columns: 1fr 1fr; }
/* Там, где соседи заведомо разной длины, карточка не тянется по высоте более длинного */
.grid-start { align-items: start; }

/* Межсекционный ритм — главный рычаг макро-иерархии: 56px против 16px внутри сетки
   даёт отношение 3.5× и превращает «одну текстуру» в главы. Было 26px (1.6×). */
.section { margin-top: var(--space-section); scroll-margin-top: 76px; }

/* Интро секции — на шкале, а не на UA-дефолте: своего margin у .sub не было, браузерный
   1em (15px) схлопывался с --space-block заголовка и ломал ритм «заголовок → интро → сетка».
   Селектор прямого потомка: .sub внутри карточек (их 40 из 44) не задет. */
.section > .sub { margin: 0 0 var(--space-4); }

#charts { display: flex; flex-direction: column; gap: var(--gap-grid); }

/* Стат-карточки */
.stat-head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-1); }
.asset-dot { width: 10px; height: 10px; border-radius: var(--radius-xs); flex: none; }
.stat-name { font-weight: 700; font-size: var(--fs-base); }
.stat-sym { color: var(--muted); font-size: var(--fs-xs); }
.stat-value { font-size: var(--fs-xl); line-height: var(--lh-xl); font-weight: 700; letter-spacing: -.02em; }
/* min-height под две строки: иначе спарклайны соседних KPI-карточек стоят на разной высоте */
.stat-sub { min-height: 38px; }
.stat-row { display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.stat-foot { margin-top: var(--space-2); }

/* ---------- Графики ---------- */
.chart-card { padding: var(--pad-card); }
.chart-head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-2); }
.chart-head h2 { display: flex; align-items: center; gap: var(--space-2); }
.chart-head .spacer { flex: 1; }
.kchart { position: relative; width: 100%; }
.kchart svg { display: block; width: 100%; }
.kchart .ktip {
  position: absolute; pointer-events: none; z-index: 5; display: none;
  background: var(--tip-bg); color: var(--tip-ink); border-radius: var(--radius-s); padding: var(--space-2) var(--space-3);
  font-size: var(--fs-xs); line-height: 1.45; white-space: nowrap;
  box-shadow: var(--shadow-pop);
}
.ktip .tl { color: var(--tip-muted); font-size: var(--fs-xs); }
.ktip .tv { font-weight: 700; }

/* Сегменты — главные органы управления графика: диапазон и источник прогноза.
   Высота была --control-h-xs (24) и на ≤640 уменьшалась ещё; это ниже любого разумного
   минимума для пальца. Теперь --control-h-sm (32) везде и --control-h (40) на телефоне,
   кегль при этом не мельчает. Группе нужны имя и role=group — их ставит app.js. */
.seg { display: inline-flex; background: var(--neutral-bg); border-radius: var(--radius-pill); padding: var(--space-1); gap: var(--space-1); }
.seg button {
  border: 0; background: none; height: var(--control-h-sm); padding: 0 var(--space-3); border-radius: var(--radius-pill); cursor: pointer;
  font: inherit; font-size: var(--fs-xs); font-weight: 600; color: var(--ink2);
}
.seg button.active, .seg button[aria-pressed="true"] { background: var(--card); color: var(--ink); box-shadow: var(--shadow-inset-sm); }

/* Имя группы сегментов. «Statistical model · AI» без подписи не говорит, чем именно
   переключаешь. */
.seg-lbl { font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.fc-src-note { margin: var(--space-1) 0 0; }

.toggle { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-h-sm); font-size: var(--fs-sm); color: var(--ink2); cursor: pointer; user-select: none; }
.toggle input { accent-color: var(--brand); width: 15px; height: 15px; }

/* Границы нарисованного окна и всего ряда — стоит вплотную под осью X, до легенды */
.chart-note { font-size: var(--fs-xs); color: var(--muted); margin: var(--space-1) 0 0; }
.chart-note:empty { display: none; }

.legend-note { font-size: var(--fs-xs); color: var(--muted); display: flex; gap: var(--space-3); align-items: center; padding: var(--space-1) 0 var(--space-2); flex-wrap: wrap; }
.legend-note .li { display: inline-flex; align-items: center; gap: var(--space-2); }
.legend-note .sw { width: 14px; height: 0; border-top: 2px solid; border-radius: 2px; }
.legend-note .sw.dash { border-top-style: dashed; }
.legend-note .sw.band { width: 14px; height: 10px; border: 0; border-radius: 2px; opacity: .35; }

/* ---------- Прогнозы ---------- */
.fc-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--gap-grid); }
/* min-width:0 обязателен: у grid-элемента min-width по умолчанию auto, и карточка с
   неразрывными подписями («measured coverage →», «self-reported») распирала дорожку
   шире 1fr — страница получала горизонтальный скролл. */
.fc-card { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.fc-src { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; min-width: 0; }
/* тона источников — модификаторы общего .chip (components.css), своих размеров не заводят */
.chip.gemini { background: var(--gemini-bg); color: var(--gemini-ink); }
.chip.statistical { background: var(--brand-bg); color: var(--brand-ink); }
.chip.backtest { background: var(--neutral-bg); color: var(--ink2); }
.fc-date { color: var(--muted); font-size: var(--fs-xs); }
.fc-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); background: var(--card-2); border: 1px solid var(--line-soft); border-radius: var(--radius-s); }
.fc-h { font-size: var(--fs-xs); font-weight: 700; color: var(--ink2); min-width: 68px; flex: none; white-space: nowrap; }
.fc-main { min-width: 0; }
.fc-mid { font-size: var(--fs-h3); font-weight: 700; }
.fc-range { font-size: var(--fs-xs); color: var(--muted); }
.fc-right { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1); flex: none; }
.fc-dir { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--fs-base); font-weight: 700; white-space: nowrap; }
.fc-dir.up { color: var(--up); } .fc-dir.down { color: var(--down); } .fc-dir.flat { color: var(--muted); }
.conf { display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; }
/* Самоотчёт LLM: без полосы (её место занимает подпись) и с переносом — «self-reported»
   не должно распирать карточку, но и молчать о происхождении числа нельзя (аудит E1-F4). */
.conf-self { white-space: normal; text-align: right; justify-content: flex-end; }
.conf-self .sub { font-size: var(--fs-2xs, var(--fs-xs)); }
/* «range not evaluated» — отдельной строкой под диапазоном, не в подбор (аудит E1-F2) */
.fc-note { display: block; }
.conf-bar { width: 54px; height: 5px; border-radius: var(--radius-xs); background: var(--line-soft); overflow: hidden; }
.conf-bar.sm { width: 40px; }
.conf-bar i { display: block; height: 100%; background: var(--brand-2); border-radius: var(--radius-xs); }

details.fc-why { border-top: 1px dashed var(--line); padding-top: var(--space-2); }
details.fc-why summary, details.fc-long summary { cursor: pointer; font-size: var(--fs-sm); font-weight: 600; color: var(--brand); list-style: none; }
details.fc-why summary::-webkit-details-marker, details.fc-long summary::-webkit-details-marker { display: none; }
details.fc-why summary::before, details.fc-long summary::before { content: "▸ "; }
details.fc-why[open] summary::before, details.fc-long[open] summary::before { content: "▾ "; }
/* Длинные горизонты прогноза (аудит E3-4): свёрнуты, но остаются в разметке. Сводка
   в summary — приглушённая, потому что это не действие, а список того, что внутри. */
details.fc-long summary { color: var(--muted); font-weight: 400; }
details.fc-long summary:hover { color: var(--brand); }
.fc-why-body { font-size: var(--fs-sm); color: var(--ink2); margin-top: var(--space-2); display: flex; flex-direction: column; gap: var(--space-2); }
.provenance {
  background: var(--card-2); border: 1px solid var(--line-soft); border-radius: var(--radius-s);
  padding: var(--space-3); font-size: var(--fs-xs); color: var(--ink2);
}
.provenance b { color: var(--ink); }
.provenance .pv-row { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* ---------- Gauge FNG ----------
   Тот же прибор, что у индекса: одна геометрия на все реализации, но своя шкала зон
   (25/45/55/75 alternative.me против ровных пятин индекса — см. charts.js).
   Гейдж стоит в том же слоте, где у соседей по ряду KPI спарклайн, то есть вторичным
   элементом: значение и зона уже прочитаны выше, в общем для всего ряда слоте.
   Числа внутри дуги здесь поэтому нет (showValue:false) — оно бы дублировало верхнюю
   строку и было бы крупнее её. */
.fng-wrap { display: flex; justify-content: center; }
.fng-wrap > div { width: 100%; max-width: 160px; }

/* ---------- Циклы и деривативы ---------- */
.cy-row {
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  padding: var(--space-2) 0; border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm);
}
.cy-row:last-child { border-bottom: 0; }
.cy-row > span:first-child { color: var(--ink2); flex: 1; min-width: 150px; }
.cy-row b { font-size: var(--fs-base); font-variant-numeric: tabular-nums; }
.cy-row i { font-style: normal; color: var(--muted); cursor: help; font-size: var(--fs-xs); }
.cy-spark { width: 90px; flex: none; min-width: 0; overflow: hidden; }

/* ---------- Алерты ----------
   Раскладка формы — классами, а не инлайн-стилями с магическими px (контракт B8). */
.al-form { display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-2); }
.al-fields { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.al-row { display: flex; gap: var(--space-3); align-items: end; flex-wrap: wrap; }
.al-f-asset { flex: 1; min-width: 90px; }
.al-f-kind { flex: 2; min-width: 190px; }
.al-f-thr { flex: 1; min-width: 130px; }
.al-f-chan { flex: 1; min-width: 150px; }
.al-list { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-2); }
.al-cond { font-weight: 700; font-size: var(--fs-sm); }
.al-note { margin-top: var(--space-2); }

/* ---------- Портфель ---------- */
.pf-sub { margin-bottom: var(--space-4); }
.pf-save-row { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-1); }
.pf-saved { color: var(--up); }
.pf-alloc-wrap { margin-top: var(--space-5); }
.pf-alloc-wrap .legend-note { margin-top: var(--space-2); }
.pf-value-row { margin-top: var(--space-1); }
.pf-value-row .read-val { margin: 0; }
.pf-chips { margin-top: var(--space-2); gap: var(--space-2); }
.pf-fc-wrap { margin-top: var(--space-4); }
.pf-fc-wrap .section-title { margin-bottom: var(--space-2); }
.pf-fc { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-3); }
.pf-inputs { display: grid; grid-template-columns: 1fr 1fr auto; gap: var(--space-3); align-items: end; }
.pf-asset-row { display: grid; grid-template-columns: 1.1fr 1fr 1fr; gap: var(--space-3); margin-bottom: var(--space-3); }
.field label { display: block; font-size: var(--fs-xs); font-weight: 600; color: var(--ink2); margin-bottom: var(--space-1); }
.field input, .field select {
  width: 100%; height: var(--control-h); padding: 0 var(--space-3); border: 1px solid var(--line); border-radius: var(--radius-s);
  font: inherit; font-size: var(--fs-base); background: var(--card); color: var(--ink);
}
.field input:focus, .field select:focus { outline: 2px solid var(--focus); border-color: var(--brand-2); }
/* Питч алертов для анонима: пример письма — вложенная поверхность, --radius-s,
   моноширинный текст письма, чтобы он читался как письмо, а не как ещё один абзац. */
.al-sample {
  margin: var(--space-4) 0; padding: var(--space-3);
  background: var(--neutral-bg); border: 1px solid var(--line-soft); border-radius: var(--radius-s);
}
.al-sample .eyebrow { margin-bottom: var(--space-2); }
.al-sample-subj { margin: 0 0 var(--space-1); font-weight: 700; font-size: var(--fs-sm); }
.al-sample-body { margin: 0; font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--ink2); }

.alloc-bar { display: flex; height: 12px; border-radius: var(--radius-pill); overflow: hidden; gap: 2px; background: var(--line-soft); }
.alloc-bar i { display: block; height: 100%; }

/* ---------- Формы ---------- */
.flash { border-radius: var(--radius-s); padding: var(--space-3) var(--space-4); font-size: var(--fs-base); margin-bottom: var(--space-4); display: flex; align-items: center; gap: var(--space-2); }
.flash .ic { flex: none; }
.flash.ok { background: var(--up-bg); color: var(--up); }
.flash.err { background: var(--down-bg); color: var(--down); }
.flash.warn { background: var(--warn-bg); color: var(--warn); }

/* ---------- Auth ---------- */
.auth-wrap { min-height: calc(100vh - 120px); display: flex; align-items: center; justify-content: center; padding: var(--space-8) var(--space-5); }
.auth-card { width: 400px; max-width: 100%; }
.auth-card .card { padding: var(--space-7); }
.auth-logo { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); margin-bottom: var(--space-6); text-align: center; }
.auth-h { margin-bottom: var(--space-1); }
.auth-lede { margin-bottom: var(--space-4); }
.auth-note { color: var(--ink2); }
.auth-form { display: flex; flex-direction: column; gap: var(--space-3); }
.auth-foot { text-align: center; margin-top: var(--space-4); font-size: var(--fs-sm); color: var(--ink2); }
.auth-note + .auth-note { margin-top: var(--space-3); }
.auth-note + .auth-form, .auth-lede + .auth-resend { margin-top: var(--space-4); }
/* Повторная отправка ссылки — отдельный блок над формой входа, с разделителем */
.auth-resend { padding-bottom: var(--space-4); border-bottom: 1px solid var(--line-soft); margin-bottom: var(--space-4); }
.auth-fine { margin-top: var(--space-4); }
/* «or» между формой и входом через Google: линия с подписью по центру */
.auth-or { display: flex; align-items: center; gap: var(--space-3); margin: var(--space-4) 0; color: var(--muted); font-size: var(--fs-xs); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; }
.auth-or::before, .auth-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
/* Вторая кнопка блока идёт во всю ширину карточки — иначе она читается как что-то мельче формы */
.auth-wide { width: 100%; justify-content: center; }
/* Переключатель темы на страницах входа (топбара там нет) */
.theme-float { position: fixed; top: var(--space-4); right: var(--space-4); z-index: 50; }

/* ---------- Админка ---------- */
.admin-tabs { display: flex; gap: var(--space-2); margin-bottom: var(--space-5); }
.admin-tabs a { display: inline-flex; align-items: center; gap: var(--space-2); height: var(--control-h-sm); padding: 0 var(--space-4); border-radius: var(--radius-pill); font-weight: 600; font-size: var(--fs-base); color: var(--ink2); }
.admin-tabs a.active { background: var(--brand-bg); color: var(--brand-ink); }
.admin-tabs a:hover { text-decoration: none; background: var(--neutral-bg); }
.role-pill { font-size: var(--fs-xs); color: var(--ink2); }
.inline-form { display: inline; }
.actions-cell { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.kv { display: grid; grid-template-columns: 220px 1fr; gap: var(--space-2) var(--space-4); font-size: var(--fs-base); }
.kv dt { color: var(--muted); } .kv dd { margin: 0; font-weight: 600; }
pre.log { background: var(--tip-bg); color: var(--tip-muted); border-radius: var(--radius-s); padding: var(--space-4); font-size: var(--fs-xs); overflow: auto; max-height: 320px; white-space: pre; }
.mono { font-family: var(--font-mono); font-size: .93em; }
code.mono { background: var(--neutral-bg); border-radius: var(--radius-xs); padding: 2px var(--space-2); font-size: var(--fs-xs); overflow-wrap: anywhere; max-width: 100%; }

/* Список вместо графика: при n<7 столбчатая диаграмма рисовала пустую область
   с двумя палочками у края и выглядела сломанной (аудит A39). */
.stat-list { list-style: none; margin: var(--space-2) 0 0; padding: 0; display: flex; flex-direction: column; }
.stat-list li {
  display: flex; align-items: baseline; gap: var(--space-3);
  padding: var(--space-2) 0; border-bottom: 1px solid var(--line-soft); font-size: var(--fs-sm);
}
.stat-list li:last-child { border-bottom: 0; }
.stat-list .d { color: var(--ink2); font-variant-numeric: tabular-nums; }
.stat-list .v { margin-left: auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.stat-list .bar { flex: 1; height: 6px; border-radius: var(--radius-xs); background: var(--line-soft); overflow: hidden; min-width: 40px; }
.stat-list .bar i { display: block; height: 100%; background: var(--brand-2); }

.empty { color: var(--muted); font-size: var(--fs-sm); padding: var(--space-4) 0; }
/* Текст диалога подтверждения (собирается в ui.js): раньше стоял инлайн-стилем с 14.5px */
.dlg-text { font-size: var(--fs-base); color: var(--ink2); }

/* ---------- Меню пользователя ---------- */
.user-trigger {
  display: inline-flex; align-items: center; gap: var(--space-2);
  height: var(--control-h-sm);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: none; color: var(--ink); cursor: pointer;
  padding: 0 var(--space-3) 0 var(--space-1); font: inherit; font-size: var(--fs-sm); font-weight: 600;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.user-trigger:hover { border-color: var(--muted); background: var(--neutral-bg); }
.user-trigger:active { transform: translateY(1px); }
.user-trigger .avatar {
  width: var(--control-h-xs); height: var(--control-h-xs); border-radius: var(--radius-pill); flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--brand), var(--brand-2)); color: var(--on-solid);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .02em;
}
.user-trigger .caret { color: var(--muted); width: 14px; height: 14px; }

/* ---------- Скелетоны загрузки ----------
   Скелетон обязан занимать столько же места, сколько займёт содержимое: иначе он не
   уменьшает сдвиг вёрстки, а откладывает его. На 400 kbps /markets набирала CLS 0.156
   при пороге 0.1 — карточка вырастала со 110 до 262px, график с 300 до 405, таблица
   точности с 94 до 209. Цифры ниже — измеренные высоты готового содержимого, а не
   подобранные на глаз, и потому это единственные «магические» px в файле. */
.sk-card { display: flex; flex-direction: column; gap: var(--space-2); }
.sk-line { height: 12px; border-radius: var(--radius-xs); background: var(--line-soft); animation: sk-pulse 1.4s ease-in-out infinite; }
.sk-line.w40 { width: 40%; } .sk-line.w60 { width: 60%; } .sk-line.w80 { width: 80%; }
.sk-line.tall { height: 28px; }
.sk-block { height: 240px; border-radius: var(--radius-s); background: var(--line-soft); animation: sk-pulse 1.4s ease-in-out infinite; }
#stat-cards .sk-card { min-height: 262px; }
.chart-card.sk-card .sk-block { height: 345px; }
#accuracy-box.sk-card { min-height: 209px; }
@keyframes sk-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .sk-line, .sk-block { animation: none; } }

/* ---------- Движение ----------
   Общие правила и обоснование — в конце assets/css/components.css. Здесь только то,
   что живёт на страницах приложения. */
.seg button, .admin-tabs a {
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.flash { animation: var(--animation-slide-in-down) forwards; animation-duration: var(--dur); animation-timing-function: var(--ease); }
/* transition тени объявляет .card на все карточки, но hover есть не у всех — переход
   в никуда. Оставлен там, где :hover действительно определён. */
.chart-card:hover, .grid-cards .card:hover { box-shadow: var(--shadow-hover); }
details.fc-why[open] .fc-why-body { animation: var(--animation-fade-in); animation-duration: var(--dur); }

/* Данные встают на место скелетона: 200 мс fade без сдвига. Сдвиг (translateY) намеренно
   не используется — он вернул бы CLS, ради которого скелетоны держат высоту. Числа внутри
   при этом не анимируются: count-up на цене врёт про то, что значение «росло». */
#stat-cards > .card, #charts > .chart-card, #accuracy-box:not(.sk-card),
#cycles-cards > .card, #dca-stats > *, #wi-result > * {
  animation: data-in var(--dur) var(--ease);
}

/* ---------- Responsive ---------- */
@media (max-width: 1000px) {
  .grid-cards { grid-template-columns: repeat(2, 1fr); }
  .fc-grid { grid-template-columns: 1fr; }
  .grid-2 { grid-template-columns: 1fr; }
}
@media (max-width: 860px) {
  .user-trigger .uname { display: none; }
  .user-trigger { padding: 0 var(--space-2) 0 var(--space-1); }
}
@media (max-width: 640px) {
  .grid-cards { grid-template-columns: 1fr; }
  .pf-inputs { grid-template-columns: 1fr; }
  .pf-asset-row { grid-template-columns: 1fr; gap: var(--space-2); padding-bottom: var(--space-2); border-bottom: 1px dashed var(--line); }
  #charts { gap: var(--gap-grid); }
  /* Высоты содержимого на узком экране другие — резерв скелетона тоже */
  #stat-cards .sk-card { min-height: 178px; }
  .chart-card.sk-card .sk-block { height: 370px; }
  #accuracy-box.sk-card { min-height: 259px; }
  /* Палец, а не курсор: сегменты дорастают до 40px. Горизонтальный паддинг остаётся
     --space-3 — на 375px ряд из семи кнопок и так на грани переноса. */
  .seg button { height: var(--control-h); }

  .chart-head { gap: var(--space-2) var(--space-3); }
  .fc-row { gap: var(--space-2); padding: var(--space-2) var(--space-3); }
  .conf-bar.sm { width: 30px; }
  .legend-note { gap: var(--space-2) var(--space-3); }

  .admin-tabs { flex-wrap: wrap; }
  .admin-tabs a { padding: 0 var(--space-3); font-size: var(--fs-sm); }
  .kv { grid-template-columns: 1fr; gap: 2px 0; }
  .kv dt { margin-top: var(--space-2); }
  .kv dd { margin-bottom: 2px; }
  .actions-cell .btn { flex: none; }
  .auth-card .card { padding: var(--space-6) var(--space-4); }
  pre.log { font-size: var(--fs-xs); padding: var(--space-3); }
}

/* Портфель: срок владения, альтернативы и температура входа (аудит E1-F19, E3-6, E3-22).
   Блок альтернатив — вложенная поверхность на --radius-s, как .al-sample: он сравнивает
   три величины и должен читаться группой, а не тремя абзацами подряд. */
.pf-vs { margin-top: var(--space-4); padding-top: var(--space-3); border-top: 1px solid var(--line-soft); }
.pf-vs .section-title { margin-bottom: var(--space-2); }
.pf-vs .sub { margin-top: var(--space-2); }
#pf-held, #pf-temp, #pf-derived { margin-top: var(--space-3); }
#pf-temp b { color: var(--ink); font-weight: 700; }
