/* Локальные шрифты Beauty Helper (self-host; Google Fonts в РФ недоступны).

   v11 (2026-09-24, BH-1418) — добавлены Literata (заголовки приложения,
   --font-display в src/appStyles.js) и её метрический фолбэк, оба внизу
   файла. Лендинг Literata не использует и не скачивает: @font-face без
   элемента, который её просит, в сеть не ходит. Правила v10 не тронуты.

   v10 (2026-09-22, BH-1392) — две правки, обе проверены замером.

   ПЕРВАЯ: IBM Plex Sans похудел со 119 до 76 КБ (-36%), рисунок не
   изменился ни на пиксель. Файл нёс ДВЕ вариативные оси — wght (100–700)
   и wdth (75–100), — а узкие начертания в продукте не запрашиваются
   нигде. Ось ширины вырезана инстансингом по wdth=100 (fontTools
   varLib.instancer), файл переименован в IBMPlexSans-v2.woff2, потому что
   папка /fonts кэшируется на год как immutable и правка под старым именем
   не долетела бы ни до одного вернувшегося пользователя.
   Сверено до и после: upm 1000, ascent 1025, descent 275, lineGap 0,
   x-height 516, capHeight 698, глифов 455, кириллических 192 — всё
   совпадает, поэтому 'IBM Plex Fallback' ниже пересчитывать не
   потребовалось. Пиксельная сверка рендера на весах 300/400/500/600/700:
   ноль отличающихся пикселей, ширина строки совпадает до сотых.

   ВТОРАЯ: исправлено утверждение про веса ZT Neue Ralewe ниже. Оно было
   неверным и стоило продукту полутора лет раздутых заголовков.

   v9 (2026-08-21) — добавлены метрические фолбэки дисплейных семейств
   'Ralewe Fallback' и 'Cormorant Fallback' (в самом низу файла, там же
   разбор и числа). Правила v8 не тронуты ни одним символом.

   v8 (2026-08-21) — ПОЧИНЕНА СИНТАКСИЧЕСКАЯ ОШИБКА, из-за которой браузер
   терял два правила: 'IBM Plex Sans' (основной текст всего продукта) и
   'IBM Plex Fallback' (метрический фолбэк, держит нулевой CLS).

   Что было. В v7 два куска пояснительной прозы стояли ВНЕ комментария:
   строка 35 начиналась с «@font-face:», строка 118 — со слова «Редизайн».
   CSS-парсер на невалидном at-правиле глотает токены до первой «;» или до
   первого блока {…}, глотая блок ЦЕЛИКОМ; точки с запятой в прозе не было,
   поэтому каждый обломок съедал следующее за ним настоящее правило.
   Проверено на боевом сайте: в fonts-v7.css браузер видел 17 @font-face
   вместо 19, IBMPlexSans.woff2 (117 КБ) скачивался по preload и
   выбрасывался — консоль писала «preloaded but not used». Весь текст сайта
   рисовался системным шрифтом. Это и есть причина жалобы Симоны
   2026-08-18 «не видны выбранные мной шрифты, видны системные как у всех»:
   правка optional → swap тогда не помогла, потому что чинила не ту болезнь.

   Отсюда правило файла: пояснения живут в плане и docs/, а не в CSS.
   Этот файл — единственный ресурс страницы, блокирующий отрисовку
   (Lighthouse: 150 мс), и в v7 66% его веса составляли комментарии.
   Полная история версий v3–v8 — plans/2026-08-21-perf-fonts-copy-and-layout.md.

   ДВА ПРАВИЛА, КОТОРЫЕ НЕЛЬЗЯ НАРУШАТЬ:

   1. Любая правка @font-face = НОВОЕ ИМЯ ФАЙЛА (следующий fonts-v9.css) и
      смена ссылок в index.html и public/legal/*.html. Папка /fonts кэшируется
      на год как immutable, а Yandex CDN игнорирует ?v= в ключе кэша (живая
      проверка 2026-07-15) — правка на месте не долетит ни до кого.
   2. font-display: swap у всех семейств. У optional период подмены равен
      нулю: не успел в ~100 мс — фирменный шрифт не применится уже никогда за
      эту загрузку. На мобильной сети в РФ он не успевает почти всегда.
      Сдвиг вёрстки держит не optional, а метрический фолбэк ниже.

   ПЕРЕД ПУБЛИКАЦИЕЙ любой новой версии — прогнать проверку разбора:
   npm run check:fonts (scripts/check-fonts.mjs) ловит ровно эту ошибку. */

