/* ============================================================
   Restored rules — kept out of main.css on purpose.

   main.css is being rewritten by another process from an older
   base, which drops these every time. Loading them from their own
   file after main.css makes the page correct regardless, and they
   can be folded back in once that process is stopped.
   ============================================================ */

/* ══════════════════════════════════════════════════════════════
   Restored: the rules below were lost when main.css was rewritten
   from an older base. The markup for all of them survived, so only
   the styling had to come back.
   ══════════════════════════════════════════════════════════════ */

/* ───────────────────────────  trust  ───────────────────────── */

.trust .wrap{padding:clamp(56px,8vw,120px) clamp(20px,4vw,var(--pad))}

.trust__title{
  margin:0 auto;
  max-width:20ch;
  text-align:center;
  font-size:clamp(1.7rem,3vw,2.4rem);
  line-height:1.22;
  letter-spacing:-.018em;
  font-weight:360;
  color:var(--ink);
}

.trust__grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(18px,2.4vw,34px);
  margin:clamp(34px,4.4vw,64px) 0 0;
}

/* the mark sits on its own plate; the words live under it, on the page
   itself, which is what keeps the row from reading as three heavy cards */
.trust__plate{
  display:grid;place-items:center;
  aspect-ratio:16/9;
  border-radius:var(--r-lg);
  background:var(--bg-2);
}
.trust__mark{
  width:clamp(46px,5vw,64px);height:auto;
  fill:none;stroke:var(--ink);stroke-width:2.4;
  stroke-linecap:round;stroke-linejoin:round;
}
.trust__mark text{
  fill:var(--ink);stroke:none;
  font-family:var(--font-sans);
  font-size:20px;font-weight:600;letter-spacing:-.02em;
}
.trust__mark--line text{font-size:15px}
.trust__mark .dot{fill:var(--brand);stroke:none}

/* the api glyph is drawn, not lettered, so it needs a lighter stroke
   than the boxed marks beside it */
.trust__mark--api{stroke-width:3.4}
.trust__mark--api .dot{stroke:var(--brand);fill:none}

/* a horizontal lockup rather than a square glyph, so it is sized on
   width and capped so it never crowds the plate */
.trust__logo{
  width:min(74%,300px);
  height:auto;
}

.trust__name{
  margin:clamp(16px,2vw,24px) 0 0;
  font-size:17px;font-weight:500;letter-spacing:-.012em;
  color:var(--ink);
}
.trust__note{
  margin:9px 0 0;
  max-width:34ch;
  font-size:15px;line-height:1.6;
  color:var(--muted);
}

/* one ruled strip rather than four cards: these are readings, not claims
   that each need their own frame */
.trust__figures{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  margin:clamp(44px,6vw,96px) 0 0;
  border:1px solid var(--line);
  border-radius:var(--r-lg);
  overflow:hidden;
}
.trust__figures li{
  padding:clamp(22px,2.6vw,32px) 16px;
  text-align:center;
}
.trust__figures li + li{border-left:1px solid var(--line)}
.trust__figures b{
  display:block;
  font-size:clamp(1.35rem,2.2vw,1.9rem);
  font-weight:500;letter-spacing:-.024em;
  color:var(--ink);
  font-variant-numeric:tabular-nums;
}
.trust__figures span{
  display:block;margin-top:6px;
  font-size:13.5px;line-height:1.45;
  color:var(--muted);
}

@media (max-width:860px){
  .trust__grid{grid-template-columns:minmax(0,1fr);gap:26px}
  .trust__plate{aspect-ratio:21/9}
  .trust__logo{width:min(56%,260px)}
  .trust__note{max-width:none}
  .trust__figures{grid-template-columns:repeat(2,minmax(0,1fr))}
  .trust__figures li:nth-child(2n){border-left:1px solid var(--line)}
  .trust__figures li:nth-child(n+3){border-top:1px solid var(--line)}
  .trust__figures li:nth-child(3){border-left:0}
}

/* ─────────────────────────  language switch  ────────────────── */

.lang{
  display:inline-grid;place-items:center;
  min-width:38px;height:26px;
  padding:0 9px;
  border:1px solid var(--line);border-radius:999px;
  background:var(--paper);
  font:inherit;font-size:11.5px;font-weight:500;letter-spacing:.04em;
  color:var(--muted);
  cursor:pointer;
  transition:color .15s ease,border-color .15s ease;
}
.lang:hover{color:var(--ink);border-color:var(--ink-3)}

/* the catalogue page carries the switch on its own line */
.langbar{border-top:1px solid var(--line)}
.langbar .wrap{
  display:flex;justify-content:flex-end;
  padding:18px clamp(20px,4vw,var(--pad));
}

/* ───────────────────────────  cookies  ─────────────────────── */

/* anchored right on a desktop: the left corner is where the page's own
   content starts, and a notice sitting there reads as part of it */
.cookie{
  position:fixed;z-index:60;
  right:clamp(12px,2vw,20px);bottom:clamp(12px,2vw,20px);
  display:flex;align-items:center;gap:14px;
  max-width:min(420px,calc(100vw - 24px));
  padding:12px 12px 12px 18px;
  border-radius:14px;
  background:rgba(46,46,48,.92);
  -webkit-backdrop-filter:blur(14px) saturate(160%);
          backdrop-filter:blur(14px) saturate(160%);
  box-shadow:0 18px 40px -22px rgba(0,0,0,.6);
  animation:cookieIn .32s cubic-bezier(.2,.7,.25,1) both;
}
.cookie__text{
  margin:0;
  font-size:13.5px;line-height:1.4;
  color:rgba(255,255,255,.9);
}
.cookie__ok{
  flex:none;
  height:34px;padding:0 16px;
  border:0;border-radius:9px;
  background:rgba(255,255,255,.16);
  font:inherit;font-size:13.5px;font-weight:500;
  color:#fff;cursor:pointer;
  transition:background-color .16s ease;
}
.cookie__ok:hover{background:rgba(255,255,255,.26)}
.cookie.is-out{
  opacity:0;transform:translateY(8px);
  transition:opacity .24s ease,transform .24s ease;
}

