/* ==========================================================================
   МИРАЗОНИТ — clean-code rebuild of the Tilda export.

   The golden reference is 1920x900 and it is untouchable: every other screen is that
   composition SCALED, not re-laid-out. Above 900px wide site.js gives <body> a CSS `zoom`
   so the page always lays out at the reference width; below 900 it reflows, and section 28
   is where that lives. The header here used to say there were no responsive rules in this
   file — there are three hundred lines of them, and a stale map is worse than no map.
   ========================================================================== */

/* --------------------------------------------------------------- 1. Fonts */

@font-face {
    font-family: 'TildaSans';
    font-style: normal;
    font-weight: 250 1000;
    font-display: swap;
    src: url('../fonts/TildaSans-VF.woff2') format('woff2-variations'),
         url('../fonts/TildaSans-VF.woff') format('woff-variations');
}

/* -------------------------------------------------------------- 2. Tokens */

:root {
    /* colour */
    --c-green-deep:  #114739;   /* section headings                       */
    --c-green:       #004533;   /* body copy, dark accents                */
    --c-orange:      #f54700;   /* accent headings, step titles           */
    --c-orange-soft: #f44c04;   /* inline accent inside the hero CTA      */
    --c-red:         #f52200;   /* small "нажмите подробнее" notes        */
    --c-lime:        #10ea00;   /* hero subtitle, footer contacts         */
    --c-ink:         #000;
    /* The three dark plates on the hero are NOT solid black in the source — Tilda puts the
       opacity on the background layer only, so the text above stays fully opaque. Here the
       alpha lives in the background colour for the same reason. */
    --c-plate-header: rgb(0 0 0 / .85);
    --c-plate-card:   rgb(0 0 0 / .75);
    --c-plate-cta:    rgb(0 0 0 / .70);
    --c-paper:       #fff;
    /* The alternating ground. A plain neutral grey — the same density as the tinted version it
       replaces, but with no cast at all: with green cards, orange buttons and a green palette
       already on the page, a tinted ground made the whole thing read as many-coloured. */
    --c-paper-warm:  #e6e6e6;
    --c-card-dark:   #050404;   /* footer card                            */

    /* gradients lifted verbatim from the source */
    --g-btn-orange: linear-gradient(0.25turn, rgb(255 159 76) 0%, rgb(150 40 0) 100%);
    --g-btn-green:  linear-gradient(0.25turn, rgb(80 220 80) 0%, rgb(0 80 30) 100%);
    --g-band:       linear-gradient(0deg, #0f591b 33%, #1b7313 68%);
    --g-stat:       linear-gradient(178.56deg, #74da1b 46%, rgb(11 109 83 / 0) 100%);
    --g-email:      linear-gradient(178.56deg, #47e22e 46%, rgb(11 109 83 / 0) 100%);
    --g-heading:    linear-gradient(76.32deg, #f28e1f 0%, #ff5207 86%);

    /* layout */
    --w-hero:    1458px;  /* hero card row + CTA bar          */
    --w-content: 1458px;  /* every content section — same box as the hero plate */
    /* The source hero row is NOT centred: Tilda anchors it to a 1200 grid as
       calc(50% - 600px - 106px), i.e. 23px right of a centred 1458 box. The
       shift is reproduced with one translate so the parity gate is exact and
       the normalization pass can delete a single line to centre it.
       That offset is now ZERO: the parity pass is long over, and 23px off the page's centre
       reads exactly as what it is — a plate that has slid sideways, with more empty room on one
       side than the other. Everything centres on the window now. */
    --hero-offset: 0px;
    --r-card:    12px;
    --r-nav:     15px;

    /* SPACING SCALE. The Tilda source hand-placed every gap, so the same relationship showed up
       as 14, 18, 22, 26, 27, 28, 30, 34, 38, 40, 42, 45, 46 and 55 px in different places.
       Normalized to seven steps; every vertical rhythm below is expressed in them.

       Widened by a consistent 1.28 on 2026-07-27: with the body copy dropped to 19px the old
       values read as cramped. One factor for every step, so the relationships between them are
       untouched and the whole site breathes by the same amount. THE OWNER'S "more air" OUTRANKS
       these numbers — if a block still reads tight, widen the scale, never a single margin.

       Widened again the same day against FlippingStroy's measured values — the owner's reference
       for what "enough air" means. There: sections 92px top and bottom, section heading to its
       content 54px. Ours now match. */
    --s-xs:  12px;   /* icon-to-label, inline pairs             */
    --s-sm:  24px;   /* label-to-control, small stacks          */
    --s-md:  38px;   /* sibling cards, button rows, paragraphs  */
    --s-lg:  50px;   /* heading-to-body, two-column gutter      */
    --s-xl:  60px;   /* section title to its content            */
    --s-2xl: 92px;   /* section padding — FlippingStroy's figure */
    --s-3xl: 124px;  /* between the technology steps            */

    /* CARD. One padding, one border, one radius for every bordered card on the site.
       The vertical padding goes from 28 to 48: "зажато всё в контейнерах" was about this number,
       and a 1458px-wide card needs far more room at its top and bottom than a narrow one. */
    --card-pad-y: 48px;
    --card-pad-x: 56px;
    /* No colour in a card's edge — glass has none. A hairline of light instead, which the
       ::before gradient below then carries round the corners. */
    --card-border: 1px solid rgb(255 255 255 / .75);

    /* SURFACES. Everything below is what the dark theme rewrites, and nothing else is. Keeping
       them in one place is what makes dark an independent expression of the same system rather
       than a set of scattered overrides: geometry, spacing and type never move, only the
       material does. Light values here; the dark ones are in section 2b. */
    --c-glass:      rgb(255 255 255 / .52);   /* every glazed card                   */
    --c-card-solid: #fff;                     /* the product card, which is opaque   */
    --c-field:      #fff;                     /* form fields on a dark plate         */
    --c-field-ink:  #000;
    --glass-hi:     rgb(255 255 255 / .9);    /* inset hairline along the top edge    */
    --glass-lo:     rgb(255 255 255 / .35);   /* and the fainter one along the bottom */
    --glass-edge:   linear-gradient(135deg,
                        rgb(255 255 255 / 1) 0%,
                        rgb(255 255 255 / .55) 12%,
                        rgb(255 255 255 / .10) 42%,
                        rgb(0 40 30 / .16) 72%,
                        rgb(255 255 255 / .70) 100%);
    --glass-edge-photo: linear-gradient(135deg,
                        rgb(255 255 255 / .85), rgb(255 255 255 / .06) 45%, rgb(245 71 0 / .28));
    --shadow-card:  0 2px 6px rgb(0 69 51 / .07), 0 20px 48px rgb(0 69 51 / .16);
    --shadow-card-hover: 0 22px 48px rgb(0 69 51 / .16);
    --shadow-photo: 0 2px 4px rgb(0 69 51 / .06), 0 14px 34px rgb(0 69 51 / .12);
    --c-rail:       rgb(0 69 51 / .35);       /* the scroll rail over a light page   */
    --c-crumb:      #9bb3aa;                  /* breadcrumb separators               */

    /* type */
    --f: 'TildaSans', Arial, Helvetica, sans-serif;
}

/* -------------------------------------------------------- 2b. The dark theme

   Not an inversion — the same system in a different material. Nothing structural changes here:
   no geometry, no spacing token, no radius, no font size. The page ground drops to a graphite
   that is close to black without being it, and the blocks are told apart the way they are in
   light — by a ground one step lighter, never by a line.

   The greens carry the faintest cast so the greys belong to this site rather than to any site,
   but they stay near-neutral on purpose: the owner had the green removed from the light theme's
   alternating ground for being one colour too many, and that judgement holds here.

   The hero and the footer are deliberately untouched. Both already sit on a photograph behind a
   near-black plate, which is to say they were already dark; re-tinting them would only make the
   dark theme look like a different site rather than the same one at night. */

html[data-theme='dark'] {
    /* These grounds were lightened once, on a report that they read as almost black, and put back
       the same day: the owner's monitor brightness had been turned down, and at normal brightness
       the original depth is what they want. Do not lighten them again without a fresh look. */
    --c-paper:       #101413;   /* page ground                                       */
    --c-paper-warm:  #171d1b;   /* the alternating ground — one step up, not down    */
    --c-green:       #d3ddd8;   /* body copy                                         */
    --c-green-deep:  #edf4f0;   /* section headings                                  */
    --c-orange:      #ff6a2b;   /* #f54700 is too deep to read as an accent on black */
    --c-red:         #ff5f43;

    --c-glass:       rgb(226 244 236 / .05);
    --c-card-solid:  #1a211e;
    --glass-hi:      rgb(255 255 255 / .10);
    --glass-lo:      rgb(255 255 255 / .028);
    --glass-edge:    linear-gradient(135deg,
                        rgb(255 255 255 / .30) 0%,
                        rgb(255 255 255 / .12) 12%,
                        rgb(255 255 255 / .02) 42%,
                        rgb(0 0 0 / .34) 72%,
                        rgb(255 255 255 / .16) 100%);
    --glass-edge-photo: linear-gradient(135deg,
                        rgb(255 255 255 / .34), rgb(255 255 255 / .03) 45%, rgb(255 106 43 / .30));
    --card-border:   1px solid rgb(255 255 255 / .10);
    --shadow-card:   0 2px 6px rgb(0 0 0 / .40), 0 20px 48px rgb(0 0 0 / .55);
    --shadow-card-hover: 0 22px 48px rgb(0 0 0 / .60);
    --shadow-photo:  0 2px 4px rgb(0 0 0 / .40), 0 14px 34px rgb(0 0 0 / .48);
    --c-rail:        rgb(211 221 216 / .30);
    --c-crumb:       #55645e;

    color-scheme: dark;
}

/* --------------------------------------------------------------- 3. Reset */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: var(--f);
    font-size: 16px;
    line-height: 1.45;
    color: var(--c-green);
    background: var(--c-paper);
    -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; border: 0; }
a   { color: inherit; }
ul  { margin: 0; padding-left: 1.15em; }
li  { margin: 0; }
p   { margin: 0; }
dl, dd { margin: 0; }
h1, h2, h3, h4 { margin: 0; font-weight: 700; }
button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible { outline: 3px solid var(--c-orange); outline-offset: 3px; }

.visually-hidden {
    position: absolute; width: 1px; height: 1px; margin: -1px;
    padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* The content column now matches the hero's lead-magnet plate exactly — same width and the
   same 23px offset — so every block on the page shares one left and one right edge. */
.container      { width: var(--w-content); margin-inline: auto; translate: var(--hero-offset) 0; }
.container--wide{ width: var(--w-hero);    margin-inline: auto; translate: var(--hero-offset) 0; }

/* --------------------------------------------------------------- 4. Buttons

   The source builds every call-to-action out of a custom HTML widget: a fixed
   300x50 gradient pill with a shine sweep and a slow press pulse. Reproduced
   here as one component instead of nine copies of inline CSS. */

.btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 300px;
    height: 50px;
    padding: 0 14px;
    border: 0;
    border-radius: var(--r-card);
    overflow: hidden;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.2;
    color: #fff;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    background: var(--g-btn-orange);
    box-shadow: 0 6px 12px rgb(0 0 0 / .3);
}

.btn--green { background: var(--g-btn-green); }
.btn--lg    { font-size: 18px; }

/* The Tilda widget swept a highlight across every button every 2 seconds and pulsed the whole
   button every 8, which read as a button clicking itself. Replaced by one slow sheen that starts
   only after the button has been on screen a while — noticed once, never nagging. */
/* FlippingStroy's sheen, ported exactly — including the one line that makes it work.
   `isolation: isolate` gives the button its own stacking context, and inside one, a child at
   z-index -1 paints ABOVE the element's background but BELOW its text. That is the whole trick:
   the light passes underneath the label instead of sweeping across it, which is the difference
   between a soft glow and the hard Tilda highlight. Without the isolation the layer escapes to
   the page and hides behind the button's own opaque gradient — which is what it had been doing,
   invisibly, all along. */
.btn { isolation: isolate; }

.btn::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: linear-gradient(110deg, transparent 32%, rgb(255 240 224 / .44) 50%, transparent 68%);
    background-size: 220% 100%;
    background-position: 0% 50%;
    opacity: 0;
    pointer-events: none;
}

/* Back and forth on an ease-in-out, not a dart across and a jump home — the light never arrives
   or leaves, it just drifts. */
.btn.is-attentive::after {
    opacity: 1;
    animation: btn-sheen 3.6s ease-in-out infinite alternate;
}

@keyframes btn-sheen {
    0%   { background-position: 0% 50%; }
    100% { background-position: 100% 50%; }
}

@media (prefers-reduced-motion: reduce) {
    .btn::after { animation: none; opacity: 0; }
}

/* -------------------------------------------------------------- 5. Header */

/* On the home page the header floats over the hero photograph, so it is translucent, exactly
   as in the source. On the inner pages there is nothing behind it — there it stays solid and
   takes up real space in the flow. */
.site-header {
    position: absolute;
    inset: 0 0 auto;
    z-index: 5;
    height: 67px;
    background: var(--c-plate-header);
}

.site-header--solid {
    position: relative;
    inset: auto;
    background: var(--c-ink);
}

/* ---------------------------------------------------------- 5b. Breadcrumbs */

.breadcrumbs {
    padding: 22px 0 0;
    background: var(--c-paper);
}

.breadcrumbs ol {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 17px;
    line-height: 26px;
}

.breadcrumbs li + li::before {
    content: '/';
    margin-right: 10px;
    color: var(--c-crumb);
}

.breadcrumbs a { color: var(--c-orange); text-decoration: none; }
.breadcrumbs a:hover { text-decoration: underline; }
.breadcrumbs [aria-current='page'] { color: var(--c-green); }

.site-header__inner {
    display: flex;
    align-items: center;
    height: 100%;
    width: var(--w-hero);
    margin-inline: auto;
    translate: var(--hero-offset) 0;
}

/* The tagline is TEXT, not part of the picture. Baked into the logo it was a heavy, tightly
   tracked face that turned to mush at 204px wide; as live type it stays crisp at any size, keeps
   the exact brand green, and its weight is a number we can choose. The wordmark and the leaf are
   the original artwork, untouched. */
.site-header__logo {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    width: 204px;
    text-decoration: none;
}

.site-header__wordmark { width: 204px; height: auto; }

.site-header__tagline {
    font-size: 8.5px;
    font-weight: 500;
    line-height: 1;
    letter-spacing: .105em;
    color: var(--c-lime);
    white-space: nowrap;
    text-transform: uppercase;
}

.site-nav {
    display: flex;
    align-items: center;
    gap: 19px;
    margin-left: 54px;
}

.site-nav a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 38px;
    padding: 0 10px;
    border-radius: var(--r-nav);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.55;
    color: #fff;
    text-align: center;
    text-transform: uppercase;
    text-decoration: none;
    transition: background-color .18s ease;
}

/* No plate behind a menu item — the underline is the whole signal. */
.site-nav a:hover { background: transparent; }

.site-header__contacts {
    margin-left: auto;
    padding-right: 44px;
    text-align: right;
    line-height: 1;
    translate: 0 -1px;
}

.site-header__phone {
    display: block;
    font-size: 22px;
    font-weight: 700;
    line-height: 27px;
    color: #fff;
    text-decoration: none;
    white-space: nowrap;
}

.site-header__mail {
    display: block;
    margin-top: -3px;
    font-size: 16px;
    font-weight: 500;
    line-height: 20px;
    text-decoration: none;
    color: var(--c-lime);
}

/* ---------------------------------------------------------------- 6. Hero */

.hero {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* max(), not a fixed height: the chevron is fixed to the BOTTOM OF THE WINDOW, so on a window
       shorter than the hero it used to land straight on the lead-magnet plate. Making the hero at
       least a windowful tall means the plate always sits one bottom-padding above the window edge,
       and the chevron always has that padding to itself — at any window height. */
    min-height: max(820px, 100vh);
    /* 84 top / 112 bottom, not 104 / 92. The block is centred vertically, so trimming the card
       alone only lifted the group by HALF of what came off it — the freed space was split above
       and below. Moving 20px from the top padding to the bottom shifts the centre up by the
       missing amount, and on a window too short to centre anything it is a straight lift off the
       top. 10px of it was handed back — 50 read as too high.
       Measured plate-to-chevron clearance: 68px at 900, 47 at 860 (a bookmarks bar), 7 at 820. */
    /* 144 / 52, not 94 / 102. The block is centred between its own paddings, so moving 50px from
       the bottom to the top carries the card and the lead-magnet plate 50px down together while
       the photograph behind them — a sibling, not a child — does not move at all. */
    padding: 144px 0 52px;
    overflow: hidden;
}

.hero__bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    /* THE APPROVED FRAMING, WRITTEN AS A RULE INSTEAD OF FOUR FIXED PIXEL VALUES.

       It used to be a 2494x1295 image pinned at left -396 / top -321. That is exactly right on a
       1920x900 window and wrong on every taller one: the picture ended 974px down, so a 1080 or
       1200 window showed a white band under the hero. A photograph sized by one fixed side inside
       a block that grows with the window is the defect this project has hit before.

       The numbers below are the same crop, derived rather than typed. The image is 1.2990x the
       window wide (2494/1920) and hangs 396px left of it (0.6899 of its total overhang), and it
       must reach from 321px above the block to its bottom edge — so its width can never fall
       below (height + 321) x 2494/1295. At 1920x900 both terms resolve to the original 2494 and
       -396 to the pixel; above that the picture grows instead of running out. */
    /* Percentages, not vw: under `zoom` a viewport unit still measures the UNZOOMED window,
       so on a 1280 laptop 129.9vw sized the picture for 1280 while the page laid out at 1920
       — the photograph stopped a third of the way across and the rest went black. A percent
       resolves against this block, which is the page's own 1920. */
    /* The same expression as the hero's own min-height, cap included — the photograph is sized
       for the block it fills, and a block that stops at 1400 must not be handed a 2073px crop. */
    --hero-h: clamp(820px, calc(100vh / var(--zoom, 1)), 1400px);
    --hero-img-w: max(129.9%, calc(var(--hero-h) * 1.9259 + 618px));
}

