/* ==========================================================================
   IAN - Creative Adaptation campaign page
   Design source: Figma "Joneja" > Frame 1 (node 4089:467), 1920 x 1423
   Base grid: 1920 canvas, 1440 content container (240px side gutters)
   ========================================================================== */

/* --------------------------------------------------------------- Fonts -- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Display face, used by exactly one heading (the offer band), so only the 700
   weight is shipped. Self-hosted like Inter rather than pulled from a CDN -
   the page is deployed as a static bundle and must not depend on one. */
@font-face {
  font-family: 'Titillium Web';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/titillium-web-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Titillium Web';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/titillium-web-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* -------------------------------------------------------------- Tokens -- */
:root {
  --orange:        #ef4401;
  --orange-hover:  #d13d01;
  --black:         #000000;
  --charcoal:      #13171a;
  --ink:           #454545;
  --strip-text:    #cccccc;

  --tile:          #0e0d0d;
  --footer:        #1f1f1f;

  --rule-header:   #292929;
  --rule-strip:    #363636;
  --rule-sep:      #373737;

  --grey-band:     #efefef;
  --sub-text:      #808080;
  --navy:          #1e184e;
  --navy-hover:    #2a2168;
  --field:         #f9f9f9;
  --field-border:  #eff0f0;
  --field-holder:  #7c7c7c;

  --offer-band:    #e8e8e8;
  /* The offer lede's third line is the one run of copy on the page that leaves
     --ink: one colour per sentence. Sampled from the design capture and
     de-blended against the #e8e8e8 band, so these are the ink colours, not the
     antialiased pixels. */
  --beat-speed:    #23b1f6;
  --beat-quality:  #d06bc0;
  --beat-workflow: #ff8c52;

  /* Four-stop brand ramp, taken 1:1 from Figma. Kept as a token because it is
     the page's one gradient and will be reused if a second heading wants it. */
  --brand-gradient: linear-gradient(88.28deg,
                      rgba(47, 54, 127, .99)    1.28%,
                      rgba(55, 190, 174, .99)  27.58%,
                      rgba(235, 107, 184, .99) 70.09%,
                      rgba(255, 140, 82, .99)  97.17%);

  --radius:        8px;
  --container:     1440px;
  /* Fluid gutter: 48px on the design canvas, easing to 20px on small phones.
     Replaces what used to be three stepped overrides. */
  --gutter:        clamp(20px, 4vw, 48px);

  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  --font-display: 'Titillium Web', var(--font);
}

/* --------------------------------------------------------------- Reset -- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--black);
  color: #fff;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
  /* Safety net only - every known overflow source is fixed at the root.
     `clip` keeps position:sticky usable later; `hidden` is the fallback. */
  overflow-x: hidden;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, p, figure { margin: 0; }
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
hr { border: 0; margin: 0; }

:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }

.container {
  width: min(var(--container), 100% - (var(--gutter) * 2));
  margin-inline: auto;
}

/* -------------------------------------------------------------- Buttons -- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 16px;
  border: 0;
  border-radius: var(--radius);
  font-size: 14px;
  font-weight: 700;
  line-height: 17px;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}
.btn--primary { background: var(--orange); color: #fff; }
.btn--primary:hover { background: var(--orange-hover); }
.btn--navy { background: var(--navy); color: #fff; }
.btn--navy:hover    { background: var(--navy-hover); }
.btn--outline { background: transparent; color: #fff; border: 1px solid rgba(255, 255, 255, .4); }
.btn--outline:hover { background: rgba(255, 255, 255, .08); border-color: #fff; }

/* ========================================================================
   Header - 84px tall, 0.5px rule at y=84
   ======================================================================== */
.site-header {
  position: relative;
  z-index: 10;
  background: var(--black);
}
/* The rule sits on the 84px boundary rather than adding to the header height. */
.site-header::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--rule-header);
}
.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 84px;
}
.site-header__logo img { width: 104px; height: 60px; }

/* ========================================================================
   Hero
   Frame coords: header 0-84, stage 84-1016, strip 1016-1078.
   Stage is therefore 932px tall @1920, and offsets inside it are
   frame-absolute minus the 84px header.
   Visual 1518x854 at (434,142) -> (434, 58) in stage
   Copy 428 wide at (238,334)   -> (238, 250) in stage
   ======================================================================== */
.hero { background: var(--black); }

/* The stage height is a pure ratio of the viewport (660 / 1920), capped at the
   660px design height. No lower floor: a floor would hold the box open while
   the vw-scaled artwork kept shrinking, which letterboxed the art and left a
   band of dead black. Ratio height means every desktop width is a uniform
   scale of the Figma composition. Trimmed down from the original 932 design
   height, which left a lot of dead black above/below the copy column once the
   artwork itself was already filling the stage. */
.hero__stage {
  position: relative;
  overflow: hidden;
  min-height: min(660px, 34.375vw);
}

/* Caps the design at its 1920 canvas so nothing keeps growing on wide screens */
.hero__stage-inner {
  position: absolute;
  inset: 0;
  width: 100%;
  max-width: 1920px;
  margin-inline: auto;
}

.hero__visual {
  position: absolute;
  left: 22.6042%;      /*  434 / 1920 */
  top: 6.2232%;        /*   58 /  932 */
  /* The Figma fill sits at natural scale, height-fitted and left-aligned inside
     its 1518px box, leaving ~32px empty on the right - so the drawn width is the
     bitmap's own 1486px, not the box width. */
  width: 77.3958%;     /* 1486 / 1920 */
  height: 91.6309%;    /*  854 /  932 */
  max-width: none;
  object-fit: contain;
  object-position: left center;
}

.hero__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.hero__overlay .container { position: relative; height: 100%; }

/* Copy width tracks the stage scale (428 / 1920 = 22.3vw) but is allowed to
   run wider than that, up to the design's 428px. 31vw is the widest it can be
   before the artwork's master-creative card marches into it on narrow desktops.
   Vertically centred in the stage instead of pinned to a fixed offset from the
   top - a fixed offset left a bigger gap below the button than above the
   eyebrow once the stage was shortened. Centring splits whatever air is left
   evenly instead of stacking it underneath the CTA. */
.hero__content {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: min(428px, 31vw);
  pointer-events: auto;
}

.hero__eyebrow {
  margin-bottom: 8px;
  color: var(--orange);
  font-size: 14px;
  font-weight: 700;
  line-height: 17px;
  text-transform: uppercase;
}
.hero__title {
  margin-bottom: 8px;
  font-size: min(48px, 3.5vw);   /* 48px at >=1372px, scales with the stage below */
  font-weight: 700;
  line-height: 1;
  text-transform: uppercase;
}
.hero__tagline {
  font-size: 14px;
  font-weight: 700;
  line-height: 17px;
}
.hero__lede {
  margin-top: 16px;
  font-size: 16px;
  font-weight: 300;
  line-height: 24px;
}
.hero__actions {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-top: 25px;
}

/* ------------------------------------------------- Hero credential strip -- */
.hero__strip {
  border-top: 1px solid var(--rule-strip);
  padding: 19px 0 18px;
}
/* Four credentials on one line. The AI one ("AI + Human Intelligence
   Workflows") is by far the longest, and at the design's 18px/48px the row
   measures ~1550px of content - wider than .container ever gets (1440px), so
   it wrapped at every width. Type tops out at 16px and the gap at 40px, which
   brings the row to ~1380px at 1920 and keeps it inside the container.
   Both are vw-driven below that: text width scales with font-size, so a vw
   ramp keeps the fit proportional all the way down to 1300, where the grid
   below takes over. Wrap stays on as a backstop only. */
