
/* ============================================================
   V4 "COLORFIELD" — bold-through-color concept for /preview-home/
   Inspired by the calm, artwork-led enterprise look the client
   referenced. Zero kinetic effects: no marquees, no tilt, no veil.
   Motion limited to gentle reveals, soft hovers, one slow float.
   ============================================================ */
p, .section-lede, .hero-lede { text-wrap: pretty; }
h1, h2, h3 { text-wrap: balance; }
::selection { background: var(--accent-soft); color: var(--ink); }
[data-theme="dark"] ::selection { color: var(--fg); }

/* top brand bar */
body::before { content: ""; position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 60;
  background: linear-gradient(90deg, var(--accent), color-mix(in oklab, var(--brand-teal) 55%, var(--accent)) 55%, var(--accent-3)); }

/* header */
.site-header .header-row { max-width: 1380px; }
@media (min-width: 861px) { .primary-nav { gap: 46px; font-size: 14.5px; } }
/* header CTA joins the yellow-pill system */
.site-header .btn-primary { background: var(--accent-3); border-color: transparent;
  color: #2A2D34; font-weight: 600; border-radius: 999px; }
.site-header .btn-primary:hover { background: color-mix(in oklab, var(--accent-3) 87%, #1E222B);
  border-color: transparent; color: #2A2D34; }

/* yellow pill — the bold brand move (measured contrast 7.05:1 light / 8.27:1 dark) */
.btn-yellow { background: var(--accent-3); border-color: transparent; color: #2A2D34;
  font-weight: 600; border-radius: 999px;
  box-shadow: 0 10px 24px -10px color-mix(in oklab, var(--accent-3) 65%, transparent);
  transition: transform .2s cubic-bezier(.2,.7,.2,1), box-shadow .2s, background-color .2s; }
.btn-yellow:hover { background: color-mix(in oklab, var(--accent-3) 87%, #1E222B);
  border-color: transparent; color: #2A2D34; transform: translateY(-2px);
  box-shadow: 0 16px 32px -10px color-mix(in oklab, var(--accent-3) 70%, transparent); }

/* ---------- HERO ---------- */
.hero { position: relative; overflow: hidden; padding: 84px 0 64px;
  background:
    radial-gradient(60rem 36rem at 84% 16%, color-mix(in oklab, var(--accent) 9%, transparent), transparent 65%),
    radial-gradient(30rem 22rem at 68% 82%, color-mix(in oklab, var(--brand-teal) 7%, transparent), transparent 60%); }
[data-theme="dark"] .hero {
  background:
    radial-gradient(60rem 36rem at 84% 16%, color-mix(in oklab, var(--accent) 13%, transparent), transparent 65%),
    radial-gradient(30rem 22rem at 68% 82%, color-mix(in oklab, var(--brand-teal) 9%, transparent), transparent 60%); }

.hero-grid { display: grid; grid-template-columns: minmax(0, 1.16fr) minmax(0, .84fr);
  gap: 40px; align-items: center; }

/* heavy sans display headline, GD-style */
.hero-title { margin: 0 0 24px; max-width: 600px;
  font: 600 clamp(36px, 4.9vw, 58px)/1.08 var(--font-sans);
  letter-spacing: -.032em; color: var(--fg); }
.hero-title em { font-style: normal;
  background: linear-gradient(90deg, var(--accent), color-mix(in oklab, var(--brand-teal) 60%, var(--accent)));
  -webkit-background-clip: text; background-clip: text; color: transparent; }

.hero-lede { font-size: 18px; line-height: 1.6; max-width: 560px; color: var(--fg-2); margin-bottom: 32px; }

.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.hero-cta .btn { padding: 13px 24px; }
.hero-cta .btn-ghost { border-radius: 999px; border-color: var(--line-strong);
  transition: transform .2s, border-color .2s, background-color .2s; }
.hero-cta .btn-ghost:hover { background: var(--bg-2); border-color: var(--fg-3);
  transform: translateY(-2px); color: var(--fg); }

/* the artwork: transparent glass composition + shaped drop shadow + one slow float */
.hero-art { position: relative; }
.hero-art img { display: block; width: 112%; max-width: none; margin-left: -6%; height: auto;
  filter: drop-shadow(0 34px 44px color-mix(in oklab, var(--accent) 26%, transparent));
  animation: floaty 9s ease-in-out infinite alternate; }
@keyframes floaty { from { transform: translateY(-6px); } to { transform: translateY(8px); } }

/* stats with colour ticks */
.hero-stats { list-style: none; margin: 40px 0 0; padding: 24px 0 0;
  border-top: 1px solid var(--line);
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px 28px; }
.hero-stats li { font: 500 12.5px/1.5 var(--font-mono); letter-spacing: .03em; color: var(--fg-3); }
.hero-stats li::before { content: ""; display: block; width: 34px; height: 3px;
  border-radius: 2px; margin-bottom: 13px; }
.hero-stats strong { display: block; font: 500 clamp(28px, 3vw, 38px)/1.1 var(--font-serif);
  letter-spacing: -.015em; color: var(--fg); margin-bottom: 4px; white-space: nowrap; }
.st-blue::before { background: var(--accent); }
.st-teal::before { background: color-mix(in oklab, var(--brand-teal) 68%, var(--accent)); }
.st-green::before { background: var(--accent-2); }
.st-yellow::before { background: var(--accent-3); }
.hero-stats li:last-child { align-self: end; }
@media (max-width: 820px) { .hero-stats { grid-template-columns: 1fr 1fr; } }

/* roles — one calm editorial line */
.hero-roles { display: flex; gap: 20px; align-items: baseline; margin-top: 30px;
  padding: 18px 0 2px; border-top: 1px solid var(--line); }
.hero-roles-label { flex: 0 0 auto; font: 600 11px/1 var(--font-mono);
  letter-spacing: .16em; text-transform: uppercase; color: var(--fg-3); }
.role-line { list-style: none; margin: 0; padding: 0; display: block; line-height: 30px; }
.role-line li { display: inline; white-space: nowrap; }
.role-line li:not(:last-child)::after { content: "· "; margin-inline-start: .5em;
  font: 500 10px/1 var(--font-mono); color: color-mix(in oklab, var(--accent) 55%, var(--fg-3)); }
.role-line .r1 { font: 500 17px var(--font-serif); letter-spacing: -.01em; color: var(--fg); }
.role-line .r2 { font: 500 14px var(--font-sans); color: var(--fg-2); }
.role-line .r3 { font: 500 10.5px var(--font-mono); letter-spacing: .07em; text-transform: uppercase; color: color-mix(in oklab, var(--fg-2) 80%, var(--fg-3)); }
@media (max-width: 700px) { .hero-roles { flex-direction: column; gap: 10px; }
  .role-line { line-height: 27px; } }

/* trusted logos — approved sizes */
.logo-marquee { height: 150px; }
.logo-marquee-track img { height: 84px; opacity: .82; }
.logo-marquee-track img:hover { opacity: 1; }
@media (max-width: 640px) { .logo-marquee { height: 104px; }
  .logo-marquee-track img { height: 58px; } }

/* ---------- WHY NGRS: image-led colour cards ---------- */
#why-ngrs .results-grid { gap: 18px; align-items: stretch; }
#why-ngrs .result-card { position: relative; display: block; padding: 24px 26px 26px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 16px;
  border-top: 4px solid var(--accent);
  box-shadow: 0 1px 2px color-mix(in oklab, var(--ink) 5%, transparent);
  transition: transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s, border-color .3s; }
#why-ngrs .result-card:hover { transform: translateY(-4px);
  box-shadow: 0 22px 44px -18px color-mix(in oklab, var(--ink) 24%, transparent); }
#why-ngrs .result-card.tint-blue { border-top-color: var(--accent); }
#why-ngrs .result-card.tint-teal { border-top-color: color-mix(in oklab, var(--brand-teal) 68%, var(--accent)); }
#why-ngrs .result-card.tint-green { border-top-color: var(--accent-2); }
#why-ngrs .result-card.tint-blue:hover { border-color: color-mix(in oklab, var(--accent) 40%, var(--line)); }
#why-ngrs .result-card.tint-teal:hover { border-color: color-mix(in oklab, var(--brand-teal) 45%, var(--line)); }
#why-ngrs .result-card.tint-green:hover { border-color: color-mix(in oklab, var(--accent-2) 45%, var(--line)); }
.card-ico { height: 108px; display: flex; align-items: center; justify-content: center; margin-bottom: 16px; }
.card-ico img { height: 108px; width: auto;
  filter: drop-shadow(0 14px 18px color-mix(in oklab, var(--accent) 22%, transparent));
  transition: transform .35s cubic-bezier(.2,.7,.2,1); }
#why-ngrs .result-card:hover .card-ico img { transform: scale(1.05); }
#why-ngrs .result-card .num { font: 600 12px/1 var(--font-mono); letter-spacing: .12em;
  display: block; margin-bottom: 12px; }
.tint-blue .num { color: var(--accent); }
.tint-teal .num { color: color-mix(in oklab, var(--brand-teal) 62%, var(--accent)); }
.tint-green .num { color: color-mix(in oklab, var(--accent-2) 82%, var(--fg-3)); }
[data-theme="dark"] .tint-green .num { color: var(--accent-2); }
.why-card-title { margin: 0 0 10px; font: 500 21px/1.3 var(--font-serif);
  letter-spacing: -.01em; color: var(--fg); text-wrap: balance; }
#why-ngrs .result-card p { margin: 0; font-size: 15px; line-height: 1.65; color: var(--fg-2); }

/* ---------- RESULTS: tinted case cards ---------- */
#results .result-card { position: relative; padding: 30px 30px; gap: 12px;
  border-radius: 16px; overflow: hidden;
  transition: transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s, border-color .3s; }
#results .result-card:hover { transform: translateY(-4px);
  box-shadow: 0 22px 44px -18px color-mix(in oklab, var(--ink) 22%, transparent); }
#results .case-blue { background: color-mix(in oklab, var(--accent) 7%, var(--bg-2));
  border-color: color-mix(in oklab, var(--accent) 26%, var(--line)); }
#results .case-teal { background: color-mix(in oklab, var(--brand-teal) 9%, var(--bg-2));
  border-color: color-mix(in oklab, var(--brand-teal) 30%, var(--line)); }
#results .result-card-figure { font-size: clamp(40px, 4vw, 54px); }
#results .result-card-figure::after { content: ""; display: block; width: 46px; height: 4px;
  border-radius: 2px; margin-top: 12px;
  background: linear-gradient(90deg, var(--accent), color-mix(in oklab, var(--brand-teal) 60%, var(--accent))); }
#results .result-card p { font-size: 14.5px; }

/* founder quote — soft sage panel */
.quote { background: color-mix(in oklab, var(--accent-2) 8%, var(--bg-2));
  border-color: color-mix(in oklab, var(--accent-2) 26%, var(--line));
  border-left: 3px solid var(--accent-2); }
.quote .quote-mark { position: absolute; }