.hero__bg img {
    position: absolute;
    top: -321px;
    /* The farmer stands well right of centre in the frame, so the crop is deliberately off-centre
       — 69% of the horizontal overhang is taken from the left. */
    left: calc((100% - var(--hero-img-w)) * .6899);
    width: var(--hero-img-w);
    height: auto;
    max-width: none;
}

.hero__inner { position: relative; z-index: 1; }

/* The owner asked for the card to grow, and it grew in both directions — but the request was for
   HEIGHT. 130px comes back off the right edge here, and the two grids below give back the same
   share, so the bullets and the factoids close up by exactly as much as the plate does. */
.hero__card {
    width: 990px;
    /* 64px at the foot, not 74. Together with the 20 taken off the factoids' top margin the card
       is 30px shorter, which is 30px the lead-magnet plate and the chevron below it get back —
       the chevron is fixed to the WINDOW, so every pixel of card height eats into its clearance
       once a browser toolbar shortens the viewport. */
    padding: 46px 70px 64px;
    border-radius: var(--r-card);
    background: var(--c-plate-card);
}

/* The hero plates were given the same glass edge as the cards below and the owner took it
   straight back off: on a photograph the hairline reads as a seam rather than as glass.
   Their material is the plate's own translucency, nothing else. */

.hero__brand {
    display: flex;
    align-items: center;
    gap: 8px;
}

.hero__mark { width: 54px; height: 54px; flex: 0 0 auto; }

.hero__title {
    display: flex;
    align-items: flex-start;
    font-size: 52px;
    font-weight: 600;
    line-height: 63px;
    color: #fff;
    letter-spacing: 0;
}

.hero__title sup {
    font-size: 25px;
    font-weight: 700;
    line-height: 1;
    margin-top: 3px;
    margin-left: 4px;
}

.hero__subtitle {
    display: inline-block;
    margin-top: 13px;
    margin-left: 3px;
    /* In caps at 21px the line measures 757px against the 693px it took in mixed case — nine per
       cent wider, inside the tenth the owner allowed, and 93px clear of the card's inner edge.
       The line-height stays at 35 so the card keeps the height it was signed off at. */
    font-size: 21px;
    font-weight: 600;
    line-height: 35px;
    color: var(--c-lime);
    text-transform: uppercase;
    text-decoration: none;
}

.hero__benefits {
    display: grid;
    grid-template-columns: 452px auto;
    row-gap: 14px;
    column-gap: 0;
    margin-top: 50px;
    padding-left: 6px;
}

.hero__benefit {
    display: flex;
    align-items: center;
    gap: 18px;
    font-size: 28px;
    font-weight: 500;
    line-height: 45px;
    color: #fff;
}

.hero__benefit img { width: 45px; height: 45px; flex: 0 0 auto; }

.hero__stats {
    display: grid;
    grid-template-columns: 242px 256px 217px auto;
    margin-top: 46px;
    padding-left: 11px;
}

.hero__stat-value {
    font-size: 43px;
    font-weight: 800;
    line-height: 63px;
    background: var(--g-stat);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.hero__stat-label {
    margin-top: -3px;
    font-size: 18px;
    font-weight: 600;
    line-height: 21px;
    color: #fff;
}

.hero__cta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 40px;
    height: 96px;
    margin-top: 46px;
    padding: 0 118px 0 58px;
    border-radius: var(--r-card);
    background: var(--c-plate-cta);
}

.hero__cta p {
    font-size: 27px;
    font-weight: 600;
    line-height: 40px;
    color: #fff;
}

.hero__cta em { font-style: normal; color: var(--c-orange-soft); }

/* ------------------------------------------------------------ 7. Sections */

.section { padding: var(--s-2xl) 0; background: var(--c-paper); }
/* Flipping the theme should read as the light going down, not as a page swap. Only the grounds
   and the copy fade; geometry never moves, so there is nothing else to animate. */
body, .section, .breadcrumbs, .page-doc { transition: background-color .35s ease, color .35s ease; }
/* Blocks are told apart by their ground, not by a line drawn between them. */
#products, #cases, #about { background: var(--c-paper-warm); }

.section__title {
    margin-bottom: var(--s-xl);
    font-size: 30px;
    font-weight: 700;
    line-height: 1.15;
    color: var(--c-green-deep);
    text-align: center;
    text-transform: uppercase;
}

.section__title--plain { text-transform: none; }
.section__title em { font-style: normal; color: var(--c-orange); }

/* BODY COPY. 19px on a 32px line, not 22 on 31. The smaller size reads as ordinary body text
   rather than large print, and the line spacing it frees is given straight back as air: the ratio
   goes from 1.41 to 1.68, which is where continuous Russian prose is comfortable.

   Every gap inside a text block comes from the spacing scale and nothing else — no em values, no
   one-off numbers. That is the whole rule, and because `.rich` is the body-copy component on every
   page, the same rhythm holds across the site. */
.rich { font-size: 19px; font-weight: 400; line-height: 32px; color: var(--c-green); }
.rich strong { font-weight: 700; }
.rich ul,
.rich ol { padding-left: 22px; margin: 0; }
.rich ul li { list-style: disc; }
.rich ol li { list-style: decimal; }
.rich li + li { margin-top: var(--s-xs); }
.rich p + p { margin-top: var(--s-sm); }
/* Tilda separated the sub-headed blocks with an empty <p>&nbsp;</p> — a whole blank line plus two
   paragraph margins, about 61px of dead air. The spacers are gone; this is the real gap. */
.rich p + p.rich__block { margin-top: var(--s-md); }
.rich p + ul,
.rich p + ol { margin-top: var(--s-xs); }
.rich ul + p,
.rich ol + p { margin-top: var(--s-sm); }

/* ------------------------------------------- 8. Technology — the three steps */

.steps { display: flex; flex-direction: column; gap: var(--s-xl); }

/* Each step is a wide glazed card of its own, same material as the product and case cards. */
.step {
    padding: var(--card-pad-y) var(--card-pad-x);
    border-radius: var(--r-card);
    border: var(--card-border);
}

.step__title {
    margin-bottom: var(--s-xl);
    font-size: 25px;
    font-weight: 700;
    line-height: 29px;
    color: var(--c-orange);
    text-align: center;
    text-transform: uppercase;
}

.step__body {
    display: grid;
    grid-template-columns: 320px 1fr;
    column-gap: var(--s-xl);
    /* The picture spans the text column exactly: its top edge sits on the first line of copy and
       its bottom edge on the bottom edge of the button. Nothing is pushed anywhere to achieve it —
       the text and its button set the height, and the photograph simply fills it. */
    align-items: stretch;
}

/* Every step reads the same way now — photograph left, copy right — on the owner's word. The
   alternating layout made the eye restart at a different edge on each step. */

/* All three photographs the same height, on the owner's word — said three times, so it is not a
   preference but the rule. They used to stretch to their own text column, which runs 426px on
   steps 1 and 3 and 350px on step 2, and the row read as ragged. */
.step__figure { position: relative; width: 400px; height: 426px; align-self: start; }

.step__figure img.step__photo {
    /* Absolute, so the picture has NO say in how tall the row is. The text column decides that,
       and the frame simply fills whatever height the text ends up needing — which puts the
       bottom of the photograph level with the bottom of the button. */
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: var(--r-card);
}

/* Drawn here rather than painted from a raster. The generated art had a wobbly hand-drawn ring and
   a ragged right edge on the digit 1, and it sat on a solid black disc; the source's own badge was
   a translucent plate. A CSS circle plus a real glyph fixes the edges by construction and lets the
   photograph show through the glass. */
.step__badge {
    position: absolute;
    top: 50%;
    left: 50%;
    /* Centred by translation, not by a -50px margin: the margin was half of the desktop badge and
       stayed half of the desktop badge when the badge shrank, so on a phone the number sat off to
       one side. A percentage translate is always half of whatever size the badge actually is. */
    translate: -50% -50%;
    display: grid;
    place-items: center;
    width: 100px;
    height: 100px;
    border-radius: 50%;
    border: 5px solid var(--c-lime);
    background: rgb(0 0 0 / .34);
    backdrop-filter: blur(10px) saturate(1.25);
    -webkit-backdrop-filter: blur(10px) saturate(1.25);
    box-shadow: 0 8px 20px rgb(0 0 0 / .28), inset 0 1px 0 rgb(255 255 255 / .28);
    font-size: 54px;
    font-weight: 800;
    line-height: 1;
    color: var(--c-lime);
    text-shadow: 0 2px 8px rgb(0 0 0 / .5);
}

/* The source puts the step button under the TEXT column, next to the photo — not under the
   whole two-column body. Keeping it there is what makes the step the right height. */
/* The button lives in the text column and its BOTTOM sits on the photograph's bottom edge — it
   must never drop below the card. The column stretches to the figure's fixed height, so pushing
   the button down with an auto margin lands it exactly there whatever the copy above it does. */
.step__text { display: flex; flex-direction: column; }
/* The button reaches back across the photograph column so it centres on the CARD — which is the
   page's own axis — instead of on the text column it happens to live in. Its bottom still lands on
   the photograph's bottom edge, because it is still the last item of the stretched text column. */
