/* ds-site-fixes.css — the design passes made AFTER the site shipped.

   ⛔ WHY A SEPARATE FILE. `ds-site-extra.css` is 160 KB, and the live channel
   (MCP `nct_globalresource_update`) replaces a resource WHOLE: a fix of ten lines
   meant re-sending the entire stylesheet, which is how a stand drifts from the
   export one botched paste at a time. This file is small enough to send whole,
   loads right after `ds-site-extra.css` (order 3, see build-plan/12_assets_register.py),
   and so wins any tie it needs to without `!important` games. Numbering continues
   ds-site-extra.css's. */

/* -- 49 ------------------------------------------------------------------
   THE DESIGN PASS OF 2026-10-01 — seven faults found by looking at every page,
   both skins, at 390 and 1440. Each one measured on devsegment.com first.

   (a) THE HERO HAD NO GUTTER ON A PHONE. `.container-fluid.px-0` around the
       carousel leaves the copy to `ps-2` / `ms-2`: the eyebrow sat 8px from the
       left edge, the body 16px, and the paragraph's right edge was 0px from the
       screen. One gutter for the whole slide — 12px, the gutter every section
       under it already uses, so the left edges line up down the page — and the eyebrow on the same line
       as everything under it.
   (b) AND THE EYEBROW WAS OFF THE COPY'S LINE AT EVERY WIDTH: it lives outside
       the `ms-2 ms-md-6` wrapper, so it started 8px (phone) / 24px (desktop)
       left of the headline. On a phone it was also 32px against a 40px
       headline — two headlines. It steps down there.
   (c) THE SLIDE COUNTER TOUCHED THE BUTTONS — 0px between the pill row's
       bottom (743) and the "01 / 04" row's top (743), measured at 1440. */
@media (max-width: 767px) {
  .ds-app .banner-section.index-one .banner-translate-carousel .d-flex.flex-column.ps-2 {
    padding-left: 12px !important; padding-right: 12px !important;
  }
  .ds-app .banner-section.index-one .banner-translate-carousel .ms-2 { margin-left: 0 !important; }
  .ds-app .banner-section.index-one .title-small { font-size: 22px !important; line-height: 1.25; }
}
@media (min-width: 768px) {
  .ds-app .banner-section.index-one .title-small { margin-left: 24px; }
}
.ds-app .banner-section .pagination-with-btn { margin-top: 28px; }

/* (d) THE CLOSING WORDMARK RAN EDGE TO EDGE. 6.4vw of an uppercase string is
       the whole viewport: 388px of 390 on a phone, the full 1440 on a laptop,
       touching both edges on all 32 pages. A wordmark needs air around it to
       read as one. */
.ds-app .footer_section [data-ds-tagline] {
  font-size: clamp(18px, 5.2vw, 104px);
  padding-inline: 16px;
}

/* (e) A BLACK BAR UNDER THE SOCIAL ICONS. Their `.social_info::before` is a
       50% black plate meant for the hero's photo rail; in the footer it drew a
       dark rectangle behind the four circles, in both skins. */
.ds-app .footer_section .social_info::before { display: none; }

/* (f) THE CLOSING BAND TURNED NAVY IN THE LIGHT SKIN. §18 fades to `--p12`,
       which is 16,27,44 in BOTH skins, under copy that is `--p8` — dark ink in
       light. The bottom third was dark text on a slate-blue smear. The light
       skin keeps the bloom and fades to a deeper step of its own ground. */
.ds-app:not(.dark) .dicscuss_projects.parallax {
  background-image:
    radial-gradient(110% 150% at 50% 130%, rgba(var(--p1), .16) 0%, rgba(var(--p1), 0) 62%),
    linear-gradient(180deg, rgba(var(--p7), .35) 0%, rgba(var(--p1), .08) 100%) !important;
}

/* (g) A SECTION'S BUTTON SAT ON ITS LAST FEATURE — 0px between `.ds-features`
       and the `.btn-area` under it ("See what it builds", "See the products",
       "How we work"). */
.ds-app .ds-features + .btn-area { margin-top: 28px; }
@media (min-width: 992px) { .ds-app .ds-features + .btn-area { margin-top: 36px; } }

/* (h) THE PLAN BUTTONS DID NOT LINE UP. Business lists seven features and the
       other two six, so its button sat 25px lower than its neighbours. The card
       is a column and the list takes the slack. */
.ds-app .pricing_section { height: 100%; }          /* the column stretches; the card did not */
.ds-app .pricing_section > div { display: flex; flex-direction: column; }
.ds-app .pricing_section > div > ul { flex: 1 1 auto; }

/* (i) THE NEWSLETTER'S ENVELOPE AND HINT WERE INK ON A DARK BAND. The footer is
       dark in both skins, but the glyph is `p4-color` and the placeholder its
       tone too — in the light skin that is 60,80,104 on the 22,104,171 circle
       and on the navy field: there, but unreadable. */
.ds-app .footer_section .newsletter .icon-area i { color: rgba(255, 255, 255, .95) !important; }
.ds-app .footer_section .newsletter input::placeholder { color: rgba(255, 255, 255, .55) !important; }

/* -- 50 ------------------------------------------------------------------
   THE PHONE, LOOKED AT AGAIN AFTER §49 WENT LIVE (2026-10-01).

   (a) THE LEGAL ROW BROKE AROUND ITS SEPARATORS. Russian and Armenian labels
       are long, so at 390px "Вход" wrapped to its own line and left a "|"
       hanging at the end of the line above it. Below 576px the pipes go and
       the links are spaced and centred instead — a wrap then reads as a wrap.
   (b) THE FORM'S SUBMIT WAS A 175px PILL ON A 390px SCREEN — the one control
       the page exists for, narrower than every field above it. Full width.
   (c) THE reCAPTCHA LINKS WERE A SIZE SMALLER THAN THE SENTENCE AROUND THEM. */
@media (max-width: 575px) {
  .ds-app .footer_section > .container-fluid .d-flex.flex-wrap {
    justify-content: center; column-gap: 20px !important; row-gap: 8px !important;
  }
  .ds-app .footer_section > .container-fluid .d-flex.flex-wrap > span { display: none; }
  .ds-app form.contact-form button[type="submit"] { width: 100%; }
}
.ds-app .footer_section .ds-captcha-note a { font-size: inherit; }

/* -- 51 ------------------------------------------------------------------
   SIX TILES IN A FOUR-COLUMN GRID LEAVE AN ORPHAN ROW. The sector grid is
   `col-lg-3`; the detail pages' "What it runs" section has six items, so it
   rendered 4 + 2 with half a row of nothing. Six or nine items take three
   columns instead — the counts where three divides evenly and four does not. */
@media (min-width: 992px) {
  .ds-app .ds-sectors:has(> :nth-child(6):last-child) > .col-lg-3,
  .ds-app .ds-sectors:has(> :nth-child(9):last-child) > .col-lg-3 {
    flex: 0 0 33.3333%; max-width: 33.3333%;
  }
}

/* -- 52 ------------------------------------------------------------------
   THE FOUR STEPS. "How we work together" is four stages in `col-xl-4`, so on a
   wide screen it read 3 + 1 with "Keep going" alone on a second row — the one
   step the copy says never ends, stranded. Four items take four columns above
   1200px (2 × 2 below is already right), with the card's `px-lg-15` brought in
   so a column of 25% still holds a sentence.
   And the step disc was the light skin's 203,216,230 in the dark skin too — four
   pale coins on a navy band. In dark it is the brand at low alpha with a
   hairline, the same treatment as the icon chips. */
@media (min-width: 1200px) {
  .ds-app .process-section .row:has(> :nth-child(4):last-child) > .col-xl-4 { flex: 0 0 25%; max-width: 25%; }
  .ds-app .process-section .row:has(> :nth-child(4):last-child) .service_card_hover {
    padding-left: 16px !important; padding-right: 16px !important;
  }
}
.ds-app.dark .process_icon_bg {
  background-color: rgba(var(--p1), .16) !important;
  box-shadow: inset 0 0 0 1px rgba(var(--p1), .35);
}

/* -- 53 ------------------------------------------------------------------
   ARMENIAN HEADINGS ON A PHONE. The full sweep (40 pages × 3 locales × 390 and
   1440, 2026-10-01) found exactly three overflows, all Armenian at 390: single
   words of 20+ letters ("Հեռահաղորդակցություն") set at 32px need 418px of a
   366px column. Below 576px the Armenian headings scale with the viewport, and
   a word that still cannot fit breaks rather than leaving the screen. */
@media (max-width: 575px) {
  html[lang^="hy"] .ds-app #ds-main h1,
  html[lang^="hy"] .ds-app #ds-main h2 { font-size: min(32px, 7.2vw) !important; }
  .ds-app #ds-main h1, .ds-app #ds-main h2 { overflow-wrap: break-word; }
}

/* -- 54 ------------------------------------------------------------------
   THE STEP NUMBER. "01"–"04" on the green badge were the body grey 168,186,205
   on 37,111,56 — 3.10:1 for 13px text, measured in the light skin on /services
   and every service page that borrows the steps. White on that green is ~6.4:1. */