/* ---------- DIAGNOSTIC: saturated gradient band ---------- */
.diag-band { display: flex; align-items: center; justify-content: space-between;
  gap: 24px 32px; flex-wrap: wrap; padding: 30px 34px; border-radius: 18px;
  background: linear-gradient(120deg, color-mix(in oklab, var(--accent) 55%, #152231), color-mix(in oklab, var(--brand-teal) 45%, #12262E));
  box-shadow: 0 20px 42px -18px color-mix(in oklab, var(--accent) 55%, transparent); }
[data-theme="dark"] .diag-band {
  background: linear-gradient(120deg, color-mix(in oklab, var(--accent) 50%, #121C29), color-mix(in oklab, var(--brand-teal) 40%, #10222A)); }
.diag-title { margin: 0 0 6px; font: 500 22px/1.3 var(--font-serif);
  letter-spacing: -.01em; color: #FFFFFF; }
.diag-body { margin: 0; font-size: 14.5px; color: rgba(255, 255, 255, .86); max-width: 620px; }

/* ---------- CTA: dark panel with artwork echo ---------- */
.cta-band { position: relative; overflow: hidden; border-top: 0;
  background: linear-gradient(140deg, #17212F, #10161F 70%); }
.cta-band::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(34rem 22rem at 12% 20%, color-mix(in oklab, var(--accent) 22%, transparent), transparent 65%),
    radial-gradient(26rem 20rem at 88% 88%, color-mix(in oklab, var(--brand-teal) 18%, transparent), transparent 62%); }
.cta-art { position: absolute; right: -70px; top: 50%; transform: translateY(-50%) rotate(-6deg);
  width: 540px; pointer-events: none; opacity: .34;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 32%); mask-image: linear-gradient(90deg, transparent, #000 32%); }
.cta-art img { width: 100%; height: auto; display: block; }
.cta-band-inner { position: relative; z-index: 1; }
.cta-title { color: #F4F6FA; font-size: clamp(28px, 3.6vw, 42px); }
.cta-copy p { color: rgba(244, 246, 250, .74); }
.cta-band .btn-lg { padding: 15px 26px; }
@media (max-width: 900px) { .cta-art { opacity: .2; width: 420px; right: -120px; } }

/* ---------- footer ---------- */
.footer-top { align-items: start; }
.footer-cols { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 40px; }
.footer-col h3 { margin: 0 0 14px; font: 500 12px/1 var(--font-mono); letter-spacing: .08em;
  text-transform: uppercase; color: var(--fg-3); padding-bottom: 10px; border-bottom: 1px solid var(--line); }
.footer-col li { line-height: 2; }

/* ---------- scroll reveal ---------- */
.rv { opacity: 0; transform: translateY(14px);
  transition: opacity .6s ease, transform .6s cubic-bezier(.2,.7,.2,1); }
.rv.in { opacity: 1; transform: none; }

/* ---------- responsive ---------- */
@media (max-width: 900px) {
  .hero { padding: 64px 0 52px; }
  .hero-grid { grid-template-columns: 1fr; gap: 36px; }
  .hero-art { max-width: 460px; }
}
@media (max-width: 820px) {
  #why-ngrs .results-grid { grid-template-columns: 1fr !important; gap: 16px; }
  .card-ico { height: 92px; } .card-ico img { height: 92px; }
  .footer-cols { grid-template-columns: 1fr 1fr; gap: 28px; }
}
@media (max-width: 560px) {
  .diag-band { padding: 24px 22px; }
  #results .result-card-figure { font-size: 40px; }
}
@media (max-width: 520px) { .footer-cols { grid-template-columns: 1fr; } }

/* ---------- reduced motion: keep only the fade ---------- */
@media (prefers-reduced-motion: reduce) {
  .hero-art img { animation: none; }
  .rv { opacity: 1; transform: none; transition: none; }
  #why-ngrs .result-card, #results .result-card, .btn-yellow,
  .hero-cta .btn-ghost, .card-ico img { transition: none; }
  #why-ngrs .result-card:hover, #results .result-card:hover,
  .btn-yellow:hover, .hero-cta .btn-ghost:hover { transform: none; }
  #why-ngrs .result-card:hover .card-ico img { transform: none; }
}

/* ---------- forced colors ---------- */
@media (forced-colors: active) {
  #why-ngrs .result-card, #results .result-card, .quote, .diag-band { border: 1px solid CanvasText; }
  .hero-title em { color: Highlight; background: none; }
  .diag-band { background: Canvas; }
  .diag-title, .diag-body { color: CanvasText; }
  .cta-art { display: none; }
}


/* ============================================================
   V4.1 FINAL — "waves-quiet" refinement layer (page-scoped)
   Page: /preview-home/v4/
   File: work/ngrs_migration/ngrs_root/preview-home/v4/index.html

   WHERE TO PASTE: inside the page's existing <style>, immediately
   BEFORE the comment "Наталья 29.07: ..." (currently line 265, right
   after the closing "}" of @media (forced-colors: active) on line 262).
   Reason: the client's approved mobile first screen must keep the last
   word. Section 15 at the end of this layer restates those values, so
   the approved first screen survives even a misplaced paste.

   Six jobs, straight from the brief:
   (1) space  (2) quiet wave lines as one background fabric
   (3) two type families only  (4) colour fades towards the footer
   (5) nothing below 13px  (6) nothing runs, crawls or scrolls by itself
   Does not touch /styles/ngrs.css?v=20260730b. No external requests.
   ============================================================ */

/* ---------- tokens ---------- */
:root {
  --container: 1120px;                 /* wider measure = more air; header rail and body now align */

  /* Wave sizes live in custom properties so the phone breakpoint can
     shrink them once, for both themes, without fighting
     [data-theme="dark"] .hero on specificity. Aspect ratios preserved. */
  --nv-field-size: 1440px 720px;       /* tile 1200x600 x1.2 */
  --nv-sweep-size: 1440px 520px;       /* sweep 1440x520 x1   */

  /* Background wave art. A data-URI SVG cannot read CSS custom
     properties, so the stroke hard-codes the *resolved* value of
     --accent per theme (light #4A86B5 / dark #6FA5D0) and bakes the
     alpha into stroke-opacity.
     --nv-wave-field: seamless tile (C1-continuous on all four edges).
     --nv-wave-sweep: one long fan, used at the top, echoed at the bottom. */
  --nv-wave-field: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='1200' height='600' viewBox='0 0 1200 600'><g fill='none' stroke='%234A86B5' stroke-opacity='.10' stroke-width='1.2'><path d='M0,90C200,52,400,128,600,90C800,52,1000,128,1200,90'/><path d='M0,240C200,202,400,278,600,240C800,202,1000,278,1200,240'/><path d='M0,390C200,352,400,428,600,390C800,352,1000,428,1200,390'/><path d='M0,540C200,502,400,578,600,540C800,502,1000,578,1200,540'/></g></svg>");
  --nv-wave-sweep: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='1440' height='520' viewBox='0 0 1440 520'><g fill='none' stroke='%234A86B5' stroke-opacity='.15' stroke-width='1.3'><path d='M-40,300C240,300,480,204,760,150C1020,100,1240,94,1480,104'/><path d='M-40,346C240,346,480,250,760,196C1020,146,1240,140,1480,150'/><path d='M-40,392C240,392,480,296,760,242C1020,192,1240,186,1480,196'/><path d='M-40,438C240,438,480,342,760,288C1020,238,1240,232,1480,242'/></g></svg>");
}
[data-theme="dark"] {
  --nv-wave-field: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='1200' height='600' viewBox='0 0 1200 600'><g fill='none' stroke='%236FA5D0' stroke-opacity='.16' stroke-width='1.2'><path d='M0,90C200,52,400,128,600,90C800,52,1000,128,1200,90'/><path d='M0,240C200,202,400,278,600,240C800,202,1000,278,1200,240'/><path d='M0,390C200,352,400,428,600,390C800,352,1000,428,1200,390'/><path d='M0,540C200,502,400,578,600,540C800,502,1000,578,1200,540'/></g></svg>");
  --nv-wave-sweep: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='1440' height='520' viewBox='0 0 1440 520'><g fill='none' stroke='%236FA5D0' stroke-opacity='.22' stroke-width='1.3'><path d='M-40,300C240,300,480,204,760,150C1020,100,1240,94,1480,104'/><path d='M-40,346C240,346,480,250,760,196C1020,146,1240,140,1480,150'/><path d='M-40,392C240,392,480,296,760,242C1020,192,1240,186,1480,196'/><path d='M-40,438C240,438,480,342,760,288C1020,238,1240,232,1480,242'/></g></svg>");
}

/* ---------- 1. the wave field: one fabric behind the whole page ----------
   body::before (the brand bar) is untouched; the field lives on ::after.
   body has no stacking context of its own, so z-index:-1 puts the field
   above the canvas background and below every block: cards and text
   always sit on solid ground. */
body { position: relative; }
body::after {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-image: var(--nv-wave-field);
  background-repeat: repeat;
  background-size: var(--nv-field-size);
  /* present under the upper half, gone before the footer — colour and
     texture both thin out towards the bottom of the page */
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 14%, #000 56%, transparent 86%);
          mask-image: linear-gradient(180deg, transparent 0, #000 14%, #000 56%, transparent 86%);
}
body::before { height: 2px; }          /* brand bar: keep the colour, lose the weight */

/* ---------- 2. header: align the header rail with the content measure ---------- */
.site-header .header-row { max-width: var(--container); }
@media (min-width: 861px) { .primary-nav { gap: 40px; font-size: 14.5px; } }

/* ---------- 3. hero: serif headline, one mono kicker, more air ---------- */
.hero {
  padding: clamp(56px, 6vw, 92px) 0 clamp(64px, 7vw, 96px);
  background:
    var(--nv-wave-sweep) 50% 100% / var(--nv-sweep-size) no-repeat,
    radial-gradient(60rem 36rem at 84% 16%, color-mix(in oklab, var(--accent) 8%, transparent), transparent 65%),
    radial-gradient(30rem 22rem at 68% 82%, color-mix(in oklab, var(--brand-teal) 6%, transparent), transparent 60%);
}
[data-theme="dark"] .hero {
  background:
    var(--nv-wave-sweep) 50% 100% / var(--nv-sweep-size) no-repeat,
    radial-gradient(60rem 36rem at 84% 16%, color-mix(in oklab, var(--accent) 12%, transparent), transparent 65%),
    radial-gradient(30rem 22rem at 68% 82%, color-mix(in oklab, var(--brand-teal) 8%, transparent), transparent 60%);
}
.hero-grid { gap: clamp(36px, 5vw, 64px); }

/* the single permitted mono element on the page */
.eyebrow { font: 500 13px/1 var(--font-mono); letter-spacing: .06em; color: var(--fg-2); margin-bottom: 26px; }

/* h1 joins the serif family used by every other heading */
.hero-title {
  margin: 0 0 24px; max-width: 620px;
  font: 500 clamp(32px, 4vw, 50px)/1.16 var(--font-serif);
  letter-spacing: -.02em; color: var(--fg);
}
/* the gradient text-clip repeated its sweep on every wrapped line; one
   solid tone reads cleaner. Darkened on paper (3.7:1 -> 4.45:1 measured),
   left at full --accent on dark where it already measures 6.7:1. */
.hero-title em { font-style: normal; font-weight: 400;
  color: color-mix(in oklab, var(--accent) 86%, var(--ink));
  background: none; -webkit-background-clip: border-box; background-clip: border-box; }
[data-theme="dark"] .hero-title em { color: var(--accent); }

.hero-cta { gap: 14px; margin-bottom: 0; }
.hero-cta .btn { padding: 14px 26px; }

/* softer artwork: smaller float, quieter shadow */
.hero-art img {
  animation-duration: 14s;
  filter: drop-shadow(0 26px 38px color-mix(in oklab, var(--accent) 18%, transparent));
}
@keyframes floaty { from { transform: translateY(-3px); } to { transform: translateY(4px); } }

/* stats */
.hero-stats { margin: clamp(44px, 5vw, 64px) 0 0; padding-top: 30px; gap: 24px 32px; }
.hero-stats li { font: 500 13.5px/1.55 var(--font-sans); letter-spacing: 0; color: var(--fg-2); }
.hero-stats li::before { width: 30px; height: 2px; margin-bottom: 14px; }
.hero-stats strong { font: 500 clamp(27px, 2.8vw, 36px)/1.12 var(--font-serif);
  letter-spacing: -.015em; margin-bottom: 6px; }

/* WE HIRE line — three tiers, one family */
.hero-roles { margin-top: clamp(30px, 3.4vw, 44px); padding: 26px 0 2px; gap: 24px; }
.hero-roles-label { font: 600 13px/1.4 var(--font-sans); letter-spacing: .1em;
  text-transform: uppercase; color: var(--fg-2); }
.role-line { line-height: 32px; }
.role-line .r1 { font: 500 17px/1 var(--font-sans); letter-spacing: -.005em; color: var(--fg); }
.role-line .r2 { font: 400 15px/1 var(--font-sans); letter-spacing: 0; color: var(--fg-2); }
.role-line .r3 { font: 400 13.5px/1 var(--font-sans); letter-spacing: .045em;
  text-transform: uppercase; color: var(--fg-2); }
.role-line li:not(:last-child)::after { content: "·"; margin-inline-start: .55em;
  font: 400 13px/1 var(--font-sans); color: color-mix(in oklab, var(--accent) 50%, var(--fg-4)); }

/* ---------- 4. trusted: the running strip becomes a still logo wall ----------
   «стильный сайт, но всё бегущее бесит» — so nothing moves here any more.
   CSS only: the 18 aria-hidden duplicate logos (they existed solely to
   feed the scroll loop) are dropped, the track wraps, the edge-fade mask
   is removed because there is no longer an edge to hide. */
.trusted { padding: clamp(28px, 3vw, 44px) 0 clamp(60px, 7vw, 96px); }
.logo-marquee {
  height: auto; overflow: visible; margin-top: 26px;
  padding: clamp(26px, 3vw, 38px) 0;
  -webkit-mask-image: none; mask-image: none;
}
.logo-marquee-track {
  width: auto; flex-wrap: wrap; justify-content: center;
  gap: clamp(24px, 3vw, 36px) clamp(30px, 4vw, 56px);
  animation: none;
}
.logo-marquee-track img[aria-hidden="true"] { display: none; }
/* max-height + max-width (never a fixed height) keeps every aspect ratio
   intact and makes overflow impossible at any width */
.logo-marquee-track img {
  height: auto; width: auto;
  max-height: 54px; max-width: min(150px, 40%);
  opacity: .72;
}

/* label + eyebrow share one quiet form: hairline, 13px Inter, wide tracking */
.section-label, .section-eyebrow {
  display: flex; align-items: center; gap: 12px;
  font: 500 13px/1.4 var(--font-sans); letter-spacing: .1em; color: var(--fg-2);
}
.section-label::before, .section-eyebrow::before {
  content: ""; flex: 0 0 26px; width: 26px; height: 1px;
  background: color-mix(in oklab, var(--accent) 55%, transparent);
}
.section-label { margin-bottom: 20px; }
.section-eyebrow { margin-bottom: 18px; }

/* ---------- 5. vertical rhythm ---------- */
.section { padding: clamp(76px, 8vw, 132px) 0; border-top: 0; }
.section-head { margin-bottom: clamp(40px, 4.6vw, 68px); max-width: 780px; }
.section-title { margin: 0 0 18px; font-size: clamp(27px, 3.1vw, 38px); line-height: 1.18; }
.section-lede { font-size: 17px; line-height: 1.72; max-width: 680px; }

/* ---------- 6. why NGRS cards ---------- */
#why-ngrs .results-grid { gap: 22px; margin-bottom: 0; }
#why-ngrs .result-card { padding: 28px 30px 32px; border-radius: 18px;
  border-top-width: 3px; box-shadow: none; }
#why-ngrs .result-card:hover { transform: translateY(-3px);
  box-shadow: 0 18px 40px -22px color-mix(in oklab, var(--ink) 22%, transparent); }
.card-ico { height: 96px; margin-bottom: 18px; }
.card-ico img { height: 96px;
  filter: drop-shadow(0 12px 16px color-mix(in oklab, var(--accent) 16%, transparent)); }
/* font only — no colour here, so the .tint-* rules below still decide the hue */
#why-ngrs .result-card .num { font: 600 13px/1 var(--font-sans); letter-spacing: .1em;
  margin-bottom: 14px; }
/* 01/02/03 measured 3.9 / 3.0 / 2.7:1 on paper — too pale for a 13px label.
   Darkened towards --ink: now 5.72 / 5.72 / 5.76:1, hue unchanged.
   Dark theme measures 6.19 / 8.14 / 8.58:1 and keeps its brighter tints. */
.tint-blue  .num { color: color-mix(in oklab, var(--accent) 70%, var(--ink)); }
.tint-teal  .num { color: color-mix(in oklab, var(--brand-teal) 52%, var(--ink)); }
.tint-green .num { color: color-mix(in oklab, var(--accent-2) 50%, var(--ink)); }
[data-theme="dark"] .tint-blue  .num { color: var(--accent); }
[data-theme="dark"] .tint-teal  .num { color: color-mix(in oklab, var(--brand-teal) 70%, var(--fg)); }
[data-theme="dark"] .tint-green .num { color: var(--accent-2); }
.why-card-title { margin: 0 0 12px; font: 500 20.5px/1.34 var(--font-serif); letter-spacing: -.01em; }
#why-ngrs .result-card p { font-size: 15px; line-height: 1.68; }

/* ---------- 7. cases + quote: colour starts stepping down ---------- */
#results .results-grid { gap: 20px; margin-bottom: clamp(28px, 3vw, 40px); }
#results .result-card { padding: 32px; border-radius: 18px; }
#results .case-blue { background: color-mix(in oklab, var(--accent) 5%, var(--bg-2));
  border-color: color-mix(in oklab, var(--accent) 20%, var(--line)); }
#results .case-teal { background: color-mix(in oklab, var(--brand-teal) 6%, var(--bg-2));
  border-color: color-mix(in oklab, var(--brand-teal) 22%, var(--line)); }
#results .result-card:hover { transform: translateY(-3px);
  box-shadow: 0 18px 40px -22px color-mix(in oklab, var(--ink) 20%, transparent); }
#results .result-card-tag { font: 500 13px/1.4 var(--font-sans); letter-spacing: .08em; color: var(--fg-2); }
#results .result-card-figure { font-size: clamp(34px, 3.4vw, 46px); line-height: 1.12; }
/* --fg-3 measured 4.0:1 on the tinted card — under the 4.5:1 floor for 14.5px */
#results .result-card-figure span { font-size: 14.5px; line-height: 1.5; margin-top: 8px; color: var(--fg-2); }
#results .result-card-figure::after { width: 40px; height: 3px; margin-top: 14px; }
#results .result-card p { font-size: 14.5px; line-height: 1.65; }
/* inline style="font-size:12px;color:var(--fg-3)" — only !important can reach it */
#results p.mono { font-family: var(--font-sans); letter-spacing: 0;
  font-size: 13px !important; color: var(--fg-2) !important; }
/* the cases grid carries an inline max-width:980px; the note and the quote
   are pulled to the same measure so the column edge stays straight at 1440 */
#results p.mono, #results .quote { max-width: 980px; }

.quote { margin-top: clamp(36px, 4vw, 56px); padding: 40px 40px 36px; border-radius: 18px;
  background: color-mix(in oklab, var(--accent-2) 5%, var(--bg-2));
  border: 1px solid color-mix(in oklab, var(--accent-2) 20%, var(--line));
  /* stated as a longhand so the sage rule survives the border-color above */
  border-left: 2px solid color-mix(in oklab, var(--accent-2) 55%, var(--line)); }
.quote blockquote { margin: 0 0 22px; font: 500 20px/1.5 var(--font-serif); max-width: 700px; }
.quote figcaption { font-size: 13.5px; color: var(--fg-2); }
.quote-mark { top: 30px; right: 34px; }

/* ---------- 8. diagnostic: the saturated band becomes a quiet panel ----------
   "низ перебор с цветами" — the gradient goes, the yellow pill stays as the
   one piece of colour that still has a job down here. */
.diag-band {
  gap: 24px 40px; padding: clamp(28px, 3.4vw, 40px) clamp(26px, 3vw, 40px);
  border-radius: 18px;
  background: color-mix(in oklab, var(--accent) 4%, var(--bg-2));
  border: 1px solid color-mix(in oklab, var(--accent) 18%, var(--line));
  box-shadow: none;
}
[data-theme="dark"] .diag-band {
  background: color-mix(in oklab, var(--accent) 8%, var(--bg-2));
  border-color: color-mix(in oklab, var(--accent) 24%, var(--line));
}
.diag-title { margin: 0 0 8px; font: 500 21px/1.35 var(--font-serif);
  letter-spacing: -.01em; color: var(--fg); }
.diag-body { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--fg-2); max-width: 620px; }

/* ---------- 9. CTA: paper instead of a dark colour block ---------- */
.cta-band {
  padding: clamp(84px, 9vw, 132px) 0;
  border-top: 1px solid var(--line);
  background: linear-gradient(180deg, color-mix(in oklab, var(--accent) 3%, var(--bg-2)), var(--bg));
}
.cta-band::before {            /* was two coloured radials — now the wave echo */
  background: var(--nv-wave-sweep) 50% 100% / var(--nv-sweep-size) no-repeat;
  opacity: .7;
}
.cta-band-inner { gap: clamp(32px, 4vw, 56px); }
.cta-copy { max-width: 620px; }
.cta-title { margin: 0 0 14px; font: 500 clamp(28px, 3.4vw, 40px)/1.18 var(--font-serif);
  letter-spacing: -.018em; color: var(--fg); }
.cta-copy p { margin: 0; font-size: 16px; line-height: 1.7; color: var(--fg-2); }
.cta-band .btn-lg { padding: 16px 28px; font-size: 15px; }
.cta-art { width: 500px; right: -80px; opacity: .10; }
[data-theme="dark"] .cta-art { opacity: .16; }

/* ---------- 10. yellow pill: same colour, softer glow ---------- */
.btn-yellow { box-shadow: 0 8px 20px -12px color-mix(in oklab, var(--accent-3) 55%, transparent); }
.btn-yellow:hover { transform: translateY(-1px);
  box-shadow: 0 12px 26px -12px color-mix(in oklab, var(--accent-3) 60%, transparent); }

/* ---------- 11. footer: no mono, more air, nothing under 13px ---------- */
.site-footer { padding: clamp(64px, 7vw, 96px) 0 40px; }
.footer-top { gap: clamp(36px, 5vw, 64px); padding-bottom: clamp(40px, 5vw, 64px); }
.footer-cols { gap: 40px 48px; }
.footer-col h3 { margin: 0 0 16px; padding-bottom: 12px;
  font: 500 13px/1.4 var(--font-sans); letter-spacing: .1em; color: var(--fg-2); }
.footer-col li { line-height: 2.05; }
.footer-col a { font-size: 14.5px; }
.footer-tagline { font-size: 14.5px; line-height: 1.7; max-width: 340px; color: var(--fg-2); }
.footer-bottom { padding-top: 30px; font: 400 13px/1.6 var(--font-sans);
  letter-spacing: 0; color: var(--fg-2); }
.footer-bottom a { color: var(--fg-2); border-bottom: 1px solid var(--line); }
.footer-bottom a:hover { color: var(--accent); }

/* the NORA chat widget injects its own <style> from /js/ai-chat.js?v=20260730b AFTER
   this block at equal specificity, and its subtitle is 12px — !important
   is the only way to reach the 13px floor without editing that shared script */
#nch-head span { font-size: 13px !important; }

/* ---------- 12. breakpoints ---------- */
@media (max-width: 900px) {
  .cta-art { width: 400px; right: -110px; opacity: .09; }
}
@media (max-width: 820px) {
  .hero-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }  /* minmax(0,…) so nowrap figures can never widen a track */
  /* ngrs.css caps this grid at 440px !important from 820px down. On a phone the
     container is narrower anyway, but at 768 it left the cards 440px wide while
     the note and the quote below ran to 725px. Only !important reaches it. */
  #results .results-grid { max-width: none !important; }
  #why-ngrs .results-grid { gap: 16px; }
  #why-ngrs .result-card { padding: 26px 24px 28px; }
  .card-ico, .card-ico img { height: 92px; }
  #results .result-card { padding: 28px 26px; }
  .quote { padding: 32px 28px 28px; }
  .footer-cols { gap: 28px 32px; }
}
@media (max-width: 640px) {
  /* denser waves read better on a phone; one place, both themes, ratio kept */
  :root { --nv-field-size: 900px 450px; --nv-sweep-size: 900px 325px; }
  .logo-marquee { padding: 22px 0; }
  .logo-marquee-track { gap: 20px 24px; }
  .logo-marquee-track img { max-height: 34px; max-width: min(104px, 30%); }
  .quote blockquote { font-size: 18.5px; line-height: 1.5; }
  .cta-title { font-size: 27px; }
  .diag-title { font-size: 19.5px; }
}

/* ---------- 13. reduced motion: nothing moves ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hero-art img { animation: none; }
  .rv { opacity: 1; transform: none; transition: none; }
  .btn-yellow, .hero-cta .btn-ghost, #why-ngrs .result-card, #results .result-card,
  .card-ico img { transition: none; }
  .btn-yellow:hover, .hero-cta .btn-ghost:hover,
  #why-ngrs .result-card:hover, #results .result-card:hover { transform: none; }
  #why-ngrs .result-card:hover .card-ico img { transform: none; }
}

/* ---------- 14. forced colours ----------
   This layer sits after the page's own forced-colors block, so every value
   that block neutralised has to be restated here or the later plain rules
   would win inside forced-colors mode. background-image is never forced by
   the UA, hence the explicit "background: Canvas" on painted sections. */
@media (forced-colors: active) {
  body::after, .cta-band::before, .cta-art { display: none; }
  .hero { background: Canvas; }
  .cta-band { background: Canvas; border-top: 1px solid CanvasText; }
  .cta-title, .cta-copy p { color: CanvasText; }
  .diag-band { background: Canvas; border: 1px solid CanvasText; }
  .diag-title, .diag-body { color: CanvasText; }
  .hero-title em { color: Highlight; }
  #why-ngrs .result-card, #results .result-card, .quote {
    background: Canvas; border: 1px solid CanvasText; }
  .tint-blue .num, .tint-teal .num, .tint-green .num,
  [data-theme="dark"] .tint-blue .num, [data-theme="dark"] .tint-teal .num,
  [data-theme="dark"] .tint-green .num { color: CanvasText; }
  #results .result-card-figure span, #results .result-card-tag,
  .quote figcaption, .footer-tagline, .footer-bottom, .footer-bottom a,
  .hero-stats li, .role-line .r2, .role-line .r3 { color: CanvasText; }
  .section-label::before, .section-eyebrow::before,
  .hero-stats li::before, #results .result-card-figure::after { background: CanvasText; }
}