/* Two constraints at once: the button's BOTTOM sits on the photograph's bottom edge, and its
   CENTRE sits on the page's axis — which means it has to reach across the photograph's column.
   Absolute inside the body does both by construction, with no arithmetic to drift: left and right
   pinned to the body's edges makes its centre the body's centre, bottom pinned makes it level with
   the figure. The text column reserves the height so the copy never runs underneath it. */
.step__body { position: relative; }

.step__actions {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    margin: 0;
    text-align: center;
}

.step__text { padding-bottom: 72px; }

/* --------------------------------------------------- 9. The green form band */

.lead-band__title {
    margin: 0 auto var(--s-md);
    max-width: 1100px;
    font-size: 25px;
    font-weight: 600;
    line-height: 36px;
    text-align: center;
    text-transform: uppercase;
    color: var(--c-green);
}

.lead-band__title em { font-style: normal; color: var(--c-orange); }

.lead-band {
    padding: var(--s-md) 0 var(--card-pad-y);
    background: var(--g-band);
}

.lead-form {
    display: grid;
    /* The form spans the same box as every other block on the page, so its left and right edges
       line up with the hero plate. Name and phone got shorter; the space they gave back is the
       contact-method picker. */
    grid-template-columns: 1fr 1fr 260px 300px;
    align-items: start;
    column-gap: var(--s-md);
    width: var(--w-content);
    margin-inline: auto;
    translate: var(--hero-offset) 0;
}

.lead-form__field {
    display: flex;
    align-items: center;
    height: 50px;
    padding: 0 20px;
    border: 0;
    border-radius: var(--r-card);
    background: #fff;
    font-size: 17px;
    color: #000;
    width: 100%;
}

/* An example in the field, not an instruction: pale enough to read as a hint rather than as a
   value someone already typed. */
.lead-form__field::placeholder,
.lead-form__phone input::placeholder,
.contact-form input::placeholder { color: #000; opacity: .38; }

.lead-form__phone {
    display: flex;
    align-items: center;
    height: 50px;
    padding: 0 8px 0 16px;
    border-radius: var(--r-card);
    background: #fff;
}

.lead-form__flag {
    display: inline-block;
    width: 22px;
    height: 15px;
    margin-right: 6px;
    flex: 0 0 auto;
    border-radius: 2px;
    background:
        linear-gradient(180deg, #fff 0 33.3%, #0039a6 33.3% 66.6%, #d52b1e 66.6% 100%);
    box-shadow: 0 0 0 1px rgb(0 0 0 / .12);
}

.lead-form__caret {
    margin-right: 10px;
    font-size: 9px;
    line-height: 1;
    color: #333;
}

.lead-form__phone input { border: 0; outline: 0; background: none; width: 100%; font-size: 17px; }

.lead-form__consent {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    gap: var(--s-xs);
    margin-top: var(--s-sm);
    font-size: 14px;
    line-height: 1.3;
    color: #fff;
}

.lead-form__consent input { width: 16px; height: 16px; accent-color: var(--c-orange); }
.lead-form__consent a { color: #fff; }

.lead-form__status {
    grid-column: 1 / -1;
    min-height: 0;
    margin-top: 6px;
    font-size: 15px;
    color: #fff;
}

/* -------------------------------------------------------- 10. Product cards */

.products { display: flex; flex-direction: column; gap: var(--s-md); }

.product {
    display: grid;
    grid-template-columns: 330px 1fr;
    column-gap: var(--s-lg);
    align-items: center;
    padding: var(--card-pad-y) var(--card-pad-x);
    border: var(--card-border);
    border-radius: var(--r-card);
    background: var(--c-card-solid);
}

.product__figure { display: flex; align-items: center; justify-content: center; }
.product__figure img { width: 330px; height: 367px; object-fit: contain; }

.product__title {
    margin-bottom: var(--s-sm);
    font-size: 25px;
    font-weight: 700;
    line-height: 29px;
    color: var(--c-orange);
    text-transform: uppercase;
}

.product__note {
    margin-top: var(--s-sm);
    font-size: 17px;
    font-weight: 400;
    line-height: 28px;
    color: var(--c-red);
}

.product__actions { display: flex; gap: var(--s-md); margin-top: var(--s-md); }

/* -------------------------------------------------------- 11. Video / demo */

/* This block is the one place on the page that has to fit a WINDOW rather than just look right:
   the owner watches the video without scrolling. Measured from the heading to the bottom of the
   player it was 870px, which clears a 900px viewport but not one with a bookmarks bar open. The
   section keeps the site's rhythm on the outside and gives back 40px of its own padding — the
   player itself is untouched, because shrinking it again was the wrong answer last time. */
/* Normal rhythm above and below, like every other block. The smart scroll lands on the
   heading rather than on the padding, so the gap exists without costing screen. */

/* And the block above it gives up most of its bottom padding rather than pushing the video off
   the screen — 144px of dead air sat between the green band and the heading. */


/* The footnote sits UNDER the player — it annotates the video, and between the heading and the
   picture it read as a subtitle to the heading instead. */
.demo__subtitle {
    margin: var(--s-md) auto 0;
    max-width: 780px;
    font-size: 17px;
    font-weight: 400;
    line-height: 28px;
    color: var(--c-orange);
    text-align: center;
}

.demo__frame {
    position: relative;
    /* Sized so the whole block — heading, note and player — clears a 900px viewport without being
       cut off. The card keeps its full width; only the player inside it got shorter, at 16:9. */
    width: 996px;
    height: 560px;
    margin-inline: auto;
    border-radius: var(--r-card);
    overflow: hidden;
    background: #000;
}

/* The player sits in the same bordered card as a product or a client case, with white space
   around it — the block is as wide as every other block, the video keeps its own size. */
.demo__card {
    width: var(--w-content);
    margin-inline: auto;
    padding: var(--card-pad-y) var(--card-pad-x);
    border: var(--card-border);
    border-radius: var(--r-card);
    /* Real glass, not a hint of it. On the tinted sections the card now clearly sits ON something
       — the ground shows through, colour lifts through the blur, and a bright inside edge catches
       the light along the top. Pronounced enough to read as a material, short of a gimmick. */
    background: var(--c-glass);
    backdrop-filter: blur(20px) saturate(1.45);
    -webkit-backdrop-filter: blur(20px) saturate(1.45);
    box-shadow: 0 1px 0 var(--glass-hi) inset,
                0 -1px 0 var(--glass-lo) inset,
                var(--shadow-card);
    transition: box-shadow .45s cubic-bezier(.16, 1, .3, 1), border-color .45s ease,
                transform .45s cubic-bezier(.16, 1, .3, 1), background-color .35s ease;
}

.demo__card:hover {
    border-color: var(--glass-hi);
    box-shadow: 0 1px 0 var(--glass-hi) inset, var(--shadow-card-hover);
}

.demo__frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* ------------------------------------------------------- 12. Client cases */

.cases { display: flex; flex-direction: column; gap: var(--s-md); }

.case {
    display: grid;
    grid-template-columns: 350px 1fr;
    column-gap: var(--s-lg);
    padding: var(--card-pad-y) var(--card-pad-x);
    border: var(--card-border);
    border-radius: var(--r-card);
}

.case__quote {
    grid-column: 1 / -1;
    margin-bottom: var(--s-md);
    font-size: 18px;
    font-weight: 700;
    font-style: italic;
    line-height: 30px;
    color: var(--c-orange);
    text-align: center;
}

.case__photo {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: var(--r-card);
}

.case__actions { grid-column: 1 / -1; margin-top: var(--s-md); text-align: center; }

/* ------------------------------------------------------------- 13. About */

.about__photo {
    width: 1261px;
    height: 413px;
    margin: 0 auto var(--s-lg);
    object-fit: cover;
    border-radius: var(--r-card);
}

.about__motto {
    margin-bottom: var(--s-md);
    /* Measured, not guessed: in caps this line is 1375px wide at 25px and 1485px at 27px, against
       a 1458px column. 25 keeps it on one line with room to spare even if the copy grows a word. */
    font-size: 25px;
    font-weight: 700;
    line-height: 38px;
    text-transform: uppercase;
    color: var(--c-orange);
}

/* ------------------------------------------------------------ 14. Russia */

/* «Кто мы и во что верим» is now the last light section before the dark footer. */
#about { padding-bottom: var(--s-2xl); }

/* The lead-in above a heading is the SUM of two paddings — the block above closing, and this one
   opening — and that sum is what the eye reads as the gap. Above «в России» it was 92 + 92; above
   the block that follows it, only 46 + 92, because this section's own bottom padding is halved.
   Halving the top the same way makes the two gaps identical at 138. */
#russia { padding-top: calc(var(--s-2xl) / 2); padding-bottom: calc(var(--s-2xl) / 2); }

.russia__lead {
    margin-bottom: var(--s-md);
    font-size: 21px;
    font-weight: 700;
    line-height: 34px;
    color: var(--c-green);
    text-align: center;
}

/* Two people side by side, together exactly as wide as the section. Each half keeps the
   original composition — photo left, role and contacts right. */
.russia__body {
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: var(--s-lg);
    align-items: start;
}

/* Each founder gets a container of their own, glazed like the cards on the tinted sections, so
   the two read as two people rather than one run-on row. */
.person {
    position: relative;
    isolation: isolate;
    display: grid;
    grid-template-columns: 356px 1fr;
    column-gap: var(--s-md);
    align-items: center;
    margin: 0;
    padding: var(--s-md);
    border-radius: var(--r-card);
    border: var(--card-border);
    background: rgb(255 255 255 / .52);
    backdrop-filter: blur(20px) saturate(1.45);
    -webkit-backdrop-filter: blur(20px) saturate(1.45);
    box-shadow: 0 1px 0 rgb(255 255 255 / .9) inset,
                0 2px 6px rgb(0 69 51 / .07),
                0 20px 48px rgb(0 69 51 / .16);
}

.person__photo {
    width: 356px;
    height: 237px;
    object-fit: cover;
    object-position: center top;
    border-radius: var(--r-card);
}

.person__info { margin: 0; }

.person__role {
    /* The caption is only a name now, so it must stay on ONE line in both halves — otherwise
       «Жоржета Коннова» wraps and the two phone numbers stop lining up. The photo width is set
       from that constraint, not the other way round. */
    white-space: nowrap;
    font-size: 25px;
    font-weight: 700;
    line-height: 30px;
    color: var(--c-green);
}

.person__role em { font-style: normal; color: var(--c-orange); }

.person__contacts {
    margin-top: var(--s-xs);
    font-size: 18px;
    font-weight: 700;
    line-height: 30px;
    color: var(--c-green);
}

.person__contacts a { text-decoration: none; white-space: nowrap; }

/* ------------------------------------------------------------ 15. Footer */

.site-footer { position: relative; padding: var(--s-3xl) 0 0; background: #000; }

.site-footer__bg { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.site-footer__bg img { width: 100%; height: 100%; object-fit: cover; }

.site-footer__card {
    position: relative;
    z-index: 1;
    width: var(--w-content);
    margin: 0 auto var(--s-sm);
    translate: var(--hero-offset) 0;
    padding: var(--card-pad-y) var(--card-pad-x);
    border-radius: var(--r-card);
    background: var(--c-plate-card);
}

.site-footer__title {
    font-size: 30px;
    font-weight: 600;
    line-height: 47px;
    color: #fff;
    text-align: center;
    text-transform: uppercase;
}

.site-footer__contacts {
    margin-top: var(--s-md);
    font-size: 25px;
    font-weight: 400;
    line-height: 39px;
    color: var(--c-lime);
    text-align: center;
}

.site-footer__contacts a { text-decoration: none; }

/* Everything else in this card sits on the card's centre line — the heading, the phone, the
   social row, the legal lines. The form was the one thing stretched edge to edge, which is what
   made the block look off. Fixed columns and a centred track put it on the same axis. */
.contact-form {
    display: grid;
    grid-template-columns: 300px 300px 260px 300px;
    justify-content: center;
    column-gap: var(--s-md);
    align-items: end;
    margin-top: var(--s-md);
}

.contact-form label {
    display: block;
    margin-bottom: 6px;
    font-size: 15px;
    font-weight: 700;
    color: #fff;
}

.contact-form input[type='text'],
.contact-form input[type='tel'] {
    width: 100%;
    height: 46px;
    padding: 0 16px;
    border: 0;
    border-radius: var(--r-card);
    background: #fff;
    font-size: 17px;
}

/* fit-content + auto margins, not justify-content: the row is a grid item spanning every track,
   and centring its own contents was not enough to move it off the first column. */
.contact-form__consent {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    width: fit-content;
    margin-inline: auto;
    gap: var(--s-xs);
    margin-top: var(--s-sm);
    font-size: 14px;
    color: var(--c-orange);
}

.contact-form__consent input { width: 16px; height: 16px; accent-color: var(--c-orange); }

.contact-form__status { grid-column: 1 / -1; margin-top: 6px; font-size: 15px; color: #fff; text-align: center; }

.site-footer__social-title {
    margin-top: var(--s-md);
    font-size: 21px;
    font-weight: 400;
    line-height: 34px;
    color: #fff;
    text-align: center;
}

/* Three icons, not five — Instagram and Facebook are gone. A wider gap keeps the shorter row from
   reading as a leftover cluster, and the flex centring balances it on the card's own axis. */
.site-footer__social {
    display: flex;
    justify-content: center;
    gap: var(--s-md);
    margin-top: var(--s-sm);
}

.site-footer__social a { display: block; width: 59px; height: 59px; }
.site-footer__social img { width: 59px; height: 59px; }

/* The whole site sits 23px right of the geometric centre — that is the source's grid, carried by
   --hero-offset on every container and on the footer card above. This strip was centred on the
   raw page instead, so the legal lines sat 23px left of everything else. */
.site-footer__legal {
    position: relative;
    z-index: 1;
    translate: var(--hero-offset) 0;
    padding: 17px 0 24px;
    background: var(--c-plate-header);
    text-align: center;
}

.site-footer__legal-links a {
    display: block;
    font-size: 17px;
    line-height: 26px;
    color: #fff;
    text-decoration: none;
}

.site-footer__legal-links a:hover { text-decoration: underline; }

.site-footer__requisites {
    margin-top: 10px;
    font-size: 15px;
    line-height: 22px;
    color: var(--c-lime);
}

/* ------------------------------------------------- 16. Inner content pages */

/* The same air above the heading as every block on the home page gets. The inner pages opened
   with --s-lg while a section on the front opens with --s-2xl, so a product page started higher
   up the screen than anything the visitor had just been reading — one rhythm now, both ways. */
.page-doc { padding: var(--s-2xl) 0; }

.page-doc__title {
    margin-bottom: var(--s-lg);
    font-size: 25px;
    font-weight: 700;
    line-height: 29px;
    color: var(--c-orange);
    text-align: center;
    text-transform: uppercase;
}

/* The heading of an inner page needs the same air above it as a heading on the home page. There
   the section opens with 85px of nothing before the title; here the title sat 45px below the top
   of its card, and a heading pressed against the edge of a box reads as cramped however much
   space the box itself has around it. The top padding matches the section rhythm; the sides and
   the foot stay the card’s own. */
.page-doc__card {
    padding: var(--s-2xl) var(--card-pad-x) var(--card-pad-y);
    border: var(--card-border);
    border-radius: var(--r-card);
}

/* A CANISTER IS NOT A SCENE, AND THE INTRO IS NOT A NEWSPAPER COLUMN.
   Measured on the inoculant page: the photograph stood 328px tall in a 278px column — spilling
   out of it — while the text beside it ran 921px wide and only 208px deep. Two columns of the
   same block, a hundred pixels apart in height, with the gap sitting under the copy where the
   eye lands. The answer turned out to be the buttons rather than the bottle: moving the order
   pair up under the intro gave the text column the height it was missing, so the canister keeps
   its original 300px and the two columns finish together. The intro also gets a reading measure
   instead of the full card. `width: 100%` on the image rather than a second fixed number — the
   old fixed 300 was wider than the column it sat in, which is how it came to overflow. */
.page-product {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr);
    column-gap: var(--s-xl);
    align-items: start;
}

/* The canister’s top edge lines up with the top of the first LINE OF TYPE, not with the top of
   the text box. A line of text sits below its own box by half its leading — measured here at 9px —
   so aligning the two boxes leaves the picture visibly higher than the sentence beside it, which
   is the thing the eye actually compares. Reset below 700, where the picture floats inside the
   copy instead of standing in a column of its own. */
.page-product__figure { padding-top: 9px; }
.page-product__figure img { width: 100%; height: auto; }

.page-product > .rich { max-width: 780px; }

/* The order pair, now inside the intro column rather than at the foot of the page. Left-aligned
   with the copy above it — centred under a 780px measure would read as a separate band. */
.page-product__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-md);
    margin-top: var(--s-md);
}

.page-doc__actions { display: flex; justify-content: center; gap: var(--s-md); margin-top: var(--s-lg); }

/* ---------------------------------------------------------------- 16b. 404
   A dead link is still a visit. The page keeps the whole site around it — header, footer, the
   consultation form — so the way out is a click rather than the back button, and the number is
   large enough to say what happened before a word is read. It scales with the window because it
   is the only display-size type on the site that has no design of its own to protect. */

.page-404 { text-align: center; }

.page-404__code {
    margin-bottom: var(--s-sm);
    font-size: clamp(38px, 7vw, 92px);
    font-weight: 800;
    line-height: 1.02;
    letter-spacing: -1px;
    color: var(--c-orange);
    text-transform: uppercase;
}

.page-404__lead { max-width: 620px; margin-inline: auto; }

/* ------------------------------------------- 17. Inline accents in rich text */

.rich .accent,
.accent { color: var(--c-orange); }

.page-doc__rest { margin-top: var(--s-lg); }

/* No top padding of its own — the preceding section's bottom padding is the gap. The BOTTOM
   padding matters though: on an inner page this band is the last thing on the page, and without
   it the consent line sits flush against the very edge of the document. */
.lead-section { padding: 0 0 var(--s-2xl); }

.page-doc .rich ul { margin: 4px 0; }

/* ------------------------------------------------- 18. Technology page only */

.tech__lead {
    margin: calc(-1 * var(--s-md)) auto var(--s-xl);
    max-width: 1198px;
    font-size: 21px;
    font-weight: 400;
    line-height: 34px;
    color: var(--c-green);
    text-align: center;
}

.step__more { margin-top: var(--s-md); }
/* Buttons sit centred under their step, all three on the same axis. */


/* ------------------------------------------------------- 19. Block divider

   The source separates the background-less sections with Tilda's T029 block: a 1 px line
   760 px wide, centred, black at 20% opacity, fading out over the outer 200 px on each side.
   Reproduced as one component; the modifiers carry the three paddings the source uses. */

/* The rule itself is gone — the alternating grounds do its job. The element stays as the small
   piece of vertical breathing room the source put between blocks. */
.divider {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    height: 26px;
    background: transparent;
}

.divider__line { display: none; }

.divider__line {
    position: relative;
    width: 760px;
    height: 1px;
    opacity: .2;
    background: linear-gradient(to right,
        rgb(0 0 0 / 0) 0,
        #000 200px,
        #000 560px,
        rgb(0 0 0 / 0) 760px);
}

.divider--pt30 { height: 56px; padding-top: 30px; }
.divider--pt15 { height: 41px; padding-top: 15px; }

/* ------------------------------------------------------ 20. Scroll reveal

   The Tilda source animated almost every element into place: 53 × fadeinup,
   35 × fadeinleft, 28 × fadeinright, 19 × fadeindown, 2 × zoomin — all with
   duration 1s and distance 100px. The directions are kept exactly (`fadeinright`
   starts 100px to the LEFT and slides right, so a left column and a right column
   converge on the centre), but the mechanism is an IntersectionObserver instead
   of Tilda's scroll listeners.

   `html.js` is set by an inline script in <head>, so with JavaScript off — or if
   site.js fails to load — nothing is ever hidden. */

/* .95s on a gentle ease-out, not .7s on an expo curve. The expo curve puts four fifths of the
   movement into the first quarter of the time, which is exactly what "бамс" means — it is a snap
   with a long tail, not an arrival. This one accelerates once and settles. */
html.js [data-reveal] {
    opacity: 0;
    transition: opacity .95s cubic-bezier(.25, .75, .35, 1), transform .95s cubic-bezier(.25, .75, .35, 1);
}

/* Promote to its own layer only while the animation is still pending. Leaving `will-change` on
   permanently kept a compositor layer over the video iframe and killed hover inside the player. */
html.js [data-reveal]:not(.is-visible) { will-change: opacity, transform; }

/* Distances deliberately small. Tilda threw every element 100px across the screen and the page
   read as things flying in from all sides; the same reveal at ~28px is noticed without being
   watched. Sideways travel is halved again — vertical motion reads as arrival, horizontal reads
   as a slide show. */
html.js [data-reveal='down']  { transform: translateY(-28px); }
html.js [data-reveal='up']    { transform: translateY(28px); }
html.js [data-reveal='right'] { transform: translateX(-16px); }
html.js [data-reveal='left']  { transform: translateX(16px); }
html.js [data-reveal='zoom']  { transform: scale(.965); }

html.js [data-reveal].is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
    html.js [data-reveal] { opacity: 1; transform: none; transition: none; }
}

/* ==========================================================================
   21. Motion and chrome — the FlippingStroy behaviour set, in Myrazonit colours
   ========================================================================== */

/* ---- the native scrollbar goes away on a real pointer; the rail replaces it ---- */
@media (hover: hover) and (pointer: fine) {
    html { scrollbar-width: none; -ms-overflow-style: none; }
    html::-webkit-scrollbar { width: 0; height: 0; display: none; }
}

/* ---- right-hand rail: one tick per section, click to jump ---- */
.scroll-rail {
    position: fixed;
    right: 20px;
    padding-inline: 10px;   /* small invisible hit strip so the rail is easy to reach */
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
    padding-block: 10px;
    z-index: 990;
    cursor: pointer;
}

.scroll-rail__top {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 30px;
    margin-bottom: 6px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--c-orange);
    font-size: 15px;
    cursor: pointer;
    opacity: 0;
    visibility: hidden;
    transform: translateY(6px);
    transition: opacity .35s ease, visibility .35s ease, transform .35s ease;
}

.scroll-rail__top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }

