/* Factri Uptime landing (F292 redesign; F293 brought it into the company's look).
   Design language: paper white, industrial blue, one signature object (the
   safety-yellow laminated QR tag). Inter throughout, one family, the same face
   the product app ships. Restraint everywhere else. */

/* Typefaces. All three are under the SIL Open Font License 1.1, which requires
   the copyright notice and the licence to travel with the font. One licence file
   per family ships beside the fonts, each carrying its own upstream notice:

     fonts/OFL-Inter.txt
       Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter)
     fonts/OFL-Noto-Devanagari.txt
       Copyright 2022 The Noto Project Authors (https://github.com/notofonts/devanagari)
     fonts/OFL-Noto-Tamil.txt
       Copyright 2022 The Noto Project Authors (https://github.com/notofonts/tamil)

   The three notices above are copied verbatim from each font's own `name` table
   (ID 0). The two Noto files hold the identical OFL 1.1 body and differ ONLY in
   that first copyright line — they are kept separate anyway, because one shared
   file would carry a single family's notice and silently misattribute the other,
   which is the specific thing the licence asks you not to do. */
@font-face {
  font-family: "Inter";
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/inter-latin-var.woff2") format("woff2");
}
/* The two Indic faces. `unicode-range` is load-bearing, not tidiness: a
   unicode-range fetch is lazy, so a browser downloads one of these only once a
   character inside its range is actually laid out. That is what stops this page,
   which contains no Tamil at all, from ever fetching the 50 KB Tamil face — and
   it is why the 121 KB Devanagari face IS fetched here, because the hero sticker
   really does say मशीन बंद?. The ranges are Google Fonts' own subset ranges for
   exactly the files in fonts/; do not narrow them by hand. */
@font-face {
  font-family: "Noto Sans Devanagari";
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/noto-sans-devanagari-var.woff2") format("woff2");
  unicode-range: U+0900-097F, U+1CD0-1CF9, U+200C-200D, U+20A8, U+20B9, U+20F0,
    U+25CC, U+A830-A839, U+A8E0-A8FF, U+11B00-11B09;
}
@font-face {
  font-family: "Noto Sans Tamil";
  font-weight: 100 900;
  font-display: swap;
  src: url("fonts/noto-sans-tamil-var.woff2") format("woff2");
  unicode-range: U+0964-0965, U+0B82-0BFA, U+200C-200D, U+20B9, U+25CC;
}

:root {
  --paper: #ffffff;
  --band: #f4f6f8;
  --ink: #171b20;
  --ink2: #545e68;
  --hair: #e3e7eb;
  --blue: #1d4ed8;
  --blue-dark: #1e40af;
  --yellow: #ffc72c;
  --yellow-edge: #e0a900;
  /* All three type tokens deliberately alias Inter: one typeface everywhere, as
     the app and factri.ai do. --mono is kept as a NAME for the label/spec voice
     (uppercase + tracking now carry it) so its call sites stay findable. Do not
     "fix" it back to a monospace face.

     Inter stays FIRST and the Noto faces sit behind it, and that order is the
     whole mechanism. The two Noto files carry no Latin glyphs at all, so a
     browser falls through the stack PER GLYPH: "Factri Uptime" inside a Hindi
     sentence keeps Inter, and the Hindi around it gets Noto, with no extra rule
     and nothing scoped by lang. Put a Noto family first and every Latin letter
     on the page would move. The seam is invisible because it only ever falls on
     a script boundary, and because Inter and Noto Sans are both low-contrast
     grotesques of near-identical colour. */
  --display: "Inter", "Noto Sans Devanagari", "Noto Sans Tamil", system-ui, sans-serif;
  --mono: "Inter", "Noto Sans Devanagari", "Noto Sans Tamil", system-ui, sans-serif;
  --body: "Inter", "Noto Sans Devanagari", "Noto Sans Tamil", system-ui, -apple-system, "Segoe UI", Roboto, "Noto Sans", sans-serif;
}

* { box-sizing: border-box; }
/* scroll-padding is the sticky header's companion: without it every in-page
   anchor (#how, #get, #audit, #pricing) lands with its heading under the bar. */