/* ── Метрический фолбэк основного текста ──────────────────────────────────
   Рисуется системным Arial, но с метриками IBM Plex Sans, снятыми с файла
   (unitsPerEm 1000, ascent 1025, descent 275, lineGap 0, x-height 516).
   Если фирменный шрифт не успел, высота строк и кегль совпадают — текст не
   прыгает и не переносится иначе. Это и есть защита от CLS. */
@font-face {
  font-family: 'IBM Plex Fallback';
  src: local('Arial');
  size-adjust: 99.5%;
  ascent-override: 103%;
  descent-override: 27.6%;
  line-gap-override: 0%;
}

/* ── IBM Plex Sans — весь текст и интерфейс (--font-body) ─────────────────
   Вариативный: один файл = все начертания 100–700.
   Двойной src намеренно указывает на ОДИН и тот же файл: встроенные WebView
   (старые Safari, браузеры внутри VK/Telegram) не знают технологию
   'woff2-variations' и без второго источника тихо пропускают весь @font-face —
   интерфейс падал на system-ui целиком (жалоба 2026-07-12). Лишнего трафика
   нет, браузер качает один вариант. */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 100 700;
  font-display: swap;
  src: url(/fonts/IBMPlexSans-v2.woff2) format('woff2-variations'),
       url(/fonts/IBMPlexSans-v2.woff2) format('woff2');
}

/* ── FoglihtenNo06 — вордмарк «BEAUTY HELPER» и декоративный знак в футере ─
   У строчной кириллицы этого шрифта нет строчных форм (на строчные коды
   посажены заглавные, разбор cmap — docs/lessons.md). Симона подтвердила
   использование несмотря на дефект 2026-07-01; не откатывать без её запроса. */
@font-face {
  font-family: 'FoglihtenNo06';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/FoglihtenNo06.woff2) format('woff2');
}

/* ── ZT Neue Ralewe — заголовки и лого (--font-display) ───────────────────
   Только Regular(400) и Medium(500), normal и italic.

   ⚠ ПОТОЛОК ВЕСА В CSS — 599. Прежняя редакция этого абзаца утверждала,
   что «любой запрошенный вес браузер подберёт к ближайшему доступному и не
   раздует до жирного». Это неверно, и на этом утверждении приложение
   прожило с поддельными заголовками до 2026-09-22 (BH-1392): начиная с 600
   движок берёт ближайшее лицо (Medium) и дорисовывает недостающую жирность
   обводкой контура. Замер на canvas, 100px: вес 500 даёт 1996922 залитых
   пикселя, вес 600 — 2829461 (+42%), вес 700 и 800 — ровно столько же, а
   ширина строки не меняется ни на пиксель. Настоящие начертания отличались
   бы и чернилами, и шириной; одинаковые числа у 600/700/800 — подпись
   синтетики. Волосяные штрихи при этом заплывают, засечки слипаются, и
   дисплейный шрифт становится неотличим от любого жирного гротеска.
   Веса 460, 500, 520 законны: все подбираются к Medium и рисуются
   настоящими глифами. Проверяет scripts/check-font-weights.mjs, вызывается
   из npm run check:fonts.
   Курсив — настоящими глифами шрифта, не синтетическим наклоном.
   Лицензия — free for commercial use (readme в public/fonts/ZT_neue_ralewe/). */
@font-face {
  font-family: 'ZT Neue Ralewe';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/ZTNeueRalewe-Regular.woff2) format('woff2');
}
@font-face {
  font-family: 'ZT Neue Ralewe';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/ZTNeueRalewe-Medium.woff2) format('woff2');
}
@font-face {
  font-family: 'ZT Neue Ralewe';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/ZTNeueRalewe-Italic.woff2) format('woff2');
}
@font-face {
  font-family: 'ZT Neue Ralewe';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/ZTNeueRalewe-MediumItalic.woff2) format('woff2');
}

/* ── Caveat — почерковый акцент онбординг-тура ────────────────────────────
   Грузится лениво, заведомо после первой отрисовки (класс .onb-hand). */
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/Caveat/caveat-cyrillic-500-normal.woff2) format('woff2');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/Caveat/caveat-latin-500-normal.woff2) format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122;
}
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/Caveat/caveat-cyrillic-600-normal.woff2) format('woff2');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/Caveat/caveat-latin-600-normal.woff2) format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122;
}

