/* ============================================================
   Ligand Pro — landing, first screen
   ============================================================ */

/* ---------- tokens ---------- */
:root {
  --bg-dark: #111111;
  --white: #FEFEFE;
  --accent: #7C5CFC;
  --accent-hover: #9179FD;
  --text-dim: rgba(255, 255, 255, .7);
  --border-dim: rgba(255, 255, 255, .35);

  /* проба: весь сайт на Arial. Вернуть Onest — заменить строку обратно на
     'Onest', sans-serif; шрифт по-прежнему подключён в index.html/privacy.html */
  --font-heading: Arial, Helvetica, sans-serif;
  --font-body: Arial, Helvetica, sans-serif;
  /* проба: заголовки h1–h3 — Onest; остальное, что было на --font-heading, остаётся Arial */
  --font-title: 'Onest', Arial, sans-serif;

  --container-pad: 40px;
  /* Page margin of the header, the hero and the sections laid out on the
     40px line. Up to a 1920px window it is those 40px; wider, it grows so the
     content stays a 1840px column in the middle while the backgrounds still
     run edge to edge. Narrow screens set their own paddings further down. */
  --page-max: 1840px;
  --page-gutter: max(40px, calc((100vw - var(--page-max)) / 2));
  /* Вертикальный ритм основных секций: одно расстояние от верхней границы
     секции до её содержимого и от содержимого до нижней границы. Эталон —
     отступ над «Весь путь от мишени до кандидата» (.reveal-intro).
     Переопределяется только в двух медиазапросах ниже по файлу. */
  --section-padding-y: 120px;

  /* 24px top pad + 48px row + 24px bottom pad */
  --header-h: 96px;
}

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

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

/* Lenis (smooth wheel): what it asks of the page */
html.lenis,
html.lenis body { height: auto; }

.lenis.lenis-smooth { scroll-behavior: auto !important; }

.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }

.lenis.lenis-stopped { overflow: hidden; }

body {
  margin: 0;
  background: var(--bg-dark);
  color: var(--white);
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.5;
  /* лёгкое сжатие для всего текста, у которого нет своего трекинга: у Arial
     буквы шире Onest, и на длинных строках набор шёл разреженнее прежнего.
     Заголовки задают трекинг сами и это значение перекрывают. */
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  font-weight: 500;
  margin: 0;
}

h1, h2, h3 { font-family: var(--font-title); letter-spacing: -0.02em; }

button {
  font: inherit;
  /* в шорткат font трекинг не входит, а браузер ставит формам letter-spacing:
     normal — без этой строки кнопки (вопросы FAQ в том числе) не подхватывали
     бы общее сжатие с body */
  letter-spacing: inherit;
  color: inherit;
  margin: 0;
  background: none;
  border: 0;
  padding: 0;
}

/* та же история, что у button: формам браузер ставит свой letter-spacing */
input, textarea, select { letter-spacing: inherit; }

a { text-decoration: none; color: inherit; }

svg { display: block; }

:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 2px;
}

/* ---------- container ---------- */
.container {
  width: 100%;
  padding: 0 var(--container-pad);
}

/* ============================================================
   HERO
   ============================================================ */
/* deliberately not .hero: the old hero's rules are still in this file */
.hero-screen {
  /* pinned: later sections scroll up over it. No ancestor (html, body) may
     have overflow hidden/auto, or sticky stops working. */
  position: sticky;
  top: 0;
  z-index: 0;
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100svh;
  padding: 40px;
  overflow: hidden;
  background: #0A0A0A;
  color: var(--white);
}

/* background scene (Three.js draws a canvas in here) */
.hero-visual {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.hero-visual canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* ---------- top bar ---------- */
.hero-top {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.hero-logo {
  display: block;
  height: 56px;
  width: auto;
}

.hero-tools {
  display: flex;
  align-items: center;
  gap: 24px;
}

.hero-lang {
  display: flex;
  align-items: center;
  gap: 4px;
}

.hero-lang-btn {
  padding: 3px 7px;
  border-radius: 4px;
  font-family: var(--font-body);
  font-size: 13px;
  color: rgba(254, 254, 254, .5);
  cursor: pointer;
  transition: color .2s ease, background-color .2s ease;
}

.hero-lang-btn:hover { color: var(--white); }

.hero-lang-btn.is-active {
  background: var(--accent);
  color: #0A0A0A;
}

.hero-menu-label {
  font-family: var(--font-body);
  font-size: 13px;
  color: rgba(254, 254, 254, .7);
}

.hero-burger {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  width: 48px;
  height: 48px;
  border: 1px solid rgba(254, 254, 254, .2);
  border-radius: 14px;
  cursor: pointer;
  transition: border-color .2s ease;
}

.hero-burger:hover { border-color: rgba(254, 254, 254, .4); }

.hero-burger-line {
  width: 18px;
  height: 2px;
  border-radius: 1px;
  background: var(--accent);
}

.hero-burger-line--short { width: 12px; }

.hero-lang-btn:focus-visible,
.hero-burger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- lede, roughly mid-height on the right ---------- */
.hero-lede {
  position: relative;
  z-index: 1;
  margin: auto 0 0 auto;
  max-width: 620px;
  font-family: var(--font-heading);
  font-size: 26px;
  font-weight: 400;
  line-height: 30px;
  text-align: right;
  color: var(--white);
}

.hero-dim { color: rgba(254, 254, 254, .4); }

/* ---------- headline, pinned to the bottom ---------- */
.hero-title {
  position: relative;
  z-index: 1;
  margin: auto 0 0;
  font-family: var(--font-heading);
  font-size: 72px;
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--white);
}

/* ---------- scroll hint ---------- */
.hero-scroll {
  position: absolute;
  right: 40px;
  bottom: 40px;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 12px;
}

.hero-scroll-text {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  letter-spacing: .15em;
  color: var(--white);
}

.hero-scroll-arrow {
  color: var(--accent);
  animation: hero-nudge 2s ease-in-out infinite;
}

@keyframes hero-nudge {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(5px); }
}

/* ============================================================
   HERO (cover) — a Mol* scene behind, nav in a pill, headline bottom
   left, lede and buttons bottom right. It is also a .hero-screen, which
   keeps it pinned under the later sections.
   ============================================================ */
.cover {
  padding: 24px var(--page-gutter) 56px;
  background: #07030A;
}

/* ---------- the Mol* scene (desktop): 7RPZ, noise settling into MRTX1133.
   It fades in once its first frame is drawn; where it does not run (phones)
   or cannot, the hero keeps its plain dark ground. ---------- */
.cover-scene {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  pointer-events: none;      /* Mol* never sees the pointer, so its wheel zoom cannot take the page */
  transition: opacity .8s ease;
}

.cover-scene.is-ready { opacity: 1; }


/* color-scheme as the page inside (dark): with two different ones the browser lays
   an opaque ground under the frame, and the pattern under the scene would not show */
.cover-scene #cover-diffusion{display:block;width:100%;height:100%;border:0;background:transparent;pointer-events:none;color-scheme:dark}

/* The scene's first frame as a picture (media/hero-poster-*.webp, shot from the
   scene itself), there from the first paint so the screen is never empty while
   the scene loads; once the live scene is drawn (.cover-scene.is-ready) the
   picture fades out as the scene fades in. As high as the screen and set where
   the scene centres its view: at 64% of the width for the diffusion scene (its
   canvas runs past the right edge), in the middle for the journey one. Only
   where the scenes frame themselves by the height (landscape, wider than 700px):
   elsewhere it would not line up, and the screen waits for the scene. */
.cover-poster { display: none; }

@media (min-width: 701px) and (min-aspect-ratio: 1/1) {
  .cover-poster {
    display: block;
    position: absolute;
    top: 0;
    left: 64%;
    z-index: 0;
    width: auto;
    max-width: none;
    height: 100%;
    transform: translateX(-64%);
    pointer-events: none;
    transition: opacity .8s ease;
  }

  .cover--journey .cover-poster { left: 50%; transform: translateX(-50%); }

  .cover-scene.is-ready + .cover-poster { opacity: 0; }

  /* the shade over the words as soon as there is a picture under them */
  .cover-poster ~ .cover-shade { opacity: 1; }
}

.cover-canvas {
  position: absolute;
  inset: 0;
}

.cover-canvas .msp-viewport-controls,
.cover-canvas .msp-viewport-top-left-controls,
.cover-canvas .msp-viewport-top-right-controls,
.cover-canvas .msp-viewport-controls-buttons,
.cover-canvas .msp-highlight-toast-wrapper,
.cover-canvas .msp-toast-container,
.cover-canvas .msp-logo,
.cover-canvas .msp-layout-region:not(.msp-layout-main) { display: none !important; }

/* all of it clear, so the brand pattern under the scene shows through: with
   a transparent background Mol* paints its viewport light and sets a
   checkerboard inline on the canvas, hence !important */
.cover-canvas .msp-plugin,
.cover-canvas .msp-plugin-content,
.cover-canvas .msp-layout-main,
.cover-canvas .msp-viewport,
.cover-canvas canvas { background: transparent !important; }

/* Mol*'s layout draws a 1px frame around the viewport; the scene has none */
.cover-canvas .msp-plugin,
.cover-canvas .msp-plugin * { border: 0 !important; box-shadow: none !important; }

/* the big brand pattern (pattern.svg, as composed for the request form:
   media/cta-pattern.svg) over the whole ground, under everything else of
   the hero, its chains as large as at the form. Its edges are ragged, so it
   is drawn half again as wide as the screen (or as tall, whichever is more)
   and centred on its solid middle: the ragged edges stay off the screen.
   The fine pattern before it (media/hero-pattern-tile.webp, from
   pattern 1.svg) is still what the switched-off pointer script draws. */
.cover-pattern {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: url('../images/cta-pattern.svg') 50% 45% / max(150vw, 150vh) auto no-repeat;
  /* very pale: it barely stands off the hero's own ground; the same on both
     first screens, and it shows through their 3D scenes */
  opacity: .15;
  pointer-events: none;
}

/* where the pattern catches on the pointer, the script draws it in WebGL
   from the same tile; the still background then steps aside */
.cover-pattern.is-drawn { background: none; }

.cover-pattern canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* shade over the scene, so the words stay legible: along the bottom, where
   the headline and the side are, and a little under the top bar */
.cover-shade {
  position: absolute;
  inset: 0;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  background:
    linear-gradient(to top, rgba(7, 3, 10, .94) 0%, rgba(7, 3, 10, .6) 24%, rgba(7, 3, 10, 0) 50%),
    linear-gradient(to bottom, rgba(7, 3, 10, .7) 0%, rgba(7, 3, 10, 0) 16%);
  transition: opacity .8s ease;
}

.cover.has-scene .cover-shade { opacity: 1; }

/* the layer that turns the molecule when dragged: over the scene, under the
   words and buttons; the page keeps its vertical swipe on touch */
.cover-grab {
  position: absolute;
  inset: 0;
  z-index: 0;
  cursor: grab;
  touch-action: pan-y;
  pointer-events: none;
}

.cover.has-scene .cover-grab { pointer-events: auto; }

.cover-grab.is-dragging { cursor: grabbing; }

/* ---------- top bar ---------- */
.cover-top {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
}

.cover-logo {
  display: block;
  height: 42px;
  width: auto;
}

.cover-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* as tall as the button beside it (.cover-top .cover-btn); no ground of its
   own, the links sit straight on the hero */
.cover-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 36px;
  padding: 0 4px;
}

/* Навигация и кнопки — Arial (--font-body), а не Onest заголовков.
   Правило общее: и пункты обеих шапок, и все четыре кнопки. */
.cover-nav-link,
.cover-btn {
  font-family: var(--font-body);
  font-weight: 500;
}

.cover-nav-link {
  position: relative;   /* якорь для линии ховера */
  padding: 6px 14px;
  border-radius: 5px;   /* ничего не заливает, но по нему скругляется фокусная рамка */
  font-size: 13px;
  color: #FEFEFE;
  transition: color .2s ease;
}

/* Ховер: слово остаётся своего цвета, под ним прочерчивается линия — слева
   направо. Линия лежит по ширине самого слова, поэтому отступает на боковые
   поля пункта; цвет берётся из currentColor, и в плавающей шапке она едет
   за --float-ink вместе с текстом. Растёт через scaleX, а не через width:
   так анимация идёт на композиторе и не пересчитывает раскладку.
   Уходит тоже вправо: без ховера линия сжимается к правому краю, а на
   ховере точка отсчёта переезжает влево — так она и входит, и выходит
   слева направо. */
.cover-nav-link::after {
  content: '';
  position: absolute;
  right: 14px;
  bottom: 2px;
  left: 14px;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform .25s ease;
}

.cover-nav-link:hover::after,
.cover-nav-link:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.cover-btn {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  height: 44px;
  padding: 0 22px;
  border-radius: 8px;
  font-size: 13px;
  white-space: nowrap;
  /* у Arial нет начертания 500 — браузер рисует 400; тонкая обводка
     цветом текста делает буквы чуть плотнее, не доходя до 700 */
  -webkit-text-stroke: .15px currentColor;
  transition: background-color .2s ease;
}

/* the one in the top bar is smaller */
.cover-top .cover-btn {
  height: 36px;
  padding: 0 16px;
  font-size: 12px;
}

/* на узких экранах шапку нажимают пальцем, а не курсором */
@media (max-width: 900px) {
  .cover-top .cover-btn {
    height: 44px;
    padding: 0 20px;
  }
}