html { scroll-behavior: smooth; scroll-padding-top: 65px; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
:focus-visible { outline: 3px solid var(--blue); outline-offset: 2px; border-radius: 6px; }

.wrap { max-width: 1140px; margin-inline: auto; padding-inline: 28px; }

.eyebrow {
  font-family: var(--mono);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--blue);
  margin: 0 0 14px;
}

h2 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -0.02em;
  font-size: clamp(1.5rem, 2.6vw, 1.8rem);
  line-height: 1.15;
  margin: 0 0 14px;
  text-wrap: balance;
}
.section-intro {
  color: var(--ink2);
  max-width: 58ch;
  margin: 0 0 36px;
  text-wrap: pretty;
}

.btn {
  display: inline-block;
  font-family: var(--display);
  font-weight: 600;
  font-size: 15.5px;
  padding: 11px 20px;
  border-radius: 8px;
  text-decoration: none;
  background: var(--blue);
  color: #fff;
  /* factri.ai's CTAs are flat fills with no outline. The transparent border is
     kept so the box size does not shift. */
  border: 1px solid transparent;
  white-space: nowrap;
}
.btn:hover { background: var(--blue-dark); }
.btn--big { font-size: 17.5px; padding: 15px 28px; }

/* ---------- header ----------
   Built to factri.ai's own measurements (tasks/f293-header-measure.mjs): 57px
   bar, sticky at top 0, white, one hairline below, no shadow, 40px logo, 18px/600
   nav links in #374151, 14px/600 CTA at 12px 32px on a 12px radius.
   ONE deliberate deviation: factri.ai's header sits in a 1280px container and
   ours stays at .wrap's 1140px, because every section below the header uses
   .wrap. Copying 1280px here would hang the logo and CTA outside the content
   column beneath them. Proportions are matched; the container width is not. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--paper);
  border-bottom: 1px solid var(--hair);
}
.nav { display: flex; align-items: center; height: 57px; gap: 28px; }
.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; flex: none; }
.brand-logo { height: 40px; width: auto; flex: none; }
.brand-rule { width: 1px; height: 24px; background: var(--hair); flex: none; }
.brand-name {
  font-family: var(--display);
  font-weight: 600;
  font-size: 19px;
  letter-spacing: -0.01em;
  color: var(--ink);
}
/* the logo already ends in a blue "AI"; a blue "Uptime" straight after it would
   read as one wordmark ("AI Uptime"), so the word stays ink. */
/* The nav sits on the RIGHT of the bar, as factri.ai's does, so `margin-left: auto`
   belongs to .links; the CTA then follows it at the .nav gap (28px, against
   factri.ai's measured ~27px CSS between its last link and its CTA).
   🔴 .cta-side must be reset to 0 here: two `auto` left margins in one flex row
   share the free space and CENTRE the nav instead of pushing it right. The
   880px block below puts the CTA's own push back for when .links is hidden. */
.links { display: flex; gap: 24px; margin-left: auto; font-size: 18px; font-weight: 600; color: #374151; }
.links a { text-decoration: none; }
.links a:hover { color: var(--ink); }
.nav .cta-side { margin-left: 0; }
.nav .btn {
  font-size: 14px;
  /* factri.ai's bar CTA measures 40px tall with the label inset 12px from the
     box edge. .btn carries a 1px transparent border, so 11px of padding plus
     that border is the same 12px inset and 11 + 16 + 11 + 2 = 40px exactly. */
  padding: 11px 32px;
  line-height: 16px;
  border-radius: 12px;
}

/* ---------- hero ---------- */
.hero { padding: 44px 0 56px; }
.hero-grid {
  display: grid;
  grid-template-columns: 1.12fr 0.88fr;
  column-gap: 48px;
  align-items: center;
}

h1 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -0.025em;
  font-size: clamp(2.1rem, 4.5vw, 3.1rem);
  line-height: 1.08;
  margin: 0;
  text-wrap: balance;
}
/* Two-tone headline, the same idea factri.ai uses on its own h1: the second
   phrase in a left-to-right blue-700 -> blue-600 gradient clipped to the text.
   The flat colour is the FALLBACK and is declared outside the @supports, so a
   browser without background-clip:text shows blue text, never invisible text.
   Both stops pass WCAG on white at large-text scale (#1d4ed8 6.70, #2563eb 5.17). */