/* ── Cormorant Garamond — цифры и цены ────────────────────────────────────
   Только normal, только cyrillic+latin, четыре веса. Курсив и сабсеты
   -ext/vietnamese удалены 2026-08-13: на русско-английском сайте не нужны,
   а грузились на каждом устройстве. */
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/co3bmX5slCNuHLi8bLeY9MK7whWMhyjYrXtKgS4.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(/fonts/co3bmX5slCNuHLi8bLeY9MK7whWMhyjYqXtK.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/co3bmX5slCNuHLi8bLeY9MK7whWMhyjYrXtKgS4.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(/fonts/co3bmX5slCNuHLi8bLeY9MK7whWMhyjYqXtK.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/co3bmX5slCNuHLi8bLeY9MK7whWMhyjYrXtKgS4.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(/fonts/co3bmX5slCNuHLi8bLeY9MK7whWMhyjYqXtK.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/co3bmX5slCNuHLi8bLeY9MK7whWMhyjYrXtKgS4.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(/fonts/co3bmX5slCNuHLi8bLeY9MK7whWMhyjYqXtK.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── Метрический фолбэк заголовков и цифр (v9, 2026-08-21) ────────────────
   ЗАЧЕМ. У основного текста фолбэк был с v5 и держит нулевой CLS. У
   дисплейных семейств его не было вовсе: пока ZT Neue Ralewe и Cormorant
   Garamond едут по сети, заголовки и цены рисуются Georgia (вторая в стеках
   display/serif в src/landing/tokens.js), а у неё другие метрики. Сильнее
   всего расходится Cormorant: его x-height 0.386 против 0.4814 у Georgia,
   то есть цифры подменяются с прыжком кегля почти на 20%.

   КАК СЧИТАЛИСЬ ЧИСЛА. Ровно тем же способом, что и 'IBM Plex Fallback'
   выше (способ восстановлен из его же значений и сходится на всех трёх
   до третьего знака):
       size-adjust       = x-height(шрифта) / x-height(запасного)
       ascent-override   = ascent(шрифта)   / size-adjust
       descent-override  = descent(шрифта)  / size-adjust
       line-gap-override = lineGap(шрифта)  / size-adjust
   Метрики шрифтов сняты с самих файлов woff2 (fontTools, hhea + OS/2),
   не на глаз. Запасной для обоих — Georgia, x-height 986/2048 = 0.4814.

   ZT Neue Ralewe:     upm 1000, ascent 1036, descent 335, gap 0, x-h 469
   Cormorant Garamond: upm 1000, ascent  924, descent 287, gap 0, x-h 386

   ОГОВОРКА. local('Georgia') есть не на всякой системе: на Android и Linux
   её обычно нет. Там правило просто не находит шрифт и молча уступает
   следующему в стеке, то есть хуже, чем было, не становится нигде. Та же
   оговорка верна и для 'IBM Plex Fallback' с его local('Arial'). */
@font-face {
  font-family: 'Ralewe Fallback';
  src: local('Georgia');
  size-adjust: 97.42%;
  ascent-override: 106.35%;
  descent-override: 34.39%;
  line-gap-override: 0%;
}
@font-face {
  font-family: 'Cormorant Fallback';
  src: local('Georgia');
  size-adjust: 80.18%;
  ascent-override: 115.25%;
  descent-override: 35.8%;
  line-gap-override: 0%;
}

/* ── Literata — заголовки приложения (v11, BH-1418) ─────────────────────
   Нарезка scripts/cut-literata.py: вариативная по толщине 400–500,
   оптический размер 24, кириллица и латиница. Лицензия SIL OFL 1.1 —
   Literata-OFL.txt рядом. Метрики сняты с файла: upm 1000, ascent 1177,
   descent 308, gap 0, x-height 508; фолбэк считается тем же способом, что
   'Ralewe Fallback' выше, от Georgia (x-height 0.4814). */
@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url(/fonts/Literata-v1.woff2) format('woff2');
}
@font-face {
  font-family: 'Literata Fallback';
  src: local('Georgia');
  size-adjust: 105.52%;
  ascent-override: 111.55%;
  descent-override: 29.19%;
  line-gap-override: 0%;
}
