/* ==========================================================================
   Ramzur — landing stylesheet

   Structure
     1. Tokens          — color, type, motion, spacing, z-index
     2. Reset & base
     3. Primitives      — wrap, eyebrow, headings, buttons, .ph placeholders
     4. Components      — nav, hero, stats, about, services, guarantees,
                          checklist, contact, forms, footer, modal
     5. Motion          — load choreography, scroll-reveal, micro-interactions
     6. Reduced motion  — single authoritative override block

   Breakpoints (used consistently throughout):
     1024px  two-column heroes and panels collapse
      940px  nav links collapse to the burger (content-driven: the five
             Russian labels stop fitting next to the logo and the CTA)
      880px  remaining two-column grids collapse
      620px  single-column everything, tightened spacing
   ========================================================================== */

/* ============================ 1. TOKENS ================================== */

:root{
  /* ---- surfaces ---- */
  --bg: #0D111C;
  --surface: #141A29;
  --surface-2: #1A2235;
  --surface-3: #202A40;

  --line: rgba(245,246,248,0.09);
  --line-strong: rgba(245,246,248,0.16);

  /* ---- text ramp ----
     Measured against every surface it is used on (WCAG 2.1, dark theme):
       --text        17.3:1 on bg   — headings, emphasis
       --text-muted   8.1:1 on bg / 6.8:1 on surface-2 — secondary body copy
       --text-faint   5.6:1 on bg / 4.7:1 on surface-2 — small labels, meta
     The previous --text-faint (#5B6478) measured 2.7-3.2:1 and failed AA
     wherever it carried text, which was every label on the page. */
  --text: #F3F5F8;
  --text-muted: #A2AABE;
  --text-faint: #828CA6;

  /* ---- brand ---- */
  --amber: #FFB454;
  --amber-hover: #FFC478;
  --amber-ink: #241705;
  --teal: #5EEAD4;

  --amber-wash: rgba(255,180,84,0.06);
  --amber-wash-strong: rgba(255,180,84,0.11);
  --draft-line: rgba(255,180,84,0.45);
  --error: #FF8B8B;
  --error-wash: rgba(255,139,139,0.09);

  /* ---- type ---- */
  --font-display: 'Unbounded', ui-sans-serif, system-ui, sans-serif;
  --font-body: 'Golos Text', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* ---- motion ----
     Exponential ease-out only: motion decelerates into place and never
     overshoots. Nothing on this page bounces. */
  --ease-out-quart: cubic-bezier(.25, 1, .5, 1);
  --ease-out-quint: cubic-bezier(.22, 1, .36, 1);
  --ease-out-expo:  cubic-bezier(.16, 1, .3, 1);

  --dur-fast: .16s;
  --dur-mid: .28s;
  --dur-slow: .5s;
  --dur-reveal: .8s;

  /* ---- space ---- */
  --space-section: clamp(64px, 8vw, 96px);
  --space-gutter: clamp(20px, 4vw, 28px);
  --space-gap: clamp(28px, 4.5vw, 56px);
  --panel-pad: clamp(24px, 3.4vw, 44px);

  /* ---- geometry ---- */
  --container: 1180px;
  --radius: 14px;
  --radius-sm: 8px;
  --nav-h: 74px;
  --marker-w: 26px;
  --prose: 68ch;

  /* ---- z-index: one semantic scale, no arbitrary 999s ---- */
  --z-base: 1;
  --z-sticky: 50;
  --z-progress: 60;
  --z-modal: 300;
  --z-skip: 400;
}

/* ============================ 2. RESET & BASE ============================ */

*{ box-sizing: border-box; }
html, body{ margin:0; padding:0; }

html{
  scroll-behavior: smooth;
  /* keeps anchored sections clear of the sticky nav */
  scroll-padding-top: calc(var(--nav-h) + 10px);
}

body{
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 16px;
  /* light-on-dark reads lighter than it measures; the extra leading buys
     back the legibility the inverted contrast costs */
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, svg{ display:block; max-width:100%; }
a{ color: inherit; text-decoration: none; }
button{ font-family: inherit; cursor: pointer; }
input, textarea, button{ font-family: inherit; font-size: inherit; }

::selection{ background: var(--amber); color: var(--amber-ink); }
::placeholder{ color: var(--text-faint); opacity: 1; }

/* One focus style for the whole page. Never removed, only replaced. */
:focus-visible{
  outline: 2px solid var(--amber);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link{
  position: absolute;
  left: 50%;
  top: 10px;
  translate: -50% -160%;
  z-index: var(--z-skip);
  background: var(--amber);
  color: var(--amber-ink);
  font-weight: 600;
  font-size: 14px;
  padding: 11px 20px;
  border-radius: 100px;
  transition: translate var(--dur-mid) var(--ease-out-quint);
}
.skip-link:focus-visible{ translate: -50% 0; }

/* thin flow-gradient bar tracking scroll progress — the same
   "one continuous line" motif as the hero graphic */
.scroll-progress{
  position: fixed;
  inset: 0 0 auto 0;
  height: 3px;
  z-index: var(--z-progress);
  pointer-events: none;
}
.scroll-progress-bar{
  display: block;
  height: 100%;
  width: 100%;
  transform-origin: 0 50%;
  transform: scaleX(0);
  background: linear-gradient(90deg, var(--amber), var(--teal));
  /* scaleX rather than width: no layout work on a scroll handler */
  transition: transform .1s linear;
}

/* ============================ 3. PRIMITIVES ============================== */

.wrap{
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-gutter);
}

/* Long Russian compounds plus large clamp scales are the overflow risk on
   this page, so every heading is allowed to break rather than escape its
   column, and grid children are all allowed to shrink below content width. */
h1, h2, h3{
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
  overflow-wrap: break-word;
}
h2{ font-size: clamp(26px, 3.4vw, 42px); }
h3{ font-size: clamp(18px, 1.9vw, 22px); }

p{ margin: 0; text-wrap: pretty; }
.muted{ color: var(--text-muted); }

.eyebrow{
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--amber);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 16px;
}
.eyebrow::before{
  content: "";
  flex: 0 0 16px;
  height: 1px;
  background: var(--amber);
}