.scroll-rail__tick {
    width: 15px;
    height: 2px;
    padding: 0;
    border: 0;
    border-radius: 4px;
    cursor: pointer;
    background-color: var(--c-rail);
    transition: width .25s ease, height .25s ease, background-color .25s ease;
}

.scroll-rail__tick:hover { width: 20px; background-color: var(--c-orange); }
.scroll-rail__tick.is-active { width: 26px; height: 4px; background-color: var(--c-orange); }

/* Over the hero and the footer the rail sits on a dark photograph — light it up there. */
.scroll-rail.on-dark .scroll-rail__tick { background-color: rgb(255 255 255 / .45); }
.scroll-rail.on-dark .scroll-rail__tick:hover,
.scroll-rail.on-dark .scroll-rail__tick.is-active { background-color: var(--c-lime); }

/* ---- the chevron that invites the first scroll ---- */
.scroll-hint {
    position: fixed;
    left: 50%;
    bottom: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    padding: 0;
    border: 0;
    background: transparent;
    color: #fff;
    cursor: pointer;
    z-index: 950;
    opacity: 0;
    visibility: hidden;
    transform: translate(-50%, 8px);
    filter: drop-shadow(0 3px 10px rgb(0 0 0 / .55));
    transition: opacity .5s ease, visibility .5s ease, color .25s ease;
}

.scroll-hint svg { width: 48px; height: 48px; }

.scroll-hint.is-shown {
    opacity: 1;
    visibility: visible;
    animation: scrollHintFloat 2.6s ease-in-out infinite;
}

.scroll-hint:hover { color: var(--c-lime); }

/* Below the hero the page is white — the white chevron would disappear, so it turns orange. */
.scroll-hint.on-light { color: var(--c-orange); filter: drop-shadow(0 2px 6px rgb(245 71 0 / .35)); }
.scroll-hint.on-light:hover { color: var(--c-red); }

@keyframes scrollHintFloat {
    0%, 100% { transform: translate(-50%, -3px); }
    50%      { transform: translate(-50%, 6px); }
}

/* ---- counting factoids ---- */
html.js .hero__stat-value.is-counting { will-change: contents; }

html.js .hero__stat-value.count-done { animation: statPop .6s cubic-bezier(.16, 1, .3, 1); }

@keyframes statPop {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.16); filter: brightness(1.6); }
    100% { transform: scale(1); }
}

/* ---- glass edge + lift on every card ---- */
.product,
.case,
.step,
.person,
.demo__card,
.page-doc__card {
    position: relative;
    isolation: isolate;
    /* The frame is the stage the picture tilts on, so it owns the perspective and clips
       whatever leans past its edge. */
    perspective: 1000px;
    overflow: hidden;
    /* Real glass, not a hint of it. On the tinted sections the card now clearly sits ON something
       — the ground shows through, colour lifts through the blur, and a bright inside edge catches
       the light along the top. Pronounced enough to read as a material, short of a gimmick. */
    background: var(--c-glass);
    backdrop-filter: blur(20px) saturate(1.45);
    -webkit-backdrop-filter: blur(20px) saturate(1.45);
    box-shadow: 0 1px 0 var(--glass-hi) inset,
                0 -1px 0 var(--glass-lo) inset,
                var(--shadow-card);
    transition: box-shadow .45s cubic-bezier(.16, 1, .3, 1), border-color .45s ease,
                transform .45s cubic-bezier(.16, 1, .3, 1), background-color .35s ease;
}

/* The glass edge itself: a hairline highlight that catches the light on the top-left. */
.product::before,
.case::before,
.step::before,
.person::before,
.demo__card::before,
.page-doc__card::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    padding: 1px;
    background: var(--glass-edge);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    opacity: 1;                 /* always present — the card should look like glass at rest */
    transition: opacity .45s ease;
}

/* Photographs get the same edge, but drawn ON TOP. A picture fills its frame corner to corner,
   so a hairline behind it would never be seen. The shadow underneath is deliberately almost
   nothing — enough to lift the photo off the paper, not enough to notice as a shadow. */
.photo-frame,
.step__figure {
    box-shadow: var(--shadow-photo);
}

.photo-frame::after,
.step__figure::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    border-radius: inherit;
    padding: 1px;
    background: var(--glass-edge-photo);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    opacity: .6;
    transition: opacity .45s ease;
}

.photo-frame:hover::after,
.step:hover .step__figure::after { opacity: 1; }

.product:hover,
.case:hover,
.step:hover,
.person:hover,
.demo__card:hover,
.page-doc__card:hover {
    /* A small, straight lift — never a tilt. The 3D movement was tried on these cards and
       rejected; what the card owes the pointer is a step towards it and a brighter edge, with the
       depth still belonging to the photograph inside the frame. */
    transform: translateY(-3px);
    border-color: var(--glass-hi);
    box-shadow: 0 1px 0 var(--glass-hi) inset, var(--shadow-card-hover);
}

.product,
.case,
.step,
.person,
.demo__card,
.page-doc__card { will-change: transform; }