/* ---------- 15. phone: mirror of the client-approved first screen ----------
   Values copied verbatim from the "Наталья 29.07" block so the approved
   mobile hero wins no matter where this layer is pasted. Do not edit. */
@media (max-width: 560px) {
  .hero { padding-top: 18px; padding-bottom: 10px; }
  .hero-title { font-size: 30px; line-height: 1.1; margin: 0 0 14px; letter-spacing: -.026em; }
  .hero-lede { font-size: 14.5px; line-height: 1.5; margin-bottom: 16px; }
  .hero-cta { margin-bottom: 16px; gap: 10px; }
  .hero-cta .btn { padding: 11px 18px; font-size: 14.5px; }
  .hero-art, .hero-visual { display: none; }
  /* new, phone-only tightening for the blocks below the fold */
  .eyebrow { margin-bottom: 16px; }
  .hero-stats { margin-top: 24px; padding-top: 20px; gap: 18px 20px; }
  .hero-stats strong { font-size: 25px; }   /* keeps "2–4 weeks" on one line at 375 */
  .hero-roles { margin-top: 22px; padding-top: 18px; gap: 12px; }
  .role-line { line-height: 29px; }
}
  /* Наталья 29.07: «на компе сразу на первой странице we hire, с телефона это не так —
     может текст сделать меньше и вместить в одно окно?». Ужимаем первый экран на
     телефоне так, чтобы заголовок, кнопки и начало блока WE HIRE попадали в один экран. */
  @media (max-width: 560px) {
    .hero { padding-top: 18px; padding-bottom: 10px; }
    .hero-title { font-size: 30px; line-height: 1.1; margin: 0 0 14px; letter-spacing: -.026em; }
    .hero-lede { font-size: 14.5px; line-height: 1.5; margin-bottom: 16px; }
    .hero-cta { margin-bottom: 16px; gap: 10px; }
    .hero-cta .btn { padding: 11px 18px; font-size: 14.5px; }
    .hero-art, .hero-visual { display: none; }          /* кубики уводим со первого экрана */
    .hero-panel, .role-block { margin-top: 4px; }
    .hero-panel .hp-head { margin-bottom: 8px; }
    .hero-panel .role-cloud .rc-lg { font-size: 17px; padding: 6px 0; }
    .hero-facts { margin-top: 12px; gap: 10px 16px; }
  }
/* ============================================================
   V4.2 — FINAL PASS, four blocks, one system
   Page: /preview-home/v4/
   File: work/ngrs_migration/ngrs_root/preview-home/v4/index.html

   WHERE TO PASTE — ONE block, ONE place: at the very END of the
   page's style element, after section 15's closing "}" and
   immediately before the closing style tag. (No literal style tag is
   written anywhere in this file: an HTML parser terminates a style
   element on the first closing-tag string it sees, even inside a CSS
   comment, which silently truncates everything after it.)
   This whole file is section 16; the four blocks
   below are 16.1 … 16.4 and there is no other paste instruction.

   Source order is load-bearing in exactly four places, all of
   which are satisfied by pasting last:
     · .quote .quote-mark{position:static}  ties line 186 (0,2,0)
     · .hero-stats li:last-child{align-self:stretch} ties line 111
     · .hero-roles .role-line li::after{content:none} ties line 389
     · the forced-colors restatements at the bottom tie section 14
   Nothing here sets .hero-roles margin-top / padding-top / gap,
   .hero-stats margin-top / padding-top / gap, or any .hero-title /
   .hero-lede / .hero-cta / .hero-art value, so section 15 (the
   client-approved phone first screen) keeps the last word.

   ------------------------------------------------------------
   THE THREE RULES THAT MAKE THE FOUR BLOCKS ONE PAGE
   (the previous pass failed cross-block coherence; these are the
    decisions that were missing, applied identically everywhere)

   1. RULE WEIGHT AND AXIS — one owner per axis.
      HORIZONTAL 2px full-width rule  = a column head. Owned by the
      stat row, and by nothing else on this page. It is NEUTRAL
      (var(--fg-4)): the client has said twice there is too much
      colour, and four saturated bars read as a dashboard.
      VERTICAL rule = "this block is a marked object". Owned by the
      WE HIRE index (2px --accent, the hero's single accent) and by
      the founder-quote panel (2px sage, already on the page at
      line 485). A vertical rule is also the one line that can never
      be confused with the horizontal wave field — which is the
      literal content of complaint #4.
      NO rule at all = the logo wall. Proof, not structure.
      Hairlines inside a block are 1px var(--line) and nothing else.

   2. TYPE — this pass adds ZERO new sans sizes.
      Label tier, page-wide, one spec: 500 / 13px / .1em / uppercase
      / var(--fg-2). Used by .section-label, .section-eyebrow and now
      .hero-roles-label (it was 600 — the only near-duplicate label
      tier on the page, now gone).
      Sans body sizes stay the page's existing 13 / 13.5 / 14.5 / 15
      / 16 / 17. The quote's identity block uses 15px, which the page
      already runs at #why-ngrs .result-card p.
      The WE HIRE index runs in the page's SECOND family (Plex Serif)
      at exactly one size per viewport — 17 / 16 / 14.5px. No third
      family, no uppercase size tier, nothing below 13px.

   3. BACKGROUNDS — this pass adds NO new background paint.
      No scrim over the wave field, no tinted panel in the hero.
      The client asked for lines in the background; erasing them
      locally to make a mark work would mean the mark is wrong.

   Reference mechanics borrowed are named per block below.
   Zero new motion. Zero new assets. Zero new type families.
   Does not touch /styles/ngrs.css.
   ============================================================ */


/* ============================================================
   16.1  STAT ROW — "the tick becomes the column's rule"
   Complaint #4a: «полосочки … не в ряд, там где регионы на разных
   уровнях». Complaint #4b: «маленькие черточки не смотрятся на фоне
   полосок и линий».

   CAUSE (verified in the file): line 111
   `.hero-stats li:last-child{align-self:end}`. The tick is the
   item's ::before, i.e. its first in-flow child, so its y follows
   the item's box top. Items 1-3 are ~67px tall; item 4 has no
   <strong> and is ~21px, and bottom-pinning it drops its box top —
   and its tick — ~45px. Specificity trap: line 111 is (0,2,1), so a
   plain `.hero-stats li` override at (0,1,1) would silently lose.
   The override below repeats `:last-child` to tie and win on order.

   BORROWED — Heidrick & Struggles `.stat`:
       .stat            { display:flex; flex-direction:column }
       .stat__underline { height:2px; width:100%; margin-bottom:8px }  <- FIRST child
   Their stat module ships no alignment CSS at all, because a
   full-width rule that is the first child of a flex column always
   lands on the same line however much or little follows it.
   Also borrowed — Egon Zehnder `.animated-stats__item`: an item with
   no figure simply occupies its column; nothing is bottom-pinned.

   Second half of the complaint is answered by SCALE and by
   SUBTRACTION, not by contrast: 30px is the same order of magnitude
   as a 1.2px background wave stroke, ~242px is not; and the block
   previously stacked FIVE horizontal line-events inside 46px (its
   own --line hairline plus four coloured stubs) over a striped
   field. The hairline goes and the four rules take its job: five
   line-events become one segmented rule.

   NOT DONE, deliberately: no ::after scrim over the wave field
   (all three reviewers were right — deleting the lines to make the
   marks work is a retreat from the brief), and padding-top is NOT
   removed, so nothing on the page moves by a pixel.
   ============================================================ */

/* the four rules replace the block's own hairline.
   padding-top is deliberately NOT touched: the figures stay exactly
   where they are today, on desktop and on the phone. */
.hero-stats { border-top: 0; }

/* every item is a flex column, rule first. No align-self anywhere. */
.hero-stats li,
.hero-stats li:last-child { display: flex; flex-direction: column; align-self: stretch; }

/* item 4 has no figure: the rule stays pinned at the top with the
   other three, and the region names drop to the bottom, level with
   the other three items' labels. That is complaint #4a read
   literally — the rule was out of line, the words were at the wrong
   level. Works with or without the markup change, because a bare
   text run in a flex container becomes an anonymous flex item. */
.hero-stats li:last-child { justify-content: space-between; }

/* the mark, at column scale. margin-bottom stays the layer's 14px
   (line 376) so the phone first screen is geometrically identical. */