.section{
  padding-block: var(--space-section);
  position: relative;
  border-bottom: 1px solid var(--line);
}
.section--alt{ background: var(--surface); }
.section-head{
  max-width: 640px;
  margin: 0 0 clamp(32px, 4vw, 48px);
}
.section-head p{
  margin-top: 14px;
  font-size: 17px;
  color: var(--text-muted);
  max-width: var(--prose);
}

/* ---------- Placeholder markers (removed before launch) ---------- */
.ph{
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  border: 1px dashed var(--draft-line);
  border-radius: 100px;
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: max(12.5px, 0.78em);
  line-height: 1.5;
  background: var(--amber-wash);
  /* was white-space:nowrap — the longer markers overflowed their
     container on narrow viewports */
  overflow-wrap: anywhere;
  max-width: 100%;
}
.ph::before{ content: "✎"; opacity: .8; }

/* the long "pick one" markers read as a note under the sentence rather than
   an inline pill wedged into running text */
.ph-note{
  display: inline-flex;
  margin-top: 10px;
}

.ph-block{
  border: 1px dashed var(--draft-line);
  background: rgba(255,180,84,0.05);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  font-size: 14.5px;
  color: var(--text-muted);
}
.ph-block b{ color: var(--amber); font-weight: 600; }

/* ---------- Buttons ---------- */
.btn{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;              /* touch target, and equal heights in a row */
  padding: 13px 26px;
  border-radius: 100px;
  font-weight: 600;
  font-size: 15px;
  line-height: 1.25;
  border: 1px solid transparent;
  text-align: center;
  transition:
    transform var(--dur-fast) var(--ease-out-quart),
    background var(--dur-mid) var(--ease-out-quart),
    border-color var(--dur-mid) var(--ease-out-quart),
    color var(--dur-mid) var(--ease-out-quart),
    box-shadow var(--dur-mid) var(--ease-out-quart);
}
.btn svg{ width:16px; height:16px; flex:0 0 auto; }
.btn-block{ width: 100%; }

.btn-primary{ background: var(--amber); color: var(--amber-ink); }
.btn-ghost{
  background: transparent;
  border-color: var(--line-strong);
  color: var(--text);
}

@media (hover: hover){
  .btn-primary:hover{
    background: var(--amber-hover);
    transform: translateY(-2px);
    box-shadow: 0 14px 28px -12px rgba(255,180,84,0.45);
  }
  /* the arrow leans toward the action on hover */
  .btn-primary:hover svg{ transform: translateX(3px); }
  .btn-ghost:hover{
    transform: translateY(-2px);
    border-color: var(--amber);
    color: var(--amber);
  }
}
.btn svg{ transition: transform var(--dur-mid) var(--ease-out-quint); }
.btn:active{ transform: translateY(0) scale(.975); }
.btn:disabled{
  opacity: .55;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* ============================ 4. COMPONENTS ============================== */

/* ---------- Nav ---------- */
.nav{
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: rgba(13,17,28,0.85);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  transition:
    box-shadow var(--dur-mid) var(--ease-out-quart),
    border-color var(--dur-mid) var(--ease-out-quart),
    background var(--dur-mid) var(--ease-out-quart);
}
.nav.scrolled{
  background: rgba(13,17,28,0.94);
  box-shadow: 0 12px 28px -12px rgba(0,0,0,0.55);
  border-color: var(--line-strong);
}
.nav > .wrap{
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  height: var(--nav-h);
}
.logo{
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -0.01em;
  flex: 0 0 auto;
}
.logo svg{ width:26px; height:26px; }
.logo--sm{ font-size: 16px; }

.nav-links{
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.4vw, 30px);
  font-size: 14.5px;
  color: var(--text-muted);
}
.nav-actions{ display:flex; align-items:center; gap:14px; }

.nav-toggle{
  display: none;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: var(--text);
  width: 44px;                    /* touch target */
  height: 44px;
  border-radius: 10px;
  transition: background var(--dur-fast) var(--ease-out-quart);
}
.nav-toggle svg{ width:24px; height:24px; }
@media (hover: hover){
  .nav-toggle:hover{ background: var(--surface-2); }
}

/* nav underline: scaleX, echoing the flow motif */
.nav-links a{
  position: relative;
  padding-block: 4px;
  transition: color var(--dur-mid) var(--ease-out-quart);
}
.nav-links a::after{
  content: "";
  position: absolute;
  inset: auto 0 -4px 0;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--amber), var(--teal));
  transform: scaleX(0);
  transform-origin: left;
  opacity: 0;
  transition:
    transform var(--dur-mid) var(--ease-out-quint),
    opacity var(--dur-fast) var(--ease-out-quart);
}
.nav-links a:hover{ color: var(--text); }
.nav-links a:hover::after{ transform: scaleX(.5); opacity: 1; }
.nav-links a.active{ color: var(--text); }
.nav-links a.active::after{ transform: scaleX(1); opacity: 1; }