.step:hover::before,
.person:hover::before,
.demo__card:hover::before,
.product:hover::before,
.case:hover::before,
.page-doc__card:hover::before { opacity: 1; }

/* Product and case photographs breathe with the card. */
.person:hover .person__photo,
.step:hover .step__photo { filter: saturate(1.06); }

/* ---- an action band answers its own text ----
   Set by site.js while the card's copy is off-screen. The button does not disappear from the
   layout — it fades and stops taking the pointer — so nothing below it shifts as you scroll. */
.is-quiet .case__actions,
.is-quiet .step__actions,
.is-quiet .product__actions {
    opacity: 0;
    pointer-events: none;
}

.case__actions,
.step__actions,
.product__actions { transition: opacity .35s ease; }

/* ---- buttons ---- */
.btn { transition: transform .25s cubic-bezier(.16, 1, .3, 1), box-shadow .25s ease, filter .25s ease; }

.btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 26px rgb(0 0 0 / .38);
    filter: saturate(1.1) brightness(1.06);
}

.btn:active { transform: translateY(0); box-shadow: 0 5px 12px rgb(0 0 0 / .35); }

/* ---- the founders' cards and the step photos lift too ---- */




/* ---- header links ---- */
.site-nav a { position: relative; }

/* 6px, not 12px: measured, the text box ends exactly 12px above the link's bottom edge, so the
   rule was sitting right on the letters. This clears them by four. */
.site-nav a::after {
    content: '';
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: 6px;
    height: 2px;
    border-radius: 2px;
    background: var(--c-lime);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .3s cubic-bezier(.16, 1, .3, 1);
}

.site-nav a:hover::after { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
    .scroll-hint.is-shown { animation: none; }
    html.js .hero__stat-value.count-done { animation: none; }
    .product, .case, .page-doc__card, .btn, .step__figure,
    .product__figure img, .case__photo, .person__photo { transition: none; }
    .product:hover, .case:hover, .page-doc__card:hover, .btn:hover { transform: none; }
}

/* ==========================================================================
   22. Depth — the cursor tilts what it points at
   ========================================================================== */

/* Every content photograph leans toward the cursor on three axes at once: rotateX/rotateY for
   the tilt, translate for the parallax shift, scale for the breathing. The values are written
   by one rAF loop in site.js as custom properties; CSS only composes them, so the transform is
   a single compositor operation. */
[data-tilt] {
    /* The 1.06 is not decoration: a picture that exactly fills its frame pulls its own corners
       inside as soon as it leans, and the gap reads as a glitch. Six per cent of overscan means
       the tilt always happens INSIDE the frame, with nothing but photograph at every edge. */
    transform: perspective(1000px)
               rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg))
               translate3d(var(--tx, 0px), var(--ty, 0px), 0)
               scale(calc(var(--tz, 1) * 1.06));
}

/* The hero backdrop uses the same idea at a bigger scale and a shallower angle: a wall of
   photograph that leans, drifts and breathes rather than a card that tips. */
.hero__bg img { transform-origin: 50% 45%; }

/* ---- icons answer the pointer too ---- */
.hero__benefit img,
.site-footer__social img,
.lead-form__flag {
    transition: transform .4s cubic-bezier(.16, 1, .3, 1), filter .4s ease;
}

/* Halved on the owner's word — the first screen answers the pointer, it does not jump at it. */
.hero__benefit:hover img { transform: scale(1.03); filter: drop-shadow(0 1px 4px rgb(16 234 0 / .16)); }

.site-footer__social a { display: block; transition: transform .35s cubic-bezier(.16, 1, .3, 1); }
.site-footer__social a:hover { transform: translateY(-4px); }
.site-footer__social a:hover img { transform: scale(1.1); filter: drop-shadow(0 6px 14px rgb(16 234 0 / .5)); }

.step__badge { transition: transform .5s cubic-bezier(.16, 1, .3, 1), filter .4s ease; }
.step:hover .step__badge { transform: scale(1.06); filter: drop-shadow(0 8px 18px rgb(0 0 0 / .4)); }

.hero__mark { transition: transform .5s cubic-bezier(.16, 1, .3, 1); }
.hero__card:hover .hero__mark { transform: scale(1.02); }
/* Pointing AT the leaf, rather than anywhere on the plate, gets a real answer. Same weight as the
   rule above, so it has to come after it to win. */
.hero__brand .hero__mark:hover { transform: scale(1.05) rotate(-2deg); }

/* ---- the rest of the first screen answers the pointer too ----
   The reveal system owns `transform` on anything carrying data-reveal — `.is-visible` resets it and
   outranks a plain hover rule. So the subtitle, which reveals, gets its hover from colour, glow and
   a growing underline, and the four factoids move their own dt/dd, which do not reveal. */
.hero__title { transition: transform .45s cubic-bezier(.16, 1, .3, 1), text-shadow .45s ease; }
.hero__title:hover { transform: translateY(-1px); text-shadow: 0 8px 20px rgb(16 234 0 / .2); }

.hero__subtitle { transition: color .3s ease, text-shadow .35s ease; }
.hero__subtitle:hover { color: #fff; text-shadow: 0 6px 20px rgb(16 234 0 / .55); }

.hero__benefit { transition: transform .4s cubic-bezier(.16, 1, .3, 1), color .3s ease, text-shadow .35s ease; }
.hero__benefit:hover { transform: translateX(2px); color: var(--c-lime); text-shadow: 0 2px 6px rgb(0 0 0 / .2); }

/* The number is painted with a gradient clipped to the glyphs, so `color` alone cannot reach it —
   the fill has to be overridden outright to turn it white. The lift keeps a plain dark shadow;
   a green one on green numbers only muddied them. */
.hero__stat-value,
.hero__stat-label { transition: transform .45s cubic-bezier(.16, 1, .3, 1), filter .4s ease, color .3s ease, -webkit-text-fill-color .3s ease; }
.hero__stats > div:hover .hero__stat-value {
    transform: translateY(-1px) scale(1.01);
    -webkit-text-fill-color: #fff;
    color: #fff;
    filter: drop-shadow(0 2px 5px rgb(0 0 0 / .2));
}
.hero__stats > div:hover .hero__stat-label { transform: none; }

/* ---- the remaining interactive surfaces ---- */
.breadcrumbs a,
.site-footer__legal-links a,
.person__contacts a,
.site-header__phone,
.site-header__mail { transition: color .25s ease, opacity .25s ease; }

.site-header__phone:hover { color: var(--c-lime); }
.person__contacts a:hover { color: var(--c-orange); }

.lead-form__field,
.contact-form input[type='text'],
.contact-form input[type='tel'],
.lead-form__phone {
    transition: box-shadow .3s ease, transform .3s cubic-bezier(.16, 1, .3, 1);
}

.lead-form__field:focus,
.lead-form__phone:focus-within,
.contact-form input:focus {
    outline: 0;
    transform: translateY(-2px);
    box-shadow: 0 0 0 3px rgb(245 71 0 / .35), 0 8px 18px rgb(0 0 0 / .18);
}

.divider__line { transition: opacity .6s ease; }

@media (prefers-reduced-motion: reduce) {
    [data-tilt] { transform: none !important; }
    .hero__benefit:hover img,
    .site-footer__social a:hover,
    .site-footer__social a:hover img,
    .step:hover .step__badge,
    .hero__title:hover,
    .hero__benefit:hover,
    .hero__stats > div:hover .hero__stat-value,
    .hero__stats > div:hover .hero__stat-label,
    .hero__brand .hero__mark:hover,
    .hero__card:hover .hero__mark { transform: none; }
}

/* ------------------------------------------------- 23. Text answers the pointer

   Not a tilt — rotating a paragraph makes it harder to read, which is the opposite of the
   point. Instead each block of copy lifts a hair and gains contrast under the cursor, so the
   thing you are reading is visibly the thing you are pointing at. Paragraph-level: whole
   sentences respond together, never single words. */

.rich p,
.rich li,
.step__title,
.product__title,
.case__quote,
.about__motto,
.russia__lead,
.person__role,
.person__contacts,
.demo__subtitle,
.product__note {
    transition: transform .35s cubic-bezier(.16, 1, .3, 1), color .35s ease, text-shadow .35s ease;
}

.rich p:hover,
.rich li:hover,
.about__motto:hover,
.russia__lead:hover,
.demo__subtitle:hover,
.product__note:hover {
    transform: translateX(4px);
    color: var(--c-green-deep);
    text-shadow: 0 1px 0 rgb(255 255 255 / .6);
}

.step__title:hover,
.product__title:hover,
.case__quote:hover {
    transform: translateY(-2px);
    text-shadow: 0 6px 16px rgb(245 71 0 / .28);
}

.person__role:hover,
.person__contacts:hover { transform: translateX(3px); }

/* Section headings get a touch of depth rather than movement — they are the anchor of the
   screen and should not shift when the cursor merely passes over them. */
.section__title,
.page-doc__title,
.site-footer__title { transition: text-shadow .4s ease; }

.section__title:hover,
.page-doc__title:hover { text-shadow: 0 8px 22px rgb(0 69 51 / .22); }

@media (prefers-reduced-motion: reduce) {
    .rich p, .rich li, .step__title, .product__title, .case__quote,
    .about__motto, .russia__lead, .person__role, .person__contacts,
    .demo__subtitle, .product__note { transition: none; }
    .rich p:hover, .rich li:hover, .about__motto:hover, .russia__lead:hover,
    .demo__subtitle:hover, .product__note:hover,
    .step__title:hover, .product__title:hover, .case__quote:hover,
    .person__role:hover, .person__contacts:hover { transform: none; }
}

/* --------------------------------------------- 24. A frame for every photograph

   The picture leans; the frame never does. Without a frame the tilted photograph pushes past
   its own edges and the whole block appears to move — which is what the technology steps and
   the client cases were doing. The frame owns the perspective, the rounded corners and the
   clipping; the image inside owns the motion. */

.photo-frame {
    display: block;
    position: relative;
    overflow: hidden;
    border-radius: var(--r-card);
    perspective: 1000px;
}

.photo-frame--case   { width: 350px; height: 272px; }
.photo-frame--person { width: 356px; height: 237px; }
/* Sized so the whole block — heading, photograph and copy — clears a 900px viewport, which is
   what the owner asked of it. */
/* The frame is 50px shorter than it was, and the crop is centred rather than pinned: the source is
   already a tight 1680x550, so pinning it to the top threw the field away and pushed the buildings
   against the bottom edge. Centred, the band keeps sky above the roofline, the whole plant, and a
   strip of the field under it. */
.photo-frame--about  { width: var(--w-content); height: 270px; margin: 0 auto var(--s-md); }
/* 52% → 38%: the picture slides ~30px down inside the frame, which buys back sky above the
   roofline. The overhang is 207px, so one percent is about two pixels. */
.photo-frame--about img { object-position: 50% 38%; }

.photo-frame img { width: 100%; height: 100%; border-radius: 0; margin: 0; }

/* The technology step already had a wrapper — it just never behaved like a frame. */
.step__figure {
    position: relative;
    width: 320px;
    border-radius: var(--r-card);
    perspective: 1000px;
    /* Without this the leaning photograph spills past its own corners and the whole step looks
       like it is moving. The frame clips; only what is inside it tilts. */
    overflow: hidden;
}

.step__figure .step__photo { border-radius: var(--r-card); }

/* The badge sits ON the frame, not inside the tilting plane, so it stays put. */
.step__badge { z-index: 2; }

/* The product canister leans inside the figure, which the card already clips. */
.product__figure { perspective: 1000px; }


/* ---------------------------------------------- 25. The contact-method picker

   A lead that says "write to me on WhatsApp" is worth more than one that only leaves a number:
   it tells the person calling back where to start. Styled as the other fields so the row reads
   as one control strip, with the arrow drawn in CSS — no image, no library. */

.lead-form__select,
.contact-form select {
    appearance: none;
    width: 100%;
    height: 50px;
    padding: 0 38px 0 20px;
    border: 0;
    border-radius: var(--r-card);
    background: #fff;
    background-image: linear-gradient(45deg, transparent 50%, var(--c-green) 50%),
                      linear-gradient(135deg, var(--c-green) 50%, transparent 50%);
    background-position: calc(100% - 20px) 22px, calc(100% - 14px) 22px;
    background-size: 6px 6px, 6px 6px;
    background-repeat: no-repeat;
    font-size: 17px;
    color: #000;
    cursor: pointer;
    transition: box-shadow .3s ease, transform .3s cubic-bezier(.16, 1, .3, 1);
}

.contact-form select { height: 46px; background-position: calc(100% - 20px) 20px, calc(100% - 14px) 20px; }

.lead-form__select:focus,
.contact-form select:focus {
    outline: 0;
    transform: translateY(-2px);
    box-shadow: 0 0 0 3px rgb(245 71 0 / .35), 0 8px 18px rgb(0 0 0 / .18);
}

/* ------------------------------------------------------- 26. Line breaking

   `balance` evens the lines of a short block so the last one is never a lonely tail — which is
   what makes a two-line quote look broken. `pretty` leaves long copy alone but refuses to end a
   paragraph on a single word. Both are the browser's own line-breaker doing the work no manual
   <br> can do responsibly, because it re-runs at every width. */

.case__quote,
.section__title,
.page-doc__title,
.step__title,
.product__title,
.lead-band__title,
.site-footer__title,
.hero__cta p,
.russia__lead,
.about__motto,
.demo__subtitle,
.hero__subtitle { text-wrap: balance; }

.rich p,
.site-footer__requisites,
.person__role { text-wrap: pretty; }

/* A sentence that owns its own block can be balanced; one welded to its neighbour by a
   <br> cannot, because a forced break switches the balancer off. site.js gives every run
   between two <br> its own margin-less block span, and these two rules are what that is
   for. `.tw-solo` is a paragraph that never needed splitting. */
.rich p > .tw-line { display: block; }
.rich p > .tw-line,
.rich p.tw-solo,
.rich li { text-wrap: balance; }

/* A quote is a sentence, not a column: give it room to find an even break. */
.case__quote { max-width: 1180px; margin-inline: auto; }

/* ------------------------------------------- 27. Header tools: theme and language

   ONE component for both, so they read as a pair rather than two unrelated widgets: a pill
   holding two segments, the current one filled. Monochrome on purpose — the header already
   carries the brand green and orange, and two more coloured controls up there turn it into a
   dashboard. */

.header-tools {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
    padding-right: 24px;
}

/* Smaller pill, bigger contents. The sun and the moon were drawn at 13px inside a 24px button —
   half the button was padding, and at that size the sun's rays read as specks. The pill loses 4px
   of height and 7px of width; the icons gain a third. */
.segmented {
    display: flex;
    align-items: center;
    gap: 2px;
    height: 28px;
    padding: 2px;
    border: 1px solid rgb(255 255 255 / .2);
    border-radius: 999px;
    background: rgb(255 255 255 / .07);
}

.segmented__opt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    font-family: inherit;
    /* RU/EN stays at 10 — at 11 the two letters start touching the sides of their circle. */
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .02em;
    /* The inherited 1.45 line box is taller than the glyphs, and a flex item centres the BOX, not
       the letters — which left RU/EN sitting visibly high in its circle. `line-height: 1` makes
       the box the glyphs' own height, so centring the box centres what you actually see. */
    line-height: 1;
    color: rgb(255 255 255 / .6);
    cursor: pointer;
    transition: color .25s ease, background-color .25s ease;
}