.strip {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
  gap: 12px clamp(16px, 2.2vw, 40px);
}
.strip__item {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--strip-text);
  font-size: clamp(13px, 1.04vw, 16px);
  font-weight: 400;
  line-height: 22px;
  text-transform: uppercase;
  white-space: nowrap;
}
.strip__item img { width: 24px; height: 24px; }
.strip__icon--globe { width: 21.5px !important; height: 21.5px !important; margin: 0 1.25px; }
.strip__sep {
  width: 1px;
  height: 22px;
  background: var(--rule-sep);
}

/* ========================================================================
   Free pilot offer - light grey band, 303px tall @1920
   Figma "Joneja" > Frame 1 > Offer (Rectangle 60), 1920 x 303 at y=1080.
     title  677 x 55 at y=1152   ->  72 below the band's top edge
     lede   665 x 90 at y=1211   ->   4 below the title's line box
   which leaves 82px under the lede. Those three numbers are the padding and
   the margin below; everything else is that canvas expressed as a ratio.

   This band takes over y=1080, the coordinate the .book comment below still
   quotes - book now starts at 1383 on the same canvas.
   ======================================================================== */
.offer {
  background: var(--offer-band);
  color: var(--ink);
  /* 72 / 1920 = 3.75vw, 82 / 1920 = 4.27vw - the same ramp the other bands
     use, holding the design values at 1920 and easing down from there. */
  padding: clamp(40px, 3.75vw, 72px) 0 clamp(44px, 4.27vw, 82px);
}

/* fit-content is load-bearing, not tidiness: a clipped background paints the
   element's own box, so a full-width h2 would stretch the four stops across
   the whole 1440 container and the glyphs would only ever reveal the middle of
   the ramp. Hugging the text reproduces the Figma 677px box at every scale. */
.offer__title {
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
  font-family: var(--font-display);
  /* 2.7vw holds the design's 36px down to 1333px, the same hand-off point
     .book__title and .scale__title use. */
  font-size: clamp(24px, 2.7vw, 36px);
  font-weight: 700;
  line-height: 1.5278;            /* 55 / 36 */
  text-align: center;
  text-transform: uppercase;
  background: var(--brand-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* Forced-colors mode drops background images, and a transparent fill over a
   dropped gradient is an invisible heading rather than a merely uncoloured
   one. Both properties have to come back, in this order. */
@media (forced-colors: active) {
  .offer__title {
    background: none;
    color: CanvasText;
    -webkit-text-fill-color: currentColor;
  }
}

/* The design box is 665 but line 2 sets 673px of type and is allowed to run
   past it, so there is deliberately no max-width here - the three <br>s hold
   the design's line breaks and the 1440 container is what actually bounds it. */
.offer__lede {
  margin: 4px 0 0;
  font-size: clamp(16px, 1.5vw, 20px);
  font-weight: 700;
  line-height: 1.5;               /* 30 / 20 */
  text-align: center;
}

/* The heading is one line at the design width, so this only bites once it wraps
   on a phone. Left to itself the greedy break splits "NO COMMITMENT." across
   two lines, and text-wrap:balance is worse rather than better here - it
   equalises line lengths, which buys the shorter ragged edge by cutting
   "ON US." in half instead. Sealing each sentence leaves the two spaces
   between them as the only break opportunities, so whichever line the heading
   turns on, it turns on a full stop. */
.offer__title span { white-space: nowrap; }

.offer__speed    { color: var(--beat-speed); }
.offer__quality  { color: var(--beat-quality); }
.offer__workflow { color: var(--beat-workflow); }

/* ========================================================================
   Book your free pilot - grey band, 368px tall @1920
   Figma "Joneja" > Frame 1 > Rectangle 59, 1920 x 368 at y=1080.
   Title 1176-1215, sub 1223-1242, row 1 at 1280, row 2 at 1343.
   Fields are 350x40 on a 3 x 36px grid, 1122px wide, centred.
   ======================================================================== */
.book {
  background: var(--grey-band);
  color: var(--ink);
  padding: 96px 0 62px;
}

/* 2.4vw holds the design's 32px down to 1333px, matching how .scale__title
   and the other headings give way. */
.book__title {
  margin: 0;
  font-size: clamp(22px, 2.4vw, 32px);
  font-weight: 700;
  line-height: 1.22;
  text-align: center;
  text-transform: uppercase;
}
.book__lede {
  margin: 8px 0 0;
  font-size: 16px;
  line-height: 19px;
  text-align: center;
  color: var(--sub-text);
}

/* The 46px button sets the row track height and the 40px fields centre in it,
   which is what produces the design's 23px field-to-field gap from a 20px
   row-gap - and the button's 3px overhang top and bottom.
   min() rather than a breakpoint: the 1440 container is already narrower than
   1122px below a 1218px viewport. */
.book__form {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: center;
  gap: 20px 36px;
  width: min(1122px, 100%);
  margin: 38px auto 0;
}

.field { display: flex; flex-direction: column; }

/* Visually hidden, not display:none - the label must stay in the accessibility
   tree, because the placeholder disappears as soon as anyone types. */
.field__label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.field__input {
  width: 100%;
  height: 40px;
  padding: 0 16px;
  border: 1px solid var(--field-border);
  border-radius: var(--radius);
  background: var(--field);
  color: var(--ink);
  font-family: inherit;   /* inputs do not inherit this on their own */
  font-size: 14px;
}
/* Firefox dims placeholders by default; opacity keeps the design's grey exact. */
.field__input::placeholder { color: var(--field-holder); opacity: 1; }
.field__input[aria-invalid="true"] { border-color: var(--orange); }

.field__error {
  margin-top: 4px;
  font-size: 12px;
  line-height: 16px;
  color: var(--orange);
}

/* Multi-column only: an in-flow error grows its field, which grows the whole
   grid row, and align-items:center then re-centres the row's other inputs -
   measured as a 10px misalignment when 2 of 3 fields error. Taking the message
   out of flow keeps every input in a row on the same baseline. It stays in flow
   in the single-column layout below, where there is nothing to misalign and an
   absolute message could overlap the next field if it wrapped to two lines. */
@media (min-width: 601px) {
  .field { position: relative; }
  .field__error {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
  }
}

/* Out of flow, so it never takes a grid cell. Off-screen rather than
   display:none, which some bots skip. */
.field--decoy {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.book__submit { width: 100%; height: 46px; }

.book__status {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--orange);
}
/* Success toast — shown after a lead form submission, corner notification.
   Kept in the DOM and toggled via [hidden] + .toast--visible (rather than
   just [hidden]) so the opacity/transform transition has a start state to
   animate from instead of popping instantly. */
.toast {
  position: fixed;
  right: 24px;
  top: 24px;
  z-index: 1000;
  width: min(340px, calc(100vw - 48px));
  padding: 18px 40px 18px 20px;
  background: #fff;
  border-left: 4px solid var(--navy);
  border-radius: var(--radius);
  box-shadow: 0 12px 28px rgba(0, 0, 0, .18);
  opacity: 0;
  transform: translateY(-16px);
  transition: opacity .2s ease, transform .2s ease;
  pointer-events: none;
}
/* Fixed WhatsApp chat button - bottom-right. */
.whatsapp-fab {
  position: fixed;
  right: 24px;
  bottom: 15px;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  background: #25d366;
  border-radius: 50%;
  box-shadow: 0 6px 16px rgba(0, 0, 0, .25);
  transition: transform .2s ease, box-shadow .2s ease;
}
.whatsapp-fab:hover,
.whatsapp-fab:focus-visible {
  transform: scale(1.08);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .3);
}
.whatsapp-fab svg {
  width: 30px;
  height: 30px;
  fill: #fff;
}

.toast--visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.toast__title {
  margin: 0 0 4px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  color: var(--navy);
}
.toast__text {
  margin: 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--ink);
}
.toast__close {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 24px;
  height: 24px;
  border: 0;
  background: none;
  color: var(--sub-text);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: color .15s ease;
}
.toast__close:hover { color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  .toast { transition: none; }
}

@media (max-width: 900px) {
  .book__form { grid-template-columns: repeat(2, 1fr); }
  .book__submit { grid-column: 1 / -1; }
}