.hero-stats li::before {
  content: ""; display: block; flex: 0 0 auto;
  width: 100%; height: 2px; border-radius: 0;   /* square ends: a rule, not a pill */
  background: var(--fg-4);
}
/* ONE decision, stated: the four brand hues come off the rules.
   The client has twice said there is too much colour, and complaint
   #3 requires WE HIRE — not the stats — to be the hero's accent.
   var(--fg-4) is theme-aware (#A8ACB6 / #5F646F), so no dark rule is
   needed. OPERATOR REVERT, one line: delete this rule and the four
   st-* colours from the layer come back at full column width. */
.hero-stats .st-blue::before,
.hero-stats .st-teal::before,
.hero-stats .st-green::before,
.hero-stats .st-yellow::before { background: var(--fg-4); }

/* the 4th item is a coverage list, not a statistic. It keeps its
   column and its rule, has no figure, and sits at the label size
   promoted to figure ink — "a set of places", not a statistic with
   the number missing. The 4 middot separators go (none of the three
   references separates list items inline, anywhere). */
.hero-stats .st-coverage .rg-list {
  display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 0; padding: 0;
}
.hero-stats .st-coverage .rg-list > span {
  white-space: nowrap;          /* no region name ever breaks mid-word */
  font-weight: 500;
  color: var(--fg);
}

@media (max-width: 640px) {
  .hero-stats .st-coverage .rg-list { gap: 5px 12px; }
}


/* ============================================================
   16.2  WE HIRE  →  "THE HIRING INDEX"
   Complaint #3: «надо сделать явным акцентом и убрать зоопарк
   шрифтов — обыграть этот блок по-другому».

   CAUSE (three declarations, three halves of the complaint):
   · THE ZOO — lines 385-388: 17 / 15 / 13.5px, two tracking values,
     and an UPPERCASE tier at 13.5px + .045em that reads as a third
     family even though it is Inter.
   · NO ACCENT — line 116/381: `border-top:1px solid var(--line)`,
     byte-identical to the rule the stats row uses one block above,
     so WE HIRE is typographically a footnote appended to the stats.
   · NO SHAPE — line 120 `display:inline;white-space:nowrap` plus
     line 389's "·" ::after: 19 roles flattened into one run-on
     sentence punctuated by 18 small marks — the same "small marks
     on a wavy background" failure as complaint #4, horizontally.

   BORROWED:
   · Heidrick `.footer__primary-links{columns:2}` + `__link{width:100%}`
     — a multi-column label list: one size, one weight, one colour,
     no bullets, no separators. Their footer explicitly KILLS its own
     ::after underline at desktop; ours kills the middots.
   · Egon Zehnder `.service-listing` / `.service-listing__link`
     (serif, 400, ONE size, one colour, no separators, ~40px of
     horizontal rhythm) — their nearest thing to 19 roles, and the
     reason this block moves into the page's second family instead of
     inventing a fourth sans size. Serif here is the accent by
     MATERIAL: it is the voice of the h1 and every section title.
   · Egon Zehnder `.text__label` — the label now uses the page's one
     label tier verbatim (500/13px/.1em/--fg-2), so the page's label
     tier count goes DOWN by one. Its 26px accent hairline is
     deliberately not copied: complaint #4 says small marks read
     badly against this background.
   · rob.co `.use-case-panel-stats{border-left:1px solid #0000000f}`
     — the only divider is a full-height edge that cannot misalign.
     Here twice: as the block's 2px --accent left rule (the accent),
     and as the native `column-rule` between index columns.
   · rob.co `.position---title` — hierarchy carried by COLOUR alone
     at the same family, same size, same weight.

   WHY THE ACCENT IS A VERTICAL RULE: the stat row 40px above owns
   the horizontal 2px rule, and the page's background field is
   horizontal. A vertical accent edge cannot be mistaken for either.
   It is also already this page's idiom for "marked object" — the
   founder-quote panel carries one (line 485).

   NOT DONE, deliberately: no accent tint / gradient sheet. The brief
   word is "space"; a coloured band in the hero contradicts it, and
   it would be a second background paint in the same 200px.
   ============================================================ */

.hero-roles {
  display: flex; flex-direction: column;
  align-items: stretch;                       /* was `baseline`, a row-era value */
  border-top: 0;                              /* the footnote hairline goes */
  border-left: 2px solid var(--accent);       /* THE accent. --accent, never --brand-blue */
  padding-left: clamp(18px, 2vw, 28px);       /* longhand only — padding-top stays section 15's */
}
/* NOTE ON THE PHONE: .hero-roles is ALREADY a flex column at <=700px
   (line 126), and section 15's `gap:12px` still governs the
   label-to-index distance because this block sets no gap. The block's
   top edge does not move; only the left edge indents. */

/* the page's one label tier, verbatim (was 600 — the only
   near-duplicate label spec on the page) */
.hero-roles .hero-roles-label {
  font: 500 13px/1.4 var(--font-sans);
  letter-spacing: .1em; text-transform: uppercase; color: var(--fg-2);
}

/* the index: ruled columns, DOM order preserved, all 19 roles stay
   plain crawlable text and no CSS-generated content anywhere */
.hero-roles .role-line {
  display: block; margin: 0; padding: 0; list-style: none;
  column-count: 4; column-gap: 36px;
  column-rule: 1px solid var(--line);         /* the only divider inside the block */
}

/* ONE tier for all 19: kills 17/15/13.5px, kills .045em, kills the
   uppercase tier, kills the run-on. (0,2,1) beats the layer's
   .role-line .r1/.r2/.r3 at (0,2,0) regardless of order. */
.hero-roles .role-line li {
  display: block;                             /* was inline */
  white-space: normal;                        /* was nowrap — would bleed out of a column */
  break-inside: avoid; -webkit-column-break-inside: avoid; page-break-inside: avoid;
  margin: 0; padding: 7px 0;
  font: 400 17px/1.4 var(--font-serif);
  letter-spacing: 0; text-transform: none;
  color: var(--fg-2);
}
/* the single emphasis: colour only, same family, same size, same
   weight (rob.co .position---title, inverted). Column balancing puts
   all four lead roles at the top of column one, so ORDER carries the
   rest. Delete this one declaration to flatten the block entirely. */
.hero-roles .role-line .r1 { color: var(--fg); }

/* the 18 middots go. Second selector is (0,3,2) and beats both the
   base (line 121) and the layer (line 389) at (0,2,2); the first is
   (0,2,2) and ties, winning on order. Belt and braces. */
.hero-roles .role-line li::after,
.hero-roles .role-line li:not(:last-child)::after { content: none; display: none; }

/* tablet: 4 -> 3 columns (the hero grid is single-column from 900px) */
@media (max-width: 900px) {
  .hero-roles .role-line { column-count: 3; column-gap: 30px; }
  .hero-roles .role-line li { font-size: 16px; }
}

/* 3 -> 2 well above the point where a column gets too narrow for the
   longest label ("Business Development" / "Solution Architects") */
@media (max-width: 760px) {
  .hero-roles .role-line { column-count: 2; column-gap: 24px; }
}

/* phone. Row height computes to ~28px against section 15's 29px
   inline rhythm, so each role occupies marginally LESS vertical
   space than it does today — the block is denser per role, not
   looser, and its top edge is unchanged.
   MEASURED IN THE BROWSER AT 375px, stated plainly rather than
   claimed away: the columns are 143.5px and exactly ONE of the 19
   labels — "Business Development" — wraps to two lines. Verified: it
   is the only one, `break-inside:avoid` keeps it whole in its column,
   and `white-space:normal` makes horizontal overflow impossible
   (document scrollWidth measured 375 at 375px, both themes). A
   two-line entry in a printed index is normal; dropping to 14px to
   avoid it would add a type size the page does not otherwise use. */
@media (max-width: 560px) {
  .hero-roles { padding-left: 16px; }
  .hero-roles .role-line { column-count: 2; column-gap: 14px; }
  .hero-roles .role-line li { font-size: 14.5px; line-height: 1.45; padding: 3px 0; }
}


/* ============================================================
   16.3  CLIENT LOGO WALL — «лого побольше надо сделать»

   MEASURED CAUSE: every asset sits on a uniform ~300x150 transparent
   canvas, but the ink inside fills only 19% (Nebulr, Acronis) to 43%
   (Cherry Labs) of that canvas height. `max-height:54px` caps the
   CANVAS, so the wall rendered ink at 10.1px to 23.0px — and raising
   max-height scales the padding with it, multiplying the spread
   instead of fixing it.

   FIXED AT THE ASSET LEVEL, not in CSS: assets/clients/fit/ holds the
   same 18 marks cropped to their ink bounding box (+2% breathing
   margin) and re-exported at 2x with Lanczos, since no vector sources
   exist. See _fit_client_logos.py. That removes the 18 per-brand
   scale factors this section would otherwise need, and with them the
   `overflow:hidden` that was the only thing preventing page overflow.

   BORROWED:
   · rob.co `.investors-block-wrapper{display:grid;grid-template-
     columns:repeat(6,1fr)}` + `.vc-cell{height:175px;place-items:
     center}` — identical fixed cells in a real grid, the mark
     normalised inside the cell instead of by a shared max-height.
     18 logos = 3 clean rows of 6, never a ragged centred wrap.
   · Egon Zehnder `.partner-section__grid{repeat(N,minmax(0,1fr))}` —
     locked box, FULL opacity, no plates, no dividers, no dimming.
     They never fade a logo, so neither do we.

   The two-class outcome falls out of the geometry rather than being
   authored: with a --lu x --lh box, every mark whose ink aspect
   exceeds --lu/--lh (3.4) is width-limited — 13 wordmarks land on one
   shared width, which is the straight vertical alignment the wall has
   never had — and the remaining 5 compact marks are height-limited
   onto one shared height. Median rendered ink 27.5px -> ~40px.
   ============================================================ */

.trusted .logo-marquee { overflow: visible; -webkit-mask-image: none; mask-image: none; }

.trusted .logo-marquee-track {
  --lu: min(150px, 13.4vw);            /* the box: one number drives the wall */
  --lh: calc(var(--lu) * .293);        /* 44px at 150 — the ink height cap */
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));   /* 18 logos = 3 clean rows */
  grid-auto-rows: calc(var(--lu) * .63);              /* box + air, from the cell not a gap */
  place-items: center;
  gap: 0;
  width: auto;
  animation: none;
}

/* This rule must NOT declare `display`: it is (0,2,1), the same as the
   layer's `.logo-marquee-track img[aria-hidden="true"]{display:none}`,
   and it comes later — declaring display here would un-hide the 18
   duplicates. The explicit guard below removes the trap entirely.
   width/height:auto + the two caps IS contain behaviour for a
   replaced element, so no aspect ratio can ever be distorted. */
.trusted .logo-marquee-track img {
  width: auto; height: auto;
  max-width: var(--lu); max-height: var(--lh);
  flex: none;
  opacity: 1;
  filter: grayscale(1);
  transition: filter .18s ease, background-color .18s ease, box-shadow .18s ease;
}
.trusted .logo-marquee-track img[aria-hidden="true"] { display: none; }

/* HOVER: the mark lights up in its own brand colours. Greyscale keeps the
   wall quiet at rest; the hover is the proof that these are 18 separate
   clients and not one flattened image. A hover state is the one motion the
   brief allows, and it is inert on touch — no tap is required to read the
   wall, so nothing can stick. */
.trusted .logo-marquee-track img:hover,
.trusted .logo-marquee-track img:focus-visible { filter: none; opacity: 1; }

/* Dark theme needs a plate: without `invert(1)` a near-black wordmark in its
   true colours is invisible on #16191F. The plate is drawn with box-shadow
   spread, so it costs no layout and cannot shift the grid. */
[data-theme="dark"] .trusted .logo-marquee-track img:hover,
[data-theme="dark"] .trusted .logo-marquee-track img:focus-visible {
  filter: none; opacity: 1;
  background: #fff;
  box-shadow: 0 0 0 12px #fff, 0 12px 28px rgba(0, 0, 0, .45);
  border-radius: 3px;
}

/* Dark theme: `invert(1)` turns the near-black marks near-white, and
   this pass also roughly triples their area. At opacity 1 that is 18
   marks brighter than the body text. Held at .88 — still a large step
   up from the .75 in ngrs.css, and reads as full strength. */
[data-theme="dark"] .trusted .logo-marquee-track img,
[data-theme="dark"] .trusted .logo-marquee-track img:hover {
  opacity: .88; filter: grayscale(1) invert(1);
}

/* 6 -> 3 up. The track is NOT narrowed and NOT centred: the wall keeps
   the same left edge as the .section-label above it. */