.segmented__opt svg {
    width: 17px;
    height: 17px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
}

/* the moon is a solid shape, not an outline */
.segmented__opt[data-theme-opt='dark'] svg { fill: currentColor; stroke: none; }

.segmented__opt:hover { color: #fff; }

.segmented__opt.is-active {
    color: #101010;
    background: rgb(255 255 255 / .92);
}

/* On an inner page the header is solid black rather than a photograph, so the pill needs a touch
   more contrast to stay visible. */
.site-header--solid .segmented { border-color: rgb(255 255 255 / .26); }

/* ------------------------------------------------------------------ 27b. FAQ
   Ten questions, two columns, one open at a time. The list is bordered rather than boxed: a page
   already full of cards does not need eleven more, and a rule reads as "there is more below" in a
   way a card does not. */

.faq {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--s-2xl);
    align-items: start;
    margin-top: var(--s-lg);
}

.faq__item { border-bottom: var(--card-border); }
/* The two columns each need a line on top, and only the first item of each does — nth-child(2)
   is the first cell of the right-hand column when the grid fills row by row... it is not, the
   grid fills across, so the top row IS items 1 and 2. */
.faq__item:nth-child(1),
.faq__item:nth-child(2) { border-top: var(--card-border); }

.faq__q {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 22px;
    align-items: center;
    gap: 22px;
    width: 100%;
    padding: 22px 0;
    border: 0;
    background: transparent;
    color: inherit;
    font-size: 18px;
    font-weight: 700;
    line-height: 1.35;
    text-align: left;
    cursor: pointer;
}

.faq__q:hover { color: var(--c-orange); }

/* The marker is drawn, not typed: a plus that loses its upright stroke when the answer is open,
   so the same element is both "open me" and "close me" without a second icon. */
.faq__q i {
    position: relative;
    justify-self: end;
    width: 18px;
    height: 18px;
}
.faq__q i::before,
.faq__q i::after {
    content: "";
    position: absolute;
    inset: 50% 0 auto 0;
    height: 2px;
    border-radius: 2px;
    background: var(--c-orange);
    translate: 0 -50%;
    transition: opacity .25s ease, rotate .3s cubic-bezier(.16, 1, .3, 1);
}
.faq__q i::after { rotate: 90deg; }
.faq__item.is-open .faq__q i::after { opacity: 0; rotate: 0deg; }

/* 0fr to 1fr: the row grows to whatever the answer actually needs, with no height measured in
   JavaScript and nothing to go stale when the text or the window changes. */
.faq__a {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows .34s cubic-bezier(.16, 1, .3, 1);
}
.faq__a > div { overflow: hidden; }
.faq__item.is-open .faq__a { grid-template-rows: 1fr; }

.faq__a p {
    margin: 0;
    padding: 0 34px 24px 0;
    font-size: 16px;
    line-height: 1.6;
    color: var(--c-green);
}
.faq__a strong { color: var(--c-green-deep); }

@media (prefers-reduced-motion: reduce) {
    .faq__a, .faq__q i::before, .faq__q i::after { transition: none; }
}

/* ======================================================================= 28. ADAPTIVE

   THE RULE, IN THE OWNER'S WORDS: on every laptop and every monitor the site must look exactly
   like the 1920 reference. Not re-composed — SCALED. If a block does not fit, it gets smaller and
   gains side air; it is never rebuilt into a different layout.

   So above the tablet line this file contains no reflow at all. site.js gives <body> a `zoom` of
   window width / 1920, which means the page LAYS OUT at 1920 CSS pixels wide whatever the window
   is: every container, column, gap and type size resolves to the reference number and is then
   drawn smaller. A 1280-wide laptop is the 1920 design at 0.667, to the pixel, hero still exactly
   one screen tall. The first attempt at this file was wrong in exactly this way — it folded the
   header into a burger and stacked the cards at 1280, which is a different site, not a smaller one.

   Below 900px the device really is different and the layout does adapt. Even there the
   composition holds: the picture stays LEFT and the text RIGHT, the picture just gets small.
   Stacking a card into one tall column is what turns a phone into endless scrolling, and that is
   what the owner does not want. Only the very narrow phones drop the second column, and only for
   the blocks where a 90px-wide photograph would say nothing.

   Everything here is width-first. A height-only rule, or a fixed px width that survives into the
   reflow, is what has broken this kind of work before. */

/* Side air. Only ever seen below the reflow line — above it the page is 1920 wide by definition. */
:root { --gutter: clamp(14px, 3.2vw, 48px); }

/* Nothing may push the window sideways. */
html, body { overflow-x: hidden; }
img, video, iframe { max-width: 100%; }
/* The companion to that max-width. Every <img> now carries its intrinsic width and height so the
   browser can reserve the box before the file arrives; without this line, a picture clamped by
   max-width would keep the declared HEIGHT and come out squashed. Anything with a class of its own
   — the framed photographs, the hero backdrop — overrides this and is unaffected. */
img { height: auto; }

/* The hero is one screenful. Under `zoom` a viewport unit still resolves against the UNZOOMED
   viewport, so 100vh would draw at 100vh x zoom — two thirds of the screen on a 1280 laptop.
   Dividing by the zoom factor is what makes it exactly one screen again, at any scale.

   The upper bound is for screens taller than they are wide — a 12.9" iPad held upright, a monitor
   turned on its side. There "one screenful" means 2073px of layout, and the reference composition
   is a card about 700px tall: the card floated in the middle of an ocean of empty photograph, sky
   above and wheat below, which is not the reference scaled, it is the reference lost. 1400 is a
   1920x1400 window — taller than any real desktop (16:10 tops out at 1200), so no laptop, monitor
   or TV is touched by this line. On the upright tablet the hero becomes two thirds of the screen
   and the next section shows below it, which is what the reference looks like. */
.hero { min-height: clamp(820px, calc(100vh / var(--zoom, 1)), 1400px); }

/* The containers are NOT touched above the tablet line. They were made fluid here once and it
   changed the reference at every window narrower than 1554 — a 1536 screen lost 18px off the
   container and the approved formatting moved. Above 900 they stay exactly what section 3 says:
   a fixed 1458. The fluid versions live inside the tablet query below. */

/* ---- the burger: three bars, no box. Hidden until the header folds ---- */
.burger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 7px;
    width: 44px;
    height: 38px;
    margin-left: auto;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
    z-index: 1002;
}

.burger span {
    display: block;
    width: 100%;
    height: 3px;
    border-radius: 2px;
    background: #fff;
    transition: transform .3s cubic-bezier(.16, 1, .3, 1), opacity .2s ease;
}

/* Open, the three bars become a cross — one control says both "menu" and "close". */
.burger.is-open span:nth-child(1) { transform: translateY(9px) rotate(45deg); }
.burger.is-open span:nth-child(2) { opacity: 0; }
.burger.is-open span:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }

/* Above the reflow line the wrapper does not exist as far as layout is concerned: `contents`
   dissolves it, so nav, tools and contacts stay direct flex children of the header row. */
.site-header__drawer { display: contents; }