.ds-app .process_icon_num { color: #fff !important; }


/* -- 55 ------------------------------------------------------------------
   CLIENTS, AND THEIR OWN WORDS (home, 2026-10-05). Two blocks, `clients` and
   `testimonials`, on ONE ground of their own (`settings.ground: "people"`), so
   they read as one movement — the marks, then the people behind them — and as
   neither the plain `audit` above nor the tinted `faq` below. The pictures are
   in ds-people.css (generated); this is layout and paint only.

   (a) THE GROUND. Every band on this site gets its depth from extra §14: a
       vertical wash, one soft bloom (alternating sides, clipped to its own
       section) and a hairline at each join. Applied to this pair as-is, that
       draws exactly what the pair must not have — a hairline and two blooms
       cut off on the same line between the logos and the quotes, measured in
       the first preview as a visible seam. So, for these two only:
         · the join between them has no hairline;
         · the wash rises through the first and falls through the second, so
           the two halves meet at its fullest;
         · ONE bloom, centred exactly ON the seam: both sections draw the same
           ellipse, in pixels, from the same point — the first from its bottom
           edge, the second from its top — so the two halves are one shape.
       The hairlines above and below the pair stay: those joins are real. */
.ds-app .ds-ground-people::before { display: none; }
.ds-app .clients-section.ds-ground-people {
  background-image:
    radial-gradient(1100px 520px at 50% 100%, rgba(var(--p1), var(--ds-tint-cool)) 0%, rgba(var(--p1), 0) 100%),
    linear-gradient(180deg, rgba(var(--p7), 0) 0%, rgba(var(--p7), .6) 100%);
}
.ds-app .testimonials-section.ds-ground-people {
  background-image:
    radial-gradient(1100px 520px at 50% 0%, rgba(var(--p1), var(--ds-tint-cool)) 0%, rgba(var(--p1), 0) 100%),
    linear-gradient(180deg, rgba(var(--p7), .6) 0%, rgba(var(--p7), 0) 100%);
}
/* ⛔ NOT a transparent border: under a 1px transparent top border the section's
   gradients REPEAT, so that row shows their bottom edge — measured as a pale
   line across the seam. No border at all is the only seamless join. */
/* ⛔ AND A 1px OVERLAP. A section's height is fractional (550.4px measured), so
   the seam row is painted part by one section and part by the other, and the
   page ground shows through the gap between the two coverages — a pale line
   exactly as wide as the bloom. The second section covers the first's last row. */
.ds-app .clients-section.ds-ground-people + .testimonials-section.ds-ground-people { border-top: 0; border-image: none; margin-top: -1px; }

/* (b) THE WALL. A plate on the card surface, the mark masked in the page's
       ink: one colour for every client, in either skin, whatever the brand's
       own colours are. The height is per mark (`--ds-logo-h`, equal AREA, set
       by 14_people.py); a narrow column shrinks the mark inside its box rather
       than spilling it, because `mask-size: contain` does the fitting. */
.ds-app .ds-client { color: inherit; text-decoration: none; }
.ds-app .ds-client__plate {
  height: 136px; padding: 24px 32px; border-radius: 20px;
  background: rgb(var(--ds-surface));
  border: 1px solid rgba(var(--p4), .16);
  box-shadow: 0 10px 30px rgba(var(--p9), .06);
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
.ds-app.dark .ds-client__plate {
  background: linear-gradient(180deg, rgba(var(--h2), .5) 0%, rgba(var(--p7), .85) 100%);
  border-color: rgba(var(--p4), .14); box-shadow: none;
}
.ds-app .ds-client__logo {
  display: block; height: var(--ds-logo-h, 56px); max-height: 100%; max-width: 100%;
  background-color: rgba(var(--p8), .80);
  -webkit-mask-image: var(--ds-logo); mask-image: var(--ds-logo);
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  transition: background-color .25s ease;
}
.ds-app a.ds-client:hover .ds-client__plate,
.ds-app a.ds-client:focus-visible .ds-client__plate {
  transform: translateY(-3px);
  border-color: rgba(var(--p1), .35);
  box-shadow: 0 16px 40px rgba(var(--p1), .12);
}
@media (max-width: 575px) { .ds-app .ds-client__plate { height: 96px; padding: 16px 14px; border-radius: 16px; } }
.ds-app a.ds-client:hover .ds-client__logo { background-color: rgb(var(--p1)); }
.ds-app.dark a.ds-client:hover .ds-client__logo { background-color: rgb(var(--p6)); }

/* (c) THE CARD. The template's bordered card at the site's card radius, the
       quote as the body and the person as the footing. The footing is pushed
       to the bottom (`margin-top: auto`), so two quotes of different lengths
       still end on one line across the row. */
.ds-app .ds-tm {
  position: relative; overflow: hidden;
  padding: 40px 40px 32px; border-radius: 24px;
  background: rgb(var(--ds-surface));
  border: 1px solid rgba(var(--p4), .16);
  box-shadow: 0 18px 50px rgba(var(--p9), .07);
}
.ds-app.dark .ds-tm {
  background: linear-gradient(180deg, rgba(var(--h2), .55) 0%, rgba(var(--p7), .9) 100%);
  border-color: rgba(var(--p4), .14);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .35);
}
@media (max-width: 575px) { .ds-app .ds-tm { padding: 28px 22px 24px; border-radius: 20px; } }

/* the ghost quote mark — the same device as the ghost numeral on the service
   cards: present at a glance, never read as text */
.ds-app .ds-tm__mark {
  position: absolute; top: 6px; right: 28px; height: 120px; pointer-events: none;
  color: rgba(var(--p1), .13);
}
/* ⛔ A TYPOGRAPHIC MARK, NOT THE ICON FONT'S. Phosphor's `quotes` glyph is two
   rounded blocks — in the first preview it read as two grey tiles in the
   corner of the card. A serif open-quote at display size is the mark every
   reader already knows. */
.ds-app .ds-tm__mark::before {
  content: "\201C"; display: block;
  font: 700 168px/1 Georgia, "Times New Roman", serif;
}
.ds-app.dark .ds-tm__mark { color: rgba(var(--p1), .32); }
@media (max-width: 575px) {
  .ds-app .ds-tm__mark { right: 16px; height: 84px; }
  .ds-app .ds-tm__mark::before { font-size: 120px; }
}

.ds-app .ds-tm__project { position: relative; margin-bottom: 18px; letter-spacing: .06em; text-transform: uppercase; padding-right: 72px; }
/* the size is set on the PARAGRAPH: the template sizes every `p` itself, so a
   size on the blockquote reached nothing (measured 16px under a rule for 18) */
.ds-app .ds-tm__quote { position: relative; padding-bottom: 28px; }
.ds-app .ds-tm__quote p { font-size: 18px; line-height: 1.65; color: inherit; }
.ds-app .ds-tm__quote:has(+ .ds-tm__tags) { padding-bottom: 0; }
@media (min-width: 1200px) { .ds-app .ds-tm__quote p { font-size: 19px; } }
@media (max-width: 575px) { .ds-app .ds-tm__quote p { font-size: 16px; } }

.ds-app .ds-tm__tags { padding: 22px 0 28px; }
.ds-app .ds-tm__tag {
  padding: 5px 12px; border-radius: 999px; line-height: 1.3;
  color: rgb(var(--p4)); background: rgba(var(--p7), .55);
  border: 1px solid rgba(var(--p4), .18);
}
.ds-app.dark .ds-tm__tag { background: rgba(var(--p6), .04); border-color: rgba(var(--p4), .2); }

.ds-app .ds-tm__who { margin-top: auto; padding-top: 24px; border-top: 1px solid rgba(var(--p4), .16); }

/* the portrait: greyscale at source, round, ringed by the brand with the
   card's own colour showing between — an outline offset paints nothing, so the
   gap is right on the white card and on the dark one alike */
.ds-app .ds-tm__photo {
  width: 72px; height: 72px; border-radius: 50%;
  background-color: rgba(var(--p4), .2); background-size: cover; background-position: center;
  outline: 1px solid rgba(var(--p1), .45); outline-offset: 3px;
}
@media (min-width: 768px) { .ds-app .ds-tm__photo { width: 96px; height: 96px; outline-offset: 4px; } }
.ds-app.dark .ds-tm__photo { filter: brightness(.92); outline-color: rgba(var(--p4), .45); }

.ds-app .ds-tm__name { line-height: 1.3; }
.ds-app .ds-tm__role { margin-top: 2px; }
.ds-app .ds-tm__link { margin-top: 6px; color: rgb(var(--p2)); text-decoration: none; }
.ds-app .ds-tm__link i { font-size: 16px; }
.ds-app .ds-tm__link:hover span { text-decoration: underline; text-underline-offset: 3px; }
/* the template colours every `span` with the ink; the handle is a link's label */
.ds-app .ds-tm__link span { color: inherit; }

/* -- 56 ------------------------------------------------------------------
   THE PLAN CARDS LINE UP AGAIN (2026-10-05). With prices back the line under
   each figure carries the user cap ("Up to 150 users — at most $4,500 a month
   …"), and one of three ran to a third line — so that card's rule and feature
   list started 17px lower than its neighbours'. The line reserves three lines
   at desktop width, where the cards sit side by side; stacked, it takes what it
   needs. */
@media (min-width: 992px) {
  .ds-app .pricing_section h3 + span { display: block; min-height: 7.2em; min-height: 4lh; }
}
@media (min-width: 1400px) {   /* wide cards: the longest line (Armenian) fits in three */
  .ds-app .pricing_section h3 + span { min-height: 5.4em; min-height: 3lh; }
}

/* -- 57 ------------------------------------------------------------------
   THE PRICE CALCULATOR (/pricing, 2026-10-05). The owner: "not cards — sliders
   and checkboxes". Controls on the left in three groups, the quote on the right,
   sticky beside them on a desktop and riding the bottom of the controls on a
   phone. All of it on palette tokens, so both skins are right with no second set.
   Markup: R.price_calc (10-render.js); behaviour: ds-pricing.js. */
.ds-app .ds-calc__panel {
  position: relative; padding: 8px 32px 24px; border-radius: 24px;
  background: rgb(var(--ds-surface)); border: 1px solid rgba(var(--p4), .16);
  box-shadow: 0 18px 50px rgba(var(--p9), .07);
}
.ds-app.dark .ds-calc__panel,
.ds-app.dark .ds-calc__sum {
  background: linear-gradient(180deg, rgba(var(--h2), .55) 0%, rgba(var(--p7), .92) 100%);
  border-color: rgba(var(--p4), .14); box-shadow: 0 18px 50px rgba(0, 0, 0, .35);
}
@media (max-width: 575px) { .ds-app .ds-calc__panel { padding: 4px 18px 0; border-radius: 20px; } }

.ds-app .ds-calc__group { padding: 24px 0 8px; }
.ds-app .ds-calc__group + .ds-calc__group { border-top: 1px solid rgba(var(--p4), .14); }
.ds-app .ds-calc__gname {
  margin: 0 0 6px; font-size: 12px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: rgb(var(--p2));
}
.ds-app .ds-calc__ctl { border: 0; margin: 0; padding: 14px 0; min-width: 0; }
/* ⛔ THE PLATFORM DECORATES EVERY CHECKBOX. Its `nicelabel` plugin adds
   `circle-nicelabel` to the input and inserts its own drawn switch right after it
   — measured on the stand as a second toggle beside ours (the preview, without the
   platform's scripts, never showed it). Ours is the one that matches the site, so
   theirs is hidden here, and every rule above reaches our parts with `~`, not `+`:
   the inserted element now sits between the input and what it styles. */
.ds-app .ds-calc .nicelabel-generated { display: none !important; }
.ds-app .ds-calc__opt input, .ds-app .ds-calc__toggle input {
  position: absolute !important; opacity: 0 !important; width: 1px !important; height: 1px !important;
  margin: 0 !important; pointer-events: none !important;
}
/* a legend floats out of the fieldset's own flow the way Bootstrap means it to,
   so the options start one line under it, not two */
.ds-app .ds-calc__ctl > legend.ds-calc__label { float: left; width: 100%; margin-bottom: 10px; }
.ds-app .ds-calc__ctl > legend.ds-calc__label + * { clear: both; }
.ds-app .ds-calc__ctl.is-off { opacity: .45; }
.ds-app .ds-calc__row { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; }
.ds-app .ds-calc__label {
  float: none; width: auto; margin: 0 0 10px; padding: 0;
  font-size: 16px; font-weight: 600; line-height: 1.35; color: rgb(var(--p8));
}
.ds-app .ds-calc__val {
  font-size: 22px; font-weight: 700; line-height: 1; color: rgb(var(--p1));
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ds-app.dark .ds-calc__val { color: rgb(var(--p8)); }
.ds-app .ds-calc__hint { margin: 10px 0 0; font-size: 13px; line-height: 1.5; color: rgb(var(--p4)); }

/* the slider: a 6px track filled in the brand up to the thumb (`--ds-fill` is
   written by ds-pricing.js, and by the build for the first paint) */
.ds-app .ds-calc__range {
  -webkit-appearance: none; appearance: none; display: block; width: 100%; height: 28px;
  margin: 0; background: transparent; cursor: pointer; --ds-fill: 0%;
}
/* ⛔ the site's own field rule (extra §5, restated with !important in §30 against
   the console skin) paints every input as a filled, bordered box — a range input
   too, which put a pale slab behind the track. The range is not a field. */
.ds-app input.ds-calc__range {
  background: transparent !important; background-image: none !important; border: 0 !important;
  padding: 0 !important; box-shadow: none !important; border-radius: 0 !important; min-height: 0 !important;
}
.ds-app .ds-calc__range:disabled { cursor: not-allowed; }
.ds-app .ds-calc__range::-webkit-slider-runnable-track {
  height: 6px; border-radius: 999px;
  background: linear-gradient(90deg, rgb(var(--p1)) 0 var(--ds-fill), rgba(var(--p4), .22) var(--ds-fill) 100%);
}
.ds-app .ds-calc__range::-moz-range-track { height: 6px; border-radius: 999px; background: rgba(var(--p4), .22); }
.ds-app .ds-calc__range::-moz-range-progress { height: 6px; border-radius: 999px; background: rgb(var(--p1)); }
.ds-app .ds-calc__range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 24px; height: 24px; margin-top: -9px;
  border-radius: 50%; background: #fff; border: 2px solid rgb(var(--p1));
  box-shadow: 0 4px 12px rgba(var(--p1), .35); transition: transform .15s ease;
}
.ds-app .ds-calc__range::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%; background: #fff; border: 2px solid rgb(var(--p1));
  box-shadow: 0 4px 12px rgba(var(--p1), .35);
}
.ds-app .ds-calc__range:hover::-webkit-slider-thumb,
.ds-app .ds-calc__range:active::-webkit-slider-thumb { transform: scale(1.12); }
.ds-app .ds-calc__range:focus-visible { outline: none; }
.ds-app .ds-calc__range:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px rgb(var(--ds-surface)), 0 0 0 6px rgba(var(--p1), .6);
}
.ds-app .ds-calc__range:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 3px rgb(var(--ds-surface)), 0 0 0 6px rgba(var(--p1), .6);
}