/* `display: block` puts the colour boundary on a LINE boundary at every width.
   Left inline, the phrase's first word ("let") trails the ink line at 320-410px
   and again at 1030-1100px, which reads as a rendering accident rather than a
   colour choice. Top level, deliberately NOT inside a media query: scoped to
   560px it would leave the 1030-1100px band (laptops, iPad landscape) broken.
   text-wrap: balance then balances the two blocks independently. */
h1 .accent { display: block; color: var(--blue); }
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  h1 .accent {
    background-image: linear-gradient(to right, #1d4ed8, #2563eb);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
  }
}
/* The spec strip. In the monospace face it used to carry, its character came from
   the typeface; in Inter it has to come from case and tracking, or it reads as
   fine print on the first screen everyone sees. 11.5px/0.045em is measured, not chosen: T1 prescribed
   12.5px/0.05em, which needs 626px in a 580px column and wraps with "· AUDIT
   RECORDS" orphaned. See tasks/f293-specline-fit.mjs. */
.hero-covers {
  font-family: var(--mono);
  font-weight: 600;
  font-size: 11.5px;
  text-transform: uppercase;
  text-wrap: balance;
  letter-spacing: 0.045em;
  color: var(--ink2);
  margin: 18px 0 0;
}
.hero-covers span { white-space: nowrap; }
.sub {
  font-size: 1.15rem;
  color: var(--ink2);
  max-width: 50ch;
  margin: 18px 0 0;
  text-wrap: pretty;
}
.cta-row { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; margin-top: 28px; }
.cta-note { font-size: 14.5px; color: var(--ink2); margin: 0; }
.lang-line { margin: 24px 0 0; font-size: 14.5px; color: var(--ink2); max-width: 52ch; }
.lang-line strong { color: var(--ink); font-weight: 600; }

/* ---------- the sticker + phone scene ---------- */
.scene { display: flex; justify-content: center; }
.scene-inner { position: relative; }

.phone {
  width: 216px;
  margin-left: 128px;
  border: 8px solid #1b2026;
  border-radius: 28px;
  overflow: hidden;
  background: #1b2026;
  box-shadow: 0 30px 55px -28px rgba(23, 32, 44, 0.5);
}
.phone img { width: 100%; height: auto; }

.sticker {
  position: absolute;
  left: 0;
  bottom: -44px;
  width: 144px;
  transform: rotate(-4deg);
  background: linear-gradient(168deg, #ffd257 0%, var(--yellow) 38%, #f5b90f 100%);
  border: 1px solid var(--yellow-edge);
  border-radius: 12px;
  box-shadow: 0 18px 34px -16px rgba(90, 62, 0, 0.45), 0 2px 5px rgba(90, 62, 0, 0.18);
  padding: 0 0 12px;
  overflow: hidden;
}
.sticker::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(115deg, rgba(255, 255, 255, 0.35) 0%, rgba(255, 255, 255, 0) 28%);
}
.sticker-tag {
  background: #171b20;
  color: #ffd257;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 8px;
  letter-spacing: 0.04em;
  padding: 6px 8px;
  white-space: nowrap;
}
.sticker-body { padding: 9px 11px 0; text-align: center; }
.sticker-hi { font-weight: 700; font-size: 14.5px; line-height: 1.3; margin: 0; font-family: var(--body); }
.sticker-en { font-family: var(--display); font-weight: 700; font-size: 11px; margin: 3px 0 8px; color: #4a3800; }
.qr-box {
  background: #fff;
  border-radius: 8px;
  width: 88px;
  margin: 0 auto;
  padding: 7px;
  border: 1px solid rgba(90, 62, 0, 0.15);
}
.qr-box svg { display: block; width: 100%; height: auto; shape-rendering: crispEdges; }
.sticker-foot {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 9px;
  letter-spacing: 0.1em;
  color: #4a3800;
  margin: 8px 0 0;
  text-align: center;
}
.scene-caption {
  margin: 60px auto 0;
  max-width: 42ch;
  text-align: center;
  font-size: 14.5px;
  color: var(--ink2);
}

/* ---------- generic section rhythm ---------- */
.section { padding: 68px 0 72px; }
.section--band { background: var(--band); border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair); }