@media (max-width: 600px) {
  .book { padding: 56px 0 48px; }
  .book__form { grid-template-columns: 1fr; }
}

/* ========================================================================
   Proven scale - gradient band, 488.5px tall @1920
   Figma y=1782..2270.5: heading at 1865 (83 from the top edge), the 1040px
   circle row at 1968.5, and 90px of band left underneath it.
   ======================================================================== */
.proven {
  background: var(--brand-gradient);
  color: #fff;
  padding: clamp(48px, 5.5vw, 83px) 0 clamp(52px, 6vw, 90px);
}

.proven__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(24px, 3.4vw, 48px);
  font-weight: 700;
  line-height: 1;
  text-align: center;
  text-transform: uppercase;
}

/* All 5 stay in one row at every width - both the gap and --stat-size (below)
   are fluid all the way down to phone widths instead of capping at a fixed
   minimum, so the row shrinks to fit rather than wrapping to 2+2+1. */
.proven__row {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: center;
  gap: clamp(6px, 1.5vw, 64px);
  margin: clamp(32px, 3.7vw, 55.5px) 0 0;
  padding: 0;
  list-style: none;
}

/* Everything inside the circle is a fraction of its diameter, so one variable
   resizes the whole composition and the design's proportions survive intact:
   45.5/212 for the number's top edge, 99/212 for the label's, and so on. */
.stat {
  --stat-size: clamp(44px, 15vw, 212px);
  --stat-border: 3px;

  position: relative;
  flex: 0 0 auto;
  width: var(--stat-size);
  height: var(--stat-size);
  border: var(--stat-border) solid #fff;
  border-radius: 50%;
}

/* The offsets are measured from the circle's outer edge, but an absolutely
   positioned child resolves `top` against the padding box - hence the border. */
.stat__num,
.stat__label {
  position: absolute;
  left: 0;
  width: 100%;
  text-align: center;
}

.stat__num {
  top: calc(var(--stat-size) * 0.21462 - var(--stat-border));   /* 45.5 / 212 */
  font-family: var(--font-display);
  font-size: calc(var(--stat-size) * 0.18868);                  /*   40 / 212 */
  font-weight: 700;
  line-height: calc(var(--stat-size) * 0.28774);                /*   61 / 212 */
  text-transform: uppercase;
  color: rgba(255, 255, 255, .99);
}

.stat__label {
  top: calc(var(--stat-size) * 0.46698 - var(--stat-border));   /*   99 / 212 */
  font-size: calc(var(--stat-size) * 0.09434);                  /*   20 / 212 */
  font-weight: 400;
  line-height: calc(var(--stat-size) * 0.11792);                /*   25 / 212 */
}

/* ========================================================================
   Built for adaptation at scale - white band
   Figma 1920 canvas: heading at y=2371, card row 2488-2788. The cards are flat
   brand-colour tiles now, not photographs - one 342 x 300 tile per pillar,
   carrying only the icon, its numeral and a paragraph.
   ======================================================================== */
.scale {
  background: #fff;
  color: var(--ink);
  /* 90px: the gap between the cream band ending at y=1423 and the heading. */
  padding: clamp(48px, 6.25vw, 90px) 0;
}

/* The row measures 1560 - 4 x 342 with three 64px gutters, on 180px margins -
   so this band is wider than the 1440 the rest of the page uses. Overriding the
   token rather than the width keeps .container's own gutter maths intact, the
   same route .gap__inner takes. */
.scale__inner { --container: 1560px; }

.scale__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(26px, 3.6vw, 48px);
  font-weight: 700;
  /* 1.1 rather than the design's flat 1: Titillium's ascenders sit high enough
     that a 1.0 box clips them against the clipped background below. */
  line-height: 1.1;
  text-align: center;
  text-transform: uppercase;
}

/* Clipped to the span's own inline box, which hugs "SCALE." exactly as the
   design's 143px gradient box does - on the h2 the four stops would stretch
   across the whole row and the word would only reveal the middle of the ramp.
   The full stop is inside the span: the design colours it too. */
.scale__title span {
  background: var(--brand-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* Forced-colors mode drops background images, and a transparent fill over a
   dropped gradient is an invisible word rather than a merely uncoloured one.
   Both properties have to come back, in this order. */
@media (forced-colors: active) {
  .scale__title span {
    background: none;
    color: CanvasText;
    -webkit-text-fill-color: currentColor;
  }
}

.scale__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(20px, 3.333vw, 64px);         /* 64 / 1920 */
  margin: clamp(32px, 4.75vw, 57px) 0 0;
  padding: 0;
  list-style: none;
}

/* Each card is a 342 x 300 composition, so every measurement inside it is
   expressed as a share of the card's own width (cqw) rather than the viewport.
   That keeps the icon, numerals and copy in the designed proportion at any
   column width. The px floors in max() stop the type collapsing when four
   columns are squeezed at the low end of the desktop range.
   The tile colour rides in on --card from the markup - four one-off values that
   belong to this row alone, not to the page's palette. */
.scale-card {
  container-type: inline-size;
  position: relative;
  border-radius: 16px;
  background: var(--card, var(--black));
  color: #fff;
}

@media (hover: hover) and (pointer: fine) {
  .scale-card {
    transition: transform .35s cubic-bezier(.2, .8, .2, 1), box-shadow .35s ease;
  }
  .scale-card:hover {
    transform: translateY(-4px);
    box-shadow:
      0 16px 28px -12px rgba(0, 0, 0, .35),
      0 0 28px 2px color-mix(in srgb, var(--card) 55%, transparent);
  }
}

/* The padding and the card's height both live on the body, not on .scale-card:
   a container's own properties resolve cqw against its nearest *ancestor*
   container, so only a descendant can measure itself against the card.
   min-height, not a fixed 300, because the paragraph is the tallest thing in
   the card - it must be free to grow the tile rather than spill out of it, and
   grid stretch then levels all four. */
.scale-card__body {
  min-height: max(240px, 87.719cqw);       /* 300 / 342, border-box */
  padding: max(16px, 7.018cqw);            /* 24 / 342 */
}

/* The speed icon is 60 x 53 where the other three are 60 x 60, so without the
   floor its paragraph would start 7px higher than its neighbours'. */
.scale-card__head {
  display: flex;
  align-items: flex-start;
  gap: max(12px, 4.678cqw);                /* 16 / 342 */
  min-height: max(44px, 17.544cqw);        /* 60 / 342 */
}
.scale-card__icon {
  flex: 0 0 auto;
  width: max(44px, 17.544cqw);
  height: auto;
  /* The icon groups are flipped vertically in Figma; the SVG export carries the
     unflipped geometry, so the flip is reapplied here. */
  transform: scaleY(-1);
}

@media (hover: hover) and (pointer: fine) {
  .scale-card__icon {
    transition: transform .6s cubic-bezier(.16, 1, .3, 1);
  }
  /* translateY has to follow the scaleY(-1) flip above, not replace it -
     transform is a single property, so the hover state re-states the flip. */
  .scale-card:hover .scale-card__icon {
    transform: scaleY(-1) translateY(-14px);
  }
}
.scale-card__meta {
  display: flex;
  flex-direction: column;
  font-size: max(15px, 5.848cqw);          /* 20 / 342 */
  line-height: 1.3;                        /* 26 / 20 */
  text-transform: uppercase;
}
.scale-card__index  { font-weight: 300; }
.scale-card__kicker { font-weight: 700; }

.scale-card__desc {
  margin: max(18px, 7.310cqw) 0 0;         /* 25 / 342 */
  font-size: max(14px, 5.848cqw);          /* 20 / 342 */
  line-height: 1.5;                        /* 30 / 20 */
}

/* Registered so the browser can interpolate --angle as an angle (not just
   swap two strings), which is what makes the conic-gradient below rotate
   smoothly instead of jumping. */
@property --scale-card-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@keyframes scale-card-shimmer {
  to { --scale-card-angle: 360deg; }
}

@media (hover: hover) and (pointer: fine) {
  /* A bright arc riding around a conic-gradient, masked down to a thin ring
     via the padding-box/border-box exclude trick - so only the border
     shimmers, not the whole card face. */
  .scale-card::before {
    content: '';
    position: absolute;
    inset: 0;
    padding: 3px;
    border-radius: inherit;
    /* White, not a --card tint: on the blue and teal cards a tinted arc sits
       too close to the card's own hue to read as a shimmer at all. */
    background: conic-gradient(
      from var(--scale-card-angle),
      transparent 0%,
      rgba(255, 255, 255, .95) 14%,
      transparent 30%
    );
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    mask-composite: exclude;
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s ease;
  }
  .scale-card:hover::before {
    opacity: 1;
    animation: scale-card-shimmer 2.2s linear infinite;
  }
}

@media (prefers-reduced-motion: reduce) {
  .scale-card,
  .scale-card__icon,
  .scale-card::before { transition: none; }
  .scale-card:hover { transform: none; }
  .scale-card:hover .scale-card__icon { transform: scaleY(-1); }
  .scale-card:hover::before { opacity: 1; animation: none; }
}

/* ========================================================================
   The Gap No One's Filled - navy band
   Design frame "Rectangle 61", 1920x541 at y=2881. Measured from the supplied
   635x164 crop.

   The scale is anchored on the icon exports, NOT on the crop width: the crop
   is hand-made - its left and right margins differ by 22px - so treating it as
   a clean 1920 capture would bake that error into every number.

   Two exports settle it instead. gap-subscription and gap-language are 60x60
   with ink running edge to edge, and both measure 22 crop px: 2.727 design px
   per crop px. gap-turnaround carries 50px of ink in its 60px box and measures
   19: 2.632. The same ratio within one antialiased pixel, from two independent
   readings - which means the icons render at their natural 60px and the crop
   is a 1/2.73 downscale of the band.
   ======================================================================== */
/* Solved backwards from the band: the ink measures 391px once the copy sets in
   three lines and the note in two, so 541 - 391 = 150 to divide. The crop puts
   more of it above the title than below the note - it cuts ~47px off each end,
   so the ink is not centred in the band. */
.gap {
  background: var(--navy);
  padding: clamp(56px, 5vw, 88px) 0 clamp(48px, 4.4vw, 62px);
}

/* The rule under the row is the one element that spans the full content width,
   so it is what the container is measured from: 380 crop px x 2.727 = 1036.
   Overriding the token rather than the width keeps .container's own gutter
   maths intact. */
.gap__inner { --container: 1040px; }

/* Set in mixed case in the markup and uppercased here, matching how the other
   uppercase titles on the page are handled. */
.gap__title {
  margin: 0;
  color: #fff;
  /* 10 crop px of cap height -> 27 design px, and Titillium's cap sits at
     ~0.7 em, so 27 / 0.7 = 39 -> 40px. */
  font-size: clamp(24px, 2.6vw, 40px);
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  text-transform: uppercase;
}

.gap__row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  /* space-between sets the real spacing; this is only the collision floor for
     the narrow end of the desktop range. */
  gap: 32px;
  margin: clamp(36px, 3.6vw, 56px) 0 0;
  /* The rule belongs to the row, not the note: it runs the full 1036px content
     width while the note is capped at 700, so hanging it off the note would
     draw it a third short. */
  padding: 0 0 clamp(20px, 2vw, 28px);
  border-bottom: 1px solid rgba(255, 255, 255, .22);
  list-style: none;
}