/* the choice: real radio inputs, drawn as option cards */
.ds-app .ds-calc__seg { display: grid; gap: 10px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.ds-app .ds-calc__seg--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 575px) { .ds-app .ds-calc__seg, .ds-app .ds-calc__seg--3 { grid-template-columns: 1fr; } }
.ds-app .ds-calc__opt { position: relative; display: block; margin: 0; cursor: pointer; }
.ds-app .ds-calc__opt input,
.ds-app .ds-calc__toggle input {
  position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none;
}
.ds-app .ds-calc__optbody {
  display: flex; flex-direction: column; gap: 4px; height: 100%; padding: 14px 16px;
  border-radius: 16px; border: 1px solid rgba(var(--p4), .22);
  background: rgba(var(--p7), .35); transition: border-color .2s ease, background .2s ease, box-shadow .2s ease;
}
.ds-app .ds-calc__opt:hover .ds-calc__optbody { border-color: rgba(var(--p1), .45); }
.ds-app .ds-calc__opt input:checked ~ .ds-calc__optbody {
  border-color: rgb(var(--p1)); background: rgba(var(--p1), .08);
  box-shadow: inset 0 0 0 1px rgb(var(--p1));
}
.ds-app.dark .ds-calc__opt input:checked ~ .ds-calc__optbody { background: rgba(var(--p1), .2); }
.ds-app .ds-calc__opt input:focus-visible ~ .ds-calc__optbody { box-shadow: 0 0 0 3px rgba(var(--p1), .45); }
.ds-app .ds-calc__optname { font-size: 15px; font-weight: 600; color: rgb(var(--p8)); }
.ds-app .ds-calc__optdesc { font-size: 12.5px; line-height: 1.45; color: rgb(var(--p4)); }
.ds-app .ds-calc__optprice { margin-top: auto; padding-top: 6px; font-size: 13px; font-weight: 700; color: rgb(var(--p1)); }
.ds-app.dark .ds-calc__optprice { color: rgb(var(--p2)); }