.cover-btn--accent { background: #9B7DDD; color: #FEFEFE; }
.cover-btn--accent:hover { background: #AB91E3; }

/* no fill, a light grey outline (inset, so the button keeps its size) */
.cover-btn--dark {
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(254, 254, 254, .4);
  color: #FEFEFE;
  transition: background-color .2s ease, box-shadow .2s ease;
}
.cover-btn--dark:hover {
  background: rgba(254, 254, 254, .08);
  box-shadow: inset 0 0 0 1px rgba(254, 254, 254, .6);
}

.cover-nav-link:focus-visible,
.cover-btn:focus-visible {
  outline: 2px solid #FEFEFE;
  outline-offset: 2px;
}

/* ---------- floating header: the top bar again, fixed ----------
   Built like the document pages' bar (.doc-head) -- a ground of its own and a
   hairline under it -- but it wears the colour of the section it is over: the
   script reads the ground under it every frame of scroll and sets the ground
   here, adding is-on-light where that ground is light enough for dark words.
   The purple mark of the logo and the accent button stay as they are, and the
   hairline follows the ink, so it shows on either. The dark set below is what
   it wears until the script first paints it. Up and hidden over the first
   screen, which has a top bar of its own; once that screen is scrolled past
   the script brings it down, and it stays down. */
.float-top {
  --float-ink: 254, 254, 254;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  /* Высоту полосы держит логотип: 10 + 38 (--brand-height в brand-motion.css)
     + 10 + 1px границы = 59px. Ниже 900px её держит уже не он, а кнопка в
     44px — её высота нужна для нажатия пальцем. */
  padding: 10px var(--page-gutter);
  background: var(--bg-dark);
  border-bottom: 1px solid rgba(var(--float-ink), .12);
  color: rgb(var(--float-ink));
  transform: translateY(-100%);
  visibility: hidden;
  transition: transform .35s cubic-bezier(.2, .7, .2, 1), visibility 0s linear .35s,
              background-color .2s ease, color .3s ease;
}

/* a light ground under it: the words go to the page's near-black */
.float-top.is-on-light { --float-ink: 17, 17, 17; }

/* над фирменным сиреневым (сторона с формой, на узких экранах она во всю
   ширину): сиреневый знак логотипа и сиреневая кнопка в нём тонут, поэтому
   знак берёт цвет текста, а кнопка — тёмная, как «Отправить заявку» */
.float-top.is-on-brand .float-top__logo path[fill="#B69DF3"] { fill: currentColor; }
.float-top.is-on-brand .cover-btn--accent { background: #111111; color: #FEFEFE; }
.float-top.is-on-brand .cover-btn--accent:hover { background: #2A2A2A; }

.float-top.is-shown {
  transform: none;
  visibility: visible;
  transition: transform .35s cubic-bezier(.2, .7, .2, 1),
              background-color .2s ease, color .3s ease;
}

.float-top__home { display: block; color: inherit; }

.float-top__home:focus-visible { outline: 2px solid rgb(var(--float-ink)); outline-offset: 4px; }

.float-top__logo {
  display: block;
  width: auto;
  height: 36px;   /* as .doc-head__logo: the two bars read as one */
  aspect-ratio: 256 / 66;
}

.float-top .cover-nav {
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.float-top .cover-nav-link {
  color: rgb(var(--float-ink));
  transition: color .3s ease;
}

.float-top .cover-nav-link:focus-visible { outline-color: rgb(var(--float-ink)); }

@media (max-width: 640px) {
  .float-top { padding: 8px 20px; }

  .float-top__logo { height: 28px; }
}

/* ---------- to the form: a small button at the bottom right ----------
   The brand violet of the hero's buttons. Hidden (and out of the tab order)
   until the script shows it; it rises in and sinks out. */
.to-form {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 19;
  /* the arrow alone, in a square */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 14px;
  background: #B69DF4;
  box-shadow: 0 8px 24px rgba(17, 17, 17, .18);
  font-family: var(--font-heading);
  font-size: 14px;
  font-weight: 500;
  color: #111111;
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px);
  transition: opacity .25s ease, transform .25s ease, visibility 0s linear .25s, background-color .2s ease;
}

.to-form.is-shown {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .25s ease, transform .25s ease, background-color .2s ease;
}

.to-form:hover { background: #C7B4F7; }

.to-form:focus-visible { outline: 2px solid #111111; outline-offset: 2px; }

.to-form__arrow { flex: none; }

@media (max-width: 640px) {
  .to-form {
    right: 16px;
    bottom: 16px;
    width: 40px;
    height: 40px;
  }
}

/* ---------- bottom: headline left, lede and buttons right ----------
   A 12-column grid inside the hero's 40px padding, the same edges as the top
   bar: the headline on columns 1-7, the side from column 8 to the edge, so its
   right edge meets the "Оставить заявку" button above. */
.cover-bottom {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: 24px;
  row-gap: 32px;
  align-items: end;
  margin-top: auto;
}

.cover-title {
  margin: 0;
  font-family: var(--font-title);
  font-size: clamp(48px, 6vw, 104px);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -0.06em;
  color: #FEFEFE;
}

/* two lines, broken where the markup says */
.cover-lede {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 18px;
  line-height: 1.5;
  white-space: nowrap;
  color: #FEFEFE;
}

/* side by side, never one under the other: the buttons do not shrink or wrap */
.cover-buttons {
  display: flex;
  flex-wrap: nowrap;
  gap: 12px;
  margin-top: 32px;
}

.cover-title { grid-column: 1 / 8; }

/* the side's width is the query for its lede below */
.cover-side {
  grid-column: 8 / 13;
  container: cover-side / inline-size;
}

/* Side by side, the headline's box ends 0.19em below its baseline (the room
   under the letters): pulled down by as much, the baseline of its last line
   sits on the bottom of the buttons. */
@media (min-width: 1200px) {
  .cover-title { margin-bottom: -0.19em; }

  /* Правый блок прижат к правой направляющей контейнера — туда же, где
     заканчивается «Оставить заявку» в верхней панели. Сама колонка своей
     ширины не меняет (иначе поедут контейнерные запросы лида): в ней один
     трек шириной по самой длинной строке, трек прижат вправо
     (justify-content), а лид и кнопки внутри него остаются по левому краю
     (justify-items). */
  .cover-side {
    display: grid;
    justify-content: end;
    justify-items: start;
  }
}

/* The lede's longer line is about 504px (RU) and 547px (EN) at 18px.
   Narrower than that the lede goes down to 16px (as on phones), where the
   line is about 448px (RU) and 486px (EN) and the two lines still hold;
   narrower still, it wraps as it likes. */
@container cover-side (max-width: 509px) {
  .cover-lede { font-size: 16px; }
}

@container cover-side (max-width: 552px) {
  :lang(en) .cover-lede { font-size: 16px; }
}

@container cover-side (max-width: 453px) {
  .cover-lede { white-space: normal; }

  .cover-lede br { display: none; }
}

@container cover-side (max-width: 491px) {
  :lang(en) .cover-lede { white-space: normal; }

  :lang(en) .cover-lede br { display: none; }
}

/* stacked: the side under the headline, below the width where its lede
   still holds to two lines beside it */
@media (max-width: 1199px) {
  .cover-bottom { row-gap: 16px; }

  .cover-title,
  .cover-side { grid-column: 1 / -1; }
}

@media (min-width: 1341px) {
  /* The headline as large as its column lets its longer line ("в единой
     системе", 7.9 times its size across) stay whole: the column is the
     screen less the padding (80px), the gap (64px), the side and 16px for a
     scrollbar; divided by 8 to leave a little room. */
  .cover-title {
    font-size: clamp(48px, min(6vw, (100vw - 160px - var(--cover-actions-w, 663px)) / 8), 104px);
  }
}

/* the two lines as set, never broken further; phones may wrap them */
@media (min-width: 641px) {
  .cover-title { white-space: nowrap; }
}

/* below this the nav pill no longer fits beside the logo and the button */
@media (max-width: 1040px) {
  .cover-nav { display: none; }
}

/* Every section after the pinned hero scrolls over it, so each one needs a
   layer above it. Their opaque backgrounds are set in their own blocks. */
.hero-screen ~ section,
.footer {
  position: relative;
  z-index: 1;
}

/* ============================================================
   TOOLS — second section
   ============================================================ */
/* the heading and text above the video, as an ordinary block in the flow */
.reveal-intro {
  padding: var(--section-padding-y) var(--container-pad);
  background: var(--white);
  text-align: center;
}

.reveal-intro__title {
  margin: 0;
  font-family: var(--font-title);
  font-size: clamp(22px, 3.6vw, 60px);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.05em;
  color: #111111;
}

/* the steps of the path as tags, the same chips as over each tool below,
   in dark ink on the white section */

.reveal-intro__text {
  max-width: 720px;
  margin: 32px auto 0;
  font-family: var(--font-body);
  font-size: 20px;
  line-height: 1.5;
  color: #6B6B6B;
}

/* Apple-style entrance, once (the script "INTRO + VIDEO: come up into place"):
   the script sets the starting state (appear), then is-up; when it is over
   both go and nothing stays set. translate and scale, never transform: the
   video block's own script moves the card with transform. */
.appear {
  opacity: 0;
  translate: 0 var(--appear-rise, 40px);
  scale: var(--appear-scale, 1);
  transition:
    opacity 1s cubic-bezier(.25, .1, .25, 1) var(--appear-delay, 0s),
    translate 1.3s cubic-bezier(.16, 1, .3, 1) var(--appear-delay, 0s),
    scale 1.3s cubic-bezier(.16, 1, .3, 1) var(--appear-delay, 0s);
}

.appear.is-up {
  opacity: 1;
  translate: 0 0;
  scale: 1;
}

.reveal {
  position: relative;
  /* Одно значение на оба зазора вокруг начала тёмной части: от верха тёмной
     части до фразы (reveal.js берёт отсюда pinTop) и — в простом режиме —
     от нижнего края видео до тёмной части. Меняется только здесь. */
  --reveal-pin-top: 128px;
  /* Шаг вертикали внутри тёмной части: фраза — подпись — ноутбук — заметки.
     reveal.js добавляет к нему воздух вокруг букв, чтобы все три промежутка
     читались одинаковыми. Меняется только здесь. */
  --reveal-gap: 40px;
  /* without the script; the script sets the height in px to fit every stage */
  height: 420vh;
  /* pulled up over the empty bottom of the intro above, so the video sits
     close under its text (--reveal-pull, set by the script; none without it) */
  margin-top: calc(-1 * var(--reveal-pull, 0px));
  /* its last stretch eases into the light grey of the next section, so the
     white cards there stand out from the first pixel; the pulled-up top is
     clear, so the intro's text shows through it */
  background: linear-gradient(to bottom, transparent var(--reveal-pull, 0px), var(--white) var(--reveal-pull, 0px), var(--white) calc(100% - 280px), #F7F7F8 100%);
}

/* The brand pattern lit up around the pointer on the dark stage: the tile's
   bead outlines (a transparent cut of pattern 1.svg, outlined, at twice the
   SVG's size) as a mask over the brand violet, meeting a soft round window that the script
   moves after the pointer (--glow-x, --glow-y). It shows only while the
   pointer is on the page (is-on) and only as far as the stage has turned
   dark (--reveal-dark, set by the section's script). */
.reveal__glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: #B69DF4;
  opacity: 0;
  pointer-events: none;
  -webkit-mask-image:
    url('../images/pattern-outline-tile.webp'),
    radial-gradient(circle 320px at var(--glow-x, 50%) var(--glow-y, 50%), #000 0%, rgba(0, 0, 0, .45) 40%, transparent 100%);
  mask-image:
    url('../images/pattern-outline-tile.webp'),
    radial-gradient(circle 320px at var(--glow-x, 50%) var(--glow-y, 50%), #000 0%, rgba(0, 0, 0, .45) 40%, transparent 100%);
  -webkit-mask-size: 103px 110.5px, 100% 100%;
  mask-size: 103px 110.5px, 100% 100%;
  -webkit-mask-repeat: repeat, no-repeat;
  mask-repeat: repeat, no-repeat;
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  transition: opacity .4s ease;
}

.reveal__glow.is-on { opacity: calc(var(--reveal-dark, 0) * .9); }

.reveal__sticky {
  /* overflow lives on the sticky element itself, never on an ancestor */
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  overflow: hidden;
}

.video-card {
  /* starting width, as a share of the largest 16:9 box the screen holds; the
     height follows from the video, so the frame is never cropped */
  --card-w: 80;
  /* JS drives this so the inner radius can stay 8px tighter throughout */
  --card-radius: 20px;

  position: relative;
  width: min(calc(var(--card-w) * 1vw), var(--page-max));
  padding: 5px;
  background: #111111;
  border-radius: var(--card-radius);
  overflow: hidden;
}

/* the video, inset by the card's padding so a black frame shows; always the
   whole frame, never cropped or stretched, as the card grows and closes */
.video-card__media {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: contain;         /* the whole frame, never cropped */
  background: #111111;
  border-radius: calc(var(--card-radius) - 3px);
}

/* while the scroll script sizes the card, the video fills it; once the card
   grows past 16:9 the thin letterbox bars blend into the black frame */
.video-card.is-sized .video-card__media {
  height: 100%;
  aspect-ratio: auto;
}

/* Laid out in its final place: one centred line with an ordinary space. The
   script shifts the halves out to the sides and brings them back with transform. */
.reveal__phrase {
  position: absolute;
  top: 50%;
  left: var(--container-pad);
  right: var(--container-pad);
  z-index: 1;
  margin: 0;
  font-family: var(--font-title);
  /* one line, as wide as the screen allows: the sentence runs about 29
     times its size across */
  font-size: clamp(22px, min(3.6vw, (100vw - 2 * var(--container-pad)) / 29), 60px);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.05em;
  color: #111111;
  text-align: center;
  white-space: nowrap;
  transform: translateY(-50%);
  pointer-events: none;
}

.reveal__half {
  display: inline-block;
  will-change: transform;
}

/* fades in under the sentence; the script moves it and the sentence together */
.reveal__text {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1;
  width: min(720px, calc(100% - 2 * var(--container-pad)));
  margin: 0;
  font-family: var(--font-body);
  font-size: 20px;
  line-height: 1.5;
  color: #6B6B6B;
  text-align: center;
  opacity: 0;
  transform: translate(-50%, 0);
  pointer-events: none;
}

/* The laptop under the text, drawn in CSS: a lid with a thin bezel and a
   camera, a screen in the platform screenshots' proportions with rounded
   corners, and the base with its thumb groove. Every size is in cqw of its
   own width, so the script sizes it by width alone. */
/* Ноутбук внутри блока заметок: свой у каждого блока, только на телефоне */
.reveal__mac--flow { display: none; }

.reveal__mac {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: min(1040px, 80vw);
  container-type: inline-size;
  opacity: 0;
  pointer-events: none;
}

.mac__lid {
  position: relative;
  width: 84cqw;
  margin: 0 auto;
  padding: 1.1cqw;
  background: #050506;
  border-radius: 2.8cqw 2.8cqw 0 0;
  /* space black: the graphite shell round the glass, lit along its edge */
  box-shadow:
    inset 0 0 0 0.12cqw #141416,
    0 0 0 0.45cqw #232326,
    0 0 0 0.55cqw #3E3E42,
    0 0 0 0.62cqw #19191B;
}

/* the camera, centred in the top bezel */
.mac__lid::before {
  content: '';
  position: absolute;
  top: 0.32cqw;
  left: 50%;
  width: 0.46cqw;
  height: 0.46cqw;
  border-radius: 50%;
  background: #1E1E22;
  transform: translateX(-50%);
}

.mac__screen {
  position: relative;
  /* the platform screenshots' own proportions, so they fill the glass */
  aspect-ratio: 1.62;
  overflow: hidden;
  background: #000000;
  /* the platform window's rounded corners */
  border-radius: 1.1cqw;
}

.mac__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000000;
}

.mac__base {
  position: relative;
  height: 2.8cqw;
  /* space black graphite, a light line along its top edge */
  background: linear-gradient(to bottom, #6A6A70 0, #414147 5%, #37373C 28%, #2C2C31 60%, #1E1E21 86%, #111113 100%);
  border-radius: 0 0 1.6cqw 1.6cqw / 0 0 1.2cqw 1.2cqw;
  box-shadow: 0 2.2cqw 3cqw -1.6cqw rgba(0, 0, 0, .6);
}

/* the thumb groove where the lid opens */
.mac__base::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 14cqw;
  height: 0.9cqw;
  background: linear-gradient(to bottom, #1A1A1D, #37373C);
  border-radius: 0 0 0.9cqw 0.9cqw;
  box-shadow: inset 0 -0.08cqw 0 #46464B;
  transform: translateX(-50%);
}

/* the first block's screen, under the others: a screenshot of the
   platform filling the glass (the glass has the screenshots' proportions, so
   cover trims at most a hairline instead of leaving black bands) */
.mac__shot {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000000;
}

/* the screen for each next block, over the first, faded in by the script:
   filling the glass as well, opaque so it hides the one beneath */
.mac__layer {
  position: absolute;
  inset: 0;
  background: #000000;
  opacity: 0;
}

.mac__layer img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* the MAKI recording (1600x1008) is a touch taller than the glass: trim more
   of it at the bottom than at the top, so its top bar lands on the same line
   as the header of the Ligand Pro screens before and after it */
.mac__layer[data-block="2"] > video.mac__shot {
  object-position: 50% 20.6%;
}

/* the third block's screens: ADMET and Design Lab as short screen recordings,
   Kinome as a still; the switch under its notes shows one at a time */
.mac__views {
  width: 100%;
  height: 100%;
}

.mac__views > * {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: #000000;
}

.mac__views > [hidden] { display: none; }

/* The notes to the right of the laptop (under it on narrower screens). The
   blocks lie in the same place and take turns; the script places them and
   fades each next one in. Their ink (r, g, b) follows the ground: light on the
   dark, dark once it has turned white. */
.reveal__notes {
  --note-ink: 254, 254, 254;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  overflow: hidden;
  color: rgb(var(--note-ink));
  pointer-events: none;
}

.reveal__note {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  opacity: 0;
  will-change: opacity, transform;
}

.reveal__note .reveal__about {
  margin-bottom: 32px;
  color: rgba(var(--note-ink), .7);
}

.reveal__note .reveal__item { border-bottom-color: rgba(var(--note-ink), .14); }

/* each tool's models, as small tags above its name, in the notes' ink */
.reveal__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 20px;
}

.reveal__chip {
  padding: 6px 10px;
  border-radius: 6px;
  background: rgba(var(--note-ink), .1);
  font-family: var(--font-heading);   /* the site's Onest, as the nav and the buttons */
  font-weight: 500;
  font-size: 13px;
  line-height: 1.2;
  color: rgb(var(--note-ink));
}

.reveal__note .reveal__num {
  background: rgba(var(--note-ink), .1);
  color: rgb(var(--note-ink));
}

/* thin rule under the text; the placeholder slides out from under it, so it
   sits above the row. The script places it and draws it in with scaleX. */
.reveal__rule {
  position: absolute;
  top: 50%;
  left: var(--container-pad);
  right: var(--container-pad);
  z-index: 2;
  height: 1px;
  background: #E6E6E6;
  transform: scaleX(0);
  transform-origin: 50% 50%;
  pointer-events: none;
}

/* The placeholder hanging from the rule, with a column of notes on each side.
   The script sizes the placeholder and moves the row with the rule. */
.reveal__row {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  column-gap: 48px;
  align-items: start;
  width: calc(100% - 2 * var(--container-pad));
  /* its top edge is the rule: the notes scroll up under it and vanish there;
     the padding carries the clip window well below the screen */
  padding-bottom: 100vh;
  overflow: hidden;
  color: #111111;
  transform: translate(-50%, 0);
  pointer-events: none;
}

/* the window the placeholder slides down through; stays above the notes, so
   under it (narrow screens) they pass behind it */
.reveal__slot {
  position: relative;
  z-index: 1;
  grid-column: 2;
  grid-row: 1;
  overflow: hidden;
}

/* every block's notes share the same two cells; the script moves them */
.reveal__aside--left { grid-column: 1; grid-row: 1; }
.reveal__aside--right { grid-column: 3; grid-row: 1; }

/* Styled like the other placeholders on the page; square at the top, where it
   meets the rule. They lie on top of each other: the first slides out from
   under the rule, each next one is revealed from the bottom up. */
.reveal__ui {
  position: absolute;
  inset: 0;
  background: #EDEDEF;
  border-radius: 0 0 12px 12px;
  transform: translateY(-100%);
}

/* a shade apart, so the change shows while they are placeholders */
.reveal__ui:not([data-block="0"]) {
  background: #E2E2E7;
  transform: none;
  clip-path: inset(100% 0 0 0);
}

/* the line that sweeps up across the placeholder when it changes */
.reveal__wipe {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  z-index: 2;
  height: 1px;
  background: #E6E6E6;
  opacity: 0;
  pointer-events: none;
}

.reveal__aside {
  opacity: 0;
  will-change: opacity, transform;
}

.reveal__name {
  margin: 0 0 20px;
  font-family: var(--font-title);
  font-size: 32px;
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -0.045em;
}

.reveal__about {
  margin: 0;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
}

.reveal__list {
  margin: 0 0 28px;
  padding: 0;
  list-style: none;
}

/* number boxes and text as in "How it works" */
.reveal__item {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: 16px;
  align-items: start;
  padding: 16px 0;
  border-bottom: 1px solid #EDEDEF;
}

.reveal__item:first-child { padding-top: 0; }

.reveal__num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: #E8E8EA;
  border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
}

.reveal__item-text {
  padding-top: 6px;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.4;
}

/* a part's main screens in the notes: a plain list, no number boxes; the
   screen's name in the notes' full ink, what it does a step quieter, as the
   paragraph above it */
.reveal__list--plain { margin: 12px 0 0; }   /* straight under the name: 32px with its own margin */

.reveal__list--plain .reveal__item { grid-template-columns: minmax(0, 1fr); }

.reveal__list--plain .reveal__item:last-child { border-bottom: 0; }

.reveal__list--plain .reveal__item-text {
  padding-top: 0;
  font-size: 15px;
  line-height: 1.5;
  color: rgba(var(--note-ink), .7);
}

.reveal__list--plain .reveal__item-text b {
  font-weight: 400;
  color: rgb(var(--note-ink));
}

/* A short window: the notes beside the laptop would not fit under the text,
   so reveal.js sets is-tight and they close up (about 70px off the tallest). */
.reveal.is-tight .reveal__note .reveal__chips { margin-bottom: 10px; }
.reveal.is-tight .reveal__note .reveal__name { margin-bottom: 10px; font-size: 24px; }
.reveal.is-tight .reveal__note .reveal__list--plain { margin-top: 4px; }
.reveal.is-tight .reveal__note .reveal__item { padding: 8px 0; }
.reveal.is-tight .reveal__note .reveal__item:first-child { padding-top: 0; }
.reveal.is-tight .reveal__note .reveal__item-text { font-size: 14px; line-height: 1.45; }

/* the site's .btn, with the arrow in its own accent square */
.reveal__cta {
  justify-content: flex-start;
  padding: 0;
  overflow: hidden;
  background: #F0F0F4;
  color: #111111;
  letter-spacing: 0;
}

.reveal__cta-label { padding: 0 20px; }

.reveal__cta-arrow {
  display: flex;
  align-self: stretch;
  align-items: center;
  justify-content: center;
  width: 44px;
  background: var(--accent);
  color: var(--white);
  transition: background-color .15s ease;
}

.reveal__cta:hover .reveal__cta-arrow { background: var(--accent-hover); }

/* too narrow for three columns: the placeholder on top, the notes under it */
@media (max-width: 1099px) {
  .reveal__row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    row-gap: 32px;
    width: min(720px, calc(100% - 2 * var(--container-pad)));
  }

  .reveal__slot {
    grid-column: 1 / -1;
    grid-row: 1;
    justify-self: center;
  }

  .reveal__aside--left { grid-column: 1; grid-row: 2; }
  .reveal__aside--right { grid-column: 2; grid-row: 2; }
}

/* ============================================================
   DOCKING — four scroll-driven stages over a molecular viewport
   ============================================================ */
/* section.how, not .how: `.hero ~ section` above paints white and would
   otherwise win on specificity over a single class. */
section.how {
  position: relative;
  padding: var(--section-padding-y) var(--page-gutter);
  /* the section above already eases into this grey */
  background: #F7F7F8;
}

.how__grid {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr);
  gap: 80px;
  align-items: start;
}

/* ---------- sticky aside ---------- */
.how__aside {
  position: sticky;
  top: 104px;
  align-self: start;
}

.how__title {
  margin: 0;
  font-family: var(--font-title);
  font-size: 44px;
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.035em;
  color: #111;
}

.how__nav {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  margin-top: 40px;
}

.how__nav-item {
  display: flex;
  align-items: center;
  min-height: 44px;          /* цель под палец */
  padding: 12px 20px;
  border-radius: 10px;
  background: transparent;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 400;
  color: #111;
  text-align: left;
  cursor: pointer;
  transition: background-color .2s ease, color .2s ease;
}

.how__nav-item:hover { background: rgba(0, 0, 0, .04); }

.how__nav-item.is-active {
  background: #A78BFA;
  color: #111;
  font-weight: 500;
}

.how__nav-item:focus-visible { outline-color: #111; }

/* ---------- step cards ---------- */
.how__steps {
  display: flex;
  flex-direction: column;
  gap: 150px;
}

.how__card {
  min-height: 720px;
  padding: 60px;
  background: var(--white);
  border-radius: 16px;
  overflow: hidden;
  scroll-margin-top: 80px;
}

.how__col { min-width: 0; }

.how__card-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 48px;
  align-items: start;
}

.how__card-title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 36px;
  font-weight: 500;
  line-height: 1.15;
  color: #111;
}

.how__card-desc {
  margin: 0;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  color: #6B6B6B;
}

.how__list {
  margin: 100px 0 0;
  padding: 0;
  list-style: none;
}

.how__item {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: 20px;
  align-items: start;
  padding: 28px 0;
  border-bottom: 1px solid #EDEDEF;
}

.how__item:last-child { border-bottom: 0; }

.how__num {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  background: #E8E8EA;
  border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  color: #111;
}

.how__item-text {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.4;
  color: #111;
}

.how__shot {
  /* bleeds past the card's 60px padding on the right, as in the mock */
  margin: 48px -60px 0 0;
  aspect-ratio: 4 / 3;
  background: #EDEDEF;
  border-radius: 12px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, .08);
}

/* ---------- how--list: the title as a small label, the steps as large
   lines, all in the heading font and the page's black: the current one full,
   the rest pale grey. A modifier, so the commented-out version keeps its own
   look. ---------- */
/* wide enough that every step stays on one line, as in the reference */
.how--list .how__grid { grid-template-columns: clamp(440px, 32vw, 560px) minmax(0, 1fr); }

.how--list .how__title {
  font-family: var(--font-title);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: -0.01em;
  color: #111;
}

.how--list .how__nav {
  gap: 6px;
  margin-top: 48px;
}

.how--list .how__nav-item {
  padding: 0;
  border-radius: 0;
  background: none;
  font-family: var(--font-heading);
  font-size: clamp(30px, 2.6vw, 40px);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: #CFCFCF;
  transition: color .3s ease;
}

.how--list .how__nav-item:hover { background: none; color: #8A8A8A; }

.how--list .how__nav-item.is-active {
  background: none;
  font-weight: 400;
  color: #111;
}

.how--list .how__nav-item:focus-visible { outline: 2px solid #111; outline-offset: 4px; }

/* ---------- step cards, after the reference: a dark visual with a two-tab
   switch over a panel of bars, then the title and text under it ---------- */
.how-cards {
  display: flex;
  flex-direction: column;
  gap: 120px;
  /* narrower than the column: on a wide screen the visuals would grow far
     past their text; the right edge in line with the header's «Оставить
     заявку» (both 40px off the page's edge) */
  width: 100%;
  max-width: 760px;
  justify-self: end;
}

.how-card {
  min-width: 0;
  scroll-margin-top: 80px;
}

.how-card__visual {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 6:5 as in the reference, but short enough that the title and the text
     under it share the screen; the width stays full when the height is capped */
  width: 100%;
  aspect-ratio: 6 / 5;
  max-height: max(560px, calc(100vh - 320px));
  padding: 48px;
  overflow: hidden;
  border-radius: 12px;
  /* deep plum ground: a glow top right, a softer one bottom left, a thin
     light line across each corner; the dark falls away to the right */
  background:
    linear-gradient(-30deg, transparent 0 21%, rgba(255, 255, 255, .22) 21.1%, rgba(255, 255, 255, .22) 21.3%, transparent 21.5%),
    linear-gradient(-12deg, transparent 0 83%, rgba(255, 255, 255, .18) 83.1%, rgba(255, 255, 255, .18) 83.3%, transparent 83.5%),
    radial-gradient(40% 55% at 100% 55%, #000000 10%, transparent 70%),
    radial-gradient(55% 40% at 68% 30%, rgba(214, 84, 196, .55), transparent 70%),
    radial-gradient(45% 35% at 12% 72%, rgba(150, 40, 130, .35), transparent 70%),
    linear-gradient(135deg, #2E0B29 0%, #1E0719 45%, #0C030A 100%);
}

/* Фирменные ленты на подложке шагов: тот же лист, что на карточках
   аудиторий, взятый маской и закрашенный фирменным цветом.
   Подложка и ленты у шага одной семьи: ленты — фирменный цвет в полную
   силу, подложка — он же, разбавленный белым. Рецептура та же, что у плашек
   аудиторий (.aud__art--pink и --violet), но белого больше: там цвет берут
   пополам, здесь — на две трети, иначе под окном платформы фон выходит
   слишком звонким. Второй стоп градиента светлее первого на ту же разницу,
   что была заложена изначально; у розового он упёрся бы в чистый белый,
   поэтому ограничен светлотой 97.5. У
   каждого шага свой цвет, свой масштаб и свой участок листа, поэтому три
   фона не выглядят одной картинкой трижды. Лежит под окном платформы
   (z-index 0), окна подняты на 1. */
.how-card__visual::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--how-pattern-ink, #B69DF4);
  -webkit-mask: var(--how-pattern-sheet, url('../images/pattern3.svg')) var(--how-pattern-pos, 50% 45%) / var(--how-pattern-size, 1500px) auto no-repeat;
  mask: var(--how-pattern-sheet, url('../images/pattern3.svg')) var(--how-pattern-pos, 50% 45%) / var(--how-pattern-size, 1500px) auto no-repeat;
  opacity: var(--how-pattern-fade, .28);
  pointer-events: none;
}

/* Шаг 1 — сиреневый, но лист другой: не одиночный мотив pattern3.svg, а
   сплошное поле лент cta-pattern.svg, то же, что на обложке брошюры и на
   первом экране. Одиночный мотив в этом крупном масштабе давал за окном
   два размытых пятна; поле идёт от края до края, и в поля вокруг окна
   попадает сам рисунок. Края листа рваные, поэтому он берётся втрое шире
   карточки и центрируется по плотной середине. */
#step-1 .how-card__visual {
  --how-ground-a: #D3C8FE;
  --how-ground-b: #E8E3FE;
  --how-pattern-ink: #7654FC;
  --how-pattern-sheet: url('../images/cta-pattern.svg');
  --how-pattern-size: 2000px;
  --how-pattern-pos: 50% 45%;
  --how-pattern-fade: .13;
}

/* Шаг 2 — фирменный розовый #FBB1E0, тот же, что на карточках аудиторий и
   у лиганда в 3D-сцене; подложка — он же, осветлённый до пастели. Лист у
   шага свой: grafic2.svg, отдельный мотив той же семьи, что pattern3.svg,
   но с другим ходом лент. Взят чуть крупнее карточки и смещён вверх,
   поэтому петли обходят окно сверху, снизу и по бокам, а не упираются в
   него одним пятном. */
#step-2 .how-card__visual {
  --how-ground-a: #FEE6F5;
  --how-ground-b: #FFF3FA;
  --how-pattern-ink: #FBB1E0;
  --how-pattern-sheet: url('../images/grafic2.svg');
  --how-pattern-size: 1000px;
  --how-pattern-pos: 50% 40%;
  /* розовый светлее чернил соседних шагов, поэтому плотность выше */
  --how-pattern-fade: .27;
}

/* Шаг 3 — мятный, тот же сплошной лист лент, что у шага 1, но взятый
   заметно крупнее: в поля попадают две-три широкие петли во всю высоту,
   как на фирменном развороте. Плотность выше, чем у соседей: в этом
   масштабе рисунка в кадре мало, и на бледной заливке он иначе теряется. */
#step-3 .how-card__visual {
  --how-ground-a: #C2DEEB;
  --how-ground-b: #DBECF3;
  --how-pattern-ink: #4198C1;
  --how-pattern-sheet: url('../images/cta-pattern.svg');
  --how-pattern-size: 6000px;
  --how-pattern-pos: 50% 45%;
  --how-pattern-fade: .27;
}

/* a glowing ribbon looping over the top */
.how-card__visual::before {
  content: '';
  position: absolute;
  top: -30%;
  left: -5%;
  width: 105%;
  height: 72%;
  border-radius: 50%;
  box-shadow: inset 0 -44px 60px -18px rgba(232, 118, 214, .55), 0 40px 90px -30px rgba(200, 60, 180, .45);
  transform: rotate(-9deg);
  pointer-events: none;
}

.how-card__tabs,
.how-card__panel {
  position: relative;
  z-index: 1;
}

.how-card__tabs {
  display: flex;
  gap: 4px;
  padding: 8px;
  background: #EEF1F5;
  border-radius: 12px;
}

.how-card__tab {
  padding: 12px 32px;
  border-radius: 8px;
  background: transparent;
  font-family: var(--font-heading);
  font-size: 20px;
  line-height: 1.2;
  color: #1E2A6B;
  cursor: pointer;
  transition: background-color .2s ease, color .2s ease;
}

.how-card__tab:hover { background: rgba(91, 100, 144, .1); }

.how-card__tab.is-active {
  background: #5B6490;
  color: #FFFFFF;
}

.how-card__tab:focus-visible { outline: 2px solid #FFFFFF; outline-offset: 2px; }

.how-card__panel {
  display: grid;
  width: 80%;
  margin-block: auto;
  padding: 44px 48px;
  background: rgba(246, 242, 246, .93);
  border-radius: 14px;
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

/* both sets share one cell, so the panel keeps its height when they swap */
.how-card__set {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  gap: 28px;
  margin: 0;
  padding: 0;
  list-style: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s ease, visibility 0s linear .3s;
}

.how-card__set.is-active {
  opacity: 1;
  visibility: visible;
  transition: opacity .3s ease;
}

.how-card__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 24px;
  row-gap: 14px;
  align-items: end;
}

.how-card__label {
  grid-column: 1;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 14px;
  letter-spacing: 0;
  color: #1E2A6B;
}

.how-card__bar {
  grid-column: 1;
  height: 6px;
  overflow: hidden;
  background: #FFFFFF;
  border-radius: 3px;
}

.how-card__fill {
  display: block;
  width: 0;
  height: 100%;
  background: #5B6490;
  border-radius: 3px;
  transition: width .9s cubic-bezier(.2, .7, .2, 1);
}

.how-card__row.is-accent .how-card__fill { background: #E9528A; }

/* the bars fill once the panel is on screen, and again on every swap */
.how-card__panel.is-in .how-card__set.is-active .how-card__fill {
  width: calc(var(--v) * 100%);
}

.how-card__value {
  grid-column: 2;
  grid-row: 1 / 3;
  min-width: 3ch;
  font-family: var(--font-heading);
  font-size: 40px;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: #1E2A6B;
}

/* ---------- step 1's visual: the project page of the platform ----------
   A light window bigger than the dark panel, running off its right edge. It
   is its own size container: 1em inside is a hundredth of its width, so the
   page scales as one picture at every width. */
.how-card__visual.how-card__visual--app {
  display: block;
  aspect-ratio: 6 / 5;
  padding: 0;
  /* подложка шага: цвет задаёт сам шаг (--how-ground-*) */
  background: linear-gradient(180deg, var(--how-ground-a, #B2B2B8) 0%, var(--how-ground-b, #C6C6CB) 100%);
}

.how-card__visual--app::before { display: none; }

.pm {
  position: absolute;
  top: 8%;
  left: 6%;
  z-index: 1;
  width: 130%;
  aspect-ratio: 8 / 5;
  overflow: hidden;
  container-type: inline-size;
  background: #FFFFFF;
  border-radius: 8px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, .45);
}

/* ---------- steps 2 and 3: a screenshot of the platform in a window ----------
   A window on the brand ground, with no browser bar above it: just the
   screenshot of the platform, rounded and shadowed. */
.how-card__visual.how-card__visual--browser {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 6 / 5;
  padding: 0;
  background: linear-gradient(180deg, var(--how-ground-a, #B2B2B8) 0%, var(--how-ground-b, #C6C6CB) 100%);
}

.how-card__visual--browser::before { display: none; }

.dk {
  position: relative;
  z-index: 1;
  width: 90%;
  aspect-ratio: 8 / 5;   /* as the screenshot, so none of it is cut */
  overflow: hidden;
  container-type: inline-size;
  background: #0B0B0C;
  border-radius: 8px;
  box-shadow: 0 24px 60px rgba(40, 40, 50, .35);
}

/* step 2: the window stands in the middle of the ground, both ways. The
   ground is a size container, so the window can be fitted by width and by
   height at once without leaving its proportion. */
#step-2 .how-card__visual--browser {
  justify-content: center;
  align-items: center;
  container-type: size;
}

/* Окно показывает снимок целиком, без обрезки: его пропорция равна
   пропорции снимка 2000×1250. Размер — наибольший, при котором подложки остаётся не меньше 5% по бокам
   и 8% сверху и снизу. */
#step-2 .dk {
  width: min(90cqw, 84cqh * 8 / 5);
  aspect-ratio: 8 / 5;
  border-radius: 8px;
}

/* and a penguin peeks over the ground's top edge. The ground clips what it
   holds, so the penguin stands outside it, in the card; its drawing is cut
   off at the bottom, and the ground (after it in the page) covers the cut
   by a pixel */
#step-1,
#step-2 { position: relative; }

.how-card__pin {
  position: absolute;
  top: 1px;
  right: 10%;
  display: block;
  width: 16%;
  height: auto;
  transform: translateY(-100%);
  pointer-events: none;
}

/* step 1: the penguin peeks out from behind the ground's left side instead,
   turned a quarter left about its bottom right corner, so its cut-off bottom
   stands on that side (the ground covering it by a pixel) and its head looks
   out to the left */
.how-card__pin--side {
  top: clamp(40px, 8vw, 140px);
  right: calc(100% - 1px);
  transform-origin: 100% 100%;
  transform: rotate(-90deg);
}

.dk__in {
  display: flex;
  flex-direction: column;
  height: 100%;
  font-family: var(--font-heading);
  font-size: 1cqw;
  color: #1C1C1E;
}

.dk__app {
  display: flex;
  flex: 1;
  min-height: 0;
}

/* Снимки платформы внутри рамок: окно показывает верхний левый угол страницы,
   низ подрезается рамкой — так же, как настоящее окно показывает часть
   страницы. */
.pm__shot,
.dk__shot {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left top;
}

.how-card__title {
  margin: 40px 0 0;
  font-family: var(--font-title);
  font-size: 32px;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.045em;
  color: #111;
}

.how-card__desc {
  max-width: 640px;
  margin: 20px 0 0;
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.6;
  color: #6B6B6B;
}

@media (prefers-reduced-motion: reduce) {
  .how-card__fill,
  .how-card__set { transition: none; }

  /* линия под пунктом шапки просто появляется, без пробега слева направо */
  .cover-nav-link::after,
  .footer__link::after,
  .footer__contact::after,
  .footer__legal::after { transition: none; }
}

/* ============================================================
   MOLECULE — dark card on the light page
   ============================================================ */
/* section.who / section.faq: `.hero ~ section` would otherwise win on
   specificity over a single class. */
section.who {
  padding: var(--section-padding-y) var(--page-gutter);
  background: var(--white);
}

/* the title on the left, the lead on the right where the reference has buttons */
.who__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 40px;
  margin-bottom: 56px;
}

.who__title {
  margin: 0;
  font-family: var(--font-title);
  font-size: 44px;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.05em;
  color: #111;
}

.who__lead {
  max-width: 420px;
  margin: 0;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.6;
  color: #6B6B6B;
}

.who__cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.who__card { min-width: 0; }

/* a light grey panel with a small diagram drawn in SVG */
.who__visual {
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: #F2F2F2;
  border-radius: 4px;
}

.who__visual svg {
  display: block;
  width: 100%;
  height: 100%;
}

.who__visual text {
  font-family: var(--font-heading);
  font-size: 17px;
  dominant-baseline: central;
}

.who__dash path {
  fill: none;
  stroke: #1C1C1C;
  stroke-width: 1;
  stroke-dasharray: 4 4;
}

.who__node rect { fill: #111111; }

.who__node text {
  fill: #FFFFFF;
  font-size: 16px;
  text-anchor: middle;
}

.who__row > rect:first-child { fill: #FFFFFF; }

.who__row text { fill: #111111; }

.who__card-title {
  margin: 32px 0 0;
  font-family: var(--font-heading);
  font-size: 20px;
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: -0.025em;
  color: #111;
}

.who__card-text {
  max-width: 560px;
  margin: 16px 0 0;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.5;
  color: #6B6B6B;
}

/* ---------- who it is for, second version ----------
   Two white cards on the light grey: who exactly it is for in small violet
   caps, the audience, one sentence; what it gets, point by point, folds out
   under a round violet plus; at the foot a strip of the brand's chains in a
   colour of the card's own. The previous version's rules above stay for when
   it comes back. */
/* the white of the carousel above eases into the grey over the block's
   top, so there is no seam between them */
section.who.who--v2 { background: linear-gradient(180deg, #FFFFFF 0, #F7F7F8 320px); }

.who--v2 .who__head { margin-bottom: 48px; }

/* the cards side by side as tall as each other, their strips in line */
.aud {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

.aud__card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  background: #FFFFFF;
  border-radius: 20px;
}

.aud__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  /* the bottom padding keeps the penguins' heads clear of the last line */
  padding: 48px 48px 28px;
}

/* the tags: small, on a light grey */
.aud__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.aud__tag {
  padding: 6px 10px;
  border-radius: 6px;
  background: #F2F2F4;
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.2;
  color: #4A4A4E;
}

.aud__name {
  margin: 28px 0 0;
  font-family: var(--font-title);
  font-size: clamp(30px, 2.8vw, 40px);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.045em;
  color: #111;
}

/* what it gets, point by point, in ruled rows */
.aud__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.aud__item {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 14px 0;
  border-top: 1px solid #E6E6EA;
  font-family: var(--font-heading);
  font-size: 17px;
  line-height: 1.35;
  color: #111;
}

.aud__item:first-child { margin-top: 28px; }

/* a small brand-violet square before each point */
.aud__item::before {
  content: '';
  flex: none;
  width: 8px;
  height: 8px;
  background: #B69DF4;
  transform: translateY(-2px);
}

/* the strip at the foot: a plain light grey, and for now a penguin
   (pin.svg) peeking up from the card's bottom edge, its cut-off bottom on
   that edge. Tall enough that the drawings standing on it are held whole
   inside the colour, cut only where the card itself ends. */
.aud__art {
  position: relative;
  flex: none;
  height: 280px;
  background: #F2F2F4;
}

.aud__art::before {
  content: '';
  position: absolute;
  bottom: 0;
  left: var(--aud-pin-x, 50%);
  width: 240px;
  height: 138px;              /* 240 x 142 / 248: the drawing's own proportions */
  background: url('../images/pin.svg') center bottom / contain no-repeat;
  transform: translateX(-50%);
}

/* The pharmaceutical card's strip: the brand's two penguins with a laptop
   (penguin1.svg) standing on a light pink band tall enough to hold them
   whole; the card's own overflow still cuts them off at its bottom edge. The
   drawing is pushed down by a share of its own height, so that cut stays the
   same whatever the card's width. */
.aud__art--pink {
  --aud-pin-x: 32%;
  background: #FDD8F0;        /* фирменный #FBB1E0, осветлённый вдвое */
  --aud-pattern-ink: #FBB1E0;   /* ленты -- сам фирменный розовый */
  --aud-pattern-pos: 40% 40%;   /* плотный участок листа, другой чем у соседки: лентами занята вся плашка */
  /* Фирменный розовый и сам по себе светлее сиреневого, поэтому на своей
     плашке он выходит бледнее: чтобы ленты весили столько же, сколько на
     соседней карточке, здесь они плотнее. */
  --aud-pattern-fade: .45;
}

.aud__penguins {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: min(100%, 640px);
  max-width: none;
  height: auto;
  transform: translate(-50%, 28%);
}

/* The academic card's strip: the brand penguin at the board (penguin2.svg), on a
   violet band -- the cool half of the pair, against the pink card opposite. This
   drawing is nearly square, unlike the pair on the first card, so it is set
   narrower; it too stands whole within the colour. */
.aud__art--violet {
  --aud-pin-x: 68%;
  background: #DCD3F8;        /* фирменный #B69DF4, осветлённый вдвое -- как розовая плашка относительно #FBB1E0 */
  --aud-pattern-ink: #B69DF4;   /* ленты -- сам фирменный сиреневый */
  --aud-pattern-pos: 75% 50%;   /* плотная середина листа: лентами занята вся плашка */
}

.aud__penguins--board {
  width: min(70%, 460px);
  transform: translate(-50%, 28%);
}

/* The coloured bands carry the brand's big ribbons (pattern3.svg), under the
   drawings: the sheet takes over the strip's pseudo-element, which used to hold
   the outline penguin (pin.svg) on the plain grey cards. The sheet is one shape
   on a clear ground, so it is used as a mask and painted per card: the band's
   own colour a shade deeper, violet on the violet card and pink on the pink one.
   It is drawn wider than any card, and each card crops a different part of it
   (--aud-pattern-pos), so the two bands are not the same picture twice. Both
   crops stay inside the sheet's dense middle -- about 60% of the window inked,
   as in the first version; its corners thin out to 30% and less, where the
   ribbons fall apart into stray blobs. The sheet is larger than any band in
   both directions, so no edge of it can reach one. The modifier alone weighs no
   more than .aud__art, so the base class is named alongside it: otherwise the
   narrow-screen rule below, which sizes the pin.svg penguin, would still set
   width and height. */
.aud__art.aud__art--pink::before,
.aud__art.aud__art--violet::before {
  inset: 0;
  width: auto;
  height: auto;
  background: var(--aud-pattern-ink);
  -webkit-mask: url('../images/pattern3.svg') var(--aud-pattern-pos, 50% 45%) / var(--aud-pattern-size, 1500px) auto no-repeat;
  mask: url('../images/pattern3.svg') var(--aud-pattern-pos, 50% 45%) / var(--aud-pattern-size, 1500px) auto no-repeat;
  opacity: var(--aud-pattern-fade, .3);   /* ленты ещё сильнее смешиваются с плашкой */
  transform: none;
}

@media (max-width: 900px) {
  .aud { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 640px) {
  .aud__body { padding: 32px 24px 22px; }

  .aud__name {
    margin-top: 20px;
    font-size: 28px;
  }

  .aud__item { font-size: 16px; }

  .aud__art { height: 220px; }

  .aud__art::before {
    width: 180px;
    height: 103px;
  }

  /* the drawing is shorter than the band is tall here: it stands on it whole */
  .aud__penguins { transform: translate(-50%, 0); }

  .aud__penguins--board {
    width: min(92%, 520px);
    transform: translate(-50%, 15%);
  }

  /* the sheet is brought down with the card, so the ribbons keep the breadth
     they have on the wide cards; left at its full size only two vague sweeps
     would reach a band this narrow */
  .aud__art { --aud-pattern-size: 950px; }

  /* то же и для лент на шагах: иначе в узкую карточку попадёт пара размытых
     мазков вместо рисунка */
  #step-1 .how-card__visual { --how-pattern-size: 700px; }
  #step-2 .how-card__visual { --how-pattern-size: 900px; }
  #step-3 .how-card__visual { --how-pattern-size: 2100px; }
}

/* ============================================================
   TOOLS, second version — a heading, a paragraph, and the tools as a
   the current screen large in the middle, its neighbours dimmed at the
   sides, round arrows between them, dots and its caption under it
   ============================================================ */
section.gal {
  --gal-w: min(62vw, 1240px);            /* the screen in the middle */
  --gal-gap: clamp(24px, 6.5vw, 130px);  /* between the screens */
  /* the chains at the top: as tall as the drawing at the page's width
     (151 / 1317 of it), never too small to read on a phone */
  --gal-chains: max(72px, 11.47vw);
  position: relative;
  padding: calc(var(--gal-chains) + 64px) 0 var(--section-padding-y);
  overflow: hidden;
  background: #FFFFFF;
  color: #111;
}

/* the brand's chains hanging from the grey block above: their flat top on
   the section's top edge; where the page is narrower than the drawing's
   proportions allow, its sides are cropped, never squeezed */
.gal__chains {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  max-width: none;
  height: var(--gal-chains);
  object-fit: cover;
  object-position: center top;
  pointer-events: none;
}

/* as tall as a screen; the screens lie in it side by side, each moved from
   the middle by its distance from the current one (--gal-at, the script) */
.gal__stage {
  position: relative;
  height: calc(var(--gal-w) * 10 / 16);
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
}

.gal__slide {
  position: absolute;
  top: 0;
  left: 50%;
  width: var(--gal-w);
  height: 100%;
  margin-left: calc(var(--gal-w) / -2);
  padding: 14px;
  border: 1px solid #E4E4E8;
  border-radius: 32px;
  background: #F4F4F6;
  opacity: .45;
  transform: translateX(calc(var(--gal-at, 0) * (var(--gal-w) + var(--gal-gap))));
  transition: transform .6s cubic-bezier(.2, .7, .2, 1), opacity .6s ease;
  cursor: pointer;
}

/* a light screen: white under it, so no dark band shows at its edges (two
   classes: it has to beat the dark ground set on every screen further down) */
.gal__slide.gal__slide--light img { background: #FFFFFF; }

.gal__slide.is-current {
  opacity: 1;
  cursor: default;
}

/* the one crossing from one side to the other, out of sight: no travel */
.gal__slide.is-jump { transition: none; }

/* whole, as on the laptop: the thin bands it leaves are black on its black */
.gal__slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: 20px;
  background: #000000;    /* the platform's screens are dark */
  pointer-events: none;
}

/* the arrows: white rings in the middle of the gaps beside the screen */
.gal__arrow {
  position: absolute;
  top: 50%;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin: -24px 0 0 -24px;
  border: 1px solid #D9D9DE;
  border-radius: 50%;
  background: #FFFFFF;
  color: #111;
  cursor: pointer;
  transition: background-color .2s ease;
}

.gal__arrow--prev { left: calc(50% - var(--gal-w) / 2 - var(--gal-gap) / 2); }

.gal__arrow--next { left: calc(50% + var(--gal-w) / 2 + var(--gal-gap) / 2); }

.gal__arrow svg { width: 16px; height: 16px; }

.gal__arrow:hover { background: #F4F4F6; }

.gal__arrow:focus-visible { outline: 2px solid #7C5CFC; outline-offset: 2px; }

/* under the current screen, centred on it: a short line for each screen,
   the current one black */
.gal__dots {
  display: flex;
  justify-content: center;
  gap: 8px;
  width: var(--gal-w);
  margin: 40px auto 0;
}

/* a tall enough target, the line itself thin */
.gal__dot {
  position: relative;
  display: flex;
  align-items: center;
  width: 28px;
  height: 16px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

/* линия остаётся тонкой, а пальцу достаётся 44px -- невидимо и не двигая ритм */
.gal__dot::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 44px;
  transform: translateY(-50%);
}

.gal__dot::before {
  content: '';
  width: 100%;
  height: 3px;
  border-radius: 2px;
  background: #DCDCE1;
  transition: background-color .25s ease;
}

.gal__dot:hover::before { background: #C4C4CB; }

.gal__dot.is-current::before { background: #111; }

.gal__dot:focus-visible { outline: 2px solid #7C5CFC; outline-offset: 2px; border-radius: 2px; }

@media (max-width: 1024px) {
  .gal__arrow {
    width: 40px;
    height: 40px;
    margin: -20px 0 0 -20px;
  }
}

/* narrow: the screen nearly as wide as the page, turned by a swipe or the dots */
@media (max-width: 640px) {
  section.gal {
    --gal-w: 84vw;
    --gal-gap: 12px;
    padding: calc(var(--gal-chains) + 40px) 0 72px;
  }

  .gal__slide {
    padding: 6px;
    border-radius: 16px;
  }

  .gal__slide img { border-radius: 11px; }

  .gal__arrow { display: none; }

  .gal__dots { margin-top: 28px; }

  .gal__dot { width: 24px; }
}

/* ============================================================
   FAQ — one item open at a time
   ============================================================ */
section.faq {
  padding: var(--section-padding-y) var(--page-gutter);
  background: var(--white);
}

.faq__title {
  margin: 0 0 48px;
  font-family: var(--font-title);
  font-size: 44px;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.05em;
  color: #111;
}

.faq__item { border-top: 1px solid #EDEDEF; }

.faq__item:last-child { border-bottom: 1px solid #EDEDEF; }

.faq__heading {
  margin: 0;
  font: inherit;
}

.faq__q {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 24px;
  column-gap: 24px;
  align-items: center;
  width: 100%;
  padding: 24px 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
}

/* as the tab names in the tools block: the same size, grey until hovered,
   darker under the pointer, black once open */
.faq__question {
  font-family: var(--font-heading);
  font-size: 22px;
  font-weight: 400;
  line-height: 1.2;
  color: #9A9A9A;
  transition: color .2s ease;
}

.faq__q:hover .faq__question { color: #555; }

.faq__item.is-open .faq__question { color: #111; }

.faq__sign {
  justify-self: end;
  color: #9A9A9A;
  transition: color .25s ease;
}

.is-open .faq__sign { color: #111; }   /* как и сам вопрос, когда он раскрыт */

.faq__sign-v {
  transform-origin: 7px 7px;
  transition: transform .25s ease;
}

.is-open .faq__sign-v { transform: scaleY(0); }

.faq__a {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  transition: grid-template-rows .3s ease;
}

.is-open .faq__a { grid-template-rows: 1fr; }

.faq__a-inner {
  min-height: 0;
  overflow: hidden;
}

.faq__answer {
  margin: 0;
  padding: 0 0 24px;
  max-width: 640px;          /* ~90 знаков в строке вместо 117 */
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.6;
  color: #6B6B6B;
}

.faq__answer a {
  color: #111111;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
}
.faq__answer a:hover,
.faq__answer a:focus-visible { text-decoration-thickness: 2px; }

/* ============================================================
   CTA — dark block with the request form
   ============================================================ */
/* section.cta: `.hero ~ section` would otherwise repaint it white. */
/* two halves of the screen: the words on the dark, the form on white */
section.cta {
  padding: 0;
  background: var(--bg-dark);
  color: var(--white);
}

.cta__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  min-height: 100vh;
}

/* the words near the top, the brand pattern winding up from the bottom */
.cta__intro {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  overflow: hidden;
  /* левое поле — по линии контента, те же 40px, что у шапки и секций; правое
     это внутренний промежуток до сиреневой половины, а не поле страницы */
  padding: clamp(80px, 14vh, 160px) 60px 80px var(--page-gutter);
  background: var(--bg-dark);
}

.cta__title,
.cta__lead { position: relative; z-index: 1; }

/* the brand pattern hangs from its ragged top edge, a little below the
   middle, and runs on past the panel's bottom and right (cropped there);
   large, as on the poster: a column or two of it across the panel */
.cta__pattern {
  position: absolute;
  top: 48%;
  left: 0;
  width: clamp(1250px, 150vw, 2600px);
  max-width: none;
  height: auto;
  pointer-events: none;
}

/* on a low screen the pattern stays clear of the words */
/* ---------- телефон, положенный набок ----------
   Первый экран ростом в целый экран, а экрана тут 360-390px. Заголовок задан
   как clamp(48px, 6vw, 104px), и здесь срабатывает нижняя граница: два ряда по
   48px вместе с подзаголовком, кнопками и отступами съедают всю высоту --
   шапка и слова смыкаются встык (замер: зазор 5px при 844x390 и 0 при 740x360).
   Ничего не обрезается, но дышать нечем, поэтому на низких экранах кегль и
   отступы уменьшены. Условие с ориентацией и высотой: на портретный телефон
   (высота 800) и на десктоп (900) не распространяется. */
@media (orientation: landscape) and (max-height: 520px) {
  .cover { padding: 16px 24px 24px; }

  .cover-title { font-size: clamp(26px, 3.6vw, 34px); }

  .cover-lede { font-size: 14px; }

  .cover-bottom { gap: 16px 32px; }

  .cover-buttons { margin-top: 16px; }

  .cover-top .cover-btn { height: 40px; }
}

@media (max-height: 760px) and (min-width: 1025px) {
  .cta__pattern { top: 56%; }
}

.cta__title {
  margin: 0;
  font-family: var(--font-title);
  font-size: clamp(36px, 3.6vw, 56px);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.05em;
  color: var(--white);
}

.cta__lead {
  margin: 28px 0 0;
  max-width: 460px;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: #B4B4B4;           /* as the text on the dark in the video reveal (TEXT_DARK_INK) */
}

/* Правое поле — по линии общего контейнера, чтобы лист формы обрывался там
   же, где кончается шапка и остальные секции. Линия эта — 40px: столько
   стоит у .cover-top, section.who, .faq и подвала. Не var(--container-pad):
   переменная на средних ширинах уходит в 24px, а перечисленные секции всё
   равно держат 40, и по переменной форма разъехалась бы с ними.
   Левое поле остаётся 56px: это внутренний промежуток между сиреневым краем
   и листом, а не поле страницы. */
.cta__card {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 80px var(--page-gutter) 80px 56px;
  background: #B69DF4;       /* the brand violet, as on the site's buttons */
  color: #111;
}

/* the form on a white sheet laid on the violet; the form keeps its own
   colours for white */
.cta__sheet {
  position: relative;
  width: 100%;
  max-width: 856px;
  margin-inline: auto;       /* stacked, the card is wider than the sheet */
  padding: 48px 48px 40px;
  border-radius: 20px;
  background: var(--white);
}

/* After a successful request (site.js, showDone): the form fades out, the
   sheet eases to the height of the thank-you note, the note rises in and the
   penguin from the confirmation email slides in from the sheet's right edge,
   where its drawing is cut off. The GIF blinks every five seconds. */
.cta__sheet.is-resizing { transition: height .5s cubic-bezier(.2, .7, .2, 1); }

.cta__sheet.is-done { overflow: hidden; }

.form.is-leaving {
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity .25s ease, transform .25s ease;
}

.cta__done[hidden] { display: none; }

.cta__done {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 300px;
  padding-right: 160px;      /* room for the penguin */
  font-family: var(--font-body);
  color: #111;
}

.cta__done-title {
  margin: 0;
  font-family: var(--font-title);
  font-size: clamp(28px, 2.6vw, 40px);
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.04em;
}

.cta__done-note {
  max-width: 440px;
  margin: 16px 0 0;
  font-size: 16px;
  line-height: 1.6;
  color: #555;
}

.cta__done-email { color: #111; overflow-wrap: anywhere; }

/* flush with the sheet's right and bottom edges (its padding is 48px / 40px) */
.cta__done-penguin {
  position: absolute;
  right: -48px;
  bottom: -40px;
  width: auto;
  height: 300px;
  transform-origin: 100% 100%;
}

.cta__done-text > * { animation: cta-done-rise .6s cubic-bezier(.2, .7, .2, 1) .15s both; }
.cta__done-note { animation-delay: .25s; }
.cta__done-penguin { animation: cta-done-peek .9s cubic-bezier(.3, 1.35, .5, 1) .3s both; }

@keyframes cta-done-rise {
  from { opacity: 0; transform: translateY(12px); }
}

@keyframes cta-done-peek {
  from { transform: translateX(110%) rotate(10deg); }
}

/* while the request is on its way: a small spinner before the button's text */
.form__submit[aria-busy="true"] { cursor: progress; }

.form__submit[aria-busy="true"]::before {
  content: "";
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-right: 10px;
  vertical-align: -3px;
  border: 2px solid rgba(255, 255, 255, .35);
  border-top-color: var(--white);
  border-radius: 50%;
  animation: form-spin .8s linear infinite;
}

@keyframes form-spin {
  to { transform: rotate(360deg); }
}

/* ---------- form ---------- */
.form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px 28px;
  width: 100%;
  max-width: 760px;
}

.form[hidden] { display: none; }

.form__wide { grid-column: 1 / -1; }

.form__label {
  display: block;
  margin-bottom: 8px;
  font-family: var(--font-body);
  font-size: 14px;
  color: #555555;           /* бледнее слов шапки (#111), но темнее прежнего серого #6B6B6B */
}

/* a field is a line: no ground, no box, only its bottom edge */
.form__input {
  width: 100%;
  height: 48px;
  padding: 0;
  border: 0;
  border-bottom: 1px solid #C9C9CF;
  border-radius: 0;
  background: transparent;
  font-family: var(--font-body);
  font-size: 16px;
  color: #111;
}

/* подсказка бледнее: над каждым полем и так есть подпись, образец в поле —
   второстепенный. Размер не трогаем: у поля он 16px, чтобы iOS не
   увеличивала страницу при фокусе */
.form__input::placeholder { color: #C4C4CA; }

/* in focus the line turns dark and a little thicker */
.form__input:focus {
  outline: none;
  border-bottom-color: #111;
  box-shadow: 0 1px 0 #111;
}

.form__select { position: relative; }

.form__input--select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 24px;
  cursor: pointer;
}

.form__caret {
  position: absolute;
  top: 50%;
  right: 0;
  margin-top: -5px;
  color: #6B6B6B;
  pointer-events: none;
}

.form__textarea {
  height: 110px;
  padding: 14px 0 28px;       /* empty room under the text; site.js grows the field to fit its hint */
  line-height: 1.5;
  resize: vertical;
}

/* ---------- checkbox ---------- */
.form__check {
  display: flex;
  align-items: center;
  gap: 12px;
  position: relative;
  margin-top: 28px;
  cursor: pointer;
}

.form__check-input {
  position: absolute;
  width: 20px;
  height: 20px;
  margin: 0;
  opacity: 0;
  cursor: pointer;   /* невидимый чекбокс лежит над квадратиком: без этого над ним стрелка */
}

.form__check-box {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border: 1px solid #C9C9CF;
  border-radius: 4px;
  background: var(--white);
  color: transparent;
  transition: background-color .2s ease, border-color .2s ease;
}

.form__check-input:checked + .form__check-box {
  background: #111;
  border-color: #111;
  color: var(--white);
}

.form__check-input:focus-visible + .form__check-box {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.form__check-text {
  font-family: var(--font-body);
  font-size: 15px;
  color: #111;
}

/* the second checkbox sits right under the first, not a block apart */
.form__check--tight { margin-top: 14px; }

/* в подписи к галочке это ссылка на документ: выделена цветом, без подчёркивания */
.form__check-link {
  color: var(--accent);
  text-decoration: none;
}

.form__error {
  margin: 14px 0 0;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.45;
  color: #C0392B;
}

/* ---------- submit ---------- */
.form__submit {
  width: 100%;
  height: 52px;
  margin-top: 28px;
  border-radius: 8px;
  background: #111;
  font-family: var(--font-body);
  font-size: 16px;
  color: var(--white);
  cursor: pointer;
  transition: background-color .2s ease;
}

.form__submit:hover { background: #2A2A2A; }

.form__submit:focus-visible { outline-color: #111; }

.form__note {
  margin: 24px 0 0;
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.5;
  color: #A5A5AD;
}

/* ============================================================
   FOOTER — continues the dark block
   ============================================================ */
/* room above, so the columns do not butt against the form's lower edge;
   a whole screen tall: the columns at the top, the legal line and the big
   logo down at the bottom (svh: the height with the phone's address bar
   shown, so it does not jump as the bar hides) */
/* ГАРНИТУРЫ ПОДВАЛА. Правило то же, что на всём сайте: Onest (--font-title) —
   только заголовки h1-h3, всё остальное Arial (--font-body), каким бы крупным
   оно ни было (ср. .cover-lede 18px, .reveal-intro__text и .cta__lead 20px —
   все на Arial). Значит, в подвале:
     Onest — .footer__title, единственный заголовок здесь;
     Arial — абзац под ним, серые подписи, ссылки навигации, почта, адрес и
             нижняя строка.
   Почта и адрес остаются на Arial не по остаточному принципу: это данные, а
   не высказывание, и нейтральные цифры со знаком @ у Arial читаются вернее,
   чем у геометричного Onest. Чтобы смена гарнитуры читалась как иерархия, а
   не как случайность, заголовок всегда на ступень крупнее их.

   Шкала подвала. Четыре ступени: заголовок, «крупное» (почта и адрес),
   ссылки навигации, мелкое (серые подписи и нижняя строка). Значения
   меняются только здесь и в оверрайде для телефона ниже по файлу, поэтому
   соотношения ступеней держатся на всех ширинах. */
.footer {
  --footer-title: 22px;
  /* Почта и адрес, одним значением на все ширины. 20, а не 22: при 22px они
     вровень с заголовком, а в самой тесной раскладке из четырёх колонок
     (1241px) адресу остаётся ~272px и строка «Большой бульвар, 42 ст. 1» в
     неё не помещается. Снизу предел — 320px экрана: там строка занимает
     ~250px из 280px доступных. */
  --footer-lead: 20px;
  --footer-link: 14px;
  --footer-text: 13px;
  --footer-fine: 12px;     /* серые подписи над блоками и нижняя строка */

  display: flex;
  flex-direction: column;
  /* a screen tall, up to 1200px: on a very tall screen a whole screen would
     leave a gap of empty dark between the columns and the logo */
  min-height: min(100vh, 1200px);
  min-height: min(100svh, 1200px);
  padding: 100px var(--page-gutter) 40px;
  background: var(--bg-dark);
  color: var(--white);
  overflow: hidden;
}

.footer__top {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1.2fr;
  gap: 40px;
  align-items: start;
  padding-bottom: 80px;
}

.footer__title {
  margin: 0;
  font-family: var(--font-title);
  font-size: var(--footer-title);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: -0.035em;
  color: var(--white);
}

.footer__text {
  margin: 16px 0 0;
  max-width: 300px;
  font-family: var(--font-body);
  font-size: var(--footer-text);
  line-height: 1.6;
  color: #B4B4B4;           /* as the lede on the dark in the form's section (.cta__lead) */
}

.footer__label {
  margin-bottom: 16px;
  font-family: var(--font-body);
  font-size: var(--footer-fine);
  font-weight: 500;
  color: rgba(254, 254, 254, .6);   /* light grey, as the copyright and the legal links */
}

.footer__links {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

.footer__link {
  font-family: var(--font-body);
  font-size: var(--footer-link);
  color: var(--white);
}

.footer__contacts {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Телефон, почта и адрес — Arial (--font-body), тот же, что у серых подписей
   над ними, а не Onest заголовка рядом (правило гарнитур — в комментарии к
   .footer выше). Разрядку убрал: -0.02em подбиралась под Onest, у Arial буквы
   шире и на минусе слипаются. */
.footer__contact {
  font-family: var(--font-body);
  font-size: var(--footer-lead);
  font-weight: 400;
  line-height: 1.25;
  color: var(--white);
}

/* Ховер у ссылок подвала — как у пунктов шапки (.cover-nav-link::after):
   под словом прочерчивается линия слева направо и уходит вправо. Полей у
   этих ссылок нет, так что линия ровно по ширине текста, чуть ниже строки. */
.footer__link,
.footer__contact,
.footer__legal { position: relative; }

.footer__link::after,
.footer__contact::after,
.footer__legal::after {
  content: '';
  position: absolute;
  right: 0;
  bottom: -3px;
  left: 0;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform .25s ease;
}

.footer__contact::after { bottom: 0; }

.footer__link:hover::after,
.footer__link:focus-visible::after,
.footer__contact:hover::after,
.footer__contact:focus-visible::after,
.footer__legal:hover::after,
.footer__legal:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.footer__address {
  font-family: var(--font-body);
  font-size: var(--footer-lead);
  font-weight: 400;
  font-style: normal;
  line-height: 1.25;
  color: var(--white);
}

.footer__bottom {
  display: flex;
  justify-content: flex-end;
  margin-top: auto;          /* down to the logo at the screen's bottom */
  align-items: center;
  gap: 24px;
  padding-bottom: 40px;
  font-family: var(--font-body);
  font-size: var(--footer-fine);
}

.footer__legal {
  color: rgba(254, 254, 254, .6);
  transition: color .2s ease;
}

.footer__legal:hover,
.footer__legal:focus-visible { color: var(--white); }

.footer__sep {
  margin: 0 -16px;
  color: rgba(254, 254, 254, .6);
}

.footer__copy { color: rgba(254, 254, 254, .6); }

/* back to the first screen: last in the bottom row, pushed to its right edge */
.footer__totop {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
}

.footer__totop-icon {
  width: 1em;
  height: 1em;
  flex: none;
}

/* ---------- oversized logo ---------- */

/* the mark and the word in one flat near-white (#FEFEFE, the site's white) */
.footer__logo-img {
  display: block;
  width: 100%;
  height: auto;
  filter: brightness(0) invert(.996);
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1200px) {
  .hero-title { font-size: 56px; }
}

/* подвал в две колонки уже отсюда, а не с 900px: в четыре колонки адресу
   остаётся 180–265px, и он рассыпается на четыре-шесть строк
   («Большой бульвар, / 42 ст. 1 / Инновационный / центр / …») */
@media (max-width: 1240px) {
  .footer__top { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Split-screen range only: at 44px the longest heading line no longer fits in
   half the viewport and the three-line lockup breaks apart. */
@media (min-width: 1025px) and (max-width: 1400px) {
}

@media (max-width: 1024px) {
  /* the halves stack: the words on the dark above, the form on white below */
  .cta__grid {
    grid-template-columns: minmax(0, 1fr);
    min-height: 0;
  }

  /* stacked: the words, then the pattern as a strip under them. Сложенной
     правое поле тоже становится полем страницы — значит, тоже 40px */
  .cta__intro {
    padding-right: 40px;
    padding-bottom: calc(clamp(220px, 35vw, 320px) + 48px);
  }

  /* сложенной карточка занимает всю ширину, и оба её поля становятся полями
     страницы — значит, оба на той же линии 40px, что у соседних секций */
  .cta__card { padding-left: 40px; padding-right: 40px; }

  .cta__pattern { top: calc(100% - clamp(220px, 35vw, 320px)); }

  .mol__head {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }

  .mol__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .how__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  .how__aside {
    position: static;
    top: auto;
  }

  .how__card { padding: 40px; }

  .how__card-grid { grid-template-columns: minmax(0, 1fr); }

  .how__list { margin-top: 48px; }

  .how__shot { margin-right: 0; }

  .how-cards { gap: 80px; }

  .how--list .how__grid { grid-template-columns: minmax(0, 1fr); }

  /* stacked under the steps: from their left edge to the request button's right one */
  .how-cards { max-width: none; }

  /* only the page's side room (40px) is left of the ground: the penguin
     keeps within it */
  .how-card__pin--side { width: 64px; }

  .how--list .how__nav { margin-top: 32px; }

  .tools {
    grid-template-columns: minmax(0, 1fr);
    min-height: 0;
  }

  .tools__media { min-height: 400px; }

  .mockup { width: 90vw; }

  .mockup__scroll { overflow-x: auto; }

  .mockup__scroll .ui-app { min-width: 880px; }

  .mockup-ghost { display: none; }
}

@media (max-width: 900px) {
  :root { --container-pad: 24px; }

  .dock { height: 300vh; }

  .dock__sticky {
    display: flex;
    flex-direction: column;
  }

  .dock__scene {
    position: relative;
    inset: auto;
    flex: 1 1 auto;
  }

  .dock__panel {
    position: relative;
    left: auto;
    top: auto;
    transform: none;
    width: 100%;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
    border-bottom: 0;
  }

  .dock__hint { display: none; }

  .reveal { height: 340vh; }

  :root { --section-padding-y: 80px; }
  .reveal-intro__title { font-size: clamp(28px, 6vw, 44px); }
  .reveal-intro__text { font-size: 17px; }

  .video-card { --card-w: 88; }

  .hero-screen { padding: 24px; }

  .cover { padding: 24px 24px 40px; }

  .hero-menu-label { display: none; }

  .hero-lede {
    max-width: 100%;
    font-size: 22px;
    text-align: left;
  }

  .hero-title { font-size: 44px; }

  .nav,
  .header__cta { display: none; }

  .burger { display: inline-flex; }

  .mobile-menu { display: block; }

  .hero__title { font-size: 36px; }

  .footer__top { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .footer__bottom {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .footer__sep { display: none; }

  .footer__totop { margin-left: 0; }

  .how__steps { gap: 60px; }
}

@media (max-width: 640px) {
  :root { --container-pad: 20px; }

  /* одна колонка: в двух каждая сжимается до ~170px, и текст рвётся клочьями --
     строка из одного слова, адрес переламывается посреди "Большой бульвар, 42" */
  .footer__top {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }

  /* Почта и адрес остаются на общих 20px: ступень между ними и заголовком
     одна и та же на всех ширинах. Мелкое подрастает — на телефоне текст
     читают с 13px с трудом, а по ссылкам ещё и попадают пальцем. */
  .footer {
    --footer-link: 16px;
    --footer-text: 14px;
  }

  .dock { height: auto; }

  .dock__sticky {
    position: static;
    height: auto;
  }

  /* the scene has to be in flow, or the unpinned section collapses to nothing */
  .dock__scene {
    position: relative;
    inset: auto;
    min-height: 60vh;
  }

  .dock__title { font-size: 30px; }

  /* молекула на телефоне опущена: над ней остаётся воздух под шапку и
     заголовок, а то, что уходит вниз, закрывает следующая секция */
  .cover-scene #cover-diffusion { transform: translateY(6%); }

  :root { --section-padding-y: 64px; }

  /* на телефоне заголовок и текст идут по левому краю: строки короткие,
     и выключка по центру рвёт их лесенкой */
  .reveal-intro { text-align: left; }

  .reveal-intro__text { margin-left: 0; margin-right: 0; }

  /* Телефон: анимации в секции нет — reveal.js на этой ширине выходит сразу
     и ничего не выставляет. Всё стоит в потоке сверху вниз: видео, фраза,
     подпись, а дальше блок за блоком — снимок экрана платформы и текст под
     ним. Ноутбук здесь скрыт: на такой ширине его рамка съедает половину
     картинки, а снимки лежат внутри самих блоков (.reveal__shot). */
  /* видео остаётся на белом, как на широком экране: тёмная часть начинается
     под ним (карточку выносит из .reveal__sticky сам reveal.js, класс is-flat) */
  .reveal {
    /* Один шаг между блоками на всю секцию: видео — фраза — три блока
       с ноутбуками — конец секции. Меняется только здесь. */
    --reveal-flat-gap: 64px;
    height: auto;
    margin-top: 0;
    background: var(--white);
  }

  /* половина шага уходит под видео, половина остаётся над фразой: граница
     белого и тёмного делит зазор ровно пополам */
  .reveal__sticky {
    position: static;
    display: block;
    height: auto;
    padding: var(--section-padding-y) 20px var(--section-padding-y);
    background: #111111;
    overflow: hidden;
  }

  .reveal.is-flat .video-card {
    width: calc(100% - 40px);
    margin: 0 20px var(--section-padding-y);
    padding: 4px;
    --card-radius: 14px;
  }

  .video-card__media {
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    object-fit: cover;
  }

  /* фраза и подпись — обычные блоки, светлые на тёмном */
  .reveal__phrase {
    position: static;
    left: auto;
    right: auto;
    margin: 0;
    font-size: clamp(20px, 5.6vw, 30px);
    white-space: normal;
    text-align: left;
    color: #FEFEFE;
    transform: none;
  }

  .reveal__half {
    display: block;
    color: #FEFEFE;
  }

  .reveal__text {
    position: static;
    width: auto;
    margin: 16px 0 0;
    font-size: 16px;
    text-align: left;
    color: #B4B4B4;
    opacity: 1;
    transform: none;
  }

  /* общий ноутбук с лентой экранов не нужен: у каждого блока заметок свой */
  .reveal__mac:not(.reveal__mac--flow) { display: none; }

  .reveal__mac--flow {
    display: block;
    position: static;
    width: 100%;
    margin-bottom: 24px;
    opacity: 1;
    transform: none;
  }

  .reveal__notes {
    position: static;
    width: auto;
    height: auto;
    margin-top: var(--reveal-flat-gap);
    overflow: visible;
    transform: none;
    pointer-events: auto;
  }

  .reveal__note {
    position: static;
    opacity: 1;
    transform: none;
  }

  .reveal__note + .reveal__note { margin-top: var(--reveal-flat-gap); }

  /* заметкам остаётся высота экрана под ноутбуком, поэтому они компактнее */
  .reveal__chips { margin-bottom: 12px; }

  .reveal__name {
    margin-bottom: 12px;
    font-size: 24px;
  }

  .reveal__list--plain { margin-top: 8px; }

  .reveal__item { padding: 10px 0; }

  .reveal__list--plain .reveal__item-text {
    font-size: 14px;
    line-height: 1.45;
  }

/* самый узкий телефон: заметки идут ещё плотнее, иначе не помещаются */
@media (max-width: 380px) {
  .reveal__name { font-size: 21px; }

  .reveal__item { padding: 8px 0; }

  .reveal__list--plain .reveal__item-text {
    font-size: 13px;
    line-height: 1.4;
  }
}


  .hero-screen { padding: 20px; }

  .cover { padding: 20px 20px 32px; }

  .cover-logo { height: 32px; }

  .cover-title { font-size: 40px; }

  /* a phone is too narrow for the two set lines: the lede wraps as it likes */
  .cover-lede {
    font-size: 16px;
    white-space: normal;
  }

  .cover-lede br { display: none; }

  .cover-buttons { margin-top: 28px; }

  /* still side by side, sharing the width */
  .cover-buttons .cover-btn {
    flex: 1 1 0;
    padding: 0 12px;
  }

  .hero-lede { font-size: 18px; }

  .hero-scroll { display: none; }

  .hero-title { font-size: 34px; }

  .hero { min-height: auto; }

  .hero__title {
    font-size: 30px;
    white-space: normal;
  }

  .hero__content { padding-bottom: 80px; }

  .hero__actions .btn { width: 100%; }

  .tools__side,
  .tools__media { padding: 40px 20px; }

  section.how { padding: var(--section-padding-y) 20px; }

  /* 20px of side room left of step 1's ground (after the 1024px rule, so
     it wins) */
  .how-card__pin--side { width: 34px; }

  .mol__card {
    margin: 0 20px;
    padding: 40px 20px;
  }

  .mol__title { font-size: 30px; }

  .cta__intro {
    padding-top: 60px;
    padding-left: 20px;
    padding-right: 20px;
  }

  .cta__card { padding: 40px 20px 48px; }

  .cta__sheet { padding: 32px 20px 28px; border-radius: 16px; }

  .cta__done { min-height: 220px; padding-right: 96px; }

  .cta__done-title { font-size: 26px; }

  .cta__done-note { font-size: 15px; }

  .cta__done-penguin { right: -20px; bottom: -28px; height: 200px; }

  .form { grid-template-columns: minmax(0, 1fr); }

  .footer { padding: 64px 20px 40px; }

  section.who { padding: var(--section-padding-y) 20px; }

  .who__title { font-size: 30px; }

  .who__head {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    margin-bottom: 32px;
  }

  .who__cards {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  .who__card-title { margin-top: 20px; }

  section.faq { padding: var(--section-padding-y) 20px; }

  .faq__title { font-size: 30px; }

  /* as the tools block's tab names on narrow screens */
  .faq__question { font-size: 18px; }

  .mol__grid { grid-template-columns: minmax(0, 1fr); }

  .how__title { font-size: 30px; }

  .how__card-title { font-size: 26px; }

  .how-cards { gap: 60px; }

  .how-card__visual {
    aspect-ratio: auto;
    max-height: none;
    gap: 32px;
    padding: 20px 16px 28px;
    border-radius: 10px;
  }

  .how-card__tab {
    padding: 10px 16px;
    font-size: 15px;
  }

  .how-card__panel {
    width: 100%;
    padding: 24px 20px;
  }

  .how-card__set { gap: 20px; }

  .how-card__label { font-size: 11px; }

  .how-card__value { font-size: 28px; }

  .how-card__title {
    margin-top: 28px;
    font-size: 26px;
  }

  .how-card__desc { font-size: 16px; }

  .tools__title { font-size: 30px; }

  .tools__desc-title { font-size: 22px; }

  .mockup,
  .mockup-ghost { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition: none !important;
    animation: none !important;
    scroll-behavior: auto !important;
  }

  .tools__panel.is-entering {
    opacity: 1;
    transform: none;
  }

  .tools__tab.is-active .tools__tab-line::after { width: 100%; }

  .dock { height: auto; }

  .dock__sticky {
    position: static;
    height: auto;
  }

  /* the scene has to be in flow, or the unpinned section collapses to nothing */
  .dock__scene {
    position: relative;
    inset: auto;
    min-height: 60vh;
  }

  .reveal { height: auto; }

  /* dark down to the rule, as the animated version is before it draws in */
  .reveal__sticky {
    position: static;
    flex-direction: column;
    gap: 32px;
    height: auto;
    padding-bottom: 64px;
    background: #111111;
  }

  .video-card {
    --card-radius: 0px;
    width: 100vw;
  }

  /* the sentence sits under the card as an ordinary heading */
  .reveal__phrase,
  .reveal__half {
    color: #FEFEFE;
  }

  .reveal__phrase {
    position: static;
    padding: 0 20px;
    font-size: clamp(28px, 6vw, 44px);
    white-space: normal;
    transform: none;
  }

  .reveal__text {
    position: static;
    width: auto;
    max-width: 720px;
    padding: 0 20px;
    font-size: 17px;
    color: #B4B4B4;
    opacity: 1;
    transform: none;
  }

  .reveal__mac {
    position: static;
    width: min(720px, calc(100% - 40px));
    opacity: 1;
    transform: none;
  }

  .reveal__notes {
    position: static;
    display: flex;
    flex-direction: column;
    gap: 56px;
    width: min(720px, calc(100% - 40px));
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
    pointer-events: auto;
  }

  .reveal__note {
    position: static;
    opacity: 1;
  }

  /* only the video on the laptop screen */
  .mac__layer { display: none; }

  .reveal__rule {
    position: static;
    align-self: stretch;
    margin: 0 20px;
    transform: none;
  }

  .reveal__row {
    position: static;
    display: flex;
    flex-direction: column;
    gap: 32px;
    width: min(720px, calc(100% - 40px));
    margin-top: -32px;
    padding-bottom: 0;
    transform: none;
    pointer-events: auto;
    /* white from the rule down, edge to edge and under the section's padding */
    background: var(--white);
    box-shadow: 0 0 0 100vmax var(--white);
    clip-path: inset(0 -100vmax -100vmax -100vmax);
  }

  /* the placeholders drop out of their shared window and each goes before
     its own block of notes */
  .reveal__slot { display: contents; }

  .reveal__ui,
  .reveal__ui:not([data-block="0"]) {
    position: static;
    width: 100%;
    aspect-ratio: 16 / 10;
    border-radius: 12px;
    transform: none;
    clip-path: none;
  }

  .reveal__ui[data-block="0"] { order: 0; }
  .reveal__aside--left[data-block="0"] { order: 1; }
  .reveal__aside--right[data-block="0"] { order: 2; }
  .reveal__ui[data-block="1"] { order: 3; }
  .reveal__aside--left[data-block="1"] { order: 4; }
  .reveal__aside--right[data-block="1"] { order: 5; }

  .reveal__aside {
    opacity: 1;
    transform: none;
  }

  .reveal__wipe { display: none; }
}

/* ============================================================
   THREE STEPS — Mol* scene, one step per wheel notch or swipe
   on a white sheet, the site's own type
   ============================================================ */
.doc-page { background: var(--bg-dark); }

.doc {
  position: relative;        /* якорь для кнопки возврата в поле слева */
  max-width: 720px;          /* ~90 знаков в строке вместо 97 */
  margin: 0 auto;
  padding: 72px 24px 96px;   /* воздух под полосой шапки */
  font-family: var(--font-body);
  color: var(--white);
}

/* Кнопка возврата стоит в пустом поле слева от колонки, вровень с заголовком.
   Поле есть только на широких экранах: колонка 720px плюс место под кнопку --
   это примерно от 1200px. Ниже кнопка встаёт в поток над заголовком, иначе она
   уехала бы за край экрана и потянула за собой горизонтальную прокрутку. */
.doc__home {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0;                /* без рамки поля не нужны: надпись встаёт в линию с заголовком */
  font-family: var(--font-heading);
  font-size: 13px;
  font-weight: 500;
  color: var(--white);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .2s ease, border-color .2s ease;
}

.doc .doc__home { color: var(--text-dim); }

.doc .doc__home:hover { color: var(--white); }

.doc__home:focus-visible { outline: 2px solid var(--white); outline-offset: 2px; }

@media (min-width: 1200px) {
  .doc__home {
    position: absolute;
    top: 72px;                      /* вровень с заголовком */
    right: calc(100% + 32px);
  }
}

@media (max-width: 1199px) {
  .doc__home { margin-bottom: 28px; }
}

.doc__title {
  margin: 0 0 10px;
  font-size: clamp(28px, 4vw, 44px);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.015em;
}

.doc__meta {
  margin: 0 0 36px;
  font-size: 14px;
  color: var(--text-dim);
}

.doc h2 {
  margin: 44px 0 14px;
  font-size: clamp(18px, 2.2vw, 22px);
  font-weight: 500;
  line-height: 1.25;
}

.doc p { margin: 0 0 14px; font-size: 16px; line-height: 1.6; }
.doc ul { margin: 0 0 14px; padding-left: 22px; }
.doc li { margin-bottom: 8px; font-size: 16px; line-height: 1.6; }
.doc a { color: var(--white); text-underline-offset: 3px; }

.doc__dl { display: grid; gap: 16px; margin: 0 0 14px; }
.doc__dl > div { display: grid; gap: 4px; }
.doc__dl dt { font-size: 16px; font-weight: 500; }
.doc__dl dd { margin: 0; font-size: 16px; line-height: 1.6; color: var(--text-dim); }

/* a narrow screen cannot hold three columns: the table scrolls on its own,
   the page does not */
.doc__table-wrap { overflow-x: auto; margin-bottom: 14px; }

.doc__table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
}

.doc__table th,
.doc__table td {
  padding: 14px 16px 14px 0;
  font-size: 15px;
  line-height: 1.55;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid rgba(254, 254, 254, .14);
}

.doc__table th {
  font-weight: 500;
  font-size: 13px;
  color: var(--text-dim);
  border-bottom-color: rgba(254, 254, 254, .3);
}

.doc__req {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 24px;
  border-radius: 16px;
  background: rgba(254, 254, 254, .06);
  font-size: 16px;
  line-height: 1.6;
}

@media (max-width: 640px) {
  .doc { padding: 40px 20px 72px; }
}

/* шапка страниц-документов в тёмном ключе, как и сама страница: фон -- та же
   тёмная подложка, что у подвала, надписи белые. Логотип -- встроенный рисунок
   из плавающей шапки: его слово нарисовано currentColor и белеет вместе с
   текстом, фиолетовый значок остаётся своим. Кнопке ничего не нужно: она
   фирменная сиреневая с тёмным текстом и читается на любом фоне. */
.doc-head {
  /* полоса тонкая: высоту держит логотип, отступы сверху и снизу минимальные */
  padding: 12px 40px;
  background: var(--bg-dark);
  border-bottom: 1px solid rgba(254, 254, 254, .12);
  color: var(--white);
}

.doc-head__home { display: inline-flex; color: inherit; }

.doc-head__logo {
  display: block;
  width: auto;
  height: 36px;
  aspect-ratio: 256 / 66;
}

.doc-head .cover-nav-link { color: var(--white); }
.doc-head .cover-nav-link:hover { background: rgba(254, 254, 254, .08); }

.doc-head__home:focus-visible,
.doc-head .cover-nav-link:focus-visible,
.doc-head .cover-btn:focus-visible { outline: 2px solid var(--white); outline-offset: 2px; }

@media (max-width: 640px) {
  .doc-head { padding: 10px 20px; }
}

/* На совсем узких экранах (320px) ряд шапки не помещается: логотип 155px плюс
   кнопка 137px плюс отступы -- это 356px против 320 доступных, и страница
   получала горизонтальную прокрутку. Логотип оставляем как есть, поджимаем
   поля, промежуток и поля кнопки. */
@media (max-width: 360px) {
  .doc-head { padding: 10px 12px; }

  .doc-head .cover-top { gap: 10px; }

  .doc-head .cover-btn {
    padding: 0 12px;
    font-size: 12px;
  }
}

/* ============================================================
   404 -- the document pages' dark shell, a penguin at the board
   ============================================================ */
.nf {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  align-items: center;
  gap: 64px;
  max-width: 1200px;
  min-height: calc(100svh - 61px);   /* the footer starts below the first screen */
  margin: 0 auto;
  padding: 72px 40px 96px;
  color: var(--white);
  font-family: var(--font-body);
}

.nf__code {
  margin: 0 0 16px;
  font-size: 14px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #B69DF4;
}

.nf__title {
  margin: 0 0 20px;
  font-family: var(--font-title);
  font-size: clamp(36px, 5vw, 64px);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.nf__lead {
  max-width: 460px;
  margin: 0 0 36px;
  font-size: 18px;
  line-height: 1.55;
  color: var(--text-dim);
}

.nf__actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* The drawing is dark ink on a transparent ground. Used as a mask it takes
   any colour, here the page's white; the lavender 404 is written on the
   empty board, right of the pointer's tip, by the board's box in the
   1346x1154 picture. */
.nf__art {
  position: relative;
  width: 100%;
  max-width: 560px;
  margin: 0 0 0 auto;
  aspect-ratio: 1346 / 1154;
  container-type: inline-size;
}

.nf__art::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--white);
  -webkit-mask: url(/assets/images/penguin-board.webp) center / contain no-repeat;
  mask: url(/assets/images/penguin-board.webp) center / contain no-repeat;
}

.nf__board {
  position: absolute;
  left: 67%;
  top: 16%;
  width: 25%;
  height: 40%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-title);
  font-size: 11cqi;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: #B69DF4;
  animation: nf-chalk 1.1s .2s cubic-bezier(.2, .7, .2, 1) both;
}

/* The eye is cut out of the drawing and drawn here, so it can blink:
   open most of the time, a quick blink and now and then a double one. */
.nf__eye {
  position: absolute;
  left: 31.87%;
  top: 29.94%;
  width: 2.82%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--white);
  animation: nf-blink 5.2s 1.4s infinite;
}

@keyframes nf-blink {
  0%, 44%, 50%, 86%, 89.5%, 93%, 100% { transform: scaleY(1); }
  47% { transform: scaleY(.12); }
  88% { transform: scaleY(.12); }
  91.5% { transform: scaleY(.12); }
}

@keyframes nf-chalk {
  from { opacity: 0; clip-path: inset(0 100% 0 0); }
  to { opacity: 1; clip-path: inset(0 0 0 0); }
}

@media (prefers-reduced-motion: reduce) {
  .nf__board,
  .nf__eye { animation: none; }
}

@media (max-width: 900px) {
  .nf {
    grid-template-columns: 1fr;
    gap: 40px;
    min-height: 0;
    padding: 48px 24px 80px;
  }

  .nf__art { order: -1; max-width: 400px; margin: 0 auto; }
  .nf__text { text-align: center; }
  .nf__lead { margin-left: auto; margin-right: auto; }
  .nf__actions { justify-content: center; }
}

@media (max-width: 640px) {
  .nf { padding: 32px 20px 64px; }
  .nf__lead { font-size: 16px; }
  .nf__actions .cover-btn { flex: 1 1 auto; }
}

/* Burette presentation indicators: dots expand into a timed active pill. */
.gal__dots { width: max-content; max-width: 100%; gap: 0; }
.gal__dot, .gal__dot.is-current { flex: 0 1 28px; width: 28px; height: 36px; justify-content: center; transition: width .24s ease; }
.gal__dot.is-current { flex-basis: 60px; width: 60px; }
.gal__dot::before, .gal__dot::after { content: none; }
.gal__dot span { position: relative; overflow: hidden; width: 6px; height: 6px; border-radius: 99px; background: #d0d0d5; transition: width .24s ease; }
.gal__dot.is-current span { width: 44px; }
.gal__dot i { position: absolute; inset: 0; background: #111; transform: scaleX(0); transform-origin: left; border-radius: inherit; }
.gal__dot.is-current i { transform: scaleX(var(--gallery-progress, 0)); }
.gal__pause { display: block; margin: 4px auto 0; border: 0; border-radius: 8px; padding: 8px 12px; background: transparent; color: #555; font: inherit; font-size: 13px; cursor: pointer; }
.gal__pause:hover { background: #eeeef1; }
.gal__pause:focus-visible { outline: 2px solid #9175d9; outline-offset: 2px; }
@media (max-width: 600px) { .gal__dots { width: calc(100% - 32px); } .gal__dot { min-width: 0; } }
@media (prefers-reduced-motion: reduce) { .gal__dot, .gal__dot span { transition: none; } }


/* ============================================================
   ЗАГОЛОВКИ: перенос строк
   ============================================================ */
/* Браузер по умолчанию заполняет строку до отказа, и у заголовка из
   нескольких строк последняя часто остаётся коротким огрызком. balance
   делит текст на строки примерно поровну; у заголовков с заданными вручную
   переносами (первый экран, фраза в секции с ноутбуком) правило ничего не
   меняет. */
h1,
h2,
h3,

/* Телефон: заголовок призыва набран с переносами под широкий экран
   («Упростите / молекулярный дизайн / с нашей платформой»); в узкую колонку
   его строки не помещаются и ломаются ещё раз, лесенкой. Переносы снимаются,
   и кегль идёт от ширины экрана, чтобы строки делились сами. */
@media (max-width: 480px) {
  .cta__title {
    font-size: clamp(28px, 8.2vw, 36px);
  }

  .cta__title br { display: none; }
}

/* Узкий телефон: длинные слова («Фармацевтические»,
   «конфиденциальности») в одну строку не влезают */
@media (max-width: 360px) {
  .aud__name { font-size: clamp(24px, 7.6vw, 28px); }

  .doc__title { font-size: clamp(24px, 7.4vw, 28px); }
}

/* Product references remain inline and follow the section's light/dark ink. */
.reveal__note a {
  color: rgb(var(--note-ink));
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .18em;
  transition: color .15s ease;
}
.reveal__note a:hover,
.reveal__note a:focus-visible {
  color: rgb(var(--note-ink));
  text-decoration-thickness: 2px;
}


/* Phones: the steps are stacked as cards right under the heading, so the
   jump list above them only repeats them as a column of grey words. */
@media (max-width: 640px) {
  .how--list .how__nav { display: none; }
}

/* Touch screens: the small text controls get a finger-sized hit area
   (about 44px tall) without changing how they look. */
@media (pointer: coarse) {
  .footer__links { gap: 0; }
  .footer__link { padding: 6px 0; }
}