/* ============================= below 900px — a tablet or a phone, not a smaller monitor ======= */
@media (max-width: 899px) {
    /* Only here do the containers become fluid — this is a tablet or a phone, where a fixed 1458
       cannot exist. Above this line they keep the reference width, untouched.

       EVERY block that is written at the reference width must appear in this list. Two were
       missing — the video card and the footer card — and because <html> is `overflow-x: hidden`
       they did not show up as a horizontal scrollbar or in scrollWidth: they were silently CLIPPED.
       The footer lost the right half of "Свяжитесь с нами", the phone number, and the Заказать
       button, on every screen under 900px including phones, while every automatic check reported
       zero overflow. The full list is: everything in the stylesheet carrying
       `width: var(--w-content)`, `var(--w-hero)`, or a fixed px width near 1000. */
    .container       { width: min(100% - var(--gutter) * 2, var(--w-content)); }
    .container--wide { width: min(100% - var(--gutter) * 2, var(--w-hero)); }
    .site-header__inner,
    .lead-form,
    .site-footer__card { width: min(100% - var(--gutter) * 2, var(--w-content)); }
    /* NOT in that list — both of these already sit inside something that has its own inset, so
       subtracting a gutter again insets them twice. The contact form is inside the footer card,
       and with no auto margin the whole of that second gutter landed on the right, which is why
       the fields sat off the card's centre line. The video card is inside a `.container`, which
       made it 670px wide on a 768 tablet where every other card on the page was 719. The parent's
       inset is the inset; 100% is centred by definition. */
    .contact-form,
    .demo__card { width: 100%; }
    .btn { width: min(300px, 100%); }

    :root {
        --s-3xl: clamp(40px, 7vw, 72px);
        --s-2xl: clamp(34px, 6vw, 60px);
        --s-xl:  clamp(26px, 4.6vw, 46px);
        --s-lg:  clamp(22px, 3.6vw, 40px);
        --s-md:  clamp(18px, 3vw, 32px);
        --s-sm:  clamp(14px, 2.4vw, 22px);
        --card-pad-y: clamp(18px, 3.4vw, 32px);
        --card-pad-x: clamp(16px, 3vw, 28px);
    }

    /* -- type: one fluid scale, so a tablet reads like a small reference rather than a poster -- */
    .hero__title      { font-size: clamp(30px, 6.4vw, 56px); }
    .hero__subtitle   { font-size: clamp(13px, 2.1vw, 19px); line-height: 1.5; }
    .hero__benefit    { font-size: clamp(14px, 2.1vw, 19px); }
    .hero__benefit img { width: clamp(30px, 4.6vw, 44px); height: auto; }
    .hero__stat-value { font-size: clamp(24px, 4.6vw, 40px); }
    .hero__stat-label { font-size: clamp(11px, 1.6vw, 14px); }
    .hero__cta p      { font-size: clamp(15px, 2.4vw, 22px); }
    .section__title   { font-size: clamp(19px, 3.1vw, 28px); }
    /* 16 is the floor, not 13. A 1.9vw slope put 14.6px on a 768 iPad while the phone rule two
       queries down was already giving a 390 screen 16 — the wider device was reading SMALLER than
       the narrow one, which is the wrong way round and was visible the moment both were opened
       side by side. Above 842 the slope takes over on its own. */
    .rich             { font-size: clamp(16px, 1.9vw, 17px); line-height: 1.62; }
    .step__title,
    .product__title   { font-size: clamp(16px, 2.5vw, 22px); line-height: 1.25; }
    .case__quote      { font-size: clamp(16px, 2vw, 18px); line-height: 1.5; }
    .btn              { height: 44px; font-size: clamp(12px, 1.8vw, 15px); }

    /* -- header folds into a drawer -- */
    .burger { display: flex; }
    .site-header { height: clamp(52px, 8vw, 62px); }
    /* The wordmark and the burger are the same height on purpose — two controls of different
       sizes either side of the header read as a mistake. The logo's height follows from its
       width (the file is 500x78), so the burger's box is driven by the same clamp. */
    .site-header__logo,
    .site-header__wordmark { width: clamp(150px, 42vw, 200px); }
    /* The BARS stay the height of the logo; the BOX is 44 so a thumb has something to hit. The
       gap is derived so the three 3px bars still span exactly the logo's height. */
    .burger {
        width: 44px;
        height: 44px;
        gap: calc((clamp(23px, 6.55vw, 31px) - 9px) / 2);
    }
    /* The Russian line under the wordmark cannot be both narrower than the wordmark and legible
       at this size — 33 characters inside 150px is about a 5px letter. It goes. */
    .site-header__tagline { display: none; }
    .site-header__drawer {
        display: flex;
        position: fixed;
        inset: 0 0 auto;
        z-index: 1001;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: var(--s-md);
        max-height: 100dvh;
        padding: 84px var(--gutter) 34px;
        overflow-y: auto;
        background: rgb(0 0 0 / .96);
        backdrop-filter: blur(18px);
        transform: translateY(-102%);
        transition: transform .38s cubic-bezier(.16, 1, .3, 1);
    }
    .site-header__drawer.is-open { transform: translateY(0); }
    .site-nav { flex-direction: column; gap: 12px; margin-left: 0; text-align: center; }
    .site-nav a {
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 44px;      /* a menu row is a thumb target, not a line of text */
        font-size: 17px;
    }
    .header-tools { margin-left: 0; padding-right: 0; gap: 16px; }
    /* Where the row has the width for them, the theme and language switchers belong IN the header,
       not buried behind a burger — on a 600px tablet there was an empty half-screen between the
       wordmark and the burger and the two controls were a tap away inside the drawer. site.js
       moves the node between the drawer and the header row; these are the row's manners. The
       burger gives up its own auto margin so the pair travels to the right edge together. */
    .site-header__inner > .header-tools {
        margin-left: auto;
        margin-right: 14px;
        gap: 12px;
    }
    .site-header__inner > .header-tools + .burger { margin-left: 0; }
    .segmented { padding: 6px; gap: 6px; }
    /* 34 was the number for a compact header row. These switchers do not live in the header row
       here — they live in the drawer, which is a whole screen with room to spare, and they are
       hit with a thumb. 44 is the size a thumb needs. */
    .segmented__opt { width: 44px; height: 44px; font-size: 13px; }
    .segmented__opt svg { width: 20px; height: 20px; }

    /* The logo is the "back to the top" control and the drawer's telephone and e-mail are the two
       things a client actually taps. All three were text-height boxes — 31, 27 and 20 pixels.
       `justify-content`, not `align-items`: this anchor is a COLUMN flex box (wordmark над
       tagline), so its main axis runs downwards and `align-items: center` only centred the
       wordmark left-to-right. Vertically the image stayed pinned to the top of the 44px box while
       the burger beside it was centred — which is the logo the owner saw sitting too high. */
    .site-header__logo {
        display: flex;
        justify-content: center;
        min-height: 44px;
    }
    /* `flex`, not `inline-flex`: inline boxes are laid on a line, and a 720px drawer is wide
       enough to fit the telephone and the e-mail on the same one — they belong on two. */
    .site-header__contacts a {
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 44px;
    }
    /* In the header row this block is pushed to the right end by `margin-left: auto` and held off
       the edge by 44px of padding. Inside the drawer — a centred column — that auto margin still
       reads as "go right", so the phone number sat against the right edge while every other row
       was centred. Both have to be undone here, not just the text-align. */
    .site-header__contacts { margin-left: 0; padding-right: 0; text-align: center; }

    /* The two founders sit side by side at 1920 — two cards, each 700px wide, each with a 356px
       portrait and room for a name and a phone number. Halve the page and each card is 350px, the
       portrait still claims 26vw of it, and the name has 130px left: "Жоржета Коннова" came out as
       "Жоржет" and the phone number as "+7 999 407-4". One card per row instead; the composition
       inside it is untouched — portrait left, name and telephone right. */
    .russia__body { grid-template-columns: minmax(0, 1fr); row-gap: var(--s-md); }

    /* -- THE COMPOSITION HOLDS: picture left, text right, picture small -- */
    .step__body,
    .product,
    .case,
    .person,
    .page-product {
        grid-template-columns: clamp(96px, 26vw, 300px) minmax(0, 1fr);
        column-gap: clamp(14px, 2.6vw, 34px);
        align-items: start;
    }
    .step__figure {
        width: 100%;
        max-width: none;
        height: auto;
        aspect-ratio: 400 / 426;
    }
    .product__figure img { width: 100%; height: auto; }
    .photo-frame--case   { width: 100%; height: 100%; }
    .person__photo,
    .photo-frame--person { width: 100%; height: auto; aspect-ratio: 356 / 237; }
    .page-product__figure img { width: 100%; height: auto; }
    .step__badge {
        width: clamp(42px, 8vw, 74px);
        height: clamp(42px, 8vw, 74px);
        border-width: 3px;
        font-size: clamp(22px, 4.4vw, 40px);
    }

    /* The step buttons were pinned to the bottom of a two-column body; here they follow the text
       so a short card does not grow a dead strip under it. Once static they become the third grid
       item, which is cell 1 of row 2 — the button slid under the PHOTOGRAPH and took its 200px
       width. Spanning both columns puts it back where the reference has it: centred under the
       whole card, the same as the case blocks two sections down. */
    .step__actions { position: static; grid-column: 1 / -1; margin-top: var(--s-md); text-align: center; }
    .step__text    { padding-bottom: 0; }

    /* -- the hero, compact --
       The desktop rules set line boxes in absolute pixels — a 45px line for a bullet, a 63px one
       for a factoid — because at 1920 those ARE the design. Carried onto a phone they become the
       gaps the owner saw: four bullets spread over half the screen with nothing between them but
       air. Everything vertical here is a ratio instead, and the margins come off the same scale
       as the rest of the block. */
    .hero__brand      { gap: 6px; }
    .hero__title      { line-height: 1.06; }
    .hero__subtitle   { margin-top: 8px; margin-left: 0; }
    .hero__benefits   { margin-top: clamp(14px, 2.6vw, 30px); padding-left: 0;
                        row-gap: clamp(7px, 1.4vw, 14px); }
    .hero__benefit    { gap: clamp(9px, 1.6vw, 16px); line-height: 1.25; }
    .hero__stats      { margin-top: clamp(14px, 2.6vw, 30px); padding-left: 0;
                        row-gap: clamp(9px, 1.8vw, 18px); }
    .hero__stat-value { line-height: 1.08; }
    .hero__stat-label { line-height: 1.22; margin-top: 2px; }

    /* -- the hero: two bullet columns become one, four factoids become two -- */
    .hero { min-height: 0; padding: clamp(74px, 13vw, 104px) 0 clamp(34px, 6vw, 60px); }
    .hero__card { width: 100%; padding: clamp(20px, 3.4vw, 34px) clamp(18px, 3vw, 32px); }
    .hero__benefits { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: clamp(10px, 1.8vw, 18px); }
    .hero__stats {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        column-gap: clamp(8px, 1.6vw, 20px);
        margin-top: clamp(18px, 3vw, 34px);
    }
    .hero__cta {
        height: auto;
        margin-top: clamp(14px, 2.6vw, 30px);   /* was a flat 46 — a third of a phone's gap budget */
        gap: clamp(12px, 2.2vw, 26px);
        padding: clamp(14px, 2.4vw, 24px) clamp(16px, 3vw, 34px);
    }
    /* 36px of leading on a 15px line is a desktop number. Here the two lines sit together. */
    .hero__cta p { line-height: 1.3; }
    .hero__cta .btn { flex: 0 0 auto; width: clamp(150px, 26vw, 260px); }

    /* -- the rest of the page -- */
    .demo__frame  { width: 100%; height: auto; aspect-ratio: 16 / 9; }
    .about__photo,
    .photo-frame--about { width: 100%; height: auto; aspect-ratio: 1458 / 270; }
    .divider__line { width: min(760px, 60%); }
    .lead-form,
    .contact-form { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: var(--s-sm); }
    /* The submit button is one cell of the same grid as the fields, so it has to be the same shape
       as them: `min(300px, 100%)` left it narrower than the telephone box directly above it, and
       44 against the fields' 46 left the bottom edges two pixels apart. A form where the button
       does not line up with the field reads as unfinished before a word of it is filled in. */
    .lead-form .btn,
    .contact-form .btn { width: 100%; height: 46px; }
    /* The FAQ keeps both columns down to the phone line — ten questions in one column is a very
       long list to scroll past, and a question is short enough to live in half a tablet. */
    .faq { column-gap: var(--s-lg); }
    .faq__q { padding: 18px 0; font-size: clamp(15px, 2.2vw, 17px); }
    .faq__a p { padding-right: 20px; font-size: clamp(14px, 2vw, 16px); }
    .case__quote, .tech__lead, .lead-band__title { max-width: 100%; }
    .scroll-rail { display: none; }

    /* THE FOOTER, AT THE SIZE OF THE DEVICE IT IS ON. At 1920 the sign-off is 30px over a 47px
       line, the telephone 25 over 39, the legal links 17 over 26 — display sizes for a block seen
       from a metre away. Carried onto a phone unchanged they were the loudest thing on the screen
       and the air between them ate half of it. Everything below scales with the viewport and
       lands back on the reference number at 899, so a tablet is a small reference and the 1920
       version is untouched. */
    .site-footer__title    { font-size: clamp(19px, 3.2vw, 28px); line-height: 1.28; }
    .site-footer__contacts { margin-top: var(--s-sm); font-size: clamp(16px, 2.7vw, 24px); line-height: 1.45; }
    .site-footer__legal    { padding: clamp(10px, 2vw, 17px) 0 clamp(14px, 2.6vw, 24px); }
    .site-footer__legal-links a { font-size: clamp(13px, 1.9vw, 17px); line-height: 1.4; }
    .site-footer__requisites { margin-top: 6px; font-size: clamp(11px, 1.7vw, 15px); line-height: 1.45; }

    /* TOUCH TARGETS. Each of these is a control a client taps to get in contact — the founders'
       telephone numbers, the footer's phone and e-mail, the legal links, the consent tick — and
       every one of them was a line of text between 18 and 30 pixels tall, too small for a thumb.
       The boxes grow around the text they already had; nothing changes size on screen. 34 and 32
       rather than a flat 44: at 44 the footer turned into a ladder of gaps, and the owner was
       right that it read as padding for its own sake. The three consent rows are <label>s wrapping
       their checkbox, so the whole row is the target and the 16px box does not have to grow. */
    .person__contacts a { display: inline-flex; align-items: center; min-height: 44px; }
    .site-footer__contacts a { display: inline-flex; align-items: center; min-height: 34px; }
    .site-footer__legal-links a {
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 32px;
    }
    .contact-form__consent,
    .lead-form__consent,
    .lead-popup__consent { min-height: 44px; }

    /* The desktop copy forces its own line breaks with <br>, and site.js gives each run its own
       block so the balancer can even it out. Those breaks were written for a 1458 container; here
       the widest column anything gets is about 500px, so every forced run wraps AND THEN starts a
       new block — a stack of half-empty lines with a ragged hole down the right side. It reads as
       broken on a 768 iPad exactly as it did on a phone. Let the runs flow together and fill the
       column instead; the copy keeps its words, the browser picks the breaks. */
    .rich p > .tw-line { display: inline; }
    .rich p > .tw-line + .tw-line::before { content: ' '; }
}

/* ================================ 700px — a phone: one column, the picture across the screen ==
   "Picture left, text right" is the TABLET instruction — it holds where there is room for two
   columns. On a phone there is not: a 26vw column turns the photograph into a thumbnail in the
   corner and squeezes the copy into a ribbon four words wide. Here the picture takes the width it
   deserves and the text goes underneath it. */
@media (max-width: 700px) {
    .hero__stats    { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 16px; }
    .hero__cta      { flex-direction: column; text-align: center; }
    .hero__cta .btn { width: 100%; }

    .step__body,
    .case,
    .person {
        grid-template-columns: minmax(0, 1fr);
        row-gap: var(--s-md);
        column-gap: 0;
        justify-items: stretch;
    }

    /* THE PRODUCT PHOTOGRAPH IS A BOTTLE, NOT A SCENE. Given the full width it filled the screen
       and told the reader nothing it does not already tell at 140px — and it pushed the price and
       the buttons a screen further down. It floats now: small, on the left, with the name and the
       opening paragraph running beside it, and everything after that — the list, the price, the
       note, the buttons — clearing it and taking the full width. The float is the right tool here
       precisely because the wrap is not a column: the text goes AROUND the picture and then
       carries on underneath it. */
    .product,
    .page-product { display: block; }
    .product__figure,
    .page-product__figure {
        float: left;
        padding-top: 0;
        width: clamp(110px, 34vw, 150px);
        margin: 0 var(--s-sm) 10px 0;
    }
    .product__figure img,
    .page-product__figure img { width: 100%; max-width: 100%; height: auto; }
    /* Everything after the first block of the copy starts below the picture. `clear` costs nothing
       once the float is behind it, so a long intro simply keeps flowing. */
    .product > div > .rich > * + *,
    .product__note,
    .product__actions,
    .page-doc__rest,
    .page-doc__actions { clear: left; }
    .step__figure {
        width: 100%;
        max-width: 100%;
        aspect-ratio: 16 / 11;   /* wide, not the desktop portrait — it is a band now, not a column */
    }
    .photo-frame--case   { grid-row: auto; align-self: stretch; width: 100%; aspect-ratio: 350 / 240; }
    .photo-frame--person { width: 100%; aspect-ratio: 356 / 237; }
    .case__actions { grid-column: 1 / -1; }

    /* THE VIDEO WANTS THE SCREEN, NOT A FRAME. On a phone the card around the player is a frame
       around a frame — a border, a blur and 2x16px of padding, all of it taken out of the picture
       somebody is trying to watch. The chrome goes and the player runs the full width of the
       window with 8px of air either side, which is about 70px more picture than it had. */
    .demo__card {
        width: 100vw;
        margin-inline: calc(50% - 50vw);
        padding: 0 8px;
        border: 0;
        background: none;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        box-shadow: none;
    }
    .demo__card:hover { border: 0; box-shadow: none; }
    .demo__subtitle { padding-inline: var(--gutter); }
    .step__badge {
        width: 54px;
        height: 54px;
        border-width: 3px;
        font-size: 28px;
    }

    .product__actions,
    .step__actions,
    .case__actions { display: flex; flex-direction: column; align-items: stretch; gap: 10px; }
    .product__actions .btn,
    .step__actions .btn,
    .case__actions .btn { width: 100%; }

    .lead-form,
    .contact-form { grid-template-columns: minmax(0, 1fr); }

    /* A phone scrolls with its thumb and keeps its own scrollbar. */
    html { scrollbar-width: auto; }
    html::-webkit-scrollbar { width: initial; height: initial; display: initial; }

    /* THE COPY IS FOR READING. 13px was a tablet floor that a phone inherited; on a 390 screen it
       is a squint. 16px is also what stops iOS zooming the page when a field takes focus. */
    .rich             { font-size: 16px; line-height: 1.58; }
    .case__quote      { font-size: 16px; line-height: 1.5; }
    .step__title,
    .product__title   { font-size: 19px; line-height: 1.28; }
    .section__title   { font-size: 21px; }
    .hero__benefit    { font-size: 16px; }

    /* The factory photograph is a 5.4:1 strip at 1920 — a wide band under a heading, which is
       right on a desktop and useless on a phone: 390px across it is 72px tall and the building
       with the sign on it is a smudge. 16:9 instead, and the extra height is taken by CROPPING THE
       SIDES, not by squeezing the picture: `cover` against a 3.05:1 source keeps the full height
       of the frame and shows the middle 58% of its width — the road, the building and the sign all
       sit inside that, with room either side. */
    .about__photo,
    .photo-frame--about { aspect-ratio: 16 / 9; }
    /* The vertical figure no longer applies — at this shape nothing is cropped top or bottom, the
       whole frame from sky to field is on screen. Horizontally the building sits a little left of
       the frame's centre, so the window is nudged the same way to keep it centred on screen. */
    .photo-frame--about img { object-position: 46% 50%; }

    /* One column on a phone: half of 390px leaves four words a line. */
    .faq { grid-template-columns: minmax(0, 1fr); }
    .faq__item:nth-child(2) { border-top: 0; }
    .faq__q { font-size: 16px; }
    .faq__a p { font-size: 15px; padding-right: 8px; }

    .breadcrumbs { font-size: 12px; }
    .site-footer__legal-links { flex-direction: column; gap: 6px; }
}