/* Not equal thirds: even thirds of the 1040 container would centre the outer
   columns 23 crop px inside where they actually sit. The columns are narrow
   boxes pushed to the container edges.

   The width is set by the line breaks, not by the crop's 251px of ink: the page
   sets this copy in Inter, which is wider than the type in the crop, and at
   251 the two longer sentences take a fourth line. 300 is the width at which
   all three break into the three lines the design draws. */
.gap__item {
  display: flex;
  flex: 0 1 300px;
  flex-direction: column;
  align-items: center;
  gap: 32px;
  text-align: center;
}

/* Natural size, per the derivation above. Both dimensions are fixed because
   all three exports are square - there is no width variation to leave free. */
.gap__icon {
  flex: 0 0 auto;
  width: 60px;
  height: 60px;
}

/* The clock reads pure white while the other two are #cccccc. The crop samples
   255 against 204, so that is the design rather than an export slip, and it is
   left alone. */

/* 20/29. The line pitch is the reliable metric here - 10.5 crop px measured
   line-top to line-top, x 2.727 = 28.6 -> 29 - and 20px is what sits under it
   at the ~1.45 the rest of the page's body copy runs. */
.gap__copy {
  margin: 0;
  color: var(--strip-text);
  font-size: 20px;
  font-weight: 400;
  line-height: 29px;
}

/* The rule itself is sampled at (86,81,122) against the (30,24,78) band - a
   quarter of the way to white - and is set on .gap__row above. */
.gap__note {
  margin: clamp(16px, 1.6vw, 22px) auto 0;
  /* Same widening as the columns, for the same reason: the crop's longest line
     is 671px, but in Inter the sentence needs 800 to hold the two lines the
     design draws rather than spilling "work." onto a third. */
  max-width: 800px;
  color: var(--strip-text);
  font-size: 20px;
  font-weight: 400;
  line-height: 29px;
  text-align: center;
}

/* ========================================================================
   How It Works - white band, four circled steps
   Straight from the design's absolute coordinates, which close on themselves:
   4 circles x 232 + 3 gaps x 60 = 1108, the stated row width. Every number
   below is one of those coordinates turned into a ratio of the 232px circle,
   which is what makes the band scale as one composition rather than as seven
   independently clamped parts.
   ======================================================================== */
.flow {
  background: #fff;
  color: var(--ink);
  /* The band this replaces set its own padding to the sibling white band's 90
     to keep the page's two white bands on one rhythm. Kept for the same
     reason - the design gives coordinates, not band bounds. */
  padding: clamp(48px, 6.25vw, 90px) 0;
}

/* 48/48 uppercase navy, per the design. Line-height 1.1 rather than its flat
   1 for the reason .scale__title already carries: Titillium's ascenders sit
   high enough in the em box that 1 clips them in some engines. */
.flow__title {
  margin: 0;
  color: var(--navy);
  font-family: var(--font-display);
  font-size: clamp(26px, 3.6vw, 48px);
  font-weight: 700;
  line-height: 1.1;
  text-align: center;
  text-transform: uppercase;
}

/* The row is the 1108px composition, and it stays one: the circles are sized
   as a percentage of it, so 4 x 20.939% + 3 x 5.4151% is exactly 100% at any
   width. Nothing here is clamped, because the circle carries its own scaling
   (see .flow__step) - clamping the row as well would fight it. */
.flow__row {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  gap: 5.4151%;               /* 60 / 1108 */
  width: min(1108px, 100%);
  /* 3604 - 3560 = 44 from the title's line box to the circles. */
  margin: clamp(28px, 3vw, 44px) auto 0;
  padding: 0;
  list-style: none;
}

/* The circle is the query container for everything inside it, so the icon,
   the copy and the arrow are all fixed fractions of whatever the circle
   currently measures. That is the one thing that has to hold: a 20px label
   inside a circle that has shrunk to 170 is not the design.
   232 / 1108 = 20.939%, and aspect-ratio takes the height from there.

   Every cqw below is over 230, not 232: cqw measures the container's content
   box, and the design's own box-sizing is border-box, so the 1px border eats
   one px at each edge. The design's coordinates are in the 232 frame, so each
   one lands a px inward of where it is written - inside the design's own
   rounding, and the alternative is a second wrapper element for nothing. */