@keyframes cookieIn{
  from{opacity:0;transform:translateY(10px)}
  to{opacity:1;transform:none}
}
/* on a phone there is no right corner to speak of — it spans the width
   instead, which also stops the text from wrapping to three lines */
@media (max-width:560px){
  .cookie{
    left:clamp(12px,2vw,20px);
    max-width:none;
  }
}

/* ───────────────────  the hero on a desktop  ────────────────
   Sized to the first screen rather than to its content, so the next
   section does not show through the gap under the fold. svh, not vh,
   so a collapsing mobile toolbar cannot make it taller than the screen.
   The Russian lines are what set the type size: "клиентов в решения,"
   has to hold on one line, so the column takes its width first. */
@media (min-width:1025px){
  .hero__inner{
    min-height:calc(100svh - var(--nav-h));
    align-items:center;
    grid-template-columns:minmax(0,1.12fr) minmax(0,1fr);
  }
  .hero__copy{
    padding-block:clamp(40px,4vw,64px);
    padding-right:clamp(20px,2vw,28px);
  }
  .hero__title{font-size:clamp(2.2rem,4.1vw,3.7rem)}
  .hero__lead{font-size:16.5px;max-width:40ch}
}

/* A 900px-tall laptop cannot hold the taller hero, and min-height does
   not shrink content. Rather than let the trust row fall off the screen,
   the artwork is capped by height and the padding gives way first. */
@media (min-width:1025px) and (max-height:920px){
  .hero__copy{padding-block:clamp(20px,2.4vw,32px)}
  .hero__title{font-size:clamp(2rem,3.4vw,3rem)}
  .hero__lead{margin-top:16px}
  .hero__actions{margin-top:24px}
  .trusted{margin-top:clamp(24px,3vw,36px)}
  .viz{max-height:calc(100svh - var(--nav-h) - 64px)}
}

/* ══════════════════════════════════════════════════════════════
   Recovered capability-section rules.

   These were not written by me — they were lost when main.css was
   rewritten, and are lifted verbatim from a snapshot of the sheet
   taken on 12 Aug at 19:21, after the redesign so the tokens match.
   Only selectors the page still uses and nothing else styles are
   included, so nothing here can shadow a newer rule.
   ══════════════════════════════════════════════════════════════ */

/* ─────────────────────────────  footer  ────────────────────── */

.foot__top{
  display:grid;
  grid-template-columns:minmax(0,1.35fr) minmax(0,2fr);
  gap:clamp(32px,5vw,72px);
  padding:clamp(44px,5vw,72px) clamp(24px,4vw,var(--pad));
}
.foot__blurb{
  margin:0;
  max-width:34ch;
  font-size:15px;line-height:1.6;
  color:var(--muted);
}
.foot__social{display:flex;gap:10px;margin-top:26px}
.foot__social a{
  display:grid;place-items:center;
  width:38px;height:38px;
  border:1px solid var(--line);border-radius:999px;
  color:var(--ink-2);background:var(--paper);
  transition:color .16s ease,border-color .16s ease,transform .16s ease;
}
.foot__social svg{
  width:18px;height:18px;
  fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;
}
.foot__social a:hover{color:var(--brand);border-color:var(--brand);transform:translateY(-1px)}
.foot__nav{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(20px,3vw,40px);
}
.foot__col h2{
  margin:0 0 18px;
  font-size:13px;font-weight:400;letter-spacing:0;
  color:var(--faint);
}
.foot__col li + li{margin-top:12px}
.foot__col a{
  font-size:15px;color:var(--ink-2);
  transition:color .15s ease;
}
.foot__col a:hover{color:var(--brand)}
/* the wordmark leads the column, the way it does at the top of the
   page — only much larger, since nothing follows it */
.foot__mark{
  display:block;
  height:clamp(40px,4.6vw,72px);width:auto;
  margin-bottom:clamp(20px,2.4vw,32px);
}
/* ── the dot field ───────────────────────────────────────────────
   The canvas sizes itself from the measured column width, so the
   grid pitch stays constant and it is the number of dots that
   changes with the viewport, never their size. */
.foot__mesh{
  padding:clamp(24px,3vw,44px) clamp(24px,4vw,var(--pad)) clamp(18px,2.2vw,30px);
}
.mesh{display:block;width:100%}
.foot__legal{
  display:flex;flex-wrap:wrap;align-items:center;
  justify-content:space-between;gap:12px 28px;
  padding:22px clamp(24px,4vw,var(--pad));
  font-size:13.5px;color:var(--faint);
}
.foot__legal p{margin:0}
.foot__legal ul{display:flex;flex-wrap:wrap;gap:24px}
.foot__legal a{transition:color .15s ease}
.foot__legal a:hover{color:var(--ink-2)}
@media (max-width:860px){
  .foot__top{grid-template-columns:minmax(0,1fr);gap:40px}
  .foot__nav{gap:28px 20px}
}
@media (max-width:560px){
  .foot__nav{grid-template-columns:repeat(2,minmax(0,1fr))}
  .foot__legal{justify-content:flex-start}
}
.caps__head{
  padding:clamp(56px,8vw,120px) clamp(20px,4vw,var(--pad)) clamp(24px,2.8vw,40px);
}
.caps__title{
  margin:14px 0 0;
  font-size:clamp(1.7rem,3vw,2.4rem);
  line-height:1.22;
  letter-spacing:-.018em;
  font-weight:360;
  color:var(--ink);
}
.caps__grid{
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  align-items:stretch;
  gap:14px;
  padding:0 clamp(24px,4vw,var(--pad)) clamp(44px,5.4vw,76px);
}
.caps__col{display:flex;flex-direction:column;gap:14px;min-width:0}
/* the still fills the card rather than floating in it: the media box
   stretches, and each still centres its own content inside that box */