@media (max-width: 899px) {
  .trusted .logo-marquee-track {
    --lu: min(150px, 22vw);
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
/* Phone: the cell measures 106px at 375, so 24vw fills it to 90px and
   leaves 16px between neighbours. Measured: ink renders 19-26px tall
   here against 6.5-14.6px before this pass. */
@media (max-width: 640px) {
  .trusted .logo-marquee-track { --lu: min(132px, 24vw); }
}


/* ============================================================
   16.4  FOUNDER QUOTE — the portrait returns as a COLUMN
   Complaint #1: «нет фотки в цитате Натальи».

   CAUSE: the <img> does not exist in v4's markup — line 842 is a
   bare text node. /preview-home/ and /v2/ carry both the element and
   the two rules that place it (56px circle + flex figcaption); v4
   was forked before that patch. v4's own layer then authored the
   caption as a text-only strip (line 487) with no flex context and
   no room reserved, and `.quote .quote-mark{position:absolute}`
   (line 186) + `top:30px;right:34px` (line 488) pins the glyph into
   the one corner a real portrait wants.

   BORROWED:
   · Heidrick `.pull-quote__icon` — the glyph is a BLOCK at the head
     of the text column with a bottom margin, never an absolutely
     positioned corner ornament. This is what frees the corner: the
     photo and the glyph now share one top line instead of one
     corner, so they stop fighting.
   · Heidrick `.author-biography-card` — fixed-size photo box +
     object-fit, identity stack (photo -> name -> role) as one unit,
     and its `__header{display:flex;flex-direction:row;gap;align-items
     :center}` for the stacked phone layout.
   · rob.co `.testimonial_img` — a square-ish plate with a small
     radius, NOT a circle. Across all three references circle = small
     inline avatar (EZ 72px cite, Heidrick 35px byline) while every
     LARGE portrait is square. Square is what turns an avatar into a
     portrait.
   · rob.co `.position---title` — the role is separated from the name
     by colour, at the same family and size. No uppercase tier added.

   The portrait is 160x200 instead of a 56px circle — about 10x the
   area, the difference between "there is an avatar in the caption"
   and "there is a person in this block".

   NOT DONE, deliberately: the blockquote is NOT touched. It stays at
   the layer's 20px (line 486) and the layer's 18.5px at <=640px
   (line 574) stays alive. The client asked for a photo; growing her
   quote was scope she did not ask for.
   ============================================================ */

.quote {
  --q-photo: 160px;
  display: grid;
  /* the photo track is FIXED, not minmax(...,auto): with `auto` as
     the max the track grows to the name's max-content and the
     portrait's right edge stops agreeing with the name's, which
     breaks the identity unit by ~8px. The name is set at 15px so it
     fits 160px without wrapping. minmax(0,1fr) on the text column
     makes horizontal overflow impossible. */
  grid-template-columns: var(--q-photo) minmax(0, 1fr);
  /* row 1 = glyph (auto), row 2 = 1fr absorbs all slack, so the
     taller spanning caption cannot push the quote away from the
     glyph */
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "cite mark"
    "cite quote";
  column-gap: clamp(26px, 3.2vw, 40px);
  align-items: start;
  /* padding is deliberately NOT declared: the layer's 40/40/36 and
     its <=820px 32/28/28 both survive untouched. At 1440 the panel
     is 980px wide, so the content box is 897px and the columns are
     160 + 40 + 697. */
}

/* the glyph leaves the corner and becomes the head of the text column */
.quote .quote-mark {
  grid-area: mark;
  position: static; top: auto; right: auto;
  display: block;                       /* kills the inline baseline gap, so the
                                           glyph's top edge lands on the photo's */
  width: 40px; height: auto;
  margin: 0 0 18px;
  color: color-mix(in oklab, var(--accent-2) 55%, transparent);
  opacity: 1;
}
/* ngrs.css line 480 recolours the mark to --accent (blue) on dark and
   drops it to opacity .4, which put a second hue into a sage panel.
   Held to sage in both themes. (0,3,0) beats it. */
[data-theme="dark"] .quote .quote-mark {
  color: color-mix(in oklab, var(--accent-2) 62%, transparent);
  opacity: 1;
}

.quote blockquote { grid-area: quote; margin: 0; }

/* identity unit: portrait -> name -> role.
   .quote-id wraps the two text lines so the block can become a
   photo|text ROW on the phone with one declaration. (Without it the
   only alternative is a grid in which the photo spans both text
   rows — and a spanning item inflates those rows, which puts 60px of
   air between the name and the role. Measured, then fixed.) */
.quote figcaption {
  grid-area: cite;
  display: flex; flex-direction: column; align-items: flex-start;
}
.quote-id { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

/* The FRAME carries the box, the border and the crop; the image just
   fills it. Two reasons this is a wrapper and not a bare <img>:
   (1) the frame's aspect-ratio gives the box a definite 160x200
   before the lazy image arrives, so the lazy load causes zero layout
   shift; (2) the source is a 320x320 studio shot in which the
   subject occupies x 4.7-90.6% (mass 12.5-58%) and y 20.9-100% —
   i.e. a fifth of a plain 4:5 cover crop would be empty white above
   her head, which is what makes it read as a cutout rather than a
   photograph. The frame lets the image be positioned past `cover`
   and land on a real crop (source x 4-74%, y 12-100%). */
.quote-photo-frame {
  position: relative; overflow: hidden;
  display: block; width: var(--q-photo); aspect-ratio: 4 / 5;
  margin: 0 0 14px;
  border-radius: 12px;
  border: 1px solid color-mix(in oklab, var(--accent-2) 40%, var(--line));
  background: var(--bg-2);
}
[data-theme="dark"] .quote-photo-frame {
  border-color: color-mix(in oklab, var(--accent-2) 46%, var(--line));
}
/* TUNED TO THIS 320x320 FILE. If the photo is ever replaced, reset
   this rule to `left:0;top:0;width:100%;height:100%;object-fit:cover`
   and re-tune, or crop the new file to 4:5 at source. */
.quote-photo {
  position: absolute; left: -6%; top: -13.5%;
  width: 143%; height: auto; display: block;
  max-width: none;                       /* the site's global img cap must not shrink it */
}

/* two tiers, one family, one size — 15px is the page's existing
   body-small (#why-ngrs .result-card p). No uppercase, no tracking
   tier, and "Natalia Domashenko" fits the 160px column at this size. */
.quote-name { font: 600 15px/1.35 var(--font-sans); letter-spacing: 0; color: var(--fg); }
.quote-role { font: 400 15px/1.45 var(--font-sans); letter-spacing: 0; color: var(--fg-2); }

/* Below 700px the text column would be too narrow to read, so the
   block stacks — and the portrait goes to the TOP, not the bottom.
   The whole argument of this block is that there is a person in it;
   on the phone the person has to arrive first. Photo + name become
   one header row (Heidrick .author-biography-card__header), then the
   glyph, then the quote. */
@media (max-width: 700px) {
  .quote {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    grid-template-areas: "cite" "mark" "quote";
    column-gap: 0;
  }
  /* photo left, name over role to its right, the pair optically
     centred against the plate — Heidrick .author-biography-card__header */
  .quote figcaption {
    flex-direction: row; align-items: center; gap: 16px;
    margin-bottom: 24px;
  }
  .quote-photo-frame { --q-photo: 128px; flex: 0 0 auto; margin: 0; }
  .quote .quote-mark { width: 34px; margin-bottom: 14px; }
}
/* Below 560px the text column would be narrower than "Natalia
   Domashenko" (~157px at 15px Inter), so the identity goes back to a
   vertical stack — still first in the block, still whole, never
   wrapped. */
@media (max-width: 560px) {
  .quote figcaption { flex-direction: column; align-items: flex-start; margin-bottom: 22px; }
  .quote-photo-frame { --q-photo: 112px; border-radius: 10px; margin: 0 0 12px; }
  .quote .quote-mark { width: 30px; margin-bottom: 12px; }
}


/* ============================================================
   16.5  FORCED COLOURS
   Section 14 of the layer neutralises several of these properties;
   every plain rule above would otherwise outrank it by source order,
   so each one is restated here. Specificities checked: this block's
   `.hero-stats li::before` (0,1,2) and `.hero-roles .role-line li`
   (0,2,1) both beat section 14's equivalents.
   ============================================================ */
@media (forced-colors: active) {
  .hero-stats li::before,
  .hero-stats .st-blue::before, .hero-stats .st-teal::before,
  .hero-stats .st-green::before, .hero-stats .st-yellow::before { background: CanvasText; }
  .hero-stats .st-coverage .rg-list > span { color: CanvasText; }

  .hero-roles { border-left-color: Highlight; }
  .hero-roles .hero-roles-label,
  .hero-roles .role-line li,
  .hero-roles .role-line .r1 { color: CanvasText; }
  .hero-roles .role-line { column-rule-color: CanvasText; }

  .trusted .logo-marquee-track img,
  [data-theme="dark"] .trusted .logo-marquee-track img { filter: none; opacity: 1; }

  .quote-photo-frame { border-color: CanvasText; }
  .quote-name, .quote-role { color: CanvasText; }
}

/* ---------- the hero illustration ----------
   The plates are glass: a cool-to-warm body, a sheen across the top third, a
   lit rim and a real shadow, in three depth planes. The back plane is blurred
   and thin, the front plane is sharp — that difference is what makes it an
   object instead of a diagram. One plate is amber: the role that closes.
   DONOR — daversa.com (`._3d_asterisk_canvas`): their dimensional element is
   their own mark, never generic decoration.
   DONOR — heidrick.com: 1:3 stroke ratio — neutral hairline for the geometry,
   colour only on short accented runs. */
.hero-art-svg .st-g { stroke-width: 1.5; }
.hero-art-svg .st   { stroke: currentColor; transition: stroke-width .45s ease, opacity .45s ease; }
.hero-art-svg .st:nth-child(4) { stroke: color-mix(in oklab, var(--accent) 76%, currentColor); stroke-width: 2.6; }

.hero-art-svg .gw0 { stop-color: color-mix(in oklab, var(--accent) 20%, transparent); }
.hero-art-svg .gw1 { stop-color: transparent; }

.hero-art-svg .gl0 { stop-color: color-mix(in oklab, var(--accent)     34%, #FFFFFF); stop-opacity: .96; }
.hero-art-svg .gl1 { stop-color: color-mix(in oklab, var(--brand-teal) 30%, #FFFFFF); stop-opacity: .84; }
.hero-art-svg .gl2 { stop-color: color-mix(in oklab, var(--accent)     16%, #FFFFFF); stop-opacity: .62; }
.hero-art-svg .am0 { stop-color: color-mix(in oklab, #E2B33C 74%, #FFFFFF); stop-opacity: .98; }
.hero-art-svg .am1 { stop-color: color-mix(in oklab, #E2B33C 34%, #FFFFFF); stop-opacity: .72; }
.hero-art-svg .sh0 { stop-color: #FFFFFF; stop-opacity: .78; }
.hero-art-svg .sh1 { stop-color: #FFFFFF; stop-opacity: 0; }
.hero-art-svg .rim { stroke: rgba(255, 255, 255, .92); }

/* the amber plate: a <use> clones the symbol, so the per-instance fill is passed
   in as an inherited custom property — it crosses into the shadow tree, an
   external selector would not. */
.hero-art-svg .plate { --pl-fill: url(#ngGlass); }
.hero-art-svg .amber { --pl-fill: url(#ngAmber); }
.hero-art-svg .p1 { opacity: .5; }
.hero-art-svg .p2 { opacity: .82; }
.hero-art-svg .p3 { opacity: 1; }
.hero-art-svg .pl { transition: opacity .45s ease; }
.hero-art-svg feDropShadow { flood-color: #2A2D34; flood-opacity: .17; }

/* dark: the glass goes from "white with a tint" to "tinted pane on a dark room" */
[data-theme="dark"] .hero-art-svg .gl0 { stop-color: color-mix(in oklab, var(--accent)     52%, #FFFFFF); stop-opacity: .30; }
[data-theme="dark"] .hero-art-svg .gl1 { stop-color: color-mix(in oklab, var(--brand-teal) 46%, #FFFFFF); stop-opacity: .22; }
[data-theme="dark"] .hero-art-svg .gl2 { stop-color: #FFFFFF; stop-opacity: .10; }
[data-theme="dark"] .hero-art-svg .am0 { stop-color: #ECC458; stop-opacity: .52; }
[data-theme="dark"] .hero-art-svg .am1 { stop-color: #ECC458; stop-opacity: .18; }
[data-theme="dark"] .hero-art-svg .sh0 { stop-color: #FFFFFF; stop-opacity: .22; }
[data-theme="dark"] .hero-art-svg .rim { stroke: rgba(255, 255, 255, .36); }
[data-theme="dark"] .hero-art-svg feDropShadow { flood-color: #000000; flood-opacity: .55; }
[data-theme="dark"] .hero-art-svg .gw0 { stop-color: color-mix(in oklab, var(--accent) 26%, transparent); }

/* the one interaction: hovering the artwork brings the searches forward.
   User-initiated, so it does not fall foul of «всё бегущее бесит». */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .hero-art:hover .hero-art-svg .st { stroke-width: 2.1; }
  .hero-art:hover .hero-art-svg .p1 { opacity: .66; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-art-svg .st, .hero-art-svg .pl { transition: none; }
}
@media (forced-colors: active) {
  .hero-art-svg .rim { stroke: CanvasText; }
  .hero-art-svg .glow { display: none; }
}


/* the stock render is gone, so its 14s float has nothing to animate */
.hero-art img, .hero-art-svg { animation: none; }
/* ---------- header lockup: the mark returns, and the abbreviation is spelled out ----
   Operator: «в хедере нет логотипа рядом с NGRS — нигде нет расшифровки
   аббревиатуры». None of the 29 reference sites spells an abbreviation out in
   the header chrome — RRA, True and RobCo all keep the full name to <title>,
   the footer and the markup. So the expansion is set small and quiet under the
   wordmark rather than beside it, and it is real text, not an aria-label, so
   an answer engine can read it.
   DONOR — rob.co `.navbar_logo-link`: mark and word in ONE link, one hit area.
   DONOR — peoplescout.com: the expansion is bound to the logo element itself. */
.brand-lockup { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.brand-lockup .brand-mark { width: 30px; height: auto; flex: none; display: block; }
.brand-lockup .brand-text { display: flex; flex-direction: column; line-height: 1; }
.brand-lockup .brand-word { font: 600 18px/1 var(--font-sans); letter-spacing: .06em; color: var(--fg); }
.brand-lockup .brand-expansion {
  margin-top: 3px; font: 400 10.5px/1.25 var(--font-sans);
  letter-spacing: .04em; color: var(--fg-3); white-space: nowrap;
}
@media (max-width: 560px) { .brand-lockup .brand-expansion { display: none; } }
@media (forced-colors: active) { .brand-lockup .brand-expansion { color: CanvasText; } }

/* ---------- 11. the hero illustration: pieces becoming one object ----------
   Three faces, three values of the same light — that is where the volume comes
   from, not from a shadow underneath. The top face catches the most light, the
   left wall is the body colour, the right wall is the shadow side. The piece
   still in the air is amber: the role that has not closed yet.
   DONOR — daversa.com: a dimensional element earns its place only when it says
   something about the company. This one is literally the product. */
.hero-art-svg .glow  { }
.hero-art-svg .gw0   { stop-color: color-mix(in oklab, var(--accent) 22%, transparent); }
.hero-art-svg .gw1   { stop-color: transparent; }

.hero-art-svg .ft { fill: url(#fTop); }
.hero-art-svg .fl { fill: url(#fLeft); }
.hero-art-svg .fr { fill: url(#fRight); }
.hero-art-svg .cu path { stroke: rgba(255, 255, 255, .82); stroke-width: .9; stroke-linejoin: round; }

.hero-art-svg .t0 { stop-color: color-mix(in oklab, var(--brand-teal) 16%, #FFFFFF); }
.hero-art-svg .t1 { stop-color: color-mix(in oklab, var(--brand-teal) 40%, #FFFFFF); }
.hero-art-svg .l0 { stop-color: color-mix(in oklab, var(--brand-teal) 62%, #FFFFFF); }
.hero-art-svg .l1 { stop-color: color-mix(in oklab, var(--accent)     64%, #FFFFFF); }
.hero-art-svg .r0 { stop-color: color-mix(in oklab, var(--accent)     78%, #FFFFFF); }
.hero-art-svg .r1 { stop-color: var(--accent); }

.hero-art-svg .am .ft { fill: url(#aTop); }
.hero-art-svg .am .fl { fill: url(#aLeft); }
.hero-art-svg .am .fr { fill: url(#aRight); }
.hero-art-svg .at0 { stop-color: #F6DA9B; }
.hero-art-svg .at1 { stop-color: #F0C765; }
.hero-art-svg .al0 { stop-color: #E9BE55; }
.hero-art-svg .al1 { stop-color: #DDA92E; }
.hero-art-svg .ar0 { stop-color: #D3991F; }
.hero-art-svg .ar1 { stop-color: #BE8617; }

/* the pieces still in the air: nearer ones are more solid */
.hero-art-svg .lp1 { opacity: .30; }
.hero-art-svg .lp2 { opacity: .50; }
.hero-art-svg .lp3 { opacity: .72; }

/* trajectories — heidrick's 1:3 stroke ratio: neutral hairlines, one accented run */
.hero-art-svg .tr path { stroke: color-mix(in oklab, var(--accent) 40%, var(--fg-4)); stroke-width: 1.3; }
.hero-art-svg .tr path:nth-child(3) { stroke: var(--accent); stroke-width: 2.4; }
.hero-art-svg .guide { stroke: color-mix(in oklab, #DDA92E 70%, transparent); stroke-width: 1.6; stroke-dasharray: 3 4; }
.hero-art-svg feDropShadow { flood-color: #2A2D34; flood-opacity: .22; }

.hero-art-svg .loose, .hero-art-svg .last, .hero-art-svg .tr path {
  transition: opacity .4s ease, transform .4s ease;
}

/* dark: the block keeps its hues but the light source weakens */
[data-theme="dark"] .hero-art-svg .t0 { stop-color: color-mix(in oklab, var(--brand-teal) 34%, #FFFFFF); }
[data-theme="dark"] .hero-art-svg .t1 { stop-color: color-mix(in oklab, var(--brand-teal) 62%, #FFFFFF); }
[data-theme="dark"] .hero-art-svg .l0 { stop-color: color-mix(in oklab, var(--brand-teal) 72%, var(--accent)); }
[data-theme="dark"] .hero-art-svg .l1 { stop-color: var(--accent); }
[data-theme="dark"] .hero-art-svg .r0 { stop-color: color-mix(in oklab, var(--accent) 74%, #16324A); }
[data-theme="dark"] .hero-art-svg .r1 { stop-color: #2F5F86; }
[data-theme="dark"] .hero-art-svg .cu path { stroke: rgba(255, 255, 255, .34); }
[data-theme="dark"] .hero-art-svg feDropShadow { flood-color: #000000; flood-opacity: .6; }

/* the one interaction: hovering brings the loose pieces forward */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .hero-art:hover .hero-art-svg .lp1 { opacity: .5; }
  .hero-art:hover .hero-art-svg .lp2 { opacity: .7; }
  .hero-art:hover .hero-art-svg .lp3 { opacity: .9; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-art-svg .loose, .hero-art-svg .last, .hero-art-svg .tr path { transition: none; }
}
@media (forced-colors: active) {
  .hero-art-svg .cu path { fill: Canvas; stroke: CanvasText; }
  .hero-art-svg .am .ft, .hero-art-svg .am .fl, .hero-art-svg .am .fr { fill: Highlight; }
  .hero-art-svg .glow { display: none; }
}


/* ============================================================
   13.  MOBILE — measured on real touch contexts, not a resized window
   Audited with Chromium under `is_mobile + has_touch` at 320 / 360 / 375 /
   390 / 430 / 768 in both themes. The expensive effects already switch
   themselves off there (backdrop-filter drops from 4 objects to 1, the field
   stops being fixed, the scroll drift does not run) — that part was right.
   These are the five things that were not.
   ============================================================ */

/* ---------- 13.1 the illustration exists on a phone ----------
   Section 15 hides .hero-art below 560px, which was correct when it was a
   stock render competing for the first screen. It is now the one drawn asset
   on the page and the founder reviews on a phone — hiding it means she never
   sees it. `display:contents` on the grid lifts .hero-copy and .hero-art out
   to be siblings of the stats and the roles, so the illustration can be
   ORDERED last: the client-approved first screen (h1, buttons, stats, the
   WE HIRE title) is untouched, and the drawing arrives one flick down. */
@media (max-width: 700px) {
  .hero > .container { display: flex; flex-direction: column; gap: 0; }
  .hero-grid  { display: contents; }
  .hero-copy  { order: 1; }
  .hero-stats { order: 2; }
  .hero-roles { order: 3; }
  .hero-art   { order: 4; display: block; margin-top: clamp(28px, 6vw, 44px); max-width: 100%; }
  .hero-art .art-frame { padding: 14px; }
}


@media (hover: none) and (pointer: coarse) {
  .site-header .theme-toggle { min-width: 44px; min-height: 44px; }
  .btn, .btn-primary, .btn-yellow, .btn-ghost { min-height: 44px; display: inline-flex;
    align-items: center; justify-content: center; }
  .primary-nav a { min-height: 44px; display: inline-flex; align-items: center; }
}
@media (max-width: 700px) { .brand-lockup { min-height: 44px; } }


/* ---------- 13.6 the rest of the touch targets ----------
   The audit turned up thirteen footer links at 17px tall stacked in columns —
   adjacent hit areas roughly a finger-width apart, which is where mis-taps
   come from — plus the burger at 40px, the footer wordmark at 19px and the
   cookie button at 35px. Padding, not font size: nothing gets visually
   heavier, the target grows underneath. */
@media (hover: none) and (pointer: coarse) {
  .site-footer a,
  .footer-cols a,
  .footer-bottom a {
    display: inline-block;
    padding-block: 11px;
    min-height: 44px;
  }
  .site-footer .wordmark,
  .site-footer .brand-lockup { display: inline-flex; align-items: center; min-height: 44px; }
  .nav-burger, .site-header .nav-burger { min-width: 44px; min-height: 44px; }
  [class*="cookie"] button, [class*="cookie"] a { min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center; }
}


/* ============================================================
   17.  INTERACTIVE WE HIRE — ported from v5 at the client's request
   (Natalia, 05.08: «вроде мы хотели интерактивное we hire оставить»).
   Logic intact: chips, five families, dim-the-rest selection, mobile
   one-family-per-row, 44px touch targets, scroll-fade on the chip row.
   v5's tokens are defined locally and resolve to v4's flat language.
   ============================================================ */
.hero-roles {
  --v5-s1: 8px; --v5-s2: 16px; --v5-s3: 24px; --v5-s4: 32px;
  --v5-paper: var(--bg-2);
  --v5-r-in: 12px;
  --v5-glass-line: var(--line);
  --v5-glass-lift: 0 1px 2px rgba(42,45,52,.05), 0 14px 34px -22px rgba(42,45,52,.22);
}
.hero-roles .hero-roles-label {
  font: 500 clamp(26px, 2.6vw, 34px)/1.12 var(--font-serif);
  letter-spacing: -.015em; text-transform: none; color: var(--fg);
  margin-bottom: 4px;
}
.hero-roles .hero-roles-label::after {
  content: ""; display: block; width: 46px; height: 3px; margin-top: 12px;
  background: var(--accent); border-radius: 2px;
}
@media (max-width: 560px) {
  .hero-roles .hero-roles-label { font-size: 21px; }
  .hero-roles .hero-roles-label::after { width: 34px; height: 2px; margin-top: 8px; }
}
.wh-plate {
  background: var(--v5-paper);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--v5-glass-lift);
  padding: var(--v5-s3);
  margin-top: 14px;
}
[data-theme="dark"] .wh-plate { background: var(--bg-2); }
@media (forced-colors: active) { .wh-plate { background: Canvas; border-color: CanvasText; } }

.wh-plate { padding: var(--v5-s3); }
.wh-lens { display: flex; flex-wrap: wrap; gap: var(--v5-s1); margin: 0 0 var(--v5-s3); }
.wh-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.wh-lens label { display: inline-flex; align-items: center; padding: 7px 14px; border: 1px solid var(--line-strong); border-radius: 999px; cursor: pointer; font: 500 13px/1.2 var(--font-sans); letter-spacing: .01em; color: var(--fg-2); background: transparent; -webkit-tap-highlight-color: transparent; transition: color .18s ease, border-color .18s ease, background-color .18s ease; }
.wh-lens label:hover { color: var(--fg); border-color: var(--fg-3); }
.wh-sr:checked + label { color: var(--fg); border-color: var(--accent); background: color-mix(in oklab, var(--accent) 15%, transparent); }
.wh-sr:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 2px; }
.wh-map { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: var(--v5-s4) var(--v5-s4); }
.wh-fam { min-width: 0; border-left: 1px solid var(--line-strong); padding-left: 22px; transition: border-color .22s ease; }
.wh-fam.f1, .wh-fam.f2 { grid-column: span 3; }
.wh-fam.f3, .wh-fam.f4, .wh-fam.f5 { grid-column: span 2; }
.wh-fam-head { margin: 0; display: flex; align-items: baseline; gap: 10px; font: 500 13px/1.4 var(--font-sans); letter-spacing: .1em; text-transform: uppercase; color: var(--fg-2); transition: color .22s ease; }
.wh-fam-n { flex: 0 0 auto; font-variant-numeric: tabular-nums; font-weight: 400; letter-spacing: .04em; color: var(--fg-2); }
.wh-bar { display: block; position: relative; margin: 10px 0 14px; width: 100%; max-width: 132px; height: 1px; background: var(--line-strong); }
.wh-bar::after { content: ""; position: absolute; left: 0; top: -1px; height: 3px; width: calc(var(--n) / 7 * 100%); background: var(--accent); transition: height .22s ease, top .22s ease; }
.wh-roles { margin: 0; padding: 0; list-style: none; font-size: 15px; column-gap: 44px; column-rule: 1px solid var(--line-strong); }
@media (min-width: 901px) {
  .wh-fam.f1 .wh-roles, .wh-fam.f2 .wh-roles { column-count: 2; }
}
.wh-roles li { position: relative; margin: 0; padding: 4px 0; font: 400 15px/1.5 var(--font-serif); letter-spacing: 0; color: var(--fg-2); overflow-wrap: break-word; transition: color .22s ease, font-size .22s ease; }
.wh-roles li::before { content: ""; position: absolute; left: -22px; top: .95em; width: 14px; height: 1px; background: var(--line-strong); transition: background-color .22s ease, height .22s ease; }
.wh-fam:hover, .wh-fam:focus-within { border-left-color: var(--accent); }
.wh-fam:hover .wh-roles,
.wh-fam:focus-within .wh-roles { column-rule-color: var(--accent); }
.wh-fam:hover .wh-roles li::before,
.wh-fam:focus-within .wh-roles li::before { background: var(--accent); height: 2px; }
.wh-fam:hover .wh-roles li,
.wh-fam:focus-within .wh-roles li { color: var(--fg); }
.wh-fam:hover .wh-fam-head,
.wh-fam:focus-within .wh-fam-head { color: var(--fg); }
.wh-plate:has(#wh-f1:checked) .f1,
.wh-plate:has(#wh-f2:checked) .f2,
.wh-plate:has(#wh-f3:checked) .f3,
.wh-plate:has(#wh-f4:checked) .f4,
.wh-plate:has(#wh-f5:checked) .f5 ,
.wh-plate:has(#wh-f6:checked) .f6 ,
.wh-plate:has(#wh-f7:checked) .f7 ,
.wh-plate:has(#wh-f8:checked) .f8 { grid-column: 1 / -1; order: -1; border-left-width: 2px; border-left-color: var(--accent); }
.wh-plate:has(#wh-f1:checked) .f1 .wh-roles,
.wh-plate:has(#wh-f2:checked) .f2 .wh-roles,
.wh-plate:has(#wh-f3:checked) .f3 .wh-roles,
.wh-plate:has(#wh-f4:checked) .f4 .wh-roles,
.wh-plate:has(#wh-f5:checked) .f5 .wh-roles ,
.wh-plate:has(#wh-f6:checked) .f6 .wh-roles ,
.wh-plate:has(#wh-f7:checked) .f7 .wh-roles ,
.wh-plate:has(#wh-f8:checked) .f8 .wh-roles { column-count: 3; column-rule-color: var(--accent); }
.wh-plate:has(#wh-f1:checked) .f1 .wh-roles li,
.wh-plate:has(#wh-f2:checked) .f2 .wh-roles li,
.wh-plate:has(#wh-f3:checked) .f3 .wh-roles li,
.wh-plate:has(#wh-f4:checked) .f4 .wh-roles li,
.wh-plate:has(#wh-f5:checked) .f5 .wh-roles li ,
.wh-plate:has(#wh-f6:checked) .f6 .wh-roles li ,
.wh-plate:has(#wh-f7:checked) .f7 .wh-roles li ,
.wh-plate:has(#wh-f8:checked) .f8 .wh-roles li { font-size: 17px; color: var(--fg); }
.wh-plate:has(#wh-f1:checked) .f1 .wh-roles li::before,
.wh-plate:has(#wh-f2:checked) .f2 .wh-roles li::before,
.wh-plate:has(#wh-f3:checked) .f3 .wh-roles li::before,
.wh-plate:has(#wh-f4:checked) .f4 .wh-roles li::before,
.wh-plate:has(#wh-f5:checked) .f5 .wh-roles li::before ,
.wh-plate:has(#wh-f6:checked) .f6 .wh-roles li::before ,
.wh-plate:has(#wh-f7:checked) .f7 .wh-roles li::before ,
.wh-plate:has(#wh-f8:checked) .f8 .wh-roles li::before { background: var(--accent); height: 2px; }
.wh-plate:has(#wh-f1:checked) .f1 .wh-bar::after,
.wh-plate:has(#wh-f2:checked) .f2 .wh-bar::after,
.wh-plate:has(#wh-f3:checked) .f3 .wh-bar::after,
.wh-plate:has(#wh-f4:checked) .f4 .wh-bar::after,
.wh-plate:has(#wh-f5:checked) .f5 .wh-bar::after ,
.wh-plate:has(#wh-f6:checked) .f6 .wh-bar::after ,
.wh-plate:has(#wh-f7:checked) .f7 .wh-bar::after ,
.wh-plate:has(#wh-f8:checked) .f8 .wh-bar::after { height: 4px; top: -1.5px; }
.wh-plate:has(#wh-f1:checked) .f1 .wh-fam-head,
.wh-plate:has(#wh-f2:checked) .f2 .wh-fam-head,
.wh-plate:has(#wh-f3:checked) .f3 .wh-fam-head,
.wh-plate:has(#wh-f4:checked) .f4 .wh-fam-head,
.wh-plate:has(#wh-f5:checked) .f5 .wh-fam-head ,
.wh-plate:has(#wh-f6:checked) .f6 .wh-fam-head ,
.wh-plate:has(#wh-f7:checked) .f7 .wh-fam-head ,
.wh-plate:has(#wh-f8:checked) .f8 .wh-fam-head { color: var(--fg); }
@media (max-width: 900px) {
  .wh-map { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--v5-s3) var(--v5-s3); }
  .wh-fam.f1, .wh-fam.f2, .wh-fam.f3, .wh-fam.f4 { grid-column: span 1; }
  .wh-fam.f5 { grid-column: span 2; }
  .wh-plate:has(.wh-sr:checked:not(#wh-all)) .wh-fam { grid-column: span 1; }
  .wh-plate:has(#wh-f5:checked) .f5 { grid-column: 1 / -1; }
  .wh-plate:has(#wh-f1:checked) .f1 .wh-roles,
  .wh-plate:has(#wh-f2:checked) .f2 .wh-roles,
  .wh-plate:has(#wh-f3:checked) .f3 .wh-roles,
  .wh-plate:has(#wh-f4:checked) .f4 .wh-roles,
  .wh-plate:has(#wh-f5:checked) .f5 .wh-roles ,
  .wh-plate:has(#wh-f6:checked) .f6 .wh-roles ,
  .wh-plate:has(#wh-f7:checked) .f7 .wh-roles ,
  .wh-plate:has(#wh-f8:checked) .f8 .wh-roles { column-count: 2; }
}
@media (max-width: 780px) {
  .wh-lens { position: relative; flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; padding-bottom: 2px; -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent 100%); mask-image: linear-gradient(90deg, #000 88%, transparent 100%); }
  .wh-lens::-webkit-scrollbar { display: none; }
  .wh-lens label { flex: 0 0 auto; }
}
@media (max-width: 560px) {
  .wh-plate { padding: 14px; }
  .wh-lens { gap: 6px; margin-bottom: var(--v5-s2); }
  .wh-lens label { padding: 6px 11px; font-size: 13px; }
  .wh-map { gap: var(--v5-s3) var(--v5-s2); }
  .wh-fam { padding-left: 16px; }
  .wh-roles li { font-size: 14.5px; line-height: 1.45; padding: 3px 0; }
  .wh-roles li::before { left: -16px; width: 10px; }
  .wh-bar { max-width: 96px; margin: 8px 0 10px; }
  .wh-plate:has(.wh-sr:checked:not(#wh-all)) .wh-fam .wh-roles { column-count: 1; }
  .wh-plate:has(#wh-f1:checked) .f1 .wh-roles li,
  .wh-plate:has(#wh-f2:checked) .f2 .wh-roles li,
  .wh-plate:has(#wh-f3:checked) .f3 .wh-roles li,
  .wh-plate:has(#wh-f4:checked) .f4 .wh-roles li,
  .wh-plate:has(#wh-f5:checked) .f5 .wh-roles li ,
  .wh-plate:has(#wh-f6:checked) .f6 .wh-roles li ,
  .wh-plate:has(#wh-f7:checked) .f7 .wh-roles li ,
  .wh-plate:has(#wh-f8:checked) .f8 .wh-roles li { font-size: 15.5px; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-art-svg .st,
  .hero-art .art-frame,
  .wh-fam, .wh-roles li, .wh-roles li::before, .wh-bar::after, .wh-fam-head,
  .wh-lens label, .trusted .lw-cell, .trusted .lw-cell img,
  .site-header .brand-mark { transition: none; }
}
@media (forced-colors: active) {
  .wh-lens label { background: Canvas; border-color: CanvasText; color: CanvasText; }
  .wh-sr:checked + label { background: Highlight; color: HighlightText; border-color: Highlight; }
  .wh-fam { border-left-color: CanvasText; }
  .wh-fam-head, .wh-fam-n, .wh-roles li { color: CanvasText; }
  .wh-roles li::before { background: CanvasText; }
  .wh-bar { background: CanvasText; }
  .wh-bar::after { background: Highlight; }
  .wh-roles { column-rule-color: CanvasText; }
}
.wh-fam { transition: opacity .22s ease, filter .22s ease, border-color .22s ease; }
.wh-plate:has(#wh-f1:checked) .wh-fam:not(.f1),
.wh-plate:has(#wh-f2:checked) .wh-fam:not(.f2),
.wh-plate:has(#wh-f3:checked) .wh-fam:not(.f3),
.wh-plate:has(#wh-f4:checked) .wh-fam:not(.f4),
.wh-plate:has(#wh-f5:checked) .wh-fam:not(.f5) ,
.wh-plate:has(#wh-f6:checked) .wh-fam:not(.f6) ,
.wh-plate:has(#wh-f7:checked) .wh-fam:not(.f7) ,
.wh-plate:has(#wh-f8:checked) .wh-fam:not(.f8) { opacity: .32; filter: saturate(.12); }
.wh-plate:has(#wh-f1:checked) .f1,
.wh-plate:has(#wh-f2:checked) .f2,
.wh-plate:has(#wh-f3:checked) .f3,
.wh-plate:has(#wh-f4:checked) .f4,
.wh-plate:has(#wh-f5:checked) .f5 ,
.wh-plate:has(#wh-f6:checked) .f6 ,
.wh-plate:has(#wh-f7:checked) .f7 ,
.wh-plate:has(#wh-f8:checked) .f8 { border-left-color: var(--accent); box-shadow: inset 1px 0 0 0 var(--accent); }
.wh-plate:has(#wh-f1:checked) .f1 .wh-fam-head,
.wh-plate:has(#wh-f2:checked) .f2 .wh-fam-head,
.wh-plate:has(#wh-f3:checked) .f3 .wh-fam-head,
.wh-plate:has(#wh-f4:checked) .f4 .wh-fam-head,
.wh-plate:has(#wh-f5:checked) .f5 .wh-fam-head ,
.wh-plate:has(#wh-f6:checked) .f6 .wh-fam-head ,
.wh-plate:has(#wh-f7:checked) .f7 .wh-fam-head ,
.wh-plate:has(#wh-f8:checked) .f8 .wh-fam-head { color: var(--fg); }
.wh-plate:has(#wh-f1:checked) .f1 .wh-roles li,
.wh-plate:has(#wh-f2:checked) .f2 .wh-roles li,
.wh-plate:has(#wh-f3:checked) .f3 .wh-roles li,
.wh-plate:has(#wh-f4:checked) .f4 .wh-roles li,
.wh-plate:has(#wh-f5:checked) .f5 .wh-roles li ,
.wh-plate:has(#wh-f6:checked) .f6 .wh-roles li ,
.wh-plate:has(#wh-f7:checked) .f7 .wh-roles li ,
.wh-plate:has(#wh-f8:checked) .f8 .wh-roles li { color: var(--fg); }
@media (prefers-reduced-motion: reduce) {
  .wh-fam { transition: none; }
}
.art-frame.v5-glass,
.wh-plate.v5-glass,
.diag-band.v5-glass, .diag-band { background: radial-gradient(126% 118% at 22% 8%, color-mix(in oklab, var(--accent) 16%, color-mix(in oklab, var(--v5-paper) 82%, transparent)) 0%, color-mix(in oklab, var(--brand-teal) 13%, color-mix(in oklab, var(--v5-paper) 78%, transparent)) 54%, color-mix(in oklab, var(--accent) 9%, color-mix(in oklab, var(--v5-paper) 46%, transparent)) 100%); border-color: color-mix(in oklab, var(--accent) 24%, var(--v5-glass-line)); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .80), var(--v5-glass-lift); }
[data-theme="dark"] .art-frame.v5-glass,
[data-theme="dark"] .wh-plate.v5-glass,
[data-theme="dark"] .diag-band.v5-glass, [data-theme="dark"] .diag-band { background: radial-gradient(126% 118% at 22% 8%, color-mix(in oklab, var(--accent) 22%, color-mix(in oklab, var(--v5-paper) 76%, transparent)) 0%, color-mix(in oklab, var(--brand-teal) 18%, color-mix(in oklab, var(--v5-paper) 70%, transparent)) 54%, color-mix(in oklab, var(--accent) 12%, color-mix(in oklab, var(--v5-paper) 40%, transparent)) 100%); border-color: color-mix(in oklab, var(--accent) 30%, var(--v5-glass-line)); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), var(--v5-glass-lift); }
.wh-lens label { background: color-mix(in oklab, var(--v5-paper) 74%, transparent); }
[data-theme="dark"] .wh-lens label { background: color-mix(in oklab, var(--v5-paper) 46%, transparent); }
@media (forced-colors: active) {
  .art-frame.v5-glass, .wh-plate.v5-glass, .diag-band { background: Canvas; box-shadow: none; border-color: CanvasText; }
  .wh-lens label { background: Canvas; }
}
@media (max-width: 620px) {
  .wh-map { grid-template-columns: minmax(0, 1fr); }
  .wh-fam, .wh-fam.f1, .wh-fam.f2, .wh-fam.f3, .wh-fam.f4, .wh-fam.f5 { grid-column: 1 / -1; }
  .wh-fam .wh-roles { column-count: 2; column-gap: 18px; }
}
@media (max-width: 380px) {
  .wh-fam .wh-roles { column-count: 1; }
}
@media (hover: none) and (pointer: coarse) {
  .wh-lens label { min-height: 44px; display: inline-flex; align-items: center; }
}
@media (max-width: 700px) {
  .wh-lens { -webkit-mask-image: linear-gradient(90deg, #000 0, #000 84%, transparent 100%); mask-image: linear-gradient(90deg, #000 0, #000 84%, transparent 100%); padding-right: 14px; }
}

/* ============================================================
   18.  LOGO WALL — обратно в бегущую строку (п.4 дока)
   «Всё-таки пустить бегущей строкой и поменьше знаки, а то смотрится
    чётными пятнами.»
   ⚠️ Это отменяет более раннее «всё бегущее бесит» — решение свежее и
   принято командой в сводном документе, поэтому исполняется. Смягчения,
   которые оставляю по умолчанию: лента останавливается при наведении и
   при фокусе с клавиатуры, полностью выключается при prefers-reduced-motion
   и на тач-устройствах (там она просто листается пальцем).
   ============================================================ */
.trusted .logo-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.trusted .logo-marquee-track {
  display: flex; align-items: center;
  width: max-content;
  grid-template-columns: none;
  gap: 56px;
  animation: lw-scroll 64s linear infinite;
}
.trusted .logo-marquee:hover .logo-marquee-track,
.trusted .logo-marquee:focus-within .logo-marquee-track { animation-play-state: paused; }
@keyframes lw-scroll { from { transform: translate3d(0,0,0); } to { transform: translate3d(-50%,0,0); } }

/* дубликаты снова нужны — ими и замыкается петля */
.trusted .logo-marquee-track img[aria-hidden="true"] { display: block; }

/* «поменьше знаки»: 52 → 38px по высоте, ширина падает пропорционально */
.trusted .logo-marquee-track img {
  flex: 0 0 auto; width: auto;
  max-width: min(112px, 100%); height: auto; max-height: 38px;
  opacity: .78; filter: grayscale(1);
  transition: filter .18s ease, opacity .18s ease;
}
.trusted .logo-marquee-track img:hover { opacity: 1; filter: none; }
[data-theme="dark"] .trusted .logo-marquee-track img { filter: grayscale(1) invert(1); opacity: .85; }
[data-theme="dark"] .trusted .logo-marquee-track img:hover { filter: none; opacity: 1; }

@media (max-width: 640px) {
  .trusted .logo-marquee-track { gap: 36px; }
  .trusted .logo-marquee-track img { max-width: min(92px, 100%); max-height: 32px; }
}
/* Лента бежит и на телефоне — Наталья смотрит с телефона и ждёт её там
   (14.08: «пропала бегущая строка»). Пальцем её можно остановить и
   полистать; отпустил — побежала дальше. Останавливается насовсем только
   при системной настройке «меньше движения». */
@media (hover: none) and (pointer: coarse) {
  .trusted .logo-marquee { overflow-x: auto; scrollbar-width: none; }
  .trusted .logo-marquee::-webkit-scrollbar { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .trusted .logo-marquee { overflow-x: auto; }
  .trusted .logo-marquee-track { animation: none; }
}
@media (forced-colors: active) { .trusted .logo-marquee-track { animation: none; } }

/* ============================================================
   19.  HEADER LOCKUP — один шрифт, один цвет (п.1 дока)
   «Шрифт NGRS рядом с лого выбивается из остального текста — нужно
    привести всё к одному шрифту. И убрать два цвета.»
   Было: NGRS — Inter 600 / 18px / трекинг 1.08px / цвет --fg, а
   расшифровка — Inter 400 / 10.5px / цвет --fg-3. Два разных цвета и
   разительно разный трекинг и читались как «другой шрифт».
   Стало: обе строки в ОДНОМ цвете (--fg) и с трекингом навигации;
   различаются только кеглем, как строчки одного набора.
   ============================================================ */
.brand-lockup .brand-word {
  font: 500 18px/1.15 var(--font-sans);
  letter-spacing: .01em;
  color: var(--fg);
}
.brand-lockup .brand-expansion {
  font: 400 13px/1.25 var(--font-sans);   /* не ниже общего порога читаемости 13px */
  letter-spacing: .01em;
  color: var(--fg);          /* один цвет на весь лок-ап */
  opacity: .68;              /* тише по весу, но НЕ второй краской */
  margin-top: 2px;
}
[data-theme="dark"] .brand-lockup .brand-word,
[data-theme="dark"] .brand-lockup .brand-expansion { color: var(--fg); }
@media (forced-colors: active) {
  .brand-lockup .brand-word, .brand-lockup .brand-expansion { color: CanvasText; opacity: 1; }
}

/* полосы позади сборки (п.1 дока: «включить наши полосы сзади») —
   тот же волосок, что у фоновых линий страницы, но внутри рамки */
.hero-art-svg .bg-stripes path {
  stroke: color-mix(in oklab, var(--accent) 28%, transparent);
  stroke-width: 1.1;
}
[data-theme="dark"] .hero-art-svg .bg-stripes path {
  stroke: color-mix(in oklab, var(--accent) 34%, transparent);
}
/* знак NGRS на верхней грани янтарной детали */
/* знак напечатан на грани: монохром, чтобы не спорить с цветом грани */
.hero-art-svg .logo-face { opacity: .82; }
[data-theme="dark"] .hero-art-svg .logo-face { opacity: .74; }
@media (forced-colors: active) { .hero-art-svg .bg-stripes, .hero-art-svg .logo-face { display: none; } }

/* ============================================================
   20.  WE HIRE — свёрнутый указатель (правка оператора 13.08:
   «требует двух-трёх страниц, нужны сворачивающиеся списки и оставлять
    только то что в фокусе внимания, длинные вертикальные списки надо
    переделывать»)

   Было: 96 ролей в 8 группах РАЗОМ — три экрана вертикальных списков.
   Стало: на экране всегда ОДНА группа. Переключатель со счётчиками
   держит охват на виду («18» рядом с Markets & Trading говорит о широте
   не хуже, чем сами 18 строк), а роли внутри группы текут в 4 колонки —
   максимум 5 строк вниз вместо восемнадцати.
   Итог по высоте: было ~2600px, стало ~330px — блок влезает в один экран.

   Все 96 ролей остаются в разметке: скрытые панели вырезаны из отрисовки,
   но не из HTML, поэтому поисковики и ИИ-краулеры читают полный список.
   Механика — те же радиокнопки, что и раньше: работает без JS, с клавиатуры
   и со скринридером.
   ============================================================ */
.wh-summary {
  margin: 0 0 14px; font: 400 14.5px/1.5 var(--font-sans); color: var(--fg-2);
}
.wh-lens {
  display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px;
  overflow: visible;                      /* больше не «уезжающая» лента */
  -webkit-mask-image: none; mask-image: none;
}
.wh-lens label {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 9px 14px; border: 1px solid var(--line); border-radius: 999px;
  font: 500 14px/1.2 var(--font-sans); color: var(--fg-2);
  cursor: pointer; background: var(--bg-2);
  transition: border-color .18s ease, color .18s ease, background-color .18s ease;
}
.wh-lens label:hover { border-color: var(--fg-3); color: var(--fg); }
.wh-chip-n {
  font-variant-numeric: tabular-nums; font-size: 12.5px; color: var(--fg-3);
}
.wh-sr:checked + label {
  background: color-mix(in oklab, var(--accent) 12%, var(--bg-2));
  border-color: var(--accent); color: var(--fg);
}
.wh-sr:checked + label .wh-chip-n { color: var(--accent); }
.wh-sr:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ровно одна панель на экране */
.wh-map { display: block; }
.wh-panel { display: none; }
.wh-plate:has(#wh-f1:checked) .p1, .wh-plate:has(#wh-f2:checked) .p2,
.wh-plate:has(#wh-f3:checked) .p3, .wh-plate:has(#wh-f4:checked) .p4,
.wh-plate:has(#wh-f5:checked) .p5, .wh-plate:has(#wh-f6:checked) .p6,
.wh-plate:has(#wh-f7:checked) .p7, .wh-plate:has(#wh-f8:checked) .p8 { display: block; }
/* браузеры без :has() показывают все панели — блок просто разворачивается
   в полный указатель, ничего не пропадает */
@supports not selector(:has(*)) { .wh-panel { display: block; } }

/* роли текут в колонки — горизонтально, а не одной длинной вертикалью */
.wh-panel .wh-roles {
  columns: 4; column-gap: 32px; column-rule: 1px solid var(--line);
  margin: 0; padding: 0; list-style: none;
}
.wh-panel .wh-roles li {
  break-inside: avoid; -webkit-column-break-inside: avoid;
  margin: 0; padding: 5px 0;
  font: 400 15.5px/1.45 var(--font-serif); color: var(--fg);
  border: 0;
}
.wh-panel .wh-roles li::before { content: none; }

@media (max-width: 900px) { .wh-panel .wh-roles { columns: 3; column-gap: 26px; } }
/* Телефон: восемь чипов в перенос давали 346px одних только кнопок —
   больше, чем сам список. Возвращаем горизонтальную ленту с затуханием:
   одна строка вместо семи, охват виден по счётчикам при прокрутке. */
@media (max-width: 640px) {
  .wh-summary { font-size: 14px; }
  .wh-lens {
    flex-wrap: nowrap; gap: 6px;
    overflow-x: auto; scrollbar-width: none;
    padding-right: 14px; margin-bottom: 16px;
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 86%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 0, #000 86%, transparent 100%);
  }
  .wh-lens::-webkit-scrollbar { display: none; }
  .wh-lens label { flex: 0 0 auto; padding: 10px 12px; font-size: 13.5px; min-height: 44px; }
  .wh-panel .wh-roles { columns: 2; column-gap: 18px; }
  .wh-panel .wh-roles li { font-size: 15px; padding: 4px 0; }
}
@media (max-width: 340px) { .wh-panel .wh-roles { columns: 1; column-rule: 0; } }
@media (forced-colors: active) {
  .wh-lens label { background: Canvas; border-color: CanvasText; color: CanvasText; }
  .wh-sr:checked + label { background: Highlight; color: HighlightText; border-color: Highlight; }
  .wh-panel .wh-roles li { color: CanvasText; }
}


/* ============================================================
   ПУБЛИКАЦИЯ 24.08: боевое меню из 8 пунктов вместо 4 у превью.
   Знак с расшифровкой шире прежнего слова NGRS примерно на 190px,
   поэтому на средних экранах расшифровка убирается, а отступы меню
   сжимаются — иначе меню наезжает на кнопку «Build my team».
   ============================================================ */
/* Карточки в ряду перестали «съезжать».
   Причина простая: у соседей по ряду заголовок то в одну строку, то в две,
   и всё, что под ним, встаёт на разной высоте — ряд читается как кривой.
   Замер по всем страницам: заголовков в три строки нет нигде, максимум две.
   Поэтому достаточно пола в две строки (`2lh` — ровно две строки текущего
   межстрочного, а не подобранные пиксели). Одна колонка на телефоне этого
   не требует: там карточки идут друг под другом.
   Это давняя особенность вёрстки, не следствие публикации: в копии сайта ДО
   неё таких мест было 17, после — 14. */
@media (min-width: 821px) {
  .start-grid h3, .modules h3, .roles-grid h3, .versus h3,
  .cases-grid h3, .posts h3, .howit-grid h3,
  .funnel-col-head h3 { min-height: 2lh; }
  /* подзаголовок в шапке воронки тоже бывает и в одну, и в две строки */
  .funnel-col-head .sub { min-height: 2lh; }

  /* Где карточки устроены одинаково, строки связываются по-настоящему:
     высота каждой строки — максимум по ряду, лишнего воздуха не появляется.
     `.cases-grid` берёт шесть строк: у части карточек нет ссылки-стрелки,
     последняя строка у них просто остаётся пустой. */
  /* Число блоков в карточке разное: на внутренних страницах три,
     на главной четыре (там ещё иконка). Поэтому не фиксированное число,
     а по факту: если хоть у одной карточки есть четвёртый блок — вся сетка
     работает на четырёх строках. Иначе четвёртый блок выпадал из связки
     и главная разъезжалась сильнее прежнего (проверено: 27px). */
  /* Селекторы с id (#why-ngrs .result-card { display: block }) сильнее
     обычного класса, поэтому карточка на главной оставалась блоком и в связку
     не входила — замер показывал те же 27px. Своя пара с id это выравнивает. */
  .results-grid { grid-template-rows: repeat(3, auto); }
  .results-grid > *,
  #why-ngrs .results-grid > *,
  #results .results-grid > * { display: grid; grid-row: span 3; grid-template-rows: subgrid; }
  .results-grid:has(> * > :nth-child(4)) { grid-template-rows: repeat(4, auto); }
  .results-grid:has(> * > :nth-child(4)) > *,
  #why-ngrs .results-grid:has(> * > :nth-child(4)) > * { grid-row: span 4; }
  .cases-grid { grid-template-rows: repeat(6, auto); }
  .cases-grid > li { display: grid; grid-row: span 6; grid-template-rows: subgrid; }
}

/* Две колонки воронки на /method/ выровнены строка в строку.
   До публикации они совпадали случайно: заголовки обеих колонок вставали в две
   строки. Новая типографика сделала левый заголовок однострочным, и вся правая
   колонка уехала вниз на 44px — сравнивать этапы стало нельзя.
   Подпирать высотой шапки нельзя: при любой правке текста поедет снова.
   Обе колонки состоят из одинаковых 12 блоков (проверено), поэтому строки
   связываются по-настоящему через subgrid — совпадёт и шапка, и каждый этап,
   и каждая строка отсева. Только там, где колонок две: ниже 800px они
   складываются в одну и связывать нечего — точка перелома у самой страницы
   стоит на 820px, её и берём. */
@media (min-width: 821px) {
  .funnel-wrap { grid-template-rows: repeat(12, auto); align-items: start; }
  .funnel-col { display: grid; grid-row: span 12; grid-template-rows: subgrid; }
}

/* Футер стал на одну колонку шире: из шапки туда переехали разделы, и
   четвёртая колонка при сетке из трёх переносилась на второй ряд — ряд из
   одной колонки выглядит как ошибка. Разбивка по ширине:
   четыре колонки на десктопе, две на планшете, одна на телефоне. */
/* Блок с названием занимал 1.4fr из 3.4 — на четыре колонки оставалось
   по 120px, и восемь ссылок ломались на две строки. Ему хватает 300px. */
@media (min-width: 1024px) {
  .footer-top { grid-template-columns: minmax(240px, 300px) 1fr; }
}
/* Колонки футера — ПО СОДЕРЖИМОМУ, а не равными долями.
   Замер: самой длинной подписи («Everything's on fire») нужно 147px, а при
   пяти равных колонках на каждую приходится 121px — подпись переносилась на
   вторую строку, и весь столбец съезжал относительно соседних. Суммарно всем
   пяти колонкам нужно 628px, свободно 700px, поэтому `auto` раздаёт каждой
   ровно её ширину, а остаток уходит в промежутки (`space-between`).
   Так же это лечится на будущее: длинная подпись расширит свою колонку, а не
   сломает ряд. Если однажды сумма перестанет влезать — колонки начнут
   переносить текст, но не выедут за край. */
.footer-cols { grid-template-columns: repeat(5, auto); justify-content: space-between; gap: 32px 20px; }
@media (max-width: 1099px) { .footer-cols { grid-template-columns: repeat(3, minmax(0,1fr)); gap: 30px 28px; } }
@media (max-width: 1023px) { .footer-cols { grid-template-columns: repeat(2, minmax(0,1fr)); gap: 28px 32px; } }
@media (max-width: 520px)  { .footer-cols { grid-template-columns: 1fr; gap: 22px; } }

/* Главная кнопка — жёлтая «таблетка» на всём сайте.
   В v4 жёлтой сделана только кнопка в шапке (.site-header .btn-primary).
   После публикации это дало разнобой: в шапке кнопка жёлтая, а на внутренних
   страницах главные кнопки остались синими — сайт читался как наполовину
   перекрашенный. Контраст жёлтой пары измерен в v4: 7,05:1 в светлой теме,
   8,27:1 в тёмной, то есть выше требования AA.
   Если команда захочет вернуть синие кнопки на внутренних страницах — это
   ровно этот блок, удаляется целиком. */
.btn-primary { background: var(--accent-3); border-color: transparent;
  color: #2A2D34; font-weight: 600; border-radius: 999px; }
.btn-primary:hover { background: color-mix(in oklab, var(--accent-3) 87%, #1E222B);
  border-color: transparent; color: #2A2D34; }

/* Шапка при восьми пунктах вместо четырёх.
   Первый заход был неверным: меню получило `flex: 0 1 auto; min-width: 0`, и
   оно стало сжиматься МЕНЬШЕ своего содержимого. Пункты с `white-space: nowrap`
   при этом не сжимаются — они просто вылезли за рамку меню и легли поверх
   переключателя темы и кнопки. Замер по границам самого меню этого не видел
   («зазор 70px»), потому что рамка была уже содержимого; проверять надо правый
   край ПОСЛЕДНЕГО ПУНКТА против левого края правого блока — так и сделано в
   fit_nav.py.
   Поэтому сжиматься не может никто, а помещается всё за счёт отступов между
   пунктами, подобранных по ширине экрана. Замер: зазор не меньше 24px на всех
   ширинах от 861 до 1920. */
.site-header .brand-lockup,
.site-header .header-actions,
.site-header .primary-nav { flex: 0 0 auto; }
.site-header .header-actions .btn-primary { white-space: nowrap; }

@media (min-width: 861px) and (max-width: 1279px) {
  .site-header .brand-lockup .brand-expansion { display: none; }
}
@media (min-width: 861px) and (max-width: 1023px) {
  .site-header .primary-nav { gap: 22px; font-size: 14px; }
}
/* Шире 1024 отступ дальше не растёт: строка шапки ограничена 1120px и на
   1920 не становится шире, чем на 1440 — запас один и тот же. В него должны
   влезть знак с расшифровкой (279px), восемь пунктов и правый блок (185px).
   При отступе 24px кнопка выезжала за рамку на 42px.
   🔴 Первый замер этого не поймал, потому что мерил ДО загрузки шрифтов:
   системный запасной шрифт уже, чем Inter, и всё «помещалось» ровно до
   подмены шрифта. Теперь проверка ждёт document.fonts.ready. */
@media (min-width: 1024px) {
  .site-header .primary-nav { gap: 34px; font-size: 14.5px; }
}


/* ============================================================
   МОБИЛЬНАЯ ДОВОДКА 24.08 — площадь нажатия.
   Замер на телефоне (is_mobile=true) нашёл 48 целей меньше 44px.
   Правила по контейнерам, а не общим правилом на все ссылки:
   ссылка внутри абзаца из требования выведена (WCAG 2.5.8), и
   раздувать её нельзя — поедет типографика текста.
   ============================================================ */
@media (hover: none) and (pointer: coarse) {
  /* фильтры и вкладки: были 40-41px */
  nav.tags a, nav.tabs a,
  .task-presets button {
    min-height: 44px; display: inline-flex; align-items: center;
  }
  /* стрелочные ссылки и «назад к колонкам»: были 13-14px */
  a.link-arrow, a.col-back, a.col-link,
  .plat-grid a {
    min-height: 44px; display: inline-flex; align-items: center;
  }
}

@media (hover: none) and (pointer: coarse) {
  /* фильтры кейсов и кнопки быстрых ответов в чате — были 41 и 34px */
  nav.cases-filters a, .chat-actions button {
    min-height: 44px; display: inline-flex; align-items: center;
  }
}

/* ============================================================
   МОБИЛЬНЫЙ ПРЕДЕЛ ШРИФТА — то, что задано в общих таблицах стилей.
   Замер нашёл 653 места мельче 13px; сам слой v4 убрал 40%, страницы
   свои правила поправили, здесь закрывается остаток из ngrs.css и
   ngrs-v4.css. Только до 860px: десктоп команда утвердила как есть.
   ============================================================ */
@media (max-width: 860px) {
  .primary-nav .ext,
  .eyebrow, .section-label, .section-eyebrow,
  .result-card-tag,
  .footer-col h3, .footer-col h4, .footer-bottom,
  .hero-stats li, .hero-roles-label, .wh-chip-n,
  #why-ngrs .result-card .num,
  .brand-lockup .brand-expansion,
  .task-presets span,
  table th, table td, table th span, table td span {
    font-size: 13px;
  }
}

/* ============================================================
   МОБИЛЬНАЯ ШАПКА. Правило «никто не сжимается» чинит десктоп, но на
   телефоне оно же запрещало кнопке сжиматься — и «Build my team»
   уезжала за правый край: на 375 на 8px, на 320 на 63px. Ни старая
   шапка, ни превью v4 так не ломались, потому что там кнопка сжималась
   (и рвалась на три строки — это тоже чинится здесь).
   Значения подобраны замером (fit_header.py): кнопка одной строкой на
   всех ширинах от 320 до 560, бургер и переключатель темы остаются
   44px, второй ряд шапке не добавляется — иначе уехал бы вниз первый
   экран, который клиент утвердил отдельно.
   ============================================================ */
@media (max-width: 560px) {
  .site-header .header-row { gap: 10px; }
  .site-header .header-actions { gap: 8px; }
  .site-header .header-actions .btn-primary { padding: 0 11px; font-size: 13.5px; }
  .site-header .brand-lockup { gap: 7px; }
  .site-header .brand-mark { width: 26px; }
  .site-header .brand-word { font-size: 16px; }
}
@media (max-width: 370px) {
  .site-header .header-row { gap: 8px; padding-left: 12px; padding-right: 12px; }
  .site-header .header-actions { gap: 6px; }
  .site-header .brand-mark { width: 24px; }
}

/* Точки слайдера цитат: полоска 24x4 нажимается только прицельно.
   Запас даётся невидимым ::after, а не размером самой полоски —
   иначе поехал бы ряд точек под слайдером. */
.qs-dot { position: relative; }
.qs-dot::after {
  content: ""; position: absolute;
  left: -7px; right: -7px; top: -20px; bottom: -20px;
}


/* ============================================================
   Предел 13px там, где размер задан атрибутом style прямо в разметке.
   Атрибут сильнее любого селектора, поэтому здесь единственное место
   во всём слое, где уместен !important — и он ограничен одним классом
   и экранами до 860px.
   ============================================================ */
@media (max-width: 860px) {
  .fs-floor { font-size: 13px !important; }
}


/* ============================================================
   ТАБЛИЦЫ НА ТЕЛЕФОНЕ. Три колонки на 375px превращают ячейку в
   столбик по два слова; читать это невозможно. Таблица получает
   минимальную ширину и едет вбок внутри своей рамки — так же, как
   уже устроена таблица на /same-time-zone-squad/.
   Тень справа — подсказка, что там есть продолжение: без неё
   горизонтальную прокрутку внутри страницы просто не замечают.
   ============================================================ */
.tbl-scroll { position: relative; }
@media (max-width: 860px) {
  .tbl-scroll {
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
  }
  .tbl-scroll > table { min-width: 620px; }
  /* Подсказка «есть продолжение». Абсолютный псевдоэлемент внутри скроллера
     ненадёжен — он едет вместе с содержимым. Здесь работает приём на четырёх
     фонах: две «шторки» с `local` прокручиваются вместе с таблицей, две тени
     с обычным `scroll` стоят у краёв. Пока таблица прокручена не до конца,
     шторка отъехала и тень видна; у края шторка её закрывает. Ячейки таблицы
     прозрачные — проверено, поэтому фон контейнера сквозь них виден. */
  .tbl-scroll {
    background-color: var(--bg);
    background-image:
      linear-gradient(to right, var(--bg) 40%, rgba(0,0,0,0)),
      linear-gradient(to left,  var(--bg) 40%, rgba(0,0,0,0)),
      radial-gradient(farthest-side at 0 50%,   rgba(0,0,0,.16), rgba(0,0,0,0)),
      radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.16), rgba(0,0,0,0));
    background-position: left center, right center, left center, right center;
    background-size: 30px 100%, 30px 100%, 15px 100%, 15px 100%;
    background-repeat: no-repeat;
    background-attachment: local, local, scroll, scroll;
  }
  .bench-wrap, .cost-table-wrap { overflow-x: auto; }
}