.flow__step {
  container-type: inline-size;
  position: relative;
  display: flex;
  flex: 0 0 20.939%;
  flex-direction: column;
  align-items: center;
  aspect-ratio: 1;
  padding: 0;
  background: #fff;
  border: 1px solid #e0e0e0;
  border-radius: 50%;
  box-shadow: 0 0 4px rgba(0, 0, 0, .25);
}

/* The arrows sit in the gaps, not in the list: they restate the order the
   <ol> already carries, so they are drawn rather than marked up. The gap is
   60 wide and it starts at the border edge, one px outside the padding box
   that 100% resolves against - so its centre is 31 out, not 30. */
.flow__step:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 50%;
  left: calc(100% + 13.4783cqw);
  width: 13.0435cqw;          /* 30 */
  height: 13.0435cqw;
  background: url('../assets/icons/flow-arrow.svg') center / contain no-repeat;
  transform: translate(-50%, -50%);
}

/* A fixed 60-tall slot with the icon hung from its top, rather than the icon
   sizing the row. Three of the four exports are 60 tall but the fourth is 50,
   and the design still starts all four at 29 - centring them in the slot
   would drop that one 5px and break the line the four icons sit on.

   The two offsets down the circle - 29 to the icon, 27 from it to the copy -
   are margins on these children rather than padding and gap on the circle:
   an element cannot query itself, so a cqw written on .flow__step would have
   resolved against the viewport instead. */
.flow__slot {
  display: flex;
  flex: 0 0 auto;
  align-items: flex-start;
  justify-content: center;
  height: 26.087cqw;          /* 60 */
  margin-top: 12.6087cqw;     /* icon top 29 */
}

.flow__icon {
  width: auto;
  height: 26.087cqw;
  max-width: none;
}
.flow__icon--wide { height: 21.7391cqw; }   /* the 70x50 export */

/* 20/24 centred, per the design. The box is 192 rather than the design's 171:
   the page sets this copy in Inter, and at 171 Inter takes "delivers
   adaptations" and "approve, and it gets" onto a fourth line. 192 is the
   width at which all four labels break into the three lines the design draws,
   and it is still inside the circle - the widest of those lines is 191 and it
   falls on line two, where the circle is 211 across. */
.flow__copy {
  margin: 11.7391cqw 0 0;     /* 116 - (29 + 60) = 27 */
  width: 83.4783cqw;          /* 192 */
  color: var(--ink);
  font-size: 8.6957cqw;       /* 20 */
  font-weight: 400;
  line-height: 1.2;
  text-align: center;
}

/* ========================================================================
   We've Already Delivered This - grey band, auto-scrolling client logos
   Ten logos (the original six plus Dell, Coca-Cola, Castrol and Walmart) run
   as a continuous marquee: the <ul> holds the set twice back-to-back and the
   animation translates it by exactly one set-width (-50%), so the loop point
   is invisible. The strip lives outside .container so the mask-image fade
   below reaches the section's actual left/right edges.
   ======================================================================== */
.clients {
  background: var(--grey-band);
  color: var(--ink);
  /* 72 on the design canvas. 5vw reaches it at 1440 - the same relation
     .flow's 6.25vw/90 uses, so the two bands ease at one rate. */
  padding: clamp(40px, 5vw, 72px) 0;
}

/* 48/48 uppercase, per the design - and in --ink here, not the navy .flow__title
   takes. Line-height 1.1 rather than its flat 1 for the reason both other
   Titillium headings carry: at 1 the ascenders clip in some engines. */
.clients__title {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: clamp(26px, 3.6vw, 48px);
  font-weight: 700;
  line-height: 1.1;
  text-align: center;
  text-transform: uppercase;
}

/* Full-bleed: a direct child of the section, not of .container, so it spans
   edge to edge and the fade below isn't clipped by the container gutter. */
.clients__marquee {
  overflow: hidden;
  width: 100%;
  margin: clamp(24px, 3.5vw, 40px) 0;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}

/* width: max-content lets the track be exactly twice the ten-logo set, which
   is what makes translateX(-50%) land the animation back on its own start
   frame with no seam. */
.clients__track {
  display: flex;
  align-items: center;
  gap: 61px;
  width: max-content;
  margin: 0;
  padding: 0;
  list-style: none;
  /* The transform animation gives this element its own stacking context, so
     the onwhite logos' mix-blend-mode can no longer see the section's grey
     background through it - it would blend against transparent instead.
     Painting the same grey here keeps the blend working. */
  background: var(--grey-band);
  animation: clients-scroll 44s linear infinite;
}

.clients__marquee:hover .clients__track,
.clients__marquee:focus-within .clients__track {
  animation-play-state: paused;
}

@keyframes clients-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Each item holds its logo's chosen display width and the image fills it, so
   height follows the export's own aspect ratio rather than being stated
   twice. The six original widths are the design's own figures; Dell, Coca-
   Cola, Castrol, Walmart and 1 India Fashion are sized by eye to read at the
   same visual scale next to them. */
.clients__item { flex: 0 0 auto; }

.clients__item--jcb      { width: 165.5px; }
.clients__item--surya    { width: 207.5px; }
.clients__item--lg       { width: 170.89px; }
.clients__item--airtel   { width: 195px; }
.clients__item--nissan   { width: 108.51px; }
.clients__item--nokia    { width: 170.11px; }
.clients__item--dell     { width: 84px; }
.clients__item--coke     { width: 113px; }
.clients__item--castrol  { width: 126px; }
.clients__item--walmart  { width: 114px; }
.clients__item--oneindia { width: 128px; }

.clients__logo {
  width: 100%;
  height: auto;
}

/* Nissan and Walmart ship as an opaque plate (white background) rather than
   a transparent cutout, so on the #efefef band they'd each sit in a visible
   rectangle. multiply takes that plate to the backdrop and leaves the mark
   untouched. Dell, Nokia, Coca-Cola and Castrol are already transparent, so
   they're the logos without this class. */
.clients__logo--onwhite { mix-blend-mode: multiply; }

/* 20/24 light, centred, per the design. The box is 960 rather than the design's
   942: set in Inter the sentence measures 944 and drops "geography." onto a
   second line at 942. 960 clears that with a little room for the variance
   between engines, and the extra is invisible - the line is centred, so a box
   wider than the line it holds looks identical. */
.clients__note {
  margin: 2px auto 0;
  max-width: 960px;
  color: var(--ink);
  font-size: 20px;
  font-weight: 300;
  line-height: 24px;
  text-align: center;
}

/* ========================================================================
   Start With a Free Pilot - black band
   Figma frame "Rectangle 63", 1920x616 at y 4346. The row closes on itself:
   4 cards x 358 + 3 gutters x 42 = 1558, sitting on 180px margins.

   Vertical, all read off the same 4346 band top:
     title  4423 (77 below the band top), 48/48
     cards  4534 (63 below the title box), 338 tall -> 4872
     band ends 4962, i.e. 90 under the cards.

   Inside a card, again from the card's own top at 4534:
     icon   4566    ( 32) 50 tall
     title  4621.92 ( 88) 24/37
     copy   4668    (134) 20/30, 292 wide inside 33px side padding
   ======================================================================== */
.pilot {
  background: var(--black);
  padding: clamp(44px, 4vw, 77px) 0 clamp(52px, 4.7vw, 90px);
}

/* Wider than the page's 1440, like the scale band: the row measures 1558 and
   overriding the token rather than the width keeps .container's own gutter
   maths intact.
   The container query is what carries the scaling - the gutter between cards
   and each card's padding are shares of this row. An element cannot query
   itself, so those live here rather than on the card: only values set on a
   card's CHILDREN are shares of the card. */
.pilot__inner {
  --container: 1558px;
  container-type: inline-size;
}

/* Left in vw rather than cqw, like the page's other 48px band titles - it is
   the one thing here that is not part of the card composition.
   1.1 rather than the design's flat 1: Titillium's ascenders sit high enough
   that a 1.0 box clips them. */