/* the switches */
.ds-app .ds-calc__toggle {
  display: flex; align-items: center; gap: 14px; margin: 0; padding: 14px 0; cursor: pointer;
}
.ds-app .ds-calc__switch {
  position: relative; flex: 0 0 44px; width: 44px; height: 26px; border-radius: 999px;
  background: rgba(var(--p4), .3); transition: background .2s ease;
}
.ds-app .ds-calc__switch::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%;
  background: #fff; box-shadow: 0 2px 6px rgba(0, 0, 0, .2); transition: transform .2s ease;
}
.ds-app .ds-calc__toggle input:checked ~ .ds-calc__switch { background: rgb(var(--p1)); }
.ds-app .ds-calc__toggle input:checked ~ .ds-calc__switch::after { transform: translateX(18px); }
.ds-app .ds-calc__toggle input:focus-visible ~ .ds-calc__switch { box-shadow: 0 0 0 3px rgba(var(--p1), .45); }
.ds-app .ds-calc__tbody { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ds-app .ds-calc__tname { font-size: 15px; font-weight: 600; color: rgb(var(--p8)); }
.ds-app .ds-calc__tdesc { font-size: 13px; line-height: 1.45; color: rgb(var(--p4)); }
.ds-app .ds-calc__tprice {
  margin-left: auto; padding-left: 10px; font-size: 14px; font-weight: 700; white-space: nowrap; color: rgb(var(--p1));
}
.ds-app.dark .ds-calc__tprice { color: rgb(var(--p2)); }
/* a phone: switch | text, and the price under the text — never the switch alone
   on a line of its own, which is what flex-wrap made of it */
@media (max-width: 575px) {
  .ds-app .ds-calc__toggle { display: grid; grid-template-columns: 44px minmax(0, 1fr); column-gap: 14px; align-items: start; }
  .ds-app .ds-calc__switch { margin-top: 2px; }
  .ds-app .ds-calc__tprice { grid-column: 2; margin: 6px 0 0; padding-left: 0; }
}

/* the quote */
@media (min-width: 992px) { .ds-app .ds-calc__sumcol { position: sticky; top: 92px; } }
.ds-app .ds-calc__sum {
  position: relative; overflow: hidden; padding: 30px 30px 28px; border-radius: 24px;
  background: rgb(var(--ds-surface)); border: 1px solid rgba(var(--p4), .16);
  box-shadow: 0 24px 60px rgba(var(--p1), .12);
}
.ds-app .ds-calc__sum::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 4px;
  background: linear-gradient(90deg, rgb(var(--p1)), rgb(var(--p2)));
}
.ds-app .ds-calc__sumhead { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ds-app .ds-calc__kicker {
  margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: rgb(var(--p4));
}
.ds-app .ds-calc__plan {
  padding: 6px 14px; border-radius: 999px; font-size: 13px; font-weight: 700;
  color: rgb(var(--p1)); background: rgba(var(--p1), .1); border: 1px solid rgba(var(--p1), .25);
}
.ds-app.dark .ds-calc__plan { color: rgb(var(--p8)); background: rgba(var(--p1), .25); }
.ds-app .ds-calc[data-plan="business"] .ds-calc__plan { color: #fff; background: rgb(var(--p1)); border-color: rgb(var(--p1)); }
.ds-app .ds-calc[data-plan="enterprise"] .ds-calc__plan { color: #fff; background: rgb(var(--p2)); border-color: rgb(var(--p2)); }
.ds-app .ds-calc__note { margin: 12px 0 0; font-size: 13.5px; line-height: 1.5; color: rgb(var(--p4)); }
.ds-app .ds-calc__total,
.ds-app .ds-calc__entbox { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin: 18px 0 22px; }
.ds-app .ds-calc__amount {
  font-size: clamp(38px, 4.2vw, 54px); font-weight: 800; line-height: 1; letter-spacing: -.02em;
  color: rgb(var(--p8)); font-variant-numeric: tabular-nums;
}
.ds-app .ds-calc__per { font-size: 15px; color: rgb(var(--p4)); }
.ds-app .ds-calc__entbox { display: none; }
.ds-app .ds-calc.is-ent .ds-calc__total,
.ds-app .ds-calc.is-ent .ds-calc__kicker--lines,
.ds-app .ds-calc.is-ent .ds-calc__lines { display: none; }
.ds-app .ds-calc.is-ent .ds-calc__entbox { display: flex; }
.ds-app .ds-calc__lines { margin: 10px 0 0; }
.ds-app .ds-calc__line {
  display: flex; justify-content: space-between; gap: 14px; padding: 8px 0;
  font-size: 14px; color: rgb(var(--p4)); border-bottom: 1px dashed rgba(var(--p4), .2);
}
.ds-app .ds-calc__line[hidden] { display: none; }
.ds-app .ds-calc__line > span:last-child { color: rgb(var(--p8)); font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ds-app .ds-calc__once {
  margin-top: 20px; padding: 14px 16px; border-radius: 16px;
  background: rgba(var(--p2), .08); border: 1px solid rgba(var(--p2), .22);
}
.ds-app .ds-calc__once[hidden] { display: none; }
.ds-app .ds-calc.is-ent .ds-calc__once .ds-calc__lines { display: block; }
.ds-app .ds-calc__oncehead { display: flex; justify-content: space-between; font-weight: 700; color: rgb(var(--p8)); }
.ds-app .ds-calc__once .ds-calc__line { border-bottom-color: rgba(var(--p2), .2); }
.ds-app .ds-calc__once .ds-calc__line:last-child { border-bottom: 0; padding-bottom: 0; }
.ds-app .ds-calc__cta { margin-top: 24px; }
.ds-app .ds-calc__cta .btn { width: 100%; justify-content: center; }

/* the phone: a bar with the plan and the total, stuck to the bottom of the screen
   for as long as the controls are on it — and a link down to the full quote */
.ds-app .ds-calc__mini {
  position: sticky; bottom: 12px; z-index: 5; display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin: 8px -6px 12px; padding: 12px 16px; border-radius: 16px; text-decoration: none;
  background: rgb(var(--p1)); color: #fff; box-shadow: 0 12px 30px rgba(var(--p1), .4);
}
.ds-app .ds-calc__mini span, .ds-app .ds-calc__mini small { color: #fff; }
.ds-app .ds-calc__miniplan { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.ds-app .ds-calc__miniamount { font-size: 20px; font-weight: 800; font-variant-numeric: tabular-nums; }
.ds-app .ds-calc__miniamount small { font-size: 12px; font-weight: 500; opacity: .85; }
.ds-app .ds-calc.is-ent .ds-calc__miniamount { display: none; }

/* -- 58 ------------------------------------------------------------------
   ONE SLIDER PER SPECIALIST (2026-10-05). The owner: a client hires x hours of an
   analyst AND y of an engineer AND z of an architect at once — the role picker
   could price only one. Three sliders under one sub-heading; each label carries
   the rate (from `c.specialists`) and one line of what the role does. */
.ds-app .ds-calc__subhead { padding: 14px 0 2px; }
.ds-app .ds-calc__rate {
  display: inline-block; margin-left: 8px; padding: 2px 8px; border-radius: 999px; vertical-align: 1px;
  font-size: 12px; font-weight: 700; color: rgb(var(--p1)); background: rgba(var(--p1), .1);
}
.ds-app.dark .ds-calc__rate { color: rgb(var(--p2)); background: rgba(var(--p2), .14); }
.ds-app .ds-calc__sub { display: block; margin-top: 2px; font-size: 12.5px; font-weight: 400; color: rgb(var(--p4)); }
.ds-app [data-ctl^="h_"] { padding-top: 10px; padding-bottom: 10px; }

/* -- 60 ------------------------------------------------------------------
   THE (i) BOXES (2026-10-05). The owner: "what is an architect, why would I need
   one" — every control explains itself on demand. A small ringed (i) beside the
   name; one click opens a card right under the row, over the content, with a
   pointer at the (i) that opened it (`--ds-arrow`, set by ds-pricing.js). */
.ds-app .ds-calc__ctl, .ds-app .ds-calc__twrap { position: relative; }
/* ⛔ THE SITE'S OWN ICON, NOT A TYPED LETTER. The first (i) was an italic serif
   "i" in a hand-drawn ring — the owner, rightly: "on its own it looks absurd". It
   was a Georgia glyph among Inter type and Phosphor icons, a 1.5px grey ring that
   read as disabled, wedged between the name and the rate pill. Now: Phosphor's
   filled `info`, the family every other icon here comes from, muted until hovered
   or open, after the rate pill so a name and its price read together, with a 28px
   hit area for a thumb and no visible box around it. */
.ds-app .ds-calc__info {
  display: inline-flex; align-items: center; justify-content: center; vertical-align: -3px;
  width: 28px; height: 28px; margin: -6px -4px -6px 2px; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: rgba(var(--p4), .62); font-size: 18px; line-height: 1; cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.ds-app .ds-calc__info i { display: block; line-height: 1; }
.ds-app .ds-calc__info:hover { color: rgb(var(--p1)); background: rgba(var(--p1), .1); }
.ds-app .ds-calc__info[aria-expanded="true"] { color: rgb(var(--p1)); }
.ds-app.dark .ds-calc__info:hover,
.ds-app.dark .ds-calc__info[aria-expanded="true"] { color: rgb(var(--p8)); background: rgba(var(--p1), .3); }
.ds-app .ds-calc__info:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(var(--p1), .45); }

.ds-app .ds-calc__pop {
  position: absolute; z-index: 30; left: 0; right: 0; margin-top: 10px; max-width: 520px;
  padding: 16px 18px 18px; border-radius: 16px;
  background: rgb(var(--ds-surface)); border: 1px solid rgba(var(--p1), .28);
  box-shadow: 0 24px 60px rgba(var(--p9), .18), 0 2px 0 rgba(var(--p1), .9) inset;
  opacity: 0; transform: translateY(-6px); transition: opacity .18s ease, transform .18s ease;
}
.ds-app.dark .ds-calc__pop {
  background: linear-gradient(180deg, rgb(var(--h2)) 0%, rgb(var(--p7)) 100%);
  border-color: rgba(var(--p1), .45); box-shadow: 0 24px 60px rgba(0, 0, 0, .55), 0 2px 0 rgba(var(--p1), .9) inset;
}
.ds-app .ds-calc__pop.is-open { opacity: 1; transform: none; }
.ds-app .ds-calc__pop[hidden] { display: none; }
/* the pointer */
.ds-app .ds-calc__pop::before {
  content: ""; position: absolute; top: -7px; left: calc(var(--ds-arrow, 24px) - 7px);
  width: 12px; height: 12px; transform: rotate(45deg);
  background: inherit; border-left: 1px solid rgba(var(--p1), .28); border-top: 1px solid rgba(var(--p1), .28);
}
.ds-app.dark .ds-calc__pop::before { background: rgb(var(--h2)); border-color: rgba(var(--p1), .45); }
.ds-app .ds-calc__pophead { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.ds-app .ds-calc__popicon { flex: 0 0 auto; font-size: 22px; line-height: 1; color: rgb(var(--p1)); }
.ds-app.dark .ds-calc__popicon { color: rgb(var(--p2)); }
.ds-app .ds-calc__poptitle { font-size: 15px; font-weight: 700; color: rgb(var(--p8)); }
.ds-app .ds-calc__popx {
  margin-left: auto; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(var(--p4), .12); color: rgb(var(--p8)); font-size: 18px; line-height: 1; cursor: pointer;
}
.ds-app .ds-calc__popx:hover { background: rgba(var(--p4), .24); }
.ds-app .ds-calc__poptext { margin: 0; font-size: 14px; line-height: 1.6; color: rgb(var(--p8)); opacity: .86; }
/* in a fieldset the box follows the floated legend; what comes after it still clears */
.ds-app .ds-calc__ctl > .ds-calc__pop + * { clear: both; }

/* -- 61 ------------------------------------------------------------------
   THE GRID WAS MISSING FROM HALF THE PAGE HEADERS (2026-10-05). The owner:
   /pricing and the Company pages have no grid in the header, /industries/
   healthcare does. Both headers are `innerBanner()`; the difference is that a
   block-built page wraps its banner in `ds-blockwrap`, and extra §14 gives every
   `.ds-blockwrap::after` the GRAIN — `opacity: .025; mix-blend-mode: overlay`.
   The banner's own `::after` (the 96px grid) is more specific and replaces the
   grain's background and size, but it never states an opacity, so the grain's
   2.5% survived and the grid faded to nothing. A catalogue entry's banner has no
   `ds-blockwrap`, which is why it kept its grid. State the two the grid needs. */
.ds-app .banner-section.inner-banner.ds-blockwrap::after,
.ds-app.dark .banner-section.inner-banner.ds-blockwrap::after { opacity: 1; mix-blend-mode: normal; }

/* -- 62 ------------------------------------------------------------------
   THE HERO FIELD BECAME A SURFACE (2026-10-07). The owner, pointing at the
   header of imidsign.am: the flat square grid behind the home carousel goes,
   a living 3D mesh comes in, with a quiet hint of a neural net. ds-kit.js
   draws it (HERO FIELD); this section gives it its inks and its place.

   (a) THE INKS, one pair per skin, read by the canvas at boot and again on
       every toggle. Light: the brand navy, laid down as ink. Dark: a lifted
       brand blue, ADDED as light — where the far rows crowd together the
       horizon glows instead of turning to a grey slab. The accent is the
       green the slide drawings use for their spark. `--ds-field-k` was the
       old grid's per-skin strength (extra §10d, .45/.52); the surface carries
       its own alphas, so it is one here. */
:root, .ds-app {
  --ds-field-line: 22, 104, 171;
  --ds-field-spark: 47, 143, 74;
  --ds-field-k: 1;
  --ds-field-blend: source-over;
  --ds-field-clear: .62;   /* how far the mesh thins under the slide's drawing */
}
.ds-app.dark {
  --ds-field-line: 80, 160, 226;
  --ds-field-spark: 89, 194, 106;
  --ds-field-k: 1;
  --ds-field-blend: lighter;
  --ds-field-clear: .45;   /* light on dark tangles less: a lighter clearing */
}
/* (b) QUIETER UNDER THE COPY. The headline and the lead live in the left
       half; the drawing lives in the right. The mesh is whole everywhere —
       a field cut off at a column reads as a mistake — but it carries half
       its weight where the words are. */
.ds-app .banner-translate-carousel > canvas.ds-ainet {
  opacity: 1;
  -webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .66) 34%, #000 64%);
          mask-image: linear-gradient(90deg, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .66) 34%, #000 64%);
}
/* (c) A phone stacks the copy over the drawing, so there is no "copy side":
       the mask goes, and the whole field steps back instead. */
@media (max-width: 991px) {
  .ds-app .banner-translate-carousel > canvas.ds-ainet {
    opacity: .72;
    -webkit-mask-image: none;
            mask-image: none;
  }
}

/* -- 63 ------------------------------------------------------------------
   THE RAIL, ALIVE (2026-10-07). The owner: let the hero's animation spread
   onto the left column, where the grid runs down and fades. The grid stays
   the stylesheet's (extra §42); ds-kit.js (THE RAIL, ALIVE) lays a canvas
   over it that lights only what moves — signals crossing in from the hero,
   running along these same lines, branching and fading downward.

   (a) Over the grid, under the rail's own contents (`.sidebar-left > *` is
       z-index 1). The mask is the grid's own fall-off, plus a clear top where
       the header and the logo sit, so a signal never outshines the cells it
       runs on and never passes behind the logo. */
.ds-app .banner-section .sidebar-left > canvas.ds-railnet {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 0; pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, transparent 96px, #000 150px, #000 70%, rgba(0, 0, 0, .45) 100%);
          mask-image: linear-gradient(180deg, transparent 0, transparent 96px, #000 150px, #000 70%, rgba(0, 0, 0, .45) 100%);
}
/* (b) When a signal arrives at the social circle, its ring lights — in the
       accent, softly, and lets go slowly. Hover still wins (it fills blue). */
.ds-app .banner-section.index-one .ds-rail__icon {
  transition: background .3s, border-color .6s, color .3s, transform .3s, box-shadow .9s ease;
}
.ds-app .banner-section.index-one .ds-rail__icon.is-ping {
  border-color: rgba(var(--ds-field-spark), .8);
  box-shadow: 0 0 0 5px rgba(var(--ds-field-spark), .10), 0 0 26px rgba(var(--ds-field-spark), .30);
}

/* -- 64 ------------------------------------------------------------------
   THE DRAWING SNAPPED INTO PLACE AT THE END OF ITS ENTRANCE (2026-10-07, the
   owner: "it glides in, then at the end it jumps into place").

   The template slides `.slide-img` in from `translateX(150%)` with a 2s
   transition that starts .6s after the slide turns active — it lands at 2.6s.
   Extra §12c starts the drawing's float at 1.6s, and a CSS ANIMATION outranks a
   running TRANSITION on the same property: at 1.6s the float took `transform`
   over from wherever the slide-in had got to and put the drawing at rest in one
   frame. The float now waits for the landing, and the landing decelerates all
   the way down instead of `ease`'s even finish. */
.ds-app .banner-translate-carousel .swiper-slide .slide-img {
  transition: transform 2s cubic-bezier(.33, 1, .68, 1) .6s;
}
.ds-app .banner-translate-carousel .swiper-slide-active .slide-img {
  animation-delay: 2.7s;
}
/* and for someone who asked for less motion, a slide simply arrives: its words
   and its drawing fade in where they stand instead of flying in from the sides.
   ⛔ THE TEMPLATE NEVER HIDES AN INACTIVE SLIDE — `.swiper-slide { opacity: 1
   !important }` — it only moves its drawing out to `translateX(150%)` and fades
   its words. Take the move away and all four drawings stand on top of each other
   (seen, 2026-10-07), so here the inactive drawing is hidden by opacity instead. */
@media (prefers-reduced-motion: reduce) {
  .ds-app .banner-translate-carousel .swiper-slide .slide-img,
  .ds-app .banner-translate-carousel .swiper-slide .title,
  .ds-app .banner-translate-carousel .swiper-slide p,
  .ds-app .banner-translate-carousel .swiper-slide .btn-area { transform: none !important; }
  .ds-app .banner-translate-carousel .swiper-slide .slide-img { transition: opacity .6s ease; opacity: 0; }
  .ds-app .banner-translate-carousel .swiper-slide-active .slide-img { opacity: 1; }
}

/* -- 65 ------------------------------------------------------------------
   THE SCREENSHOTS BEHIND THE SLIDES STEP BACK (2026-10-07, the owner: "too
   heavy for the eyes"). They were tuned (extra §10b) when the band had nothing
   else alive in it; it now carries the mesh (§62) and a drawing per slide, and
   a product screen at full strength under both is one layer too many. The
   veil comes up across the whole width — most on the right, where the shot was
   barely veiled at all — so the screen is still FELT behind the words and no
   longer read. Same four stops, same gradient (heroBg() in 05-art.js). */
:root, .ds-app { --ds-hero-1: .78; --ds-hero-2: .76; --ds-hero-3: .70; --ds-hero-4: .64; }
.ds-app.dark   { --ds-hero-1: .80; --ds-hero-2: .78; --ds-hero-3: .72; --ds-hero-4: .66; }

/* -- 66 ------------------------------------------------------------------
   THE STATISTICS PANEL'S HAIRLINES DID NOT MEET (found looking at the home
   page as a whole, 2026-10-07). `.counter_right_side` draws its grid with the
   borders of each cell's INNER box, and that box was only as tall as its own
   text — so when one label wraps to two lines (“week: an engineer with AI
   builds and tests your system”) its neighbour's border stops 24px short:
   the horizontal rule steps, the vertical one doubles. Measured: column 210,
   box 186. The box now fills its column and centres its figure in it, so the
   four cells are one ruled panel again — on home, /about and /demo alike. */
.ds-app .counter_right_side > .row > [class*="col-"] { display: flex; }
.ds-app .counter_right_side > .row > [class*="col-"] > .cus-border {
  flex: 1 1 auto;
  display: flex; flex-direction: column; justify-content: center;
}

/* -- 67 ------------------------------------------------------------------
   THE LOGO SHRANK IN ARMENIAN (2026-10-07). The header is one flex row —
   brand, menu, controls — and every part of it may shrink. The Armenian menu
   is ~130px wider than the English one (Ծառայություններ, Ընկերություն), so
   at 1440 and 1200 the row took the difference out of the BRAND: measured
   163×50 → 90×28. The menu meanwhile kept 120px of leading margin and padding
   (Bootstrap's ms-xxl-20 + ps-xxl-10) it did not need.
   The brand no longer gives way; the Armenian menu drops the leading space
   and, where it is still tight, closes its gaps a little. */
.ds-app .header-section nav.navbar > div:first-child { flex-shrink: 0; }
.ds-app .header-section nav.navbar > .navbar-collapse { min-width: 0; }
html[lang|="hy"] .ds-app .header-section .navbar-nav {
  margin-left: 0 !important; padding-left: 0 !important;
}
@media (min-width: 992px) and (max-width: 1399px) {
  html[lang|="hy"] .ds-app .header-section .navbar-nav { column-gap: 6px !important; }
  html[lang|="hy"] .ds-app .header-section .right-area { column-gap: 12px !important; }
}
@media (min-width: 992px) and (max-width: 1199px) {
  html[lang|="hy"] .ds-app .header-section .navbar-nav a { font-size: 15px; }
}

/* -- 68 ------------------------------------------------------------------
   THE MESH NO LONGER STOPS AT A LINE (2026-10-07, the owner: "on the left it
   breaks off — let it run a little into the left panel and melt into it").
   The canvas ended at the carousel's own left edge, which sits 24px short of
   the rail's border (the two columns' gutters), so the surface stopped in a
   straight vertical cut with a strip of bare ground beside it. From 1400px,
   where the rail exists, the canvas reaches 136px further left — across the
   gutter and into the rail's right side — and fades to nothing there. It
   paints above the rail's ground and grid and below its label and circle
   (`.sidebar-left > *` is z-index 1), so it melts into the panel without
   touching what is on it. The carousel lets it out: Swiper's `overflow:
   hidden` is not what keeps the slides apart — a fade carousel stacks them in
   place, each slide clips its own drawing, each copy column its own words. */
@media (min-width: 1400px) {
  .ds-app .banner-section.index-one .banner-translate-carousel { overflow: visible; }
  .ds-app .banner-section.index-one .banner-translate-carousel > canvas.ds-ainet {
    left: -136px; width: calc(100% + 136px);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, rgba(0, 0, 0, .14) 56px, rgba(0, 0, 0, .5) 136px, rgba(0, 0, 0, .66) 36%, #000 64%);
            mask-image: linear-gradient(90deg, transparent 0, rgba(0, 0, 0, .14) 56px, rgba(0, 0, 0, .5) 136px, rgba(0, 0, 0, .66) 36%, #000 64%);
  }
}

/* -- 69 ------------------------------------------------------------------
   THE SECTION SCREENSHOTS GET AN EDGE (2026-10-07, a designer's pass). A
   product screen beside the copy had a radius and nothing else: on the dark
   skin a dark UI sits on a dark band and its edges simply dissolve, so the
   picture reads as a smudge rather than as a screen. One hairline and one
   soft drop give it a surface — the same treatment as the site's cards, in
   each skin's own weight. */
.ds-app .choose-section .choose_us,
.ds-app .forms-section .choose_us {
  box-shadow: 0 0 0 1px rgba(var(--p8), .07), 0 24px 56px -18px rgba(8, 21, 37, .22);
}
.ds-app.dark .choose-section .choose_us,
.ds-app.dark .forms-section .choose_us {
  box-shadow: 0 0 0 1px rgba(var(--p4), .18), 0 28px 70px -20px rgba(0, 0, 0, .6), 0 0 0 6px rgba(var(--p1), .04);
}

/* -- 70 ------------------------------------------------------------------
   THE GHOST CHART UNDER "A WEEK, NOT YEARS" STANDS CLEAR OF THE WORDS. The
   band's drawing (extra §36) is pinned to the bottom left at 560×300, and its
   tallest bar rose to within a few pixels of the heading's baseline — a
   drawing touching a headline reads as an accident. A little smaller and a
   little lower: same drawing, a clear gap above it. */
.ds-app #numbers {
  background-size: 500px 268px, cover, cover;
  background-position: left 3% bottom 26px, center, center;
}

/* -- 71 ------------------------------------------------------------------
   THE NEWSLETTER HEADING IS AN h3 NOW (2026-10-08, 22_components.py). It
   follows the page's last h2, and the template's h4 there was the one heading
   jump on every page. Its size is the `fs-four` class either way; this carries
   over the one rule that was written against the tag (extra §-footer, line
   height 1.2 — on a phone `fs-four` alone would give it 130%). */
.ds-app .footer_section .newsletter .content-area h3 { line-height: 1.2; }

/* -- 72 ------------------------------------------------------------------
   THE CASE STUDY (2026-10-08, /case-studies — 10-render.js `caseStudy`). One
   delivered system per card, in the testimonial card's material so the two
   read as one family: the same surface, hairline and soft drop, the same dark
   gradient. What is new is the order a buyer reads in — who, the line that
   says what it is, problem / built / changed beside the system in a window
   frame, then the numbers on a ruled strip, then the customer's own words. */
.ds-app .ds-case {
  position: relative; overflow: hidden; isolation: isolate;
  padding: 48px 48px 40px; border-radius: 28px;
  background: rgb(var(--ds-surface));
  border: 1px solid rgba(var(--p4), .16);
  box-shadow: 0 24px 70px rgba(var(--p9), .08);
}
.ds-app.dark .ds-case {
  background: linear-gradient(180deg, rgba(var(--h2), .55) 0%, rgba(var(--p7), .92) 100%);
  border-color: rgba(var(--p4), .14);
  box-shadow: 0 28px 80px rgba(0, 0, 0, .4);
}
/* a brand light behind the picture, faint — the card's one colour field */
.ds-app .ds-case::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  right: -12%; bottom: -30%; width: 70%; height: 90%;
  background: radial-gradient(closest-side, rgba(var(--p1), .09), rgba(var(--p1), 0));
}
.ds-app.dark .ds-case::before { background: radial-gradient(closest-side, rgba(var(--p1), .22), rgba(var(--p1), 0)); }
.ds-app .ds-case--flip::before { left: -12%; right: auto; }

.ds-app .ds-case__head { position: relative; margin-bottom: 40px; padding-right: 96px; }
.ds-app .ds-case__eyebrow { letter-spacing: .08em; text-transform: uppercase; margin-bottom: 10px; }
.ds-app .ds-case__title { line-height: 1.12; }
.ds-app .ds-case__lead { margin-top: 12px; font-size: 18px; line-height: 1.55; max-width: 62ch; }
.ds-app .ds-case__index {
  position: absolute; top: -10px; right: 0; line-height: 1; font-weight: 700;
  color: rgba(var(--p1), .12); letter-spacing: -.04em; pointer-events: none;
}
.ds-app.dark .ds-case__index { color: rgba(var(--p1), .38); }
.ds-app .ds-case__mark {
  width: 120px; height: 88px; padding: 14px 16px; border-radius: 18px;
  background: rgba(var(--p7), .55); border: 1px solid rgba(var(--p4), .16);
}
.ds-app.dark .ds-case__mark { background: rgba(var(--p6), .04); border-color: rgba(var(--p4), .18); }
.ds-app .ds-case__mark .ds-client__logo { height: calc(var(--ds-logo-h, 56px) * .82); }

.ds-app .ds-case__parts { gap: 26px; }
.ds-app .ds-case__part { padding-left: 20px; border-left: 2px solid rgba(var(--p1), .22); }
.ds-app.dark .ds-case__part { border-left-color: rgba(var(--p1), .5); }
.ds-app .ds-case__part p + p { margin-top: 10px; }
.ds-app .ds-case__tags { margin-top: 28px; }

/* the system in a window: three lights and the screen's name, so a screenshot
   reads as a running application rather than as an illustration */
.ds-app .ds-browser {
  border-radius: 16px; overflow: hidden;
  background: rgb(var(--ds-surface));
  border: 1px solid rgba(var(--p4), .18);
  box-shadow: 0 0 0 1px rgba(var(--p8), .03), 0 30px 60px -24px rgba(8, 21, 37, .35);
}
.ds-app.dark .ds-browser {
  border-color: rgba(var(--p4), .22);
  box-shadow: 0 0 0 6px rgba(var(--p1), .05), 0 34px 70px -22px rgba(0, 0, 0, .7);
}
.ds-app .ds-browser__bar {
  height: 34px; padding: 0 14px;
  background: rgba(var(--p7), .75); border-bottom: 1px solid rgba(var(--p4), .14);
}
.ds-app.dark .ds-browser__bar { background: rgba(var(--h2), .7); border-bottom-color: rgba(var(--p4), .16); }
.ds-app .ds-browser__bar i { width: 10px; height: 10px; border-radius: 50%; background: rgba(var(--p4), .3); flex-shrink: 0; }
.ds-app .ds-browser__bar i:nth-child(1) { background: #ff5f57; }
.ds-app .ds-browser__bar i:nth-child(2) { background: #febc2e; }
.ds-app .ds-browser__bar i:nth-child(3) { background: #28c840; }
.ds-app .ds-browser__url {
  margin: 0 auto; padding: 3px 14px; border-radius: 999px; max-width: 70%;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  color: rgb(var(--p4)); background: rgba(var(--p6), .6);
}
.ds-app.dark .ds-browser__url { background: rgba(var(--p7), .7); }
/* every case picture is cut to 1456x728 (account bar off, 2:1) — the box takes that ratio, so
   `cover` has nothing left to crop and no KPI at the right edge is lost */
.ds-app .ds-browser img { aspect-ratio: 2 / 1; object-fit: cover; object-position: top left; }

/* the numbers: one ruled strip, the figure in the statistics' own green */
.ds-app .ds-case__metrics {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-top: 44px; border-top: 1px solid rgba(var(--p4), .16);
}
.ds-app .ds-case__metric { padding: 26px 20px 4px; }
.ds-app .ds-case__metric + .ds-case__metric { border-left: 1px solid rgba(var(--p4), .16); }
.ds-app .ds-case__value {
  font-size: 44px; line-height: 1.05; font-weight: 700; letter-spacing: -.03em;
  color: rgb(var(--p3)); margin-bottom: 8px; white-space: nowrap;
}
.ds-app.dark .ds-case__value { color: rgb(var(--p2)); }
/* the template sizes and inks `.counter` itself (16px, the body ink): inside a
   figure it must take the figure's own size and green, or the count-up shows a
   small grey number under a large empty line */
.ds-app .ds-case__value .counter { font: inherit; color: inherit; letter-spacing: inherit; line-height: inherit; }
.ds-app .ds-case__label { line-height: 1.4; }

.ds-app .ds-case__quote {
  margin-top: 36px; padding-top: 28px; border-top: 1px solid rgba(var(--p4), .16);
}
.ds-app .ds-case__quote blockquote p { font-size: 18px; line-height: 1.6; font-style: italic; }
.ds-app .ds-case__quote blockquote p::before { content: "\201C"; }
.ds-app .ds-case__quote blockquote p::after { content: "\201D"; }
.ds-app .ds-case__photo { width: 56px !important; height: 56px !important; outline-offset: 2px !important; }

@media (max-width: 1199px) {
  .ds-app .ds-case__value { font-size: 36px; }
}
@media (max-width: 991px) {
  .ds-app .ds-case { padding: 36px 28px 30px; border-radius: 24px; }
  .ds-app .ds-case__head { margin-bottom: 28px; padding-right: 64px; }
  .ds-app .ds-case__index { font-size: 52px; top: -4px; }
  .ds-app .ds-case__metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ds-app .ds-case__metric:nth-child(3) { border-left: 0; }
  .ds-app .ds-case__metric:nth-child(n + 3) { border-top: 1px solid rgba(var(--p4), .16); }
}
@media (max-width: 575px) {
  .ds-app .ds-case { padding: 28px 20px 24px; border-radius: 20px; }
  .ds-app .ds-case__head { padding-right: 0; }
  .ds-app .ds-case__index { display: none; }
  .ds-app .ds-case__lead { font-size: 16px; }
  .ds-app .ds-case__metric { padding: 20px 12px 2px; }
  .ds-app .ds-case__value { font-size: 30px; }
  .ds-app .ds-case__quote blockquote p { font-size: 16px; }
}
/* the procedure as its own picture: a lane of numbered stages joined by a rule */
.ds-app .ds-case__lane {
  position: relative; padding: 26px 26px 22px; border-radius: 18px;
  background: rgba(var(--p7), .5); border: 1px solid rgba(var(--p4), .16);
}
.ds-app.dark .ds-case__lane { background: rgba(var(--p6), .03); border-color: rgba(var(--p4), .18); }
.ds-app .ds-case__lanehead { color: rgb(var(--p4)); letter-spacing: .08em; text-transform: uppercase; margin-bottom: 16px; }
.ds-app .ds-case__flow { position: relative; display: grid; gap: 14px; }
.ds-app .ds-case__flow::before {
  content: ""; position: absolute; left: 17px; top: 18px; bottom: 18px; width: 2px;
  background: linear-gradient(180deg, rgba(var(--p1), .5), rgba(var(--p3), .5));
}
.ds-app .ds-case__step { position: relative; }
.ds-app .ds-case__stepno {
  width: 36px; height: 36px; border-radius: 50%; position: relative; z-index: 1;
  font-size: 13px; font-weight: 700; color: rgb(var(--p1));
  background: rgb(var(--ds-surface)); border: 2px solid rgba(var(--p1), .45);
}
.ds-app .ds-case__step:last-child .ds-case__stepno { color: rgb(var(--p6)); background: rgb(var(--p3)); border-color: rgb(var(--p3)); }
.ds-app.dark .ds-case__stepno { color: rgb(var(--p8)); border-color: rgba(var(--p1), .7); }
.ds-app.dark .ds-case__step:last-child .ds-case__stepno { color: rgb(var(--p5)); background: rgb(var(--p2)); border-color: rgb(var(--p2)); }
.ds-app .ds-case__step > span:last-child { padding-top: 6px; }

/* -- 73 ------------------------------------------------------------------
   SEVEN ITEMS IN THE TOP MENU (2026-10-08, the owner: "Features" and "Case
   studies" go in the top menu, all three languages). The row was set for five:
   80px of leading space and 48px between items. Measured with seven at 1440:
   the menu ran 45px (en), 59px (ru) and 131px (hy) into the controls, and
   "Case studies" broke onto two lines. So, for every language now (not only
   the Armenian of §67): no leading space, tighter gaps, labels on one line.
   Where seven still cannot fit — below 1200, and Armenian below 1600, measured
   — the two new items step out of the bar and stay in the side panel and the
   footer; the five that always fitted stay put, so no width loses a menu it had.
   ⛔ `.navbar .navbar-nav`, not `.navbar-nav`: the template's own link rule is
   `.header-section .navbar .navbar-nav a` (0,4,1) and outranked a shorter one.
   ⛔ `href$=`, not `href=`: ds-kit rewrites every link to the project's mount at
   runtime ("features" becomes "/features"), so an exact match never fires. */
@media (min-width: 992px) {
  .ds-app .header-section .navbar-nav { margin-left: 0 !important; padding-left: 0 !important; }
  .ds-app .header-section .navbar .navbar-nav > li > a,
  .ds-app .header-section .navbar .navbar-nav > li > button { white-space: nowrap; }
}
@media (min-width: 1200px) {
  .ds-app .header-section .navbar-nav { column-gap: 4px !important; }
  .ds-app .header-section .navbar .navbar-nav > li > a,
  .ds-app .header-section .navbar .navbar-nav > li > button { padding-left: 10px; padding-right: 10px; }
  .ds-app .header-section .right-area { column-gap: 14px !important; }
}
/* the narrowest desktop, measured on the live home page (its header runs
   ~20px wider than an inner page's): 16px and 8px padding left the English
   menu 10px INTO the controls at 1200; 15px with 6px leaves 46 */
@media (min-width: 1200px) and (max-width: 1299px) {
  .ds-app .header-section .navbar-nav { column-gap: 0 !important; }
  .ds-app .header-section .navbar .navbar-nav > li > a,
  .ds-app .header-section .navbar .navbar-nav > li > button { padding-left: 8px; padding-right: 8px; font-size: 15px; }
}
@media (min-width: 1200px) and (max-width: 1279px) {
  .ds-app .header-section .navbar .navbar-nav > li > a,
  .ds-app .header-section .navbar .navbar-nav > li > button { padding-left: 6px; padding-right: 6px; }
}
@media (min-width: 992px) and (max-width: 1199px) {
  .ds-app .header-section .navbar-nav > li:has(> a[href$="features"]),
  .ds-app .header-section .navbar-nav > li:has(> a[href$="case-studies"]) { display: none !important; }
}
@media (min-width: 992px) and (max-width: 1599px) {
  html[lang|="hy"] .ds-app .header-section .navbar-nav > li:has(> a[href$="features"]),
  html[lang|="hy"] .ds-app .header-section .navbar-nav > li:has(> a[href$="case-studies"]) { display: none !important; }
}
@media (min-width: 1600px) and (max-width: 1799px) {
  html[lang|="hy"] .ds-app .header-section .navbar-nav { column-gap: 0 !important; }
  html[lang|="hy"] .ds-app .header-section .navbar .navbar-nav > li > a,
  html[lang|="hy"] .ds-app .header-section .navbar .navbar-nav > li > button { padding-left: 8px; padding-right: 8px; }
}

/* -- 74 ------------------------------------------------------------------
   PARTNERS (2026-10-13, /partners — 10-render.js `partnerCard`, 05-art.js
   `artAlliance`). The owner asked for a Partners page reached from Company,
   with the partner's own logo, "как будет круто по дизайнерски". One card per
   partner, in the case card's material (§72) so the two pages read as one
   family; what is new is the STAGE — the partner's mark, large, on a lit square
   of the site's own grid with two slow orbits around it, and the whole square
   is the link to their site.

   (a) THE CARD. */
.ds-app .ds-partner {
  position: relative; overflow: hidden; isolation: isolate;
  padding: 48px; border-radius: 28px;
  background: rgb(var(--ds-surface));
  border: 1px solid rgba(var(--p4), .16);
  box-shadow: 0 24px 70px rgba(var(--p9), .08);
}
.ds-app.dark .ds-partner {
  background: linear-gradient(180deg, rgba(var(--h2), .55) 0%, rgba(var(--p7), .92) 100%);
  border-color: rgba(var(--p4), .14);
  box-shadow: 0 28px 80px rgba(0, 0, 0, .4);
}
/* one brand light, behind the copy — the stage carries its own */
.ds-app .ds-partner::before {
  content: ""; position: absolute; z-index: -1; pointer-events: none;
  right: -14%; top: -34%; width: 70%; height: 96%;
  background: radial-gradient(closest-side, rgba(var(--p1), .07), rgba(var(--p1), 0));
}
.ds-app.dark .ds-partner::before { background: radial-gradient(closest-side, rgba(var(--p1), .18), rgba(var(--p1), 0)); }
.ds-app .ds-partner--flip::before { left: -14%; right: auto; }

/* (b) THE STAGE. Square on a desktop, wide below lg (a full-width square on a
       tablet is a screen of nothing but a logo). The rings are sized from the
       stage's HEIGHT, so they stay circles whatever its shape. */
.ds-app .ds-partner__stage {
  position: relative; overflow: hidden; isolation: isolate;
  aspect-ratio: 1 / 1; width: 100%; padding: 10% 8%;
  border-radius: 24px; text-decoration: none; color: inherit;
  background:
    radial-gradient(58% 58% at 50% 48%, rgba(var(--p1), .11) 0%, rgba(var(--p1), 0) 72%),
    radial-gradient(38% 38% at 74% 80%, rgba(var(--p3), .10) 0%, rgba(var(--p3), 0) 100%),
    rgb(var(--p5));
  border: 1px solid rgba(var(--p4), .16);
  transition: border-color .3s ease, box-shadow .3s ease, transform .3s ease;
}
.ds-app.dark .ds-partner__stage {
  background:
    radial-gradient(58% 58% at 50% 48%, rgba(var(--p1), .30) 0%, rgba(var(--p1), 0) 72%),
    radial-gradient(38% 38% at 74% 80%, rgba(var(--p2), .12) 0%, rgba(var(--p2), 0) 100%),
    rgba(var(--p5), .72);
  border-color: rgba(var(--p4), .18);
}
/* the site's lattice, dissolving toward the rim like the banners' */
.ds-app .ds-partner__stage::before {
  content: ""; position: absolute; inset: 0; z-index: -2; pointer-events: none;
  background-image:
    repeating-linear-gradient(90deg, rgba(var(--p4), .11) 0 1px, transparent 1px 48px),
    repeating-linear-gradient(0deg,  rgba(var(--p4), .11) 0 1px, transparent 1px 48px);
  background-position: center;
  -webkit-mask-image: radial-gradient(closest-side, #000 20%, transparent 100%);
          mask-image: radial-gradient(closest-side, #000 20%, transparent 100%);
}
.ds-app.dark .ds-partner__stage::before {
  background-image:
    repeating-linear-gradient(90deg, rgba(var(--p6), .06) 0 1px, transparent 1px 48px),
    repeating-linear-gradient(0deg,  rgba(var(--p6), .06) 0 1px, transparent 1px 48px);
}
.ds-app a.ds-partner__stage:hover,
.ds-app a.ds-partner__stage:focus-visible {
  transform: translateY(-3px);
  border-color: rgba(var(--p1), .38);
  box-shadow: 0 26px 60px rgba(var(--p1), .14);
}
.ds-app a.ds-partner__stage:focus-visible { outline: 2px solid rgb(var(--p1)); outline-offset: 4px; }

/* the orbits: a dashed outer track, then two rings each carrying a light —
   ours in the brand blue, the partner's in the mark green, turning opposite ways */
.ds-app .ds-partner__rings { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.ds-app .ds-partner__rings i {
  position: absolute; left: 50%; top: 50%; aspect-ratio: 1 / 1; width: auto;
  border-radius: 50%; border: 1px solid rgba(var(--p4), .20);
  transform: translate(-50%, -50%) rotate(0deg);
}
.ds-app .ds-partner__rings i:nth-child(1) { height: 90%; border-style: dashed; border-color: rgba(var(--p4), .16); }
.ds-app .ds-partner__rings i:nth-child(2) { height: 72%; animation: ds-orbit 30s linear infinite; }
.ds-app .ds-partner__rings i:nth-child(3) { height: 54%; animation: ds-orbit 22s linear infinite reverse; }
.ds-app.dark .ds-partner__rings i { border-color: rgba(var(--p4), .16); }
.ds-app.dark .ds-partner__rings i:nth-child(1) { border-color: rgba(var(--p4), .12); }
.ds-app .ds-partner__rings i:nth-child(2)::after,
.ds-app .ds-partner__rings i:nth-child(3)::after {
  content: ""; position: absolute; top: -5px; left: 50%; width: 10px; height: 10px; margin-left: -5px; border-radius: 50%;
}
.ds-app .ds-partner__rings i:nth-child(2)::after { background: rgb(var(--p1)); box-shadow: 0 0 0 5px rgba(var(--p1), .14), 0 0 16px rgba(var(--p1), .75); }
.ds-app .ds-partner__rings i:nth-child(3)::after { background: rgb(var(--p3)); box-shadow: 0 0 0 5px rgba(var(--p3), .14), 0 0 16px rgba(var(--p3), .75); }
.ds-app.dark .ds-partner__rings i:nth-child(3)::after { background: rgb(var(--p2)); box-shadow: 0 0 0 5px rgba(var(--p2), .14), 0 0 16px rgba(var(--p2), .75); }
@keyframes ds-orbit { to { transform: translate(-50%, -50%) rotate(360deg); } }

/* the mark, in TWO layers: the partner's own colours as the box's background, and
   its black parts as a MASK painted in the page's ink (`--p8`: near-black on the
   light skin, near-white on the dark one). A partner's mark is drawn for a white
   page; this is how it keeps its colour AND reads on ours. Each mark's two files and
   its ratio are the `--<key>` rules below; site-src/partners/ says how they are made. */
.ds-app .ds-partner__logo {
  display: block; position: relative; z-index: 1;
  width: min(90%, 400px); aspect-ratio: 3 / 2;
  background-position: center; background-size: contain; background-repeat: no-repeat;
  transition: transform .3s ease;
}
.ds-app .ds-partner__logo::after {
  content: ""; position: absolute; inset: 0;
  background-color: rgb(var(--p8));
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.ds-app a.ds-partner__stage:hover .ds-partner__logo { transform: scale(1.03); }
/* Instigate: the globe held up by four figures and a lattice (instigate-ink / -globe) */
.ds-app .ds-partner__logo--instigate { aspect-ratio: 236 / 153; background-image: url("images/partners/instigate-globe.svg"); }
.ds-app .ds-partner__logo--instigate::after {
  -webkit-mask-image: url("images/partners/instigate-ink.svg"); mask-image: url("images/partners/instigate-ink.svg");
}

/* their address, as a pill at the foot of the stage */
.ds-app .ds-partner__host {
  position: absolute; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 1;
  padding: 6px 14px; border-radius: 999px; white-space: nowrap;
  color: rgb(var(--p4)); background: rgba(var(--ds-surface), .82);
  border: 1px solid rgba(var(--p4), .16);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: color .25s ease, border-color .25s ease;
}
.ds-app.dark .ds-partner__host { background: rgba(var(--p7), .78); }
.ds-app .ds-partner__host i { font-size: 14px; }
.ds-app a.ds-partner__stage:hover .ds-partner__host { color: rgb(var(--p1)); border-color: rgba(var(--p1), .35); }
.ds-app.dark a.ds-partner__stage:hover .ds-partner__host { color: rgb(var(--p8)); border-color: rgba(var(--p1), .6); }

/* (c) THE COPY */
.ds-app .ds-partner__eyebrow { letter-spacing: .08em; text-transform: uppercase; margin-bottom: 10px; }
.ds-app .ds-partner__title { line-height: 1.12; }
.ds-app .ds-partner__lead { margin-top: 14px; font-size: 19px; line-height: 1.55; max-width: 60ch; }
.ds-app .ds-partner__body { gap: 12px; margin-top: 18px; max-width: 64ch; }
.ds-app .ds-partner__tags { margin-top: 24px; }
.ds-app .ds-partner__cta { margin-top: 30px; }

/* (d) THE FIGURES: the case card's ruled strip, as many columns as there are facts */
.ds-app .ds-partner__facts {
  grid-template-columns: repeat(var(--ds-n, 3), minmax(0, 1fr));
  margin-top: 44px; border-top: 1px solid rgba(var(--p4), .16);
}
.ds-app .ds-partner__fact { padding: 26px 20px 4px; }
.ds-app .ds-partner__fact + .ds-partner__fact { border-left: 1px solid rgba(var(--p4), .16); }

@media (max-width: 991px) {
  .ds-app .ds-partner { padding: 36px 28px 30px; border-radius: 24px; }
  /* the address pill keeps its own strip at the foot, so the mark never sits under it */
  .ds-app .ds-partner__stage { aspect-ratio: 16 / 9; padding: 5% 12% 64px; }
  .ds-app .ds-partner__logo { width: min(56%, 360px); }
}
/* a phone: the figures become rows — the number, then what it counts */
@media (max-width: 575px) {
  .ds-app .ds-partner { padding: 22px 18px 24px; border-radius: 20px; }
  .ds-app .ds-partner__stage { aspect-ratio: 4 / 3; border-radius: 18px; padding: 5% 8% 56px; }
  .ds-app .ds-partner__logo { width: 78%; }
  .ds-app .ds-partner__host { bottom: 14px; }
  .ds-app .ds-partner__lead { font-size: 17px; }
  .ds-app .ds-partner__facts { grid-template-columns: 1fr; margin-top: 30px; }
  .ds-app .ds-partner__fact { display: flex; align-items: baseline; gap: 14px; padding: 16px 4px; }
  .ds-app .ds-partner__fact + .ds-partner__fact { border-left: 0; border-top: 1px solid rgba(var(--p4), .16); }
  .ds-app .ds-partner__fact .ds-case__value { font-size: 30px; margin-bottom: 0; min-width: 4.2ch; }
}
@media (prefers-reduced-motion: reduce) {
  .ds-app .ds-partner__rings i { animation: none; }
  .ds-app .ds-partner__stage, .ds-app .ds-partner__logo { transition: none; }
}

/* (e) THE ALLIANCE — the banner's drawing. Ours in the brand blue, theirs in the
       mark green, the links running from one colour into the other. */
.ds-app .ds-art__allyaura { filter: blur(26px); }
.ds-app .ds-art__allyaura--a { fill: rgba(var(--p1), .10); }
.ds-app .ds-art__allyaura--b { fill: rgba(var(--p3), .10); }
.ds-app.dark .ds-art__allyaura--a { fill: rgba(var(--p1), .24); }
.ds-app.dark .ds-art__allyaura--b { fill: rgba(var(--p2), .12); }
.ds-app .ds-art__allyedge path { stroke-width: 1.5; stroke-linecap: round; }
.ds-app .ds-art__allyedge--a { stroke: rgba(var(--p1), .40); }
.ds-app .ds-art__allyedge--b { stroke: rgba(var(--p3), .40); }
.ds-app.dark .ds-art__allyedge--a { stroke: rgba(var(--p1), .62); }
.ds-app.dark .ds-art__allyedge--b { stroke: rgba(var(--p2), .38); }
.ds-app .ds-art__allynode--a { fill: rgba(var(--p1), .95); }
.ds-app .ds-art__allynode--b { fill: rgba(var(--p3), .95); }
.ds-app.dark .ds-art__allynode--b { fill: rgba(var(--p2), .95); }
.ds-app .ds-art__allynode--hub { fill: rgb(var(--p5)); stroke-width: 3; }
.ds-app .ds-art__allynode--a.ds-art__allynode--hub { stroke: rgb(var(--p1)); }
.ds-app .ds-art__allynode--b.ds-art__allynode--hub { stroke: rgb(var(--p3)); }
.ds-app.dark .ds-art__allynode--b.ds-art__allynode--hub { stroke: rgb(var(--p2)); }
.ds-app .ds-art__allylink path { stroke-width: 2.6; stroke-linecap: round; opacity: .9; }
/* a dash of light crossing each link; the gap is longer than any link, so one
   dash is on a link at a time, and the offset carries it past the far end */
.ds-app .ds-art__allysig path {
  stroke: rgb(var(--p6)); stroke-width: 3.4; stroke-linecap: round;
  stroke-dasharray: 14 400; stroke-dashoffset: 14;
  filter: drop-shadow(0 0 5px rgba(var(--p2), .9));
  animation: ds-ally-flow 3.3s cubic-bezier(.45, 0, .55, 1) infinite;
}
.ds-app:not(.dark) .ds-art__allysig path { stroke: rgb(var(--p3)); filter: drop-shadow(0 0 4px rgba(var(--p3), .55)); }
@keyframes ds-ally-flow {
  0%   { stroke-dashoffset: 14;   opacity: 0; }
  12%  { opacity: 1; }
  82%  { opacity: 1; }
  100% { stroke-dashoffset: -150; opacity: 0; }
}
.ds-app .ds-art__allyping {
  fill: none; stroke: rgba(var(--p1), .7); stroke-width: 2;
  transform-box: fill-box; transform-origin: center;
  animation: ds-ally-ping 2.8s ease-out infinite;
}
.ds-app .ds-art__allyping--b { stroke: rgba(var(--p3), .7); animation-delay: 1.4s; }
.ds-app.dark .ds-art__allyping--b { stroke: rgba(var(--p2), .7); }
@keyframes ds-ally-ping {
  0%       { transform: scale(1);   opacity: .9; }
  70%,100% { transform: scale(2.6); opacity: 0; }
}

/* -- 75 ------------------------------------------------------------------
   THE LIVE BACKUP COPY ON /pricing (2026-10-18). The switch sits in the "Scale"
   group, under the size slider it is priced from, and on-premise takes BOTH out
   of the bill — the database is not charged on your own servers, so neither is
   its copy. §49's dim rule only ever reached `.ds-calc__ctl` (the sliders and the
   fieldsets); a switch is a `.ds-calc__twrap`, so without this line the slider
   greyed out and the switch beside it stayed bright while both were dead. */
.ds-app .ds-calc__twrap.is-off { opacity: .45; }
.ds-app .ds-calc__twrap.is-off .ds-calc__toggle { cursor: not-allowed; }

/* -- 76 ------------------------------------------------------------------
   A CONTROL THE PRICE LIST NO LONGER SELLS (2026-10-19, work-case/14). The
   figures on /pricing come from the billing service now, and it can say that a
   support level, a specialist or a switch is not offered at all — `apply()` in
   ds-pricing.js then hides that control and unchecks it.

   ⛔ `hidden` ALONE WOULD NOT HIDE ONE OF THEM. The attribute's `display: none`
   comes from the UA sheet, and an author `display` of ANY specificity beats it:
   §415 gives `.ds-calc__opt` `display: block`, so a support card marked hidden
   would have stayed on the page, selectable, priced and wrong. The lines and the
   one-time box already carry their own rule for exactly this reason (§507, §513);
   these are the rest of the calculator's own boxes. */
.ds-app .ds-calc__opt[hidden],
.ds-app .ds-calc__ctl[hidden],
.ds-app .ds-calc__twrap[hidden],
.ds-app .ds-calc__subhead[hidden] { display: none; }

/* -- 77 ------------------------------------------------------------------
   A ROW OF SUPPORT CARDS THAT IS NOT THREE (2026-10-19, work-case/14). §43
   sets two columns and §44 three; `apply()` re-counts the row when the price
   list stops selling a level, so one card and four are both reachable now —
   and both fell back to the two-column rule, which left a single surviving
   card sitting in half a row and four cards wrapping 2×2. */
.ds-app .ds-calc__seg--1 { grid-template-columns: 1fr; }
.ds-app .ds-calc__seg--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 992px) {
  .ds-app .ds-calc__seg--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 575px) {
  .ds-app .ds-calc__seg--1, .ds-app .ds-calc__seg--4 { grid-template-columns: 1fr; }
}

/* -- 78 ------------------------------------------------------------------
   ONE PAGE LOAD, ONE SET OF FIGURES (owner, 2026-10-19: "показывает 10 потом
   сразу меняет на 5 ... глаз режет").

   Measured on the stand: the page paints at 231 ms and the billing service's
   answer is applied at 430 ms, so a rate the owner changed a minute ago
   arrived as a visible correction — the seed's figures for a fifth of a
   second, and then the real ones. Both numbers right, and the page looking
   like it changed its mind.

   ⛔ THE STYLESHEET HAS TO BE THE ONE THAT HOLDS THEM, BECAUSE SCRIPT CANNOT.
   The platform writes `defer="defer"` on every global resource (seen in the
   served <head>), and a deferred script runs only after the document has been
   parsed — measured in a real load: the calculator is painted with the seed's
   figures, and only THEN does ds-pricing.js get to run. A veil put on from
   script therefore arrives too late to prevent anything: it fades out numbers
   the visitor has already read, and fades them back in changed. That version
   of this section was strictly worse than the flicker it was written for.

   So the figures are held back from the FIRST PAINT, by a render-blocking
   stylesheet, and released by whichever comes first:
     · the answer — ds-pricing.js puts `ds-calc-shown` on <html> the moment the
       figures are final (applied, refused, or no runtime to ask with), and the
       hold ends instantly, with no fade to draw the eye to it;
     · this animation's own deadline, 900 ms, which is the ONLY deadline in the
       mechanism. It belongs here and not in the script for the same reason the
       hold does: a visitor whose JS is blocked, or whose ds-pricing.js never
       arrives, gets the quote the build rendered — late, but on screen and
       correct. The stylesheet can hide a price only for as long as it takes
       itself to show it again.

   `visibility` goes with the opacity so an invisible slider cannot be dragged
   into a value the answer is about to overwrite; the box keeps its size either
   way, so nothing on the page moves when the figures appear. */
@keyframes ds-calc-hold {
  0%, 72% { opacity: 0; visibility: hidden; }
  100%    { opacity: 1; visibility: visible; }
}
/* the same deadline without the fade, for a reader who asked for no motion */
@keyframes ds-calc-hold-plain {
  0%, 99% { opacity: 0; visibility: hidden; }
  100%    { opacity: 1; visibility: visible; }
}
.ds-app .ds-calc { animation: ds-calc-hold 900ms ease-out both; }
html.ds-calc-shown .ds-app .ds-calc { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .ds-app .ds-calc { animation-name: ds-calc-hold-plain; }
}