.mobile-menu{
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-bottom: 1px solid transparent;
  max-height: 0;
  overflow: hidden;
  visibility: hidden;
  transition:
    max-height var(--dur-slow) var(--ease-out-quint),
    visibility 0s linear var(--dur-slow),
    border-color var(--dur-slow) var(--ease-out-quint);
}
.mobile-menu.open{
  max-height: 400px;
  visibility: visible;
  border-bottom-color: var(--line);
  transition:
    max-height var(--dur-slow) var(--ease-out-quint),
    visibility 0s,
    border-color var(--dur-slow) var(--ease-out-quint);
}
.mobile-menu a{
  padding: 15px var(--space-gutter);
  border-top: 1px solid var(--line);
  color: var(--text-muted);
  font-size: 15px;
  /* links slide in behind the opening panel, in reading order */
  opacity: 0;
  transform: translateY(-8px);
  transition:
    opacity var(--dur-mid) var(--ease-out-quart),
    transform var(--dur-mid) var(--ease-out-quart),
    color var(--dur-fast) var(--ease-out-quart);
}
.mobile-menu.open a{
  opacity: 1;
  transform: none;
  transition-delay: calc(90ms + var(--i, 0) * 45ms);
}
.mobile-menu a.active{ color: var(--amber); }

@media (max-width: 940px){
  .nav-links{ display:none; }
  .nav-toggle{ display:flex; }
  .btn-ghost.nav-only{ display:none; }
}

/* ---------- Hero ---------- */
.hero{
  padding-top: clamp(52px, 6vw, 76px);
  padding-bottom: clamp(40px, 5vw, 60px);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
.hero-grid{
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: var(--space-gap);
  align-items: center;
}
.hero-grid > *{ min-width: 0; }

.hero h1{
  /* Unbounded sets very wide: past ~46px this headline runs to six lines and
     stops reading as one statement */
  font-size: clamp(29px, 3.5vw, 46px);
  margin-bottom: 22px;
  max-width: 22ch;
}
.hero h1 em{ font-style: normal; color: var(--amber); }

.hero-sub{
  font-size: clamp(16.5px, 1.4vw, 18px);
  color: var(--text-muted);
  max-width: 48ch;
  margin-bottom: clamp(26px, 3vw, 34px);
}
.hero-ctas{
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: clamp(30px, 4vw, 46px);
}
.hero-note{
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-faint);
  display: flex;
  /* the note wraps to two lines on narrow viewports; centring the dot then
     parks it in the gap between them, so it aligns to the first line instead */
  align-items: flex-start;
  gap: 10px;
}
.hero-note .dot{
  flex: 0 0 7px;
  width: 7px;
  height: 7px;
  margin-top: .48em;                      /* optical centre of the first line */
  border-radius: 50%;
  background: var(--teal);
  box-shadow: 0 0 0 3px rgba(94,234,212,0.15);
}

.hero-visual{ position: relative; }
.hero-visual svg{ width:100%; height:auto; }

/* The hero was the one grid on the page with no mobile rule: below ~1024px
   the headline was being squeezed into roughly half a phone width. */
@media (max-width: 1024px){
  .hero-grid{ grid-template-columns: 1fr; gap: clamp(24px, 4vw, 40px); }
  .hero h1{ max-width: 24ch; }
  .hero-visual{
    order: 2;
    width: 100%;
    max-width: 520px;
    margin-inline: auto;
  }
}
@media (max-width: 620px){
  /* the graphic is decoration, and on a phone it costs more scroll than
     it returns; the motif still carries via the progress bar */
  .hero-visual{ display: none; }
}

/* ---------- Stats ---------- */
.stats{
  margin-top: clamp(34px, 4.5vw, 52px);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--line);
}
.stat{
  padding: clamp(22px, 2.6vw, 30px) clamp(14px, 2vw, 24px);
  border-inline-end: 1px solid var(--line);
  transition: background var(--dur-mid) var(--ease-out-quart);
}
.stat:nth-child(4n){ border-inline-end: none; }
.stat-num{
  font-family: var(--font-mono);
  font-size: clamp(24px, 2.6vw, 32px);
  font-weight: 600;
  line-height: 1.1;
  color: var(--amber);
  display: block;
  margin-bottom: 6px;
  font-variant-numeric: tabular-nums;
}
/* .stat-num also carries .ph while the numbers are placeholders; without this
   the block display stretches the marker pill across the whole column */
.stat-num.ph{ display: inline-flex; }
.stat-label{
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--text-muted);
  display: block;
}
@media (hover: hover){
  .stat:hover{ background: rgba(255,180,84,0.045); }
}
@media (max-width: 880px){
  .stats{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* previously every cell kept its right border, so column 2 drew a
     stray hairline against the container edge */
  .stat:nth-child(2n){ border-inline-end: none; }
  .stat:nth-child(-n+2){ border-block-end: 1px solid var(--line); }
}
@media (max-width: 460px){
  .stats{ grid-template-columns: 1fr; }
  .stat{ border-inline-end: none; border-block-end: 1px solid var(--line); }
  .stat:last-child{ border-block-end: none; }
}

/* ---------- About ---------- */
/* the method panel slides in horizontally, so its track clips rather than
   letting the transform widen the document */
.about-grid{
  overflow-x: clip;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-gap);
  align-items: start;
}
.about-copy > * + *{ margin-top: 26px; }
.about-copy h3{ margin-bottom: 10px; }
.about-copy p{ max-width: var(--prose); }

/* The right-hand column stacks the process panel and the team credential.
   A wrapper rather than making both direct grid children: at the one-column
   breakpoint two grid items would separate and the card would drift away
   from the panel it belongs under. */
.about-side{
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
}

.method{
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(22px, 2.6vw, 30px);
}
.method-title{
  font-family: var(--font-mono);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--text-faint);
  margin-bottom: 22px;
}
.method-step{
  display: flex;
  gap: 16px;
  padding: 16px 0;
  border-top: 1px solid var(--line);
}
.method-step:first-of-type{ border-top: none; padding-top: 0; }
.method-step .n{
  font-family: var(--font-mono);
  color: var(--amber);
  font-size: 14px;
  line-height: 1.7;                       /* optically aligns to the first text line */
  flex: 0 0 var(--marker-w);
  font-variant-numeric: tabular-nums;
}
.method-step p{ font-size: 15px; color: var(--text-muted); }
.method-step strong{ color: var(--text); font-weight: 600; }