.pilot__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(26px, 3.6vw, 48px);
  font-weight: 700;
  line-height: 1.1;
  text-align: center;
  text-transform: uppercase;
}

.pilot__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: max(20px, 2.6957cqw);             /* 42 / 1558 */
  margin: clamp(36px, 3.28vw, 63px) 0 0;
  padding: 0;
  list-style: none;
}

/* The 338 height is not stated: it falls out of the stack. At the design width
   card three's paragraph sets in six lines, so 32 + 50 + 6 + 37 + 9 + 180 + 32
   = 346, and grid stretch levels the other three to it. Declaring a height as
   well would only give the longest paragraph something to spill out of.

   The padding is a PERCENTAGE, not a cqw share, and that is deliberate: a grid
   item's percentage padding resolves against its own track, so 33/358 stays
   33px per 358px of card at four columns, two, or one - where a share of the
   row above would only be right at the design width.

   The tile colour and its hairline are one-off values for this band, not page
   palette, so they stay literal. */
.pilot-card {
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8.9385% 9.2179%;              /* 32 / 358, 33 / 358 */
  background: #212121;
  border: 1px solid #727272;
  border-radius: 16px;
  text-align: center;
}

/* cqw below is 1% of the card's CONTENT box, not of the card: 358 less its two
   1px borders and its 33px padding either side leaves 290, which is what these
   four ratios divide by. The card's own padding above divides by 358 because a
   percentage there is measured against the grid track instead. Getting the two
   bases the wrong way round scales every child down by a fifth. */

/* Height-locked, width free - the complimentary-pilot tick is a 69x50 export
   where the other three are 50x50, and fixing the height is what makes the
   four read as one set. */
.pilot-card__icon {
  flex: 0 0 auto;
  width: auto;
  height: max(34px, 17.2414cqw);         /* 50 / 290 */
  max-width: 100%;
}

.pilot-card__title {
  margin: max(6px, 2.0690cqw) 0 0;       /*  6 / 290 */
  font-family: var(--font-display);
  font-size: max(17px, 8.2759cqw);       /* 24 / 290 */
  font-weight: 700;
  line-height: 1.5417;                   /* 37 / 24 */
  text-transform: uppercase;
}

.pilot-card__desc {
  margin: max(8px, 3.1034cqw) 0 0;       /*  9 / 290 */
  font-size: max(14px, 6.8966cqw);       /* 20 / 290 */
  font-weight: 400;
  line-height: 1.5;                      /* 30 / 20 */
}

/* ========================================================================
   FAQ - white band
   New section: not lifted from a full-page capture like the bands above it,
   but from a standalone Figma CSS export of the accordion rows (1920
   canvas, container 1560 x 658 at left 180, top 5052).

   Row rhythm, all read off the container's own top at 5052:
     title   5052 ( 0)   48 tall
     row 1   5162 (110)  70 tall, expanded - panel follows at 5232, 120 tall
     row 2   5352 (300)  70 tall
     row 3   5424 (372)  70 tall
     row 4   5496 (444)  70 tall
     row 5   5568 (516)  70 tall
     row 6   5640 (588)  70 tall, ends 5710 = 5052 + 658

   Row/panel heights are NOT reproduced as fixed px: the 70/120 pair is only
   correct for this one (shortest) question and its two-line answer. The
   other five answers run longer, so height is left to fall out of padding +
   content, the same reasoning .pilot-card documents for its own height.

   Band padding is not from the capture either - there is no coordinate for
   where this section sits against its neighbours, so it reuses .scale's and
   .flow's own undocumented-bounds figure.
   ======================================================================== */
.faq {
  background: #fff;
  color: var(--ink);
  padding: clamp(48px, 6.25vw, 90px) 0;
}

/* Wider than the page's 1440, like the scale and pilot bands: the row
   measures 1560 on 180px margins. Overriding the token rather than the
   width keeps .container's own gutter maths intact. */
.faq__inner { --container: 1560px; }

/* Left-aligned, unlike every other section title on the page - the source
   box sits flush with the container's own left edge, and the reference
   crop confirms it (every other h2 here is centred). */
.faq__title {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-display);
  font-size: clamp(26px, 3.6vw, 48px);
  font-weight: 700;
  line-height: 1.1;
  text-transform: uppercase;
}

/* 62 / 1920 = 3.2292vw - the gap from the title's own box bottom to the
   first row, read directly off the capture's two boxes. */
.faq__list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: clamp(28px, 3.2292vw, 62px) 0 0;
  padding: 0;
  list-style: none;
}

/* Cross-engine marker removal: Chromium needs the pseudo-element hidden,
   Firefox now draws summary's marker as a real ::marker. list-style alone
   covers older engines that still use display:list-item. */
.faq-item__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: clamp(16px, 1.1979vw, 23px) clamp(18px, 1.5625vw, 30px);
  background: #d9d9d9;
  color: #000;
  cursor: pointer;
  list-style: none;
}
.faq-item__summary::-webkit-details-marker { display: none; }
.faq-item__summary::marker { display: none; }

.faq-item__question {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 700;
  line-height: 1.4;
  text-transform: uppercase;
}

/* Drawn in CSS, like the footer's social discs and the How It Works arrows -
   no image asset for a shape this simple. Two bars: the horizontal one is
   permanent, the vertical one is only present while the row is closed, so a
   "+" loses its vertical stroke and becomes a "-" on open. */
.faq-item__icon {
  position: relative;
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
}
.faq-item__icon::before,
.faq-item__icon::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--ink);
  transform: translate(-50%, -50%);
}
.faq-item__icon::before { width: 20px; height: 1.33px; }
.faq-item__icon::after  { width: 1.33px; height: 20px; }

.faq-item[open] .faq-item__icon::after { opacity: 0; }

/* 30 / 1920 = 1.5625vw on all four sides - the same inset the row uses
   horizontally, applied here vertically too since the source panel (120
   tall around a 60px two-line answer) splits its own space the same way. */
.faq-item__panel {
  padding: clamp(20px, 1.5625vw, 30px) clamp(18px, 1.5625vw, 30px);
  background: #f3f3f3;
}

.faq-item__answer {
  margin: 0;
  font-size: 20px;
  font-weight: 400;
  line-height: 1.5;                      /* 30 / 20 */
}

/* ========================================================================
   Contact Us - #282828 band
   Figma frame "Contact Us", 1920x360.5 at y 5808. Everything in it is a single
   880-wide centred group at y 5872.75, 231 tall, so the band's padding is the
   64.75 left over at each end (5808 -> 5872.75, and 6103.75 -> 6168.5).

   The group's five boxes, top and height, frame-absolute:
     eyebrow  5872.75  30   20/30
     title    5908.25  76   50/76, brand ramp
     lede     5975.25  37   24/37
     cue      6032.25  30   20/30
     button   6070.75  33   14/17, ending on 6103.75 = the group's own bottom

   The margins below are box-to-box gaps off those numbers, which is why the
   lede's is negative: Figma sizes a text box to its line-height, so the 50px
   title in a 76px box overhangs the lede's top by 9 while the ink between the
   two still clears by about 10. Spacing off the ink instead would push the
   whole lower half of the group down by that 9.
   ======================================================================== */
.contact {
  /* A one-off band colour, like the pilot tiles - not page palette. */
  background: #282828;
  padding: clamp(38px, 3.3724vw, 64.75px) 0;   /* 64.75 / 1920 */
}

.contact__inner {
  --container: 880px;
  text-align: center;
}

.contact__eyebrow {
  font-family: var(--font-display);
  font-size: clamp(15px, 1.0417vw, 20px);      /* 20 / 1920 */
  font-weight: 700;
  line-height: 1.5;                            /* 30 / 20 */
}

/* The ramp clips to the full 880 box rather than to fit-content as
   .offer__title does, because here the design's gradient box IS the 880 group
   - the line sets in ~835 of it, so the stops land where Figma puts them. */
