/* checkout.css — generated: 3 checkout page stylesheets + shared funnel,
   each namespaced under a body scope class. Do not edit by hand. */

/* ===== shared funnel + payment sheet (all checkout pages) ===== */
.m-checkout .kf-overlay {
  position: fixed;
  inset: 0;
  z-index: 2147483600;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--page-bg, #fafafa);
  display: flex;
  justify-content: center;
  padding: 28px 18px 48px;
}
.m-checkout .kf-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 2147483646;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  /* 20, а не 18: с 12.09 модалка — обычный флекс-элемент подложки (высота по
     контенту), поэтому просвет вокруг неё задают ЭТИ поля. Раньше она стояла
     `absolute; inset: 20px` и поля подложки не значили ничего. */
  padding: 20px;
}
.m-checkout a.pay_button {
  text-decoration: none;
}
.m-checkout .kc-pay-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 200;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  animation: kc-pay-fade 0.25s ease;
}
@keyframes kc-pay-fade { from { background: rgba(0, 0, 0, 0); } to { background: rgba(0, 0, 0, 0.5); } }
.m-checkout .kc-pay-sheet {
  position: relative;
  background: #f4f4f6;
  width: 100%;
  max-width: 480px;
  max-height: 94vh;
  overflow-y: auto;
  border-radius: 20px 20px 0 0;
  padding: 22px 18px calc(24px + env(safe-area-inset-bottom));
  animation: kc-pay-slide-up 0.34s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes kc-pay-slide-up { from { transform: translateY(100%); } to { transform: translateY(0); } }
.m-checkout .kc-pay-close {
  position: absolute; top: 16px; left: 16px; border: none; background: transparent;
  font-size: 26px; line-height: 1; color: #3a3a3a; cursor: pointer;
}
.m-checkout .kc-pay-title {
  text-align: center; font-size: 21px; font-weight: 800; line-height: 1.25;
  color: #1a1a1a; margin: 6px 28px 18px;
}
.m-checkout .kc-pay-hl { color: #2fa84f; }
.m-checkout .kc-pay-summary { background: #eaeaee; border-radius: 14px; padding: 16px; margin-bottom: 16px; }
.m-checkout .kc-pay-line,
.m-checkout .kc-pay-promo,
.m-checkout .kc-pay-total {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 15px; color: #4a4a4a; margin-bottom: 10px;
}
.m-checkout .kc-pay-line--muted { color: #7a7a7a; }
.m-checkout .kc-pay-neg { color: #e2483a; }
.m-checkout .kc-pay-code { background: #dcdce1; border-radius: 8px; padding: 4px 10px; font-weight: 600; color: #2a2a2a; }
.m-checkout .kc-pay-hr { height: 1px; background: #d5d5db; margin: 6px 0 12px; }
.m-checkout .kc-pay-total { font-size: 20px; font-weight: 800; color: #1a1a1a; margin-bottom: 0; }
.m-checkout .kc-pay-total s { color: #9a9aa2; font-weight: 500; font-size: 16px; }
.m-checkout .kc-pay-apple {
  width: 100%; height: 54px; border: none; border-radius: 9999px; background: #000; color: #fff;
  font-size: 17px; font-weight: 600; display: inline-flex; align-items: center; justify-content: center;
  gap: 6px; cursor: pointer; margin-bottom: 14px;
}
.m-checkout .kc-pay-apple:disabled { opacity: 0.55; cursor: not-allowed; }
.m-checkout .kc-pay-card { background: #fff; border-radius: 16px; padding: 18px 16px; box-shadow: 0 1px 8px rgba(0,0,0,0.05); }
.m-checkout .kc-pay-card-head { font-weight: 700; font-size: 15px; color: #1a1a1a; margin-bottom: 14px; }
.m-checkout .kc-pay-input {
  width: 100%; height: 52px; border: none; border-radius: 10px; background: #eceef3;
  padding: 0 16px; font-size: 16px; color: #1a1a1a; margin-bottom: 12px;
}
.m-checkout .kc-pay-input::placeholder { color: #aeb0b8; }
.m-checkout .kc-pay-valid { font-size: 13px; font-weight: 600; color: #6a6a6a; margin-bottom: 8px; }
.m-checkout .kc-pay-exp { display: flex; align-items: center; gap: 10px; margin-bottom: 0; }
.m-checkout .kc-pay-sm { width: 76px; text-align: center; padding: 0 8px; margin-bottom: 0; }
.m-checkout .kc-pay-slash { color: #aeb0b8; font-size: 18px; }
.m-checkout .kc-pay-info {
  margin-left: auto; width: 26px; height: 26px; border: 1px solid #c8c8d0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px; font-style: italic;
  color: #9a9aa2; flex-shrink: 0;
}
.m-checkout .kc-pay-btn {
  width: 100%; height: 54px; border: none; border-radius: 9999px; background: #5fa84f; color: #fff;
  font-size: 17px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center;
  gap: 8px; cursor: pointer; margin-top: 16px;
}
.m-checkout .kc-pay-btn:hover:not(:disabled) { background: #559746; }
.m-checkout .kc-pay-btn:disabled { opacity: 0.6; cursor: not-allowed; }
.m-checkout .kc-pay-safe {
  margin: 16px auto 0; width: fit-content; background: #e7f3e9; color: #2f7d43;
  border-radius: 10px; padding: 8px 16px; font-size: 14px; font-weight: 600;
}
.m-checkout .kc-pay-error { color: #b00020; font-size: 14px; margin-top: 8px; }

/* Optional sensitive-data consent checkbox above the final pay CTA. */
.m-checkout .kc-consent { margin: 0 0 14px; text-align: left; }
.m-checkout .kc-consent__label {
  display: flex; gap: 8px; align-items: flex-start; cursor: pointer;
  font-size: 12px; line-height: 1.45; color: #6d7572;
}
.m-checkout .kc-consent__box { flex: 0 0 auto; width: 16px; height: 16px; margin-top: 1px; accent-color: var(--main-accent-color, #5fa84f); }
.m-checkout .kc-consent a { color: inherit; text-decoration: underline; }


/* ===== 28-day kegel checkout =====
   Своих правил у кегель-чекаута больше нет (правка Игоря 07.09): страница
   рендерится тем же шаблоном, что мужская, и оформляется общим блоком ниже
   по селектору .m-checkout-rd. Прежние 1063 строки доредизайновой вёрстки
   удалены — они били по тем же классам и, стоя выше по файлу, спорили бы с
   общими правилами специфичностью. Палитра переменных у обеих страниц была
   побайтно одинаковой, поэтому терять нечего. Класс .m-checkout-kegel на
   body остаётся: по нему различаются страницы в аналитике и в снапшоте. */

/* ===== master-sex checkout ===== */
.m-checkout-rd .kc-root {
  --font-family: "Sofia Pro", "Arial", serif;
  /* --page-bg ЗДЕСЬ НЕТ: он объявлен на BODY (и у `-rd`, и у женской страницы).
     Любая копия на .kc-root перекрывает женское значение — переменная берётся
     с ближайшего предка, а не по порядку правил (поймано 13.09, см. второй
     блок `.m-checkout-rd .kc-root` ниже по файлу). Доредизайновый #fafafa тут
     и так был мёртвым: редизайн красит канвас своим значением. */
  --pay-button-bg: #6b6b6b;
  --button-primary-color: #6b6b6b;
  --button-primary-color-text: #fff;
  --main-accent-color: #888787;
  --your-goal-color: #24b172;
  --your-goal-text-color: #fff;
  --light-background-color: #d9d9d9;
  --discount-background-color: #acc0b0;
  --second_accent: #257a33;
  --empty-rating: #d9d9d9;
  --soft-accent: #898989;
  --plans-hover-bg: #fff;
  --why-so-unique: transparent;
  --pay-button-text: #ffffff;
  --plans-bg: #f3f4f4;
  --plans-tile-bg: #fcfcfc;
  --plans-text: #1d4034;
  --plans-bg-selected: #fff;
  --plans-text-selected: #1d4034;
  --plans-offer-bg: #208357;
  --plans-offer-text: #ffffff;
  --discount-timer-bg: #208357;
  --discount-timer-text: #ffffff;
  --header-text-color: #1f2d26;
  --featured-in-background: #acc0b08a;
  --without-coach-background: #efeeee;
  --with-coach-background: #eef5ef;
  --reviews-background: #efeeee;
  --social-rating: #4f7a5c;

  min-height: 100dvh;
  background: var(--page-bg);
  font-family: var(--font-family);
  color: #2b3330;
}
.m-checkout-rd .kc-inner {
  margin: 0 auto;
  max-width: 724px;
  padding: 0 16px 120px;
}
.m-checkout-rd .three_month {
  font-family: "SF Pro", "Arial", serif;
}
.m-checkout-rd .header_stylish {
  font-family: "Playfair Display", serif;
  font-weight: 400;
  letter-spacing: -0.03em;
}
.m-checkout-rd .new_york_font {
  font-family: "Sofia Pro", "Arial", serif;
}
.m-checkout-rd .sf_pro_font {
  font-family: "SF Pro", "Arial", serif;
}
.m-checkout-rd .kc-divider {
  height: 1px;
  background-color: rgba(0, 0, 0, 0.3);
  margin: 12px 0 16px;
}
.m-checkout-rd .tc-scroll-hint {
  --hint-height: 35px;
  --stroke: var(--soft-accent);
  --blur: 6px;
  --thickness: 6;
  --fade: 0.25;

  width: 100%;
  height: var(--hint-height);
  display: grid;
  place-items: center;
  pointer-events: none;
  margin: 6px 0 30px;
  position: relative;
  z-index: 1;
}
.m-checkout-rd .tc-scroll-hint svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.06));
}
.m-checkout-rd .tc-scroll-hint .chev path {
  fill: none;
  stroke: var(--stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: var(--thickness);
  opacity: var(--fade);
  transform-origin: 300px 30px;
  animation: kc-tc-drop 1.8s ease-in-out infinite;
}
.m-checkout-rd .tc-scroll-hint .chev-1 path {
  animation-delay: 0s;
  opacity: calc(var(--fade) + 0.3);
}
.m-checkout-rd .tc-scroll-hint .chev-2 path {
  animation-delay: 0.18s;
  opacity: calc(var(--fade) + 0.18);
}
.m-checkout-rd .tc-scroll-hint .chev-3 path {
  animation-delay: 0.36s;
  opacity: calc(var(--fade) + 0.05);
}
@keyframes kc-tc-drop {
  0% {
    transform: translateY(0);
    opacity: 0.35;
  }
  40% {
    transform: translateY(3px);
    opacity: 0.95;
  }
  100% {
    transform: translateY(0);
    opacity: 0.35;
  }
}
@media (min-width: 640px) {
.m-checkout-rd .tc-scroll-hint {
    margin-bottom: 48px;
  }

}
@media (min-width: 1024px) {
.m-checkout-rd .tc-scroll-hint {
    margin-bottom: 64px;
    --hint-height: 40px;
    --thickness: 7;
  }

}
.m-checkout-rd .plans_list {
  display: grid;
  row-gap: 10px;
  overflow: visible;
}
/* Доредизайновые правила пакетов (.plan-box … ::before «MOST POPULAR») удалены
   05.09: блок пересобран по Figma 615:20739 — новые правила лежат в конце
   файла, рядом с остальным редизайном мужского чекаута. */
.m-checkout-rd .pay_button_box {
  width: 100%;
}
.m-checkout-rd .pay_button_box.kc-fixed {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  width: min(100%, 724px);
  margin-inline: auto;
  padding: 16px;
  background: linear-gradient(transparent, var(--page-bg) 40%);
}
.m-checkout-rd .pay_button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 12px 24px;
  min-height: 56px;
  border: none;
  border-radius: 4px;
  background-color: var(--button-primary-color);
  color: var(--button-primary-color-text);
  font-family: "SF Pro", "Arial", serif;
  font-size: 18px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease-in-out;
}
.m-checkout-rd .pay_button:hover:not(:disabled) {
  background-color: color-mix(in srgb, var(--pay-button-bg) 92%, black);
}
.m-checkout-rd .pay_button:active:not(:disabled) {
  background-color: color-mix(in srgb, var(--pay-button-bg) 84%, black);
}
.m-checkout-rd .pay_button:disabled {
  opacity: 0.9;
  cursor: not-allowed;
  pointer-events: none;
}
.m-checkout-rd .pay_button[data-loading="true"] {
  cursor: not-allowed;
  pointer-events: none;
}
.m-checkout-rd .pay_button[data-loading="true"] .pay_button__content {
  opacity: 0;
}
.m-checkout-rd .pay_button__content {
  display: inline-flex;
  align-items: center;
}
.m-checkout-rd .pay_button__loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
}
.m-checkout-rd .pay_button__spinner {
  width: 16px;
  height: 16px;
  border: 2px solid transparent;
  border-top: 2px solid currentColor;
  border-radius: 50%;
  animation: pay_button_spin 1s linear infinite;
}
@keyframes pay_button_spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
.m-checkout-rd .center-image-block {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 32px 0 0;
  /* Радиус 26 и на самом блоке (правка Игоря 12.09). Визуально он ничего не
     меняет: картинку скругляет правило ниже — но контейнер теперь режет по
     тому же радиусу всё, что в него положат. */
  border-radius: 26px;
  overflow: hidden;
}
.m-checkout-rd .center-image-block img {
  width: 100%;
  max-width: 500px;
  height: auto;
  object-fit: contain;
  border-radius: 26px;
}
.m-checkout-rd .kc-program {
  margin: 56px 0 0;
  background: transparent;
  border-radius: 0;
  padding: 0;
}
/* Заголовок — общее правило заголовков блоков, см. .kc-featband-title. */
/* Левая колонка опущена на 40 относительно правой. Сдвиг ТРАНСФОРМОМ, а не
   margin'ом: margin вырастил бы каждую строку сетки на 40 и развёл карточки
   по вертикали; трансформ на раскладку не влияет, поэтому обе колонки
   остаются с зазором 10, а место под съехавшую вниз левую резервирует
   padding-bottom у самой сетки. Разбивать разметку на две колонки нельзя —
   поменялся бы порядок чтения. */
.m-checkout-rd .kc-program__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 10px;
  row-gap: 10px;
  padding-bottom: 40px;
}
.m-checkout-rd .kc-program__grid > .kc-program__item:nth-child(odd) {
  transform: translateY(40px);
}
.m-checkout-rd .kc-program__item {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 20px;
  border: 1px solid var(--rd-hairline);
  border-radius: 26px;
  text-align: left;
}
/* Прежний трекинг −0.02em снят вместе с SF Pro Black: он был нужен тяжёлому
   начертанию, а у Faculty Glyphic 400 просто сжимает цифры. Число внутри —
   отдельным спаном в --success; спан ИНЛАЙНОВЫЙ (не блочные .coPlanTitle*),
   чтобы строка переносилась естественно: «28 days» помещается в одну, а
   «50+ 3D pleasure maps» в три. */
.m-checkout-rd .kc-program__num {
  font-size: 24px;
  line-height: 1.1;
  color: var(--text-light, #192126);
}
.m-checkout-rd .kc-program__numLead {
  color: var(--rd-accent);
}
.m-checkout-rd .kc-program__text {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-light-muted, #5E6468);
}
.m-checkout-rd .kc-policy-overlay {
  position: fixed;
  inset: 0;
  z-index: 2147483000;
  display: none;
  flex-direction: column;
  background: var(--page-bg);
  color: #1a1a1a;
}
.m-checkout-rd .kc-policy-overlay--open {
  display: flex;
}
.m-checkout-rd .kc-policy-overlay__top {
  display: flex;
  align-items: center;
  width: 100%;
  box-sizing: border-box;
  padding: 12px 12px 0;
  flex-shrink: 0;
}
.m-checkout-rd .kc-policy-overlay__back {
  border: none;
  background: transparent;
  font-family: "Sofia Pro", "Arial", sans-serif;
  font-size: 16px;
  font-weight: 500;
  color: #1a1a1a;
  padding: 8px;
  cursor: pointer;
}
.m-checkout-rd .kc-policy-overlay__close {
  margin-left: auto;
  padding: 8px;
  border: none;
  background: transparent;
  color: #1a1a1a;
  cursor: pointer;
  line-height: 0;
}
.m-checkout-rd .kc-policy-overlay__main {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.m-checkout-rd .kc-policy-overlay__nav {
  margin-top: 8px;
  padding: 0 24px 24px;
}
.m-checkout-rd .kc-policy-overlay__link {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
  font-family: "Sofia Pro", "Arial", sans-serif;
  font-size: 18px;
  font-weight: 600;
  line-height: 1.35;
  color: #1a1a1a;
  padding: 18px 0;
}
.m-checkout-rd .kc-policy-overlay__divider {
  height: 1px;
  background: #1a1a1a;
  opacity: 0.9;
}
.m-checkout-rd .kc-policy-overlay__detail {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.m-checkout-rd .kc-policy-overlay__detail-body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 4px 20px 40px;
  text-align: left;
  font-family: "Sofia Pro", "Arial", sans-serif;
  font-size: 15px;
  line-height: 1.5;
  color: #1a1a1a;
}
.m-checkout-rd .kc-policy-overlay__detail-body strong {
  font-weight: 700;
}
.m-checkout-rd .kc-policy-overlay__detail-body a {
  color: #1a1a1a;
  text-decoration: underline;
}
.m-checkout-rd .kc-pay-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 200;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  animation: kc-pay-fade 0.25s ease;
}
@keyframes kc-pay-fade {
  from { background: rgba(0, 0, 0, 0); }
  to { background: rgba(0, 0, 0, 0.5); }
}
/* Фон — канвас страницы (правка Игоря 09.09), поэтому лист тёплый на женской
   версии и холодный на мужской. Верхние углы 32 — КОНЦЕНТРИЧНО крестику:
   круглая кнопка 44 (радиус 22) стоит с отступом 10, 22 + 10 = 32. Отступ
   кнопки и этот радиус связаны — менять их только ПАРОЙ. */
.m-checkout-rd .kc-pay-sheet {
  position: relative;
  background: var(--page-bg, #F2F1F6);
  width: 100%;
  max-width: 480px;
  max-height: 94vh;
  overflow-y: auto;
  border-radius: 32px 32px 0 0;
  padding: 22px 18px calc(24px + env(safe-area-inset-bottom));
  animation: kc-pay-slide-up 0.34s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes kc-pay-slide-up {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}
/* Вид (44, круг, белая подложка, тень, отклик нажатия) целиком из app.css —
   .appRoundBtn/.pressShrink, класс вешает скрипт. Здесь только место: правый
   верхний угол листа, 8 сверху и справа (правка Игоря 09.09; было 16 слева с
   текстовым «×»). ВАЖНО: у легаси-правила .m-checkout .kc-pay-close те же две
   специфичности, и оно ставит `background: transparent` и `border: none`
   раньше по файлу — поэтому подложку и отсутствие рамки надо повторить, иначе
   кнопка осталась бы прозрачной. */
.m-checkout-rd .kc-pay-close {
  position: absolute;
  top: 10px;
  right: 10px;
  left: auto;
  z-index: 1;
  background: #FFFFFF;
  border: 0;
  font-size: 0;
  color: var(--text-light, #192126);
  cursor: pointer;
}
/* Заголовок — в левый верхний угол и по левому краю (правка Игоря 09.09):
   так он встаёт РЯДОМ с крестиком, а не под ним, и лист становится на 38
   короче. Все четыре значения — правка Игоря 09.09: 6 сверху, 50 справа, 28
   до summary, 20 слева (то есть 38 от кромки листа с его паддингом 18).
   Правый 52 даёт ровно 16 до крестика: кнопка шириной 44 стоит в 10 от кромки,
   её левый край на 54, контентный бокс кончается на 18, 54 − 18 = 36, плюс 16
   зазора = 52. Отступ кнопки и это число связаны. */
.m-checkout-rd .kc-pay-title {
  text-align: left;
  font-size: 21px;
  font-weight: 800;
  line-height: 1.25;
  color: var(--text-light, #192126);
  margin: 6px 52px 16px 20px;
}
.m-checkout-rd .kc-pay-hl { color: var(--success, #28840F); }
/* Правка Игоря 09.09: радиус 26 и паддинг 20 — как у карточек редизайна;
   первые три строки 14, строка Total 16 (см. ниже). */
.m-checkout-rd .kc-pay-summary {
  background: transparent;
  border: 1px solid var(--divider, #DADDE3);
  border-radius: 26px;
  padding: 18px 20px;
  margin-bottom: 16px;
}
.m-checkout-rd .kc-pay-line,
.m-checkout-rd .kc-pay-promo,
.m-checkout-rd .kc-pay-total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  color: var(--text-light, #192126);
  margin-bottom: 10px;
}
/* Подписи слева в первых трёх строках — muted, значения справа остаются
   тёмными (правка Игоря 09.09). Вторая строка (скидка) muted целиком, у неё
   правая часть красится отдельно как --success. */
.m-checkout-rd .kc-pay-line > span:first-child,
.m-checkout-rd .kc-pay-promo > span:first-child {
  color: var(--text-light-muted, #5E6468);
}
.m-checkout-rd .kc-pay-line--muted { color: var(--text-light-muted, #5E6468); }
/* Строка промокода была на 8 выше первых двух: её высоту задавала пилюля (27
   против 19) — ровно её вертикальные паддинги 4 + 4. Теперь высота строки
   прибита к высоте СТРОКИ ТЕКСТА, а пилюля центрируется в ней (align-items:
   center из общего правила выше) и симметрично вылезает за неё на 4. Интерлиньяж
   задан явно тем же числом, иначе 19 зависело бы от наследуемого значения.
   `line-height` НЕ трогает .kc-pay-total: у него свой кегль 16. */
.m-checkout-rd .kc-pay-line,
.m-checkout-rd .kc-pay-promo { line-height: 19px; }
.m-checkout-rd .kc-pay-promo { height: 19px; }
/* Скидка — токеном SUCCESS, а не error (правка Игоря 09.09): это выгода
   покупателя, а не ошибка. */
.m-checkout-rd .kc-pay-neg { color: var(--success, #28840F); }
/* Подложка — тот же тинт, что у блока промокода на самой странице
   (.coPromo → --rd-tint), поэтому на женской странице плашка становится
   тёплой вместе со всей палитрой. */
.m-checkout-rd .kc-pay-code {
  background: var(--rd-tint);
  border-radius: 8px;
  padding: 4px 10px;
  font-weight: 600;
  color: var(--success, #28840F);
  /* Оптическое выравнивание (правка Игоря 10.09): по правой кромке должен
     стоять ТЕКСТ пилюли, а не её бокс. Замер до правки: значение первой строки
     и бокс пилюли кончались на 363, а текст внутри — на 353, ровно на её правый
     паддинг. Отрицательный правый margin в ряду со `space-between` выпускает
     пилюлю на эти 10 наружу, и её текст встаёт на общую линию; бокс при этом
     заходит в правое поле summary (20), до рамки остаётся 11. */
  margin-right: -10px;
}
.m-checkout-rd .kc-pay-hr {
  height: 1px;
  background: #d5d5db;
  margin: 16px 0 14px;
}
.m-checkout-rd .kc-pay-total {
  font-size: 16px;
  font-weight: 800;
  color: var(--text-light, #192126);
  margin-bottom: 0;
}
/* Старая цена: кегль наследуется от строки (те же 16), зачёркивание — токеном
   error, как у старой цены на пейволах. Зазор до актуальной цены — пробел из
   разметки плюс эти 2px (правка Игоря 09.09). */
.m-checkout-rd .kc-pay-total s {
  /* Тот же #969FA6, что у зачёркнутой цены в пакетах (.plan-crossed): там
     объяснено, почему не `--text-light-muted` — он слишком плотный, и разница
     с актуальной ценой почти не читается. */
  color: #969FA6;
  font-weight: 500;
  font-size: 16px;
  margin-right: 2px;
  text-decoration-color: var(--error, #C51013);
}
/* Кнопка Apple Pay — по их гайдлайнам: чёрная капсула, СИСТЕМНЫЙ шрифт (SF
   Pro на их платформах, поэтому стек начинается с -apple-system) и знак яблока
   перед словом Pay. Faculty Glyphic тут не годится: гайдлайны требуют шрифт
   системы. Знак ставит скрипт символом U+F8FF; на не-Apple он не отрисуется —
   там Apple Pay и не работает, но саму кнопку мы пока показываем всегда
   (гейт по window.ApplePaySession не делали). */
.m-checkout-rd .kc-pay-apple {
  width: 100%;
  height: 50px;
  border: none;
  border-radius: 9999px;
  background: #000;
  color: #fff;
  /* `!important` обязателен: ниже по файлу стоит блок «ШРИФТ И ЖИРНОСТЬ НА
     ВСЕЙ СТРАНИЦЕ» — `body.m-checkout-rd *` с !important на Faculty Glyphic и
     вес 400. Он специально прибит ко всей странице (иначе побеждают инлайновые
     жирности разметки), и обойти его можно только тем же !important при
     большей специфичности. Это ЕДИНСТВЕННОЕ исключение из того правила. */
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro",
    "Helvetica Neue", Helvetica, Arial, sans-serif !important;
  font-size: 17px;
  font-weight: 600 !important;
  letter-spacing: -0.01em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  margin-bottom: 14px;
}
/* Знак и слово Pay — ОДИН флекс-элемент: между ними нужен тонкий зазор самого
   знака, а не общий gap 6px кнопки. */
.m-checkout-rd .kc-pay-appleMark {
  font-family: inherit !important;
  font-weight: inherit !important;
}
.m-checkout-rd .kc-pay-apple:disabled { opacity: 0.55; cursor: not-allowed; }
/* Правка Игоря 09.09: радиус 26, паддинг 20/20/4 и без тени. Нижние 4 — потому
   что последнее поле несёт свои 16 снизу, вместе выходят те же 20. */
.m-checkout-rd .kc-pay-card {
  background: #fff;
  border-radius: 26px;
  padding: 20px 20px 4px;
  /* Именно `none`, а не отсутствие объявления: тень ставит легаси-правило
     .m-checkout .kc-pay-card той же специфичности выше по файлу, и без явного
     сброса она осталась бы (замер: rgba(0,0,0,0.05) 0 1px 8px). */
  box-shadow: none;
}
.m-checkout-rd .kc-pay-card-head {
  font-weight: 700;
  font-size: 15px;
  color: var(--text-light, #192126);
  margin-bottom: 14px;
}
/* Правка Игоря 09.09: белый фон, обводка разделителем, радиус 16 (был 10 и фон
   канваса). `box-sizing: border-box` обязателен вместе с обводкой: у полей
   заданы height 52 и width 76 у MM/YY, и на content-box рамка раздула бы их до
   54 и 78. */
.m-checkout-rd .kc-pay-input {
  width: 100%;
  height: 50px;
  box-sizing: border-box;
  border: 1px solid var(--divider, #DADDE3);
  border-radius: 14px;
  background: #FFFFFF;
  padding: 0 16px;
  font-size: 16px;
  color: var(--text-light, #192126);
  margin-bottom: 16px;
}
/* Тот же #969FA6, что у зачёркнутой цены в пакетах: `--text-light-muted`
   читался почти как введённое значение. */
.m-checkout-rd .kc-pay-input::placeholder { color: #969FA6; }
.m-checkout-rd .kc-pay-valid {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-light-muted, #5E6468);
  margin-bottom: 8px;
}
.m-checkout-rd .kc-pay-exp {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
}
.m-checkout-rd .kc-pay-sm {
  width: 76px;
  text-align: center;
  padding: 0 8px;
  margin-bottom: 0;
}
.m-checkout-rd .kc-pay-slash { color: var(--text-light-muted, #5E6468); font-size: 18px; }
.m-checkout-rd .kc-pay-info {
  margin-left: auto;
  width: 26px;
  height: 26px;
  border: 1px solid var(--divider, #DADDE3);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-style: italic;
  color: var(--text-light-muted, #5E6468);
  flex-shrink: 0;
}
.m-checkout-rd .kc-pay-btn {
  width: 100%;
  height: 50px;
  border: none;
  border-radius: 9999px;
  background: var(--success, #28840F);
  color: #fff;
  font-size: 17px;
  font-weight: 700;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  margin-top: 16px;
}
/* Ховер — притемнение фильтром, а не вторым зелёным: отдельного «тёмного
   success» в токенах нет, а выдумывать значение рядом с токеном нельзя. */
.m-checkout-rd .kc-pay-btn:hover:not(:disabled) { filter: brightness(0.92); }
.m-checkout-rd .kc-pay-btn:disabled { opacity: 0.6; cursor: not-allowed; }
/* Подложка — как у пилюли промокода в САМОМ summary (.kc-pay-code, то есть
   --rd-tint), скругление полное; галочка — наш check-ic-14.svg маской в цвете
   success. Правка Игоря 09.09 отменяет прежнюю белую подложку «как пилюля на
   странице». */
.m-checkout-rd .kc-pay-safe {
  margin: 16px auto 0;
  width: fit-content;
  /* Именно `flex`, а не `inline-flex`: у инлайнового бокса `margin: auto` по
     горизонтали не центрирует, и плашка уезжала к левой кромке. */
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--rd-tint);
  color: var(--success, #28840F);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 600;
}
.m-checkout-rd .kc-pay-safeIc {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  background-color: var(--success, #28840F);
  -webkit-mask: url('/app/images/check-ic-14.svg') center / contain no-repeat;
  mask: url('/app/images/check-ic-14.svg') center / contain no-repeat;
}
/* Селектор был МЁРТВЫМ: скрипт печатает класс `kc-pay-error`, а не `kc-error`,
   поэтому сообщение об ошибке доставалось легаси-правилу .m-checkout
   .kc-pay-error с его #b00020. Заодно ссылка внутри сообщения не имела правил
   вовсе и рисовалась синей браузерной. */
.m-checkout-rd .kc-pay-error {
  color: var(--error, #C51013);
  font-size: 14px;
  margin-top: 8px;
}
.m-checkout-rd .kc-pay-error-link {
  color: inherit;
  text-decoration: underline;
}
/* border-radius убран: фон блока прозрачный (--why-so-unique: transparent),
   скруглять нечего. */
.m-checkout-rd .kc-why-block {
  background-color: var(--why-so-unique);
  display: grid;
  gap: 4px;
  margin-top: 48px;
}
/* Заголовок why-блока набран как заголовок страницы (.coPlanTitle): капс
   26/1.2, трекинг 0.03em, тёмный токен (правка Игоря 06.09). Своё — только
   margin/padding: он живёт внутри блока, а не в потоке страницы. Прежние
   Playfair Display и --header-text-color убраны: семейство и так перебивало
   правило шрифта страницы, а цвет был доредизайновый. */
.m-checkout-rd .kc-why-title {
  margin: 8px 0 0;
  padding-top: 0;
  font-size: 26px;
  line-height: 1.2;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  text-align: center;
  color: var(--text-light, #192126);
}
.m-checkout-rd .kc-why-row {
  padding: 8px 0 8px 8px;
  display: flex;
  gap: 24px;
  align-items: flex-start;
}
.m-checkout-rd .kc-why-block .kc-why-row:first-of-type {
  padding-top: 24px;
}
/* Иконки красятся токеном, поэтому подставлены CSS-маской, а не <img>:
   файлы одноцветные (один путь fill="black"), красить <img> нечем. Адрес
   приходит инлайновой переменной --ic из шаблона — тот же приём, что у
   .prIcon в профиле. */
.m-checkout-rd .kc-why-row__icon {
  margin-top: 4px;
  flex: 0 0 36px;
  width: 36px;
  height: 36px;
  background-color: var(--rd-accent);
  -webkit-mask: var(--ic) center / contain no-repeat;
  mask: var(--ic) center / contain no-repeat;
}
/* Заголовок строки — блочный: <br> между ним и текстом убран из разметки,
   строки разводит сам блок плюс padding-bottom 4 (правка Игоря 06.09). */
.m-checkout-rd .kc-why-row__title {
  display: block;
  font-size: 20px;
  line-height: 1.55;
  padding-bottom: 4px;
  color: var(--text-light, #192126);
}
.m-checkout-rd .kc-why-row__text {
  display: block;
  font-size: 14px;
  line-height: 1.55;
  padding-right: 10px;
  color: var(--text-light-muted, #5E6468);
}
.m-checkout-rd .kc-featband-wrap {
  max-width: 760px;
  margin: 56px auto 0;
}
/* Кегль, трекинг, капс и цвет — как у заголовка why-блока. Playfair Display
   и --header-text-color убраны: семейство перебивало правило шрифта страницы,
   цвет был доредизайновый. Тем же правилом набран заголовок блока отзыва —
   Игорь просил один-в-один, поэтому он стоит здесь же, а не копией. */
.m-checkout-rd .kc-featband-title,
.m-checkout-rd .kc-amb-card__title,
.m-checkout-rd .kc-program__title,
.m-checkout-rd .kc-wellness__changes-title,
.m-checkout-rd .kc-stories__title,
.m-checkout-rd .kc-faq__title,
.m-checkout-rd .kc-results__title {
  margin: 0 0 24px;
  text-align: center;
  font-size: 26px;
  line-height: 1.2;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-light, #192126);
}
/* Плашка логотипов: вместо заливки — волосяная обводка разделителя, радиус 26
   как у карточек страницы. */
.m-checkout-rd .kc-featband-strip {
  background: transparent;
  border: 1px solid var(--rd-hairline);
  border-radius: 26px;
  overflow: hidden;
}
.m-checkout-rd .kc-featband-strip-inner {
  padding: 24px 16px;
  display: grid;
  place-items: center;
}
.m-checkout-rd .kc-featband-image {
  display: block;
  width: 92%;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
}
/* Секция отзыва — сам по себе не карточка: подложка, тень, радиус и предел
   ширины сняты, карточкой стал только <article> внутри (правка Игоря 06.09).
   Заголовок набран правилом заголовка «As featured in» — см. выше.
   Мёртвое семейство system-ui убрано: его перебивает правило шрифта страницы. */
.m-checkout-rd .kc-amb-card {
  margin: 56px auto 0;
  background: transparent;
}
/* Шапка с аватаром убрана из разметки — её правила (.kc-amb-card__header,
   __profile, __avatar, __name, __stats) удалены вместе с ней. */
.m-checkout-rd .kc-amb-card__post {
  border-top: 0;
}
/* Верх карточки — картинка: скругление на обёртке плюс overflow, чтобы срез
   работал независимо от того, чем картинка заполняет бокс. */
.m-checkout-rd .kc-amb-card__media {
  position: relative;
  border-radius: 26px 26px 0 0;
  overflow: hidden;
}
.m-checkout-rd .kc-amb-card__image {
  display: block;
  width: 100%;
  height: auto;
}
.m-checkout-rd .kc-amb-card__caption {
  padding: 20px;
  border-radius: 0 0 26px 26px;
  background: #FFFFFF;
  font-size: 14px;
  line-height: 1.4;
  color: var(--text-light, #192126);
}
.m-checkout-rd .kc-amb-card__caption strong {
  display: block;
  margin-bottom: 8px;
  font-size: 16px;
}
/* Секция и её первый блок — уже не карточки: подложка, обводка, тень,
   радиусы и предел ширины сняты, карточкой стала только плашка со
   статистикой (правка Игоря 06.09). Заголовок набран общим правилом
   заголовков блоков — см. .kc-featband-title. */
.m-checkout-rd .kc-wellness {
  margin: 56px auto 0;
  background: transparent;
  padding: 0;
}
.m-checkout-rd .kc-wellness__changes {
  margin-top: 0;
  overflow: hidden;
}
.m-checkout-rd .kc-wellness__changes-head {
  padding: 0;
}
/* Боковые поля тела сняты вслед за полями шапки: иначе белая плашка
   статистики встала бы на 44 уже остальных карточек страницы. */
.m-checkout-rd .kc-wellness__changes-body {
  padding: 0;
}
.m-checkout-rd .kc-wellness__stats {
  display: grid;
  gap: 24px;
  margin: 0 0 12px;
  padding: 32px;
  border-radius: 26px;
  background: #FFFFFF;
}
.m-checkout-rd .kc-wellness__stat {
  text-align: left;
  padding: 0 0 24px;
  border-bottom: 1px solid var(--divider, #DADDE3);
}
/* У последней ячейки линии нет — как в списках профиля и Support. Вместе с
   ней снят и нижний отступ: он разводил текст с линией, а у кромки карточки
   его роль играет её собственное поле 32. */
.m-checkout-rd .kc-wellness__stat:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}
.m-checkout-rd .kc-wellness__percent {
  font-size: 32px;
  color: var(--text-light, #192126);
  line-height: 1;
  letter-spacing: 0;
}
/* Весь текст ячейки — одним muted: прежнее правило .kc-wellness__desc strong
   красило фрагмент в тёмный, выделение убрано (правка Игоря 06.09). */
.m-checkout-rd .kc-wellness__desc {
  color: var(--text-light-muted, #5E6468);
  margin-top: 8px;
  font-size: 16px;
  line-height: 1.55;
}
.m-checkout-rd .kc-wellness__note {
  text-align: center;
  font-style: italic;
  font-size: 13px;
  color: rgba(23, 32, 23, 0.5);
  margin-top: 0;
}
/* Две карточки сравнения. Первая — прозрачная в волосяной обводке
   разделителя; вторая берёт цвета блока промокода (заливка #DEF3DE, обводка
   #B0D9B0 — значения нод 649:3992 / 649:3993). Тени сняты, радиус 26 как у
   карточек страницы (правка Игоря 06.09). Отступ 32 стоит на самой карточке:
   «этот блок» в правке — вся карточка, а не список внутри. */
.m-checkout-rd .kc-wellness__card {
  margin-top: 32px;
  padding: 24px 20px;
  border: 1px solid var(--rd-hairline);
  border-radius: 26px;
  background: transparent;
  box-shadow: none;
}
.m-checkout-rd .kc-wellness__card--accent {
  margin-top: 10px;
  border-color: var(--rd-tint-line);
  background: var(--rd-tint);
}
.m-checkout-rd .kc-wellness__title {
  margin: 0 0 16px;
  padding-top: 0;
  color: var(--text-light, #192126);
  font-size: 18px;
  line-height: 24px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  text-align: center;
}
.m-checkout-rd .kc-wellness__nobrand {
  color: var(--error, #C51013);
}
.m-checkout-rd .kc-wellness__brand {
  color: var(--rd-accent);
}
.m-checkout-rd .kc-wellness__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 16px;
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-light, #192126);
}
.m-checkout-rd .kc-wellness__list li {
  display: grid;
  grid-template-columns: 16px 1fr;
  align-items: start;
  gap: 10px;
}
.m-checkout-rd .kc-wellness__list em {
  font-style: italic;
}
/* Иконки статуса двухцветные (круг плюс белый глиф), поэтому <img>, а не
   маска. Смещение 4.4 = (24.8 − 16) / 2 — центр иконки на центре первой
   строки 16/1.55. */
.m-checkout-rd .kc-wellness__ic {
  display: block;
  width: 16px;
  height: 16px;
  margin-top: 4.4px;
}
/* Крестик в списке «без IntimPath» — серым, а не красным (правка Игоря
   06.09). Файл circle-false.svg общий для продукта и залит `--error`, править
   его нельзя, поэтому цвет меняется фильтром: grayscale уводит #C51013 в
   яркость 54.65, множитель поднимает её до нужного серого.
   1.72 давало 94 — яркость `--text-light-muted`; по правке Игоря 07.09 круг
   на 30% светлее, то есть на 30% пути к белому: 94 + 0.3 × (255 − 94) = 142,
   отсюда 142 / 54.65 = 2.6. Белый крестик остаётся белым (255 × 2.6
   клипается), контраст с подложкой 3.3:1 — для сплошного глифа хватает. */
.m-checkout-rd .kc-wellness__list--grey .kc-wellness__ic {
  filter: grayscale(1) brightness(2.6);
}
/* Секция уже не карточка: предел ширины и радиус сняты, цвет — токен
   (правка Игоря 06.09). Заголовок набран общим правилом заголовков блоков —
   см. .kc-featband-title, поэтому своих объявлений у него больше нет. */
.m-checkout-rd .kc-faq {
  margin: 56px auto 0;
  background: transparent;
  padding: 0;
  color: var(--text-light, #192126);
}
/* Ячейки FAQ по образцу профиля (.faqScreen в app.css, экран
   /profile/faq): волосяная линия висит на ЯЧЕЙКЕ, а не на строке вопроса —
   иначе она оказалась бы между вопросом и раскрытым ответом; у последней её
   нет. Поля 24 по вертикали, вопрос 16/20 тёмным, шеврон 16 в #969FA6 —
   тот же глиф и тот же цвет, что у карточек Today и списка профиля.
   Раскрытие здесь нативное (<details>), без анимации высоты: у профиля её
   ведёт скрипт плеера, а тут разметку строит сервер. */
.m-checkout-rd .kc-faq__item {
  border-bottom: 1px solid var(--rd-hairline);
}
.m-checkout-rd .kc-faq__item:last-of-type {
  border-bottom: 0;
}
.m-checkout-rd .kc-faq__q {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 24px 0;
  color: var(--text-light, #192126);
}
.m-checkout-rd .kc-faq__q::-webkit-details-marker {
  display: none;
}
.m-checkout-rd .kc-faq__label {
  font-size: 16px;
  line-height: 20px;
}
.m-checkout-rd .kc-faq__a {
  overflow: hidden;
}
.m-checkout-rd .kc-faq__aIn {
  padding: 0 0 24px;
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-light-muted, #5E6468);
}
/* Раскрытие: высоту панели анимирует скрипт в пикселях (auto не
   анимируется) — ровно как аккордеон профиля; текст догоняет фейдом с
   задержкой 120мс. Правила включаются классом .is-live, который вешает тот
   же скрипт: без JS остаётся нативное поведение <details> и текст не
   должен быть спрятан. */
.m-checkout-rd .kc-faq.is-live .kc-faq__a {
  transition: height 300ms cubic-bezier(0.4, 0, 0.6, 1);
}
.m-checkout-rd .kc-faq.is-live .kc-faq__aIn {
  opacity: 0;
  transition: opacity 200ms ease-out;
}
.m-checkout-rd .kc-faq.is-live .kc-faq__item.is-open .kc-faq__aIn {
  opacity: 1;
  transition-delay: 120ms;
}
/* Закрытый — шеврон смотрит вниз, на раскрытии доворачивается на 180°:
   те же 90° / 270° и та же кривая, что в профиле. */
.m-checkout-rd .kc-faq__chev {
  flex: 0 0 auto;
  color: #969FA6;
  transform: rotate(90deg);
  transition: transform 300ms cubic-bezier(0.4, 0, 0.6, 1);
}
.m-checkout-rd .kc-faq__item[open] .kc-faq__chev {
  transform: rotate(270deg);
}
.m-checkout-rd .kc-faq.is-live .kc-faq__item .kc-faq__chev { transform: rotate(90deg); }
.m-checkout-rd .kc-faq.is-live .kc-faq__item.is-open .kc-faq__chev { transform: rotate(270deg); }
@media (prefers-reduced-motion: reduce) {
  .m-checkout-rd .kc-faq__chev,
  .m-checkout-rd .kc-faq.is-live .kc-faq__a,
  .m-checkout-rd .kc-faq.is-live .kc-faq__aIn { transition: none; }
}
.m-checkout-rd .kc-testimonial {
  margin-top: 10px;
  padding: 20px;
  background-color: var(--reviews-background);
  text-align: left;
  border-radius: 10px;
}
.m-checkout-rd .kc-testimonial:first-of-type {
  margin-top: 30px;
}
.m-checkout-rd .kc-testimonial__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  margin-bottom: 12px;
}
.m-checkout-rd .kc-testimonial__avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  flex: 0 0 44px;
  object-fit: cover;
}
.m-checkout-rd .kc-testimonial__meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.m-checkout-rd .kc-testimonial__handle {
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-light, #192126);
}
.m-checkout-rd .kc-testimonial__date {
  font-size: 12px;
  color: #9a9f9d;
}
.m-checkout-rd .kc-testimonial__stars {
  color: #f5a623;
  font-size: 16px;
  letter-spacing: 2px;
}
.m-checkout-rd .kc-testimonial__text {
  display: block;
  color: var(--text-light-muted, #5E6468);
  font-size: 16px;
  line-height: 1.55;
}
.m-checkout-rd .kc-testi-carousel {
  margin-top: 24px;
}
.m-checkout-rd .kc-testi-carousel__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-bottom: 20px;
}
.m-checkout-rd .kc-testimonial--card {
  min-height: 150px;
  background-color: #ffffff;
  border-radius: 26px;
  padding: 20px;
  box-shadow: none;
}
/* Отбивку карточек задаёт только нижний отступ. Верхний гасим и у первой
   тоже: правило .kc-testimonial:first-of-type специфичнее и иначе вернуло бы
   свои 30. */
.m-checkout-rd .kc-testimonial--card,
.m-checkout-rd .kc-testimonial--card:first-of-type {
  margin-top: 0;
  margin-bottom: 10px;
}
.m-checkout-rd .kc-testi-carousel__arrow {
  flex: 0 0 46px;
  width: 46px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background-color: #ffffff;
  color: #141d19;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(20, 29, 25, 0.12);
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.m-checkout-rd .kc-testi-carousel__arrow:hover {
  box-shadow: 0 8px 22px rgba(20, 29, 25, 0.18);
  transform: translateY(-1px);
}
.m-checkout-rd .kc-testi-carousel__dots {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
.m-checkout-rd .kc-testi-carousel__dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background-color: var(--empty-rating);
  cursor: pointer;
  transition: width 0.25s ease, background-color 0.25s ease;
}
.m-checkout-rd .kc-testi-carousel__dot--active {
  width: 22px;
  border-radius: 4px;
  background-color: #b7bbb9;
}


/* ===== female checkout =====
   Как и у кегеля, своих правил у женского чекаута больше нет (правка Игоря
   07.09): страница рендерится общим шаблоном и оформляется блоком
   .m-checkout-rd. Отличается только палитрой — она задана переменными в
   конце файла (§ Женская палитра). Прежние 909 строк удалены. */

/* ===== promo / countdown block (ported from inline PromoTimerBlock) ===== */
.m-checkout .checkout-promo { background: var(--discount-background-color, #acc0b0); border-radius: 10px; padding: 12px; margin: 10px 0; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); }
.m-checkout .checkout-promo__head { display: flex; align-items: center; justify-content: center; gap: 8px; }
.m-checkout .checkout-promo__head span { color: #1d4034; font-size: 17px; font-weight: 700; line-height: 24px; }
.m-checkout .checkout-promo__row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--pay-button-bg, #6b6b6b); }
/* Значок перед кодом вернулся сюда из checkout.js (правка 05.09). С 07.09
   этот блок остался только у женской страницы: мужская и кегель рисуют
   промокод карточкой .coPromo с настоящей иконкой. */
.m-checkout .checkout-promo__code::before { content: "\1F3F7\FE0F  "; }
.m-checkout .checkout-promo__code { flex: 1; display: flex; align-items: center; height: 54px; background: #f3f4f4; border: 1px solid #d2d4d3; border-radius: 6px; padding-left: 12px; font-size: 16px; font-weight: 700; color: #1d4034; }
.m-checkout .checkout-promo__timer { display: flex; align-items: center; justify-content: center; gap: 6px; min-width: 92px; height: 54px; padding: 0 10px; background: var(--discount-timer-bg, #208357); color: var(--discount-timer-text, #fff); border-radius: 6px; font-size: 20px; font-weight: 600; }
.m-checkout .checkout-promo__timer small { display: block; font-size: 11px; font-weight: 500; }
/* ═══════════════════════════════════════════════════════════════════════════
   РЕДИЗАЙН /master-sex-checkout — навбар и секция сравнения (04.09.2026)

   Референс скелета — Figma 615:20509 (фрейм 393). Из него взяты ТОЛЬКО
   размеры, отступы и радиусы; цвета заменены нашими токенами, шрифт — Faculty
   Glyphic, канвас — фон мужской воронки.

   ПОЧЕМУ ЗДЕСЬ МОЖНО ССЫЛАТЬСЯ НА КОМПОНЕНТЫ ПРИЛОЖЕНИЯ: чекаут-страницы
   подключают И app.css (через partials/app-head), И этот файл. Поэтому
   .appCta и .readerCtaBar берутся НАСТОЯЩИЕ, а не копиями, как пришлось делать
   в воронках (там только main.css). Правишь их в app.css — правка доезжает
   сюда сама; ниже только перекраска под канвас чекаута.

   Шапка файла говорит «generated … do not edit by hand» — генератора этого
   файла в репозитории нет (артефакт разового порта с Next.js), файл давно
   правится руками.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Канвас объявлен ещё и на BODY. Корни оверлеев (.kf-overlay воронки,
   .kf-modal-backdrop, .kc-policy-overlay) лежат РЯДОМ с .kc-root, а не внутри, поэтому
   со скоупом .kc-root токен до них не наследовался — и лист оплаты вместе с
   экранами успеха/отказа рисовался на фолбэке #FAFAFA вместо цвета воронки
   (замер: оверлей rgb(250,250,250) на обеих воронках). Значение обязано
   совпадать со значением на .kc-root ниже. */
/* Палитра редизайна тоже на BODY, и по той же причине: плашка промокода в
   листе оплаты красится `--rd-tint`, а лист лежит в [data-payment-root] —
   СОСЕДЕ .kc-root (замер: `rgba(0,0,0,0)` вместо тинта). Страничные правила
   от переезда не страдают: они все внутри .kc-root, и токен доезжает до них
   наследованием. */
body.m-checkout-rd {
  --page-bg: #F2F1F6;
  /* Цвет выделения страницы: акцентные части заголовков, выбранный пакет,
     иконки why-блока, пилюля и шкала «Your Goal», числа «Inside your
     program», галочка согласия. У мужской и кегель-страниц это наш зелёный
     токен, у женской — акцент её воронки (см. § Женская палитра в конце
     файла). НЕ путать с зеленью блоков промокода и «100% money-back»: там
     цвета прибиты значениями нод и от страницы не зависят. */
  --rd-accent: var(--success, #28840F);
  /* Пара тинтов карточки «What IntimPath can help you with», блока промокода
     и «100% money-back». Значения по умолчанию РАВНЫ нодовым зелёным. */
  --rd-tint: #DEF3DE;
  --rd-tint-line: #B0D9B0;
  /* Волосяная обводка карточек и разделители ячеек: чёрный 15% (правка Игоря
     07.09; был `--divider` #DADDE3). Холодный серый токена спорил с тёплым
     канвасом женской страницы, а на мужской и кегельной чёрный с
     прозрачностью читается ровнее — Игорь распространил его на все три.
     Затронуты «30-day money-back guarantee», «How life might be without
     IntimPath», плашка логотипов «As featured in», ячейки «Inside your
     program» и разделители FAQ. Остальные волосяные линии (строки блока
     сравнения, ячейки статистики, обводка отметки выбора и чекбокса, пустые
     черточки шкалы) остались на `--divider`. */
  --rd-hairline: rgba(0, 0, 0, 0.15);
}

.m-checkout-rd .kc-root {
  /* --page-bg ЗДЕСЬ БОЛЬШЕ НЕ ОБЪЯВЛЯЕТСЯ (поймано Игорём 13.09: женский чекаут
     стоял на мужском канвасе). Он объявлен на BODY — и у `-rd`, и у женской
     страницы, — а эта копия на .kc-root ПЕРЕКРЫВАЛА женское значение для всего,
     что внутри: переменная берётся с ближайшего предка, и порядок правил в
     файле тут ни при чём. Копия осталась с 09.09, когда токены переносили на
     body ради листа оплаты (он лежит РЯДОМ с .kc-root). Замер до починки:
     на body #F7F0EB, на .kc-root #F2F1F6, фактический фон 242,241,246.
     Цвет выделения: акцентные части заголовков, выбранный пакет,
     иконки why-блока, пилюля и шкала «Your Goal», числа «Inside your
     program», галочка согласия. У мужской и кегель-страниц это наш зелёный
     токен, у женской — акцент её воронки (см. § Женская палитра в конце
     файла). НЕ путать с зеленью блоков промокода и «100% money-back»: там
     цвета прибиты значениями нод и от страницы не зависят. */
  /* --rd-accent / --rd-tint / --rd-tint-line / --rd-hairline объявлены на
     BODY (см. выше): их читает ещё и лист оплаты, который лежит РЯДОМ с
     .kc-root. Сюда они доезжают наследованием. */
  /* Faculty ships 400 only; ниже вес прибит явно на переписанных блоках. */
  font-family: "Faculty Glyphic", "Helvetica Neue", Arial, sans-serif;
  color: var(--text-light, #192126);
}
/* Колонка 480 и поля 20 — как на Today (.m-todayscreen .section: padding 0 20).
   Было 724/16: на телефоне это давало почти полноэкранную ширину, а верхняя
   секция вообще не тянулась — её ширины были прибиты медиазапросами
   (колонки 154, картинка 312), они удалены вместе со старой разметкой. */
.m-checkout-rd .kc-inner {
  margin: 0 auto;
  max-width: 480px;
  padding: env(safe-area-inset-top, 0px) 20px 120px;
}

/* ── Навбар (Figma 615:20511) ──────────────────────────────────────────────
   Из нод: высота 64, внутренняя строка min-height 56, кнопка 200×48 радиус
   999, текст таймера 28/40, боксы цифр 40 и двоеточие 10. Плашки и тени у
   макета (белый 80% + blur 8 + тень) здесь нет: навбар не фиксированный
   (решение Игоря 04.09), уезжает вместе с контентом, и отделять его от
   страницы нечем — он и не должен. */
.m-checkout-rd .coNav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 64px;
  /* Белая подложка — из ноды (замечание Игоря 04.09). Во всю ширину колонки,
     как Header в макете: он там шириной во весь фрейм, а не по полям контента,
     поэтому отрицательные поля возвращают их обратно паддингом.
     В ноде заливка — белый 80% с backdrop-blur 8; и то и другое там нужно,
     потому что бар зафиксирован и под ним ездит контент. Наш скролится вместе
     со страницей, размывать ему нечего, а 80% поверх канваса дали бы не белый,
     а сероватый — поэтому сплошной #FFFFFF. */
  margin: 0 -20px;
  padding: 4px 20px;
  background: #FFFFFF;
}
.m-checkout-rd .coNavTimer {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  font-size: 28px;
  line-height: 40px;
  /* Зелёный макета → наш токен. */
  color: var(--rd-accent);
  font-variant-numeric: tabular-nums;
}
/* Ширины боксов из нод: цифры 40, двоеточие 10 — так счётчик не дёргает
   кнопку при смене разряда. */
.m-checkout-rd .coNavTimerNum { display: inline-block; width: 40px; text-align: center; }
.m-checkout-rd .coNavTimerSep { display: inline-block; width: 10px; text-align: center; }
/* Геометрия из нод, вид — продуктовая кнопка: .appCta уже даёт тёмную заливку
   --btn-dark, радиус 999, кегль 15/0.5 и отклик нажатия (решение Игоря 04.09
   — зелёный макета для CTA не берём). */
/* 200 из нод — но не жёстко: `flex: 0 1 200px` даёт ровно 200, пока строка
   помещается, и позволяет ужаться на узком экране, где иначе таймер и кнопка
   не разошлись бы. `max-width` в процентах здесь не годится — он резал бы
   кнопку до 199.1 уже на 402 (362 × 55%). */
.m-checkout-rd .coNavCta {
  flex: 0 1 200px;
  width: auto;
  min-width: 0;
  min-height: 48px;
  padding: 0 16px;
  text-transform: uppercase;
}

/* ── Секция сравнения (Figma 615:20538) ────────────────────────────────────
   В макете plan-box шире своей обёртки (393 против 361), то есть идёт во всю
   ширину фрейма — повторяем отрицательными полями по 20. */
.m-checkout-rd .coCompare {
  margin: 0 -20px;
}
/* Зона hero: от кромки навбара до белого блока сравнения. Её padding-top даёт
   те же 24 зазора, что раньше были margin'ом секции, а фон — вертикальный
   градиент (правка Игоря 04.09): #E9E9F0 в нуле, #F2F1F6 с 70% и ниже.
   Высота не задаётся числом — её набирают содержимое (34 строка пилюль + 246
   полоса картинок) и этот padding, итого 304. Поэтому 70% градиента всегда
   приходится на одно и то же место относительно картинок, как бы их размер
   ни правился дальше.
   Картинки — PNG с альфой (RGBA), так что градиент виден и вокруг фигур. */
.m-checkout-rd .coHeroZone {
  padding-top: 24px;
  background: linear-gradient(180deg, #E9E9F0 0%, #F2F1F6 70%);
}
/* Строка пилюль: min-height 32, пилюля по центру своей половины. */
.m-checkout-rd .coCompareRow { display: flex; }
.m-checkout-rd .coCompareHalf {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  min-height: 32px;
}
/* Пилюля: радиус 12, поля 12/8, текст 12/18 (всё из нод). «Now» — белая с
   тёмным текстом, «Your Goal» — в нашем зелёном токене. */
/* Пилюля: радиус 12 и поля 8/12 из нод, кегль 14 (правка Игоря 04.09; в
   макете 12). Интерлиньяж оставлен макетным 18 — высота пилюли от этого
   остаётся 34, на которой построена вся вертикаль секции.
   Цвет заливки живёт в переменной, потому что его же берёт кончик. */
.m-checkout-rd .coPill {
  --pill-bg: #FFFFFF;
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 8px 12px;
  border-radius: 12px;
  background: var(--pill-bg);
  color: var(--text-light, #192126);
  font-size: 14px;
  line-height: 18px;
}
.m-checkout-rd .coPillGoal {
  --pill-bg: var(--rd-accent);
  color: #FFFFFF;
}
/* Кончик тултипа снизу по центру (правка Игоря 04.09; в макете чекаута его
   нет, форма — со скриншота Игоря). Пропорции сняты с него: у пузыря высотой
   365 кончик 105×55, то есть 28.8% и 15% от высоты; на нашей пилюле 34 это
   10×5. Рисуем границами: 5 прозрачных слева и справа дают ширину 10, верхняя
   в цвет пилюли — высоту 5. Цвет берётся из --pill-bg, поэтому у «Your Goal»
   кончик зелёный сам, без второго правила. */
.m-checkout-rd .coPill::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid var(--pill-bg);
  pointer-events: none;
}
/* Hero: две картинки по 216×180 (файлы @2x), у каждой своя половина.
   Вертикаль в координатах секции: строка пилюль 0…34, полоса hero 34…280
   (отбивка сверху 16 + картинка 230), белый блок с 280. В макете картинка 180
   при отбивке 24 и низ hero на 238 — всё это правки Игоря 04.09, включая
   подъём стрелок на 20 (82 → 62 от начала секции).

   Картинка ШИРЕ своей половины (216 против 201 на вьюпорте 402), поэтому
   центрируется абсолютом и обрезается кромками половины — тем же приёмом, что
   фото карточки пикера (app.css .pickPhoto): `left: 50% + translateX(-50%)`
   центрирует и при переполнении, в отличие от `justify-content: center`, у
   которого обрезанный край становится недостижимым для прокрутки. На широкой
   колонке (480) половина шире картинки, и та просто стоит по центру. */
.m-checkout-rd .coCompareHero {
  position: relative;
  display: flex;
  /* 24 отбивки + картинка 180 (правка Игоря 09.09: полоса приведена к женской,
     то есть к НОДОВОЙ геометрии 644:2429; до этого у мужской и кегельной было
     16 + 230 — картинки, увеличенные вручную 04.09 с макетных 180 до 210 и
     затем до 230). Теперь все три страницы одинаковы, и женских оверрайдов
     геометрии больше нет — у неё осталась только своя пара стопов градиента. */
  height: 204px;
}
.m-checkout-rd .coHeroHalf {
  position: relative;
  overflow: hidden;
  min-height: 0;
}
.m-checkout-rd .coHeroImg {
  position: absolute;
  top: 24px;
  left: 50%;
  transform: translateX(-50%);
  /* 216×180 — та же пропорция файлов (432×360 = 1.2), но при нодовой высоте
     180. При 216 в половине 201 обрезается по 7.5 с каждой стороны — столько
     же, сколько в макете. */
  width: 216px;
  height: 180px;
  max-width: none;
  display: block;
}
/* Стрелки: 47×48 (размер файла; Игорь переснял его с трёх шевронов на два),
   по центру ВСЕЙ секции. Верх 48 от начала полосы hero — из ноды (там y 82
   при начале полосы на 34); прежние 28 относились к увеличенным вручную
   картинкам.
   Серый макета (#DDDCE0) отличается от нашего --divider на 3/255 по каналу,
   но красим всё равно токеном — маской по файлу, тем же приёмом, что иконки
   списка профиля (app.css .prIcon): у <img> цвет не подменить. */
.m-checkout-rd .coHeroArrows {
  position: absolute;
  top: 48px;
  left: 50%;
  transform: translateX(-50%);
  width: 47px;
  height: 48px;
  pointer-events: none;
}
/* Каждый шеврон — отдельный слой: файл разрезан на два, и в каждом остался
   ТОТ ЖЕ viewBox 47×48, поэтому слои кладутся inset: 0 и встают ровно на свои
   места — позиционировать по отдельности нечего. Разрез вместо инлайнового
   SVG — приём разрезанных иконок перемотки в плеере: движение идёт
   CSS-трансформом по своему слою, то есть на GPU и без перерисовки вектора,
   а маска остаётся и красит шеврон нашим токеном (у файла свой жёсткий
   #DDDCE0, через <img> его не подменить). */
.m-checkout-rd .coHeroArrow {
  position: absolute;
  inset: 0;
  background-color: var(--divider, #DADDE3);
  -webkit-mask: var(--ic) center / contain no-repeat;
  mask: var(--ic) center / contain no-repeat;
  /* Анимация бесконечная, поэтому постоянный слой оправдан: он же спасает от
     растрового дрожания на дробных пикселях по ходу кривой. */
  will-change: transform;
  /* Кривая НЕсимметричная: разгон на 0.25, торможение на 0.5 — та же, что у
     волны на экране результата самопроверки. Она подобрана Игорем ровно под
     «мягкий финиш»: за первые 10% времени проходится 4.8% пути, за последние
     25% — 9%. Симметричная cubic-bezier(0.4, 0, 0.6, 1), стоявшая здесь
     сначала, читалась резче (правка Игоря 04.09). Домашнее правило проекта:
     мягкий финиш даёт длительность + easeOutCubic-профиль, а не более крутая
     кривая вроде easeOutQuint — та, наоборот, читается рывком. */
  animation: coArrowNudge 2150ms cubic-bezier(0.25, 0, 0.5, 1) infinite;
}
/* Стаггер: правый шеврон трогается позже левого, так волна бежит вправо —
   туда же, куда смотрят стрелки. Удвоен вместе с длительностью хода (было
   120 при ходе 900): при вдвое более медленном движении прежняя задержка
   читалась бы как одновременный старт. */
.m-checkout-rd .coHeroArrow:nth-child(2) { animation-delay: 240ms; }

/* Толчок ВПРАВО и возврат, потом пауза: покой → +5 → покой за 1800мс
   (было 900 — правка Игоря 04.09, «в два раза длиннее ради плавности»),
   остаток 350мс — стоим (пауза уменьшена вдвое, там же). Цикл 2150, поэтому
   пик на 900/2150 = 41.86%, возврат на 1800/2150 = 83.72%.
   Кривая применяется к каждому отрезку, поэтому и подход к пику, и возврат в
   покой затухают одинаково мягко. Амплитуда 5 — треть расстояния между
   шевронами (их контуры начинаются на 0.63 и 16.08): заметно, но пара не
   разъезжается. */
@keyframes coArrowNudge {
  0%       { transform: translateX(0); }
  41.86%   { transform: translateX(5px); }
  83.72%   { transform: translateX(0); }
  100%     { transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .m-checkout-rd .coHeroArrow { animation: none; }
}
/* Белый блок строк. В макете он собран из двух половин, у каждой скруглены
   только ВНЕШНИЕ углы (20) — вместе выходит один блок со скруглением по всем
   четырём. У нас это один элемент, поэтому радиус задаётся сразу. Поля 20 у
   каждой половины (из нод), снизу у блока 8. */
.m-checkout-rd .coCompareInfo {
  display: flex;
  border-radius: 26px;
  background: #FFFFFF;
  /* 4 сверху — правка Игоря 05.09 (в макете 0); 8 снизу и радиус 26 —
     правка Игоря 09.09 (были 16 и 20). */
  padding-top: 4px;
  padding-bottom: 8px;
}
.m-checkout-rd .coCompareCol { flex: 1 1 0; min-width: 0; padding: 0 20px; }
/* Строка: сверху 12, снизу 13 (правка Игоря 09.09; из нод было 16/17),
   волосяная линия. У ПОСЛЕДНЕЙ строки остались нодовые 16/16 и нет линии —
   Игорь назвал значения только для .coInfoItem, поэтому .coInfoItemLast ниже
   не тронут и он на 4 выше остальных. */
.m-checkout-rd .coInfoItem {
  padding: 12px 0 13px;
  border-bottom: 1px solid var(--divider, #DADDE3);
}
.m-checkout-rd .coInfoItemLast { padding: 16px 0; border-bottom: 0; }
/* Кегль 16/1.55 вместо макетных 14/20 и отбивка 4 до значения — правка Игоря
   04.09. 16/1.55 — типографика текста читалки, ею набран весь продукт. */
.m-checkout-rd .coInfoTitle {
  font-size: 16px;
  line-height: 1.55;
  /* 2 — правка Игоря 09.09 (было 4). */
  padding-bottom: 2px;
  color: var(--text-light, #192126);
}
.m-checkout-rd .coInfoValue {
  font-size: 12px;
  line-height: 18px;
  color: var(--text-light-muted, #5E6468);
}
/* Полоски шкалы: отбивка сверху 8, зазор 4.1, высота 8, радиус 2 (из нод).
   Цвета макета (оранжево-красный градиент «плохого» уровня и зелёный
   «хорошего») → наша пара токенов --error / --success, пустые — --divider. */
.m-checkout-rd .coProgress { display: flex; gap: 4.1px; padding-top: 8px; }
.m-checkout-rd .coLine {
  flex: 1 1 0;
  min-width: 0;
  height: 8px;
  border-radius: 999px;
  background: var(--divider, #DADDE3);
}
.m-checkout-rd .coLine.is-now { background: var(--error, #C51013); }
.m-checkout-rd .coLine.is-goal { background: var(--rd-accent); }

/* ── Прибитая кнопка: бар читалки, перекрашенный в канвас ──────────────────
   Геометрия и растворяющий хвост — из app.css (.readerCtaBar + FIXED_BOTTOM_WIDE
   в app-player.js: fixed, 480, translateX(-50%), хвост 34). Здесь только
   позиционирование (в app.css бар по умолчанию relative, fixed ему выдаёт
   инлайн плеера) и цвет: у читалки подложка белая, у нас — канвас. Боковое
   поле 20, чтобы кнопка встала по полю страницы, а не на 4 уже. */
.m-checkout-rd .coCtaBar {
  position: fixed;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  max-width: 480px;
  z-index: 20;
  padding: 0 20px 20px;
  background: #F2F1F6;
}
.m-checkout-rd .coCtaBar::before {
  background: linear-gradient(
    to bottom,
    rgba(242, 241, 246, 0),
    rgba(242, 241, 246, 0.57) 45%,
    rgba(242, 241, 246, 0.94) 85%,
    #F2F1F6
  );
}

/* ЖИРНОСТЬ. У Faculty Glyphic одно начертание — 400; всё, что просит другое,
   браузер синтезирует сам, и текст плывёт. На переписанных блоках вес прибит
   явно вместе с запретом синтеза. `!important` здесь на всякий случай: в
   исходной разметке этой страницы жирности стоят ИНЛАЙНОМ и обычное
   объявление они бы перебили. */
.m-checkout-rd .coNav,
.m-checkout-rd .coNav *,
.m-checkout-rd .coCompare,
.m-checkout-rd .coCompare *,
.m-checkout-rd .coCtaBar,
.m-checkout-rd .coCtaBar * {
  font-family: "Faculty Glyphic", "Helvetica Neue", Arial, sans-serif;
  font-weight: 400 !important;
  font-synthesis-weight: none;
  -webkit-font-synthesis: none;
  font-synthesis: none;
}


/* ── Заголовок «Get your Personal / Sex is a Skill plan!» (правка Игоря 05.09)
   Капс 28/1.2, трекинг 1.1 — значение редизайна для капсовых заголовков
   (.spTitle сплиттера и заголовки стартовых экранов воронок, оба 30 капсом,
   tailwind.css § СПЛИТТЕРЫ). Регистр задаёт CSS: строки контента
   (MASTER_CONTENT.planHeadline) набраны обычным регистром.
   Отступ сверху 40 — от белого блока сравнения; прежние стрелки-подсказка и
   разделитель между ними убраны. */
.m-checkout-rd .coPlanTitle {
  margin: 40px 0 0;
  font-size: 26px;
  line-height: 1.2;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  text-align: center;
  color: var(--text-light, #192126);
}
/* Строки — блочные: в контенте они приходят двумя отдельными элементами
   (раньше их склеивал <br> внутри одной строки). */
/* Спаны частей заголовка. Ими набраны и заголовок страницы, и заголовок
   why-блока — обе выделяют вторую строку токеном --success. */
.m-checkout-rd .coPlanTitleLead,
.m-checkout-rd .coPlanTitleAccent { display: block; }
.m-checkout-rd .coPlanTitleAccent { color: var(--rd-accent); }

/* ── ШРИФТ И ЖИРНОСТЬ НА ВСЕЙ СТРАНИЦЕ (правка Игоря 05.09) ────────────────
   У Faculty Glyphic одно начертание — 400. Всё, что просит другое, браузер
   синтезирует сам, и текст плывёт. Просит многое: в разметке чекаута жирности
   стоят ИНЛАЙНОМ, а в правилах выше по этому файлу — свои font-weight и свои
   семейства (Sofia Pro, Playfair Display, SF Pro, Urbanist, New York).
   Поэтому вес и семейство прибиты ко ВСЕЙ странице с `!important`: иначе
   инлайновый стиль и доредизайновые правила побеждают.

   Селектор по `body.m-checkout-rd`, а не по `.kc-root`: лист оплаты и
   экраны пост-покупки (kc-pay-*, kf-*) рисуются в [data-payment-root] /
   [data-funnel-root] — они вне .kc-root, но на той же странице.

   Заголовки в разметке — <h1>/<h2>, у них ещё и браузерный bold; он снимается
   тем же правилом. */
body.m-checkout-rd,
body.m-checkout-rd * {
  font-family: "Faculty Glyphic", "Helvetica Neue", Arial, sans-serif !important;
  font-weight: 400 !important;
  font-synthesis-weight: none;
  -webkit-font-synthesis: none;
  font-synthesis: none;
}


/* ── Блок промокода по референсу Figma 649:3992 (правка Игоря 05.09) ───────
   Из нод: карточка радиус 30, шапка поля 13/13/4 с обводкой 1px сверху и по
   бокам, полоса перфорации высотой 24 с линией 1px и двумя кругами 24 в цвет
   канваса на left/right −12 (их наполовину срезает overflow полосы), тело
   поля 4/13/13 с обводкой снизу и по бокам; пилюля кода белая, радиус 42,
   поля 4 4 4 16; иконка 32, галочка 16, тексты 16/24; таймер — плашка радиус
   30, поля 6/16, ряд цифр высотой 20 (цифры 18, боксы 37, двоеточие с
   прозрачностью 0.5), подписи 10/14 с минимальной шириной 42 и зазором 4.

   ЦВЕТА. Значения нод — заливка #DEF3DE, все волосяные линии и обводки
   выкусов #B0D9B0 (правка Игоря 05.09). Выводить их из `--success` через
   color-mix пробовали — 10% по канвасу даёт rgb(222,230,223) против макетных
   rgb(222,243,222): тон уходит в серый, на глаз не тот цвет. С 07.09 они
   стоят в токенах `--rd-tint` / `--rd-tint-line`, значения которых по
   умолчанию РАВНЫ этим двум хексам, — так женская страница получает свою
   тёплую пару, не заводя вторую копию правил.
   Выкусы перфорации — ровно `--page-bg`, как в ноде. Тексты — `--text-light`.
   Тёплая подложка таймера #FFF3CA — тоже как в ноде 649:4016 (две сплошные
   заливки друг на друге, верхняя и есть #FFF3CA); янтаря в палитре нет. */
.m-checkout-rd .coPromo {
  margin-top: 20px;
  border-radius: 30px;
  background: var(--rd-tint);
}
.m-checkout-rd .coPromoHead {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 13px 13px 4px;
  border: 1px solid var(--rd-tint-line);
  border-bottom: 0;
  border-radius: 30px 30px 0 0;
}
.m-checkout-rd .coPromoIcon { flex: 0 0 auto; display: block; width: 32px; height: 32px; }
.m-checkout-rd .coPromoHeadText {
  font-size: 16px;
  line-height: 24px;
  color: var(--text-light, #192126);
}
/* Полоса перфорации. Круги наполовину за кромками, лишнее срезает overflow —
   так в макете и получается «билетный» выкус. */
.m-checkout-rd .coPromoPerf {
  position: relative;
  display: flex;
  align-items: center;
  height: 24px;
  overflow: hidden;
}
.m-checkout-rd .coPromoLine {
  flex: 1 1 auto;
  height: 1px;
  border-radius: 100px;
  background: var(--rd-tint-line);
}
.m-checkout-rd .coPromoPerf::before,
.m-checkout-rd .coPromoPerf::after {
  content: "";
  position: absolute;
  top: 0;
  width: 24px;
  height: 24px;
  box-sizing: border-box;
  border-radius: 999px;
  background: var(--page-bg, #F2F1F6);
  border: 1px solid var(--rd-tint-line);
}
.m-checkout-rd .coPromoPerf::before { left: -12px; }
.m-checkout-rd .coPromoPerf::after { right: -12px; }

.m-checkout-rd .coPromoBody {
  padding: 4px 13px 13px;
  border: 1px solid var(--rd-tint-line);
  border-top: 0;
  border-radius: 0 0 30px 30px;
  overflow: hidden;
}
.m-checkout-rd .coPromoCode {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 4px 4px 16px;
  border-radius: 42px;
  background: #FFFFFF;
}
.m-checkout-rd .coPromoCodeLeft {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.m-checkout-rd .coPromoCheck { flex: 0 0 auto; display: block; width: 16px; height: 16px; }
.m-checkout-rd .coPromoCodeText {
  font-size: 16px;
  line-height: 24px;
  color: var(--text-light, #192126);
}
/* Таймер. Высота пилюли кода (54 в макете) держится именно им: 4 + 46 + 4,
   где 46 = поля 6 + ряд цифр 20 + подписи 14 + 6. Поэтому интерлиньяж цифр
   здесь 20, а не нодовые 28: в ноде ряд задан высотой 20, и 28 — это
   собственный интерлиньяж текстового стиля, который Figma центрирует внутри
   ряда; в CSS 28 просто вылезли бы на подписи. */
.m-checkout-rd .coPromoTimer {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  max-height: 48px;
  padding: 6px 16px;
  border-radius: 30px;
  background: #FFF3CA;
}
.m-checkout-rd .coPromoTimerRow {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 20px;
  gap: 2px;
}
.m-checkout-rd .coPromoTimerNum {
  width: 37px;
  text-align: center;
  font-size: 18px;
  line-height: 20px;
  color: var(--text-light, #192126);
  font-variant-numeric: tabular-nums;
}
.m-checkout-rd .coPromoTimerSep {
  font-size: 18px;
  line-height: 20px;
  opacity: 0.5;
  color: var(--text-light, #192126);
}
.m-checkout-rd .coPromoTimerCaps { height: 14px; gap: 4px; }
.m-checkout-rd .coPromoCap {
  min-width: 42px;
  text-align: center;
  font-size: 10px;
  line-height: 14px;
  color: var(--text-light, #192126);
}

/* Отступ от блока промокода до пакетов (правка Игоря 05.09). Правило стоит
   ПОЗЖЕ доредизайнового `.m-checkout-rd .plans_list` по файлу — иначе
   пришлось бы поднимать специфичность. */
.m-checkout-rd .plans_list {
  margin-top: 40px;
}


/* ── Пакеты по референсу Figma 615:20739 (правка Игоря 05.09) ──────────────
   Числа из нод. Список — колонка с зазором 8 (нода 615:20740). Карточка
   615:20741: белая, радиус 26, высота 88, поля 16; отметка выбора 20 и
   колонка текста через 16, между названием и подписью 2. Название 16/155%
   капсом, подпись 11/140%. Справа блок 615:21987 «старая цена → новая»:
   зазор 6, стрелка 12 со штрихом 1.2, оба кегля 16/120%; зачёркивания в ноде
   НЕТ (textDecoration NONE у 615:21989) — старую цену отделяет только цвет и
   стрелка. Соседний блок «$0.04 per day» (615:20758) в макете скрыт.

   Бейдж показывается ТОЛЬКО у выбранного пакета — плашкой 24 у верхней кромки
   (нода 615:20776, текст 14/20 капсом, звезда 16, точка-разделитель). У
   невыбранных карточек надписи нет ни одной в макете, поэтому прежний
   `.plan-offer-badge` на каждой карточке ушёл.

   ОТЛИЧИЯ ОТ МАКЕТА, о которых просил Игорь. (а) В ноде выделенная карточка —
   белый бокс с обводкой 1px и плашкой во всю ширину, поэтому внутренние углы
   белого поля прямые. Здесь зелёная подложка сделана рамкой 4 по бокам и
   снизу, а белое поле скруглено КОНЦЕНТРИЧНО: 22 = 26 − 4. (б) Радиус самой
   карточки 26 — как у невыбранных, а не нодовые 16: разнобой между соседними
   карточками читался ошибкой. (в) Отметка выбора 24, а не нодовые 20.
   (г) Подпись 12, а не нодовые 11. (д) Поля плашки бейджа 6, а не 2.

   ЦВЕТА. Зелень плашки и рамки — наш токен `--success` (#28840F): в ноде
   плашка #1F871F, но галочка выбора там же нарисована ровно нашим токеном
   (нода 650:4078 = #28840F), и второй зелёный на странице не нужен. Тексты —
   токены продукта вместо макетных #2C2118/#7A6D5D: `--text-light` и
   `--text-light-muted`. Обводка невыбранной отметки — `--divider` (в ноде
   #D8D7E1, тот же волосяной серый). */
.m-checkout-rd .plan-box {
  position: relative;
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 26px;
  background: #FFFFFF;
  color: var(--text-light, #192126);
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  /* Отклик нажатия — тот же рецепт, что у карточек ответов воронки
     (.qzAnswer в § СКИН ВОРОНОК, а туда он пришёл из app.css): вжатие до 0.97
     за 90мс, возврат 260мс. Класс .is-pressed вешает общий драйвер
     partials/app-press.ejs — селектор карточки добавлен в его SEL. */
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition: transform 260ms ease-out;
}
.m-checkout-rd .plan-box.is-pressed,
.m-checkout-rd .plan-box:active {
  transform: scale(0.97);
  transition: transform 90ms ease-out;
}
.m-checkout-rd .plan-box.plan-selected {
  padding: 0 4px 4px;
  border-radius: 26px;
  background: var(--rd-accent);
  box-shadow: 0 6px 24px rgba(24, 25, 37, 0.1);
  cursor: default;
}
/* Плашка бейджа. Высота 24 держится строкой 20 плюс поля 2 — как в ноде. */
.m-checkout-rd .plan-label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px;
  color: #FFFFFF;
  font-size: 14px;
  line-height: 20px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}
.m-checkout-rd .plan-label-star {
  flex: 0 0 auto;
  font-size: 16px;
  line-height: 16px;
}
.m-checkout-rd .plan-body {
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 108px;
  padding: 16px 20px 16px 16px;
  border-radius: inherit;
}
.m-checkout-rd .plan-selected .plan-body {
  border-radius: 22px;
  background: #FFFFFF;
}
/* Отметка выбора. Обводка невыбранной — inset-тенью, а не border: в ноде она
   INSIDE и в габарит 20 не входит. */
.m-checkout-rd .plan-mark {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #FFFFFF;
  box-shadow: inset 0 0 0 1.25px var(--divider, #DADDE3);
}
.m-checkout-rd .plan-selected .plan-mark { box-shadow: none; }
/* Галочка — <img>, а на iOS долгое нажатие по картинке поднимает системное
   меню («Share… / Save to Photos») и рвёт отклик; тот же набор свойств стоит
   у глифов плеера. */
.m-checkout-rd .plan-mark-on {
  display: block;
  width: 24px;
  height: 24px;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
  -webkit-touch-callout: none;
}
.m-checkout-rd .plan-info {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Трекинг капса. У продукта он держится около ОДНОГО пикселя независимо от
   кегля: 1.1px при 12 (надзаголовки сплиттеров и воронок) и 0.84px при 28
   (заголовок этой страницы). 0.06em при 16 = 0.96px и 0.07em при 14 = 0.98px
   ложатся ровно в этот ряд (правка Игоря 05.09). */
.m-checkout-rd .plan-duration {
  margin: 0;
  font-size: 18px;
  line-height: 1.55;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-light, #192126);
}
.m-checkout-rd .plan-offer {
  font-size: 12px;
  line-height: 1.4;
  color: var(--text-light-muted, #5E6468);
}
.m-checkout-rd .plan-price {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
}
/* Старая цена набрана серым #969FA6 — тем же, что шевроны карточек и
   неактивные вкладки таббара; `--text-light-muted` (#5E6468) для неё
   оказался слишком плотным, разницы с новой ценой почти не читалось.
   Линия зачёркивания при этом красная (`--error`), а стрелка между ценами —
   тёмная (правка Игоря 06.09): цвет линии задаётся отдельно от цвета текста
   через text-decoration-color. */
.m-checkout-rd .plan-crossed {
  margin: 0;
  font-size: 16px;
  line-height: 1.2;
  text-decoration: line-through;
  text-decoration-color: var(--error, #C51013);
  color: #969FA6;
}
.m-checkout-rd .plan-arrow {
  flex: 0 0 auto;
  display: block;
  color: var(--text-light, #192126);
}
.m-checkout-rd .plan-total {
  font-size: 16px;
  line-height: 1.2;
  color: var(--text-light, #192126);
}

/* ── Дисклеймер, гарантия и согласие (правка Игоря 05.09) ──────────────────
   Кнопка GET MY PLAN из потока убрана — она прибита снизу экрана
   (.coCtaBar). Мелкий дисклеймер, стоявший под ней, переехал прямо под
   пакеты; гарантия и галочка согласия собраны в одну карточку с обводкой в
   `--divider` и радиусом 26 — той же формы, что карточки пакетов. */
.m-checkout-rd .coFinePrint {
  margin: 16px 0 0;
  font-size: 10px;
  line-height: 1.4;
  text-align: center;
  color: var(--text-light-muted, #5E6468);
}
.m-checkout-rd .coGuard {
  margin-top: 32px;
  padding: 20px 16px 24px;
  border: 1px solid var(--rd-hairline);
  border-radius: 26px;
}
/* Заголовок обычным регистром (правка Игоря 05.09). Трекинг 0.06em снят
   вместе с капсом: он и стоял только ради него — на строчных то же значение
   читается разрядкой. */
.m-checkout-rd .coGuardTitle {
  margin: 0 0 12px;
  font-size: 16px;
  line-height: 1.55;
  text-align: center;
  color: var(--text-light, #192126);
}
.m-checkout-rd .kc-consent { margin: 0; }
.m-checkout-rd .kc-consent__label {
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-light-muted, #5E6468);
}
/* Чекбокс в стиле продукта: нативную отрисовку снимаем, обводка — волосяная в
   `--divider`, радиус 5 (та же доля от стороны, что 12 у поля ввода читалки
   высотой 40), выделенное состояние — заливка `--success` с белой галочкой из
   circle-true.svg (её контур и используется маской, чтобы цвет шёл токеном). */
.m-checkout-rd .kc-consent__box {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin: 1px 0 0;
  border-radius: 5px;
  background: #FFFFFF;
  box-shadow: inset 0 0 0 1px var(--divider, #DADDE3);
  cursor: pointer;
}
.m-checkout-rd .kc-consent__box:checked {
  background: var(--rd-accent);
  box-shadow: none;
}
.m-checkout-rd .kc-consent__box:checked::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: #FFFFFF;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M11.4517 4.21622C10.7682 5.26307 10.3624 5.68201 9.38395 6.69176L7.80742 8.24859C7.26055 8.81304 6.61892 9.41752 6.61892 9.41752C6.61892 9.41752 5.23418 7.98981 4.55157 6.94198L3.16683 8.36969C4.18244 9.07475 5.56718 10.5025 5.56718 10.5025C5.56718 10.5025 6.04369 10.8615 6.66189 11.8091C7.34547 10.7622 7.86211 10.3618 8.85917 9.33354L10.4355 7.7767C11.412 6.76793 11.8179 6.34899 12.8335 5.64393L11.4517 4.21622Z'/></svg>") center / 16px 16px no-repeat;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M11.4517 4.21622C10.7682 5.26307 10.3624 5.68201 9.38395 6.69176L7.80742 8.24859C7.26055 8.81304 6.61892 9.41752 6.61892 9.41752C6.61892 9.41752 5.23418 7.98981 4.55157 6.94198L3.16683 8.36969C4.18244 9.07475 5.56718 10.5025 5.56718 10.5025C5.56718 10.5025 6.04369 10.8615 6.66189 11.8091C7.34547 10.7622 7.86211 10.3618 8.85917 9.33354L10.4355 7.7767C11.412 6.76793 11.8179 6.34899 12.8335 5.64393L11.4517 4.21622Z'/></svg>") center / 16px 16px no-repeat;
}
.m-checkout-rd .kc-consent a { color: inherit; text-decoration: underline; }

/* ── Success stories (правка Игоря 06.09) ──────────────────────────────────
   Прежний инлайновый заголовок в SF Pro Black заменён общим правилом
   заголовков блоков; акцентом идёт первая строка. Верхнее поле секции 56 —
   как отбивка между секциями страницы. */
.m-checkout-rd .kc-stories {
  padding-top: 56px;
  text-align: center;
}

/* ── Get noticeable results (правка Игоря 06.09) ───────────────────────────
   Прежний инлайновый .header_stylish заменён общим правилом заголовков
   блоков; вторая часть — токеном --success. Спаны здесь ИНЛАЙНОВЫЕ: у
   остальных заголовков они блочные и дают перенос, а тут его быть не должно —
   строка ломается сама по ширине колонки. */
.m-checkout-rd .kc-results {
  margin: 56px 0 0;
  padding: 0;
}
.m-checkout-rd .kc-results__title .coPlanTitleLead,
.m-checkout-rd .kc-results__title .coPlanTitleAccent { display: inline; }

/* ── 100% money-back guarantee (правка Игоря 06.09) ────────────────────────
   Цвета и поля — карточки «What IntimPath can help you with»
   (.kc-wellness__card--accent). Радиус 26 взял оттуда же: у прежней плашки
   он был 10 и рядом с остальными карточками страницы читался ошибкой.
   Иконка одноцветная (один путь fill="black"), поэтому подставлена маской и
   красится токеном — тот же приём, что у иконок why-блока. */
.m-checkout-rd .kc-moneyback {
  margin: 32px 0 0;
  padding: 24px 20px;
  border: 1px solid var(--rd-tint-line);
  border-radius: 26px;
  background: var(--rd-tint);
}
.m-checkout-rd .kc-moneyback__head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 12px;
}
.m-checkout-rd .kc-moneyback__ic {
  flex: 0 0 auto;
  width: 50px;
  height: 50px;
  background-color: var(--rd-accent);
  -webkit-mask: var(--ic) center / contain no-repeat;
  mask: var(--ic) center / contain no-repeat;
}
.m-checkout-rd .kc-moneyback__title {
  margin: 0;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-light, #192126);
}
.m-checkout-rd .kc-moneyback__text {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-light, #192126);
}

/* ── Появление блоков при скролле (правка Игоря 06.09) ─────────────────────
   Элемент трогается с места, когда его верх пересекает отметку 85% высоты
   вьюпорта. Порог задаётся rootMargin наблюдателя (−15% снизу). История:
   сначала было 70%, 07.09 пробовали кромку экрана — как у Apple, где по
   замеру записи блок к выходу на 93% высоты уже набирал 0.39 прозрачности, —
   но на нашей странице это читалось плохо, и Игорь остановился на 85%.

   Про референс. Я снял apple.com/iphone: НИКАКОГО появления контента при
   скролле там сейчас нет — секции стоят статично, в таблицах стилей нет ни
   одного keyframe со сдвигом больше 8px. Что на apple.com действительно
   измеряется — фирменная кривая раскрытия меню: opacity + transform,
   0.24–0.32с, `cubic-bezier(0.4, 0, 0.6, 1)`, стагер 0.08с, но ход всего
   4–8px, и на 40px эта длительность читается рывком. Поэтому взята кривая,
   которую Игорь сам подобрал для подъёма на сопоставимое расстояние (экран
   самопроверки, CLAUDE.md § part3): 600мс `cubic-bezier(0.25, 0, 0.5, 1)` —
   несимметричная, разгон на четверти, торможение на половине.

   Класс вешает скрипт, и только тем элементам, что на первом кадре ниже
   линии: иначе верх страницы моргал бы на загрузке.

   ДЛИТЕЛЬНОСТЬ ОДНА НА ОБА СВОЙСТВА — 600мс (правка Игоря 07.09). Разводить
   их пробовали: в записи apple.com/iphone ход встаёт на место на 383-й мс, а
   прозрачность добирает до 0.99 только к 533-й (отношение 0.72), и сдвиг
   ставили на 450мс. На нашей странице это не понравилось — вернули 600.

   ДИСТАНЦИЯ 26, а не 40 (правка Игоря 07.09). Покадровый разбор записи
   apple.com/iphone (60 к/с, скролл вычтен фазовой корреляцией, прозрачность
   снята через маску глифов заголовка «Significant others.»): под этой самой
   кривой ход у них ложится в 27px при длительности 581мс — то есть кривая и
   время у нас уже совпадали, расходилось только расстояние. Держим его
   переменной: у левой колонки «Inside your program» покой не нулевой, и обе
   точки её анимации считаются от того же числа. */
/* ЭКСПЕРИМЕНТ (правка Игоря 09.09): значения перенесены с realyou.space —
   850мс на оба свойства, кривая cubic-bezier(0.32, 0.08, 0.24, 1), ход 36
   (у них translateY(3.6rem) при root font 10px) и каскад 110мс на элемент.
   Сняты из источника (website/assets/css/home.css, блок «SCROLL REVEAL —
   staggered fade-in (Apple "StaggeredFadeIn" pattern)»), а не с рендера.
   Профиль кривых: у нас было 24.5% пути к четверти времени и 549мс до 99%,
   у них 33.6% и 739мс — линейнее в начале и с длинным пологим хвостом.
   ПРЕЖНИЕ НАШИ ЗНАЧЕНИЯ, если откатывать: 600мс,
   cubic-bezier(0.25, 0, 0.5, 1), --rev-dy 26px, без transition-delay. */
.m-checkout-rd {
  --rev-dy: 36px;
}
.m-checkout-rd .coReveal {
  opacity: 0;
  transform: translateY(var(--rev-dy));
  transition:
    opacity 850ms cubic-bezier(0.32, 0.08, 0.24, 1),
    transform 850ms cubic-bezier(0.32, 0.08, 0.24, 1);
  /* --rev-i — номер элемента внутри группы, --rev-offset — сколько элементов
     уже отыграло в этой волне (ненулевой только на первом экране, чтобы он
     проявлялся одной непрерывной волной). Оба ставит checkout.js. */
  transition-delay: calc((var(--rev-i, 0) + var(--rev-offset, 0)) * 110ms);
}
.m-checkout-rd .coReveal.is-in {
  opacity: 1;
  transform: none;
}
/* У ячеек левой колонки «Inside your program» покой — не ноль, а свой сдвиг
   на 40 (см. .kc-program__grid). Поэтому и старт, и финиш у них сдвинуты на
   ту же величину: 80 → 40 вместо 40 → 0. Иначе на финише анимации колонка
   подпрыгнула бы к нулю, а после снятия классов вернулась обратно. */
.m-checkout-rd .kc-program__grid > .kc-program__item:nth-child(odd).coReveal {
  transform: translateY(calc(40px + var(--rev-dy)));
}
.m-checkout-rd .kc-program__grid > .kc-program__item:nth-child(odd).coReveal.is-in {
  transform: translateY(40px);
}
@media (prefers-reduced-motion: reduce) {
  .m-checkout-rd .coReveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ── Женская палитра (правка Игоря 07.09) ──────────────────────────────────
   Женский чекаут — тот же документ и те же правила, что мужской; отличается
   только цветами. Оба значения взяты из женской воронки /f_first
   (tailwind.css § СКИН ВОРОНОК, .coach-theme-female): канвас `--skin-bg`
   #F7F0EB и акцент `--accent-ink` #A37353 — тот самый, которым там выделен
   текст.

   Тинты карточки «What IntimPath can help you with» переведены в тёплый тон
   по тому же рецепту, что у зелёной пары: тон акцента при S и L зелёных
   (#DEF3DE — S 46.7 / L 91.2, #B0D9B0 — S 35 / L 77.1). Получилось
   #F3E6DE и #D9C1B0.

   Зелень остаётся ровно там, где просил Игорь: блок промокода и «100%
   money-back» — у них цвета прибиты значениями нод Figma и не ходят через
   `--rd-accent`. */
/* Всё на BODY по той же причине, что у мужской палитры: тинт нужен ещё и
   листу оплаты, а он сосед .kc-root, не потомок. */
body.m-checkout-female {
  --page-bg: #F7F0EB;
  --rd-accent: #A37353;
  --rd-tint: #F3E6DE;
  --rd-tint-line: #D9C1B0;
}
/* Зелёные РАСТРОВЫЕ/векторные иконки страницы: circle-true.svg (галочка
   выбранного пакета, галочка промокода, галочки списка «с IntimPath») и
   promo-tag.svg — файлы общие для продукта, и покрасить <img> токеном нечем.
   Маской не выйдет: circle-true двухцветный (зелёный круг плюс белый глиф) и
   стал бы сплошным кружком. Поэтому цвет меняется фильтром. Цепочка
   подобрана численно по спековым матрицам feColorMatrix: #28840F → #A37353
   ровно, без отклонения по каналам, а белый остаётся белым (hue-rotate и
   saturate не трогают серую ось, brightness>1 клипается). У promo-tag все три
   пути залиты тем же #28840F, так что он попадает в точку тем же фильтром.
   С 07.09 зелени на женской странице не осталось нигде, поэтому фильтр висит
   на всех трёх местах, включая блок промокода. */
.m-checkout-female .plan-mark-on,
.m-checkout-female .coPromoCheck,
.m-checkout-female .coPromoIcon,
.m-checkout-female .kc-wellness__list--green .kc-wellness__ic {
  filter: hue-rotate(-80.9deg) saturate(0.437) brightness(1.181);
}

/* Hero женской страницы: от неё осталась ТОЛЬКО пара стопов градиента (ноды
   644:2429: #EBE3DA сверху, #F7F1E9 на 70%). Геометрия полосы — высота 204,
   картинка 216×180 при отбивке 24, стрелки на 48 — с 09.09 общая для всех
   трёх страниц и живёт в блоке .m-checkout-rd выше: Игорь попросил привести
   мужскую и кегельную к женской. */
.m-checkout-female .coHeroZone {
  background: linear-gradient(180deg, #EBE3DA 0%, #F7F1E9 70%);
}

/* Черточки шкалы (правка Игоря 07.09, второй заход): три справа снова
   акцентом страницы, одна слева — серым #969FA6. Это существующий серый
   продукта (шевроны карточек Today, неактивные вкладки таббара) и он заметно
   темнее пустых черточек в `--divider` (#DADDE3), поэтому «заполненная» всё
   ещё читается заполненной. Выделенный пакет вернулся на `--rd-accent`. */
.m-checkout-female .coLine.is-now { background: #969FA6; }
.m-checkout-female .coLine.is-goal { background: var(--rd-accent); }

/* Стрелки hero — чёрный 8% вместо `--divider` (правка Игоря 07.09). Цвет
   задаётся подложкой маскированного слоя, поэтому меняется одной строкой. */
.m-checkout-female .coHeroArrow {
  background-color: rgba(0, 0, 0, 0.08);
}


/* ═══════════════════════════════════════════════════════════════════════════
   ЭКРАНЫ УСПЕХА И ОТКАЗА КАРТЫ (Figma 790:3626 и 790:3656)
   ═══════════════════════════════════════════════════════════════════════════
   По вёрстке это экран «YOU'RE GREAT!» после тренировки, только в СВЕТЛОЙ
   теме и с заголовком 36 вместо 40. Сцена (кольцо + галочка + звёзды) —
   компонент `.finScene` из app.css, БЕЗ копии: app.css подключён и на
   чекаутах (partials/app-head.ejs), поэтому и правила сцены, и токены
   --success / --error / --text-light / --btn-dark здесь уже есть. Копировать
   их сюда значило бы держать две расходящиеся версии одной анимации.
   Строитель сцены, наоборот, скопирован в checkout.js: он живёт в
   app-player.js, а плеер сюда не грузится.

   Фон приходит из --page-bg, то есть равен канвасу воронки, с которой человек
   пришёл: #F2F1F6 у мужской и кегель, #F7F0EB у женской. Токен для этого
   поднят на body (см. § --page-bg на body выше) — .kf-overlay сосед .kc-root,
   а не потомок.

   Классы новые (.kf-done*), а не правка .kf-title / .kf-subtitle: на момент
   переписывания те же правила носили карточки офферов ultimate/remarketing.
   С 10.09 эти офферы переведены на шаблон пейвола (.pwFunnel / .pwModal), и
   весь доредизайновый набор .kf-* (card, wordmark, eyebrow, title, subtitle,
   цены, features, cta, decline, modal) из файла удалён — живыми остались
   только .kf-overlay,
   .kf-modal-backdrop и сами .kf-done*.
   --------------------------------------------------------------------------- */
/* Вертикальный центр, а не координаты макета: у оверлея свои паддинги 28/48, и
   с ними центрирование само даёт макетные отступы (замер по нодам: верх сцены
   216 у успеха и 181 у отказа против 219 и 187 у нас). `margin: auto` вместо
   align-items: center — иначе высокий блок обрезался бы сверху при прокрутке. */
.m-checkout .kf-done {
  margin: auto 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  width: 100%;
  max-width: 402px;
  font-family: "Faculty Glyphic", "Helvetica Neue", Arial, sans-serif;
}
/* Ритм: сцена → 29 → заголовок → 8 → подзаголовок → 36 → кнопка → 36 →
   строка поддержки. Зазор до сцены тот же, что у .finTitle в app.css (экран
   тот же), а кегль 28 и зазор 8 под подзаголовок — правка Игоря 09.09 вместо
   нодовых 36 и 12. Капса тоже нет: заголовок набирается как в контенте
   («You're all set!»), а не `text-transform: uppercase`, как на экране
   завершения тренировки. */
.m-checkout .kf-doneTitle {
  margin: 29px 0 0;
  font-size: 28px;
  line-height: 1.3;
  font-weight: 400;
  text-transform: none;
  color: var(--text-light, #192126);
}
/* Боковые 20: на экране отказа тут стоит причина от банка — строка длинная и
   без полей шла бы от кромки до кромки. Короткому «Your plan is ready.» они
   не мешают. */
.m-checkout .kf-doneSub {
  margin: 8px 20px 0;
  font-size: 16px;
  line-height: 1.55;
  font-weight: 400;
  color: var(--text-light-muted, #5E6468);
}
/* Список купленного (решение Игоря 09.09): в макете его нет, но это
   единственное место, где виден состав покупки — списаний в цепочке до трёх.
   Набран как подзаголовок и стоит ПОД ним, поэтому свой верхний зазор у него
   тот же 12. */
.m-checkout .kf-doneList {
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
  font-size: 16px;
  line-height: 1.55;
  color: var(--text-light-muted, #5E6468);
}
.m-checkout .kf-doneItem + .kf-doneItem { margin-top: 16px; }
/* Ряд из трёх ромбов над подписью пункта (правка Игоря 09.09). Ассет тот же,
   что у буллетов читалки, и подставлен МАСКОЙ: в файле ромб залит #192126, а
   цвет тут нужен от текста списка — см. .readerBulletDot / .introHeroDot в
   app.css. Файл 6×6 с ромбом 4×4 внутри, поэтому `contain` в боксе 7 рисует
   его ровно на 7. Прозрачность 0.5 — «светлее вдвое» по правке Игоря; она на
   элементе, а не в цвете, потому что цвет наследуется от текста списка. */
.m-checkout .kf-doneDots {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-bottom: 16px;
}
.m-checkout .kf-doneDot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  opacity: 0.5;
  background-color: currentColor;
  -webkit-mask: url('/app/images/dot-romb.svg') center / contain no-repeat;
  mask: url('/app/images/dot-romb.svg') center / contain no-repeat;
}
.m-checkout .kf-doneItemTitle {
  display: block;
  color: var(--text-light, #192126);
}
.m-checkout .kf-doneItemDetail { display: block; }
/* Кнопка обжимает подпись (в ноде auto-layout с паддингом 12/28), но у неё
   задана МИНИМАЛЬНАЯ ширина 280 — отсюда 280 у короткой «Try again» и 314 у
   длинной «Open the IntimPath web app» (замер: 313.8 против нодовых 314).
   `max-width` — на случай длинной локализованной строки на узком экране. */
.m-checkout .kf-doneCta {
  margin: 36px 0 0;
  box-sizing: border-box;
  min-width: 280px;
  max-width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 12px 28px;
  border: 0;
  border-radius: 50px;
  background: var(--btn-dark, #192126);
  color: #FFFFFF;
  font-family: inherit;
  font-size: 16px;
  line-height: 1.5;
  font-weight: 400;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 160ms ease, transform 260ms ease-out;
}
.m-checkout .kf-doneCta:active {
  transform: scale(0.97);
  transition-duration: 160ms, 90ms;
}
@media (hover: hover) and (pointer: fine) {
  .m-checkout .kf-doneCta:hover { background: #2C363D; }
}
.m-checkout .kf-doneSupport {
  margin: 36px 0 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--text-light-muted, #5E6468);
}


/* ── ПОСТТРАНЗ-ОФФЕР НА ШАБЛОНЕ ПЕЙВОЛОВ (Figma 781:6606) ──────────────────
   Экран строит checkout.js классами .m-paywall из app.css (он на чекаутах
   подключён), поэтому здесь только то, чего у страницы-пейвола нет: она сама
   лежит в документе, а этот экран — слой поверх чекаута.
   Специфичность 2 класса перебивает `.viewport { position: relative }` из
   app.css, а по файлу checkout.css идёт после — иначе слой не стал бы
   фиксированным. */
.m-checkout .pwFunnel {
  position: fixed;
  inset: 0;
  z-index: 2147483600;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Колонка 480 (класс viewport-wide), а канвасом надо залить ВСЁ окно: на
     десктопе по бокам иначе просвечивал бы чекаут. Тень нулевого размытия и
     радиусом 100vmax красит именно поля вокруг колонки — без второго элемента
     и без ломки внутренней раскладки, которая рассчитана на 480. */
  box-shadow: 0 0 0 100vmax var(--pw-canvas, #112330);
  clip-path: inset(-100vmax);
}


/* ── ДАУНСЕЛЛ-МОДАЛКА НА ШАБЛОНЕ ПЕЙВОЛА (правка Игоря 10.09) ──────────────
   Содержимое строит тот же `paywallOffer()` в checkout.js, что ultimate и
   посттранз, поэтому здесь только пере-привязка: у пейвола тулбар с крестиком
   и бар кнопки прибиты к ВЬЮПОРТУ, а тело держит `min-height: 100dvh` и запас
   под фиксированный бар. В модалке это flex-колонка: тулбар absolute в её
   углу, тело со своей прокруткой, бар обычным блоком в конце — так кнопка
   видна всегда, а прокручивается только содержимое.
   Селекторы из ТРЁХ классов не случайны: правила пейвола (`.m-paywall .pwRoot`,
   `.m-paywall-legalbar .readerCtaBar`) держат два, и меньшим их не перебить. */
.m-checkout .pwModal {
  /* ВЫСОТА ПО КОНТЕНТУ, а не во весь экран (правка Игоря 12.09). Раньше стояло
     `position: absolute; inset: 20px`, то есть модалка ВСЕГДА занимала экран
     минус 20 с каждой стороны — и на высоком экране между списком выгод и
     кнопкой зияла пустота. Теперь она обычный флекс-элемент подложки
     (`align-items: center` у неё уже был), поэтому по вертикали её распирает
     собственный контент, а `max-height` включается только когда он не влез:
     тогда упирается в потолок и прокручивается тело (.pwRoot ниже).
     ВАЖНО: `position: relative` нужен не для раскладки, а как якорь —
     крестик .pwTopBar абсолютный, и без него он считался бы от экрана. */
  position: relative;
  width: 100%;
  max-width: 480px;
  max-height: 100%;
  display: flex;
  flex-direction: column;
  /* Скругление концентрично крестику: круг 44 (радиус 22) стоит с отступом 10.
     `overflow: hidden` и режет кадр сверху, и обрезает углы. */
  border-radius: 32px;
  overflow: hidden;
  box-shadow: 0 18px 48px rgba(20, 29, 25, 0.8);
}
.m-checkout .pwModal .pwTopBar {
  position: absolute;
  top: 10px;
  right: 10px;
  left: auto;
  transform: none;
  width: auto;
  max-width: none;
  padding: 0;
  z-index: 2;
}
.m-checkout .pwModal .pwRoot {
  min-height: 0;
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Чтобы, докрутив содержимое, палец не начинал листать страницу чекаута под
     затемнением. */
  overscroll-behavior: contain;
  /* Запас под фиксированный бар не нужен: бар лежит в потоке колонки. */
  padding-bottom: 0;
}
.m-checkout .pwModal .readerCtaBar {
  /* `relative`, а НЕ `static`: бару довольно выйти из `fixed`, но хвост
     растворения — это его `::before` с `bottom: 100%`, и абсолютный
     псевдоэлемент считается от ближайшего ПОЗИЦИОНИРОВАННОГО предка. У
     статичного бара им становилась сама `.pwModal` (`absolute`), и хвост
     уезжал на 34px выше её верхней кромки, где его срезал `overflow: hidden` —
     то есть градиента не было вовсе (замер: `bottom` 834px при высоте модалки
     834). С `relative` он встаёт ровно над баром, как на пейволе. */
  position: relative;
  /* ...и обязательно `inset: auto`: у пейвольного бара стоят `bottom: 0` и
     `left: 50%`, и при `static` они инертны, а при `relative` начинают
     СМЕЩАТЬ бокс — кнопка с припиской уезжала на полширины вправо и вверх,
     поверх списка (поймано кадром). */
  inset: auto;
  transform: none;
  width: auto;
  max-width: none;
  flex: 0 0 auto;
  /* safe-area внутри модалки не нужна — её нижняя кромка и так в 20 от края.
     Нижние 12 — правка Игоря 12.09 (10.09 было 20, до того 8). */
  padding: 0 24px 12px;
}

/* Своя вертикаль модалки (правки Игоря 10.09). ВАЖНО: значения касаются ТОЛЬКО
   даунселла — четыре страницы `/unlock/*`, экран ultimate и посттранз остаются
   на общих числах блока `.m-paywall` в app.css. Отсюда и селекторы из ТРЁХ
   классов: правила общего блока держат два, и меньшим их не перебить. */
.m-checkout .pwModal .pwHead {
  /* Шапка опущена на 22 (было −126): в 362-й модалке кадр масштабируется до
     207, а не 230 как в 402-й колонке, и при прежнем подъёме над
     надзаголовком оставалось 9.1px. Замер после правки — 31.1.
     Боковые 24 (правка Игоря 11.09; было 32), подъём −96 (правка 12.09;
     было −104). */
  margin: -96px 24px 0;
}
.m-checkout .pwModal .pwBadge { margin: 36px auto 0; }
/* Зазор между галочкой и текстом пункта — только в модалке (правка Игоря
   11.09). На страницах и в остальной воронке у .pwItem свой нодовый gap. */
.m-checkout .pwModal .pwItem { gap: 16px; }
/* Обводки и радиуса у карточки пунктов в модалке НЕТ: блок стоит на её канвасе
   без рамки, поэтому боковые 32 совпадают с боковыми шапки и пункты идут по
   одной вертикали с заголовком и ценой. Плашки `.pwCardLabel` у бандла нет
   (карточка `pwCardBare`), так что разрезать обводку тут нечему. */
.m-checkout .pwModal .pwCard {
  /* Правка Игоря 11.09: было `40px 32px 24px` + верхние 40 под пилюлю. Пилюли
     у даунселла больше нет, поэтому полей нет вовсе, а боковые задаёт margin.
     С 12.09 боковые 24 (было 30) — пункты встали на одну вертикаль с шапкой,
     а нижний отступ сравнялся с верхним (36; был 24). */
  margin: 36px 24px;
  border: 0;
  border-radius: 0;
  padding: 0;
}
/* Карточка без пилюли — то же самое; правило оставлено на случай, если пилюля
   когда-нибудь вернётся и общему `.pwCard` понадобится верхний запас. */
.m-checkout .pwModal .pwCardBare { padding: 0; }
/* Зазор кнопка→приписка 12 (на страницах 10). С 10.09 модалка тоже на варианте
   A, то есть окно ФИКСИРОВАННОЙ высоты, а зазор из-за глобального border-box
   входит в неё — значит слагаемое в формуле обязано повторять этот зазор,
   иначе видно 2.87 строки вместо трёх (замер: содержимое 45.85 против 47.85 =
   3 × 15.95). Держать парой, как и на страницах. */
.m-checkout .pwModal .pwLegalScroll {
  padding-top: 12px;
  height: calc(11px * 1.45 * 3 + 12px);
}