/* Now carries real team facts, so the dashed "fill me in" treatment is gone.
   It shares the .method panel language it sits beneath — the page's existing
   form for a block of stated specifics — rather than inventing a third card
   style. Spacing comes from the .about-side gap, so no margin here. */
.team-card{
  padding: clamp(20px, 2.2vw, 24px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.team-card-title{
  font-family: var(--font-mono);
  font-size: 12.5px;
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--text-faint);
  margin-bottom: 12px;
}
.team-card-body{ font-size: 15px; color: var(--text-muted); }
/* the university is the credential, so it is the one thing lifted to full ink */
.team-card-body strong{ color: var(--text); font-weight: 600; }

/* The four disciplines are listed once, here, rather than repeated in the
   sentence above — a scannable row beats a comma list buried in prose.
   Markers lead each item instead of separating them: a middot separator
   dangles at the end of a line whenever the row wraps, which it does below
   about 420px. */
.team-disciplines{
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
}
.team-disciplines li{
  display: flex;
  align-items: center;
  gap: 8px;
}
.team-disciplines li::before{
  content: "";
  flex: 0 0 4px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--amber);
}

@media (max-width: 880px){
  .about-grid{ grid-template-columns: 1fr; }
}

/* ---------- Services ---------- */
.service-list{ display: flex; flex-direction: column; gap: 20px; }
.service{
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(24px, 3vw, 36px);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
  gap: var(--space-gap);
}
/* Both columns are flex so the CTA and the bonus strip can be pinned to the
   bottom. Previously they floated at their own content heights and the two
   halves of every card ended on different lines. */
.service-lead,
.service-detail{ display: flex; flex-direction: column; min-width: 0; }

.service-tag{
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--teal);
  text-transform: uppercase;
  letter-spacing: .08em;
  margin-bottom: 14px;
  display: block;
}
.service h3{ margin-bottom: 14px; }
.service-for{
  color: var(--text-muted);
  font-size: 15px;
  margin-bottom: 22px;
  max-width: 46ch;
}
.service-cta{
  margin-top: auto;
  align-self: flex-start;
}