.contact__title {
  margin: clamp(4px, .2865vw, 5.5px) 0 0;      /* 5.5 / 1920 */
  font-family: var(--font-display);
  font-size: clamp(26px, 2.6042vw, 50px);      /* 50 / 1920 */
  font-weight: 700;
  line-height: 1.52;                           /* 76 / 50 */
  text-transform: uppercase;
  background: var(--brand-gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

/* Forced-colors mode drops background images, and a transparent fill over a
   dropped gradient is an invisible heading rather than a merely uncoloured
   one. Both properties have to come back, in this order. */
@media (forced-colors: active) {
  .contact__title {
    background: none;
    color: CanvasText;
    -webkit-text-fill-color: currentColor;
  }
}

/* max() is the negative's clamp: it caps the overlap at the design's 9px on
   anything 1920 and wider, and eases it back towards 0 as the title narrows
   and eventually wraps. No max-width - the line sets in ~725 of the 880 at the
   design size, and the design's 704 box would only force a wrap. */
.contact__lede {
  margin: max(-9px, -.4688vw) 0 0;             /* -9 / 1920 */
  font-family: var(--font-display);
  font-size: clamp(16px, 1.25vw, 24px);        /* 24 / 1920 */
  font-weight: 700;
  line-height: 1.5417;                         /* 37 / 24 */
}

.contact__cue {
  margin: clamp(12px, 1.0417vw, 20px) 0 0;     /* 20 / 1920 */
  font-family: var(--font-display);
  font-size: clamp(15px, 1.0417vw, 20px);      /* 20 / 1920 */
  font-weight: 700;
  line-height: 1.5;                            /* 30 / 20 */
}

/* A flex row rather than letting the inline-flex button centre itself on a
   text line: the parent's line-height would otherwise add descender space
   under it and the group would overrun its 231. */
.contact__actions {
  display: flex;
  justify-content: center;
  margin-top: clamp(6px, .4427vw, 8.5px);      /* 8.5 / 1920 */
}

/* ========================================================================
   Footer - 57px bar
   Measured from the supplied 1920x57 capture, which is 1:1 with the design
   canvas: the copy's first ink lands on x=241, i.e. the same 240 gutter every
   other band uses.

   Type is 14/400: the string's ink runs 375px, and 14px Inter sets it in 383
   of advance - about 4px of side bearings short of the ink, which is what a
   375px run means. The x-height agrees independently (7.3px measured, 0.517em
   in Inter -> 14.1). The cap measurement is the only one that disagrees, and
   at a 9px cap the antialiasing is worth more than the reading.

   Three groups on one line: copy left, legal centred, social right. A
   1fr / auto / 1fr grid rather than space-between, because space-between
   centres the gaps, not the middle group - and the capture centres the legal
   pair on the row, not between its neighbours.

   The 32px discs set the band's 57px height, so the padding is the 12.5px
   that leaves over. The capture runs them out to x=1800, past the 1680 the
   1440 container ends at; they are pulled back inside it here so the footer
   lines up with every band above it.
   ======================================================================== */
.site-footer {
  background: var(--footer);
  padding: 12.5px 0;
}

.site-footer__contact {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 8px;
  padding-bottom: 12.5px;
  margin-bottom: 12.5px;
  border-bottom: 1px solid rgba(255, 255, 255, .1);
  font-size: 14px;
  line-height: 20px;
}

.site-footer__contact-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--sub-text);
}

.site-footer__contact-link:hover {
  color: var(--orange);
  text-decoration: underline;
}

.site-footer__contact-link svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
  flex-shrink: 0;
}

.site-footer__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  min-height: 32px;
}

.site-footer__copy {
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
}

.site-footer__legal {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  line-height: 20px;
}

.site-footer__legal a:hover { text-decoration: underline; }

/* --rule-strip, the divider colour used elsewhere, lands 15 points off this
   band and the bar disappears; --sub-text reads as a separator without
   pulling weight from the two links. */
.site-footer__sep { color: var(--sub-text); }

.site-footer__social {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-footer__social a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #fff;
  /* The glyph inherits this, so the hover only has to swap two colours. */
  color: var(--footer);
  transition: background-color .15s ease, color .15s ease;
}

.site-footer__social a:hover {
  background: var(--orange);
  color: #fff;
}

.site-footer__social svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

/* The disc is a background, which forced-colors drops - without an outline the
   five glyphs would float on the band with nothing holding them. */
@media (forced-colors: active) {
  .site-footer__social a { border: 1px solid CanvasText; }
}

/* ========================================================================
   Responsive
   ======================================================================== */

/* ---- Desktop only ------------------------------------------------------
   The Figma canvas is very slightly asymmetric: left-aligned content starts at
   x=238 while the right edge of the nav lands on x=1680. The container is kept
   symmetric (1440 centred = 240..1680) and left-aligned content is nudged the
   remaining 2px so both edges land exactly on the design.                    */
@media (min-width: 1200px) {
  .site-header__logo { margin-left: -2px; }
  .hero__content { left: -2px; }
}

/* ---- Below 1280px: the footer row stacks --------------------------------
   Centring the legal pair on the row costs more than it looks: the two 1fr
   tracks either side are equal by definition, so the wider of them - the
   copy, whose ink measures 439px in 14px Inter - has to fit in half of what
   the legal pair leaves. That needs 439 x 2 + 224 + 48 = 1150 of container,
   i.e. 1246 of viewport. 1280 is the first standard width that clears it with
   room to spare; below it the copy would break to two lines beside a legal
   pair meant to sit level with it, so the three groups stack instead.

   Discs first in the stack - a thumb reaches the row above the copy, not the
   one below it.                                                             */
@media (max-width: 1279px) {
  /* The track stays stretched and each group centres its own contents.
     justify-items: center would size the row to max-content instead, and the
     copy - the one group here that has to wrap - would run off a phone. */
  .site-footer__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 16px;
  }
  .site-footer__copy { text-align: center; }
  .site-footer__legal,
  .site-footer__social { justify-content: center; }
  .site-footer__social { order: -1; }
}

/* ---- Below 1300px: credential strip goes two-up ------------------------
   Broken out from the hero-stack breakpoint below because the strip switches
   to the grid earlier than the rest of the hero layout does. 1300 is where
   the one-line row bottoms out: the vw ramp has type at its 13px floor and
   the row still needs ~1150px against a ~1200px container (see the .strip
   comment above). The rules only read as dividers on a single line, and the
   strip is two-up or stacked from here down. */
@media (max-width: 1299px) {
  .strip__sep { display: none; }
  .strip {
    display: grid;
    grid-template-columns: repeat(2, auto);
    justify-content: center;
    justify-items: start;
    gap: 14px 40px;
  }
  .strip__item { font-size: 16px; }
}

