/* ===== sprio-sticky-fix ===== */
/* workflow-local.css contains  body { overflow-x: hidden }  and that stylesheet
   is only linked on a page that has at least one CMS module section. So adding
   a module turns the body into a scroll container, and every position:sticky
   element on that page stops sticking - the home page's stacked case-study
   cards among them. clip stops sideways scrolling without creating the
   container, so sticky keeps working. */
body { overflow-x: clip !important; }

/* ===== sprio-pinned-header ===== */
body:not(.sprio-editor-active) .sprio-sticky-header.sprio-sticky-header--fixed-hidden,
body:not(.sprio-editor-active) .sprio-sticky-header.sprio-sticky-header--fixed-hidden:not(.sprio-sticky-header--offset-on-sticky) {
  transform: translateY(0) !important;
  top: var(--wp-admin--admin-bar--height, 0px) !important;
  -webkit-backdrop-filter: saturate(180%) blur(40px) !important;
  backdrop-filter: saturate(180%) blur(40px) !important;
}
body:not(.sprio-editor-active) .sprio-sticky-header.sprio-sticky-header--fixed-hidden.sprio-sticky-header--transparent-header {
  background-color: var(--sprio-sticky-header-bg-color) !important;
}

/* ===== sprio-company-pages ===== */
/* ============================================================ page heading
   The services hero is a 637px stage: a gradient, a min-height and two
   call-to-action buttons. That is right for a page selling something and
   wrong for "Leadership" or "Privacy policy" — which is what made all of
   these read as services pages wearing a different title. The heading, the
   breadcrumb and the standfirst are kept; the stage is not. The top padding
   has to clear the pinned header, which is 94px tall. */

.sprio-company .sprio-module--hero-service,
.sprio-company .workflow-enterprise-hero {
  min-height: 0 !important;
  background-image: none !important;
}
.sprio-company .workflow-enterprise-copyblock {
  padding-top: 118px !important;
  padding-bottom: 44px !important;
}
.sprio-company .sprio-module--hero-service {
  border-bottom: 1px solid rgba(3, 3, 7, 0.08);
}

/* ============================================ pages with nothing to sell on */
.sprio-bare .mod-band--logos,
.sprio-bare .mod-band--articles { display: none !important; }

/* ====================================== the blog band opens too far down

   calc(165px + 4vh) — 205px on a normal window — was drawn for the export,
   where this band followed a section that overlapped it. Here it follows an
   ordinary module that has already ended with its own 62px of padding, so the
   two together left the best part of 270px of empty page above "FROM OUR
   BLOG", and the band read as detached rather than as the next thing.

   Cut to the rhythm every other section on the page keeps. The break is still
   there and still clearly a break — it is just a break, not a gap. The foot of
   the band is left alone: nothing was wrong under it, and so are the narrow
   layouts, where the export's own 95 and 80 were already the right size.     */
@media (min-width: 1025px) {
  .sprio-22 .sprio-element.sprio-element-3cdf3c7 {
    --padding-top: clamp(72px, 5.2vw, 90px);
  }
}

/* ============================================== contact: details, not cards
   Three feature cards with big icon tiles is how a services page lists
   capabilities. An address is not a capability: it wants to be read at a
   glance, without decoration competing with it. */

.sprio-p-contact .workflow-ibm-capabilities > article {
  border: 0 !important;
  background: transparent !important;
  padding: 0 28px 0 0 !important;
}
.sprio-p-contact .workflow-ibm-icon {
  width: 26px !important;
  height: 26px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  background: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  margin-bottom: 10px !important;
  padding: 0 !important;
}
.sprio-p-contact .workflow-ibm-icon svg { width: 22px !important; height: 22px !important; }
.sprio-p-contact .workflow-ibm-capabilities > article h3 {
  font-size: 19px !important;
  margin-bottom: 6px !important;
}
.sprio-p-contact .workflow-ibm-capabilities > article p {
  font-size: 14.5px !important;
  line-height: 1.55 !important;
}
/* "See AI services" belongs on a services page, not beside a contact form */
.sprio-p-contact .workflow-enterprise-button-secondary { display: none !important; }

/* ============================================ leadership: people, not tiles
   The use-case card is built to be clicked through to a case study: a wide
   landscape image with an arrow in the corner. A person is a portrait, and
   this card goes nowhere. */

.sprio-p-leadership .workflow-ibm-card-go { display: none !important; }
.sprio-p-leadership .workflow-ibm-card-grid > article { cursor: default !important; }
.sprio-p-leadership .workflow-ibm-card-grid > article img,
.sprio-p-leadership .workflow-ibm-card-grid > article > div:first-child {
  aspect-ratio: 4 / 5 !important;
  height: auto !important;
  min-height: 0 !important;
  object-fit: cover !important;
  object-position: center top !important;
  border-radius: 10px 10px 0 0 !important;
}
/* Until a photograph is uploaded the slot is a flat neutral rather than the
   design's assorted pastel fallbacks, which look like a mistake side by side */
.sprio-p-leadership .workflow-ibm-card-grid > article > div:first-child {
  background-color: #eceaf2 !important;
  background-image: none !important;
}
.sprio-p-leadership .workflow-ibm-card-grid > article > div:first-child:has(img),
.sprio-p-leadership .workflow-ibm-card-grid > article > div:first-child[style*="url"] {
  background-color: transparent !important;
}
.sprio-p-leadership .workflow-ibm-card-grid > article h3 {
  font-size: 19px !important;
  margin-bottom: 4px !important;
}
.sprio-p-leadership .workflow-ibm-card-grid > article p {
  font-size: 14.5px !important;
  line-height: 1.6 !important;
}

/* ============================================ policy pages read as a document
   An accordion is a way of hiding text a reader has to hunt through. A privacy
   policy is read straight down, and somebody looking for one clause should be
   able to use the browser's own find. Every panel is opened and the accordion
   furniture removed, so the page becomes a document. */

.sprio-lean .sprio-module--faq-accordion details[open] > .e-con,
.sprio-lean .sprio-module--faq-accordion details[open] > *:not(summary) {
  display: flex !important;
  height: auto !important;
  max-height: none !important;
  overflow: visible !important;
  opacity: 1 !important;
  visibility: visible !important;
}
.sprio-lean .sprio-module--faq-accordion summary::marker,
.sprio-lean .sprio-module--faq-accordion summary::-webkit-details-marker { display: none !important; }
.sprio-lean .sprio-module--faq-accordion .sprio-theme-arrow-solid-down,
.sprio-lean .sprio-module--faq-accordion .sprio-theme-arrow-solid-up,
.sprio-lean .sprio-module--faq-accordion [class*="arrow"] { display: none !important; }
.sprio-lean .sprio-module--faq-accordion summary { cursor: default !important; pointer-events: none !important; }

/* The FAQ module sets its heading beside the questions, which leaves a policy
   document in the right-hand half of the page with 340px of nothing beside it.
   Stacked, the clauses get the full measure.

   Written as a descendant selector rather than a child one: the flex row that
   does the splitting is five levels inside the module, not directly under it,
   so "> .e-con" matched nothing at all and the column stayed 628px wide. */
.sprio-lean .sprio-module--faq-accordion .e-con.e-parent {
  flex-direction: column !important;
  align-items: stretch !important;
}
.sprio-lean .sprio-module--faq-accordion .e-con.e-parent > .e-con,
.sprio-lean .sprio-module--faq-accordion .e-con.e-parent > .sprio-element {
  width: 100% !important;
  max-width: 100% !important;
  flex: 0 0 auto !important;
}

/* The module offers a link beside its heading, and this page has no use for
   one — it renders as a black rectangle sitting on its own.

   One selector per rule on purpose: an unsupported selector anywhere in a
   comma-separated list makes the browser drop the WHOLE list. The first
   version paired this with ":blank", which Chromium does not support, so
   neither half applied and the rectangle stayed on the page. */
.sprio-lean .sprio-module--faq-accordion a:empty { display: none !important; }
.sprio-lean .sprio-module--faq-accordion .workflow-enterprise-button:empty { display: none !important; }
.sprio-lean .sprio-module--faq-accordion .mod-btn:empty { display: none !important; }

/* ===== sprio-case-lab-module ===== */
/* ====================================================== the case study deck

   /theme/sprio-case-lab.css already draws the cards themselves; it is loaded
   on every page. What it does not know about is the module's own wrapper,
   which is a three-column grid inside a 1280px column. The deck is one wide
   column, so the wrapper has to stop being a grid and stop being narrow —
   only on the section that actually carries a deck. */

.sprio-module--case-studies.sprio-has-deck .workflow-ibm-case-studies {
  display: block !important;
  width: min(1820px, calc(100vw - 226px)) !important;
  max-width: none !important;
  margin-left: auto !important;
  margin-right: auto !important;
  grid-template-columns: none !important;
}

/* The heading block sits above the deck rather than beside it, the way the
   home page has it: label, heading, one line, then the cards. */
.sprio-module--case-studies.sprio-has-deck :is(.mod-kicker, h2, .mod-standfirst) {
  grid-column: auto !important;
  text-align: center;
  max-width: 760px;
  margin-left: auto;
  margin-right: auto;
}

.sprio-module--case-studies.sprio-has-deck .sprio-scroll-stack { margin-top: clamp(28px, 3vw, 48px); }

/* ------------------------------------- the hole underneath the case studies

   The deck works by giving every card a tall bottom margin — that margin is
   the scrolling distance in which the next card climbs over it. The last card
   has one too, plus the stack has its own tail below that, and neither is
   doing any work: there is no fourth card to make room for. Together they left
   about 250px of empty page between the last case study and the next section,
   which is why that one join looked wrong when every other join is the same.

   Both are taken away. The section then ends where its content ends, and the
   space to the next module is the module padding, exactly like everywhere
   else. The cards above still stack, because their margins are untouched. */

.sprio-module--case-studies.sprio-has-deck .sprio-scroll-stack { padding-bottom: 0; }
.sprio-module--case-studies.sprio-has-deck .sprio-stack-card:last-child { margin-bottom: 0; }

/* The scroll room the last card pins in — see the note in sprio-local.js. It
   has to be longer than the gap between two cards, or the last card reaches
   its position only after the two above it have already let go, and the three
   are never level. Nothing is drawn here: what fills the screen during it is
   the finished stack, held still. */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-tail {
  height: clamp(240px, 28vh, 380px);
  pointer-events: none;
}

/* One column, one card on screen at a time: there is no stack to hold level
   and the room would only be an empty scroll. */
@media (max-width: 1100px) {
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-tail { height: 0; }
}

/* A deck card is its own coloured surface. The module's own card rules are
   written as  .sprio-module--case-studies .workflow-ibm-case-studies article
   — two classes and a type, which outranks the single .sprio-stack-card the
   deck's stylesheet uses, so a deck card came out white, square and not
   sticky. Everything the deck needs is restated here at a higher specificity
   rather than sprinkled with !important on the other side. */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-card {
  position: sticky;
  top: 42px;
  display: flex;
  flex-direction: column;
  isolation: isolate;
  width: calc(100% - var(--deck-peek, 0px));
  /* 660 was a guess, and a guess that no card's content ever reached: it left
     a quarter of every card empty below the writing. The script measures the
     deepest card in the set and gives them all that height, so the cards still
     match each other but none of them is taller than it has anything to say.
     The old fixed value stays as the fallback for a browser that never runs
     the script. */
  min-height: var(--deck-card-min, min(660px, calc(100vh - 86px)));
  margin: 0 0 18vh var(--deck-peek, 0px);
  padding: 36px 40px 34px;
  border: 1px solid rgba(3, 3, 7, 0.08);
  border-radius: 26px;
  overflow: hidden;
  box-shadow: 0 26px 78px rgba(25, 24, 32, 0.13);
  transform: translateY(var(--stack-offset, 0px));
}

/* ---------------------------------------------- the three card tints

   These used to be violet, blue and green. Measured against the brand violet
   (#6904f2) the green sat 138 degrees away in hue, nearly opposite it, and was
   also the most saturated of the three: the least brand-like colour given the
   loudest treatment, which is why the eye went straight to it.

   The set below is anchored on the brand instead. All three sit at the same
   lightness and the same chroma, spaced either side of the brand hue, so no
   one card shouts over the others:

     violet  288 degrees, the brand's own hue
     blue    233
     pink    343

   Every one of them clears 12:1 against the near-black text on the cards.

   To go back to a green third card rather than a pink one, put #9edcaa in
   --tint-3 below. That is the old green brought to the same lightness and
   chroma as the other two, so it stops dominating, though it is still an
   off-brand hue. The class name in sprio-local.js would want renaming too.

   The same three colours are used by three other card families as well: the
   industries row, the workflow card grids, and the case lab. They are all
   repointed at these variables further down, because changing the deck alone
   would leave a green card sitting two sections above a pink one. */