/* ============ 500px — one bullet column. Not before, because there IS room before ==============
   The four hero bullets were dropped to a single column at 700, and on a 600px tablet that left
   half the card empty with the list running down one side of it. A bullet needs its icon (30–44px)
   plus about 160px of text, so two columns fit from roughly 455px of window upward. 500 is that
   line with a margin: 320–430 phones keep the single column, everything wider gets both. */
@media (max-width: 500px) {
    .hero__benefits { grid-template-columns: minmax(0, 1fr); }
}

/* =========== short PORTRAIT phones: an iPhone SE is 667 tall and the first screen was 698 =======
   Every modern phone has 800–930px of height and the hero sits inside it with room to spare, so
   nothing here may touch them — this is keyed on HEIGHT, and 700 is below every current handset.
   What it catches is the older 4.7" and 5" screens: 375x667, 360x640, 320x568. On those the lead
   magnet — the one thing on the page that collects a request — began below the fold. The numbers
   come off the hero's own padding and the vertical gaps inside the card; no type is shrunk, so the
   block reads exactly the same, just packed tighter. */
@media (max-width: 700px) and (max-height: 700px) and (orientation: portrait) {
    .hero { padding-top: 52px; padding-bottom: 16px; }
    .hero__benefits,
    .hero__stats  { margin-top: 12px; row-gap: 8px; }
    .hero__cta    { margin-top: 12px; padding-top: 12px; padding-bottom: 12px; }
    .hero__card   { padding-top: 16px; padding-bottom: 16px; }
    .scroll-hint  { display: none; }   /* nothing to hint at when the whole block is on screen */
}

/* ===================================== short landscape phones: the hero must not eat the screen */
@media (max-height: 480px) and (orientation: landscape) and (max-width: 899px) {
    .hero { padding: 66px 0 30px; }
    .scroll-hint { display: none; }
}

/* ==================================================================== 29. LEAD POPUP

   Ported from FlippingStroy and recoloured into this site's palette. The behaviour is what
   matters and it is not obvious: on a phone the dialog is pinned to the TOP of the screen, not
   centred, because the on-screen keyboard eats the bottom half and a centred dialog puts its own
   fields under it. site.js additionally clamps the overlay to `visualViewport`, so when the
   keyboard opens the box shrinks instead of sliding out of reach. */

.lead-popup {
    position: fixed;
    inset: 0;
    z-index: 12000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgb(4 12 9 / .66);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    animation: leadPopupFade .24s ease both;
}

.lead-popup[hidden] { display: none; }

.lead-popup__box {
    position: relative;
    width: 100%;
    max-width: 470px;
    max-height: calc(100dvh - 48px);
    padding: 38px 34px 30px;
    overflow-y: auto;
    overflow-x: hidden;
    border: 1px solid rgb(255 255 255 / .14);
    border-radius: var(--r-card);
    background: rgb(10 20 16 / .98);
    box-shadow: 0 34px 90px rgb(0 8 5 / .55);
    animation: leadPopupIn .34s cubic-bezier(.16, 1, .3, 1) both;
}

/* Stated, not assumed: with no `color-scheme` the browser falls back to the machine's own
   setting, and on a laptop in dark mode that repainted the light theme's form controls. */
html[data-theme='light'] { color-scheme: light; }
html[data-theme='light'] .lead-popup { background: rgb(0 40 28 / .44); }
html[data-theme='light'] .lead-popup__box {
    border-color: rgb(0 69 51 / .16);
    background: rgb(252 253 252 / .99);
    box-shadow: 0 34px 90px rgb(0 69 51 / .26);
}

.lead-popup__close {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 10px;
    color: rgb(255 255 255 / .55);
    background: transparent;
    cursor: pointer;
    transition: color .2s ease, background .2s ease, border-color .2s ease;
}
html[data-theme='light'] .lead-popup__close { color: rgb(0 69 51 / .5); }

.lead-popup__close svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.lead-popup__close:hover {
    color: var(--c-orange);
    background: rgb(245 71 0 / .1);
    border-color: rgb(245 71 0 / .32);
}

.lead-popup__head { margin-bottom: 20px; padding-right: 34px; }

.lead-popup__eyebrow {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--c-orange);
}

.lead-popup__head h3 {
    margin-top: 10px;
    font-size: 25px;
    font-weight: 700;
    line-height: 1.15;
    color: var(--c-green-deep);
    text-wrap: balance;
}
html[data-theme='dark'] .lead-popup__head h3 { color: #edf4f0; }

.lead-popup__lead {
    margin-top: 10px;
    font-size: 15px;
    line-height: 1.5;
    color: var(--c-green);
    text-wrap: pretty;
}
html[data-theme='dark'] .lead-popup__lead { color: #b9c6c0; }

.lead-popup__form { display: grid; gap: 14px; }

.lead-popup__field { display: grid; gap: 6px; }

.lead-popup__field > span {
    font-size: 13px;
    font-weight: 600;
    color: var(--c-green);
}
html[data-theme='dark'] .lead-popup__field > span { color: #b9c6c0; }

.lead-popup__field input,
.lead-popup__field select,
.lead-popup__field textarea {
    width: 100%;
    height: 48px;
    padding: 0 14px;
    border: 1px solid rgb(0 69 51 / .18);
    border-radius: var(--r-card);
    font-size: 16px;          /* 16 keeps iOS from zooming the page on focus */
    color: var(--c-green);
    background: #fff;
    appearance: none;
}
html[data-theme='dark'] .lead-popup__field input,
html[data-theme='dark'] .lead-popup__field select,
html[data-theme='dark'] .lead-popup__field textarea {
    border-color: rgb(255 255 255 / .14);
    color: #e6ede9;
    background: rgb(255 255 255 / .06);
}
.lead-popup__field input:focus,
.lead-popup__field select:focus,
.lead-popup__field textarea:focus { outline: 0; border-color: var(--c-orange); }

/* The question is the one field with more than a line to say, so it gets a real box and room to
   grow — but no drag handle: a resizable corner inside a dialog that clamps itself to the visible
   viewport on a phone is a way to push the send button off the screen. */
.lead-popup__field textarea {
    height: auto;
    min-height: 62px;
    padding: 12px 14px;
    line-height: 1.35;
    resize: none;
}

/* THE LIST THAT DROPS DOWN IS DRAWN BY THE OPERATING SYSTEM, NOT BY THIS PAGE.
   It takes its cue from two things only: the element's `color-scheme`, and explicit colours on
   the <option>s. Neither was set, so the list ignored everything around it — in the dark theme
   the popup's field is dark and the list opening out of it was white, and on a machine whose
   system theme is dark the light version came out with pale text on that white list, which is
   unreadable. Written for every select on the site so the two the forms use behave the same. */
select option {
    background: #fff;
    color: #000;
}
html[data-theme='dark'] .lead-popup__field select { color-scheme: dark; }
html[data-theme='dark'] .lead-popup__field select option {
    background: #1a211e;
    color: #e6ede9;
}

.lead-popup__form .btn { width: 100%; margin-top: 4px; }

.lead-popup__consent {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    font-size: 13px;
    line-height: 1.35;
    color: var(--c-green);
}
html[data-theme='dark'] .lead-popup__consent { color: #a9b6b0; }
.lead-popup__consent input { width: 16px; height: 16px; margin-top: 2px; accent-color: var(--c-orange); }
.lead-popup__consent a { color: var(--c-orange); }

.lead-popup__status:empty { display: none; }
.lead-popup__status {
    margin-top: 2px;
    font-size: 14px;
    line-height: 1.4;
    color: var(--c-orange);
}

@keyframes leadPopupFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes leadPopupIn {
    from { opacity: 0; transform: translateY(18px) scale(.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Phone and portrait tablet: the dialog goes to the TOP. A centred one puts its own fields under
   the keyboard the moment the first input is focused. */
@media (max-width: 980px) {
    .lead-popup {
        align-items: flex-start;
        padding: 12px;
        padding-top: calc(env(safe-area-inset-top, 0px) + 12px);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
    .lead-popup__box {
        max-width: 520px;
        max-height: calc(100dvh - 24px);
        padding: 26px 20px 22px;
    }
    .lead-popup__head { margin-bottom: 16px; }
    .lead-popup__head h3 { font-size: 22px; }
    .lead-popup__lead { font-size: 14px; }
}

/* A landscape phone has almost no height at all — tighten everything vertical. */
@media (max-width: 980px) and (max-height: 560px) {
    .lead-popup__box { padding: 18px 16px 14px; }
    .lead-popup__head { margin-bottom: 12px; }
    .lead-popup__head h3 { font-size: 19px; }
    .lead-popup__lead { display: none; }
    .lead-popup__form { gap: 10px; }
    .lead-popup__field input,
    .lead-popup__field select { height: 42px; }
}

@media (prefers-reduced-motion: reduce) {
    .lead-popup, .lead-popup__box { animation: none; }
}

/* ==================================================================== 30. THE CURSOR

   The pointer is part of the brand here: an orange arrow with a thin white outline so it stays
   visible over the sunset photograph as well as over paper, one size up from the system default
   but no more — a big cursor reads as a gimmick. The hand gets the same treatment, because a
   custom arrow next to a stock hand looks like a bug.

   The hotspot numbers matter: 4 4 puts the arrow's tip where the system's is, and 12 3 puts the
   hand's index fingertip on the target. A wrong hotspot makes every click feel misaligned.
   `auto` / `pointer` stay as the fallback for anything that cannot load the image. */

html, body { cursor: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2230%22%20height%3D%2230%22%20viewBox%3D%220%200%2030%2030%22%3E%3Cpath%20d%3D%22M5%203.2%2024%2015.4l-8.1%201.2%204.5%208.1-3.1%201.7-4.5-8.1L8%2022.9z%22%20fill%3D%22%2310ea00%22%20stroke%3D%22%23fff%22%20stroke-width%3D%221.6%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E") 4 4, auto; }

a, button, label, summary, select,
input[type='checkbox'], input[type='radio'],
.btn, .scroll-rail__tick, .scroll-hint, .burger,
.segmented__opt, .lead-popup__close { cursor: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2232%22%20height%3D%2232%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20d%3D%22M12.4%2015.3V6.6a2.1%202.1%200%200%201%204.2%200v6.9m0-1.1a1.9%201.9%200%200%201%203.8%200v1.7m0-.9a1.9%201.9%200%200%201%203.8%200v2m0-.6a1.9%201.9%200%200%201%203.7%200v4.6c0%204.7-3.4%208.4-8.2%208.4-4%200-6-1.6-7.7-4.2l-3.9-6.1a2.1%202.1%200%200%201%203.3-2.5l1.9%202.2z%22%20fill%3D%22%2310ea00%22%20stroke%3D%22%23fff%22%20stroke-width%3D%221.6%22%20stroke-linejoin%3D%22round%22%20stroke-linecap%3D%22round%22%2F%3E%3C%2Fsvg%3E") 12 3, pointer; }

input[type='text'], input[type='tel'], input[type='email'], textarea { cursor: text; }

/* ---- the first screen on a phone ----
   At 1920 the plates are near-black because they sit on a bright photograph and the text has to
   win. On a phone the plate is nearly the whole screen, and a black slab reads as a black screen
   with the picture hidden behind it. So they lighten and blur instead: the field still shows
   through, the copy still reads. */
@media (max-width: 899px) {
    .hero__card {
        background: rgb(12 24 18 / .58);
        backdrop-filter: blur(14px) saturate(1.2);
        -webkit-backdrop-filter: blur(14px) saturate(1.2);
        border: 1px solid rgb(255 255 255 / .12);
    }
    .hero__cta {
        background: rgb(12 24 18 / .55);
        backdrop-filter: blur(14px) saturate(1.2);
        -webkit-backdrop-filter: blur(14px) saturate(1.2);
        border: 1px solid rgb(255 255 255 / .12);
    }
}