/* ---- Below 1200px: hero stacks ----------------------------------------- */
@media (max-width: 1199px) {
  .hero__stage {
    display: flex;
    flex-direction: column;
    gap: 24px;
    min-height: 0;
    padding-top: 32px;
    overflow: visible;
  }
  /* Roughly the left 20% of the hero PNG is empty black - it exists so the
     headline can sit over it in the desktop composition. Once the hero stacks,
     that space is pure waste, so it is cropped back to a ~6% breathing margin.
     The crop is a fraction of --art-w, so it stays proportional to whatever
     width the artwork is given in each tier below. */
  .hero__stage-inner { position: static; inset: auto; overflow: hidden; }
  .hero__visual {
    --art-w: 118%;
    position: static;
    width: var(--art-w);
    max-width: none;
    height: auto;
    margin-left: calc(var(--art-w) * -0.135);
    object-fit: contain;
  }
  .hero__overlay { position: static; pointer-events: auto; }
  .hero__overlay .container { height: auto; }
  .hero__content {
    position: static;
    top: auto;
    transform: none;
    width: 100%;
    max-width: 680px;
  }
  /* One fluid ramp instead of the old 44/36/30 steps - no jumps between
     breakpoints, and the four forced title lines still fit at 320px. */
  .hero__title { font-size: clamp(30px, 5.6vw, 48px); }
  .hero__lede br { display: none; }

  /* Two up. The cap is the design's own pair - 2 x 342 either side of one 64px
     gutter - so each card holds roughly its designed width rather than letting
     the two of them balloon across a tablet-width container. */
  .scale__grid {
    grid-template-columns: repeat(2, 1fr);
    max-width: 748px;
    margin-inline: auto;
  }

  /* Three columns still fit here, but space-between stops being the right
     distributor once the container is narrower than the sum of the designed
     column widths and gaps - it would push the outer two into the gutters.
     Equal columns take over from this width down. */
  .gap__row {
    justify-content: center;
    gap: clamp(20px, 3vw, 40px);
  }
  .gap__item { flex: 1 1 0; }

  /* Two up. The container is capped at the design's own pair - 2 x 358 either
     side of one 42px gutter - rather than the grid, so the cards keep their
     designed width AND the gutter stays the 42 that cqw reads off the row. */
  .pilot__inner { --container: 758px; }
  .pilot__grid { grid-template-columns: repeat(2, 1fr); }
}

/* ---- Below 1080px: the logo strip scales down, still scrolling ---------- */
@media (max-width: 1080px) {
  /* Same fixed 0.75 factor the old six-logo grid used below this width -
     applied here to the gap and to all eleven items, so the strip just runs
     narrower rather than switching layout. */
  .clients__track { gap: 45.75px; }

  .clients__item--jcb      { width: 124.1px; }
  .clients__item--surya    { width: 155.6px; }
  .clients__item--lg       { width: 128.2px; }
  .clients__item--airtel   { width: 146.3px; }
  .clients__item--nissan   { width: 81.4px; }
  .clients__item--nokia    { width: 127.6px; }
  .clients__item--dell     { width: 63px; }
  .clients__item--coke     { width: 84.75px; }
  .clients__item--castrol  { width: 94.5px; }
  .clients__item--walmart  { width: 85.5px; }
  .clients__item--oneindia { width: 96px; }
}

/* ---- Below 900px: the four steps stack ---------------------------------- */
@media (max-width: 900px) {
  /* Four across bottoms out here. At 900 the row hands each circle 173px, and
     the label inside it - a fixed fraction of the circle, by design - has come
     down to 15px with the icon at 45. That is the end of the composition, not
     a tight version of it, so it becomes a column and the arrows turn with it. */
  .flow__row {
    flex-direction: column;
    align-items: center;
    /* 52 rather than the row's 60: the gap now carries the arrow across its
       short axis, and 52 leaves it the air the 60px horizontal gap does. */
    gap: 52px;
    width: 100%;
  }
  /* The circle stops being a fraction of the row and holds its designed 232,
     which is what puts the label back at its designed 20px. The vw term is
     only the floor for phones narrower than ~380px. */
  .flow__step { flex: 0 0 auto; width: min(232px, 68vw); }

  .flow__step:not(:last-child)::after {
    top: calc(100% + 26px);
    left: 50%;
    transform: translate(-50%, -50%) rotate(90deg);
  }
}

/* ---- Tablet / phone ---------------------------------------------------- */
@media (max-width: 767px) {
  .hero__stage { padding-top: 20px; gap: 20px; }
  .hero__lede  { font-size: 15px; line-height: 23px; }
  .hero__actions { flex-wrap: wrap; }

  /* The hero artwork is a single 1486x854 raster. Fitted to a phone it renders
     its column headings at ~4px, so it becomes a horizontally scrollable frame
     held at a legible width instead. 235vw caps the drag at roughly one
     screenful. The negative crop margin is simply clipped here - in LTR the
     scrollable region never extends to the left of the padding box - so the
     frame opens on the artwork itself rather than on its empty margin. */
  .hero__stage-inner {
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--rule-strip) transparent;
  }
  .hero__visual { --art-w: clamp(660px, 235vw, 920px); }

  .strip {
    grid-template-columns: 1fr;
    justify-content: start;
    justify-items: start;
    gap: 12px;
  }
  .strip__item { font-size: 14px; line-height: 20px; }

  /* Line 2 is a 673px line at the design size and about 538 at the 16px floor,
     which stops clearing the container just under 600. Dropping the breaks
     lets all three sentences reflow together instead of leaving one of them
     hard-broken across a ragged fourth line - the sentence colouring on the
     last line carries the rhythm on its own. */
  .offer__lede br { display: none; }

  /* Single column. Capped at 400px so the card never grows so tall that the
     427/342 aspect box pushes the next card a full screen away. */
  .scale__grid {
    grid-template-columns: 1fr;
    max-width: 400px;
    gap: 20px;
  }

  /* One up. Capped at 400 so the card stays near its designed 358 on a large
     phone instead of running the full gutter width. */
  .pilot__grid {
    grid-template-columns: 1fr;
    max-width: 400px;
    margin-inline: auto;
    gap: 20px;
  }

  /* The type inside a card is a share of the card, so a 400px column would set
     the copy at 22px and the heading at 27 - larger than the design's 20/24 on
     a screen with less room for it. Pinned back to the same 17/25 the other
     bands run at this width. */
  .pilot-card__title { font-size: 21px; line-height: 1.3; }
  .pilot-card__desc  { font-size: 17px; line-height: 25px; }

  /* Each column is a full sentence, and three of them side by side at this
     width wrap to five or six lines each - three narrow ragged blocks that no
     longer read as a row. One column per sentence instead. */
  .gap__row {
    flex-direction: column;
    align-items: center;
    max-width: 420px;
    margin-inline: auto;
    gap: 36px;
  }
  .gap__item { flex: 0 1 auto; width: 100%; gap: 20px; }
  .gap__icon { width: 48px; height: 48px; }
  .gap__copy,
  .gap__note { font-size: 17px; line-height: 25px; }

  /* One line at the design size becomes four here, and 20/24 sets them tight
     enough that the block reads as a paragraph rather than a caption. */
  .clients__note { font-size: 17px; line-height: 25px; }

  /* Below ~430px the string wraps to two lines; the padding gives it room. */
  .site-footer { padding: 20px 0; }
  .site-footer__copy,
  .site-footer__legal,
  .site-footer__contact { font-size: 13px; line-height: 19px; }
}

/* ---- Below 560px -------------------------------------------------------- */
@media (max-width: 559px) {
  /* Scale cards go one up here. Two columns leave each card ~210px, and
     inside that the paragraph runs to nine lines beside an icon already sitting
     on its 44px floor - the tile stops reading as a tile. The 420 cap keeps the
     single column near the designed 342 on a large phone. */
  .scale__grid {
    grid-template-columns: 1fr;
    max-width: 420px;
  }
}

/* ---- Small phones ------------------------------------------------------ */
@media (max-width: 479px) {
  .hero__actions .btn { flex: 1 1 100%; }

  .strip__item { white-space: normal; }
  /* Stacked one-up here, so each item only has to clear the container on its
     own - but the AI credential is long enough that a flat size still clips at
     the narrow end. A vw ramp holds it to one line from 320 up. */
  .strip__item--ai { font-size: clamp(11px, 3.6vw, 14px); white-space: nowrap; }
}

/* ---- Landscape phones --------------------------------------------------
   Short viewports where the stacked hero would otherwise push the credential
   strip a long way below the fold.                                          */
@media (max-width: 926px) and (max-height: 500px) and (orientation: landscape) {
  .hero__stage { padding-top: 32px; gap: 28px; }
  .hero__title { font-size: clamp(28px, 4.4vw, 38px); }
  .hero__actions { margin-top: 18px; }
}

/* ---- Motion preferences ------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  html { scroll-behavior: auto !important; }
}