/* ---------- how it works ---------- */
.steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 36px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.steps li { border-top: 3px solid var(--blue); padding-top: 16px; }
.step-num {
  font-family: var(--mono);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.09em;
  color: var(--blue);
  text-transform: uppercase;
  display: block;
  margin-bottom: 8px;
}
.steps h3 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 18.5px;
  letter-spacing: -0.01em;
  margin: 0 0 8px;
}
.steps p { margin: 0; font-size: 15.5px; color: var(--ink2); }

/* browser-framed screenshots */
.shot { margin: 48px 0 0; }
.browser {
  border: 1px solid var(--hair);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 24px 48px -30px rgba(23, 32, 44, 0.35);
}
.browser-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 12px;
  background: #eef1f4;
  border-bottom: 1px solid var(--hair);
}
.browser-bar i {
  width: 9px; height: 9px; border-radius: 50%;
  background: #cfd6dc; display: block;
}
.shot-caption {
  margin: 14px auto 0;
  max-width: 68ch;
  text-align: center;
  font-size: 14.5px;
  color: var(--ink2);
}

/* ---------- what you get: spotlight rows ---------- */
.spotlights { margin: 72px 0 0; display: flex; flex-direction: column; gap: 72px; }
.spot {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: 52px;
  align-items: center;
}
/* zigzag: odd rows lead with the media on the left, so row 1 opens on its image.
   Flip the track widths too, so the wide media column stays wide whichever side it lands on. */
.spot:nth-child(odd) { grid-template-columns: 1.15fr 0.85fr; }
.spot:nth-child(odd) .spot-media { order: -1; }
.spot-copy h3 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 25px;
  letter-spacing: -0.02em;
  margin: 0 0 12px;
}
.spot-copy p { margin: 0; font-size: 16.5px; color: var(--ink2); max-width: 46ch; text-wrap: pretty; }
.spot-media { min-width: 0; }
.spot-media .browser { margin: 0; }
/* the phone spotlight: narrower media column, phone centred. Keep the phone column
   narrow on both sides (override the wide-media flip above for phone rows). */
.spot--phone { grid-template-columns: 1fr 0.7fr; }
.spot--phone:nth-child(odd) { grid-template-columns: 0.7fr 1fr; }
.spot--phone .spot-media { display: flex; justify-content: center; }
.spot--phone .phone { margin-left: 0; width: 260px; }

/* AI chat: an ILLUSTRATION (not a screenshot), inside the page's dashed "this is drawn" frame */
.ai-chat {
  margin: 0;
  border: 1px dashed #c8cfd6;
  border-radius: 16px;
  background: var(--band);
  padding: 16px 16px 12px;
}
.ai-chat-card {
  background: #fff;
  border: 1px solid var(--hair);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 18px 40px -30px rgba(23, 32, 44, 0.4);
}
.ai-chat-head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--hair);
  background: #fbfcfd;
  font-family: var(--display);
  font-weight: 700;
  font-size: 14.5px;
  color: var(--ink);
}
.ai-dot {
  width: 22px; height: 22px; border-radius: 50%; flex: none;
  background: linear-gradient(150deg, #3b82f6, var(--blue));
}
.ai-chat-body { display: flex; flex-direction: column; gap: 10px; padding: 16px; }
.bubble {
  max-width: 82%;
  padding: 10px 13px;
  border-radius: 16px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink);
  text-wrap: pretty;
}
.bubble.you {
  align-self: flex-end;
  background: var(--blue);
  color: #fff;
  border-bottom-right-radius: 5px;
}
.bubble.ai {
  align-self: flex-start;
  background: var(--band);
  border: 1px solid var(--hair);
  border-bottom-left-radius: 5px;
}
.ai-chat-foot {
  padding: 11px 16px;
  border-top: 1px solid var(--hair);
  background: #fbfcfd;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: 0.01em;
  color: var(--ink2);
  text-align: center;
  text-wrap: balance;
}
.ai-chat figcaption {
  margin: 10px 4px 2px;
  font-size: 13.5px;
  color: var(--ink2);
  text-align: center;
  text-wrap: pretty;
}