.cap__media{
  flex:1;min-height:0;
  display:flex;align-items:stretch;justify-content:center;
  padding:clamp(6px,1vw,14px) 0;
}
.cap__name{
  margin:clamp(12px,1.5vw,20px) 0 0;
  font-size:clamp(15.5px,1.2vw,18px);
  line-height:1.28;
  font-weight:500;letter-spacing:-.012em;
  color:var(--ink);
}
/* the sunken plane every still is drawn on */
.mock{
  width:100%;
  display:flex;flex-direction:column;justify-content:center;
  padding:clamp(12px,1.25vw,17px);
  background:var(--sand);
  border:1px solid var(--line);
  border-radius:14px;
}
.mock__cap{
  margin:0 0 13px;
  text-align:center;
  font-size:13px;font-weight:600;letter-spacing:-.01em;
  color:var(--ink-2);
}
/* ── chips ───────────────────────────────────────────────────── */

.pill{
  display:flex;align-items:center;justify-content:center;
  height:34px;padding:0 12px;
  border-radius:999px;
  border:1px solid transparent;
  background:var(--sunk);
  font-size:12.5px;font-weight:500;letter-spacing:-.01em;
  color:var(--muted);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.pill.is-on{
  background:var(--paper);border-color:var(--line);color:var(--ink);
  box-shadow:0 1px 2px rgba(23,23,26,.07);
}
.pills{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
.tone .pill{
  animation:pillOn var(--cycle) linear infinite both;
  animation-delay:calc(var(--i,0)*var(--step));
}
/* Same walk on a shorter list: a quarter of the loop each, a third
   each. The numbers in the keyframes are those fractions minus the
   1.4% it takes to swap, so the change stays crisp. */
.cyc4 .pill{
  animation:pillOn4 var(--cycle) linear infinite both;
  animation-delay:calc(var(--i,0)*var(--cycle)/4);
}
/* ── extra stills ────────────────────────────────────────────── */

/* the footing line every folded still ends on: label left, figure right */
.tkt{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:13px 0 0;padding-top:12px;
  border-top:1px solid var(--line);
  font-size:12.5px;color:var(--muted);
}
.tkt b{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
/* price watch */
.watch{display:grid;gap:9px}
.watch li{
  display:flex;align-items:center;gap:10px;
  font-size:12.5px;color:var(--muted);
}
.watch b{margin-left:auto;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.watch em{
  flex:none;width:44px;
  justify-items:end;
  font-style:normal;font-size:12px;font-weight:600;
  font-variant-numeric:tabular-nums;
}
.watch .dn{color:var(--pos)}
.watch .up{color:var(--neg)}
/* Two readings stacked in one cell: the outgoing one leaves through the
   top as the next arrives from below, and the box is only ever one line
   tall, so nothing in the row moves. Rows are offset by --r to stop all
   three flipping on the same beat. */
.roll{
  /* --r must exist here even though no row sets it. The delay below
     multiplies it, and an unset custom property poisons the whole calc:
     var(--r,0)'s fallback does NOT rescue it, the declaration is dropped
     and both figures start at 0s, printing one on top of the other.
     Measured in the browser: --r absent -> delay 0s, --r:0 -> 4s. */
  --r:0;
  display:inline-grid;
  overflow:hidden;
  height:1.35em;line-height:1.35em;
}
.roll i{
  grid-area:1/1;
  font-style:normal;
  animation:rollUp 8s cubic-bezier(.5,0,.2,1) infinite both;
  animation-delay:calc(var(--i,0)*4s - var(--r,0)*.9s);
}
/* templates — the lit row walks the list, a third of the cycle each */
.tpl{display:grid;gap:7px}
.tpl li{
  display:flex;align-items:center;gap:9px;
  padding:9px 10px;
  border:1px solid transparent;border-radius:10px;
  background:var(--sunk);
  font-size:12.5px;line-height:1.25;color:var(--muted);
}
.tpl__key{
  flex:none;
  padding:2px 7px;border-radius:6px;
  background:var(--paper);
  font-family:'JetBrains Mono',ui-monospace,monospace;
  font-size:11px;font-weight:500;color:var(--brand);
}
.cyc3 .tpl li{
  animation:rowOn3 var(--cycle) linear infinite both;
  animation-delay:calc(var(--i,0)*var(--cycle)/3);
}
/* buyer questions — the answer lands a beat behind the question and both
   hold for the rest of the loop, so the card reads as a queue clearing */
.qa{gap:9px}
.qa__row{
  display:flex;gap:9px;
  margin:0;
  font-size:12.5px;line-height:1.45;color:var(--muted);
  animation:qaIn 9s cubic-bezier(.16,1,.3,1) infinite both;
}
.qa__row--a{animation-delay:1.1s}
.qa__row--a{color:var(--ink-2)}
.qa__row em{color:var(--faint);font-style:normal}
.qa__badge{
  display:grid;place-items:center;
  width:20px;height:20px;flex:none;
  border-radius:6px;
  background:var(--sunk);
  font-size:10.5px;font-weight:700;color:var(--muted);
}
.qa__badge--a{background:var(--brand);color:#fff}
/* survey scale */
.nps{display:grid;grid-template-columns:repeat(11,minmax(0,1fr));gap:4px}
.nps span{
  display:grid;place-items:center;
  height:30px;
  border-radius:7px;
  background:var(--sunk);
  font-size:11.5px;font-weight:500;color:var(--muted);
  font-variant-numeric:tabular-nums;
  animation:npsWave 6s ease-in-out infinite both;
  animation-delay:calc(var(--i,0)*90ms);
}
.nps .is-on{background:var(--brand);color:#fff;font-weight:600}
/* first-line chat */
.chat{gap:9px}
.chat__msg{
  max-width:86%;
  margin:0;padding:10px 12px;
  border-radius:12px 12px 12px 4px;
  background:var(--sunk);
  font-size:12.5px;line-height:1.45;color:var(--muted);
}
.chat__msg--out{
  margin-left:auto;
  border-radius:12px 12px 4px 12px;
  background:var(--paper);
  border:1px solid var(--line);
  color:var(--ink-2);
  animation:chatIn 9s cubic-bezier(.16,1,.3,1) infinite both;
}
.chat__who{
  display:block;margin-bottom:3px;
  font-size:10px;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;color:var(--brand);
}
.vs .is-you{color:var(--ink-2)}
.vs .is-you i::before{background:var(--brand)}
.vs .is-you b{color:var(--ink)}
/* the row that needs someone to look at it, in the same red the charts
   already use for negative sentiment */
.vs .is-low i::before{background:var(--neg)}
/* an alert is addressed to the team, not sent by them — the bubble
   keeps the label but drops the right-hand alignment */
.chat--wide .chat__msg--out{margin-left:0;max-width:100%}
/* ── learn more ──────────────────────────────────────────────── */

/* The snapshot this was recovered from drove the fold with a hidden
   checkbox. The markup has since moved to a real button that toggles
   .is-open, so the rules below follow that instead — the old
   :checked selectors matched nothing and left the extra cards
   permanently hidden behind an invisible 1px control. */

/* the section's bottom air moves from the grid onto the button row */
.caps__grid{padding-bottom:clamp(20px,2.2vw,30px)}
.caps__more{
  display:flex;justify-content:center;
  margin:0;
  padding:0 clamp(24px,4vw,var(--pad)) clamp(44px,5.4vw,76px);
}
.caps__more .lbl-less{display:none}
.caps.is-open .lbl-more{display:none}
.caps.is-open .lbl-less{display:inline}
.caps.is-open .chev{transform:rotate(180deg)}

/* Collapsing on grid-template-rows rather than max-height: the closed
   height is honestly zero and the open one is whatever the cards need,
   so nothing has to guess a ceiling. Only applied once the script has
   marked itself present — without it the extra cards simply stay open,
   which is the right no-JS answer. */
.caps.is-ready .cap-fold{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .62s cubic-bezier(.16,1,.3,1),
             margin-top .62s cubic-bezier(.16,1,.3,1);
  /* the column's own gap would otherwise show under the last card
     while the fold is empty */
  margin-top:-14px;
}
.caps.is-ready.is-open .cap-fold{grid-template-rows:1fr;margin-top:0}
.cap-fold__in{
  overflow:hidden;min-height:0;
  display:flex;flex-direction:column;gap:14px;
}
/* the column tightens below 720px, and the gap the fold cancels has to
   tighten with it */
@media (max-width:720px){
  .caps.is-ready .cap-fold{margin-top:-12px}
  .cap-fold__in{gap:12px}
}
.caps.is-open .cap--more{
  animation:capIn .55s cubic-bezier(.16,1,.3,1) both;
  animation-delay:calc(var(--i,0)*55ms);
}
.chev{
  width:11px;height:8px;flex:none;
  fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;
  transition:transform .22s ease;
}
/* ── review stills ───────────────────────────────────────────── */

/* stars, flag and timestamp wrap rather than push the date out of the
   panel on a narrow card */
.rev__top{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px;margin-bottom:11px}
.rev__date{margin-left:auto;font-size:11.5px;color:var(--faint);white-space:nowrap}
.rate{display:inline-flex;gap:2.5px}
.rate svg{width:13px;height:13px;fill:#D4D3D0}
.rate svg.on{fill:var(--neu)}
.flag{
  display:inline-flex;align-items:center;gap:6px;
  height:24px;padding:0 10px;
  border-radius:999px;
  background:#FBEDED;border:1px solid color-mix(in srgb,var(--neg) 30%,transparent);
  color:var(--neg);
  font-size:11.5px;font-weight:600;letter-spacing:-.01em;
  white-space:nowrap;
}
.flag svg{
  width:12px;height:12px;flex:none;
  fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;
}
.rev__text{
  margin:0;
  font-size:13.5px;line-height:1.55;
  color:var(--ink-2);
}
/* Highlight sweeps in on scroll. The finished state is the default
   and the animation runs from empty, so a browser without a view()
   timeline shows the highlight rather than nothing. The underline
   is the second channel: solid under praise, dashed under a
   complaint, so the two never rest on hue alone. */
.hl{
  padding:0 2px;
  -webkit-box-decoration-break:clone;
          box-decoration-break:clone;   /* a wrapped span keeps both ends */
  border-radius:3px;
  color:var(--ink);
  background-color:transparent;
  background-image:linear-gradient(var(--hl),var(--hl));
  background-repeat:no-repeat;
  background-size:100% 100%;
}
.hl--pos{--hl:rgba(15,143,102,.15);border-bottom:2px solid var(--pos)}
.hl--neg{--hl:rgba(208,59,59,.14);border-bottom:2px dashed var(--neg)}
.ghostbtn{
  display:inline-flex;align-items:center;align-self:flex-start;
  margin-top:14px;height:32px;padding:0 14px;
  border-radius:999px;
  background:var(--paper);border:1px solid var(--line);
  font-size:12.5px;font-weight:600;letter-spacing:-.01em;
  color:var(--ink-2);
}
/* ── dashboards ──────────────────────────────────────────────── */

.dash{display:flex;flex-direction:column;justify-content:center;gap:12px;width:100%}
.dash__cap{
  margin:0 0 10px;
  display:flex;align-items:baseline;gap:8px;
  font-size:12.5px;font-weight:600;letter-spacing:-.01em;
  color:var(--ink-2);
}
.dash__sub{font-weight:500;color:var(--faint);font-size:11px}
.topics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(10px,1.2vw,18px)}
.topic__cap{
  margin:0 0 8px;
  font-size:12px;font-weight:600;letter-spacing:-.01em;
  color:var(--ink-2);
}
.donut{display:block;width:100%;max-width:118px;margin:0 auto;height:auto}
.donut__track{fill:none;stroke:#DFDEDD;stroke-width:13}
.donut circle.seg{fill:none;stroke-width:13}
.legend{margin:10px 0 0;display:grid;gap:5px}
.legend li{
  display:flex;align-items:center;gap:7px;
  font-size:10.5px;letter-spacing:-.01em;
  color:var(--muted);
}
.legend i{width:8px;height:8px;flex:none;border-radius:2.5px;background:var(--sw)}
.legend b{margin-left:auto;font-weight:600;color:var(--ink-2);font-variant-numeric:tabular-nums}
.legend--row{display:flex;flex-wrap:wrap;gap:6px 16px;margin-top:8px}
.legend--row li{gap:6px}
.legend--row b{margin-left:4px}
/* the charts are drawn at roughly the size they are read at, so the
   cap keeps a wide panel from scaling the tick labels up with it */
.chart{display:block;width:100%;max-width:420px;margin-inline:auto;height:auto;overflow:visible}
.ch-grid{stroke:var(--grid);stroke-width:1}
.ch-axis{stroke:var(--ax);stroke-width:1}
.ch-cat{fill:var(--faint);font-size:10.5px;font-weight:500}
.ch-tick{fill:var(--faint);font-size:9.5px;font-weight:500}
.ch-val{fill:var(--ink-2);font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}
.bar--pos{fill:var(--pos)}
.bar--neu{fill:var(--neu)}
.bar--neg{fill:var(--neg)}
/* stacked bands, each parted from the next by a 2px stroke in the
   panel colour — that gap is what keeps the boundary readable when
   two fills sit straight against each other. The bands keep the
   full-strength trio so the legend swatch and the fill are the same
   colour, with no lightened stand-in in between. */
.area--pos{fill:var(--pos)}
.area--neu{fill:var(--neu)}
.area--neg{fill:var(--neg)}
.edge{fill:none;stroke:var(--sand);stroke-width:2}
@media (prefers-reduced-motion:reduce){
  /* the tone chips cycle forever and have no meaningful end state —
     freeze the fourth one lit, the way the band freezes its first
     source */
  .tone .pill{animation:none !important}
  .tone .pill[style*="--i:3"]{
    background:var(--paper);border-color:var(--line);color:var(--ink);
    box-shadow:0 1px 2px rgba(23,23,26,.07);
  }
  /* the folded stills have the same problem, and the support reply would
     be zeroed out altogether — it ends its loop faded */
  .cyc4 .pill,.cyc3 .tpl li,.chat__msg--out,.nps span,
  .roll i,.qa__row,.vs i::before{animation:none !important}
  /* both readings share one cell, so the second has to be dropped once
     the roll that hid it is gone */
  .roll i + i{opacity:0}
  .cyc4 .pill[style*="--i:1"]{
    background:var(--paper);border-color:var(--line);color:var(--ink);
    box-shadow:0 1px 2px rgba(23,23,26,.07);
  }
  .cyc3 .tpl li[style*="--i:1"]{
    background:var(--paper);border-color:var(--line);color:var(--ink);
  }
}
@media (max-width:1024px){
  .caps__grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .caps__col--wide{grid-column:1/-1}
  /* the column now runs the full width, so its two short cards pair up
     under the charts rather than each stretching a chat bubble or a set
     of bars across the whole block */
  .caps__col--wide{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}
  .caps__col--wide > .cap:first-child{grid-column:1/-1}
  /* the charts card is now the full width of the block, so its three
     panels share the row instead of stacking */
  .caps__col--wide .dash{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.35fr);
  }
  .caps__col--wide .topics{grid-column:1/-1}
  /* wide card, so the ring and its list sit side by side instead of
     stacking — otherwise the list stretches the width of the column
     and the values drift away from their labels */
  .caps__col--wide .topic{
    display:grid;
    grid-template-columns:auto minmax(0,1fr);
    grid-template-areas:"cap cap" "ring list";
    justify-content:start;align-items:center;
    gap:8px clamp(12px,1.6vw,20px);
  }
  .caps__col--wide .topic__cap{grid-area:cap}
  .caps__col--wide .donut{grid-area:ring;width:96px;margin:0}
  .caps__col--wide .legend{grid-area:list;max-width:240px;margin-top:0}
}
@media (max-width:720px){
  .caps__grid{grid-template-columns:minmax(0,1fr);gap:12px}
  .caps__col{gap:12px}
  .caps__col--wide .dash{grid-template-columns:minmax(0,1fr)}
  /* one ring per row now: side by side there is no longer room for a
     96px ring and a labelled list twice over */
  .caps__col--wide .topics{grid-template-columns:minmax(0,1fr);gap:16px}
  .caps__col--wide .legend{max-width:none}
  .cap__name{font-size:18px}
  .pills{gap:7px}
  .rev__text{font-size:13px}
}
/* review mock author -------------------------------------------- */
.rev__ava{
  width:22px;height:22px;flex:none;
  border-radius:50%;
  background:#EDECEA;
}
/* ─────────────────────────────  quote  ─────────────────────────── */

.quote__inner{
  margin:0;
  max-width:760px;
  margin-inline:auto;
  padding:clamp(64px,9vw,140px) clamp(20px,4vw,var(--pad));
  text-align:center;
}
.quote__text{margin:0}
.quote__text p{
  margin:0;
  font-size:clamp(1.15rem,2.1vw,1.7rem);
  line-height:1.42;
  letter-spacing:-.014em;
  font-weight:360;
  color:var(--ink);
  text-wrap:balance;
}
.quote__by{
  display:flex;align-items:center;justify-content:center;gap:12px;
  margin-top:clamp(28px,3.4vw,44px);
}
.quote__ava{
  width:52px;height:52px;flex:none;
  border-radius:50%;
  object-fit:cover;
  background:var(--chip);
}
.quote__who{
  display:flex;flex-direction:column;align-items:flex-start;
  font-size:14.5px;line-height:1.45;
  color:var(--muted);
  text-align:left;
}
.quote__who b{font-weight:500;color:var(--ink)}
/* a full-bleed still inside a capability card: the render carries its
   own white ground, so it meets the card edge without a seam */
.cap__shot{
  display:block;
  /* height:auto let the aspect ratio decide, so in a card whose media
     box came out shorter than the render wanted, the image simply grew
     past the panel and shoved itself against the caption — 57px over on
     a 1440 column. Bounded by the box and fitted inside it instead; the
     render carries its own white ground, so contain leaves no seam. */
  width:100%;height:100%;
  min-height:0;
  object-fit:contain;
  margin:auto;
  border-radius:var(--r);
}

/* keyframes those rules drive */
@keyframes pillOn4{
  0%    {background:#EAE9E7;border-color:transparent;color:#6C6C75;box-shadow:none}
  2%,23%{background:#FFFFFF;border-color:#E4E3E2;color:#17171A;box-shadow:0 1px 2px rgba(23,23,26,.07)}
  25%,100%{background:#EAE9E7;border-color:transparent;color:#6C6C75;box-shadow:none}
}
/* The two values are half a cycle apart, so each has to stay up for a
   little MORE than half of one: at 4%–46% the outgoing figure had gone
   before the incoming one arrived and the slot sat empty for 450ms
   every cycle. Now they overlap briefly, which is the roll itself —
   one leaving upward as the next comes in from below. */
@keyframes rollUp{
  0%      {opacity:0;transform:translateY(105%)}
  3%,49%  {opacity:1;transform:none}
  55%     {opacity:0;transform:translateY(-105%)}
  100%    {opacity:0;transform:translateY(-105%)}
}
@keyframes rowOn3{
  0%      {background:#EAE9E7;border-color:transparent;color:#6C6C75}
  2%,31%  {background:#FFFFFF;border-color:#E4E3E2;color:#17171A}
  33%,100%{background:#EAE9E7;border-color:transparent;color:#6C6C75}
}
@keyframes qaIn{
  0%,3%   {opacity:0;transform:translateY(9px)}
  13%,92% {opacity:1;transform:none}
  100%    {opacity:0;transform:translateY(9px)}
}
@keyframes npsWave{
  0%,72%,100%{transform:none}
  80%        {transform:translateY(-3px)}
}
@keyframes capIn{
  from{opacity:0;transform:translateY(16px)}
  to  {opacity:1;transform:none}
}

/* ══════════════════════════════════════════════════════════════
   Written fresh, not recovered.

   These blocks were lost with no copy left anywhere — no snapshot
   holds them — so they are rebuilt from the markup and the JS
   contract rather than restored. They follow the page's own
   measurements: the ink ramp, 999px pills, and the same clamp()
   rhythm as every other section.
   ══════════════════════════════════════════════════════════════ */

/* ─────────────────────────  the closing ask  ─────────────────── */

/* A tinted band, so the last question on the page does not read as a
   footnote to the FAQ above it. Centred, unlike the rest of the page:
   there is one thing to do here and nothing to scan past it. */
.finale{background:var(--bg-2)}
.finale .wrap{padding:clamp(64px,9vw,124px) clamp(20px,4vw,var(--pad))}
.finale__inner{max-width:720px;margin-inline:auto;text-align:center}

.finale__eyebrow{margin:0}

.finale__title{
  margin:14px 0 0;
  font-size:clamp(1.9rem,3.6vw,2.9rem);
  line-height:1.18;
  letter-spacing:-.022em;
  font-weight:360;
  color:var(--ink);
}

.finale__lead{
  margin:18px auto 0;
  max-width:44ch;
  font-size:16.5px;line-height:1.6;
  color:var(--muted);
}

.finale__actions{
  display:flex;flex-wrap:wrap;
  align-items:center;justify-content:center;
  gap:12px;
  margin:clamp(26px,3.4vw,38px) 0 0;
}

.finale__fine{
  margin:18px 0 0;
  font-size:13.5px;line-height:1.5;
  color:var(--faint);
}

.finale__wa{width:17px;height:17px;flex:none;fill:currentColor}

/* the quieter of the two: a hairline rather than a fill, so the pair
   reads as one ask and one way out of it */
.btn--outline{
  background:var(--paper);
  border-color:var(--ink-3);
  color:var(--ink);
  transition:border-color .16s ease,background-color .16s ease;
}
.btn--outline:hover{border-color:var(--ink);background:var(--paper)}

@media (max-width:560px){
  .finale__actions{flex-direction:column;align-items:stretch}
  .finale__actions .btn{width:100%}
}

/* ───────────────────────  the demo dialog  ──────────────────── */

/* The dialog box itself is defined in restore-2.css, which loads after
   this file. The copy that stood here was fully overridden, so it is
   gone rather than kept as a second answer to the same question. */

.lead__card{
  position:relative;
  max-height:calc(100svh - 32px);
  overflow-y:auto;
  overscroll-behavior:contain;
  padding:clamp(22px,3.4vw,30px);
  border-radius:22px;
  background:var(--paper);
  box-shadow:0 40px 80px -40px rgba(0,0,0,.42);
  text-align:left;
}

.lead__x{
  position:absolute;top:14px;right:14px;
  display:grid;place-items:center;
  width:32px;height:32px;
  border:0;border-radius:999px;
  background:var(--chip);
  cursor:pointer;
  transition:background-color .16s ease;
}
.lead__x:hover{background:var(--chip-h)}
.lead__x svg{
  width:11px;height:11px;
  fill:none;stroke:var(--ink-2);stroke-width:1.6;stroke-linecap:round;
}

/* who is on the other end, before anything is asked of the reader */
.lead__who{display:flex;align-items:center;gap:11px;padding-right:38px}
/* .lead__ava is defined in restore-2.css, which loads after this file and
   owns the photo and the presence dot. The copy that stood here drew a
   second monogram into the dot, so it is gone rather than duplicated. */
.lead__id{display:flex;flex-direction:column;gap:1px;min-width:0}
.lead__id b{font-size:14.5px;font-weight:600;letter-spacing:-.01em;color:var(--ink)}
.lead__id > span{font-size:12.5px;line-height:1.4;color:var(--muted)}

.lead__title{
  margin:clamp(16px,2vw,20px) 0 0;
  font-size:clamp(1.2rem,2.2vw,1.45rem);
  line-height:1.26;
  letter-spacing:-.018em;
  font-weight:500;
  color:var(--ink);
}

/* a message, not a paragraph — the corner nearest the sender is the
   one that stays square */
.lead__bubble{
  margin:12px 0 0;
  padding:13px 15px;
  border-radius:14px 14px 14px 4px;
  background:var(--bg-2);
  font-size:14.5px;line-height:1.55;
  color:var(--ink-2);
}
.lead__bubble--plain{
  border-radius:14px;
  background:transparent;
  padding:0;
  color:var(--muted);
  text-align:center;
}
.lead__bubble--plain b{color:var(--ink);font-weight:600;white-space:nowrap}

.lead__form{margin:clamp(18px,2.4vw,22px) 0 0}
.lead__label{
  display:block;
  margin:0 0 7px;
  font-size:12.5px;font-weight:500;letter-spacing:-.004em;
  color:var(--ink-2);
}

/* the code and the number are one field split in two, so the ring on
   focus belongs to the row rather than to either half */
.lead__row{
  display:flex;align-items:stretch;
  border:1px solid var(--ink-3);border-radius:11px;
  background:var(--paper);
  overflow:hidden;
  transition:border-color .16s ease,box-shadow .16s ease;
}
.lead__row:focus-within{
  border-color:var(--brand);
  box-shadow:0 0 0 3px rgba(125,98,255,.16);
}
.lead__row.is-bad{border-color:#D8574B;box-shadow:0 0 0 3px rgba(216,87,75,.14)}

/* .lead__cc is defined in restore-2.css, which loads after this file and
   re-declares every property here except appearance. The copy that stood
   here paired appearance:none with a chevron of its own; the later rule
   overwrote the chevron and kept the appearance, which left the country
   selector with no arrow at all — a bold "RU +7" that read as a fixed
   prefix rather than a control with four options behind it. Removed so
   the native caret comes back, which is what the later padding expects. */
.lead__cc:focus{outline:none}

.lead__in{
  flex:1;min-width:0;
  height:46px;padding:0 14px;
  border:0;
  background:transparent;
  font:inherit;font-size:15px;color:var(--ink);
}
.lead__in::placeholder{color:var(--faint)}
.lead__in:focus{outline:none}

/* the name field is a lone input, so it carries the frame itself */
.lead__form > .lead__in{
  display:block;width:100%;
  border:1px solid var(--ink-3);border-radius:11px;
  background:var(--paper);
  transition:border-color .16s ease,box-shadow .16s ease;
}
.lead__form > .lead__in:focus{
  border-color:var(--brand);
  box-shadow:0 0 0 3px rgba(125,98,255,.16);
}
.lead__form > .lead__in.is-bad{border-color:#D8574B;box-shadow:0 0 0 3px rgba(216,87,75,.14)}

.lead__hint{
  margin:8px 0 16px;
  font-size:12.5px;line-height:1.45;
  color:var(--muted);
}
.lead__hint [data-hint-bad]{color:#C1483D}

.lead__go{
  display:flex;align-items:center;justify-content:center;gap:9px;
  width:100%;height:50px;
  margin:18px 0 0;
  border:0;border-radius:999px;
  background:var(--brand);
  font:inherit;font-size:15.5px;font-weight:500;letter-spacing:-.006em;
  color:#fff;cursor:pointer;
  transition:background-color .16s ease;
}
.lead__go:hover{background:var(--brand-ink)}
.lead__wa{width:19px;height:19px;flex:none;fill:currentColor}

.lead__note{
  display:flex;align-items:flex-start;gap:7px;
  margin:11px 0 0;
  font-size:12.5px;line-height:1.45;
  color:var(--faint);
}
.lead__note svg{
  width:12px;height:14px;flex:none;margin-top:1px;
  fill:none;stroke:currentColor;stroke-width:1.3;
  stroke-linecap:round;stroke-linejoin:round;
}

.lead__alt{
  display:block;
  margin:16px 0 0;
  font-size:13.5px;
  color:var(--brand-ink);
  text-decoration:none;
}
.lead__alt:hover{text-decoration:underline}

.lead__foot{
  margin:16px 0 0;
  padding-top:14px;
  border-top:1px solid var(--line);
  font-size:13px;
  color:var(--muted);
}
.lead__foot a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--ink-3)}
.lead__foot a:hover{border-bottom-color:var(--ink)}

/* the confirmation replaces the card's contents rather than the card */
.lead__done{text-align:center;padding:clamp(8px,1.6vw,16px) 0}
.lead__done .lead__title{margin-top:16px}
.lead__tick{
  display:grid;place-items:center;
  width:52px;height:52px;margin:0 auto;
  border-radius:999px;
  background:var(--brand-soft);
}
.lead__tick svg{
  width:24px;height:24px;
  fill:none;stroke:var(--brand-ink);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;
}
.lead__back{
  height:44px;padding:0 26px;
  margin:20px 0 0;
  border:0;border-radius:999px;
  background:var(--chip);
  font:inherit;font-size:15px;font-weight:500;color:var(--ink);
  cursor:pointer;
  transition:background-color .16s ease;
}
.lead__back:hover{background:var(--chip-h)}

@keyframes leadIn{
  from{opacity:0;transform:translateY(14px) scale(.985)}
  to{opacity:1;transform:none}
}
@keyframes leadFade{from{opacity:0}to{opacity:1}}

/* ──────────────────  the qr still in the fold  ──────────────── */

.qr__row{
  display:flex;align-items:center;
  gap:clamp(14px,1.8vw,20px);
}
.qr__svg{
  flex:none;
  width:clamp(78px,7.4vw,94px);height:auto;
  fill:var(--ink);stroke:var(--ink);
}
.qr__side{display:flex;flex-direction:column;gap:9px;min-width:0}
.qr__lead{
  margin:0;
  font-size:13px;line-height:1.4;
  color:var(--ink-2);
}

/* five pips that light in turn, the way the card is actually filled in */
.qr__stars{display:inline-flex;gap:3px}
.qr__stars i{
  width:12px;height:12px;
  background:var(--ink-3);
  clip-path:polygon(50% 0,61.8% 35.5%,98% 35.5%,69% 57.5%,80% 91%,50% 70%,20% 91%,31% 57.5%,2% 35.5%,38.2% 35.5%);
  animation:qrStar 3.4s steps(1,end) infinite;
  animation-delay:calc(var(--i,0)*180ms);
}

.qr__voice{display:inline-flex;align-items:center;gap:8px}
.qr__mic{
  display:grid;place-items:center;
  width:24px;height:24px;flex:none;
  border-radius:999px;
  background:var(--brand-soft);
}
.qr__mic svg{
  width:13px;height:13px;
  fill:none;stroke:var(--brand-ink);stroke-width:1.4;
  stroke-linecap:round;stroke-linejoin:round;
}
.qr__voice b{
  font-size:12px;font-weight:500;
  color:var(--muted);
  font-variant-numeric:tabular-nums;
}

.wave{display:inline-flex;align-items:center;gap:2.5px;height:16px}
.wave i{
  width:2.5px;height:100%;
  border-radius:2px;
  background:var(--ink-3);
  transform:scaleY(.34);
  animation:qrWave 1.15s ease-in-out infinite alternate;
  animation-delay:calc(var(--i,0)*90ms);
}

@keyframes qrStar{
  0%,100%{background:var(--ink-3)}
  18%,92%{background:#E8A93C}
}
@keyframes qrWave{
  from{transform:scaleY(.3)}
  to{transform:scaleY(1)}
}

/* ── the sources card turns the same page as the other three ─────
   Card 1 carries one frame per trade now, in the same order and on the
   same clock as the .vstack cards beside it, so the row of logos always
   belongs to the trade the rest of the row is talking about.

   Deliberately not .vstack: that wrapper pads its frames, and both
   children here — the connector row and the feed — are positioned
   against the art, so the padding would push them off their marks. */
.srcstack{position:absolute;inset:0;display:grid}
.srcstack > .v{
  grid-area:1/1;
  animation:vSwap var(--vcycle) ease-in-out infinite both;
  animation-delay:calc(var(--i,0) * var(--vstep));
}

/* A frame is on screen for about 3.5s of its 4.5s slot. The two inner
   loops were written for a row that never changed and run on 9s, which
   inside that window would cut the lighting sequence in half and start
   each trade on a different beat. Both are folded onto the frame so
   every trade plays the same short sequence from the top. */
.srcstack .src__row{--cycle:4.5s;--slot:.62s}
.srcstack .feed__row{animation-duration:4.5s}

/* ── the trend the chat says it is building ──────────────────────
   The working line above promises «Строю график» and what used to land
   under it was a table, which is the one thing a chart is not. This is
   the chart: thirty points, one per day, as a path. --neg is declared
   on .caps and the chat window is not inside it, so the badge carries
   the value as a fallback the way the dialog does. */
.awin__chart{
  margin:0;
  padding:13px 14px 10px;
  border:1px solid var(--line);
  border-radius:12px;
  background:var(--paper);
}
.awin__chart figcaption{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto;
  align-items:center;
  gap:2px 12px;
  margin-bottom:12px;
}
.awin__chartname{
  grid-area:1/1;
  font-size:13.5px;font-weight:600;letter-spacing:-.01em;
  color:var(--ink);
}
.awin__chartsub{
  grid-area:2/1;
  font-size:11.5px;line-height:1.35;
  color:var(--faint);
}
/* the figure reads against both lines at once, so it spans them */
.awin__chartdelta{
  grid-area:1/2/3/3;
  padding:3px 9px;
  border-radius:999px;
  background:color-mix(in srgb,var(--neg,#B92E2E) 10%,transparent);
  font-size:11.5px;font-weight:600;
  color:var(--neg,#B92E2E);
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}

.awin__plot{
  display:block;width:100%;height:auto;
  /* the dot marks the last point, which sits on the right edge of the
     plot — clipping it to the viewBox would cut it in half */
  overflow:visible;
}
.awin__area{fill:url(#awinTrend)}
.awin__line{
  fill:none;stroke:var(--brand);stroke-width:2;
  stroke-linejoin:round;stroke-linecap:round;
  /* the card is wider than the viewBox, and a scaled 2px stroke reads as
     a marker pen */
  vector-effect:non-scaling-stroke;
}
.awin__tip{fill:var(--brand);stroke:var(--paper);stroke-width:2}