:root {
  --tint-1: #c7c1ff; /* violet, the brand hue */
  --tint-2: #89d6ff; /* blue   */
  --tint-3: #f7b2db; /* pink   */
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-card--violet { background: var(--tint-1); }
.sprio-module--case-studies.sprio-has-deck .sprio-stack-card--blue   { background: var(--tint-2); }
.sprio-module--case-studies.sprio-has-deck .sprio-stack-card--pink   { background: var(--tint-3); }

/* The plain cards lift 5px on hover. A card that is holding its position
   under the one above it must not move at all. */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-card:hover {
  transform: translateY(var(--stack-offset, 0px));
  border-color: rgba(3, 3, 7, 0.08);
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-card.is-visible {
  box-shadow: 0 32px 88px rgba(25, 24, 32, 0.16);
  transform: translateY(calc(var(--stack-offset, 0px) - 8px));
}

/* the photograph band the plain card draws above its words */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-card::before { content: none !important; }

@media (max-width: 1200px) {
  .sprio-module--case-studies.sprio-has-deck .workflow-ibm-case-studies {
    width: min(1120px, calc(100vw - 42px)) !important;
  }
}

@media (max-width: 767px) {
  .sprio-module--case-studies.sprio-has-deck .workflow-ibm-case-studies {
    width: calc(100vw - 28px) !important;
  }
}

/* ===== sprio-page-rhythm ===== */
/* ================================================== the rhythm of the page

   Every module carried up to 104px of padding at the top and the same at the
   bottom, so two sections in a row put 208px of nothing between them. On a
   long page that reads as the page having stalled rather than as breathing
   room. Two thirds of it is enough to keep the sections separate. */

/* The two exclusions matter. The banner and any edge-to-edge band set
   padding:0 on themselves with a single class, and this rule carries two, so
   without the :not() it wins and pushes a strip of blank page in above the
   violet ribbon — which is what "the ribbon has come down" looks like. */
body.sprio-modules .sprio-module:not(.sprio-module--hero-service):not(.sprio-module--bleed) {
  padding-top: clamp(44px, 3.6vw, 68px);
  padding-bottom: clamp(44px, 3.6vw, 68px);
}

/* The first section after the banner sits closer to it: the banner is already
   a full stop. */
body.sprio-modules .sprio-module--hero-service + .sprio-module:not(.sprio-module--bleed) { padding-top: clamp(30px, 2.4vw, 44px); }

/* ------------------------------------------ the two joins that were not level

   Modules space themselves with their own padding, so every join between two
   of them is the same. Two joins on the page are not between two modules, and
   both were bigger than the rest:

   The client logo band is a theme block, not a module, and it carries a 101px
   tail of its own. That tail plus the next module's padding made the join
   under the logos half again as deep as every other join on the page.

   The contact block is edge to edge, so it sets its own padding to nothing —
   which lets the same 101px tail escape out of the bottom of it and land
   between the block and whatever follows.

   Both are set to the module's own spacing, so the join above them and the
   join below them are the same distance as everywhere else. */

body.sprio-modules .sprio-module--hero-service + .sprio-element,
body.sprio-modules .sprio-module--contact-form > .sprio-element {
  margin-bottom: clamp(44px, 3.6vw, 68px) !important;
}

/* ------------------------------------------------- the four capability tiles

   reveal="on" holds the card's body back until the reader points at it, and
   fills the card with the brand violet. On this row the fill is the brand
   blue instead — the family the site's own blue band is drawn from, which the
   theme puts around #303cb4. White type on it clears AA comfortably.

   Written with the module class in front so it outranks the theme's own
   .opt-reveal-on rule rather than fighting it with !important. */

@media (hover: hover) and (pointer: fine) {
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article:hover,
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article:focus-within {
    background: #303cb4;
    border-color: #303cb4;
  }
}

/* ===== sprio-no-crumbs ===== */
/* ================================================== the breadcrumb, per page

   Hidden rather than deleted, and hidden in the stylesheet rather than by
   script, so the row never draws and then disappears — a flicker at the top of
   the banner is worse than the breadcrumb itself.

   Which pages is the noCrumbs list in the script above. */

.sprio-no-crumbs .workflow-enterprise-breadcrumb { display: none !important; }

/* The breadcrumb carried the gap between itself and the headline, so taking it
   away leaves the headline sitting high against the ribbon. This puts that air
   back as padding on the block instead. */
.sprio-no-crumbs .workflow-enterprise-copyblock { padding-top: clamp(88px, 9vw, 132px) !important; }

/* ===== sprio-stack-logo-image ===== */
/* ============================================ the client logo on a case card

   The deck's stylesheet draws the mark in the corner of a card with two CSS
   shapes on an empty span, which is why uploading a picture appeared to do
   nothing: there was no image on the card for it to become. When a card has a
   picture, the span is swapped for a real <img> and sized to sit on the same
   baseline as the drawn shape it replaces. */

.sprio-stack-brand .sprio-stack-logo--img {
  width: auto;
  height: 40px;
  max-width: 160px;
  object-fit: contain;
  object-position: left center;
}

@media (max-width: 767px) {
  .sprio-stack-brand .sprio-stack-logo--img { height: 30px; max-width: 120px; }
}

/* ===== sprio-no-ribbon ===== */
/* ================================================== the ribbon, switched off

   Hidden in the stylesheet rather than removed by script, so on the pages that
   do not want it the strip is never drawn at all — no flash of violet before it
   disappears.

   The banner keeps its own top edge either way: the ribbon sits above the copy
   block rather than inside it, so taking it away closes the gap without moving
   anything else. */

.sprio-no-ribbon .workflow-enterprise-alert { display: none !important; }

/* ---------------------------------------------------------- the call bar

   The page keeps its own ribbon words. The ask is added after them, and it has
   to look like a different kind of thing or the strip reads as one long
   sentence that happens to end in a phone number. So it is a quiet pill: a
   thin outline, a little smaller than the sentence beside it, sitting on the
   strip rather than shouting over it.

   The size is set in em, so it stays smaller than the ribbon copy at every
   width instead of being pinned to one number that is right on a laptop and
   wrong on a large monitor. */

.workflow-enterprise-alert .sprio-callbar {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  flex-wrap: wrap;
  padding: 0.42em 0.95em;
  border: 1px solid rgba(255, 255, 255, 0.32);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  font-size: max(13px, 0.62em);
  font-weight: 500;
  line-height: 1.25;
}

/* The theme gives every link inside this strip the arrow's treatment — 32px,
   and glued to the top right corner on a phone. That is what made the number
   look the way it did. Both are undone here by name, not by weakening the
   theme's rule, which the arrow on other pages may still want. */

.workflow-enterprise-alert a.sprio-callbar-number {
  position: static !important;
  right: auto !important;
  top: auto !important;
  font-size: 1em !important;
  line-height: inherit !important;
  font-weight: 700;
  color: #fff !important;
  text-decoration: none !important;
  white-space: nowrap;
}

.workflow-enterprise-alert a.sprio-callbar-number:hover,
.workflow-enterprise-alert a.sprio-callbar-number:focus {
  text-decoration: underline !important;
  text-underline-offset: 3px;
}

/* With the arrow gone the row has one thing less to space out, so the words
   and the ask sit together rather than drifting to opposite ends. */
.workflow-enterprise-alert { gap: clamp(10px, 1.4vw, 22px) !important; }

/* On a phone the strip stacks, and a pill pinned to the left under the message
   is the right shape. It just needs a little air above it. */
@media (max-width: 767px) {
  .workflow-enterprise-alert .sprio-callbar { margin-top: 2px; }
}

/* ===== sprio-deck-card-v2 =====

   The case study card, rearranged.

   The old card put the figure in the middle of the body, beside a drawn
   arrow, with the client's name up in the header next to the title. Three
   things competed for the top-left corner and the number — the only reason
   anyone reads a case study — sat in the quietest part of the card.

   So the card becomes two columns. The left one is the claim, read top to
   bottom: which case this is, what was done, who for, and the figure, set
   large at the bottom where the eye lands last and stays. The right one is
   the evidence: problem, approach, outcome, each with its label in a narrow
   column of its own so the three read as a set rather than as prose.

   Done by rearranging what the module already renders — the wrappers become
   display:contents so their children join the card's own grid — so nothing
   changes in the markup or the CMS, only where each part sits. */

.sprio-module--case-studies.sprio-has-deck .sprio-stack-card {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr);
  grid-template-rows: auto auto auto 1fr auto auto;
  column-gap: clamp(24px, 3vw, 56px);
  row-gap: 0;
  align-content: start;
  padding: clamp(28px, 2.8vw, 44px);
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-head,
.sprio-module--case-studies.sprio-has-deck .sprio-stack-body {
  display: contents;
}

/* ---- the left column: the claim */

.sprio-module--case-studies.sprio-has-deck .sprio-stack-number {
  grid-column: 1;
  grid-row: 1;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  font-variant-numeric: tabular-nums;
  opacity: 0.72;
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-head h4 {
  grid-column: 1;
  grid-row: 2;
  margin: 12px 0 16px;
  font-size: clamp(23px, 2.1vw, 33px);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.028em;
  text-wrap: balance;
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-badges {
  grid-column: 1;
  grid-row: 3;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-badge {
  padding: 5px 12px;
  border: 1px solid rgba(5, 5, 8, 0.22);
  border-radius: 999px;
  background: transparent;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* The figure. Sits at the bottom of the column — row 4 is the one that
   stretches, so the block is pushed down however tall the card grows. */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-visual {
  grid-column: 1;
  grid-row: 4;
  align-self: end;
  display: block;
  padding: 34px 0 0;
  background: none;
  border: 0;
}

/* the drawn arrow: it pointed at nothing */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-arrow { display: none !important; }

.sprio-module--case-studies.sprio-has-deck .sprio-stack-metric {
  display: block;
  padding: 0;
  background: none;
  border: 0;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-metric strong {
  display: block;
  font-size: clamp(50px, 6vw, 88px);
  font-weight: 500;
  line-height: 0.94;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-metric span {
  display: block;
  margin-top: 8px;
  font-size: 16px;
  line-height: 1.4;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-visual > p {
  margin: 10px 0 0;
  font-size: 14.5px;
  opacity: 0.72;
}

/* who it was for, under the figure */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-brand {
  grid-column: 1;
  grid-row: 5;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 0 0;
  font-size: 14px;
  font-weight: 600;
}

/* ---- the right column: the evidence

   It used to be centred across the middle five rows, which left a quarter of
   the card — 230 to 290 empty pixels — below it, and made the card look like
   it was hanging down past its own contents. The evidence now runs the full
   depth of the card and divides the space between its three parts, so the
   column ends where the card ends and the three read as one list rather than
   three paragraphs floating in the middle.                                   */

.sprio-module--case-studies.sprio-has-deck .sprio-stack-copy {
  grid-column: 2;
  grid-row: 1 / -1;
  align-self: stretch;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(18px, 2.2vh, 32px);
  padding: 4px 0 2px;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-copy section {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  gap: 16px;
  margin: 0;
}

/* A hairline between them, so the space that divides the three parts reads as
   structure rather than as a gap that was left over. */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-copy section + section {
  border-top: 1px solid rgba(5, 5, 8, 0.16);
  padding-top: clamp(18px, 2.2vh, 32px);
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-copy h5 {
  margin: 0;
  padding-top: 3px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-copy p {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.58;
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-link {
  grid-column: 1;
  grid-row: 6;
  justify-self: start;
  margin-top: 22px;
  font-size: 14px;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 4px;
}

@media (max-width: 1100px) {
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-card {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto;
  }
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-number,
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-head h4,
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-badges,
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-visual,
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-brand,
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-copy,
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-link {
    grid-column: 1;
    grid-row: auto;
    align-self: auto;
  }
  /* Stacked in one column there is no second column to fill, so the evidence
     simply follows the figure instead of spreading itself down the card. */
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-copy {
    margin-top: 26px;
    justify-content: flex-start;
    padding: 0;
  }
}

@media (max-width: 720px) {
  .sprio-module--case-studies.sprio-has-deck .sprio-stack-copy section {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
  }
}

/* ===== sprio-capability-tiles-v2 =====

   The four things the platform does, as one band rather than four cards.

   Cards with borders and icons made these read as four unrelated features.
   They are not: they are the four halves of one answer to "why does this
   work". So the band is a single dark plane divided by hairlines, each
   panel carrying only its name until somebody points at it — at which
   point that one panel fills with the brand blue and explains itself.

   The numbers come from a CSS counter, so they follow the panels rather
   than being typed into the CMS and going stale when one is reordered. */

body.sprio-modules .sprio-module--integration-grid.opt-reveal-on {
  background: #050508;
  color: #fff;
}
.sprio-module--integration-grid.opt-reveal-on .mod-kicker { color: #d9bdff; }
.sprio-module--integration-grid.opt-reveal-on h2 { color: #fff; }
.sprio-module--integration-grid.opt-reveal-on .mod-standfirst { color: rgba(255, 255, 255, 0.74); }

/* heading on the left, the paragraph answering it on the right */
@media (min-width: 1000px) {
  .sprio-module--integration-grid.opt-reveal-on .mod-integrations {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 32px;
    align-items: end;
  }
  .sprio-module--integration-grid.opt-reveal-on .mod-kicker { grid-column: 1; }
  .sprio-module--integration-grid.opt-reveal-on h2 { grid-column: 1; margin-top: 14px; }
  .sprio-module--integration-grid.opt-reveal-on .mod-standfirst {
    grid-column: 2;
    grid-row: 1 / 3;
    align-self: end;
    max-width: 52ch;
  }
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid { grid-column: 1 / -1; }
}

.sprio-module--integration-grid.opt-reveal-on .mod-integration-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  margin-top: clamp(32px, 3.4vw, 52px);
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.16);
  counter-reset: sprio-tile;
}

.sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article {
  counter-increment: sprio-tile;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 268px;
  margin: 0;
  padding: 26px 24px;
  background: #050508;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  transition: background 200ms ease;
}

.sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article::before {
  content: counter(sprio-tile, decimal-leading-zero);
  position: absolute;
  top: 22px;
  left: 24px;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.5);
  font-variant-numeric: tabular-nums;
}

/* the icon tile: the name is the whole point of a panel this size */
.sprio-module--integration-grid.opt-reveal-on .mod-integration-grid .workflow-ibm-icon {
  display: none !important;
}

.sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article h3 {
  margin: 0;
  color: #fff;
  font-size: clamp(19px, 1.6vw, 24px);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article p {
  margin: 0;
  color: rgba(255, 255, 255, 0.74);
  font-size: 14.5px;
  line-height: 1.55;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 240ms ease, opacity 200ms ease, margin-top 240ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article:hover,
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article:focus-within {
    background: #303cb4;
  }
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article:hover p,
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article:focus-within p {
    max-height: 260px;
    opacity: 1;
    margin-top: 12px;
  }
}

/* No hover on a touch screen, so the words are simply there. */
@media (hover: none) {
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article p {
    max-height: none;
    opacity: 1;
    margin-top: 12px;
  }
}

@media (max-width: 1100px) {
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 640px) {
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article {
    min-height: 0;
    padding-top: 52px;
  }
}

/* ----- the properties the deck's own stylesheet still had hold of
   Each line here is undoing one rule in sprio-case-lab.css that the
   rearrangement above left in place: the title was centred, the client's
   name pinned to the right, the figure sitting inside a 400px-tall white
   panel, the evidence carrying a 6px rule down its side and 82px of
   padding under it, and the link positioned absolutely into the bottom
   right corner. */

.sprio-module--case-studies.sprio-has-deck .sprio-stack-card { text-align: left; }

.sprio-module--case-studies.sprio-has-deck .sprio-stack-head h4 {
  max-width: none;
  text-align: left;
  font-weight: 500;
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-brand {
  justify-self: start;
  white-space: normal;
  line-height: 1.3;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-brand .sprio-stack-logo--img {
  height: 26px;
  max-width: 92px;
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-visual {
  position: static;
  min-height: 0;
  overflow: visible;
  border-radius: 0;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-visual > p {
  max-width: 42ch;
  font-size: 14.5px;
  font-weight: 400;
  line-height: 1.5;
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-copy {
  align-content: stretch;
  padding-bottom: 0;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-copy section {
  max-width: none;
  padding-left: 0;
  border-left: 0;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-copy h5 {
  margin: 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  line-height: 1.3;
  color: inherit;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-copy p {
  max-width: 60ch;
  font-size: 15.5px;
  line-height: 1.58;
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-link {
  position: static;
  right: auto;
  bottom: auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: inherit;
  font-size: 14px;
  font-weight: 600;
  gap: 8px;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-link span { font-size: 1em; }

/* The old card's decoration: a 58px drawn arrow pointing across the panel,
   and two large shapes behind the link. Both belonged to a layout where the
   figure sat inside its own framed box. They are drawn with pseudo-elements,
   so hiding the elements is not enough — the content itself is dropped. */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-arrow,
.sprio-module--case-studies.sprio-has-deck .sprio-stack-arrow::before,
.sprio-module--case-studies.sprio-has-deck .sprio-stack-arrow::after {
  display: none !important;
  content: none !important;
}
.sprio-module--case-studies.sprio-has-deck .sprio-stack-link::before,
.sprio-module--case-studies.sprio-has-deck .sprio-stack-link::after {
  content: none !important;
}

/* ----- the band has to be a band
   .sprio-module is a centred 1280px column, so a background on it stops at
   the text edge and the dark plane reads as a stripe behind the tiles with
   the heading stranded on white above it — white type on white ground.
   The section breaks out to the full window and puts the column width back
   as its own side padding, so the ink runs edge to edge and the heading
   sits on it. */
.sprio-module--integration-grid.opt-reveal-on {
  width: 100vw !important;
  max-width: 100vw !important;
  margin-left: calc(50% - 50vw) !important;
  margin-right: calc(50% - 50vw) !important;
  padding-left: max(24px, calc(50vw - var(--wf-stack, 1280px) / 2)) !important;
  padding-right: max(24px, calc(50vw - var(--wf-stack, 1280px) / 2)) !important;
  background: #050508 !important;
  color: #fff;
}

/* the link sat away from the column edge it should line up with */
.sprio-module--case-studies.sprio-has-deck .sprio-stack-link { margin-left: 0; }

/* ----- the words on the dark band
   The module's own stylesheet colours its heading, kicker and standfirst
   for a light ground, with selectors carrying the same weight as these, so
   on the ink plane the heading was near-black on near-black and the kicker
   was brand violet on it — invisible, both. Stated as final here because
   the ground is now fixed and the contrast has to hold with it. */
.sprio-module--integration-grid.opt-reveal-on .mod-kicker { color: #d9bdff !important; }
.sprio-module--integration-grid.opt-reveal-on h2,
.sprio-module--integration-grid.opt-reveal-on h2 * { color: #ffffff !important; }
.sprio-module--integration-grid.opt-reveal-on .mod-standfirst,
.sprio-module--integration-grid.opt-reveal-on .mod-standfirst * { color: rgba(255, 255, 255, 0.74) !important; }
.sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article h3 { color: #ffffff !important; }
.sprio-module--integration-grid.opt-reveal-on .mod-integration-grid article p { color: rgba(255, 255, 255, 0.74) !important; }

/* The heading and kicker were still being coloured for a light ground by a
   rule that outranked the one above. Restated at the specificity of the
   thing that was winning rather than by piling on more !important. */
body.sprio-modules .sprio-module--integration-grid.opt-reveal-on .mod-integrations > h2,
body.sprio-modules .sprio-module--integration-grid.opt-reveal-on .mod-integrations > h2 * {
  color: #ffffff !important;
}
body.sprio-modules .sprio-module--integration-grid.opt-reveal-on .mod-integrations > .mod-kicker {
  color: #d9bdff !important;
}
body.sprio-modules .sprio-module--integration-grid.opt-reveal-on .mod-integrations > .mod-standfirst {
  color: rgba(255, 255, 255, 0.74) !important;
}

/* ===================================================== the client quotes

   One quote at a time, centred, with the one before and the one after showing
   at the edges so the set reads as a set rather than as a single card that
   happens to change. Arrows and dots underneath; drag on touch.

   Deliberately not a scroll container. The industries row taught that a native
   horizontal scroller lying across the page catches a trackpad flick and stops
   the page dead. This moves by transform only, so the wheel always belongs to
   the page and nothing can trap the reader.                                  */

.sprio-quotes {
  --q-slide: min(720px, 60vw);
  --q-gap: clamp(16px, 1.6vw, 26px);
  width: 100%;
  padding: clamp(56px, 5vw, 86px) 0 clamp(40px, 3.6vw, 62px);
}

.sprio-quotes-title {
  margin: 0 0 clamp(28px, 3vw, 46px);
  text-align: center;
  color: #030307;
  font-size: clamp(30px, 3.1vw, 46px);
  font-weight: 500;
  line-height: 1.06;
  letter-spacing: -0.03em;
}

.sprio-quotes-viewport {
  overflow: hidden;
  /* the peeking neighbours are clipped by the window, not by a box with edges */
  padding: 6px 0;
}

.sprio-quotes-track {
  display: flex;
  gap: var(--q-gap);
  align-items: stretch;
  will-change: transform;
  transition: transform 620ms cubic-bezier(0.22, 0.61, 0.36, 1);
  /* a vertical drag is the page's, always */
  touch-action: pan-y;
}

.sprio-quotes[data-dragging="1"] .sprio-quotes-track { transition: none; }

.sprio-quote {
  flex: 0 0 var(--q-slide);
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  padding: clamp(30px, 2.6vw, 44px);
  background: #fff;
  border: 1px solid rgba(3, 3, 7, 0.1);
  /* the neighbours are present but plainly not the one being read */
  opacity: 0.32;
  transform: scale(0.965);
  transition: opacity 420ms ease, transform 520ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.sprio-quote[data-current="1"] {
  opacity: 1;
  transform: none;
  box-shadow: 0 26px 64px rgba(25, 24, 32, 0.09);
}

.sprio-quote-mark {
  margin: -10px 0 6px;
  color: var(--wf-violet, #6904f2);
  font-size: 58px;
  line-height: 0.6;
  font-weight: 500;
}

.sprio-quote-text {
  margin: 0 0 auto;
  color: #030307;
  font-size: clamp(17px, 1.28vw, 21px);
  line-height: 1.5;
  letter-spacing: -0.005em;
}

.sprio-quote-text p { margin: 0 0 12px; }
.sprio-quote-text p:last-child { margin-bottom: 0; }

.sprio-quote-by {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: clamp(24px, 2.4vw, 36px);
  padding-top: clamp(18px, 1.8vw, 26px);
  border-top: 1px solid rgba(3, 3, 7, 0.1);
}

.sprio-quote-face {
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 999px;
  object-fit: cover;
  background: #eceaf2;
}

/* a face that will not load is a grey ring, not a broken-image box */
.sprio-quote-face[data-broken="1"] { visibility: hidden; width: 0; margin-right: -14px; }

.sprio-quote-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sprio-quote-who strong { color: #030307; font-size: 16px; font-weight: 600; line-height: 1.2; }
.sprio-quote-who span { color: rgba(3, 3, 7, 0.56); font-size: 14px; line-height: 1.3; }

/* ------------------------------------------------------------- the controls */

.sprio-quotes-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  margin-top: clamp(26px, 2.6vw, 40px);
}

.sprio-quotes-btn {
  display: grid !important;
  place-items: center;
  width: 46px !important;
  height: 46px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  border: 1px solid rgba(3, 3, 7, 0.16) !important;
  border-radius: 999px !important;
  background: #fff !important;
  background-image: none !important;
  box-shadow: none !important;
  color: #030307 !important;
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, color 160ms ease;
}

.sprio-quotes-btn svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sprio-quotes-btn:hover:not(:disabled),
.sprio-quotes-btn:focus-visible {
  border-color: var(--wf-violet, #6904f2) !important;
  color: var(--wf-violet, #6904f2) !important;
  outline: none;
}

.sprio-quotes-btn:disabled { opacity: 0.3; cursor: default; }

.sprio-quotes-dots { display: flex; align-items: center; gap: 9px; }

/* The theme paints every <button> on the page black with a pill radius, which
   turned these into five black slabs. Forced, like the rail buttons. */
.sprio-quotes .sprio-quotes-dot {
  width: 8px !important;
  height: 8px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 999px !important;
  background: rgba(3, 3, 7, 0.2) !important;
  background-image: none !important;
  box-shadow: none !important;
  font-size: 0;
  cursor: pointer;
  transition: width 260ms ease, background-color 200ms ease;
}

.sprio-quotes .sprio-quotes-dot[aria-selected="true"] {
  width: 26px !important;
  background: var(--wf-violet, #6904f2) !important;
}
.sprio-quotes .sprio-quotes-dot:focus-visible { outline: 2px solid var(--wf-violet, #6904f2); outline-offset: 3px; }

/* one card at a time once there is no room for neighbours to peek */
@media (max-width: 900px) {
  .sprio-quotes { --q-slide: min(560px, 84vw); }
}

@media (max-width: 560px) {
  .sprio-quotes { --q-slide: 86vw; }
  .sprio-quote { opacity: 0.5; }
}

@media (prefers-reduced-motion: reduce) {
  .sprio-quotes-track,
  .sprio-quote { transition: none; }
}

/* ============================================== the logo rows, moving

   A row of client marks that sits still is a list. A row that travels reads as
   a roster too long to fit — which is the point of showing it. One row, one
   direction, no controls, no stops: the reader is not meant to operate it.

   Every mark is still its own image field in the admin. The copies that make
   the loop seamless are made in the browser and carry no CMS attributes, so
   editing the row still edits one logo, not three.                           */

.sprio-marquee {
  position: relative;
  overflow: hidden;
  /* The row inside is deliberately wider than the page. Without min-width the
     flex parent sizes itself to that content and the strip stops clipping —
     measured at 6736px wide inside a 1440px window. */
  flex: 1 1 100%;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  /* the ends fade rather than cut, so a mark never appears to be sliced */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 5%, #000 95%, transparent);
}

.sprio-marquee-row {
  display: flex;
  align-items: center;
  gap: clamp(38px, 4.4vw, 74px);
  width: max-content;
  padding: 4px 0;
}

/* Set by the script once it knows how wide one pass is. Without it the row
   simply sits there, which is what a browser with no JavaScript should see. */
.sprio-marquee[data-marquee-ready="1"] .sprio-marquee-row {
  animation: sprio-marquee-left var(--marquee-seconds, 40s) linear infinite;
}

.sprio-marquee[data-marquee-ready="1"][data-marquee-dir="right"] .sprio-marquee-row {
  animation-name: sprio-marquee-right;
}

.sprio-marquee:hover .sprio-marquee-row { animation-play-state: paused; }

@keyframes sprio-marquee-left {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(calc(-1 * var(--marquee-pass, 50%)), 0, 0); }
}

@keyframes sprio-marquee-right {
  from { transform: translate3d(calc(-1 * var(--marquee-pass, 50%)), 0, 0); }
  to { transform: translate3d(0, 0, 0); }
}

.sprio-marquee-cell {
  display: flex;
  align-items: center;
  flex: none;
}

.sprio-marquee-cell img {
  display: block;
  width: auto;
  height: clamp(26px, 2.4vw, 38px);
  max-width: none;
  object-fit: contain;
}

/* The theme sets every h2 on the page to 46px with 6px of tracking. This one
   is a label above a logo row, not a section heading, so it is forced back to
   the small uppercase line the design always had there. */
.sprio-22 .sprio-element .sprio-marquee-title,
.sprio-marquee-title {
  width: 100%;
  margin: 0 0 clamp(22px, 2.4vw, 38px) !important;
  text-align: center !important;
  color: rgba(3, 3, 7, 0.5) !important;
  font-size: 13px !important;
  font-weight: 600 !important;
  letter-spacing: 0.14em !important;
  line-height: 1.2 !important;
  text-transform: uppercase !important;
}

/* ---------------------------------------------- the stack strip, labelled */

.sprio-stackbar {
  display: flex;
  align-items: center;
  gap: clamp(20px, 2.4vw, 40px);
  width: 100%;
  padding: clamp(18px, 1.8vw, 26px) clamp(20px, 2.4vw, 34px);
  border: 1px solid rgba(3, 3, 7, 0.1);
  background: #fff;
}

.sprio-stackbar-label {
  flex: none;
  padding-right: clamp(20px, 2.4vw, 40px);
  border-right: 1px solid rgba(3, 3, 7, 0.1);
  color: #030307;
  font-size: clamp(15px, 1.15vw, 18px);
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
}

.sprio-stackbar .sprio-marquee { flex: 1 1 auto; width: auto; min-width: 0; }

@media (max-width: 640px) {
  .sprio-stackbar { flex-direction: column; align-items: stretch; gap: 14px; }
  .sprio-stackbar-label { padding: 0 0 12px; border-right: 0; border-bottom: 1px solid rgba(3, 3, 7, 0.1); }
}

/* Motion that carries no information is the first thing to go. */
@media (prefers-reduced-motion: reduce) {
  .sprio-marquee[data-marquee-ready="1"] .sprio-marquee-row { animation: none; }
  .sprio-marquee-row { flex-wrap: wrap; justify-content: center; width: 100%; }
}

/* ---------------------------------------------- the quotes: forced controls */

/* The theme rounds nothing — border-radius: 0 !important on a long list of
   selectors, this pair among them. A carousel control is a circle. */
.sprio-quotes .sprio-quotes-btn { border-radius: 999px !important; }

/* ================================================= the hero, on a rotation

   The banner the site already had is slide one, with its own words still in
   its own fields. Any extra slide the admin fills in joins the rotation; an
   extra slide left blank is not a slide, so a site that adds none looks
   exactly as it did — no arrows, no dots, no timer, nothing to notice.

   All the slides occupy one grid cell, so the banner is as deep as the
   deepest of them and nothing jumps when it turns over.                      */

/* The banner's background video sits in an absolutely positioned layer that
   covers the whole container, so anything that has to be clickable has to be
   lifted above it — the arrows were being swallowed by it. */
.sprio-hero .sprio-hero-slides,
.sprio-hero .sprio-hero-nav {
  position: relative;
  z-index: 2;
}

.sprio-hero .sprio-hero-slides {
  display: grid;
  width: 100%;
}

.sprio-hero-slide {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
}

/* Only one is readable at a time. The others are still in the layout — that is
   what keeps the banner from changing height — but they are not seen and not
   reachable by keyboard or screen reader. */
.sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide {
  opacity: 0;
  visibility: hidden;
  transform: translateY(14px);
  transition: opacity 620ms ease, transform 720ms cubic-bezier(0.22, 0.61, 0.36, 1), visibility 0s linear 620ms;
  pointer-events: none;
}

.sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide[data-current="1"] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
  pointer-events: auto;
}

/* ---- an extra slide's own furniture, matched to the first slide's */

.sprio-hero-eyebrow {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 18px;
  color: var(--wf-violet, #6904f2);
  font-size: clamp(14px, 1.05vw, 17px);
  font-weight: 500;
}

.sprio-hero-head {
  margin: 0 0 18px;
  color: #030307;
  font-size: clamp(34px, 4.6vw, 68px);
  font-weight: 500;
  line-height: 1.04;
  letter-spacing: -0.035em;
  text-wrap: balance;
}

.sprio-hero-sub {
  margin: 0 0 30px;
  max-width: 46ch;
  color: rgba(3, 3, 7, 0.72);
  font-size: clamp(16px, 1.35vw, 21px);
  font-weight: 400;
  line-height: 1.42;
}

.sprio-hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }

/* A button with nothing written on it is not a button — it is a black box with
   an arrow in it. Either of the two goes if its label is empty, which is what
   lets an extra slide carry a headline and no call to action. */
.sprio-hero-cta > div:not(:has(.sprio-button-text:not(:empty))) { display: none; }

/* ...and a row of no buttons at all takes no room. */
.sprio-hero-cta:not(:has(.sprio-button-text:not(:empty))) { display: none; }

.sprio-hero-note {
  margin-top: 18px;
  color: rgba(3, 3, 7, 0.56);
  font-size: 14px;
  line-height: 1.4;
}

.sprio-hero-note:empty { display: none; }

/* ---- the controls, only ever shown when there is more than one slide */

.sprio-hero-nav {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: clamp(28px, 2.8vw, 44px);
}

.sprio-hero-nav[hidden] { display: none; }

.sprio-hero .sprio-hero-btn {
  display: grid !important;
  place-items: center;
  width: 44px !important;
  height: 44px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  border: 1px solid rgba(3, 3, 7, 0.22) !important;
  border-radius: 999px !important;
  background: rgba(255, 255, 255, 0.72) !important;
  background-image: none !important;
  box-shadow: none !important;
  color: #030307 !important;
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, color 160ms ease;
}

.sprio-hero .sprio-hero-btn svg {
  width: 19px; height: 19px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}

.sprio-hero .sprio-hero-btn:hover,
.sprio-hero .sprio-hero-btn:focus-visible {
  border-color: var(--wf-violet, #6904f2) !important;
  color: var(--wf-violet, #6904f2) !important;
  background: #fff !important;
  outline: none;
}

.sprio-hero-dots { display: flex; align-items: center; gap: 8px; }

.sprio-hero .sprio-hero-dot {
  width: 8px !important;
  height: 8px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 0 !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 999px !important;
  background: rgba(3, 3, 7, 0.24) !important;
  background-image: none !important;
  box-shadow: none !important;
  font-size: 0;
  cursor: pointer;
  transition: width 260ms ease, background-color 200ms ease;
}

.sprio-hero .sprio-hero-dot[aria-selected="true"] {
  width: 26px !important;
  background: var(--wf-violet, #6904f2) !important;
}

.sprio-hero .sprio-hero-dot:focus-visible { outline: 2px solid var(--wf-violet, #6904f2); outline-offset: 3px; }

@media (prefers-reduced-motion: reduce) {
  .sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide { transition: opacity 1ms linear, visibility 0s; transform: none; }
}

/* ============================== the hero banner: where the words sit

   The banner carries margin-top: -225px so it tucks under the 94px header,
   and the theme then pins its content to the BOTTOM of a 100vh box. So the
   gap between the header and the first line was whatever happened to be left
   over: measured at 20px on a 680-tall window and 274px on a 1080 one. On a
   laptop the headline was very nearly touching the navigation.

   Anchored to the top instead, with a padding that pays back the negative
   margin first. The clearance is then the same at every window size, and the
   banner is capped so a tall screen does not leave the words stranded in the
   middle of a very deep empty box.                                          */

/* The cap was 900px. Raised to 980, which is what makes the banner taller on
   the monitors most people are actually on: a 1080 or 1440 screen was hitting
   the cap and stopping at 900, while a laptop was already at 100vh and could
   not grow without pushing the next section off the fold entirely. So this is
   80px on a desktop and no change on a short window, which is the right way
   round. */
.sprio-hero {
  min-height: min(100vh, 980px) !important;
  --min-height: min(100vh, 980px) !important;
}

.sprio-hero > .e-con-inner {
  justify-content: flex-start !important;
  /* 225 of negative margin, then the clearance we actually want */
  padding-top: 300px !important;
  padding-bottom: clamp(56px, 7vh, 96px) !important;
}

/* The banner's negative margin is -225px on a desktop and -145px from the
   tablet layout down, so the padding that pays it back changes with it. Both
   land the first line 75px under the header. */
@media (max-width: 1024px) {
  .sprio-hero > .e-con-inner { padding-top: 220px !important; }
}

/* ---------------------------------------- one rhythm across every slide

   Slide one is the theme's own markup and sets the measure: 74px headline on
   an 81px line with -3px of tracking, a 20px sub, and 20px between each part.
   The extra slides were coming out at 46px because they carried the theme's
   heading class, which won over the size set here. They now match slide one
   exactly, so switching between them moves nothing but the words.           */

.sprio-hero .sprio-hero-eyebrow { margin-bottom: 20px; }

/* Measured off slide one rather than guessed. The theme steps its headline at
   two breakpoints instead of scaling with the window — 74/45/30 with tracking
   of -3/-2.5/-1.5 — so a fluid clamp drifted away from it at every size except
   the one it was tuned at. These are the same three steps, exactly. */
.sprio-hero .sprio-hero-head {
  margin: 0 0 20px;
  max-width: 20ch;
  color: #030307;
  font-size: 74px;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -3px;
  text-wrap: balance;
}

.sprio-hero .sprio-hero-sub {
  margin: 0 0 20px;
  max-width: 52ch;
  color: rgba(3, 3, 7, 0.72);
  font-size: 20px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: normal;
}

@media (max-width: 1024px) {
  .sprio-hero .sprio-hero-head { font-size: 45px; letter-spacing: -2.5px; }
  .sprio-hero .sprio-hero-sub { font-size: 18px; }
}

@media (max-width: 767px) {
  .sprio-hero .sprio-hero-head { font-size: 30px; letter-spacing: -1.5px; }
  .sprio-hero .sprio-hero-sub { font-size: 17px; }
}

.sprio-hero .sprio-hero-cta { margin-bottom: 10px; }

/* --------------------------------- a picture of its own, per slide

   Each slide can carry its own background. It sits above the banner's own
   picture or film and below the words, and crosses over rather than cutting,
   so a slide that has none simply lets the banner's own background show.
   Two layers, used alternately — one cannot fade to another on its own.     */

.sprio-hero-shot { display: none !important; }

.sprio-hero-shots {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

.sprio-hero-shot-layer {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0;
  transition: opacity 700ms ease;
}

.sprio-hero-shot-layer[data-on="1"] { opacity: 1; }

/* ------------------------------------- reading the words off a photograph

   The first attempt washed the picture out with a near-opaque pale gradient,
   because the banner's type is near-black and had to stay readable. That made
   the upload pointless — you could barely see what you had put there.

   So the slide turns over instead. A picture is dark behind white type, not
   pale behind black type: the scrim here is only as heavy as legibility needs,
   the words go white, and the call to action carries the brand violet rather
   than borrowing whatever the background happens to be. The band is marked
   data-hero-shot while a picture is showing, so a slide without one keeps the
   original light treatment exactly as it was.

   The scrim fades in and out on the same 700ms as the picture underneath it,
   so nothing snaps when the banner turns over.                              */

.sprio-hero-shots::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 700ms ease;
  pointer-events: none;
  /* Three layers, because one gradient could not do it.

     A gradient alone is measured across the window, but the text column is
     not: on a 1280 laptop the headline runs to 74% of the width, out where a
     left-weighted wash has already thinned away. Measured against a
     pure-white photograph — the worst case there is — that left the headline
     at 2.2:1, under the 3:1 floor for large type.

     So: an even floor over the whole frame that no photograph can beat,
     extra weight down the left where the words are, and a little more at the
     top and bottom edges so neither the header nor the arrows ever sit on a
     bright band. Worst case is now about 9:1 behind the words and 5:1 at the
     far end of the headline, and the picture still shows at better than half
     strength across the right of the frame. */
  background:
    linear-gradient(
      100deg,
      rgba(6, 4, 20, 0.55) 0%,
      rgba(6, 4, 20, 0.55) 40%,
      rgba(6, 4, 20, 0.3) 68%,
      rgba(6, 4, 20, 0) 92%
    ),
    linear-gradient(
      to bottom,
      rgba(6, 4, 20, 0.3) 0%,
      rgba(6, 4, 20, 0) 24%,
      rgba(6, 4, 20, 0) 68%,
      rgba(6, 4, 20, 0.28) 100%
    ),
    linear-gradient(rgba(6, 4, 20, 0.38), rgba(6, 4, 20, 0.38));
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-shots::after { opacity: 1; }

/* Stacked, the words sit over the middle of the picture rather than to one
   side of it, so the scrim covers the whole frame instead of one edge. */
@media (max-width: 767px) {
  .sprio-hero-shots::after {
    background:
      linear-gradient(
        180deg,
        rgba(6, 4, 20, 0.5) 0%,
        rgba(6, 4, 20, 0.36) 48%,
        rgba(6, 4, 20, 0.5) 100%
      ),
      linear-gradient(rgba(6, 4, 20, 0.42), rgba(6, 4, 20, 0.42));
  }
}

/* ---- the words, turned over */

.sprio-hero .sprio-hero-eyebrow,
.sprio-hero .sprio-hero-head,
.sprio-hero .sprio-hero-sub,
.sprio-hero .sprio-hero-note {
  transition: color 480ms ease;
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-head {
  color: #ffffff;
  text-shadow: 0 1px 26px rgba(6, 4, 20, 0.42);
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-sub {
  color: rgba(255, 255, 255, 0.86);
  text-shadow: 0 1px 18px rgba(6, 4, 20, 0.38);
}

/* The brand violet is #6904f2 — far too dark to read on a dark scrim. This is
   the same hue lifted until it clears 7:1 against it. */
.sprio-hero[data-hero-shot="1"] .sprio-hero-eyebrow {
  color: #c9aeff;
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-note {
  color: rgba(255, 255, 255, 0.66);
}

/* ---- the call to action, in the brand colour rather than the background's */

.sprio-hero[data-hero-shot="1"] .sprio-hero-slide .sprio-button {
  border: 1px solid transparent !important;
  background-color: var(--wf-violet, #6904f2) !important;
  background-image: none !important;
  color: #ffffff !important;
  fill: #ffffff !important;
  box-shadow: 0 10px 30px rgba(105, 4, 242, 0.34) !important;
  transition: background-color 180ms ease, border-color 180ms ease, color 180ms ease, box-shadow 180ms ease;
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-slide .sprio-button:hover,
.sprio-hero[data-hero-shot="1"] .sprio-hero-slide .sprio-button:focus {
  background-color: #5703cc !important;
  border-color: transparent !important;
  color: #ffffff !important;
  fill: #ffffff !important;
  box-shadow: 0 14px 34px rgba(105, 4, 242, 0.44) !important;
}

/* The second button is the quieter of the two, so it stays glass over the
   picture instead of a second block of violet. */
.sprio-hero[data-hero-shot="1"] .sprio-hero-slide .sprio-element-5a4cc30 .sprio-button {
  background-color: rgba(255, 255, 255, 0.12) !important;
  border-color: rgba(255, 255, 255, 0.44) !important;
  color: #ffffff !important;
  fill: #ffffff !important;
  box-shadow: none !important;
  backdrop-filter: blur(6px);
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-slide .sprio-element-5a4cc30 .sprio-button:hover,
.sprio-hero[data-hero-shot="1"] .sprio-hero-slide .sprio-element-5a4cc30 .sprio-button:focus {
  background-color: #ffffff !important;
  border-color: #ffffff !important;
  color: #030307 !important;
  fill: #030307 !important;
}

/* ---- the controls, turned over with everything else */

/* The controls sit low and left, where the scrim is thinnest, so white on
   glass is not enough on its own — a pale photograph swallowed them. They
   carry their own dark glass instead, which reads on anything. */
.sprio-hero[data-hero-shot="1"] .sprio-hero-btn {
  border-color: rgba(255, 255, 255, 0.58) !important;
  background: rgba(6, 4, 20, 0.42) !important;
  color: #ffffff !important;
  backdrop-filter: blur(6px);
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-btn:hover,
.sprio-hero[data-hero-shot="1"] .sprio-hero-btn:focus-visible {
  border-color: #ffffff !important;
  background: #ffffff !important;
  color: #030307 !important;
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-dots {
  padding: 10px 14px;
  border-radius: 999px;
  background: rgba(6, 4, 20, 0.42);
  backdrop-filter: blur(6px);
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-dot {
  background: rgba(255, 255, 255, 0.46) !important;
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-dot[aria-selected="true"] {
  background: #ffffff !important;
}

.sprio-hero[data-hero-shot="1"] .sprio-hero-dot:focus-visible { outline-color: #ffffff; }

@media (prefers-reduced-motion: reduce) {
  .sprio-hero-shot-layer,
  .sprio-hero-shots::after { transition: none; }
  .sprio-hero .sprio-hero-eyebrow,
  .sprio-hero .sprio-hero-head,
  .sprio-hero .sprio-hero-sub,
  .sprio-hero .sprio-hero-note { transition: none; }
}

/* ============================ the same three tints, everywhere else they are used

   The violet / blue / green trio was hardcoded into four stylesheets before
   this one: the industries row, the two workflow card grids, the case lab, and
   a couple of gradients built from all three. Repointing only the case-study
   deck would have put a pink card two sections below a green one.

   These selectors mirror the originals exactly, so they match on specificity
   and win on source order — this file loads last. The tokens are redefined too,
   for the places that read them rather than the literal hex.                */

:root,
.workflow-enterprise-page {
  --wf-violet-soft: var(--tint-1);
  --wf-blue-soft: var(--tint-2);
  --wf-green-soft: var(--tint-3);
}

/* The workflow card grids. Same guard, for the same reason. */
.sprio-module:not(.opt-tone-dark):not(.opt-tone-blue) .workflow-ibm-card-grid article:nth-child(1),
.workflow-enterprise-page:not(.sprio-module) .workflow-ibm-card-grid article:nth-child(1) { background: var(--tint-1); }
.sprio-module:not(.opt-tone-dark):not(.opt-tone-blue) .workflow-ibm-card-grid article:nth-child(2),
.workflow-enterprise-page:not(.sprio-module) .workflow-ibm-card-grid article:nth-child(2) { background: var(--tint-2); }
.sprio-module:not(.opt-tone-dark):not(.opt-tone-blue) .workflow-ibm-card-grid article:nth-child(3),
.workflow-enterprise-page:not(.sprio-module) .workflow-ibm-card-grid article:nth-child(3) { background: var(--tint-3); }

/* The industries row, which cycles every four.

   The tone guard matters. In the module's own stylesheet these tints sit
   ABOVE the dark and blue tone rules, so a row set to Tone = dark was painted
   by the later rule and stayed dark. Copying the tints into this file, which
   loads last, quietly reversed that and put violet, blue and pink cards on a
   band that is meant to be black. The :not() pairs restore the original
   behaviour by excluding those tones outright rather than relying on which
   file happens to load last. */
.sprio-module--use-case-cards:not(.opt-tone-dark):not(.opt-tone-blue) .workflow-ibm-card-grid article:nth-child(4n + 1) { background: var(--tint-1); }
.sprio-module--use-case-cards:not(.opt-tone-dark):not(.opt-tone-blue) .workflow-ibm-card-grid article:nth-child(4n + 2) { background: var(--tint-2); }
.sprio-module--use-case-cards:not(.opt-tone-dark):not(.opt-tone-blue) .workflow-ibm-card-grid article:nth-child(4n + 3) { background: var(--tint-3); }

/* the case lab's own deck, which the module above normally replaces */
.sprio-stack-card--violet { background: var(--tint-1); }
.sprio-stack-card--blue   { background: var(--tint-2); }
.sprio-stack-card--green,
.sprio-stack-card--pink   { background: var(--tint-3); }

/* the thumbnails, whose class names do not match the colours they draw */
.workflow-ibm-thumb.is-purple { background: var(--tint-1) !important; }
.workflow-ibm-thumb.is-cyan   { background: var(--tint-2) !important; }
.workflow-ibm-thumb.is-blue   { background: var(--tint-3) !important; }

/* and the two panels built out of all three */
.workflow-template-command .workflow-ibm-video {
  background:
    linear-gradient(90deg, rgba(3, 3, 7, 0.92), rgba(3, 3, 7, 0.74)),
    linear-gradient(135deg, var(--tint-1), var(--tint-2) 52%, var(--tint-3)) !important;
}

.workflow-template-proof .workflow-ibm-video { background: var(--tint-1) !important; }

.workflow-ibm-orbit span {
  background: radial-gradient(circle at 42% 34%, #fff 0 12%, var(--tint-1) 36%, var(--wf-violet, #6904f2) 72%);
}

/* ================== the "View all case studies" button under the home deck

   There was about 250px of empty page between the last card and the button,
   growing to 330px on a tall monitor. Nothing is drawn in it: it is the last
   card's own 162px bottom margin plus 90px of padding on the stack.

   That room is not decoration though, and this is the trap. A sticky card is
   held only while its containing block still extends below it, so the trailing
   space is exactly what lets the last card reach its pinned position and sit
   level with the two under it. Measured: cutting the stack's padding to 150px
   drops the third card 96px below the others, which is the same fault the deck
   had before the tail spacer was added.

   So the space stays and the button moves into it. A negative margin on the
   button changes nothing about the stack's box, so every card's containing
   block is untouched — verified by comparing all three card positions at
   twelve window sizes, identical in every one.

   The pull is scaled to the window height because the gap is: 28vh is what the
   trailing room works out to, and the 78px left over is the gap that should be
   there. That lands a steady 72px under the cards from a 768-tall laptop to a
   1200-tall monitor, instead of anything from 209 to 330.                    */

.sprio-case-lab .sprio-element-bb9e9de {
  margin-top: min(0px, calc(78px - 28vh));
}

/* Phones stack the cards differently and the button is the thing being
   tapped, so it keeps a little more room around it. */
@media (max-width: 767px) {
  .sprio-case-lab .sprio-element-bb9e9de {
    margin-top: min(0px, calc(100px - 28vh));
  }
}

/* ============================================ a proper head on the stack strip

   The stack row had one word set inline inside the bar and nothing else, so it
   read as a caption on a logo strip rather than as a section of the page like
   everything above and below it. It now carries the same three parts the rest
   of the page uses: a small-caps label, a title, and a line under it.

   The label keeps the field the inline caption used, so whatever was written
   there is what the label now says and nothing had to be retyped. */

/* The section's own container is a flex ROW with nowrap, which squeezed the
   head into a 190px column beside the logo bar and pushed it off the left edge
   (measured at x: -15). The axis is turned for this one section so the head
   sits above the strip, which is the only thing it was ever meant to do. */
.sprio-22 .sprio-element.sprio-element-0bed64a > .e-con-inner {
  flex-direction: column !important;
  align-items: stretch !important;
  flex-wrap: wrap;
}

.sprio-stackhead {
  flex: 0 0 auto;
  width: 100%;
  margin: 0 0 clamp(26px, 2.6vw, 42px);
}

.sprio-22 .sprio-element .sprio-stackhead-kicker,
.sprio-stackhead-kicker {
  display: block;
  margin: 0 0 14px;
  color: var(--wf-violet, #6904f2);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.14em;
  line-height: 1.2;
  text-transform: uppercase;
}

.sprio-22 .sprio-element .sprio-stackhead-title,
.sprio-stackhead-title {
  margin: 0 0 14px !important;
  max-width: 22ch;
  color: #030307 !important;
  font-size: clamp(28px, 3.1vw, 46px) !important;
  font-weight: 500 !important;
  line-height: 1.1 !important;
  letter-spacing: -0.03em !important;
  text-transform: none !important;
  text-align: left !important;
}

.sprio-22 .sprio-element .sprio-stackhead-sub,
.sprio-stackhead-sub {
  margin: 0 !important;
  max-width: 58ch;
  color: rgba(3, 3, 7, 0.62) !important;
  font-size: clamp(15px, 1.15vw, 18px) !important;
  line-height: 1.5 !important;
}

.sprio-stackhead-title:empty,
.sprio-stackhead-sub:empty,
.sprio-stackhead-kicker:empty { display: none; }

/* ==================================================== room around the FAQ band

   The FAQ had 5px under it. Its neighbours sit on 100px, and the band below is
   a coloured one, so the questions ran straight into it. Above, the section
   before it paints its background past its own box, which is why the FAQ looked
   flush at the top as well.

   Written as margins rather than padding on purpose. These sections are in
   normal flow and their vertical margins collapse, which was measured before
   choosing: a margin is a FLOOR, so where a neighbour already leaves 105px the
   spacing is unchanged, and where it leaves almost nothing this puts the room
   back. Padding would have added to whatever was already there and given the
   FAQ a 200px gap above it on the pages that were already fine. */

.sprio-22 .sprio-element.sprio-element-80ed41b {
  margin-top: clamp(56px, 6vw, 96px);
  margin-bottom: clamp(64px, 6.4vw, 104px);
}

/* ==================================================== making the page scroll

   The scroll was stuttering, and the causes were measurable rather than a
   matter of taste. Three of them, in order of how much they cost:

   1  background-attachment: fixed on one photo band. The browser cannot hand
      that background to the compositor, so it repaints it on every single
      scroll frame. It is the classic cause of exactly this symptom.

   2  seven elements running backdrop-filter: blur(5px) url(#sprio-lg-fx3).
      A backdrop-filter is already expensive; one that runs an SVG filter
      chain over whatever is behind it, on seven elements at once, is far
      worse. The blur is kept, the SVG filter is not.

   3  shadows with 70 and 78px blur radii on cards that move while you scroll,
      including the sticky deck. A large blur radius is paid for in paint time
      every frame the element is redrawn.                                     */

/* 1 */
.sprio-page-wrapper [class*="sprio-element-"],
.sprio-page-wrapper .sprio-motion-effects-layer,
.sprio-page-wrapper .sprio-background-overlay {
  background-attachment: scroll !important;
}

/* 2 — the same blur, without the SVG filter behind it */
.sprio-element-b212894,
.sprio-element-52e7da9,
.sprio-element-1101302,
.sprio-element-29ff2d8,
.sprio-element-938d6a3,
.sprio-element-506dbd0,
.sprio-element-ee67aa1 {
  backdrop-filter: blur(5px) !important;
  -webkit-backdrop-filter: blur(5px) !important;
}

/* a 40px backdrop blur is the single most expensive thing on the page; 18px
   reads the same at this size */
.sprio-element-daf3b60 {
  backdrop-filter: saturate(1.4) blur(18px) !important;
  -webkit-backdrop-filter: saturate(1.4) blur(18px) !important;
}

/* 3 */
.sprio-page-wrapper .sprio-element-df538be,
.sprio-page-wrapper .sprio-element-10d9a1a,
.sprio-page-wrapper .sprio-element-9d7d59a,
.sprio-page-wrapper .sprio-element-95259b8 {
  box-shadow: 0 14px 38px rgba(0, 0, 0, 0.14) !important;
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-card,
.sprio-case-lab .sprio-stack-card {
  box-shadow: 0 16px 44px rgba(25, 24, 32, 0.14);
}

.sprio-module--case-studies.sprio-has-deck .sprio-stack-card.is-visible,
.sprio-case-lab .sprio-stack-card.is-visible {
  box-shadow: 0 20px 52px rgba(25, 24, 32, 0.17);
}

/* ------------------------------------ the theme's own entrance animations

   This is what was catching at every module, and the numbers say so plainly.
   Measured on the home page: 137 elements carrying animated-fast, 80 carrying
   animated, and 90 keyframe animations running at once. They are Elementor's
   entrance effects, started per element as it scrolls into view, which is
   exactly the shape of the complaint.

   Two of them are very expensive. slideInUp moves an element from
   translate3d(0, 100%, 0) — a whole element height — and zoomIn scales from
   0.3 to 1, so the browser rasterises a large section at several sizes on the
   way. Doing that to a full-width band, once per band, is the hitch.

   They are turned off rather than tuned, because the page already has one
   entrance now and it does not need two of them fighting. sprio-invisible is
   the class the theme's script uses to hold an element hidden until it is
   ready to animate it, so that has to be released here too or two thirds of
   the page would simply never appear.                                       */

.sprio-page-wrapper .sprio-invisible {
  visibility: visible !important;
}

.sprio-page-wrapper .animated,
.sprio-page-wrapper .animated-fast,
.sprio-page-wrapper .fadeIn,
.sprio-page-wrapper .fadeInUp,
.sprio-page-wrapper .fadeInDown,
.sprio-page-wrapper .fadeInLeft,
.sprio-page-wrapper .fadeInRight,
.sprio-page-wrapper .slideInUp,
.sprio-page-wrapper .slideInDown,
.sprio-page-wrapper .slideInLeft,
.sprio-page-wrapper .slideInRight,
.sprio-page-wrapper .zoomIn,
.sprio-page-wrapper .bounceIn {
  animation: none !important;
  opacity: 1 !important;
  visibility: visible !important;
}

/* The wheel should move the page and nothing else. scroll-behavior: smooth on
   the root makes the browser animate scrolling it did not need to animate,
   which is felt as drag. Anchor links still glide, because the script asks for
   that behaviour on the one jump where it belongs. */
html { scroll-behavior: auto; }
html { scroll-padding-top: 110px; }

/* ======================================================= sections appearing

   Each block rises a little and fades in as it comes into view, the way a
   Framer or Webflow page does. Only opacity and transform are animated, so
   the compositor does the work and nothing lands on the main thread while you
   are scrolling.

   The hidden state is applied ONLY once the script has marked the page, so if
   the script never runs the page is simply visible rather than blank. Sticky
   things are left out entirely: a transform on an ancestor changes what a
   sticky child is positioned against, and the case study deck depends on it. */

.sprio-reveal-ready .sprio-rv {
  opacity: 0;
  transform: translate3d(0, 14px, 0);
  transition: opacity 520ms cubic-bezier(0.22, 0.61, 0.36, 1),
              transform 560ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.sprio-reveal-ready .sprio-rv.is-in {
  opacity: 1;
  transform: none;
}

/* No will-change here, deliberately. It was on 21 full-width blocks, which
   asks the browser to hold 21 section-sized layers on the GPU for the whole
   visit. Chrome composites a transform/opacity transition without being told
   to, and only for as long as it is actually running. No stagger either: the
   delays only kept those layers alive for longer. */

@media (prefers-reduced-motion: reduce) {
  .sprio-reveal-ready .sprio-rv {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ==================================================== the hero, while it turns

   The banner already changed slide on a timer. What it did not do was look
   like anything: the picture cut straight in and the words appeared all at
   once. Now the picture drifts very slowly the whole time it is on screen,
   and the words come up in order behind it. */

.sprio-hero-shot-layer {
  transform: scale(1.06);
  transition: opacity 900ms ease, transform 900ms ease;
}

.sprio-hero-shot-layer[data-on="1"] {
  transform: scale(1);
  animation: sprio-hero-drift 14s ease-out forwards;
}

@keyframes sprio-hero-drift {
  from { transform: scale(1); }
  to   { transform: scale(1.06); }
}

/* the words, in order */
.sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide[data-current="1"] > * {
  animation: sprio-hero-rise 760ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}
.sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide[data-current="1"] > *:nth-child(2) { animation-delay: 80ms; }
.sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide[data-current="1"] > *:nth-child(3) { animation-delay: 160ms; }
.sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide[data-current="1"] > *:nth-child(4) { animation-delay: 240ms; }
.sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide[data-current="1"] > *:nth-child(5) { animation-delay: 320ms; }
.sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide[data-current="1"] > *:nth-child(6) { animation-delay: 400ms; }

@keyframes sprio-hero-rise {
  from { opacity: 0; transform: translate3d(0, 20px, 0); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .sprio-hero-shot-layer,
  .sprio-hero-shot-layer[data-on="1"] { animation: none; transform: none; transition: opacity 1ms linear; }
  .sprio-hero-slides[data-hero-ready="1"] .sprio-hero-slide[data-current="1"] > * { animation: none; }
}

/* ======================================================= legal documents

   Terms, privacy, cookies. One column, one measure, numbered clauses. The rest
   of the site is built to be scanned; this is built to be read and cited, so
   the only decoration is the rule between clauses and the number in the
   margin, and the numbers come from a CSS counter rather than being typed —
   insert a clause in the middle and the ones after it renumber themselves.  */

.mod-legal {
  width: min(760px, calc(100vw - 48px));
  margin: 0 auto;
  padding: clamp(40px, 5vw, 84px) 0 clamp(56px, 6vw, 96px);
  color: var(--wf-ink, #030307);
  counter-reset: clause;
}

.mod-legal .mod-kicker {
  display: block;
  margin-bottom: 14px;
  color: var(--wf-violet, #6904f2);
  font-size: 12.5px; font-weight: 600;
  letter-spacing: 0.13em; text-transform: uppercase;
}

.mod-legal-title {
  margin: 0 0 16px;
  font-size: clamp(30px, 3.8vw, 52px);
  font-weight: 500; line-height: 1.06; letter-spacing: -0.04em;
}

.mod-legal .mod-standfirst {
  margin: 0 0 10px;
  max-width: 62ch;
  color: rgba(3, 3, 7, 0.62);
  font-size: clamp(16px, 1.35vw, 19px); line-height: 1.55;
}

.mod-legal-date {
  margin: 0 0 clamp(28px, 3vw, 42px);
  color: rgba(3, 3, 7, 0.55);
  font-size: 14px;
}

.mod-legal-intro {
  padding-bottom: clamp(26px, 3vw, 38px);
  border-bottom: 1px solid rgba(3, 3, 7, 0.12);
  font-size: 17px; line-height: 1.7; color: rgba(3, 3, 7, 0.82);
}

.mod-legal-clause {
  padding: clamp(26px, 3vw, 38px) 0;
  border-bottom: 1px solid rgba(3, 3, 7, 0.12);
}

.mod-legal-clause h2 {
  margin: 0 0 12px;
  font-size: clamp(19px, 1.8vw, 24px);
  font-weight: 500; line-height: 1.25; letter-spacing: -0.03em;
}

/* The number, set in the margin where there is room for it and above the
   heading where there is not. */
.mod-legal-clause h2::before {
  counter-increment: clause;
  content: counter(clause) ".";
  display: inline-block;
  min-width: 1.9em;
  color: var(--wf-violet, #6904f2);
  font-variant-numeric: tabular-nums;
}

.mod-legal-body { font-size: 17px; line-height: 1.7; color: rgba(3, 3, 7, 0.82); }
.mod-legal-body p { margin: 0 0 14px; }
.mod-legal-body p:last-child { margin-bottom: 0; }
.mod-legal-body ul, .mod-legal-body ol { margin: 0 0 14px; padding-left: 22px; }
.mod-legal-body li { margin-bottom: 7px; }
.mod-legal-body a,
.mod-legal-intro a,
.mod-legal-foot a { color: var(--wf-violet, #6904f2); }

.mod-legal-foot {
  margin-top: clamp(28px, 3vw, 42px);
  padding: clamp(22px, 2.4vw, 32px);
  border-radius: 16px;
  background: var(--tint-1, #c7c1ff);
  font-size: 16.5px; line-height: 1.6;
}
.mod-legal-foot p { margin: 0 0 12px; }
.mod-legal-foot p:last-child { margin-bottom: 0; }

/* A hanging indent, so a heading that wraps lines up under itself rather than
   under its own number. Done with text-indent rather than a negative margin:
   a negative margin pulls the number into the page gutter, which is fine at
   1440 and clipped at 380. */
.mod-legal-clause h2 { padding-left: 2.2em; text-indent: -2.2em; }

/* ---- the home page deck's source markup

   The deck script replaces this block with the drawn cards, so none of it is
   normally seen. It is styled anyway, because "normally" is doing a lot of
   work in that sentence: if the script has not run yet, or fails, this is what
   a visitor gets, and an unstyled pile of spans is a broken page. Styled, it
   is a plain list of the same facts.                                        */

.sprio-case-source {
  display: grid;
  gap: clamp(18px, 2vw, 28px);
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}

.sprio-case-source-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: clamp(20px, 2.2vw, 30px);
  border-radius: 20px;
  background: var(--tint-1, #c7c1ff);
  color: var(--wf-ink, #030307);
  font-size: 15.5px;
  line-height: 1.5;
}
.sprio-case-source-card h3 { margin: 0; font-size: 21px; font-weight: 500; letter-spacing: -0.03em; }
.sprio-case-source-card p { margin: 0; }
.sprio-case-source-card img { width: auto; height: 26px; object-fit: contain; align-self: flex-start; }
.sprio-case-source-card a { color: inherit; font-weight: 500; }

/* ============================================================ case studies

   The index and one study. Deliberately quiet: the cards carry the same three
   tints the deck uses so the two read as one family, and everything else is
   type, rule lines and space. A case study is read for its evidence, and
   decoration between a reader and a number is just something to look past.  */

.cs-index,
.cs-study {
  width: min(1180px, calc(100vw - 48px));
  margin: 0 auto;
  padding: clamp(48px, 6vw, 96px) 0 clamp(64px, 7vw, 110px);
  color: var(--wf-ink, #030307);
}

.cs-kicker,
.cs-tag {
  display: inline-block;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

.cs-kicker { color: var(--wf-violet, #6904f2); margin-bottom: 16px; }

.cs-index-head { max-width: min(740px, 100%); margin-bottom: clamp(36px, 4vw, 62px); }
.cs-index-head h1 { max-width: 18ch; }

.cs-index-head h1 {
  margin: 0 0 18px;
  font-size: clamp(32px, 4.2vw, 60px);
  font-weight: 500;
  line-height: 1.06;
  letter-spacing: -0.035em;
}

.cs-index-lede {
  margin: 0;
  max-width: 52ch;
  color: rgba(3, 3, 7, 0.62);
  font-size: clamp(16px, 1.25vw, 19px);
  line-height: 1.5;
}

.cs-grid {
  display: grid;
  gap: clamp(18px, 1.8vw, 26px);
  /* auto-FILL, not auto-fit: with one case study published, auto-fit collapses
     the empty tracks and stretches that single card the full width of the page,
     which reads as a mistake. auto-fill keeps a card the width of a card. */
  grid-template-columns: repeat(auto-fill, minmax(330px, 1fr));
}

/* ---- one card */

.cs-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(24px, 2.4vw, 34px);
  border-radius: 22px;
  color: var(--wf-ink, #030307);
  text-decoration: none;
  background: var(--tint-1);
  transition: transform 260ms cubic-bezier(0.22, 0.61, 0.36, 1), box-shadow 260ms ease;
}

.cs-card--violet { background: var(--tint-1); }
.cs-card--blue   { background: var(--tint-2); }
.cs-card--pink   { background: var(--tint-3); }

@media (hover: hover) and (pointer: fine) {
  .cs-card:hover { transform: translateY(-4px); box-shadow: 0 16px 44px rgba(25, 24, 32, 0.16); }
}

.cs-card:focus-visible { outline: 3px solid var(--wf-violet, #6904f2); outline-offset: 3px; }

.cs-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.cs-card-tags { display: flex; flex-wrap: wrap; gap: 8px; }

.cs-tag {
  padding: 6px 11px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.6);
  color: rgba(3, 3, 7, 0.74);
}

.cs-tag--client { background: rgba(3, 3, 7, 0.08); }

.cs-card-logo { height: 26px; max-width: 110px; object-fit: contain; opacity: 0.86; }

.cs-card-metric { display: flex; align-items: baseline; gap: 10px; margin-top: 6px; }
.cs-card-metric strong {
  font-size: clamp(38px, 3.6vw, 54px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.04em;
}
.cs-card-metric span { color: rgba(3, 3, 7, 0.66); font-size: 15px; }

.cs-card-title {
  font-size: clamp(19px, 1.5vw, 23px);
  font-weight: 500;
  line-height: 1.22;
  letter-spacing: -0.02em;
}

.cs-card-summary { color: rgba(3, 3, 7, 0.66); font-size: 15px; line-height: 1.5; }

.cs-card-go {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid rgba(3, 3, 7, 0.14);
  font-size: 14.5px;
  font-weight: 500;
}

.cs-card-go svg {
  width: 17px; height: 17px; fill: none; stroke: currentColor;
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
  transition: transform 220ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .cs-card:hover .cs-card-go svg { transform: translateX(4px); }
}

.cs-empty { color: rgba(3, 3, 7, 0.55); font-size: 17px; }

/* ---- one study

   Laid out as bands: headline, a strip of figures, the three-part story in a
   card, what moved, the quote, the black panel. The proportions come from the
   design; the type does not. The mockup is set in Inter at weights 800 and up
   with -0.06em tracking, and dropping that into this site would put a second
   voice on one domain — so every size here is the site's own scale and every
   heading is the 500 the rest of the site uses. What carries across is the
   structure and the rhythm, which is what was actually being designed.        */

.cs-study { max-width: 1160px; }

/* 0.6 rather than the 0.5 this used to be: at 13.5px, half-strength ink on
   white measures 3.95:1, which is under the 4.5:1 small text has to meet. */
.cs-crumbs { display: flex; gap: 8px; margin-bottom: 26px; font-size: 13.5px; color: rgba(3, 3, 7, 0.62); }
.cs-crumbs a { color: inherit; text-decoration: none; }
.cs-crumbs a:hover { color: var(--wf-violet, #6904f2); }
.cs-crumbs em { font-style: normal; color: rgba(3, 3, 7, 0.72); }

.cs-study-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.cs-study-tags .cs-tag { background: rgba(3, 3, 7, 0.06); }

.cs-eyebrow {
  margin: 0 0 18px;
  color: var(--wf-violet, #6904f2);
  font-size: 12.5px; font-weight: 600;
  letter-spacing: 0.13em; text-transform: uppercase;
}

.cs-hero h1 {
  max-width: 20ch;
  margin: 0 0 20px;
  font-size: clamp(34px, 4.6vw, 66px);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.04em;
}

.cs-hero-copy {
  margin: 0 0 24px;
  max-width: 60ch;
  color: rgba(3, 3, 7, 0.62);
  font-size: clamp(17px, 1.5vw, 22px);
  line-height: 1.55;
}

.cs-study-meta {
  display: flex; align-items: center; gap: 16px;
  margin: 0 0 clamp(30px, 3.2vw, 48px);
  color: rgba(3, 3, 7, 0.62); font-size: 14px;
}
.cs-study-logo { height: 28px; max-width: 130px; object-fit: contain; }

/* the strip of figures: one card, divided, so it reads as a single claim */
.cs-strip {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  overflow: hidden;
  margin: 0 0 clamp(34px, 3.8vw, 62px);
  border: 1px solid rgba(3, 3, 7, 0.1);
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 22px 60px rgba(15, 12, 8, 0.07);
}
.cs-strip[data-count="1"] { grid-template-columns: minmax(0, 1fr); }
.cs-strip[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cs-strip[data-count="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.cs-metric {
  padding: clamp(24px, 2.4vw, 34px) clamp(20px, 2vw, 30px);
  border-right: 1px solid rgba(3, 3, 7, 0.1);
}
.cs-metric:last-child { border-right: 0; }

.cs-metric strong {
  display: block;
  margin-bottom: 10px;
  color: var(--wf-violet, #6904f2);
  font-size: clamp(38px, 4.2vw, 62px);
  font-weight: 500; line-height: 0.94; letter-spacing: -0.045em;
}
.cs-metric span {
  display: block;
  max-width: 22ch;
  color: rgba(3, 3, 7, 0.72);
  font-size: clamp(15px, 1.15vw, 17px);
  line-height: 1.35;
}

.cs-study-art {
  height: clamp(220px, 30vw, 420px);
  margin: 0 0 clamp(34px, 3.8vw, 58px);
  border-radius: 20px;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* the case in short, and what changed: same head-then-content shape */
.cs-short,
.cs-changed {
  margin: 0 0 clamp(38px, 4.2vw, 68px);
  padding-top: clamp(34px, 3.8vw, 62px);
  border-top: 1px solid rgba(3, 3, 7, 0.12);
}

.cs-short h2,
.cs-changed h2 {
  margin: 0 0 14px;
  font-size: clamp(26px, 3vw, 42px);
  font-weight: 500; line-height: 1.06; letter-spacing: -0.04em;
}

.cs-lead {
  margin: 0;
  max-width: 62ch;
  color: rgba(3, 3, 7, 0.62);
  font-size: clamp(16px, 1.3vw, 19px);
  line-height: 1.55;
}

.cs-short-head { max-width: 820px; margin-bottom: clamp(24px, 2.6vw, 34px); }

.cs-panel {
  padding: clamp(26px, 3.2vw, 52px);
  border: 1px solid rgba(3, 3, 7, 0.1);
  border-radius: 18px;
  background: #fff;
}

.cs-block {
  padding-bottom: clamp(24px, 2.4vw, 32px);
  margin-bottom: clamp(24px, 2.4vw, 32px);
  border-bottom: 1px solid rgba(3, 3, 7, 0.1);
}
.cs-block:last-child { padding-bottom: 0; margin-bottom: 0; border-bottom: 0; }

.cs-block h3 {
  margin: 0 0 12px;
  font-size: clamp(19px, 1.7vw, 24px);
  font-weight: 500; line-height: 1.2; letter-spacing: -0.03em;
}
.cs-block p {
  margin: 0 0 16px;
  color: rgba(3, 3, 7, 0.78);
  font-size: 17px; line-height: 1.66;
}
.cs-block p:last-child { margin-bottom: 0; }
.cs-block ul {
  display: grid; gap: 10px;
  margin: 0; padding-left: 20px;
  color: rgba(3, 3, 7, 0.62);
  font-size: 16px; line-height: 1.55;
}
.cs-block li::marker { color: var(--wf-violet, #6904f2); }

/* what changed: the head beside the numbers, not above them */
.cs-changed {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(28px, 4vw, 72px);
  align-items: start;
}
.cs-changed-head { grid-column: 1; }
.cs-results {
  grid-column: 2;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}
.cs-result {
  padding: 20px 22px;
  border: 1px solid rgba(3, 3, 7, 0.1);
  border-radius: 14px;
  background: #fff;
}
.cs-result strong {
  display: block; margin-bottom: 6px;
  color: var(--wf-violet, #6904f2);
  font-size: clamp(26px, 2.6vw, 34px);
  font-weight: 500; line-height: 1; letter-spacing: -0.035em;
}
.cs-result span { color: rgba(3, 3, 7, 0.72); font-size: 15.5px; line-height: 1.4; }

/* the quote, in the brand tint rather than the mockup's own lilac */
.cs-quote {
  margin: 0 0 clamp(38px, 4.2vw, 68px);
  padding: clamp(30px, 4.4vw, 64px);
  border: 1px solid rgba(105, 4, 242, 0.16);
  border-radius: 20px;
  background: var(--tint-1);
}
.cs-quote p {
  max-width: 24ch;
  margin: 0 0 26px;
  font-size: clamp(24px, 3.4vw, 46px);
  font-weight: 500; line-height: 1.12; letter-spacing: -0.04em;
}
.cs-quote cite {
  /* on the violet tint, not on white: 0.6 measures 4.64:1 there, which is
     inside the margin of error rather than comfortably past it. */
  color: rgba(3, 3, 7, 0.7);
  font-size: 16px; font-style: normal; font-weight: 500;
}

.cs-study-body {
  max-width: 76ch;
  margin: 0 0 clamp(38px, 4.2vw, 68px);
  font-size: 17.5px; line-height: 1.62; color: rgba(3, 3, 7, 0.82);
}
.cs-study-body h2 {
  margin: clamp(32px, 3vw, 46px) 0 14px;
  color: var(--wf-ink, #030307);
  font-size: clamp(22px, 2vw, 30px); font-weight: 500;
  letter-spacing: -0.025em; line-height: 1.18;
}
.cs-study-body h3 { margin: 28px 0 10px; font-size: 20px; font-weight: 600; }
.cs-study-body p { margin: 0 0 18px; }
.cs-study-body ul, .cs-study-body ol { margin: 0 0 18px; padding-left: 22px; }
.cs-study-body li { margin-bottom: 8px; }
.cs-study-body a { color: var(--wf-violet, #6904f2); }
.cs-study-body blockquote {
  margin: 26px 0; padding: 4px 0 4px 22px;
  border-left: 3px solid var(--wf-violet, #6904f2);
  color: var(--wf-ink, #030307); font-size: 20px; line-height: 1.45;
}
.cs-study-body table { width: 100%; border-collapse: collapse; margin: 0 0 22px; font-size: 15.5px; }
.cs-study-body th, .cs-study-body td { padding: 12px 14px; border-bottom: 1px solid rgba(3,3,7,.12); text-align: left; }
.cs-study-body th { font-weight: 600; }

.cs-study-cta {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: clamp(24px, 3vw, 40px);
  margin: 0;
  padding: clamp(30px, 4.2vw, 62px);
  border-radius: 22px;
  background: #050508; color: #fff;
}
.cs-study-cta h2 {
  max-width: 20ch;
  margin: 0 0 14px;
  color: #fff;
  font-size: clamp(26px, 3.4vw, 48px);
  font-weight: 500; line-height: 1.04; letter-spacing: -0.04em;
}
.cs-study-cta p {
  max-width: 58ch;
  margin: 0;
  color: rgba(255, 255, 255, 0.66);
  font-size: clamp(16px, 1.35vw, 20px); line-height: 1.5;
}

.cs-btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 26px; border-radius: 999px;
  background: var(--wf-violet, #6904f2); color: #fff;
  font-size: 15px; font-weight: 500; text-decoration: none;
  transition: background-color 180ms ease;
}
.cs-btn:hover { background: #5703cc; }
.cs-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.cs-more { margin-top: clamp(46px, 5vw, 78px); }
.cs-more h2 {
  margin: 0 0 22px;
  font-size: clamp(20px, 1.8vw, 26px); font-weight: 500; letter-spacing: -0.025em;
}
.cs-grid--more { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

.cs-back { margin: clamp(34px, 3.6vw, 52px) 0 0; }
.cs-back a { color: rgba(3, 3, 7, 0.6); font-size: 15px; text-decoration: none; }
.cs-back a:hover { color: var(--wf-violet, #6904f2); }

/* The strip and the two-column bands fold in the same order the design folds
   them: four figures to two, then to one; the head above its numbers instead
   of beside them. */
@media (max-width: 980px) {
  .cs-strip,
  .cs-strip[data-count="3"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cs-metric:nth-child(2n) { border-right: 0; }
  .cs-metric:nth-child(-n + 2):not(:last-child) { border-bottom: 1px solid rgba(3, 3, 7, 0.1); }

  .cs-changed { grid-template-columns: minmax(0, 1fr); }
  .cs-changed-head, .cs-results { grid-column: 1; }

  .cs-study-cta { grid-template-columns: minmax(0, 1fr); }
  .cs-btn { justify-self: start; }
}

@media (max-width: 640px) {
  .cs-strip,
  .cs-strip[data-count="2"],
  .cs-strip[data-count="3"] { grid-template-columns: minmax(0, 1fr); }
  .cs-metric { border-right: 0; border-bottom: 1px solid rgba(3, 3, 7, 0.1); }
  .cs-metric:last-child { border-bottom: 0; }
  .cs-metric span { max-width: none; }

  .cs-results { grid-template-columns: minmax(0, 1fr); }
  .cs-btn { width: 100%; justify-content: center; }
}

/* ========================================================= request a demo */

/* The two panels sit against each other with no gap and no page padding, the
   way the contact page does it: a dark photograph on the left carrying the
   words, a pale card on the right carrying the form. A booking page that is
   two columns of type on white is the thing that reads as unfinished. */
.demo-wrap {
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding: clamp(28px, 3.4vw, 62px) max(20px, calc(50vw - 620px));
  color: var(--wf-ink, #030307);
}

.demo-grid {
  display: grid;
  gap: 0;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1fr);
  align-items: stretch;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 24px 70px rgba(9, 8, 22, 0.16);
}

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

/* ---- the dark panel */

.demo-side {
  position: relative;
  padding: clamp(30px, 3.4vw, 56px);
  background-color: #0b0a1c;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  color: #fff;
  isolation: isolate;
}

/* The picture is behind words, so it is darkened rather than left to chance:
   a photograph that happens to be pale in one corner is where white type
   disappears. Heaviest at the top left, where the heading sits. */
.demo-side::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(120deg, rgba(9, 8, 26, 0.94) 0%, rgba(9, 8, 26, 0.82) 46%, rgba(9, 8, 26, 0.62) 100%),
    linear-gradient(rgba(9, 8, 26, 0.34), rgba(9, 8, 26, 0.34));
}

.demo-side-inner { position: relative; }

.demo-kicker {
  display: inline-block; margin-bottom: 16px;
  color: var(--wf-violet-soft, #c9aeff);
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.13em; text-transform: uppercase;
}

.demo-side h1 {
  margin: 0 0 18px;
  color: #fff;
  font-size: clamp(28px, 3.2vw, 46px); font-weight: 500;
  line-height: 1.1; letter-spacing: -0.032em;
}

.demo-lede {
  margin: 0 0 clamp(26px, 2.8vw, 38px);
  max-width: 40ch; color: rgba(255, 255, 255, 0.76);
  font-size: clamp(15.5px, 1.2vw, 18px); line-height: 1.5;
}

.demo-points {
  list-style: none; margin: 0 0 28px; padding: 26px 0 0;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  display: grid; gap: 20px;
}
.demo-points li { display: flex; gap: 15px; align-items: flex-start; }
.demo-points span {
  flex: none; display: grid; place-items: center;
  width: 29px; height: 29px; border-radius: 999px;
  background: var(--wf-violet, #6904f2); color: #fff;
  font-size: 13px; font-weight: 600;
}
.demo-points div { color: rgba(255, 255, 255, 0.7); font-size: 15px; line-height: 1.5; }
.demo-points strong { display: block; margin-bottom: 3px; color: #fff; font-weight: 600; }

.demo-note { margin: 0; color: rgba(255, 255, 255, 0.6); font-size: 14.5px; }
.demo-note a { color: var(--wf-violet-soft, #c9aeff); }

/* ---- the form */

.demo-form {
  padding: clamp(28px, 3vw, 46px);
  border: 0;
  border-radius: 0;
  background: #faf9f7;
  box-shadow: none;
}

.demo-form-head { margin-bottom: 24px; }
.demo-form-head h2 { margin: 0 0 6px; font-size: clamp(20px, 1.8vw, 26px); font-weight: 500; letter-spacing: -0.025em; }
.demo-form-head p { margin: 0; color: rgba(3, 3, 7, 0.58); font-size: 14.5px; }

.demo-row { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; margin-bottom: 16px; }
@media (max-width: 620px) { .demo-row { grid-template-columns: 1fr; } }

.demo-field { display: block; margin-bottom: 16px; }
.demo-row .demo-field { margin-bottom: 0; }

.demo-label { display: block; margin-bottom: 7px; font-size: 14px; font-weight: 500; }
.demo-label b { color: var(--wf-violet, #6904f2); font-weight: 600; }

.demo-form input[type="text"],
.demo-form input[type="email"],
.demo-form input[type="tel"],
.demo-form input[type="date"],
.demo-form textarea {
  width: 100%;
  padding: 13px 15px;
  border: 1px solid rgba(3, 3, 7, 0.18);
  border-radius: 11px;
  background: #fff;
  color: var(--wf-ink, #030307);
  font: inherit; font-size: 15.5px;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}

.demo-form textarea { resize: vertical; min-height: 96px; }

.demo-form input:focus,
.demo-form textarea:focus {
  outline: none;
  border-color: var(--wf-violet, #6904f2);
  box-shadow: 0 0 0 3px rgba(105, 4, 242, 0.16);
}

.demo-field.is-bad input,
.demo-field.is-bad textarea { border-color: #c62828; box-shadow: 0 0 0 3px rgba(198, 40, 40, 0.12); }

.demo-hint { display: block; margin-top: 6px; color: rgba(3, 3, 7, 0.5); font-size: 13px; }

/* the slots */
.demo-slots { display: flex; flex-wrap: wrap; gap: 8px; }

.demo-slot { position: relative; }
.demo-slot input {
  position: absolute; inset: 0; margin: 0;
  width: 100%; height: 100%; opacity: 0; cursor: pointer;
}
.demo-slot span {
  display: block; padding: 9px 13px;
  border: 1px solid rgba(3, 3, 7, 0.18);
  border-radius: 999px;
  font-size: 14px; white-space: nowrap;
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
.demo-slot input:checked + span {
  border-color: var(--wf-violet, #6904f2);
  background: var(--wf-violet, #6904f2);
  color: #fff;
}
.demo-slot input:focus-visible + span { outline: 2px solid var(--wf-violet, #6904f2); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .demo-slot input:not(:checked):hover + span { border-color: rgba(3, 3, 7, 0.4); }
}

/* the honeypot: off screen rather than display:none, which some bots skip */
.demo-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* The theme styles every <button> on the site — black, square — and its rules
   outrank a single class. Measured: this came out rgb(0,0,0) with a 0px radius
   until it was stated at this weight. The same reason the carousel dots and the
   hero arrows are written the way they are. */
.demo-wrap .demo-form .demo-submit {
  display: inline-flex !important; align-items: center; gap: 10px;
  margin-top: 8px !important; padding: 16px 28px !important;
  width: auto !important; min-width: 0 !important;
  border: 0 !important; border-radius: 999px !important;
  background: var(--wf-violet, #6904f2) !important;
  background-image: none !important;
  color: #fff !important;
  font: inherit; font-size: 15.5px !important; font-weight: 500 !important;
  letter-spacing: normal !important; text-transform: none !important;
  box-shadow: none !important;
  cursor: pointer;
  transition: background-color 180ms ease, box-shadow 180ms ease;
}
.demo-wrap .demo-form .demo-submit:hover:not(:disabled) {
  background: #5703cc !important;
  box-shadow: 0 12px 30px rgba(105, 4, 242, 0.3) !important;
}
.demo-wrap .demo-form .demo-submit:disabled { opacity: 0.6; cursor: default; }
.demo-wrap .demo-form .demo-submit svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.demo-privacy { margin: 14px 0 0; color: rgba(3, 3, 7, 0.5); font-size: 13.5px; }

.demo-message { margin-top: 12px; font-size: 14.5px; }
.demo-message.is-bad { color: #c62828; }
.demo-message.is-ok { color: #0a7a52; }
.demo-message:empty { margin-top: 0; }

.demo-done { padding: 12px 0; }
.demo-done h2 { margin: 0 0 10px; font-size: clamp(22px, 2vw, 28px); font-weight: 500; letter-spacing: -0.025em; }
.demo-done p { margin: 0; color: rgba(3, 3, 7, 0.66); font-size: 16px; line-height: 1.55; }
.demo-done a { color: var(--wf-violet, #6904f2); }

/* ==========================================================================
   Scrolling
   ==========================================================================

   Two things were making the page stutter on the way down, and neither of
   them was the amount of content.

   The first is the sticky header. It carried
   backdrop-filter: saturate(1.4) blur(18px) on top of a background that is
   already solid white, so it blurred something no visitor could ever see —
   and still made the browser re-rasterise a full-width strip on every single
   scroll frame, because a fixed element with a backdrop filter has to be
   recomposited against whatever has just moved behind it. Removing it changes
   no pixel on the screen and removes the work entirely. The blur on the cards
   further down is left alone: those sit on translucent white over photographs,
   where it is doing visible work.

   The second is the page's own height. A home page is around twelve thousand
   pixels of markup, and the browser was laying out and painting all of it
   whether or not any of it was on screen. content-visibility lets it skip the
   parts that are not, and contain-intrinsic-size keeps the scrollbar honest
   while it does — "auto" means the browser remembers each section's real
   height once it has seen it, so scrolling back up does not jump.

   The case study deck is excluded on purpose: its cards are stacked with
   transforms and read their own position as you scroll, and a section that is
   allowed to skip rendering cannot measure itself. */

[class*="sprio-sticky-header"] {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

#content > div > .e-con.e-parent,
#content > div > [class*="sprio-module--"] {
  content-visibility: auto;
  contain-intrinsic-size: auto 1000px;
}

#content .sprio-case-lab,
#content > div > .sprio-case-lab,
#content .sprio-scroll-stack {
  content-visibility: visible;
  contain-intrinsic-size: none;
}

/* ==========================================================================
   The invitation panel
   ========================================================================== */

.sprio-panel {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 240ms ease;
}

.sprio-panel.is-open { opacity: 1; pointer-events: auto; }

.sprio-panel-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(12, 12, 24, 0.55);
}

.sprio-panel-box {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  width: min(1040px, 100%);
  max-height: calc(100vh - 40px);
  overflow: auto;
  border-radius: 18px;
  background: #fff;
  box-shadow: 0 30px 90px rgba(12, 12, 24, 0.35);
  transform: translateY(12px) scale(0.985);
  transition: transform 240ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

.sprio-panel.is-open .sprio-panel-box { transform: none; }

.sprio-panel-say {
  padding: 44px 40px;
  color: #fff;
  background: linear-gradient(160deg, #101b52 0%, #1b2f8f 55%, #101b52 100%);
}

.sprio-panel-say h2 {
  margin: 0 0 16px;
  font-size: clamp(30px, 3.2vw, 46px);
  line-height: 1.06;
  letter-spacing: -0.02em;
  color: #fff;
}

.sprio-panel-say p {
  margin: 0 0 30px;
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.82);
}

.sprio-panel-logos {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px 14px;
  align-items: center;
}

.sprio-panel-logo img {
  display: block;
  width: 100%;
  max-height: 34px;
  object-fit: contain;
  filter: brightness(0) invert(1);
  opacity: 0.9;
}

.sprio-panel-form {
  position: relative;
  padding: 44px 40px;
}

.sprio-panel-close {
  position: absolute;
  top: 14px;
  right: 16px;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: #4a4a58;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}

.sprio-panel-close:hover { background: #f1f1f6; }

.sprio-panel-form form { display: grid; gap: 22px; }

.sprio-panel-form label { display: grid; gap: 6px; }

.sprio-panel-form label > span {
  font-size: 13px;
  color: #6a6a78;
}

.sprio-panel-form input[type="text"],
.sprio-panel-form input[type="email"],
.sprio-panel-form input[type="tel"],
.sprio-panel-form textarea {
  width: 100%;
  padding: 6px 2px 9px;
  border: 0;
  border-bottom: 1px solid #d6d6de;
  border-radius: 0;
  background: transparent;
  font: inherit;
  font-size: 16px;
  color: #17171f;
}

.sprio-panel-form input:focus,
.sprio-panel-form textarea:focus {
  outline: 0;
  border-bottom-color: #1b2f8f;
}

.sprio-panel-form textarea { resize: vertical; min-height: 64px; }

.sprio-panel-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }

.sprio-panel-consent {
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 10px;
  font-size: 13px;
  line-height: 1.5;
  color: #4a4a58;
}

.sprio-panel-consent input { margin-top: 3px; }
.sprio-panel-consent a { color: #1b2f8f; text-decoration: underline; }

.sprio-panel-trap { position: absolute; left: -9999px; width: 1px; height: 1px; }

.sprio-panel-note { margin: 0; font-size: 13px; color: #b00020; }

.sprio-panel-send {
  justify-self: start;
  padding: 13px 34px;
  border: 0;
  border-radius: 999px;
  background: #2563eb;
  color: #fff;
  font: inherit;
  font-size: 15px;
  cursor: pointer;
  transition: background 180ms ease;
}

.sprio-panel-send:hover { background: #1d4ed8; }
.sprio-panel-send[disabled] { opacity: 0.6; cursor: default; }

.sprio-panel-thanks { display: grid; place-items: center; min-height: 220px; text-align: center; }
.sprio-panel-thanks h3 { margin: 0; font-size: 20px; color: #17171f; }

@media (max-width: 900px) {
  .sprio-panel-box { grid-template-columns: 1fr; }
  .sprio-panel-say { padding: 32px 26px; }
  .sprio-panel-say p { margin-bottom: 22px; }
  .sprio-panel-logos { grid-template-columns: repeat(3, 1fr); gap: 14px 12px; }
  .sprio-panel-logo img { max-height: 26px; }
  .sprio-panel-form { padding: 30px 26px 34px; }
  .sprio-panel-pair { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Phones
   ==========================================================================

   Two things this screen size was missing: something to press in the header,
   and a ceiling on how large a picture is allowed to be. */

.sprio-mobile-cta {
  display: none;
  margin-right: 14px;
  padding: 9px 16px;
  border-radius: 999px;
  background: #17171f;
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
}

.sprio-mobile-cta:hover,
.sprio-mobile-cta:focus { color: #fff; }

@media (max-width: 1024px) {
  .sprio-mobile-cta { display: inline-flex; align-items: center; }
}

@media (max-width: 767px) {
  #content img,
  #content svg { max-width: 100%; height: auto; }

  #content [class*="marquee"] img,
  #content [class*="logo"] img,
  #content [class*="client"] img {
    max-height: 30px;
    width: auto;
  }
}

/* The theme styles every button and input on the site, and those rules are
   both later and heavier than anything a new component can reasonably write.
   Rather than fight that everywhere, the panel restates the handful of
   properties that actually carry its look, scoped to itself so nothing else
   on the site is touched. */

.sprio-panel .sprio-panel-send {
  background: #2563eb !important;
  color: #fff !important;
  border: 0 !important;
  border-radius: 999px !important;
  padding: 13px 34px !important;
  font-size: 15px !important;
  font-weight: 600 !important;
  text-transform: none !important;
  letter-spacing: 0 !important;
  box-shadow: none !important;
}

.sprio-panel .sprio-panel-send:hover { background: #1d4ed8 !important; }

.sprio-panel .sprio-panel-close {
  background: transparent !important;
  color: #4a4a58 !important;
  border: 0 !important;
  border-radius: 50% !important;
  padding: 0 !important;
  font-size: 26px !important;
  font-weight: 400 !important;
  box-shadow: none !important;
}

.sprio-panel .sprio-panel-close:hover { background: #f1f1f6 !important; color: #17171f !important; }

.sprio-panel label > span {
  text-transform: none !important;
  letter-spacing: 0 !important;
  font-size: 13px !important;
  font-weight: 400 !important;
}

.sprio-panel input[type="text"],
.sprio-panel input[type="email"],
.sprio-panel input[type="tel"],
.sprio-panel textarea {
  border: 0 !important;
  border-bottom: 1px solid #d6d6de !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  padding: 6px 2px 9px !important;
  font-size: 16px !important;
}

.sprio-panel input[type="text"]:focus,
.sprio-panel input[type="email"]:focus,
.sprio-panel input[type="tel"]:focus,
.sprio-panel textarea:focus {
  border-bottom-color: #1b2f8f !important;
  outline: 0 !important;
}

.sprio-panel .sprio-panel-consent span { text-transform: none !important; letter-spacing: 0 !important; }

/* On a phone the two panels become one column, and the top one was eating the
   whole screen: a person arrived at a wall of blue with the form somewhere
   below the fold, which is a worse first impression than no panel at all. So
   on small screens the left panel shrinks to a headline and a sentence, the
   logo wall steps aside, and the close button moves onto the box itself where
   a thumb can find it. */

.sprio-panel { z-index: 2147483000; }

@media (max-width: 900px) {
  .sprio-panel { padding: 12px; align-items: flex-start; }

  .sprio-panel-box {
    max-height: calc(100dvh - 24px);
    margin-top: 4vh;
  }

  .sprio-panel-say { padding: 24px 22px 22px; }

  .sprio-panel-say h2 {
    font-size: 26px;
    line-height: 1.12;
    margin-bottom: 10px;
  }

  .sprio-panel-say p {
    font-size: 13.5px;
    line-height: 1.5;
    margin-bottom: 0;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .sprio-panel-logos { display: none; }

  .sprio-panel-form { padding: 22px 22px 26px; }
  .sprio-panel-form form { gap: 16px; }

  .sprio-panel .sprio-panel-close {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 2;
    color: #fff !important;
    background: rgba(255, 255, 255, 0.14) !important;
  }

  .sprio-panel .sprio-panel-close:hover {
    background: rgba(255, 255, 255, 0.24) !important;
    color: #fff !important;
  }
}

@media (max-width: 900px) and (min-height: 780px) {
  .sprio-panel-logos {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    margin-top: 18px;
  }
  .sprio-panel-logo:nth-child(n + 4) { display: none; }
  .sprio-panel-logo img { max-height: 22px; }
}

/* The button is inserted beside the menu icon, so whatever holds the two of
   them has to lay them out in a row. Scoped with :has so it only applies to
   the one element that actually received the button. */
@media (max-width: 1024px) {
  [data-sprio-type="header"] *:has(> .sprio-mobile-cta) {
    display: flex !important;
    align-items: center;
    gap: 10px;
    flex-direction: row;
  }
}

/* The heading is now the tap target on a phone, so it should look like one and
   be large enough to hit. The call to action sits at the end of the open menu,
   full width, where a thumb expects the last item to be. */
@media (max-width: 1024px) {
  .e-n-menu-title {
    cursor: pointer;
    min-height: 44px;
  }

  .e-n-menu-title-container { flex: 1 1 auto; }

  .sprio-menu-cta-item { display: block; padding: 14px 0 4px; }

  .sprio-menu-cta {
    display: block;
    padding: 14px 20px;
    border-radius: 999px;
    background: #17171f;
    color: #fff !important;
    font-size: 15px;
    font-weight: 600;
    line-height: 1;
    text-align: center;
    text-decoration: none !important;
  }
}

/* The cross has to be above the panel it sits on. Without a stacking order of
   its own it was painted underneath the white half on desktop: visible,
   because the form has no background of its own where the button sits, and
   completely unclickable, because the panel above it swallowed the press. */
.sprio-panel .sprio-panel-close {
  z-index: 5;
  pointer-events: auto;
}

.sprio-panel-say,
.sprio-panel-form { position: relative; z-index: 1; }

/* The hero ships every slide in the markup and drops the empty ones as soon as
   its script runs. That script sits behind the theme's own bundle, so on a
   slow connection there were a couple of seconds where a slide nobody wrote
   anything on was on screen. Hiding everything after the first until the
   script has had its say costs nothing and removes the flash: the attribute is
   set the moment the slides are settled. */
.sprio-hero-slides:not([data-hero-ready]) .sprio-hero-slide:nth-child(n + 2) {
  display: none !important;
}