/* ---------- what you get: text-card strip ----------
   Six cards in one band panel. `repeat(3, 1fr)` is EXPLICIT on purpose: an
   auto-fit/auto-fill track would let six cards resolve as 4 + 2 on a wide
   laptop, which is the ragged last row this grouping exists to remove. */
.features {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* The "call-up": one light band behind the six cards so the group reads as a set
   inside the white section, rather than trailing off the spotlights above it.
   Deliberately quiet: no new accent, no gradient, no per-card colour. 16px is the
   page's large-panel radius (the same one .ai-chat uses); the cards keep their 12px. */
.features-block {
  margin-top: 68px;
  background: var(--band);
  border: 1px solid var(--hair);
  border-radius: 16px;
  padding: 28px 28px 32px;
}
.features-block .eyebrow { margin-bottom: 18px; }
.features--strip { margin-top: 0; }
.features li {
  border: 1px solid var(--hair);
  border-radius: 12px;
  background: #fff;
  padding: 20px 20px 22px;
}
.features b {
  display: block;
  font-family: var(--display);
  font-weight: 700;
  font-size: 16.5px;
  letter-spacing: -0.01em;
  margin-bottom: 7px;
}
.features li p { margin: 0; font-size: 15px; color: var(--ink2); }
/* `transparent` would show the block's band fill; this card wants the same white
   face as its five neighbours, with only the dashed edge marking it as not-yet. */
.feature--soon { position: relative; border-style: dashed; border-color: #c8cfd6; }
/* The badge is pinned to the card's TOP RIGHT and taken out of flow, so the heading
   and paragraph start at the card's normal top edge and stay left-aligned, exactly
   like the other five. 20px = the card's own padding, so the badge sits on the same
   optical margin as the text. */
.badge-soon {
  position: absolute;
  top: 20px;
  right: 20px;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.09em;
  color: #7a5a00;
  background: #fff3cf;
  border: 1px solid #e8cf85;
  border-radius: 6px;
  padding: 2px 8px;
  white-space: nowrap;
}
/* The heading's right gutter clears the badge at every width, so a longer title can
   never run under it. 112px = the measured badge box (~92px) plus the 20px gutter. */
.feature--soon b { padding-right: 112px; }

/* ---------- audit ---------- */
.audit-grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 56px;
  align-items: center;
}
.audit-list { margin: 0; padding: 0; list-style: none; }
.audit-list li { padding: 16px 0; border-top: 1px solid var(--hair); font-size: 16px; }
.audit-list li:last-child { border-bottom: 1px solid var(--hair); }
.audit-list b { font-family: var(--display); font-weight: 700; letter-spacing: -0.01em; }
.audit-list span { display: block; color: var(--ink2); font-size: 15px; margin-top: 3px; }
.audit-phone { display: flex; flex-direction: column; align-items: center; margin: 0; }
.audit-phone .phone { margin-left: 0; width: 250px; }
.audit-phone figcaption {
  margin-top: 14px;
  max-width: 36ch;
  text-align: center;
  font-size: 14px;
  color: var(--ink2);
}

/* ---------- pricing ---------- */
/* Four plans, four across. EXPLICIT columns, not auto-fit: at the old
   `minmax(230px, 1fr)` inside an 860px cap, a fourth card cannot fit its own
   minimum (860 - 3 gaps = 806 / 4 = 201px) and the row silently breaks 3 + 1.
   1060px is the widest cap that still leaves each card 251px, which holds the
   longest plan line ("Calibration and maintenance module") to two lines. */
.plans {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
  margin: 0 auto;
  max-width: 1060px;
  padding: 0;
  list-style: none;
  align-items: stretch;
}
.plan {
  border: 1px solid var(--hair);
  border-radius: 12px;
  background: #fff;
  padding: 22px 20px 24px;
  display: flex;
  flex-direction: column;
}
.plan--starter { border: 2px solid var(--blue); }
.plan-tag {
  display: inline-block;
  align-self: flex-start;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #fff;
  background: var(--blue);
  border-radius: 6px;
  padding: 3px 8px;
  margin-bottom: 12px;
}
.plan h3 {
  font-family: var(--display);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -0.01em;
  margin: 0 0 2px;
}
.plan-price {
  font-family: var(--mono);
  font-weight: 500;
  font-size: 14.5px;
  color: var(--ink2);
  margin: 0 0 16px;
}
.plan ul { margin: 0; padding: 0; list-style: none; flex: 1; }
.plan ul li {
  font-size: 14.5px;
  color: var(--ink2);
  padding: 6px 0;
  border-top: 1px solid var(--hair);
}
.plan ul li strong { color: var(--ink); font-weight: 600; }
/* Enterprise's action. A text link in the page's own link treatment, NOT a filled
   button: a fourth blue button in the row would out-shout the Starter card, which
   is the one the page actually recommends. `.plan ul { flex: 1 }` pushes it to the
   card's foot, so the four cards still bottom out level. */
.plan-link {
  margin-top: 14px;
  font-weight: 600;
  font-size: 14.5px;
  color: var(--blue);
  text-decoration: none;
  align-self: flex-start;
}
.plan-link:hover { text-decoration: underline; }
.plan-link::after { content: " \203A"; }
.plan-notes {
  margin: 28px auto 0;
  max-width: 72ch;
  font-size: 14.5px;
  color: var(--ink2);
  text-align: center;
  text-wrap: pretty;
}
.plan-notes p { margin: 6px 0 0; }

/* ---------- integrators ----------
   The boxed dark panel from the pre-rebuild site (git f001dfa), restored in the
   current design language: contained inside .wrap, not full width; the page's
   16px large-panel radius, not the old 20px; and the dark DERIVED from the two
   tokens the page already owns rather than the old pasted #0f2744 gradient:
   --ink (#171b20) walked toward --blue-dark (#1e40af) by color-mix. The two flat
   hex values on the line above the gradient are the same mix, precomputed, so a
   browser without color-mix still lands on the same navy instead of falling back
   to white-on-white. Contrast figures for every pair are in the F294 PR body. */
.integrators { padding: 8px 0 56px; }
.integrators-panel {
  border-radius: 16px;
  padding: 48px;
  background: #181e2b;
  background: linear-gradient(140deg, #181e2b 0%, #192545 100%);
  background: linear-gradient(
    140deg,
    color-mix(in srgb, var(--ink) 92%, var(--blue-dark)) 0%,
    color-mix(in srgb, var(--ink) 74%, var(--blue-dark)) 100%
  );
}
.integrators-panel h2 { color: #fff; margin: 0 0 12px; }
.integrators-panel p {
  margin: 0;
  font-size: 16px;
  max-width: 62ch;
  color: #ced5ed;
  color: color-mix(in srgb, #fff 78%, var(--blue-dark));
  text-wrap: pretty;
}
.int-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 24px 0 28px;
  padding: 0;
  list-style: none;
}
.int-pills li {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: #e4e8f5;
  color: color-mix(in srgb, #fff 88%, var(--blue-dark));
  /* 0.42 alpha white on this navy, not the old 0.22: the outline has to stay
     visible as a boundary, which 0.22 does not manage on a panel this dark. */
  border: 1px solid rgba(255, 255, 255, 0.42);
  border-radius: 999px;
  padding: 6px 14px;
}
.btn--on-dark { background: #fff; color: var(--blue-dark); }
.btn--on-dark:hover { background: #e8eefb; color: var(--blue-dark); }

/* ---------- request access ---------- */
.request { text-align: center; }
.request .section-intro { margin-inline: auto; margin-bottom: 26px; }
.request-email { margin: 22px 0 0; font-size: 15px; color: var(--ink2); }
.request-email a { font-weight: 500; color: var(--blue); }

/* ---------- footer ---------- */
footer { border-top: 1px solid var(--hair); padding: 26px 0 34px; }
.foot {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  font-size: 14px;
  color: var(--ink2);
}
.foot .brand-logo { height: 28px; }
.foot .brand-rule { height: 18px; }
.foot .brand-name { font-size: 16px; }
.foot-mail { margin-left: auto; font-weight: 500; font-size: 14px; color: var(--blue); }

/* ---------- responsive ---------- */
/* The nav hides at 880, not 860. Measured, not chosen: brand + links + CTA need
   more than the content column below ~870px, so the flex row shrinks .links and
   "How it works" wraps to two lines inside a 57px bar. That band existed before
   the nav moved right (it was 861-889px then, 861-869px after); hiding the links
   at 880 closes it with 11px of headroom for a metric shift. */
@media (max-width: 880px) {
  .links { display: none; }
  /* with the links gone there is nothing left to push the CTA, so it takes the
     job back; otherwise it sits glued to the brand lockup */
  .nav .cta-side { margin-left: auto; }
}

/* Plans get their OWN breakpoint, 1100 rather than the page's 1020. Four columns
   need more room than the three the feature grid uses: at 1024 a four-up row leaves
   each card 229px, and the "Most plants start here" tag wraps to two lines inside it,
   which reads as a mistake. 1100 is the measured width at which that tag stays on
   one line with room to spare. Capped at 760px two-up so the pair does not stretch. */
@media (max-width: 1100px) {
  .plans { grid-template-columns: repeat(2, 1fr); max-width: 760px; }
}

@media (max-width: 1020px) {
  .hero-grid { grid-template-columns: 1fr; }
  .hero-scene { margin: 34px 0 8px; }
  .steps { grid-template-columns: 1fr; gap: 26px; }
  .features { grid-template-columns: 1fr 1fr; }
  .features-block { padding: 24px 24px 28px; }
  .audit-grid { grid-template-columns: 1fr; gap: 44px; }
  .integrators-panel { padding: 36px 32px 40px; }
  /* spotlights stack: text first, then the full-width image.
     The nth-child selectors match the desktop track-flip specificity so the stack wins. */
  .spotlights { gap: 48px; }
  .spot, .spot:nth-child(odd),
  .spot--phone, .spot--phone:nth-child(odd) { grid-template-columns: 1fr; gap: 22px; }
  .spot:nth-child(odd) .spot-media { order: 0; }
  .spot-copy p { max-width: 60ch; }
}

@media (max-width: 560px) {
  body { font-size: 16px; }
  .wrap { padding-inline: 20px; }
  .nav { gap: 10px; height: 57px; }
  /* the bar must not wrap at 360px, so the CTA gives up its wide side padding
     before the logo gives up any height */
  .nav .btn { font-size: 14px; padding: 11px 14px; }
  .brand { gap: 9px; }
  .brand-rule { height: 20px; }
  .brand-name { font-size: 17px; }

  .hero { padding: 30px 0 52px; }
  .hero-scene { margin: 30px 0 26px; }
  .sub { max-width: 100%; }

  .phone { width: 202px; margin-left: 0; border-width: 7px; border-radius: 24px; }
  .sticker { width: 130px; left: -22px; bottom: -60px; }
  .sticker-hi { font-size: 14px; }
  .sticker-tag { font-size: 7.5px; letter-spacing: 0.03em; padding: 5px 7px; }
  .sticker-en { font-size: 10.5px; }
  .qr-box { width: 84px; padding: 6px; }
  .scene-caption { margin-top: 86px; }

  .section { padding: 48px 0 54px; }
  .features { grid-template-columns: 1fr; }
  .features-block { padding: 20px 18px 24px; border-radius: 14px; }
  .plans { grid-template-columns: 1fr; }
  .audit-phone .phone { width: 226px; }
  .integrators { padding: 4px 0 44px; }
  .integrators-panel { padding: 28px 22px 32px; border-radius: 14px; }
  .foot { flex-direction: column; align-items: flex-start; gap: 8px; }
  .foot-mail { margin-left: 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