.stack-label{
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: .08em;
  margin: 0 0 12px;
}
.stack-list{
  list-style: none;
  margin: 0 0 22px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.stack-list li{
  position: relative;
  padding-left: 22px;
  font-size: 15px;
  color: var(--text);
}
.stack-list li::before{
  content: "";
  position: absolute;
  left: 0;
  top: 0.6em;                             /* scales with the text, not a fixed 8px */
  width: 10px;
  height: 2px;                            /* 1px landed on half-pixels and rendered grey */
  border-radius: 2px;
  background: var(--amber);
  transform-origin: left;
  transition: transform var(--dur-mid) var(--ease-out-quint);
}
.bonus{
  margin-top: auto;
  border-top: 1px solid var(--line);
  padding-top: 18px;
  font-size: 14.5px;
  color: var(--text-muted);
}
.bonus b{ color: var(--text); }

@media (hover: hover){
  .service{
    transition:
      transform var(--dur-mid) var(--ease-out-quint),
      border-color var(--dur-mid) var(--ease-out-quart),
      box-shadow var(--dur-mid) var(--ease-out-quart);
  }
  .service:hover{
    transform: translateY(-4px);
    border-color: var(--line-strong);
    box-shadow: 0 24px 48px -28px rgba(0,0,0,0.6);
  }
  /* the leader rules extend rather than the text reflowing —
     transform, so hovering a card does no layout work */
  .service:hover .stack-list li::before{ transform: scaleX(1.9); }
}

@media (max-width: 880px){
  .service{ grid-template-columns: 1fr; gap: 24px; }
  .service-cta{ margin-top: 4px; }
  .bonus{ margin-top: 4px; }
}

/* ---------- Clients / social proof ----------
   A punctuation band between two full-weight sections, not a third one: the
   tighter vertical rhythm is what keeps "who we are -> who trusted us ->
   what we do" reading as one thought.

   Deliberately NOT a card grid and NOT a marquee. The page already states
   factual proof as hairline-divided cells (the "в цифрах" strip, the process
   steps, the contact rows), so this reuses that language; and an
   auto-scrolling logo carousel is the exact "cheap outsourcing site" move
   PRODUCT.md lists as an anti-reference. */
.section--tight{ padding-block: clamp(48px, 6vw, 68px); }
.clients-head{ margin-bottom: clamp(28px, 3.2vw, 40px); }

/* Rows are separated by hairlines, columns by whitespace.
   Vertical dividers were the obvious choice here (it is what the "в цифрах"
   strip does) but they cannot survive a partial last row: with auto-fit, four
   columns and five logos, the fifth cell draws a divider that dangles into
   empty space. Row rules have no such failure — the wrapper clips the final
   cell border, so its own bottom rule is the only line under the last row
   whether that row is full or not.
   Net effect: this wall stays correct for any number of entries at any
   width, so deleting a card needs no CSS change. */
.client-wall-clip{
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.client-wall{
  --client-pad: clamp(14px, 1.6vw, 20px);
  list-style: none;
  padding: 0;
  /* bled outward so the hover wash reads as a band and the first column's
     content still lines up with the section heading — the same trick the
     checklist rows use */
  margin: 0 calc(-1 * var(--client-pad)) -1px;
  display: grid;
  /* Explicit count, matched to the number of logos in the markup, so there
     is never a dead track at the end of the row. Five across at full width;
     three and two below, where the row may end partial — harmless, because
     the dividers are row rules only and the wrapper clips the last one.
     Add or remove a logo? Change the 5 here to match. */
  grid-template-columns: repeat(5, minmax(0, 1fr));
}
.client{
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
  min-width: 0;
  /* no column gap: cells butt together so the row rule runs continuously
     instead of breaking into one segment per cell */
  padding: clamp(22px, 2.4vw, 28px) var(--client-pad);
  border-bottom: 1px solid var(--line);
  transition: background var(--dur-mid) var(--ease-out-quart);
}

@media (max-width: 1080px){
  .client-wall{ grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 620px){
  .client-wall{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.client-mark{
  display: flex;
  align-items: center;
  justify-content: flex-start;
  width: 100%;
  min-height: 44px;
}

/* Client logos arrive in whatever colour and aspect ratio the client sends.
   Flattening every one to a single white keeps the wall from reading as a
   ransom note on this dark ground, and it stays legible on touch (where
   there is no hover) because the resting opacity is already readable.
   Colour is deliberately never restored: a navy or black wordmark would
   disappear against --bg. */
.client-logo{
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 34px;
  /* brightness(0) flattens to black while keeping the alpha channel,
     invert(1) then lifts it to white — works for any source colour */
  filter: brightness(0) invert(1);
  opacity: .72;
  /* Per-logo optical balance: a wide wordmark and a compact square mark read
     as different visual weights at the same height, so each is nudged via
     --logo-scale (values set further down, per src).

     transform-origin pins the LEFT edge. By default scale() works about the
     centre, which insets a scaled-down logo — the first mark in the row then
     sits ~18px right of the section heading it is supposed to align with. */
  scale: var(--logo-scale, 1);
  transform-origin: 0 50%;
  transition:
    opacity var(--dur-mid) var(--ease-out-quart),
    scale var(--dur-mid) var(--ease-out-quint);
}

/* placeholder slot, in the same dashed language as every other pending item */
.client-mark--empty{
  justify-content: center;
  border: 1px dashed var(--draft-line);
  border-radius: var(--radius-sm);
  background: rgba(255,180,84,0.05);
  color: var(--amber);
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: .04em;
}

/* The industry is the fact that turns a logo into a claim. Left as plain
   pending text rather than a second dashed pill per cell — twelve dashed
   markers in one band was pure noise, and the note below explains it once. */
.client-industry{
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--text-muted);
}
.client-industry:empty::before{ content: "отрасль"; color: var(--text-faint); }
/* Per-logo optical balance — see the --logo-scale note above. Values are
   derived from each mark's rendered area at a shared 34px cap:
     glotus  4704px^2 (4:1 wordmark)  -> pulled down
     qadam   1875px^2                 -> nudged up
     dopsy   2035px^2                 -> reference, left alone
     sabil   1152px^2 (1:1 square)    -> pulled up hardest
     yassawi 1938px^2                 -> nudged up
   Re-derive these if a logo is swapped; do not copy them onto a new mark. */
.client-logo[src$="client-glotus.svg"]  { --logo-scale: .74; }
.client-logo[src$="client-qadam.svg"]   { --logo-scale: 1.05; }
.client-logo[src$="client-sabil.svg"]   { --logo-scale: 1.30; }
.client-logo[src$="client-yassawi.svg"] { --logo-scale: 1.05; }

.clients-note{ margin-top: clamp(22px, 2.6vw, 30px); }
.clients-note code{
  font-family: var(--font-mono);
  font-size: .92em;
  color: var(--text);
}

@media (hover: hover){
  .client:hover{ background: rgba(255,180,84,0.05); }
  .client:hover .client-logo{ opacity: 1; scale: calc(var(--logo-scale, 1) * 1.04); }
}

/* The wall settles in reading order — it is a list being scanned, so the
   entrance follows the same left-to-right cadence as the stats strip.

   The wrapper carries .reveal purely as the scroll trigger; its own fade and
   rise are cancelled so the cells are the only thing that moves. Otherwise
   the block and its children animate opacity over each other and the whole
   wall arrives muddy. */
.js .client-wall-clip.reveal{ opacity: 1; }
.js .client-wall-clip.reveal:not(.is-visible){ transform: none; }
.js .client-wall-clip:not(.is-visible) .client{ opacity: 0; }
.js .client-wall-clip.is-visible .client{
  animation: clientIn .6s var(--ease-out-quint) both;
  animation-delay: calc(120ms + var(--i, 0) * 65ms);
}
@keyframes clientIn{
  from{ opacity: 0; transform: translateY(12px); }
  to  { opacity: 1; transform: none; }
}

/* ---------- Guarantees ---------- */
.guarantee-grid{
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 24px;
}
.guarantee{
  display: flex;
  flex-direction: column;
  padding: clamp(24px, 2.6vw, 30px) clamp(22px, 2.4vw, 26px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.guarantee svg{
  width: 26px;
  height: 26px;
  color: var(--amber);
  margin-bottom: 18px;
  transition: transform var(--dur-mid) var(--ease-out-quint);
}
.guarantee h3{ margin-bottom: 10px; font-size: 18px; }
.guarantee p{ color: var(--text-muted); font-size: 14.5px; }
/* pinned to the bottom so the one card that carries a draft tag still
   lines up with the two that do not */
.guarantee .draft-tag{
  align-self: flex-start;
  margin-top: auto;
  padding-top: 14px;
}
.guarantee-cta{ margin-top: clamp(28px, 3.4vw, 36px); }

@media (hover: hover){
  .guarantee{
    transition:
      transform var(--dur-mid) var(--ease-out-quint),
      border-color var(--dur-mid) var(--ease-out-quart);
  }
  .guarantee:hover{ transform: translateY(-4px); border-color: var(--draft-line); }
  .guarantee:hover svg{ transform: scale(1.12) rotate(-4deg); }
}

/* ---------- Checklist ---------- */
.checklist-panel{
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--panel-pad);
  display: grid;
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: var(--space-gap);
}
.checklist-items{ list-style: none; margin: 0; padding: 0; }
.checklist-items li{
  display: flex;
  gap: 16px;
  padding: 16px 12px;
  margin-inline: -12px;
  border-top: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-size: 15px;
  transition: background var(--dur-mid) var(--ease-out-quart);
}
.checklist-items li:first-child{ border-top: none; }
.checklist-items .num{
  font-family: var(--font-mono);
  color: var(--amber);
  font-size: 14px;
  line-height: 1.7;
  flex: 0 0 var(--marker-w);
  font-variant-numeric: tabular-nums;
}
.checklist-side{
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.checklist-side h3{ margin-bottom: 14px; }
.checklist-side p{
  color: var(--text-muted);
  margin-bottom: 26px;
  font-size: 15px;
  max-width: 46ch;
}
.checklist-cta{ align-self: flex-start; }

@media (hover: hover){
  .checklist-items li:hover{ background: var(--amber-wash); }
}
@media (max-width: 880px){
  .checklist-panel{ grid-template-columns: 1fr; }
  .checklist-side{ order: -1; }
}

/* ---------- Contact ---------- */
.contact-grid{
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-gap);
  align-items: start;
}
.contact-title{ margin-bottom: 14px; }
.contact-intro{
  margin-bottom: clamp(24px, 3vw, 32px);
  font-size: 16px;
  max-width: var(--prose);
}
.alt-contacts-label{ margin-bottom: 20px; }
.alt-contacts{ display: flex; flex-direction: column; }
.alt-contact{
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 16px 0;
  border-top: 1px solid var(--line);
}
.alt-contact:first-child{ border-top: none; padding-top: 0; }
.alt-contact .label{ font-size: 13.5px; color: var(--text-muted); }
.alt-contacts-note{ margin-top: 28px; }

/* The contact grid was the second two-column layout with no mobile rule. */
@media (max-width: 880px){
  .contact-grid{ grid-template-columns: 1fr; }
}

/* ---------- Forms ---------- */
.form-field{ margin-bottom: 18px; }
.form-field label{
  display: block;
  font-size: 13.5px;
  color: var(--text-muted);
  margin-bottom: 8px;
}
.form-field .req{ color: var(--amber); }
.form-field .opt{
  color: var(--text-faint);
  font-size: 12.5px;
}
.form-field input,
.form-field textarea{
  width: 100%;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 13px 15px;
  color: var(--text);
  font-size: 15px;
  line-height: 1.5;
  transition:
    border-color var(--dur-fast) var(--ease-out-quart),
    box-shadow var(--dur-fast) var(--ease-out-quart),
    background var(--dur-fast) var(--ease-out-quart);
}
.form-field input:hover,
.form-field textarea:hover{ border-color: var(--text-faint); }
.form-field input:focus-visible,
.form-field textarea:focus-visible{
  outline: none;                          /* replaced, not removed */
  border-color: var(--amber);
  box-shadow: 0 0 0 3px var(--amber-wash-strong);
}
.form-field textarea{
  min-height: 88px;
  /* height is driven by content (see the autogrow behaviour in script.js),
     so the manual resize handle would just fight it */
  resize: none;
  max-height: 240px;
  overflow-y: auto;
}
.form-note{
  font-size: 13px;
  color: var(--text-faint);
  margin-top: 14px;
}

.field-error{
  margin-top: 7px;
  font-size: 13px;
  color: var(--error);
}
.form-field.error input,
.form-field.error textarea{
  border-color: var(--error);
  background: var(--error-wash);
}
.form-field.error label{ color: var(--error); }

/* ---------- Honeypot ----------
   Visually gone, but still a real rendered field: display:none and
   visibility:hidden are both patterns spam bots know to skip. */
.hp{
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  pointer-events: none;
}

/* ---------- Send failure ----------
   Warm red rather than the brand amber: amber already means "placeholder,
   fill me in" everywhere else on this page, so reusing it for a failure
   would collide with an established meaning. */
.form-error{
  border: 1px solid var(--error);
  border-radius: var(--radius-sm);
  background: var(--error-wash);
  padding: 16px 18px;
  margin-bottom: 20px;
  font-size: 14.5px;
  color: var(--text-muted);
  animation: successIn var(--dur-slow) var(--ease-out-expo) both;
}
.form-error-title{
  color: var(--error);
  font-weight: 600;
  margin-bottom: 6px;
}
.form-error-contacts{
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  font-size: 14px;
}
.form-error-contacts a{
  color: var(--text);
  border-bottom: 1px solid var(--line-strong);
  padding-bottom: 1px;
  transition: border-color var(--dur-fast) var(--ease-out-quart),
              color var(--dur-fast) var(--ease-out-quart);
}
.form-error-contacts a:hover{ color: var(--amber); border-bottom-color: var(--amber); }

/* ---------- Submit in flight ----------
   The label change is what actually communicates the state; the ring is
   secondary, so it is the part that disappears under reduced motion. */
.btn[data-sending]{
  opacity: 1;                 /* overrides the generic :disabled dimming */
  cursor: progress;
  gap: 12px;
}
.btn[data-sending]::before{
  content: "";
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  animation: btnSpin .7s linear infinite;
}
@keyframes btnSpin{ to{ transform: rotate(360deg); } }

.form-success{
  display: none;
  align-items: flex-start;
  gap: 12px;
  padding: 18px 20px;
  border: 1px solid var(--teal);
  border-radius: var(--radius-sm);
  background: rgba(94,234,212,0.07);
  color: var(--teal);
  font-size: 14.5px;
  margin-bottom: 20px;
}
.form-success.show{
  display: flex;
  animation: successIn var(--dur-slow) var(--ease-out-expo) both;
}
.form-success-mark{
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  margin-top: 2px;
}
.form-success.show .form-success-mark path{
  stroke-dasharray: 26;
  stroke-dashoffset: 26;
  animation: drawCheck .5s var(--ease-out-quart) .18s forwards;
}
#leadForm.hidden,
#modalForm.hidden{ display: none; }

/* ---------- Footer ---------- */
footer{ padding-block: 44px; }
footer > .wrap{
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px 24px;
}
.footer-links{
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  font-size: 14px;
  color: var(--text-muted);
}
.footer-links a{ transition: color var(--dur-fast) var(--ease-out-quart); }
.footer-links a:hover{ color: var(--text); }
.footer-copy{ font-size: 13px; color: var(--text-faint); }

/* ---------- Final CTA ---------- */
.cta-final{
  text-align: center;
  padding-block: clamp(64px, 8vw, 90px);
}
.cta-final h2{ margin-bottom: 18px; }
.cta-final p{
  color: var(--text-muted);
  margin-bottom: 32px;
  font-size: 17px;
  max-width: 46ch;
  margin-inline: auto;
  text-wrap: balance;
}
.cta-final .hero-ctas{ justify-content: center; margin-bottom: 0; }

/* ---------- Lead modal ---------- */
.modal-overlay{
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: rgba(9,12,20,0.72);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  transition: opacity var(--dur-mid) var(--ease-out-quart);
}
/* The dialog is fully removed from the tree when closed, so its inputs are
   never reachable by Tab — previously they stayed in the tab order behind
   an opacity-0 overlay. script.js delays this until the exit finishes. */
.modal-overlay[hidden]{ display: none; }
.modal-overlay.open{ opacity: 1; }

.modal{
  width: 100%;
  max-width: 440px;
  /* short viewports (landscape phones) used to clip the submit button
     with no way to reach it */
  max-height: calc(100dvh - 48px);
  display: flex;
  flex-direction: column;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: clamp(28px, 4vw, 40px) clamp(22px, 3vw, 36px) clamp(24px, 3vw, 32px);
  position: relative;
  transform: translateY(20px) scale(.97);
  opacity: 0;
  filter: blur(4px);
  transition:
    transform var(--dur-slow) var(--ease-out-expo),
    opacity var(--dur-mid) var(--ease-out-quart),
    filter var(--dur-slow) var(--ease-out-expo);
}
.modal-overlay.open .modal{
  transform: none;
  opacity: 1;
  filter: blur(0);
}

/* Reserved height for the per-CTA title + subtitle. Without it a two-line
   title made the dialog taller and re-centred it, so the same button
   appeared to move between openings. */
.modal-head{
  min-height: 110px;
  margin-bottom: 22px;
  padding-right: 40px;
}
.modal h3{ font-size: clamp(20px, 2.4vw, 24px); margin-bottom: 10px; }
.modal-sub{ font-size: 14.5px; }
.modal-overlay.open .modal-head > *{
  animation: headIn var(--dur-slow) var(--ease-out-expo) both;
}
.modal-overlay.open .modal-head > h3{ animation-delay: 90ms; }
.modal-overlay.open .modal-head > .modal-sub{ animation-delay: 150ms; }

.modal-body{
  overflow-y: auto;
  /* room for the focus ring inside the scroll container */
  margin: -4px;
  padding: 4px;
}

.modal-close{
  position: absolute;
  top: 12px;
  right: 12px;
  width: 44px;                            /* touch target */
  height: 44px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background var(--dur-fast) var(--ease-out-quart),
    color var(--dur-fast) var(--ease-out-quart),
    transform var(--dur-fast) var(--ease-out-quart);
}
.modal-close svg{ width:16px; height:16px; }
.modal-close:hover{
  background: var(--surface-3);
  color: var(--text);
  transform: rotate(90deg);
}
body.modal-open{ overflow: hidden; }

/* ============================ 5. MOTION ================================== */

/* ---------- Hero load choreography ----------
   One orchestrated entrance for the fold, in reading order. These are CSS
   animations rather than class-triggered transitions, so they fire on load
   with no JS involved and cannot leave the hero blank. */
@keyframes heroIn{
  from{ opacity: 0; transform: translateY(18px); filter: blur(8px); }
  to  { opacity: 1; transform: none;             filter: blur(0); }
}
.hero-in{
  animation: heroIn .85s var(--ease-out-expo) both;
  animation-delay: calc(60ms + var(--in, 0) * 90ms);
}

/* ---------- Hero graphic: scattered routine resolving into one flow ---------- */
.chaos-dot,
.chaos-line{
  opacity: 0;
  animation: settleChaos .6s var(--ease-out-quart) both;
  animation-delay: calc(var(--i, 0) * 55ms);
}
@keyframes settleChaos{ to{ opacity: .55; } }

.flow-path{
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
  animation: drawFlow 1.5s var(--ease-out-quart) .65s forwards;
}
@keyframes drawFlow{ to{ stroke-dashoffset: 0; opacity: 1; } }

.flow-node{
  opacity: 0;
  transform: scale(0);
  transform-origin: 500px 210px;
  animation: popNode .5s var(--ease-out-expo) 2s forwards;
}
@keyframes popNode{ to{ opacity: 1; transform: scale(1); } }

.flow-halo{
  opacity: 0;
  animation: fadeIn .6s var(--ease-out-quart) 2.15s forwards;
}
@keyframes fadeIn{ to{ opacity: 1; } }

/* a short bright segment running the finished route, on a slow loop —
   the same idea as the scroll-progress bar and the nav underline */
.flow-signal{
  stroke-dasharray: 12 88;
  stroke-dashoffset: 100;
  opacity: 0;
  filter: drop-shadow(0 0 4px rgba(255,244,224,0.55));
  animation: signalTravel 4.2s linear 2.6s infinite;
}
@keyframes signalTravel{
  0%  { stroke-dashoffset: 100; opacity: 0; }
  12% { opacity: .85; }
  70% { opacity: .85; }
  100%{ stroke-dashoffset: 0;   opacity: 0; }
}

/* ambient pulse on the resolved end-node: quiet, never pulls focus */
.pulse-ring{
  opacity: 0;
  transform-origin: 500px 210px;
  animation: ringPulse 2.8s var(--ease-out-quart) 2.3s infinite;
}
@keyframes ringPulse{
  0%  { transform: scale(.85); opacity: 0; }
  25% { opacity: .4; }
  100%{ transform: scale(1.9); opacity: 0; }
}

/* ---------- Scroll-reveal ----------
   Only gated behind html.js, so with JS off (or in a renderer where
   transitions never fire) every section renders in its visible state. */
.js .reveal{
  --d: calc(var(--i, 0) * 70ms);
  opacity: 0;
  transition:
    opacity var(--dur-reveal) var(--ease-out-expo) var(--d, 0ms),
    transform var(--dur-reveal) var(--ease-out-expo) var(--d, 0ms);
}

/* Each reveal fits what it reveals rather than one entrance applied to
   everything: the side panel slides in from its own edge, list items enter
   along the reading direction, cards rise, numbers settle.

   Every resting transform is scoped to :not(.is-visible) so the arrived
   state cannot be overridden by a later, equally specific variant rule. */
.js .reveal:not(.is-visible){ transform: translateY(26px); }
.js .method.reveal:not(.is-visible),
.js .team-card.reveal:not(.is-visible){ transform: translateX(24px); }
.js .checklist-items li.reveal:not(.is-visible){ transform: translateX(-16px); }
.js .guarantee.reveal:not(.is-visible){ transform: translateY(24px) scale(.985); }
.js .stat.reveal:not(.is-visible){ transform: translateY(14px); }
.js .cta-final .reveal:not(.is-visible){ transform: translateY(22px) scale(.99); }

.js .reveal.is-visible{ opacity: 1; transform: none; }

/* method steps tick in as a sequence — it is a numbered process, so the
   order is the content */
.js .method.is-visible .method-step{
  animation: stepIn .55s var(--ease-out-quint) both;
  animation-delay: calc(220ms + var(--i, 0) * 90ms);
}
@keyframes stepIn{
  from{ opacity: 0; transform: translateY(10px); }
  to  { opacity: 1; transform: none; }
}

/* ---------- Micro-interactions ---------- */
.alt-contact{ transition: transform var(--dur-fast) var(--ease-out-quart); }
@media (hover: hover){
  /* transform, not padding: hovering a row does no layout work */
  .alt-contact:hover{ transform: translateX(5px); }
}

@keyframes successIn{
  from{ opacity: 0; transform: translateY(-8px) scale(.985); }
  to  { opacity: 1; transform: none; }
}
@keyframes drawCheck{ to{ stroke-dashoffset: 0; } }
@keyframes headIn{
  from{ opacity: 0; transform: translateY(6px); }
  to  { opacity: 1; transform: none; }
}

@keyframes shake{
  10%,90%      { transform: translateX(-1px); }
  20%,80%      { transform: translateX(2px); }
  30%,50%,70%  { transform: translateX(-5px); }
  40%,60%      { transform: translateX(5px); }
}
.shake{ animation: shake .5s var(--ease-out-quart); }

/* ====================== 6. REDUCED MOTION ================================
   One authoritative block. Every automatic, looping and reveal animation
   resolves to its finished state; only instant colour feedback remains. */
@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; }

  *, *::before, *::after{
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* resolved end-state for the hero sequence */
  .hero-in{ animation: none; opacity: 1; transform: none; filter: none; }
  .chaos-dot, .chaos-line{ animation: none; opacity: .55; }
  .flow-path{ animation: none; stroke-dashoffset: 0; opacity: 1; }
  .flow-node{ animation: none; opacity: 1; transform: scale(1); }
  .flow-halo{ animation: none; opacity: 1; }
  .flow-signal, .pulse-ring{ animation: none; opacity: 0; }

  /* content is simply present; the reveal never runs */
  .js .reveal,
  .js .reveal:not(.is-visible),
  .js .reveal.is-visible{ opacity: 1; transform: none; }
  .js .method.is-visible .method-step{ animation: none; opacity: 1; transform: none; }
  .js .client-wall-clip:not(.is-visible) .client,
  .js .client-wall-clip.is-visible .client{ animation: none; opacity: 1; transform: none; }

  /* crossfade instead of movement */
  .form-success.show{ animation: none; }
  .form-error{ animation: none; }
  .btn[data-sending]::before{ animation: none; opacity: .45; border-top-color: currentColor; }
  .form-success.show .form-success-mark path{ animation: none; stroke-dashoffset: 0; }
  .modal-overlay.open .modal-head > *{ animation: none; opacity: 1; transform: none; }
  .modal{ filter: none; transform: none; }
  .mobile-menu{ transition: none; }
  .shake{ animation: none; }

  /* no hover displacement */
  .btn:hover, .btn:active,
  .service:hover, .guarantee:hover,
  .alt-contact:hover, .modal-close:hover{ transform: none; }
  .btn-primary:hover svg,
  .service:hover .stack-list li::before,
  .guarantee:hover svg{ transform: none; }
  .client:hover .client-logo{ scale: var(--logo-scale, 1); }
}
