/* Local inner-page polish for the exported AI Workflow Automation page. */
html {
  scroll-behavior: smooth;
}

/* Home-page visual alignment for the inner service page. */
.workflow-enterprise-page,
.workflow-enterprise-page :is(h1, h2, h3, h4, h5, h6, p, a, button, span, strong, em) {
  font-family: "Instrument Sans", sans-serif !important;
}

.workflow-enterprise-page {
  --wf-ink: #030307;
  --wf-muted: rgba(3, 3, 7, 0.58);
  --wf-soft-line: rgba(3, 3, 7, 0.1);
  --wf-violet: #6904f2;
  --wf-violet-soft: #d9bdff;
  --wf-blue-soft: #a7ddfb;
  --wf-green-soft: #7bdd91;
}

.workflow-enterprise-page .sprio-element-ae2bf0c {
  background-color: #f4efff !important;
  background-image:
    linear-gradient(90deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0.94) 38%, rgba(255, 255, 255, 0.62) 64%, rgba(255, 255, 255, 0.12) 100%),
    url('/theme/AI Workflow Automation – Sprio_files/sprio-photo-03.jpg') !important;
  --min-height: clamp(560px, 66vh, 690px) !important;
}

.workflow-enterprise-alert {
  min-height: 62px;
  background: var(--wf-violet);
  font-size: clamp(17px, 1.28vw, 22px);
  font-weight: 500;
}

.workflow-enterprise-alert strong,
.workflow-enterprise-alert a {
  color: #bca1ff;
}

.workflow-enterprise-breadcrumb {
  color: rgba(3, 3, 7, 0.72);
  font-size: 16px;
}

.workflow-enterprise-breadcrumb a,
.workflow-ibm-intro-copy a,
.workflow-ibm-case-studies a,
.workflow-ibm-resources a,
.workflow-ibm-pager button,
.workflow-ibm-related a,
.workflow-ibm-icon,
.workflow-ibm-related span {
  color: var(--wf-violet);
}

.workflow-enterprise-title {
  color: var(--wf-ink);
  font-size: clamp(44px, 4.45vw, 64px);
  font-weight: 500;
  line-height: 1.08;
}

.workflow-ibm-intro-copy h2,
.workflow-ibm-capabilities > h2,
.workflow-ibm-usecases > h2,
.workflow-ibm-case-studies > h2 {
  color: var(--wf-ink);
  font-size: clamp(40px, 4.35vw, 62px);
  font-weight: 500;
  line-height: 1.1;
}

.workflow-enterprise-copy {
  color: var(--wf-ink);
  font-size: clamp(20px, 1.6vw, 26px);
  font-weight: 500;
  line-height: 1.28;
}

.workflow-enterprise-button {
  min-height: 58px;
  min-width: min(340px, 100%);
  border-radius: 60px !important;
  border-color: var(--wf-ink);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.1;
}

.workflow-enterprise-button-primary {
  background: #000;
  border-color: #000;
  color: #fff;
}

.workflow-enterprise-button-secondary {
  background: rgba(255, 255, 255, 0.9);
  border-color: rgba(3, 3, 7, 0.1);
  color: var(--wf-ink);
  box-shadow: 0 16px 40px rgba(25, 24, 32, 0.12);
}

.workflow-ibm-stack {
  width: min(1280px, calc(100vw - 96px));
  gap: clamp(74px, 7vw, 116px);
}

.workflow-ibm-intro-copy h2 {
  color: var(--wf-violet);
}

.workflow-ibm-intro-copy p,
.workflow-ibm-capabilities p,
.workflow-ibm-card-grid p,
.workflow-ibm-case-studies p,
.workflow-ibm-usecases p {
  color: var(--wf-muted);
  font-size: 18px;
  line-height: 1.45;
}

.workflow-ibm-intro-copy strong,
.workflow-ibm-capabilities h3,
.workflow-ibm-resources h3,
.workflow-ibm-card-grid h3,
.workflow-ibm-case-studies h3,
.workflow-ibm-related h3 {
  color: var(--wf-ink);
  font-weight: 700;
}

.workflow-ibm-video,
.workflow-ibm-resources,
.workflow-ibm-resources article,
.workflow-ibm-card-grid article,
.workflow-ibm-related article {
  border-radius: 26px !important;
}

.workflow-ibm-resources {
  background: #f6f3ff;
}

.workflow-ibm-resources article,
.workflow-ibm-card-grid article,
.workflow-ibm-related article {
  border-color: var(--wf-soft-line);
  box-shadow: 0 20px 58px rgba(25, 24, 32, 0.1);
  overflow: hidden;
}

.workflow-ibm-thumb.is-cyan {
  background: var(--wf-blue-soft);
}

.workflow-ibm-thumb.is-purple {
  background: var(--wf-violet-soft);
}

.workflow-ibm-thumb.is-blue {
  background: var(--wf-green-soft);
}

.workflow-ibm-thumb span {
  border-color: rgba(105, 4, 242, 0.26);
  color: var(--wf-ink);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.workflow-ibm-orbit::before,
.workflow-ibm-orbit::after,
.workflow-ibm-orbit i,
.workflow-ibm-orbit b {
  border-color: rgba(105, 4, 242, 0.42);
}

.workflow-ibm-orbit span {
  background: radial-gradient(circle at 42% 34%, #fff 0 12%, #d9bdff 36%, #6904f2 72%);
  box-shadow: 0 0 42px rgba(105, 4, 242, 0.34);
}

.workflow-ibm-card-grid article:nth-child(1) {
  background: #d9bdff;
}

.workflow-ibm-card-grid article:nth-child(2) {
  background: #a7ddfb;
}

.workflow-ibm-card-grid article:nth-child(3) {
  background: #7bdd91;
}

.workflow-ibm-card-grid article:nth-child(4),
.workflow-ibm-related article {
  background: #fff;
}

.workflow-ibm-logo {
  color: var(--wf-violet);
}

@media (max-width: 767px) {
  .workflow-enterprise-title {
    font-size: clamp(38px, 10vw, 48px);
    line-height: 1.08;
  }

  .workflow-ibm-intro-copy h2,
  .workflow-ibm-capabilities > h2,
  .workflow-ibm-usecases > h2,
  .workflow-ibm-case-studies > h2 {
    font-size: clamp(36px, 9.5vw, 48px);
    line-height: 1.08;
  }

  .workflow-enterprise-copy {
    font-size: 21px;
    line-height: 1.22;
  }

  .workflow-ibm-stack {
    width: calc(100vw - 40px);
  }
}

/* Final typography + interaction layer matched to the home page. */
.workflow-enterprise-title,
.workflow-ibm-intro-copy h2,
.workflow-ibm-capabilities > h2,
.workflow-ibm-usecases > h2,
.workflow-ibm-case-studies > h2 {
  color: #030307 !important;
  font-size: clamp(36px, 3.2vw, 46px) !important;
  font-weight: 500 !important;
  line-height: 1 !important;
  letter-spacing: 0 !important;
}

.workflow-ibm-intro-copy h2 {
  color: #6904f2 !important;
}

.workflow-enterprise-copy {
  color: #030307 !important;
  font-size: 20px !important;
  font-weight: 500 !important;
  line-height: 1.4 !important;
  letter-spacing: 0 !important;
}

.workflow-ibm-capabilities h3,
.workflow-ibm-card-grid h3,
.workflow-ibm-case-studies h3,
.workflow-ibm-related h3,
.workflow-ibm-resources h3 {
  color: #030307 !important;
  font-size: 20px !important;
  font-weight: 500 !important;
  line-height: 1.4 !important;
  letter-spacing: 0 !important;
}

.workflow-ibm-intro-copy p,
.workflow-ibm-capabilities p,
.workflow-ibm-card-grid p,
.workflow-ibm-case-studies p,
.workflow-ibm-resources p {
  color: rgba(3, 3, 7, 0.58) !important;
  font-size: 14px !important;
  font-weight: 400 !important;
  line-height: 1.4 !important;
  letter-spacing: 0 !important;
}

.workflow-enterprise-button,
.workflow-ibm-intro-copy a,
.workflow-ibm-case-studies a,
.workflow-ibm-resources a,
.workflow-ibm-related a,
.workflow-ibm-pager button {
  transition: transform 220ms ease, box-shadow 220ms ease, color 220ms ease, background 220ms ease, border-color 220ms ease !important;
}

.workflow-enterprise-button:hover,
.workflow-ibm-pager button:hover {
  box-shadow: 0 18px 44px rgba(25, 24, 32, 0.18) !important;
  transform: translateY(-3px) !important;
}

.workflow-ibm-resources article,
.workflow-ibm-card-grid article,
.workflow-ibm-related article {
  transition: transform 260ms ease, box-shadow 260ms ease, border-color 260ms ease, background 260ms ease !important;
  will-change: transform;
}

.workflow-ibm-resources article:hover,
.workflow-ibm-card-grid article:hover,
.workflow-ibm-related article:hover {
  border-color: rgba(3, 3, 7, 0.28) !important;
  box-shadow: 0 30px 82px rgba(25, 24, 32, 0.18) !important;
  transform: translateY(-8px) !important;
}

.workflow-ibm-intro-copy a:hover,
.workflow-ibm-case-studies a:hover,
.workflow-ibm-resources article:hover a,
.workflow-ibm-related article:hover a {
  transform: translateX(8px) !important;
}

.workflow-ibm-card-art,
.workflow-ibm-thumb {
  transition: filter 260ms ease, transform 360ms ease !important;
  transform-origin: center;
}

.workflow-ibm-card-grid article:hover .workflow-ibm-card-art,
.workflow-ibm-resources article:hover .workflow-ibm-thumb {
  filter: saturate(1.12) contrast(1.04);
  transform: scale(1.025);
}

.workflow-ibm-card-grid article:hover h3,
.workflow-ibm-related article:hover h3,
.workflow-ibm-resources article:hover h3 {
  color: #6904f2 !important;
}

@media (max-width: 767px) {
  .workflow-enterprise-title,
  .workflow-ibm-intro-copy h2,
  .workflow-ibm-capabilities > h2,
  .workflow-ibm-usecases > h2,
  .workflow-ibm-case-studies > h2 {
    font-size: 34px !important;
    line-height: 1.05 !important;
  }

  .workflow-enterprise-copy {
    font-size: 18px !important;
    line-height: 1.35 !important;
  }

  .workflow-ibm-capabilities h3,
  .workflow-ibm-card-grid h3,
  .workflow-ibm-case-studies h3,
  .workflow-ibm-related h3,
  .workflow-ibm-resources h3 {
    font-size: 20px !important;
  }

  .workflow-ibm-resources article:hover,
  .workflow-ibm-card-grid article:hover,
  .workflow-ibm-related article:hover,
  .workflow-enterprise-button:hover,
  .workflow-ibm-pager button:hover {
    transform: none !important;
  }
}

/* Final sharp corner pass for every custom and exported inner-page surface. */
:is(.sprio-28, .sprio-3911, .sprio-707, .sprio-location-header, .sprio-location-footer) :is(
  .e-con,
  .sprio-button,
  .sprio-icon,
  .sprio-widget-container,
  .sprio-cta,
  .swiper-slide,
  .sprio-button,
  img,
  input,
  textarea,
  select,
  button
),
.workflow-enterprise-page :is(
  .workflow-enterprise-alert,
  .workflow-enterprise-button,
  .workflow-ibm-video,
  .workflow-ibm-resources,
  .workflow-ibm-resources article,
  .workflow-ibm-thumb,
  .workflow-ibm-thumb span,
  .workflow-ibm-card-grid article,
  .workflow-ibm-card-art,
  .workflow-ibm-related article,
  .workflow-ibm-pager button
),
.sprio-scroll-to-top {
  border-radius: 0 !important;
  --border-radius: 0px !important;
}

/* Full-width navigation shell on inner pages. */
.sprio-location-header,
.sprio-location-header .sprio-element-daf3b60,
.sprio-location-header .sprio-element-8737862 {
  left: 0 !important;
  right: 0 !important;
  width: 100vw !important;
  max-width: none !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}

.sprio-location-header .sprio-element-8737862 {
  padding-left: clamp(24px, 3vw, 48px) !important;
  padding-right: clamp(24px, 3vw, 48px) !important;
}

.sprio-location-header .sprio-element-daf3b60 {
  padding-left: 0 !important;
  padding-right: 0 !important;
}

@media (min-width: 1025px) {
  .sprio-707 .sprio-element-b6ff56c .e-n-menu-content {
    left: 0 !important;
    right: 0 !important;
    width: 100vw !important;
    max-width: none !important;
  }
}

/* clip, not hidden: overflow-x:hidden makes the body a scroll container,
   and that silently kills position:sticky anywhere on the page - the
   home page's stacked case-study cards among them. clip stops sideways
   scrolling without creating the container. */
body {
  overflow-x: clip;
}

.sprio-theme-arrow-right::before {
  content: "\2192" !important;
  font-family: Arial, Helvetica, sans-serif !important;
  font-weight: 700;
}

.sprio-theme-arrow-solid-down::before,
.sprio-theme-arrow-solid-down-menu::before {
  content: "\25BE" !important;
  font-family: Arial, Helvetica, sans-serif !important;
  font-size: 0.72em;
}

.sprio-theme-arrow-solid-up::before {
  content: "\25B4" !important;
  font-family: Arial, Helvetica, sans-serif !important;
  font-size: 0.72em;
}

.sprio-location-header .e-n-menu-dropdown-icon i {
  display: none !important;
}

.sprio-location-header .e-n-menu-dropdown-icon::before {
  content: "\25BE";
  display: inline-block;
  color: currentColor;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  transform: translateY(-1px);
}

.sprio-location-header .e-n-menu-title.e-current .e-n-menu-dropdown-icon::before,
.sprio-location-header .e-n-menu-title.workflow-menu-open .e-n-menu-dropdown-icon::before {
  content: "\25B4";
}

[data-element_type="container"].sprio-has-theme-cp,
[data-element_type="container"][class*="sprio-cp-"],
.sprio-has-theme-cp,
[class*="sprio-cp-"] {
  -webkit-clip-path: none !important;
  clip-path: none !important;
}

:is(.sprio-28, .sprio-3911, .sprio-location-header, .sprio-location-footer) .e-con,
:is(.sprio-28, .sprio-3911, .sprio-location-header, .sprio-location-footer) .sprio-button,
:is(.sprio-28, .sprio-3911, .sprio-location-header, .sprio-location-footer) .sprio-icon,
:is(.sprio-28, .sprio-3911, .sprio-location-header, .sprio-location-footer) img,
.sprio-scroll-to-top {
  border-radius: 0 !important;
  --border-radius: 0px !important;
}

.sprio-location-header .sprio-element-8737862 {
  --border-radius: 0px !important;
}

.sprio-28 .sprio-element-ae2bf0c {
  --min-height: clamp(620px, 76vh, 820px) !important;
  --padding-top: calc(150px + 4vh) !important;
  --padding-bottom: clamp(72px, 8vh, 120px) !important;
}

.sprio-28 .sprio-element-ae2bf0c > .e-con-inner {
  max-width: 1280px !important;
}

.sprio-28 .sprio-element-23cc7aa5,
.sprio-28 .sprio-element-5305238e {
  position: relative;
  z-index: 3;
}

.sprio-3911 .sprio-element-54711964 {
  display: none !important;
}

.workflow-enterprise-page {
  --wf-ink: #050507;
  --wf-muted: rgba(5, 5, 7, 0.64);
  --wf-soft: rgba(255, 255, 255, 0.76);
  --wf-line: rgba(5, 5, 7, 0.14);
  --wf-violet: #6904f2;
}

.workflow-enterprise-page .sprio-element-23cc7aa5,
.workflow-enterprise-page .sprio-element-7ce65dc {
  display: none !important;
}

.workflow-enterprise-page .sprio-element-ae2bf0c {
  overflow: hidden;
  color: var(--wf-ink);
  background-color: #fff !important;
  background-image:
    linear-gradient(90deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0.96) 34%, rgba(255, 255, 255, 0.76) 58%, rgba(255, 255, 255, 0.06) 100%),
    url('/theme/AI Workflow Automation – Sprio_files/sprio-photo-03.jpg') !important;
  background-position: center, right center !important;
  background-repeat: no-repeat !important;
  background-size: cover, cover !important;
  --min-height: clamp(560px, 67vh, 700px) !important;
  --padding-top: 0px !important;
  --padding-bottom: 0px !important;
}

.workflow-enterprise-page .sprio-element-ae2bf0c > .e-con-inner {
  width: 100% !important;
  max-width: none !important;
  padding: 0 !important;
}

.workflow-enterprise-hero {
  min-height: inherit;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: stretch;
}

.workflow-enterprise-alert {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(18px, 3vw, 44px);
  min-height: 64px;
  padding: 12px 32px;
  background: #4d1d88;
  color: #fff;
  font-size: clamp(17px, 1.55vw, 24px);
  line-height: 1.25;
}

.workflow-enterprise-alert strong {
  color: #9fc0ff;
  font-weight: 700;
}

.workflow-enterprise-alert span {
  font-weight: 400;
}

.workflow-enterprise-alert a {
  color: #9fc0ff;
  font-size: 32px;
  line-height: 1;
  text-decoration: none !important;
}

.workflow-enterprise-copyblock {
  display: flex;
  flex: 1;
  flex-direction: column;
  justify-content: center;
  width: min(100%, 1440px);
  margin: 0 auto;
  padding: clamp(64px, 7vw, 104px) 32px clamp(48px, 6vw, 86px);
}

.workflow-enterprise-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: 11px;
  margin-bottom: clamp(32px, 4vw, 50px);
  color: rgba(5, 5, 7, 0.78);
  font-size: 17px;
  line-height: 1;
}

.workflow-enterprise-breadcrumb a {
  color: #246bff;
  text-decoration: none !important;
}

.workflow-enterprise-breadcrumb span {
  display: inline-flex;
  align-items: center;
}

.workflow-enterprise-title {
  max-width: 760px;
  margin: 0;
  font-size: clamp(62px, 7vw, 108px);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.04;
}

.workflow-enterprise-copy {
  max-width: 700px;
  margin: clamp(150px, 18vh, 220px) 0 0;
  color: rgba(5, 5, 7, 0.82);
  font-size: clamp(25px, 2.4vw, 38px);
  line-height: 1.22;
}

.workflow-enterprise-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 36px;
}

.workflow-enterprise-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  min-height: 64px;
  min-width: min(360px, 100%);
  padding: 0 28px;
  border: 1px solid #246bff;
  color: var(--wf-ink);
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
  text-decoration: none !important;
  transition: transform 180ms ease, background 180ms ease, color 180ms ease;
}

.workflow-enterprise-button:hover {
  transform: translateY(-2px);
}

.workflow-enterprise-button-primary {
  background: #246bff;
  border-color: #246bff;
  color: #fff;
}

.workflow-enterprise-button-secondary {
  background: rgba(255, 255, 255, 0.74);
  color: #246bff;
}

.workflow-enterprise-button span {
  font-size: 22px;
  line-height: 0;
}

.workflow-enterprise-band {
  width: min(1320px, calc(100vw - 84px));
  margin: clamp(72px, 8vw, 112px) auto;
  color: var(--wf-ink);
}

.workflow-enterprise-band-header {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(300px, 0.54fr);
  gap: clamp(34px, 7vw, 110px);
  align-items: end;
  padding-bottom: 34px;
  border-bottom: 1px solid var(--wf-line);
}

.workflow-enterprise-band h2 {
  margin: 0;
  font-size: clamp(42px, 5.2vw, 84px);
  font-weight: 500;
  letter-spacing: 0;
  line-height: 0.98;
}

.workflow-enterprise-band p {
  margin: 0;
  color: var(--wf-muted);
  font-size: 19px;
  line-height: 1.42;
}

.workflow-enterprise-modules {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-left: 1px solid var(--wf-line);
}

.workflow-enterprise-module {
  min-height: 270px;
  padding: 28px;
  border-right: 1px solid var(--wf-line);
  border-bottom: 1px solid var(--wf-line);
  background: #fff;
}

.workflow-enterprise-module:nth-child(2) {
  background: #f4efff;
}

.workflow-enterprise-module:nth-child(3) {
  background: #eaf8ff;
}

.workflow-enterprise-module:nth-child(4) {
  background: #e8f9ee;
}

.workflow-enterprise-module span {
  display: block;
  color: var(--wf-muted);
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
}

.workflow-enterprise-module strong {
  display: block;
  margin-top: 70px;
  font-size: 28px;
  font-weight: 600;
  line-height: 1.05;
}

.workflow-enterprise-module p {
  margin-top: 18px;
  font-size: 16px;
}

.workflow-enterprise-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: 32px;
  background: #050507;
  color: #fff;
}

.workflow-enterprise-strip div {
  min-height: 138px;
  padding: 26px 28px;
  border-right: 1px solid rgba(255, 255, 255, 0.18);
}

.workflow-enterprise-strip div:last-child {
  border-right: 0;
}

.workflow-enterprise-strip span,
.workflow-enterprise-strip strong {
  display: block;
}

.workflow-enterprise-strip span {
  color: rgba(255, 255, 255, 0.56);
  font-size: 13px;
  font-weight: 650;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.workflow-enterprise-strip strong {
  margin-top: 28px;
  font-size: 22px;
  font-weight: 550;
  line-height: 1.18;
}

.workflow-enterprise-page .sprio-element-406ed477,
.workflow-enterprise-page .sprio-element-52e63228,
.workflow-enterprise-page .sprio-element-4a0f7d26,
.workflow-enterprise-page .sprio-element-1e13b91a,
.workflow-enterprise-page .sprio-element-26ad4a43 {
  display: none !important;
}

.workflow-ibm-stack {
  display: grid;
  gap: clamp(88px, 9vw, 150px);
  width: min(1400px, calc(100vw - 64px));
  margin: clamp(72px, 8vw, 120px) auto;
}

.workflow-ibm-stack h2,
.workflow-ibm-stack h3,
.workflow-ibm-stack p {
  letter-spacing: 0;
}

.workflow-ibm-intro {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(420px, 0.95fr);
  gap: clamp(48px, 7vw, 120px);
  align-items: center;
}

.workflow-ibm-intro-copy h2,
.workflow-ibm-capabilities > h2,
.workflow-ibm-usecases > h2,
.workflow-ibm-case-studies > h2 {
  margin: 0;
  color: var(--wf-ink);
  font-size: clamp(58px, 6.4vw, 104px);
  font-weight: 400;
  line-height: 1.02;
}

.workflow-ibm-intro-copy h2 {
  color: #246bff;
}

.workflow-ibm-intro-copy p {
  max-width: 680px;
  margin: 34px 0 0;
  color: rgba(5, 5, 7, 0.76);
  font-size: 22px;
  line-height: 1.42;
}

.workflow-ibm-intro-copy strong {
  display: block;
  max-width: 720px;
  margin-top: 34px;
  color: var(--wf-ink);
  font-size: 21px;
  line-height: 1.38;
}

.workflow-ibm-intro-copy a,
.workflow-ibm-case-studies a {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-top: 32px;
  color: #246bff;
  font-size: 20px;
  font-weight: 500;
  text-decoration: none !important;
}

.workflow-ibm-video {
  position: relative;
  min-height: 380px;
  background: #f4f4f4;
  overflow: hidden;
}

.workflow-ibm-orbit {
  position: absolute;
  inset: 64px 0 78px;
  display: grid;
  place-items: center;
}

.workflow-ibm-orbit::before,
.workflow-ibm-orbit::after,
.workflow-ibm-orbit i,
.workflow-ibm-orbit b {
  content: "";
  position: absolute;
  width: 246px;
  height: 246px;
  border: 2px solid rgba(36, 107, 255, 0.55);
  border-radius: 50% !important;
}

.workflow-ibm-orbit::before {
  transform: rotate(18deg) scaleX(1.26);
}

.workflow-ibm-orbit::after {
  transform: rotate(-34deg) scaleX(1.18);
}

.workflow-ibm-orbit i {
  transform: rotate(72deg) scaleX(1.24);
}

.workflow-ibm-orbit b {
  transform: rotate(-8deg) scaleX(0.68);
}

.workflow-ibm-orbit span {
  width: 82px;
  height: 82px;
  border-radius: 50% !important;
  background: radial-gradient(circle at 42% 34%, #fff 0 12%, #9fc0ff 30%, #145dff 70%);
  box-shadow: 0 0 42px rgba(36, 107, 255, 0.38);
  z-index: 2;
}

.workflow-ibm-video button {
  position: absolute;
  right: 24px;
  bottom: 42px;
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border: 0;
  border-radius: 50% !important;
  background: rgba(5, 5, 7, 0.42);
  color: #fff;
  font-size: 22px;
}

.workflow-ibm-video small {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -38px;
  color: rgba(5, 5, 7, 0.56);
  font-size: 15px;
}

.workflow-ibm-resources {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, minmax(360px, 1fr));
  gap: 16px;
  padding: 40px 12px 86px;
  background: #f4f4f4;
  overflow: hidden;
}

.workflow-ibm-resources article {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  min-height: 164px;
  border: 1px solid rgba(5, 5, 7, 0.22);
  background: #fff;
}

.workflow-ibm-thumb {
  position: relative;
  min-height: 164px;
  padding: 16px;
  color: #050507;
  overflow: hidden;
}

.workflow-ibm-thumb::before,
.workflow-ibm-thumb::after {
  content: "";
  position: absolute;
  border-radius: 50% !important;
  background: rgba(255, 255, 255, 0.36);
}

.workflow-ibm-thumb::before {
  width: 190px;
  height: 190px;
  left: -42px;
  bottom: -78px;
}

.workflow-ibm-thumb::after {
  width: 136px;
  height: 136px;
  right: -38px;
  top: -42px;
}

.workflow-ibm-thumb.is-cyan {
  background: linear-gradient(135deg, #8ae4ff, #d5f3ff);
}

.workflow-ibm-thumb.is-purple {
  background: linear-gradient(135deg, #9b63ff, #d6bdff);
}

.workflow-ibm-thumb.is-blue {
  background: linear-gradient(135deg, #075bff, #82bdff);
}

.workflow-ibm-thumb span {
  position: relative;
  display: inline-flex;
  z-index: 1;
  padding: 6px 12px;
  border: 1px solid rgba(36, 107, 255, 0.75);
  border-radius: 999px !important;
  background: #fff;
  color: #246bff;
  font-size: 13px;
  line-height: 1;
}

.workflow-ibm-thumb strong {
  position: absolute;
  left: 18px;
  right: 18px;
  bottom: 22px;
  z-index: 1;
  font-size: 24px;
  line-height: 1.05;
}

.workflow-ibm-resources article > div:last-child {
  position: relative;
  padding: 20px 48px 20px 24px;
}

.workflow-ibm-resources article > div:last-child > span {
  display: block;
  margin-bottom: 10px;
  color: #246bff;
  font-size: 14px;
}

.workflow-ibm-resources h3 {
  margin: 0;
  font-size: 20px;
  font-weight: 650;
  line-height: 1.25;
}

.workflow-ibm-resources p {
  margin: 12px 0 0;
  color: rgba(5, 5, 7, 0.72);
  font-size: 16px;
  line-height: 1.32;
}

.workflow-ibm-resources a {
  position: absolute;
  right: 20px;
  bottom: 20px;
  color: #246bff;
  font-size: 32px;
  line-height: 1;
  text-decoration: none !important;
}

.workflow-ibm-pager {
  position: absolute;
  right: 16px;
  bottom: 22px;
  display: flex;
  align-items: center;
  gap: 18px;
}

.workflow-ibm-pager button {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1px solid rgba(5, 5, 7, 0.22);
  background: #fff;
  color: #246bff;
  font-size: 22px;
  line-height: 0;
}

.workflow-ibm-capabilities {
  display: grid;
  grid-template-columns: minmax(260px, 0.8fr) repeat(3, minmax(0, 1fr));
  gap: clamp(36px, 5vw, 80px);
  align-items: start;
}

.workflow-ibm-capabilities article {
  min-height: 430px;
}

.workflow-ibm-icon {
  display: block;
  min-height: 112px;
  color: #246bff;
  font-size: 84px;
  font-weight: 300;
  line-height: 1;
}

.workflow-ibm-capabilities h3 {
  margin: 20px 0 0;
  font-size: 21px;
  font-weight: 700;
  line-height: 1.34;
}

.workflow-ibm-capabilities p {
  margin: 28px 0 0;
  color: rgba(5, 5, 7, 0.72);
  font-size: 20px;
  line-height: 1.42;
}

.workflow-ibm-usecases h2,
.workflow-ibm-case-studies h2 {
  margin-bottom: 54px;
}

.workflow-ibm-card-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}

.workflow-ibm-card-grid article {
  min-height: 640px;
  border: 1px solid rgba(5, 5, 7, 0.18);
  background: #fff;
}

.workflow-ibm-card-art {
  height: 240px;
  border-bottom: 1px solid rgba(5, 5, 7, 0.16);
  background-size: cover;
}

.art-one {
  background:
    linear-gradient(135deg, rgba(5, 5, 7, 0.18), rgba(255, 255, 255, 0.1)),
    url('/theme/AI Workflow Automation – Sprio_files/sprio-photo-02.jpg') center / cover;
}

.art-two {
  background:
    linear-gradient(135deg, rgba(105, 4, 242, 0.28), rgba(255, 255, 255, 0.08)),
    url('/theme/AI Workflow Automation – Sprio_files/sprio-photo-07.jpg') center / cover;
}

.art-three {
  background:
    linear-gradient(135deg, rgba(36, 107, 255, 0.22), rgba(255, 255, 255, 0.06)),
    url('/theme/AI Workflow Automation – Sprio_files/sprio-photo-06.jpg') center / cover;
}

.art-four {
  background:
    linear-gradient(135deg, rgba(34, 202, 119, 0.2), rgba(255, 255, 255, 0.04)),
    url('/theme/AI Workflow Automation – Sprio_files/sprio-photo-01.jpg') center / cover;
}

.workflow-ibm-card-grid h3 {
  margin: 28px 24px 0;
  font-size: 28px;
  font-weight: 400;
  line-height: 1.16;
}

.workflow-ibm-card-grid p {
  margin: 86px 24px 0;
  color: rgba(5, 5, 7, 0.74);
  font-size: 20px;
  line-height: 1.45;
}

.workflow-ibm-case-studies {
  display: grid;
  grid-template-columns: minmax(270px, 0.8fr) repeat(3, minmax(0, 1fr));
  gap: clamp(42px, 6vw, 90px);
  align-items: start;
}

.workflow-ibm-case-studies > h2 {
  margin-bottom: 0;
}

.workflow-ibm-logo {
  min-height: 96px;
  color: #20104f;
  font-size: 34px;
  font-weight: 800;
  line-height: 1;
}

.workflow-ibm-case-studies h3 {
  margin: 28px 0 0;
  font-size: 21px;
  font-weight: 700;
  line-height: 1.3;
}

.workflow-ibm-case-studies p {
  margin: 10px 0 0;
  color: rgba(5, 5, 7, 0.74);
  font-size: 20px;
  line-height: 1.42;
}

.workflow-ibm-related {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
  padding-bottom: 68px;
  border-bottom: 1px solid rgba(5, 5, 7, 0.35);
}

.workflow-ibm-related article {
  position: relative;
  min-height: 320px;
  padding: 28px;
  border: 1px solid rgba(5, 5, 7, 0.18);
  background: #fff;
}

.workflow-ibm-related span {
  color: #246bff;
  font-size: 68px;
  line-height: 1;
}

.workflow-ibm-related h3 {
  position: absolute;
  left: 28px;
  right: 64px;
  bottom: 32px;
  margin: 0;
  font-size: 22px;
  font-weight: 400;
  line-height: 1.18;
}

.workflow-ibm-related a {
  position: absolute;
  right: 28px;
  bottom: 30px;
  color: #246bff;
  font-size: 34px;
  line-height: 1;
  text-decoration: none !important;
}

.workflow-enterprise-page .sprio-element-798c9f28 {
  display: none !important;
  --margin-bottom: 0 !important;
  z-index: 12;
}

.workflow-enterprise-page .sprio-element-e1d6e61 {
  border: 1px solid var(--wf-line);
  box-shadow: 0 18px 54px rgba(5, 5, 7, 0.08);
}

.workflow-enterprise-page .sprio-element-406ed477,
.workflow-enterprise-page .sprio-element-4a0f7d26 {
  --padding-top: clamp(76px, 8vw, 116px) !important;
  --padding-bottom: clamp(76px, 8vw, 116px) !important;
}

.workflow-enterprise-page .sprio-element-52e63228 {
  margin-top: 0 !important;
  background: #050507 !important;
  color: #fff;
  --padding-top: clamp(78px, 8vw, 118px) !important;
  --padding-bottom: clamp(78px, 8vw, 118px) !important;
}

.workflow-enterprise-page .sprio-element-52e63228 :is(h1, h2, h3, h4, p, .sprio-heading-title) {
  color: inherit !important;
}

.workflow-enterprise-page .sprio-element-52e63228 .sprio-widget-text-editor {
  color: rgba(255, 255, 255, 0.72) !important;
}

.sprio-707 .sprio-element-b6ff56c .e-n-menu-content {
  z-index: 2147483620 !important;
}

.sprio-707 .sprio-element-b6ff56c .e-n-menu-content > .e-con {
  box-shadow: 0 22px 70px rgba(0, 0, 0, 0.16);
}

@media (min-width: 1025px) {
  .sprio-707 .sprio-element-b6ff56c .e-n-menu-content:not(.e-active) > .e-con {
    display: none !important;
  }

  .sprio-707 .sprio-element-b6ff56c .e-n-menu-content.e-active > .e-con,
  .sprio-707 .sprio-element-b6ff56c .e-n-menu-content > .e-con.e-active {
    display: flex !important;
    pointer-events: auto !important;
    opacity: 1 !important;
    visibility: visible !important;
    transform: translateY(0) !important;
  }

  .sprio-707 .sprio-element-b6ff56c .e-n-menu-title.workflow-menu-open {
    border-radius: 0 !important;
    background: rgba(255, 255, 255, 0.9);
    box-shadow: 0 0 0 1px rgba(3, 3, 7, 0.1);
  }

  .sprio-707 .sprio-element-b6ff56c .e-n-menu-title.workflow-menu-open .e-n-menu-title-text,
  .sprio-707 .sprio-element-b6ff56c .e-n-menu-title.workflow-menu-open .e-n-menu-dropdown-icon i {
    color: #6904f2 !important;
  }
}

@media (max-width: 767px) {
  .sprio-28 .e-con {
    --padding-left: 20px !important;
    --padding-right: 20px !important;
  }

  .workflow-enterprise-page .sprio-element-ae2bf0c {
    --min-height: auto !important;
    background-position: center, 62% center !important;
    --padding-top: 0px !important;
    --padding-bottom: 0px !important;
  }

  .workflow-enterprise-hero,
  .workflow-enterprise-band-header,
  .workflow-enterprise-modules,
  .workflow-enterprise-strip,
  .workflow-ibm-intro,
  .workflow-ibm-capabilities,
  .workflow-ibm-card-grid,
  .workflow-ibm-case-studies,
  .workflow-ibm-related {
    grid-template-columns: 1fr;
  }

  .workflow-enterprise-title {
    font-size: clamp(48px, 15vw, 68px);
  }

  .workflow-enterprise-strip div {
    border-right: 0;
    border-bottom: 1px solid var(--wf-line);
  }

  .workflow-enterprise-alert {
    align-items: flex-start;
    justify-content: flex-start;
    gap: 8px;
    min-height: 72px;
    padding: 13px 20px;
    font-size: 15px;
  }

  .workflow-enterprise-alert {
    flex-direction: column;
  }

  .workflow-enterprise-alert a {
    position: absolute;
    right: 20px;
    top: 21px;
    font-size: 24px;
  }

  .workflow-enterprise-copyblock {
    min-height: 540px;
    padding: 42px 20px 48px;
  }

  .workflow-enterprise-breadcrumb {
    margin-bottom: 34px;
    font-size: 15px;
  }

  .workflow-enterprise-copy {
    margin-top: 160px;
    font-size: 24px;
  }

  .workflow-enterprise-button {
    width: 100%;
    min-height: 58px;
    font-size: 18px;
  }

  .workflow-enterprise-band {
    width: calc(100vw - 40px);
    margin: 56px auto;
  }

  .workflow-ibm-stack {
    gap: 72px;
    width: calc(100vw - 40px);
  }

  .workflow-ibm-intro-copy h2,
  .workflow-ibm-capabilities > h2,
  .workflow-ibm-usecases > h2,
  .workflow-ibm-case-studies > h2 {
    font-size: clamp(42px, 12vw, 58px);
  }

  .workflow-ibm-intro-copy p,
  .workflow-ibm-intro-copy strong,
  .workflow-ibm-capabilities p,
  .workflow-ibm-card-grid p,
  .workflow-ibm-case-studies p {
    font-size: 18px;
  }

  .workflow-ibm-video {
    min-height: 300px;
    margin-bottom: 28px;
  }

  .workflow-ibm-resources {
    grid-template-columns: 1fr;
    padding: 20px 10px 76px;
  }

  .workflow-ibm-resources article {
    grid-template-columns: 1fr;
  }

  .workflow-ibm-capabilities article,
  .workflow-ibm-card-grid article,
  .workflow-ibm-related article {
    min-height: auto;
  }

  .workflow-ibm-card-grid p {
    margin-top: 42px;
    padding-bottom: 28px;
  }

  .workflow-ibm-card-art {
    height: 210px;
  }
}

/* Final home-page match: keep these after all responsive/exported rules. */
.workflow-enterprise-page,
.workflow-enterprise-page :is(h1, h2, h3, h4, h5, h6, p, a, button, span, strong, em) {
  font-family: "Instrument Sans", sans-serif !important;
}

.workflow-enterprise-page {
  --wf-ink: #030307;
  --wf-muted: rgba(3, 3, 7, 0.58);
  --wf-soft-line: rgba(3, 3, 7, 0.1);
  --wf-violet: #6904f2;
  --wf-violet-soft: #d9bdff;
  --wf-blue-soft: #a7ddfb;
  --wf-green-soft: #7bdd91;
}

.workflow-enterprise-page .sprio-element-ae2bf0c {
  background-color: #f4efff !important;
  background-image:
    linear-gradient(90deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0.94) 38%, rgba(255, 255, 255, 0.62) 64%, rgba(255, 255, 255, 0.12) 100%),
    url('/theme/AI Workflow Automation – Sprio_files/sprio-photo-03.jpg') !important;
  --min-height: clamp(560px, 66vh, 690px) !important;
}

.workflow-enterprise-alert {
  min-height: 62px;
  background: var(--wf-violet);
  font-size: clamp(17px, 1.28vw, 22px);
  font-weight: 500;
}

.workflow-enterprise-alert strong,
.workflow-enterprise-alert a {
  color: #d9bdff;
}

.workflow-enterprise-breadcrumb {
  color: rgba(3, 3, 7, 0.72);
  font-size: 16px;
}

.workflow-enterprise-breadcrumb a,
.workflow-ibm-intro-copy a,
.workflow-ibm-case-studies a,
.workflow-ibm-resources a,
.workflow-ibm-pager button,
.workflow-ibm-related a,
.workflow-ibm-icon,
.workflow-ibm-related span {
  color: var(--wf-violet);
}

.workflow-enterprise-title,
.workflow-ibm-intro-copy h2,
.workflow-ibm-capabilities > h2,
.workflow-ibm-usecases > h2,
.workflow-ibm-case-studies > h2 {
  color: var(--wf-ink);
  font-size: clamp(48px, 5.15vw, 74px);
  font-weight: 500;
  line-height: 1.1;
}

.workflow-enterprise-copy {
  color: var(--wf-ink);
  font-size: clamp(23px, 2vw, 32px);
  font-weight: 500;
  line-height: 1.22;
}

.workflow-enterprise-button {
  min-height: 58px;
  min-width: min(340px, 100%);
  border-radius: 60px !important;
  border-color: #000;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.1;
}

.workflow-enterprise-button-primary {
  background: #000;
  border-color: #000;
  color: #fff;
}

.workflow-enterprise-button-secondary {
  background: rgba(255, 255, 255, 0.92);
  border-color: rgba(3, 3, 7, 0.1);
  color: var(--wf-ink);
  box-shadow: 0 16px 40px rgba(25, 24, 32, 0.12);
}

.workflow-ibm-stack {
  width: min(1280px, calc(100vw - 96px));
  gap: clamp(74px, 7vw, 116px);
}

.workflow-ibm-intro-copy h2 {
  color: var(--wf-violet);
}

.workflow-ibm-intro-copy p,
.workflow-ibm-capabilities p,
.workflow-ibm-card-grid p,
.workflow-ibm-case-studies p,
.workflow-ibm-usecases p {
  color: var(--wf-muted);
  font-size: 18px;
  line-height: 1.45;
}

.workflow-ibm-intro-copy strong,
.workflow-ibm-capabilities h3,
.workflow-ibm-resources h3,
.workflow-ibm-card-grid h3,
.workflow-ibm-case-studies h3,
.workflow-ibm-related h3 {
  color: var(--wf-ink);
  font-weight: 700;
}

.workflow-ibm-video,
.workflow-ibm-resources,
.workflow-ibm-resources article,
.workflow-ibm-card-grid article,
.workflow-ibm-related article {
  border-radius: 26px !important;
}

.workflow-ibm-resources {
  background: #f6f3ff;
}

.workflow-ibm-resources article,
.workflow-ibm-card-grid article,
.workflow-ibm-related article {
  border-color: var(--wf-soft-line);
  box-shadow: 0 20px 58px rgba(25, 24, 32, 0.1);
  overflow: hidden;
}

.workflow-ibm-thumb.is-cyan {
  background: var(--wf-blue-soft);
}

.workflow-ibm-thumb.is-purple {
  background: var(--wf-violet-soft);
}

.workflow-ibm-thumb.is-blue {
  background: var(--wf-green-soft);
}

.workflow-ibm-thumb span {
  border-color: rgba(105, 4, 242, 0.26);
  color: var(--wf-ink);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.workflow-ibm-orbit::before,
.workflow-ibm-orbit::after,
.workflow-ibm-orbit i,
.workflow-ibm-orbit b {
  border-color: rgba(105, 4, 242, 0.42);
}

.workflow-ibm-orbit span {
  background: radial-gradient(circle at 42% 34%, #fff 0 12%, #d9bdff 36%, #6904f2 72%);
  box-shadow: 0 0 42px rgba(105, 4, 242, 0.34);
}

.workflow-ibm-card-grid article:nth-child(1) {
  background: #d9bdff;
}

.workflow-ibm-card-grid article:nth-child(2) {
  background: #a7ddfb;
}

.workflow-ibm-card-grid article:nth-child(3) {
  background: #7bdd91;
}

.workflow-ibm-card-grid article:nth-child(4),
.workflow-ibm-related article {
  background: #fff;
}

.workflow-ibm-logo {
  color: var(--wf-violet);
}

@media (max-width: 767px) {
  .workflow-enterprise-title,
  .workflow-ibm-intro-copy h2,
  .workflow-ibm-capabilities > h2,
  .workflow-ibm-usecases > h2,
  .workflow-ibm-case-studies > h2 {
    font-size: clamp(40px, 11vw, 58px);
    line-height: 1.08;
  }

  .workflow-enterprise-copy {
    font-size: 23px;
    line-height: 1.22;
  }

  .workflow-ibm-stack {
    width: calc(100vw - 40px);
  }
}

/* Final inner-page spacing pass matched to the home page rhythm. */
.workflow-ibm-stack {
  width: min(1280px, calc(100vw - 160px)) !important;
  margin: clamp(84px, 7vw, 108px) auto clamp(96px, 8vw, 124px) !important;
  gap: clamp(76px, 6.6vw, 96px) !important;
}

.workflow-ibm-intro {
  gap: clamp(48px, 5.8vw, 78px) !important;
}

.workflow-ibm-intro-copy p {
  margin-top: 22px !important;
}

.workflow-ibm-intro-copy strong {
  margin-top: 22px !important;
}

.workflow-ibm-intro-copy a,
.workflow-ibm-case-studies a {
  margin-top: 24px !important;
}

.workflow-ibm-resources {
  padding: 32px 12px 72px !important;
}

.workflow-ibm-capabilities {
  gap: clamp(40px, 4.5vw, 64px) !important;
}

.workflow-ibm-capabilities article {
  min-height: auto !important;
}

.workflow-ibm-capabilities h3 {
  margin-top: 18px !important;
}

.workflow-ibm-capabilities p {
  margin-top: 16px !important;
}

.workflow-ibm-usecases h2,
.workflow-ibm-case-studies h2 {
  margin-bottom: 38px !important;
}

.workflow-ibm-card-grid article {
  min-height: 500px !important;
}

.workflow-ibm-card-grid p {
  margin: 20px 24px 0 !important;
}

.workflow-ibm-case-studies {
  gap: clamp(40px, 4.8vw, 68px) !important;
}

.workflow-ibm-case-studies h3 {
  margin-top: 20px !important;
}

.workflow-ibm-related {
  padding-bottom: 76px !important;
}

@media (max-width: 1024px) {
  .workflow-ibm-stack {
    width: min(1120px, calc(100vw - 42px)) !important;
    margin: 72px auto 88px !important;
    gap: 68px !important;
  }
}

@media (max-width: 767px) {
  .workflow-ibm-stack {
    width: calc(100vw - 40px) !important;
    margin: 56px auto 72px !important;
    gap: 56px !important;
  }

  .workflow-ibm-usecases h2,
  .workflow-ibm-case-studies h2 {
    margin-bottom: 26px !important;
  }

  .workflow-ibm-card-grid article {
    min-height: auto !important;
  }
}

/* Offering template 02: command-center / operating-model page. */
.workflow-template-command .workflow-ibm-intro {
  grid-template-columns: minmax(420px, 0.9fr) minmax(0, 1fr) !important;
  align-items: stretch !important;
}

.workflow-template-command .workflow-ibm-video {
  order: -1;
  min-height: 430px !important;
  background:
    linear-gradient(90deg, rgba(3, 3, 7, 0.92), rgba(3, 3, 7, 0.74)),
    linear-gradient(135deg, #d9bdff, #a7ddfb 52%, #7bdd91) !important;
}

.workflow-template-command .workflow-ibm-video small {
  color: rgba(255, 255, 255, 0.68) !important;
}

.workflow-template-command .workflow-ibm-orbit::before,
.workflow-template-command .workflow-ibm-orbit::after,
.workflow-template-command .workflow-ibm-orbit i,
.workflow-template-command .workflow-ibm-orbit b {
  border-color: rgba(255, 255, 255, 0.5) !important;
}

.workflow-template-command .workflow-ibm-resources {
  background: #030307 !important;
}

.workflow-template-command .workflow-ibm-resources article {
  background: rgba(255, 255, 255, 0.96) !important;
}

.workflow-template-command .workflow-ibm-capabilities {
  grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
}

.workflow-template-command .workflow-ibm-capabilities > h2 {
  grid-column: 1 / -1;
}

.workflow-template-command .workflow-ibm-capabilities article {
  padding: 28px !important;
  border: 1px solid rgba(3, 3, 7, 0.1);
  background: #f6f3ff;
  transition: transform 260ms ease, box-shadow 260ms ease, background 260ms ease;
}

.workflow-template-command .workflow-ibm-capabilities article:hover {
  background: #fff;
  box-shadow: 0 24px 64px rgba(25, 24, 32, 0.14);
  transform: translateY(-6px);
}

.workflow-template-command .workflow-ibm-card-grid article {
  min-height: 420px !important;
}

.workflow-template-command .workflow-ibm-card-art {
  height: 190px !important;
}

/* Offering template 03: proof-led / outcome page. */
.workflow-template-proof .workflow-ibm-usecases {
  order: 2;
}

.workflow-template-proof .workflow-ibm-case-studies {
  order: 3;
}

.workflow-template-proof .workflow-ibm-resources {
  order: 4;
}

.workflow-template-proof .workflow-ibm-capabilities {
  order: 5;
}

.workflow-template-proof .workflow-ibm-related {
  order: 6;
}

.workflow-template-proof .workflow-ibm-intro {
  order: 1;
  grid-template-columns: minmax(0, 1fr) minmax(360px, 0.55fr) !important;
}

.workflow-template-proof .workflow-ibm-video {
  min-height: 360px !important;
  background: #d9bdff !important;
}

.workflow-template-proof .workflow-ibm-card-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}

.workflow-template-proof .workflow-ibm-card-grid article {
  min-height: 360px !important;
  display: grid;
  grid-template-columns: 210px minmax(0, 1fr);
  align-items: stretch;
}

.workflow-template-proof .workflow-ibm-card-art {
  height: auto !important;
  min-height: 100%;
  border-right: 1px solid rgba(5, 5, 7, 0.16);
  border-bottom: 0 !important;
}

.workflow-template-proof .workflow-ibm-card-grid h3 {
  margin: 34px 28px 0 !important;
}

.workflow-template-proof .workflow-ibm-card-grid p {
  margin: 20px 28px 34px !important;
}

.workflow-template-proof .workflow-ibm-case-studies {
  padding-top: 48px;
  border-top: 1px solid rgba(3, 3, 7, 0.12);
}

.workflow-template-proof .workflow-ibm-case-studies article {
  padding-top: 4px;
}

.workflow-template-proof .workflow-ibm-resources {
  background: #f6f3ff !important;
}

@media (max-width: 1024px) {
  .workflow-template-command .workflow-ibm-intro,
  .workflow-template-command .workflow-ibm-capabilities,
  .workflow-template-proof .workflow-ibm-intro,
  .workflow-template-proof .workflow-ibm-card-grid {
    grid-template-columns: 1fr !important;
  }

  .workflow-template-proof .workflow-ibm-card-grid article {
    grid-template-columns: 1fr !important;
  }

  .workflow-template-proof .workflow-ibm-card-art {
    height: 220px !important;
    min-height: 0;
    border-right: 0;
    border-bottom: 1px solid rgba(5, 5, 7, 0.16) !important;
  }
}


/* ===========================================================================
   Sprio module library — presentation for modules.html
   ---------------------------------------------------------------------------
   The new modules are built from the same parts the service page already uses.
   Every value below was read off that page, not chosen here:

     section heading   clamp(40px, 4.35vw, 62px), weight 500, LEFT, in its own
                       grid column — never centred
     glyph             84px, weight 300, violet, no box around it
     card              1px solid rgba(5, 5, 7, 0.18) on white, NO shadow
     grid gap          16px between cards
     column gap        clamp(36px, 5vw, 80px) between heading and content
     body copy         18px / 1.45, --wf-muted
     corners           0, everywhere

   Modules 01-07 need nothing here: they are the service page's own markup and
   are styled by workflow-local.css exactly as they are on that page.
   =========================================================================== */

.modules-page {
  --wf-ink: #030307;
  --wf-paper: #faf9f7;
  --wf-muted: rgba(3, 3, 7, 0.58);
  --wf-line: rgba(5, 5, 7, 0.18);
  --wf-violet: #6904f2;
  --wf-violet-soft: #d9bdff;
  --wf-blue-soft: #a7ddfb;
  --wf-green-soft: #7bdd91;
  --wf-stack: min(1280px, calc(100vw - 96px));
  --wf-gutter: clamp(36px, 5vw, 80px);

  /* The gap between case-study cards, as the export sets it (and sets it with
     !important, in workflow-local.css). Named here so the rail can lay out to
     the same measure instead of a second one that happens to look similar. */
  --wf-cs-gap: clamp(40px, 4.8vw, 68px);

  /* The card arrow, drawn once. Every card that leads somewhere uses this
     same mark, at the same size, in the same corner. */
  --wf-arrow: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h15M13 6l6 6-6 6'/%3E%3C/svg%3E");

  font-family: "Instrument Sans", sans-serif;
  color: var(--wf-ink);
}

.modules-page :is(h1, h2, h3, h4, h5, h6, p, a, span, strong, em, td, th, li, time) {
  font-family: "Instrument Sans", sans-serif;
}

/* Nothing WE add is ever round, and nothing floats on a shadow.
   Scoped to our own mod-* classes on purpose: the harvested modules must keep
   the live page's own treatment, including the deliberately circular orbit
   rings and play button inside the intro split. */
.modules-page [class^="mod-"],
.modules-page [class*=" mod-"] {
  border-radius: 0 !important;
  box-shadow: none !important;
}

/* ===========================================================================
   A module on a real page
   ---------------------------------------------------------------------------
   The library page supplies width, tokens and rhythm from its own wrappers.
   Dropped into a page built by the CMS a module has none of that, so every
   blueprint ships wrapped in .sprio-module, which supplies exactly the same
   context. One module then renders identically in the library and on a page.
   =========================================================================== */

.sprio-module {
  width: var(--wf-stack);
  margin: 0 auto;
  padding: clamp(64px, 6vw, 104px) 0;
}

/* Bands that run edge to edge carry their own padding. */
.sprio-module--bleed { width: 100%; padding: 0; }

/* The hero is the page's own top band: full width, and it owns its image. */
.sprio-module--hero-service {
  width: 100%;
  padding: 0;
  overflow: hidden;
  min-height: clamp(560px, 67vh, 700px);
  display: flex;
  background-color: #fff;
  background-image:
    linear-gradient(90deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0.96) 34%, rgba(255, 255, 255, 0.76) 58%, rgba(255, 255, 255, 0.06) 100%),
    url('/theme/sprio-photo-03.jpg.webp');
  background-position: center, right center;
  background-repeat: no-repeat;
  background-size: cover, cover;
}

.sprio-module--hero-service .workflow-enterprise-hero { width: 100%; }

/* The hero's copy sits on the same left edge as every section below it. */
.sprio-module--hero-service .workflow-enterprise-copyblock {
  width: var(--wf-stack);
  margin: 0 auto;
}

/* Modules laid out inside the service page's stack fill the wrapper instead. */
.sprio-module > .workflow-ibm-intro,
.sprio-module > .workflow-ibm-capabilities,
.sprio-module > .workflow-ibm-usecases,
.sprio-module > .workflow-ibm-case-studies,
.sprio-module > .workflow-ibm-related,
.sprio-module > .workflow-ibm-resources { width: 100%; }

/* ------------------------------------------------------------ page framing */

.modules-intro,
.modules-note {
  width: var(--wf-stack);
  margin: clamp(64px, 6vw, 96px) auto clamp(32px, 3vw, 48px);
}

.modules-intro h1 {
  font-size: clamp(44px, 4.45vw, 64px);
  font-weight: 500;
  line-height: 1.08;
  margin: 0;
}

.modules-intro p {
  color: var(--wf-muted);
  font-size: 18px;
  line-height: 1.45;
  max-width: 820px;
  margin: 20px 0 0;
}

.modules-note {
  margin-top: clamp(80px, 8vw, 128px);
  border-bottom: 1px solid rgba(5, 5, 7, 0.35);
  padding-bottom: 14px;
}

.modules-note h2 {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--wf-muted);
  margin: 0;
}

/* -------------------------------------------------------- the module label */

.mod {
  width: var(--wf-stack);
  margin: 0 auto clamp(84px, 8vw, 132px);
}

.mod--bleed .mod-body {
  width: 100vw;
  margin-left: calc(50% - 50vw);
}

.mod-label {
  display: flex;
  align-items: baseline;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 0;
  margin-bottom: 44px;
  border-top: 2px solid var(--wf-ink);
  border-bottom: 1px solid var(--wf-line);
}

.mod-label .mod-num {
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--wf-violet);
}

.mod-label h2 { font-size: 22px; font-weight: 500; line-height: 1.2; margin: 0; flex: 1 1 auto; }

.mod-label code {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 13px;
  color: var(--wf-muted);
  border: 1px solid var(--wf-line);
  padding: 4px 10px;
}

.mod-label .mod-use {
  flex-basis: 100%;
  font-size: 14px;
  color: var(--wf-muted);
  line-height: 1.45;
}

/* Harvested modules carry their own scroll offsets from the live page. */
.mod-body > [id] { scroll-margin-top: 0 !important; }

/* ------------------------------------------------------------ shared parts */

/* Section heading: left, in its own column, at the page's display size. */
.mod-body > div > h2 {
  color: var(--wf-ink);
  font-size: clamp(40px, 4.35vw, 62px);
  font-weight: 500;
  line-height: 1.1;
  margin: 0;
}

.mod-tags { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }

.mod-tag {
  display: inline-block;
  padding: 7px 14px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--wf-ink);
  background: rgba(3, 3, 7, 0.06);
}

.mod-tag.is-violet { background: var(--wf-violet-soft); }
.mod-tag.is-blue   { background: var(--wf-blue-soft); }
.mod-tag.is-green  { background: var(--wf-green-soft); }

.mod-source {
  display: inline-block;
  margin-top: 20px;
  color: var(--wf-violet);
  font-size: 15px;
}

/* ========================================================= 08 stat-band-dark */

.mod-statband { background: var(--wf-ink); padding: clamp(80px, 7vw, 120px) 0; }
.mod-statband .mod-inner { width: var(--wf-stack); margin: 0 auto; }

.mod-statband .mod-head { max-width: 940px; margin-bottom: clamp(56px, 5vw, 84px); }

.mod-statband .mod-head h3 {
  color: #fff;
  font-size: clamp(40px, 4.35vw, 62px);
  font-weight: 500;
  line-height: 1.1;
  margin: 0;
}

.mod-statband .mod-head p {
  color: rgba(255, 255, 255, 0.62);
  font-size: 18px;
  line-height: 1.45;
  margin: 22px 0 0;
  max-width: 720px;
}

.mod-statgrid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; }

.mod-statgrid article {
  padding: 0 clamp(24px, 2.4vw, 40px);
  border-left: 1px solid rgba(255, 255, 255, 0.22);
}

.mod-statgrid article:first-child { padding-left: 0; border-left: 0; }

.mod-statgrid strong {
  display: block;
  font-size: clamp(48px, 4.6vw, 68px);
  font-weight: 300;
  line-height: 1;
  color: var(--wf-violet-soft);
}

.mod-statgrid p {
  color: rgba(255, 255, 255, 0.62);
  font-size: 17px;
  line-height: 1.45;
  margin: 26px 0 0;
}

.mod-statgrid .mod-source { color: var(--wf-violet-soft); }

/* ====================================================== 09 capabilities-tagged
   Uses .workflow-ibm-capabilities itself; only the tag row is added.          */

/* ============================================================ 10 process-steps */

.mod-steps {
  display: grid;
  grid-template-columns: minmax(340px, 0.8fr) minmax(0, 3fr);
  gap: var(--wf-gutter);
  align-items: start;
}

/* Three steps was what the design was drawn with, but a process is however
   many steps it is: the track takes its column count from the content, so four
   sit in a row of four rather than three plus an orphan. */
.mod-steps-track {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: clamp(24px, 3vw, 48px);
  position: relative;
}

/* One line behind the numerals, from the first to the last. It runs through the
   centre of the discs, which each cover the length of line they sit on — so the
   line reads as threading them together rather than passing behind them. */
.mod-steps-track::before {
  content: "";
  position: absolute;
  top: 36px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--wf-violet);
}

.mod-steps-track article { position: relative; }

/* The step number is a disc, not a numeral on the page.

   72px across with its centre on the line at 36px, and the h3 below carries the
   difference (46px, against the numeral's old 34px) so the block is the same
   118px tall it always was and nothing under it moves.

   The fill is the brand violet — the colour the numerals and the line were
   already drawn in — so the discs belong to the same mark rather than
   introducing a second accent. On a dark or blue band it stays exactly as it
   is: a solid disc carries its own contrast and has nothing to invert.        */
/* Prefixed with .sprio-module and marked, deliberately: the page-wide flatten
   reset is `.modules-page [class^="mod-"] { border-radius: 0 !important }`, and
   an unprefixed .mod-steps .mod-step-num ties it on specificity and loses on
   source order — which is how the phone once rendered as a square silver box. */
.sprio-module .mod-steps .mod-step-num {
  position: relative;
  display: grid !important;
  place-items: center;
  width: 72px !important;
  height: 72px !important;
  padding: 0 !important;
  border-radius: 50% !important;
  background: var(--wf-violet) !important;
  color: #fff;
  font-size: 30px;
  font-weight: 400;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.mod-steps h3 { font-size: 22px; font-weight: 500; line-height: 1.35; margin: 46px 0 0; }
.mod-steps p { color: var(--wf-muted); font-size: 17px; line-height: 1.5; margin: 16px 0 0; }

/* ========================================================= 11 capability-table */

.mod-table-block {
  display: grid;
  grid-template-columns: minmax(340px, 0.8fr) minmax(0, 3fr);
  gap: var(--wf-gutter);
  align-items: start;
}

.mod-table-wrap { overflow-x: auto; border-top: 1px solid rgba(5, 5, 7, 0.35); }
.mod-table { width: 100%; min-width: 860px; border-collapse: collapse; text-align: left; }

.mod-table thead th {
  padding: 22px 24px 22px 0;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wf-muted);
  border-bottom: 1px solid var(--wf-line);
}

.mod-table td {
  padding: 26px 24px 26px 0;
  vertical-align: top;
  border-bottom: 1px solid var(--wf-line);
  font-size: 17px;
  line-height: 1.5;
  color: var(--wf-muted);
}

.mod-table td:first-child { color: var(--wf-ink); font-weight: 500; }

/* ========================================================= 12 integration-grid */

.mod-integrations {
  display: grid;
  grid-template-columns: minmax(340px, 0.8fr) minmax(0, 3fr);
  gap: var(--wf-gutter);
  align-items: start;
}

.mod-integration-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }

.mod-integration-grid article {
  border: 1px solid var(--wf-line);
  background: #fff;
  padding: 30px 28px 34px;
  min-height: 320px;
  display: flex;
  flex-direction: column;
}

.mod-integration-grid h3 { font-size: 19px; font-weight: 500; line-height: 1.35; margin: 20px 0 0; }
.mod-integration-grid p { color: var(--wf-muted); font-size: 16px; line-height: 1.5; margin: 14px 0 0; }

/* ============================================================= 13 stat-cards */

.mod-statcards {
  display: grid;
  grid-template-columns: minmax(340px, 0.8fr) minmax(0, 3fr);
  gap: var(--wf-gutter);
  align-items: start;
}

.mod-statcard-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }

.mod-statcard-grid article {
  border: 1px solid var(--wf-line);
  padding: 34px 30px 36px;
  background: #fff;
}

.mod-statcard-grid article:nth-child(1),
.mod-statcard-grid article:nth-child(6) { background: var(--wf-violet-soft); border-color: transparent; }
.mod-statcard-grid article:nth-child(2) { background: var(--wf-blue-soft); border-color: transparent; }
.mod-statcard-grid article:nth-child(4) { background: var(--wf-green-soft); border-color: transparent; }

.mod-statcard-grid strong {
  display: block;
  font-size: clamp(42px, 3.8vw, 58px);
  font-weight: 300;
  line-height: 1;
  color: var(--wf-ink);
}

.mod-statcard-grid h3 { font-size: 19px; font-weight: 500; line-height: 1.35; margin: 22px 0 0; }
.mod-statcard-grid p { color: var(--wf-muted); font-size: 16px; line-height: 1.5; margin: 12px 0 0; }
.mod-statcard-grid .mod-source { font-size: 14px; }

/* ============================================================== 14 split-chat */

.mod-sublabel {
  display: block;
  margin: 44px 0 0;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--wf-line);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--wf-ink);
}

.mod-checklist { list-style: none; margin: 0; padding: 0; }

.mod-checklist li { padding: 26px 0; border-bottom: 1px solid var(--wf-line); }
.mod-checklist h3 { font-size: 19px; font-weight: 500; line-height: 1.35; margin: 0; }
.mod-checklist p { color: var(--wf-muted); font-size: 16px; line-height: 1.5; margin: 10px 0 0; }

.mod-chat { border: 1px solid var(--wf-line); background: #faf8ff; }

.mod-chat-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 20px 24px;
  background: var(--wf-ink);
  color: #fff;
}

.mod-chat-head .mod-avatar {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--wf-violet);
  font-size: 15px;
  font-weight: 500;
}

.mod-chat-head strong { display: block; font-size: 16px; font-weight: 500; }
.mod-chat-head span { font-size: 13px; color: rgba(255, 255, 255, 0.62); }

.mod-chat-body { padding: 26px; display: flex; flex-direction: column; gap: 18px; }

.mod-bubble {
  max-width: 84%;
  padding: 16px 18px;
  font-size: 15px;
  line-height: 1.5;
  border: 1px solid var(--wf-line);
  background: #fff;
}

.mod-bubble.is-guest { align-self: flex-end; background: var(--wf-violet-soft); border-color: transparent; }
.mod-bubble time { display: block; margin-top: 10px; font-size: 12px; color: var(--wf-muted); }

/* ================================================================ responsive */

@media (max-width: 1024px) {
  .mod-steps,
  .mod-table-block,
  .mod-integrations,
  .mod-statcards { grid-template-columns: 1fr; }
  .mod-integration-grid,
  .mod-statcard-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mod-statgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 48px; }
  .mod-statgrid article:nth-child(3) { padding-left: 0; border-left: 0; }
  .mod-steps-track { grid-template-columns: 1fr; }
  .mod-steps-track::before { display: none; }
}

@media (max-width: 767px) {
  .modules-page { --wf-stack: calc(100vw - 40px); }
  .mod-integration-grid,
  .mod-statcard-grid,
  .mod-statgrid { grid-template-columns: 1fr; }
  .mod-statgrid article { padding-left: 0; border-left: 0; }
  .mod-body > div > h2,
  .mod-statband .mod-head h3 { font-size: 34px; }
}

/* ============================================ 15 heading position, per section

   Where a section's heading sits is an editorial decision, so it is a setting
   in the admin rather than a line in this file: each section carries either
   opt-head-top or opt-head-side, and the two blocks below are what those mean.

   Above the content is the house default and is what an unset section gets, so
   a page picks it up without being touched. Beside the content restores the
   layout the sections came out of the export with.

   Two shapes to handle. The export's own sections make the heading the first
   cell of the same grid as the cards, so above means spanning every column.
   The library's sections keep the heading in a column of its own beside a
   wrapper, so above means collapsing to a single column.                     */

/* Three is what the design was drawn with, not a limit on the content: a
   compliance section with four items in a three-column grid leaves one card
   stranded on a row of its own.

   auto-fit was the obvious fix and the wrong one — it sizes tracks from the
   space, so three cards in a row wide enough for five came out narrow with a
   gap on the right. The count is what matters here, not the width, so the
   count is what the rule reads: four items get four columns; three, five and
   six all sit better in three. */
.sprio-module:not(.opt-head-side) .workflow-ibm-capabilities,
.sprio-module:not(.opt-head-side) .workflow-ibm-case-studies {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: 16px;
}

.sprio-module:not(.opt-head-side) .workflow-ibm-capabilities:has(article:nth-of-type(4)):not(:has(article:nth-of-type(5))),
.sprio-module:not(.opt-head-side) .workflow-ibm-case-studies:has(article:nth-of-type(4)):not(:has(article:nth-of-type(5))) {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.sprio-module:not(.opt-head-side) .workflow-ibm-capabilities > h2,
.sprio-module:not(.opt-head-side) .workflow-ibm-case-studies > h2 {
  grid-column: 1 / -1;
  margin-bottom: 0;
}

.sprio-module:not(.opt-head-side) .mod-steps,
.sprio-module:not(.opt-head-side) .mod-table-block,
.sprio-module:not(.opt-head-side) .mod-integrations,
.sprio-module:not(.opt-head-side) .mod-statcards {
  grid-template-columns: minmax(0, 1fr);
  row-gap: 38px;
}

/* Full width, a heading is no longer held to a narrow column — cap the measure
   or a short heading stretches into one thin line across the page. */
.sprio-module:not(.opt-head-side) .workflow-ibm-capabilities > h2,
.sprio-module:not(.opt-head-side) .workflow-ibm-case-studies > h2,
.sprio-module:not(.opt-head-side) .mod-steps > h2,
.sprio-module:not(.opt-head-side) .mod-table-block > h2,
.sprio-module:not(.opt-head-side) .mod-integrations > h2,
.sprio-module:not(.opt-head-side) .mod-statcards > h2 {
  max-width: 20ch;
}

/* Beside the content: the use-case cards are the one module whose heading was
   always on top, so this is the only place the side layout has to be built. */
.sprio-module.opt-head-side .workflow-ibm-usecases {
  display: grid;
  grid-template-columns: minmax(340px, 0.8fr) minmax(0, 3fr);
  gap: var(--wf-gutter);
  align-items: start;
}

.sprio-module.opt-head-side .workflow-ibm-usecases > h2 { margin-bottom: 0; }

/* One column on a phone — and marked important, which is the whole point.

   The four-item rule above is written with :has(), so it computes far higher
   than this one; a media query adds nothing to specificity. A section with
   exactly four cards therefore kept its four columns all the way down, and four
   capability cards on a 390px phone came out 58px wide — a title broken one
   word per line, one letter at a time. It was on the government and
   manufacturing pages as well, and had been since those pages were built.

   Fifth time a rule in this project has lost a fight it looked like it was
   winning. !important settles this one because there is nothing below a single
   column to disagree about. */
@media (max-width: 767px) {
  .sprio-module:not(.opt-head-side) .workflow-ibm-capabilities,
  .sprio-module:not(.opt-head-side) .workflow-ibm-case-studies,
  .sprio-module.opt-head-side .workflow-ibm-usecases {
    grid-template-columns: 1fr !important;
  }
}

/* Four cards do not fit across a tablet either. Between the phone breakpoint
   and 1024 the four-column rule gives 138px a card, so the same sections that
   were 58px wide on a phone were merely unreadable rather than absurd. Two
   columns there. Marked important for the same reason as the rule above: the
   four-item rule is written with :has() and outranks anything simpler. */
@media (min-width: 768px) and (max-width: 1023px) {
  .sprio-module:not(.opt-head-side) .workflow-ibm-capabilities:has(article:nth-of-type(4)):not(:has(article:nth-of-type(5))),
  .sprio-module:not(.opt-head-side) .workflow-ibm-case-studies:has(article:nth-of-type(4)):not(:has(article:nth-of-type(5))) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }
}

/* ===================================================== 16 comparison table

   Module 11's table with one column fewer. Nothing about the type or the rules
   changes; the columns simply divide differently, and the two states being
   compared get equal width so neither reads as the answer before it is read. */

.mod-table--3 th:first-child,
.mod-table--3 td:first-child { width: 22%; }
.mod-table--3 th:not(:first-child),
.mod-table--3 td:not(:first-child) { width: 39%; }

/* ========================================================= 17 figure strip

   Module 08's figures without its band: same grid, same hairlines, on white.
   Six fit where the dark band takes four, so the columns halve and the rows
   gain the space the band's padding used to hold.                            */

.mod-figstrip { display: grid; row-gap: 38px; }

.mod-figstrip .mod-statgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--wf-gutter);
  row-gap: 48px;
}

.mod-figstrip .mod-statgrid article {
  padding-left: 28px;
  border-left: 1px solid rgba(5, 5, 7, 0.18);
}

.mod-figstrip .mod-statgrid strong {
  display: block;
  color: var(--wf-violet);
  font-size: clamp(38px, 3.4vw, 52px);
  font-weight: 400;
  line-height: 1;
}

.mod-figstrip .mod-statgrid p {
  margin: 14px 0 0;
  color: var(--wf-muted);
  font-size: 16px;
  line-height: 1.5;
}

@media (max-width: 1024px) {
  .mod-figstrip .mod-statgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 767px) {
  .mod-figstrip .mod-statgrid { grid-template-columns: 1fr; }
  .mod-figstrip .mod-statgrid article { padding-left: 0; border-left: 0; }
}

/* ======================================================== 18 the icon set

   Drawings, not font glyphs. One geometric system on a 48-unit grid, stroked at
   a hairline and never filled, so an icon carries the same weight as the rules
   around it instead of sitting on the page like a bullet.

   The stroke is currentColor, which is what lets an icon invert with its card
   when the card turns violet on hover.                                        */

/* The glyph's own font rules must not size a drawing, and the colour is set on
   the SVG rather than inherited: the surrounding copy is muted grey, and an icon
   that inherits it disappears. */
.sprio-icon {
  width: 54px;
  height: 54px;
  display: block;
  margin: 0;
  overflow: visible;
  color: var(--wf-violet);
  stroke: currentColor;
}

.workflow-ibm-icon:has(.sprio-icon) {
  display: block;
  font-size: 0;
  line-height: 0;
  height: auto;
  min-height: 0;
}

/* ================================================== 19 reveal on hover

   A four-up grid where each card shows only its title, and gives up its
   explanation when the reader asks for it by pointing at it. The text is in the
   markup either way — hidden by opacity, never removed — so it is read by search
   engines and by a screen reader exactly as if it were visible.

   Touch has no hover. Rather than trap the copy behind a gesture that does not
   exist, anything without a fine pointer gets every card open, which is the
   layout this module has always had.                                          */

@media (hover: hover) and (pointer: fine) {
  .opt-reveal-on .mod-integration-grid article,
  .opt-reveal-on .workflow-ibm-capabilities article {
    position: relative;
    justify-content: flex-end;
    transition: background-color 220ms ease, border-color 220ms ease;
  }

  /* The title sits at the foot of the card and stays there when the body
     appears, so nothing jumps under the pointer. */
  .opt-reveal-on .mod-integration-grid article > h3,
  .opt-reveal-on .workflow-ibm-capabilities article > h3 {
    margin-top: auto;
    transition: color 220ms ease;
  }

  .opt-reveal-on .mod-integration-grid article > .workflow-ibm-icon,
  .opt-reveal-on .workflow-ibm-capabilities article > .workflow-ibm-icon {
    position: absolute;
    top: 30px;
    left: 28px;
    transition: color 220ms ease;
  }

  .opt-reveal-on .mod-integration-grid article > p,
  .opt-reveal-on .workflow-ibm-capabilities article > p {
    max-height: 0;
    opacity: 0;
    margin-top: 0;
    overflow: hidden;
    transition: max-height 260ms ease, opacity 180ms ease, margin-top 260ms ease;
  }

  .opt-reveal-on .mod-integration-grid article:hover,
  .opt-reveal-on .mod-integration-grid article:focus-within,
  .opt-reveal-on .workflow-ibm-capabilities article:hover,
  .opt-reveal-on .workflow-ibm-capabilities article:focus-within {
    background: var(--wf-violet);
    border-color: var(--wf-violet);
  }

  .opt-reveal-on .mod-integration-grid article:hover > *,
  .opt-reveal-on .mod-integration-grid article:focus-within > *,
  .opt-reveal-on .workflow-ibm-capabilities article:hover > *,
  .opt-reveal-on .workflow-ibm-capabilities article:focus-within > *,
  .opt-reveal-on .mod-integration-grid article:hover .sprio-icon,
  .opt-reveal-on .mod-integration-grid article:focus-within .sprio-icon,
  .opt-reveal-on .workflow-ibm-capabilities article:hover .sprio-icon,
  .opt-reveal-on .workflow-ibm-capabilities article:focus-within .sprio-icon {
    color: #fff;
  }

  .opt-reveal-on .mod-integration-grid article:hover > p,
  .opt-reveal-on .mod-integration-grid article:focus-within > p,
  .opt-reveal-on .workflow-ibm-capabilities article:hover > p,
  .opt-reveal-on .workflow-ibm-capabilities article:focus-within > p {
    max-height: 22em;
    opacity: 1;
    margin-top: 14px;
  }
}

/* ================================================== 20 open cards, no frame

   The figure cards were boxed and tinted — six filled rectangles in a row, which
   on a page that already stacks bordered grids reads as more furniture than
   content. Open is now the default: no border, no fill, and the space that was
   doing the separating comes from the gutter instead, so the columns are held
   apart by air rather than by a line.

   Nothing about the type changes. `frame="boxed"` puts the original back, per
   section, from the admin.                                                    */

.sprio-module:not(.opt-frame-boxed) .mod-statcard-grid {
  column-gap: var(--wf-gutter);
  row-gap: clamp(46px, 4.4vw, 68px);
}

.sprio-module:not(.opt-frame-boxed) .mod-statcard-grid article {
  border: 0;
  background: none;
  padding: 0;
}

/* The figure carried the card; without one it needs to lead, so it takes the
   violet the icons use and the title takes the weight the fill used to give. */
.sprio-module:not(.opt-frame-boxed) .mod-statcard-grid strong {
  color: var(--wf-violet);
  font-weight: 400;
}

.sprio-module:not(.opt-frame-boxed) .mod-statcard-grid h3 {
  margin-top: 20px;
  font-size: 20px;
  font-weight: 600;
}

.sprio-module:not(.opt-frame-boxed) .mod-statcard-grid p {
  margin-top: 10px;
  font-size: 17px;
  line-height: 1.5;
  max-width: 34ch;
}

/* The same treatment for the tile grids. A page of bordered rectangles reads as
   a spreadsheet; without the borders the columns are still columns, held by the
   gutter, and the icons carry the rhythm. A section can still ask to be boxed.

   A grid that reveals on hover keeps its card, deliberately: the violet fill
   needs a shape to fill, and a reader needs to see what is worth pointing at.
   Open and reveal are alternatives, not a combination.                        */

.sprio-module:not(.opt-frame-boxed):not(.opt-reveal-on) .mod-integration-grid,
.sprio-module:not(.opt-frame-boxed):not(.opt-reveal-on) .workflow-ibm-capabilities {
  column-gap: var(--wf-gutter);
  row-gap: clamp(46px, 4.4vw, 68px);
}

.sprio-module:not(.opt-frame-boxed):not(.opt-reveal-on) .mod-integration-grid article,
.sprio-module:not(.opt-frame-boxed):not(.opt-reveal-on) .workflow-ibm-capabilities article {
  border: 0;
  background: none;
  padding: 0;
  min-height: 0;
}

.sprio-module:not(.opt-frame-boxed):not(.opt-reveal-on) .mod-integration-grid h3,
.sprio-module:not(.opt-frame-boxed):not(.opt-reveal-on) .workflow-ibm-capabilities h3 {
  margin-top: 22px;
  font-size: 20px;
  font-weight: 600;
}

.sprio-module:not(.opt-frame-boxed):not(.opt-reveal-on) .mod-integration-grid p,
.sprio-module:not(.opt-frame-boxed):not(.opt-reveal-on) .workflow-ibm-capabilities p {
  margin-top: 10px;
  font-size: 17px;
  line-height: 1.5;
  max-width: 36ch;
}

/* ============================================ 21 use case cards, extended

   Four was the number the design was drawn with, and four is a poor fit for
   content that happens to have five or eight. The grid takes its columns from
   the space available, so any number wraps to a sensible row instead of
   overflowing one.

   The arrow is the same affordance the related-links cards already carry: it
   sits at the foot of the card, out of the copy's way, and covers the whole
   card so the entire tile is the target rather than a 20-pixel glyph.        */

/* One row, however many cards, moved by the prev/next pair.

   The row stays. What had to go was the reason the page seized up in the
   middle of it: the row was a native horizontal scroller lying across the full
   width of the window, and a trackpad flick is never perfectly vertical. Chrome
   locks a gesture to the first scroller that can take it, so a downward swipe
   with a few pixels of sideways drift latched onto the cards — measured at zero
   pixels of page movement and 140 of sideways card movement — and the reader
   felt the page hang.

   So on a mouse or trackpad the row is no longer wheel-scrollable at all: the
   arrows move it, and the wheel always belongs to the page. Touch keeps its
   swipe, where the browser picks an axis per gesture and gets it right. Both
   still reach every card; neither can trap the reader.                       */
.sprio-module--use-case-cards .workflow-ibm-card-grid {
  --uc-gap: clamp(16px, 1.5vw, 22px);
  --uc-per-view: 4;
  grid-template-columns: none;
  grid-auto-flow: column;
  /* The track, not the item, decides the width in a grid — a min on the article
     is ignored. Sizing the track as a share of the row rather than in pixels is
     what stops a card being sliced in half against the right-hand edge: a whole
     number of them fills the width at every window size, and the rest wait
     behind the arrows instead of hanging half out of the section. */
  grid-auto-columns: calc((100% - (var(--uc-per-view) - 1) * var(--uc-gap)) / var(--uc-per-view));
  align-items: stretch;
  gap: var(--uc-gap);
  overflow-x: auto;
  overflow-y: hidden;
  /* Nothing this row does may reach the page behind it. */
  overscroll-behavior: contain;
  scroll-snap-type: x proximity;
  scroll-padding-left: 0;
  padding-bottom: 4px;
  scrollbar-width: none;
}

.sprio-module--use-case-cards .workflow-ibm-card-grid article { scroll-snap-align: start; }

.sprio-module--use-case-cards .workflow-ibm-card-grid::-webkit-scrollbar { display: none; }

/* Three or fewer never scroll, so they share the row rather than leaving a
   quarter of it empty on the right. */
.sprio-module--use-case-cards .workflow-ibm-card-grid:has(> article:nth-child(-n + 3):last-child) {
  grid-auto-columns: minmax(0, 1fr);
}

/* A pointer that has a wheel is a pointer that can latch. Hidden overflow still
   scrolls under script, so the arrows lose nothing — and focus still drags the
   row along when a card is reached by keyboard. */
@media (hover: hover) and (pointer: fine) {
  .sprio-module--use-case-cards .workflow-ibm-card-grid { overflow-x: hidden; }
}

@media (max-width: 1199px) {
  .sprio-module--use-case-cards .workflow-ibm-card-grid { --uc-per-view: 3; }
}

@media (max-width: 899px) {
  .sprio-module--use-case-cards .workflow-ibm-card-grid { --uc-per-view: 2; }
}

/* On a phone the next card shows an edge of itself, which says swipe better
   than any arrow does. */
@media (max-width: 639px) {
  .sprio-module--use-case-cards .workflow-ibm-card-grid {
    grid-auto-columns: 78vw;
    scroll-snap-type: x mandatory;
  }
}

/* The card itself: picture, then copy, then the arrow on the foot rule. Laid
   out in flow rather than by absolute position, so the copy can never run
   under the arrow however long the sentence is, and every card in a row ends
   on the same line whatever it holds. */
.sprio-module--use-case-cards .workflow-ibm-card-grid article {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0 !important;
  overflow: hidden;
}

/* The picture was a fixed 240px whatever the column width, which is what put
   it and the title at odds. A ratio keeps the crop honest at every size. */
.sprio-module--use-case-cards .workflow-ibm-card-art {
  flex: none;
  height: auto !important;
  min-height: 0;
  aspect-ratio: 16 / 10;
  background-position: center;
  background-size: cover;
  position: relative;
}

/* A photograph can end on anything — a white wall, a face, a bright sky — and
   whatever it ends on sits directly above the title. Darkening the last third
   of the image gives the title a consistent foot to stand on without tinting
   the card, so it works over any picture and on any band. */
.sprio-module--use-case-cards .workflow-ibm-card-art::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 42%;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.34) 100%);
  pointer-events: none;
}

.sprio-module--use-case-cards .workflow-ibm-card-grid article h3 {
  margin: 24px 24px 0 !important;
  font-size: 20px;
  line-height: 1.25;
  letter-spacing: -0.01em;
}

.sprio-module--use-case-cards .workflow-ibm-card-grid article p {
  margin: 10px 24px 22px !important;
  padding-bottom: 0;
  font-size: 15.5px;
  line-height: 1.6;
}

/* The arrow sits on a hairline at the foot of the card, pushed there by the
   copy above it rather than pinned over it. */
.sprio-module--use-case-cards .workflow-ibm-card-go {
  position: relative;
  right: auto;
  bottom: auto;
  margin: auto 24px 0;
  padding: 16px 0 20px;
  width: auto;
  height: auto;
  min-height: 22px;
  border-top: 1px solid rgba(5, 5, 7, 0.14);
}

.sprio-module--use-case-cards .workflow-ibm-card-go::after {
  inset: auto 0 20px auto;
  width: 22px;
  height: 22px;
}

.workflow-ibm-card-go {
  position: absolute;
  right: 26px;
  bottom: 24px;
  width: 22px;
  height: 22px;
  font-size: 0;
  color: var(--wf-ink);
}

/* The whole card is the link; the glyph only says so. */
.workflow-ibm-card-go::after {
  content: "";
  position: absolute;
  inset: 0;
  background: currentColor;
  -webkit-mask: no-repeat center/22px var(--wf-arrow);
  mask: no-repeat center/22px var(--wf-arrow);
}

.workflow-ibm-card-go::before {
  content: "";
  position: absolute;
  inset: auto;
  top: -100vh;
  right: -100vw;
  bottom: -100vh;
  left: -100vw;
}

/* Reached by keyboard the card has to say so; the arrow alone is 22 pixels of
   glyph in the corner of a 400-pixel target. */
.sprio-module--use-case-cards .workflow-ibm-card-grid article:focus-within {
  outline: 2px solid var(--wf-violet);
  outline-offset: 2px;
}

.sprio-module--use-case-cards .workflow-ibm-card-go:focus-visible { outline: none; }

/* The tints were written for exactly four cards, so a fifth onwards came out
   white. They repeat every four instead, which keeps the rhythm however many
   cards a section carries. */
.sprio-module--use-case-cards .workflow-ibm-card-grid article:nth-child(4n + 1) { background: #d9bdff; }
.sprio-module--use-case-cards .workflow-ibm-card-grid article:nth-child(4n + 2) { background: #a7ddfb; }
.sprio-module--use-case-cards .workflow-ibm-card-grid article:nth-child(4n + 3) { background: #7bdd91; }
.sprio-module--use-case-cards .workflow-ibm-card-grid article:nth-child(4n)     { background: #fff; }

/* =============================================== 22 typography, matched

   The family was already the home page's. The heading treatment was not: at
   this size Instrument Sans needs the negative tracking the home page gives it,
   or the words sit loose and read as a different typeface even though they are
   not. Measured off the home page: 500 weight, tight, tucked line height.     */

.sprio-module h2 {
  letter-spacing: -0.028em;
  line-height: 1.04;
}

.sprio-module h3 { letter-spacing: -0.012em; }

.sprio-module p,
.sprio-module td,
.sprio-module li { font-weight: 400; }

/* ================================================== 23 the rail's controls

   A scrollbar tells you there is more only once you have already found it. The
   pair of buttons and the count say so up front, and the buttons disable at
   each end rather than dead-ending silently.

   They are added by script, so a page without JavaScript keeps a rail that
   still scrolls by trackpad, swipe and keyboard — it simply has no buttons. */

.mod-rail-nav {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  margin-top: 26px;
}

/* The theme styles every <button> on the page — black fill, violet fill, pill
   radius. These are not those buttons, so the reset is deliberate and forced. */
.sprio-module .mod-rail-nav .mod-rail-btn {
  width: 46px !important;
  height: 46px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  display: grid !important;
  place-items: center;
  padding: 0 !important;
  margin: 0 !important;
  border: 1px solid var(--wf-line) !important;
  border-radius: 0 !important;
  background: #fff !important;
  background-image: none !important;
  box-shadow: none !important;
  color: var(--wf-ink) !important;
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, color 160ms ease;
}

.mod-rail-btn svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sprio-module .mod-rail-nav .mod-rail-btn:hover:not(:disabled),
.sprio-module .mod-rail-nav .mod-rail-btn:focus-visible {
  border-color: var(--wf-violet) !important;
  color: var(--wf-violet) !important;
  outline: none;
}

.sprio-module .mod-rail-nav .mod-rail-btn:disabled {
  opacity: 0.32;
  cursor: default;
}

.sprio-module .mod-rail-nav .mod-rail-btn svg { width: 20px; height: 20px; }

.mod-rail-count {
  min-width: 52px;
  text-align: center;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
  color: var(--wf-muted);
}

/* ==================================================== 24 things that respond

   Restraint on purpose: a card lifts a little, a rule thickens, an arrow moves
   the distance it is pointing. Nothing scales, nothing shadows, nothing bounces
   — the design has no shadows and no round corners, and motion should not
   smuggle either back in.                                                    */

.sprio-module .workflow-ibm-card-grid article,
.sprio-module .mod-integration-grid article,
.sprio-module .workflow-ibm-capabilities article,
.sprio-module .mod-statcard-grid article,
.sprio-module .workflow-ibm-related article {
  transition: transform 260ms cubic-bezier(0.22, 0.61, 0.36, 1), border-color 200ms ease;
}

.sprio-module .workflow-ibm-card-grid article:hover,
.sprio-module .workflow-ibm-related article:hover {
  transform: translateY(-4px);
}

.sprio-module .workflow-ibm-related article:hover { border-color: var(--wf-violet); }

.workflow-ibm-card-go,
.sprio-module .workflow-ibm-related a {
  transition: transform 220ms cubic-bezier(0.22, 0.61, 0.36, 1), color 180ms ease;
}

.sprio-module .workflow-ibm-card-grid article:hover .workflow-ibm-card-go,
.sprio-module .workflow-ibm-related article:hover a {
  transform: translateX(5px);
  color: var(--wf-violet);
}

/* A table row is a target too: the eye loses the line halfway across otherwise. */
.sprio-module .mod-table tbody tr { transition: background-color 160ms ease; }
.sprio-module .mod-table tbody tr:hover { background: rgba(105, 4, 242, 0.04); }

/* Figures and steps: the violet deepens rather than the card moving. */
.sprio-module .mod-statgrid article strong,
.sprio-module .mod-steps .mod-step-num { transition: color 200ms ease; }

.sprio-module .workflow-ibm-icon { transition: transform 300ms cubic-bezier(0.22, 0.61, 0.36, 1); }
.sprio-module article:hover > .workflow-ibm-icon { transform: translateY(-3px); }

/* ===================================================== 25 arriving sections

   The hiding rule is written so it can only apply once the script has marked
   the document: no JavaScript, no hidden content. The same guard covers the
   moment before the script runs, and prefers-reduced-motion never gets here at
   all — the class is not added.                                              */

.sprio-motion .sprio-module [data-rise] {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 620ms cubic-bezier(0.22, 0.61, 0.36, 1) var(--rise-delay, 0ms),
    transform 620ms cubic-bezier(0.22, 0.61, 0.36, 1) var(--rise-delay, 0ms);
}

.sprio-motion .sprio-module [data-rise].is-in {
  opacity: 1;
  transform: none;
}

/* A row of a table must not be transformed — it detaches from its borders. */
.sprio-motion .sprio-module tbody tr[data-rise] { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .sprio-module *,
  .sprio-module *::before,
  .sprio-module *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
  }
}

/* ============================================================== 26 the phone

   The conversation used to be a panel with a dark strip on top. It is a phone
   now, because that is what the reader is being asked to imagine: a customer
   messaging a business from the device in their hand.

   Everything is drawn — no photograph of a handset, so nothing to load, the
   frame takes the page's own colours, and it stays sharp at any size. The shell
   is the padding, the screen is the panels inside it, and the chrome (the
   island, the home bar) is pseudo-elements, which the reset at the top of this
   file cannot reach.

   Every radius and shadow here is !important on purpose. Section 02 flattens
   everything we add, deliberately — the design has no round corners. A device
   is the exception the rule was never written for, so it says so out loud
   rather than by weakening the rule for everything else.

   The status line is added by the script and the layout allows for it either
   way, so a browser that never runs it gets a phone with a taller header, not
   a hole.                                                                    */

.sprio-module .mod-chat {
  position: relative;
  width: min(354px, 100%);
  margin: 0 auto;
  padding: 12px;
  border: 0;
  /* A horizontal sweep, not a diagonal: machined metal catches the light in
     bands down its length, and that is the whole difference between a titanium
     rail and a grey border. */
  background: linear-gradient(
    96deg,
    #6d6d79 0%, #cfcfd8 5%, #f4f4f8 11%, #a2a2ae 26%,
    #52525d 48%, #a6a6b2 70%, #f1f1f5 88%, #777783 100%
  ) !important;
  border-radius: 54px !important;
  box-shadow:
    0 0 0 1px rgba(3, 3, 7, 0.4),
    0 46px 92px -34px rgba(3, 3, 7, 0.52),
    0 14px 32px -16px rgba(3, 3, 7, 0.34) !important;
}

/* The black gasket between glass and metal, drawn over both so the two
   surfaces read as one edge rather than as two things placed together. */
.sprio-module .mod-chat::before {
  content: '';
  position: absolute;
  inset: 10px;
  border-radius: 44px;
  box-shadow: 0 0 0 3px #07070c;
  pointer-events: none;
  z-index: 5;
}

/* The island. Near-black on a near-black header, so it needs the hairline to
   exist at all — which is also how it looks on the device. */
.sprio-module .mod-chat::after {
  content: '';
  position: absolute;
  top: 24px;
  left: 50%;
  width: 94px;
  height: 28px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: #000;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.09);
  z-index: 6;
}

/* ---------------------------------------------------------------- the screen */

.sprio-module .mod-phone-status {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 52px;
  padding: 6px 28px 0;
  border-radius: 42px 42px 0 0 !important;
  background: var(--wf-ink);
  color: #fff;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.sprio-module .mod-phone-status .mod-phone-icons { display: inline-flex; align-items: center; gap: 6px; }
.sprio-module .mod-phone-status svg { display: block; height: 11px; width: auto; fill: currentColor; }

.sprio-module .mod-chat > .mod-chat-head {
  position: relative;
  border-radius: 42px 42px 0 0 !important;
  padding: 60px 20px 18px;
}

/* With the status line present the header is no longer the top of the screen. */
.sprio-module .mod-phone-status + .mod-chat-head { border-radius: 0 !important; padding-top: 14px; }

.sprio-module .mod-chat-head .mod-avatar {
  width: 40px;
  height: 40px;
  border-radius: 999px !important;
  font-size: 14px;
  color: #fff;
}

.sprio-module .mod-chat-head strong { font-size: 15px; }
.sprio-module .mod-chat-head div > span { font-size: 12px; }

/* A live line rather than the word alone: the dot is what says "now". Scoped to
   the span beside the name — the avatar is a span too. */
.sprio-module .mod-chat-head div > span::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 7px;
  border-radius: 999px;
  background: #35d07f;
  vertical-align: middle;
}

.sprio-module .mod-chat-body {
  position: relative;
  padding: 18px 14px 34px;
  gap: 11px;
  border-radius: 0 0 42px 42px !important;
  background:
    radial-gradient(120% 55% at 50% 0%, rgba(105, 4, 242, 0.07), transparent 62%),
    #f5f3fb;
}

/* The home bar. */
.sprio-module .mod-chat-body::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 11px;
  width: 116px;
  height: 5px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: rgba(3, 3, 7, 0.26);
}

.sprio-module .mod-chat .mod-bubble {
  max-width: 84%;
  padding: 9px 13px 7px;
  font-size: 14px;
  line-height: 1.42;
  border: 0;
  border-radius: 17px 17px 17px 5px !important;
  background: #fff;
  box-shadow: 0 1px 2px rgba(3, 3, 7, 0.12) !important;
}

.sprio-module .mod-chat .mod-bubble.is-guest {
  border-radius: 17px 17px 5px 17px !important;
  background: var(--wf-violet);
  color: #fff;
}

.sprio-module .mod-chat .mod-bubble time { margin-top: 4px; font-size: 11px; }
.sprio-module .mod-chat .mod-bubble.is-guest time { color: rgba(255, 255, 255, 0.74); }

@media (max-width: 767px) {
  .sprio-module .mod-chat { width: min(320px, 100%); }
}

/* ================================================= 27 case studies, as tiles

   A picture on top, the client's wordmark under it, then the story. The same
   shape the "featured work" strip uses, so a case study reads as a piece of
   work rather than as a paragraph in a box.

   The picture is the point, and a card without one is not a case study — so
   every card has one whether or not the content file supplies it. A file can
   set <img src> per card; a card left alone falls back to the site's own
   photography, a different frame per position, which is why the fallback lives
   here rather than in the blueprint (a rebuilt row copies row one, so three
   cards would otherwise share one photograph).                               */

.sprio-module--case-studies .workflow-ibm-case-studies article {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 0 0 30px;
  border: 1px solid var(--wf-line);
  border-radius: 0;
  background: #fff;
  overflow: hidden;
  transition: transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1), border-color 200ms ease;
}

.sprio-module--case-studies .workflow-ibm-case-studies article:hover {
  transform: translateY(-5px);
  border-color: rgba(5, 5, 7, 0.4);
}

/* The media band. A block in the flow, so the words sit under it rather than
   on top of it, and the card is as tall as its content. */
.sprio-module--case-studies .workflow-ibm-case-studies article::before {
  content: '';
  display: block;
  aspect-ratio: 16 / 10;
  background-color: #12121c;
  background-position: center;
  background-size: cover;
  background-image: var(--wf-cs-photo, none);
  margin-bottom: 26px;
}

.sprio-module--case-studies .workflow-ibm-case-studies article:nth-of-type(3n + 1) { --wf-cs-photo: url('/theme/sprio-photo-05.jpg.webp'); }
.sprio-module--case-studies .workflow-ibm-case-studies article:nth-of-type(3n + 2) { --wf-cs-photo: url('/theme/sprio-photo-10.jpg.webp'); }
.sprio-module--case-studies .workflow-ibm-case-studies article:nth-of-type(3n)     { --wf-cs-photo: url('/theme/sprio-photo-14.jpg.webp'); }

/* A supplied picture covers the fallback rather than replacing the band, so a
   half-filled section has no holes in it. */
.sprio-module--case-studies article > .wf-cs-media {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}

.sprio-module--case-studies article > .wf-cs-media:not([src]),
.sprio-module--case-studies article > .wf-cs-media[src=''] { display: none; }

.sprio-module--case-studies article > :is(.workflow-ibm-logo, h3, p) { padding: 0 26px; }

.sprio-module--case-studies .workflow-ibm-logo {
  /* The export reserves 96px here for a client's logo artwork. With a wordmark
     set in type under a photograph that is just a hole in the card. */
  min-height: 0;
  color: var(--wf-ink) !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase;
  margin-bottom: 16px;
}

.sprio-module--case-studies article h3 {
  color: var(--wf-ink) !important;
  font-size: 20px !important;
  font-weight: 500 !important;
  line-height: 1.32 !important;
  margin: 0 0 12px;
}

.sprio-module--case-studies article p {
  color: var(--wf-muted) !important;
  font-size: 15px !important;
  line-height: 1.5 !important;
  margin: 0;
}

/* ============================================ 28 the field, used more widely

   The same slow field behind the dark band, at a fraction of the strength. A
   flat black section next to an animated card looks like the card is a mistake;
   this is what ties them together. It is decoration only — nothing here carries
   meaning, so it can be switched off wholesale below.                        */

.sprio-module .mod-statband { position: relative; overflow: hidden; isolation: isolate; }

.sprio-module .mod-statband::before {
  content: '';
  position: absolute;
  inset: -40%;
  z-index: 0;
  background:
    radial-gradient(30% 46% at 18% 26%, rgba(105, 4, 242, 0.5), transparent 70%),
    radial-gradient(34% 50% at 82% 74%, rgba(28, 86, 255, 0.4), transparent 72%);
  animation: sprio-drift 28s ease-in-out infinite alternate;
}

.sprio-module .mod-statband > .mod-inner { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  .sprio-module--case-studies article::before,
  .sprio-module .mod-statband::before { animation: none; }
}

/* ================================================ 29 the arrow, everywhere

   The use-case cards put a drawn arrow in the bottom-right corner and made the
   whole tile the target. Three other card modules shipped the same idea as a
   literal "->" typed at the end of a link, which reads as a typo at card size
   and sits wherever the copy happens to end.

   Same mark, same corner, same size, on every card that leads somewhere. The
   link keeps its words for anyone who cannot see the glyph — the text is set
   to nothing, not removed, so a screen reader still announces "Learn more"
   rather than "link".                                                       */

.sprio-module--related-links .workflow-ibm-related article,
.sprio-module--resource-cards .workflow-ibm-resources article,
.sprio-module--case-studies .workflow-ibm-case-studies article { position: relative; }

/* Room for it, so the arrow never lands on the last line of the copy — and
   only on a card that has one. A card whose content file gave no link has no
   arrow, and reserving the corner anyway leaves it standing on empty space. */
.sprio-module--related-links .workflow-ibm-related article:has(> a),
.sprio-module--resource-cards .workflow-ibm-resources article:has(a) > div:last-child,
.sprio-module--case-studies .workflow-ibm-case-studies article:has(> a) { padding-bottom: 62px; }

.sprio-module--related-links .workflow-ibm-related article > a,
.sprio-module--resource-cards .workflow-ibm-resources article a,
.sprio-module--case-studies .workflow-ibm-case-studies article > a {
  position: absolute;
  right: 26px;
  bottom: 24px;
  width: 22px;
  height: 22px;
  margin: 0;
  padding: 0;
  font-size: 0;
  line-height: 0;
  color: var(--wf-ink);
}

.sprio-module--related-links .workflow-ibm-related article > a::after,
.sprio-module--resource-cards .workflow-ibm-resources article a::after,
.sprio-module--case-studies .workflow-ibm-case-studies article > a::after {
  content: "";
  position: absolute;
  inset: 0;
  background: currentColor;
  -webkit-mask: no-repeat center/22px var(--wf-arrow);
  mask: no-repeat center/22px var(--wf-arrow);
}

/* The whole card is the link; the glyph only says so. */
.sprio-module--resource-cards .workflow-ibm-resources article a::before,
.sprio-module--case-studies .workflow-ibm-case-studies article > a::before {
  content: "";
  position: absolute;
  top: -100vh;
  right: -100vw;
  bottom: -100vh;
  left: -100vw;
}

/* It moves the distance it is pointing, like the rest of them. */
.sprio-module--related-links .workflow-ibm-related article > a,
.sprio-module--resource-cards .workflow-ibm-resources article a,
.sprio-module--case-studies .workflow-ibm-case-studies article > a {
  transition: transform 220ms cubic-bezier(0.22, 0.61, 0.36, 1), color 180ms ease;
}

.sprio-module--related-links .workflow-ibm-related article:hover > a,
.sprio-module--resource-cards .workflow-ibm-resources article:hover a,
.sprio-module--case-studies .workflow-ibm-case-studies article:hover > a {
  transform: translateX(5px);
}

/* ============================================== 30 nothing to say, nothing drawn

   A module ships with a fixed number of slots and a page rarely has exactly
   that many. A conversation of five messages, a case-study card with a headline
   and no standfirst: the missing field is blanked, and a blanked block element
   still paints — an empty bubble, a blank line holding a gap open. Neither is
   content, so neither is drawn.                                              */

.sprio-module .mod-chat .mod-bubble:empty,
.sprio-module--case-studies article p:empty,
.sprio-module--case-studies article .workflow-ibm-logo:empty { display: none; }


/* ==================================================== 31 back on brand

   Three values were drifting between the home page and everything built from
   the module library. All three are measurable, none is a matter of taste, and
   together they are why an inner page reads as a different site.

     ground      the home page is #faf9f7; the library was #ffffff
     heading     three colours were in play — #000, #030307 and violet — and
                 the tracking flipped between -0.028em and none
     display     46px here against 74px there, so the same typeface spoke in a
                 smaller, less certain voice

   Scoped away from .sprio-module--bleed on purpose. Those are the home page's
   own sections — the FAQ, the article strip, the contact band, the dark stat
   band — lifted whole. They are already on brand because they ARE the brand,
   and restyling them is how you break the thing you are trying to match.

   Named selectors rather than a blanket .sprio-module h2, because the lifted
   sections put their small uppercase kickers in an h2 as well: a blanket rule
   sets "COMMON QUESTIONS" at 58px, which is exactly what it did the first
   time I wrote this.                                                         */

.sprio-module:not(.sprio-module--bleed) > div > h2,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-intro-copy h2,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-capabilities > h2,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-usecases > h2,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-case-studies > h2 {
  color: #000 !important;
  font-weight: 500 !important;
  letter-spacing: 0 !important; /* measured off the home page: section headings are untracked */
  font-size: clamp(42px, 4vw, 58px) !important;
  line-height: 1.04 !important;
}

/* Panels are white ON the paper, which is what gives the home page its quiet
   depth. Open sections stay open — they just stop being invisible. */
.sprio-module .mod-table,
.sprio-module--case-studies .workflow-ibm-case-studies article,
.sprio-module .mod-chat-body,
.sprio-module .workflow-ibm-related article { background: #fff; }

/* The home page's dark is #000. The library's was #030307 — close enough to
   look like a mistake rather than a decision. */
.sprio-module .mod-statband { background: #000; }

/* The ground. It belongs to the page rather than to a module: a module is only
   as wide as the stack, so paper painted there leaves white margins down both
   sides. The class is set on <body> only for pages built from modules, so the
   home page — which paints its own sections — is untouched. */
:root { --wf-paper: #faf9f7; }

/* !important because the exported theme paints the body white from its own
   stylesheet, and this file loads alongside it rather than after it. */
body.sprio-modules { background: var(--wf-paper) !important; }

body.sprio-modules .sprio-module:not(.sprio-module--bleed):not(.sprio-module--hero-service):not(.opt-tone-dark):not(.opt-tone-blue) {
  background: transparent;
}

/* ============================================ 32 the bands, black and blue

   A section can sit on the page's own paper, on black, or on blue. The band
   runs edge to edge and carries a slow field of the brand's colour behind it,
   drifting on a long cycle — long enough that it reads as depth rather than as
   something moving, which is the difference between a brand band and a banner.

   The blue is the home page's own: sampled off the CTA band there, the family
   sits around #24246c with highlights toward #303cb4.

   How the bleed works: the module stops being a centred 1280px column and
   becomes a full-width block that re-creates the column with its own side
   padding. That keeps overflow:hidden usable, which is what lets the field
   drift inside the band instead of over the sections around it.             */

.sprio-module.opt-tone-dark,
.sprio-module.opt-tone-blue {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  width: 100%;
  padding-left: calc((100vw - var(--wf-stack)) / 2);
  padding-right: calc((100vw - var(--wf-stack)) / 2);
  color: #fff;
}

.sprio-module.opt-tone-dark { background: #000; }
.sprio-module.opt-tone-blue { background: #171d5e; }

.sprio-module.opt-tone-dark::before,
.sprio-module.opt-tone-blue::before {
  content: '';
  position: absolute;
  inset: -45%;
  z-index: 0;
  animation: sprio-drift 26s ease-in-out infinite alternate;
}

.sprio-module.opt-tone-dark::before {
  background:
    radial-gradient(32% 44% at 22% 24%, rgba(105, 4, 242, 0.55), transparent 70%),
    radial-gradient(36% 48% at 80% 74%, rgba(36, 60, 180, 0.45), transparent 72%);
}

.sprio-module.opt-tone-blue::before {
  background:
    radial-gradient(34% 46% at 26% 22%, rgba(105, 4, 242, 0.62), transparent 70%),
    radial-gradient(38% 50% at 78% 76%, rgba(48, 60, 180, 0.7), transparent 72%),
    radial-gradient(30% 38% at 62% 6%, rgba(0, 178, 220, 0.22), transparent 70%);
}

/* Every child sits above the field. */
.sprio-module.opt-tone-dark > *,
.sprio-module.opt-tone-blue > * { position: relative; z-index: 1; }

/* ------------------------------------------------- what a band does to type */

.sprio-module.opt-tone-dark :is(h2, h3, h4, strong, td, th, .workflow-ibm-logo),
.sprio-module.opt-tone-blue :is(h2, h3, h4, strong, td, th, .workflow-ibm-logo) {
  color: #fff !important;
}

.sprio-module.opt-tone-dark :is(p, li, time, small, span),
.sprio-module.opt-tone-blue :is(p, li, time, small, span) {
  color: rgba(255, 255, 255, 0.66) !important;
}

.sprio-module.opt-tone-dark a:not(.workflow-enterprise-button),
.sprio-module.opt-tone-blue a:not(.workflow-enterprise-button) { color: #fff !important; }

/* The figure is the loudest thing on a dark band, as it is on the stat band. */
.sprio-module.opt-tone-dark .mod-statcard-grid strong,
.sprio-module.opt-tone-blue .mod-statcard-grid strong,
.sprio-module.opt-tone-dark .mod-figstrip strong,
.sprio-module.opt-tone-blue .mod-figstrip strong {
  color: var(--wf-violet-soft) !important;
}

/* The step number is not in that list any more. It is a solid disc now, so it
   carries its own contrast and has nothing to invert — paling it on a band
   would put soft violet type on a violet fill. */
.sprio-module.opt-tone-dark .mod-step-num,
.sprio-module.opt-tone-blue .mod-step-num,
.sprio-module.opt-tone-image .mod-step-num { color: #fff !important; }

/* ------------------------------------------- and to rules, cards and glyphs */

.sprio-module.opt-tone-dark :is(article, li, tr, td, th, .mod-table, .mod-checklist li),
.sprio-module.opt-tone-blue :is(article, li, tr, td, th, .mod-table, .mod-checklist li) {
  border-color: rgba(255, 255, 255, 0.2) !important;
}

.sprio-module.opt-tone-dark .mod-table thead th,
.sprio-module.opt-tone-blue .mod-table thead th { border-bottom-color: rgba(255, 255, 255, 0.4) !important; }

.sprio-module.opt-tone-dark .mod-table tbody tr:hover,
.sprio-module.opt-tone-blue .mod-table tbody tr:hover { background: rgba(255, 255, 255, 0.06) !important; }

.sprio-module.opt-tone-dark .workflow-ibm-icon,
.sprio-module.opt-tone-blue .workflow-ibm-icon,
.sprio-module.opt-tone-dark .sprio-icon,
.sprio-module.opt-tone-blue .sprio-icon { color: #fff !important; }

/* Chips read as outlines on a band; a pastel fill on black looks like a sticker. */
.sprio-module.opt-tone-dark .mod-tag,
.sprio-module.opt-tone-blue .mod-tag {
  background: transparent !important;
  border: 1px solid rgba(255, 255, 255, 0.42);
  color: #fff !important;
}

/* Panels that were white on paper go glassy rather than staying a white slab. */
.sprio-module.opt-tone-dark :is(.mod-table, .workflow-ibm-related article),
.sprio-module.opt-tone-blue :is(.mod-table, .workflow-ibm-related article) {
  background: rgba(255, 255, 255, 0.04) !important;
}

/* A card that was open stays open; a boxed one gets a hairline, not a fill. */
.sprio-module.opt-tone-dark .workflow-ibm-card-grid article,
.sprio-module.opt-tone-blue .workflow-ibm-card-grid article { background: rgba(255, 255, 255, 0.06); }

@media (prefers-reduced-motion: reduce) {
  .sprio-module.opt-tone-dark::before,
  .sprio-module.opt-tone-blue::before { animation: none; }
}

/* The phone is its own screen and keeps its own colours. Inverting type inside
   it would put white timestamps on a white bubble — the band is behind the
   device, not inside it. */
.sprio-module.opt-tone-dark .mod-chat :is(p, li, time, small, span, strong, h3, h4),
.sprio-module.opt-tone-blue .mod-chat :is(p, li, time, small, span, strong, h3, h4) { color: inherit !important; }

.sprio-module.opt-tone-dark .mod-chat-body,
.sprio-module.opt-tone-blue .mod-chat-body { color: var(--wf-ink); }

.sprio-module.opt-tone-dark .mod-chat .mod-bubble.is-guest,
.sprio-module.opt-tone-blue .mod-chat .mod-bubble.is-guest { color: #fff !important; }

.sprio-module.opt-tone-dark .mod-chat .mod-bubble.is-guest time,
.sprio-module.opt-tone-blue .mod-chat .mod-bubble.is-guest time { color: rgba(255, 255, 255, 0.74) !important; }

/* The band is the section's background, so the module's own wrapper must stop
   painting one. Some harvested wrappers carry a white fill or a pale gradient
   from the export — left alone they sit on top of the band and the white type
   lands on white. Only the immediate child is cleared; panels nested deeper,
   the phone above all, keep their own surfaces. */
.sprio-module.opt-tone-dark > *,
.sprio-module.opt-tone-blue > * { background: transparent !important; }

/* Section 31 pins headings to black by name, which is right on paper and wrong
   on a band. Same selectors, same weight, later in the file. */
.sprio-module.opt-tone-dark > div > h2,
.sprio-module.opt-tone-blue > div > h2,
.sprio-module.opt-tone-dark .workflow-ibm-intro-copy h2,
.sprio-module.opt-tone-blue .workflow-ibm-intro-copy h2,
.sprio-module.opt-tone-dark .workflow-ibm-capabilities > h2,
.sprio-module.opt-tone-blue .workflow-ibm-capabilities > h2,
.sprio-module.opt-tone-dark .workflow-ibm-usecases > h2,
.sprio-module.opt-tone-blue .workflow-ibm-usecases > h2,
.sprio-module.opt-tone-dark .workflow-ibm-case-studies > h2,
.sprio-module.opt-tone-blue .workflow-ibm-case-studies > h2 { color: #fff !important; }

/* ================================================ 33 one type scale

   Measured off the inner page before this existed:

     H1  46px            one
     H2  58px            thirteen — bigger than the H1 above it
     H3  62 / 46 / 22 / 20w600 / 20w500 / 19px      six treatments
     P   20 / 18 / 17 / 16 / 14px                   five

   Measured off the home page, which is the brand:

     display   74px      the page title
     section   46px      a section heading
     card      20px w500 a card or list title
     lede      18px      a section standfirst
     body      16px      card copy, table cells
     meta      14px      captions, sources, timestamps
     kicker    12px      the small uppercase labels

   That is the scale below, and every step of it is one value. The ratio is
   what makes a hierarchy readable: 74 over 46 over 20 reads instantly, 46
   under 58 reads as a mistake.

   Scoped away from .sprio-module--bleed throughout — those are the home
   page's own sections and already measure exactly this.                     */

.modules-page {
  /* Down 20% from 46/5.1vw/74 at Karan's request — every stop scaled by the
     same 0.8 so the ramp keeps its shape across the whole viewport range, not
     just at the top end. The tracking is in em, so it follows on its own.
     This drives the inner-page hero only; the home page's own hero is a bleed
     section and is deliberately left where it is. */
  --t-display: clamp(37px, 4.08vw, 59px);
  --t-section: clamp(32px, 3.2vw, 46px);
  --t-card: 20px;
  --t-lede: 18px;
  --t-body: 16px;
  --t-meta: 14px;
  --t-figure: clamp(38px, 3.4vw, 48px);
  --t-figure-lg: clamp(44px, 4.2vw, 60px);
}

/* ---------------------------------------------------------------- display */

.sprio-module--hero-service .workflow-enterprise-title {
  font-size: var(--t-display) !important;
  font-weight: 500 !important;
  line-height: 1.10 !important;
  letter-spacing: -0.036em !important;
}

.sprio-module--hero-service .workflow-enterprise-copy {
  font-size: var(--t-lede) !important;
  font-weight: 400 !important;
  line-height: 1.5 !important;
}

/* ---------------------------------------------------------------- section */

.sprio-module:not(.sprio-module--bleed) > div > h2,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-intro-copy h2,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-capabilities > h2,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-usecases > h2,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-case-studies > h2,
.sprio-module .mod-statband .mod-head h3 {
  font-size: var(--t-section) !important;
  font-weight: 500 !important;
  line-height: 1.06 !important;
  letter-spacing: 0 !important;
}

/* ------------------------------------------------------- card and list title */

.sprio-module:not(.sprio-module--bleed) :is(article, li, .mod-chat-head, .workflow-ibm-thumb) :is(h3, h4),
.sprio-module:not(.sprio-module--bleed) .mod-checklist h3,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-card-grid h3,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-related h3 {
  font-size: var(--t-card) !important;
  font-weight: 500 !important;
  line-height: 1.34 !important;
  letter-spacing: 0 !important;
}

/* -------------------------------------------------------------------- copy */

.sprio-module:not(.sprio-module--bleed) :is(p, li, td) {
  font-size: var(--t-body) !important;
  font-weight: 400 !important;
  line-height: 1.52 !important;
}

/* The standfirst under a section heading is the one paragraph that leads. */
.sprio-module:not(.sprio-module--bleed) > div > p,
.sprio-module:not(.sprio-module--bleed) .workflow-ibm-intro-copy > p,
.sprio-module .mod-statband .mod-head p {
  font-size: var(--t-lede) !important;
  line-height: 1.5 !important;
}

.sprio-module:not(.sprio-module--bleed) :is(.mod-source, time, small, figcaption, .workflow-ibm-video small) {
  font-size: var(--t-meta) !important;
}

.sprio-module:not(.sprio-module--bleed) .mod-table th {
  font-size: 13px !important;
  font-weight: 500 !important;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------ figures */

.sprio-module:not(.sprio-module--bleed) :is(.mod-statcard-grid, .mod-figstrip) strong {
  font-size: var(--t-figure) !important;
  font-weight: 300 !important;
  line-height: 1 !important;
  letter-spacing: -0.02em;
}

.sprio-module .mod-statgrid strong {
  font-size: var(--t-figure-lg) !important;
  font-weight: 300 !important;
  line-height: 1 !important;
}

/* The step number is out of the figure scale. It was a 84px numeral sitting on
   a line and it is now a 72px disc with the number inside it, which is a mark
   rather than a figure — sized by the disc, not by the page's type ramp. */
.sprio-module:not(.sprio-module--bleed) .mod-step-num {
  font-size: 30px !important;
  font-weight: 400 !important;
  line-height: 1 !important;
}

/* The phone runs at its own scale — it is a screen, not a column of the page. */
.sprio-module .mod-chat :is(p, li, td, h3, h4, strong, time, span) { font-size: inherit !important; }
.sprio-module .mod-chat .mod-bubble { font-size: 14px !important; line-height: 1.42 !important; }
.sprio-module .mod-chat .mod-bubble time { font-size: 11px !important; }
.sprio-module .mod-chat-head strong { font-size: 15px !important; }
.sprio-module .mod-chat-head div > span { font-size: 12px !important; }
.sprio-module .mod-phone-status { font-size: 13.5px !important; }

/* ============================================ 34 two quiet pieces of motion

   Restraint is the whole point. A page that moves everywhere is a page nobody
   can read, so this is two things and no more.

   The rule under a section heading draws itself across as the section is
   reached — 520ms, once, left to right. It is the only thing on the page that
   announces a section, and it costs one transform.

   The figures count up, which the script handles. Both are off entirely under
   prefers-reduced-motion, and both are decoration: the rule is a border, the
   figure is the real number the moment the count lands. */

.sprio-motion .sprio-module:not(.sprio-module--bleed) > div > h2 { position: relative; }

.sprio-motion .sprio-module:not(.sprio-module--bleed) > div > h2::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -22px;
  width: 84px;
  height: 2px;
  background: var(--wf-violet);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 520ms cubic-bezier(0.22, 0.61, 0.36, 1) 120ms;
}

.sprio-motion .sprio-module:not(.sprio-module--bleed) > div > h2.is-in::after { transform: scaleX(1); }

.sprio-module.opt-tone-dark > div > h2::after,
.sprio-module.opt-tone-blue > div > h2::after { background: var(--wf-violet-soft); }

/* A photograph settles rather than snapping into place. */
.sprio-module :is(.workflow-ibm-card-grid article, .workflow-ibm-case-studies article) { overflow: hidden; }

.sprio-module :is(.workflow-ibm-card-art, .wf-cs-media) {
  transition: transform 700ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.sprio-module article:hover :is(.workflow-ibm-card-art, .wf-cs-media) { transform: scale(1.04); }

@media (prefers-reduced-motion: reduce) {
  .sprio-module :is(.workflow-ibm-card-art, .wf-cs-media) { transition: none; }
}

/* ============================== 35 the kicker and the standfirst

   Every section now opens the way the home page's do: a small uppercase label,
   the heading, then one line saying what the section is for. Both are optional
   — a section that supplies neither renders exactly as before, because an
   empty one is not drawn (section 30). */

.sprio-module .mod-kicker {
  display: block;
  margin-bottom: 14px;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--wf-ink);
}

.sprio-module .mod-standfirst {
  margin: 22px 0 0;
  max-width: 62ch;
  font-size: var(--t-lede) !important;
  font-weight: 400 !important;
  line-height: 1.5 !important;
  color: var(--wf-muted) !important;
}

.sprio-module .mod-kicker:empty,
.sprio-module .mod-standfirst:empty { display: none; }

/* The rule that draws in sits under the standfirst, not under the heading, or
   it lands in the middle of the block. */
.sprio-motion .sprio-module:not(.sprio-module--bleed) > div > h2::after { bottom: -14px; }

.sprio-module .mod-statband .mod-kicker,
.sprio-module.opt-tone-dark .mod-kicker,
.sprio-module.opt-tone-blue .mod-kicker { color: rgba(255, 255, 255, 0.72) !important; }

.sprio-module.opt-tone-dark .mod-standfirst,
.sprio-module.opt-tone-blue .mod-standfirst { color: rgba(255, 255, 255, 0.66) !important; }

/* =========================== 36 the image band, with the panel floating

   A photograph is the section, and the content sits in a white panel laid on
   top of it with the image showing all the way around. The panel is where the
   type lives, so nothing inverts and nothing has to be checked for contrast —
   the page's own colours carry on inside it.

   The photograph drifts very slowly. Long enough that it reads as the picture
   breathing rather than as a slideshow, and it is transform-only, so it costs
   the compositor and not the main thread.                                    */

.sprio-module.opt-tone-image {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  width: 100%;
  padding:
    clamp(72px, 7vw, 118px)
    calc((100vw - var(--wf-stack)) / 2 + clamp(0px, 3.2vw, 60px));
  background: #0a0a12;
}

.sprio-module.opt-tone-image::before {
  content: '';
  position: absolute;
  inset: -8%;
  z-index: 0;
  background-image: var(--wf-band-photo, url('/theme/sprio-photo-09.jpg.webp'));
  background-size: cover;
  background-position: center;
  animation: sprio-float 32s ease-in-out infinite alternate;
}

/* Different frame per band, so two image sections on one page are two pictures. */
/* Chosen deliberately: wide, dark, no faces. A portrait under a panel gets
   cropped to an eye and a chin, and a light photograph needs so much scrim to
   carry a white panel that it stops being a photograph. */
.sprio-module.opt-tone-image:nth-of-type(3n + 1)::before { --wf-band-photo: url('/theme/sprio-photo-09.jpg.webp'); }
.sprio-module.opt-tone-image:nth-of-type(3n + 2)::before { --wf-band-photo: url('/theme/sprio-photo-12.jpg.webp'); }
.sprio-module.opt-tone-image:nth-of-type(3n)::before     { --wf-band-photo: url('/theme/sprio-photo-08.jpg.webp'); }

/* Enough scrim that the panel has something to sit on, not so much that the
   photograph stops being a photograph. */
.sprio-module.opt-tone-image::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(5, 5, 12, 0.28), rgba(5, 5, 12, 0.5));
}

.sprio-module.opt-tone-image > * {
  position: relative;
  z-index: 2;
  background: #fff;
  padding: clamp(34px, 3.6vw, 60px);
  box-shadow: 0 48px 96px -44px rgba(3, 3, 7, 0.62);
}

@keyframes sprio-float {
  from { transform: scale(1.02) translate3d(-1%, -0.6%, 0); }
  to   { transform: scale(1.10) translate3d(1.4%, 1%, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .sprio-module.opt-tone-image::before { animation: none; }
}


/* ==================================== 38 the last two type strays

   Two sizes escaped the scale because they live in bleed sections, which
   section 33 deliberately leaves alone. The dark band's figure captions were
   rendering at 17px on a page whose body is 16 and whose lede is 18 — a size
   that exists nowhere else on the site. */

.sprio-module .mod-statgrid p { font-size: var(--t-body) !important; line-height: 1.52 !important; }
.sprio-module .mod-statband .mod-head p { font-size: var(--t-lede) !important; }

/* ============================== 39 the standfirst, and light panels on a band

   TWO FIXES, BOTH REGRESSIONS I INTRODUCED.

   1. The gaps inside the heading block.

   The kicker and the standfirst were added around each heading without touching
   the spacing that was already there, so both distances came out as whatever the
   module happened to be doing: 4px, 56px and 110px under one page's headings,
   and 18px above one heading against 84px above the next.

   Measured with the margins zeroed, the distance a module contributes is exactly
   its container's row-gap and nothing else — 0 in the block modules, 38 in the
   grids, 64 in the capability grid, 68 in the case studies. So the compensation
   is a short table keyed on that gap, and every line resolves to one distance:
   14px above the heading, 40px below it. 40 clears the violet rule that draws in
   under the heading at -14px.

   MEASURE THIS WITH MOTION OFF. Sections arrive by rising 18px into place, so a
   heading caught mid-animation reads 18px low and every gap around it is wrong
   by that much — which is how the first version of this table came to be
   calibrated against a moving target and landed 18px out across the board.      */

/* The block modules — the intro copy, the use-case rail, the stat band's head —
   settle it with margins, because margins are all there is between siblings. */

.sprio-module .mod-kicker:has(+ :is(h1, h2, h3)) { margin-bottom: 14px !important; }
.sprio-module .mod-kicker + :is(h1, h2, h3) { margin-top: 0 !important; }
.sprio-module :is(h2, h3):has(+ .mod-standfirst) { margin-bottom: 0 !important; }
.sprio-module :is(h2, h3) + .mod-standfirst { margin-top: 40px !important; }

/* The grid modules cannot be settled with margins at all.

   There the kicker, the heading, the standfirst and the content are four grid
   ITEMS on four rows, and the container's row-gap sits between them: 38 in the
   grids and the tables, 64 in the capability grid, 68 in the case studies. A
   negative margin looks like it should absorb that, and it does not — a grid
   track floors at zero, so pulling a 22px kicker up by 50 removes 22 and
   silently discards the rest. That is what left the kicker 42px above its
   heading while every other section had it at 14.

   So the gap is taken off the container and handed back to the content. Each of
   these containers holds exactly four children — kicker, heading, standfirst,
   one content block — which is what makes the exchange exact: the rows inside
   the heading block close to 14, and the content carries the module's own gap
   back as a margin. A section with no kicker and no standfirst is unaffected,
   because 14 + the margin is the gap it always had.                            */

.sprio-module :is(.mod-table-block, .mod-statcards, .mod-integrations, .mod-steps,
                  .mod-figstrip, .workflow-ibm-capabilities, .workflow-ibm-case-studies) {
  row-gap: 14px !important;
}
.sprio-module :is(.mod-table-block, .mod-statcards, .mod-integrations, .mod-steps,
                  .mod-figstrip, .workflow-ibm-capabilities, .workflow-ibm-case-studies)
  > :is(h2, h3) + .mod-standfirst { margin-top: 26px !important; }

/* Grid items do not collapse their margins, so the kicker's own 14px would be
   added to the row-gap rather than absorbed by it. The row-gap is the distance. */
.sprio-module :is(.mod-table-block, .mod-statcards, .mod-integrations, .mod-steps,
                  .mod-figstrip, .workflow-ibm-capabilities, .workflow-ibm-case-studies)
  > .mod-kicker { margin-bottom: 0 !important; }

/* row-gap was 38: the grids, the tables and the figure strip */
.sprio-module .mod-table-block > .mod-table-wrap,
.sprio-module .mod-statcards > .mod-statcard-grid,
.sprio-module .mod-integrations > .mod-integration-grid,
.sprio-module .mod-steps > .mod-steps-track,
.sprio-module .mod-figstrip > .mod-statgrid { margin-top: 24px !important; }
/* row-gap was 64: the capability grids */
.sprio-module .workflow-ibm-capabilities > article { margin-top: 50px !important; }
/* row-gap was 68: the case studies */
.sprio-module .workflow-ibm-case-studies > article,
.sprio-module .workflow-ibm-case-studies > .mod-cs-rail { margin-top: 54px !important; }

/*  2. A white panel on a coloured band.

   A band inverts its type to white, which is right for text sitting ON the
   band and wrong for text inside a panel sitting on it. The phone was already
   excepted; the case-study cards were not, so three white cards carried white
   text and read as empty boxes. Any light surface keeps the page's own ink. */

.sprio-module.opt-tone-dark :is(.mod-chat, .sprio-module--case-studies article, .workflow-ibm-case-studies article),
.sprio-module.opt-tone-blue :is(.mod-chat, .sprio-module--case-studies article, .workflow-ibm-case-studies article),
.sprio-module.opt-tone-image :is(.mod-chat, .sprio-module--case-studies article, .workflow-ibm-case-studies article) {
  color: var(--wf-ink);
}

.sprio-module.opt-tone-dark .workflow-ibm-case-studies article :is(h2, h3, h4, strong),
.sprio-module.opt-tone-blue .workflow-ibm-case-studies article :is(h2, h3, h4, strong),
.sprio-module.opt-tone-image .workflow-ibm-case-studies article :is(h2, h3, h4, strong) {
  color: var(--wf-ink) !important;
}

.sprio-module.opt-tone-dark .workflow-ibm-case-studies article :is(p, span, .workflow-ibm-logo),
.sprio-module.opt-tone-blue .workflow-ibm-case-studies article :is(p, span, .workflow-ibm-logo),
.sprio-module.opt-tone-image .workflow-ibm-case-studies article :is(p, span, .workflow-ibm-logo) {
  color: var(--wf-muted) !important;
}

.sprio-module.opt-tone-dark .workflow-ibm-case-studies article > a,
.sprio-module.opt-tone-blue .workflow-ibm-case-studies article > a,
.sprio-module.opt-tone-image .workflow-ibm-case-studies article > a { color: var(--wf-ink) !important; }

/* ================== 40 the heading block spans, like the heading always did

   The kicker and the standfirst were added as siblings of the heading, and in
   the grid modules that makes them grid ITEMS — so they took a card's cell.
   On a three-column case-study section that pushed two cards along and wrapped
   the third onto its own row. The heading already spanned the full width; its
   kicker and standfirst have to as well. */

.sprio-module :is(.workflow-ibm-capabilities, .workflow-ibm-case-studies, .workflow-ibm-usecases,
                  .mod-steps, .mod-table-block, .mod-integrations, .mod-statcards, .mod-figstrip)
  > :is(.mod-kicker, .mod-standfirst) {
  grid-column: 1 / -1;
}

/* ===================== 41 more than three case studies, on a rail

   Three fit across the page. A fourth used to make all four narrower, and a
   fifth wrapped onto a second row with two empty cells beside it — neither is
   what a set of proof points should do. So beyond three the cards become a
   rail, exactly like the use-case cards: three in view at full size, the rest
   a scroll away, with the same prev/next pair bottom right.

   The wrapper is added by script (see modules-local.js) rather than written
   into the module, so it reaches pages that were imported before this existed
   and, with JavaScript off, the cards simply wrap as they used to.            */

.sprio-module .mod-cs-rail {
  grid-column: 1 / -1;
  display: grid;
  grid-auto-flow: column;
  /* Exactly a third of the visible width, and never narrower than the copy can
     take. It has to be one fixed length rather than a minmax(): given a range,
     the grid fits every track inside the container instead of overflowing it —
     which came out as four three-quarter-width cards in a row that could not
     scroll and so never earned its buttons. The track decides the width in a
     grid, so this belongs here and not on the article.

     The gap is the export's own, taken from a variable rather than retyped: a
     railed section sits directly under an un-railed one on some pages, and a
     card that changes width because a fourth was added would be visible. */
  grid-auto-columns: max(272px, calc((100% - 2 * var(--wf-cs-gap)) / 3));
  column-gap: var(--wf-cs-gap);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 4px;
  scrollbar-width: none;
}

.sprio-module .mod-cs-rail::-webkit-scrollbar { display: none; }
.sprio-module .mod-cs-rail > article { scroll-snap-align: start; margin-top: 0 !important; }

/* The buttons are a grid item too — without this they take one card's cell and
   sit in the middle of the row. */
.sprio-module .workflow-ibm-case-studies > .mod-rail-nav { grid-column: 1 / -1; }

/* A rail sets its own column count, so the four-across exception must not also
   apply — otherwise four cards are laid out twice, by two different rules. */
.sprio-module:not(.opt-head-side) .workflow-ibm-case-studies:has(> .mod-cs-rail) {
  grid-template-columns: minmax(0, 1fr);
}

/* One card at a time on a phone, where three would be 90px wide each. */
@media (max-width: 767px) {
  .sprio-module .mod-cs-rail { grid-auto-columns: minmax(0, 82%); }
}

/* On a band the buttons are the one light thing that should not stay light. */
.sprio-module.opt-tone-dark .mod-rail-nav .mod-rail-btn,
.sprio-module.opt-tone-blue .mod-rail-nav .mod-rail-btn {
  background: transparent !important;
  border-color: rgba(255, 255, 255, 0.38) !important;
  color: #fff !important;
}
.sprio-module.opt-tone-dark .mod-rail-nav .mod-rail-btn:hover:not(:disabled),
.sprio-module.opt-tone-blue .mod-rail-nav .mod-rail-btn:hover:not(:disabled) {
  border-color: #fff !important;
  background: rgba(255, 255, 255, 0.12) !important;
}
.sprio-module.opt-tone-dark .mod-rail-count,
.sprio-module.opt-tone-blue .mod-rail-count { color: rgba(255, 255, 255, 0.66) !important; }

/* ============================ 42 the orbit graphic, drifting

   The intro's illustration was a still: four ellipses and a sphere that looked
   like a diagram of something moving without moving. It now turns.

   Each ring keeps the tilt and stretch the export drew it with — those are
   stored as --r and --sx so a keyframe can spin the ring without flattening
   it, because `transform` is one property and a rotation written on its own
   would drop the scaleX and turn every ellipse back into a circle.

   Transform and opacity only, so it runs on the compositor: this sits behind
   copy people are reading and must never cost them a frame. And it is inside
   .sprio-motion, which the script only adds when the reader has not asked for
   less motion — so reduced-motion gets the still image, deliberately.

   The variant comes from the page slug (see document.ts), so pages differ from
   each other without anyone choosing.                                        */

.sprio-module .workflow-ibm-orbit::before { --r: 18deg;  --sx: 1.26; }
.sprio-module .workflow-ibm-orbit::after  { --r: -34deg; --sx: 1.18; }
.sprio-module .workflow-ibm-orbit i       { --r: 72deg;  --sx: 1.24; }
.sprio-module .workflow-ibm-orbit b       { --r: -8deg;  --sx: 0.68; }

@keyframes wf-orbit-spin {
  from { transform: rotate(var(--r)) scaleX(var(--sx)); }
  to   { transform: rotate(calc(var(--r) + 360deg)) scaleX(var(--sx)); }
}

/* A ring that leans rather than turning all the way round. */
@keyframes wf-orbit-sway {
  0%   { transform: rotate(calc(var(--r) - 9deg)) scaleX(var(--sx)); }
  50%  { transform: rotate(calc(var(--r) + 9deg)) scaleX(calc(var(--sx) * 1.06)); }
  100% { transform: rotate(calc(var(--r) - 9deg)) scaleX(var(--sx)); }
}

/* The sphere. It is the one lit object in the picture, so it breathes rather
   than travels — a moving highlight reads as alive, a moving ball reads as a
   loading spinner. */
@keyframes wf-orbit-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.07); }
}

@keyframes wf-orbit-drift {
  0%, 100% { transform: translate3d(0, -7px, 0); }
  50%      { transform: translate3d(0, 7px, 0); }
}

.sprio-motion .sprio-module .workflow-ibm-orbit::before,
.sprio-motion .sprio-module .workflow-ibm-orbit::after,
.sprio-motion .sprio-module .workflow-ibm-orbit i,
.sprio-motion .sprio-module .workflow-ibm-orbit b {
  animation: wf-orbit-spin var(--wf-orbit-dur, 48s) linear infinite;
  will-change: transform;
}

.sprio-motion .sprio-module .workflow-ibm-orbit span {
  animation: wf-orbit-breathe var(--wf-orb-dur, 7s) ease-in-out infinite;
  will-change: transform;
}

/* The rings are staggered so they never line up and never sit still together;
   the multipliers are prime-ish on purpose. */
.sprio-motion .sprio-module .workflow-ibm-orbit::before { animation-duration: calc(var(--wf-orbit-dur, 48s) * 1); }
.sprio-motion .sprio-module .workflow-ibm-orbit::after  { animation-duration: calc(var(--wf-orbit-dur, 48s) * 1.37); animation-direction: reverse; }
.sprio-motion .sprio-module .workflow-ibm-orbit i       { animation-duration: calc(var(--wf-orbit-dur, 48s) * 0.79); }
.sprio-motion .sprio-module .workflow-ibm-orbit b       { animation-duration: calc(var(--wf-orbit-dur, 48s) * 1.61); animation-direction: reverse; }

/* -------------------------------------- five graphics, one per page slug

   Not five speeds of the same picture — five different pictures. A page that
   only differs from the last one by how fast the same rings turn still reads as
   the same page, which was the point of doing this at all.

   All five are drawn from the SAME five elements the export ships: the orbit
   box's ::before and ::after, its <i>, its <b>, and the <span> that is the
   sphere. Nothing is added to the markup, so this reaches pages that were
   imported long before it existed, and a page with no illustration is
   unaffected.

   Shape rules sit outside .sprio-motion on purpose: a reader who has asked for
   less motion still gets their page's own picture, just a still one. Only the
   animations are inside it.

   Specificity is deliberate throughout. The base is `.workflow-ibm-orbit::before`
   in the theme's own sheet, and the shared animation above is three classes
   deep, so a variant has to out-rank both — hence the long prefixes rather than
   a pile of !important. */

/* 1 — ORBIT. Ellipses crossing, a lit sphere at the centre. The house default,
       and the one the export was drawn as. */
body[data-motion="1"] { --wf-orbit-dur: 48s; --wf-orb-dur: 7s; }

/* 2 — RIPPLE. Rings leaving the centre and fading, one after another: a call
       going out. Nothing rotates, so it reads as broadcast rather than orbit. */
body[data-motion="2"] { --wf-orb-dur: 4.4s; }

/* Still first, so a reader with motion turned off gets four concentric rings
   rather than nothing: the animated version starts every ring at opacity 0 and
   fades it in on its own delay, which off-screen means an empty grey box. */
body[data-motion="2"] .sprio-module .workflow-ibm-orbit::before,
body[data-motion="2"] .sprio-module .workflow-ibm-orbit::after,
body[data-motion="2"] .sprio-module .workflow-ibm-orbit i,
body[data-motion="2"] .sprio-module .workflow-ibm-orbit b {
  border-width: 1.5px;
  transform: none;
  opacity: 0.45;
}
body[data-motion="2"] .sprio-module .workflow-ibm-orbit::before { width: 108px; height: 108px; }
body[data-motion="2"] .sprio-module .workflow-ibm-orbit::after  { width: 172px; height: 172px; }
body[data-motion="2"] .sprio-module .workflow-ibm-orbit i       { width: 236px; height: 236px; }
body[data-motion="2"] .sprio-module .workflow-ibm-orbit b       { width: 300px; height: 300px; }

/* Animated, they are all one size and the ripple carries them outward. */
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit::before,
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit::after,
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit i,
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit b {
  width: 132px;
  height: 132px;
  opacity: 0;
}

@keyframes wf-ripple {
  0%   { transform: scale(0.45); opacity: 0; }
  10%  { opacity: 0.9; }
  100% { transform: scale(2.5); opacity: 0; }
}

.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit::before,
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit::after,
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit i,
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit b {
  animation: wf-ripple 5.2s ease-out infinite;
}
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit::after { animation-delay: 1.3s; }
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit i      { animation-delay: 2.6s; }
.sprio-motion body[data-motion="2"] .sprio-module .workflow-ibm-orbit b      { animation-delay: 3.9s; }

/* 3 — ARCS. Three open arcs stacked outward from the sphere, lighting in
       sequence: signal leaving a transmitter. Only the top edge of each circle
       is drawn, which is what turns a ring into an arc. */
body[data-motion="3"] { --wf-orb-dur: 6s; }

body[data-motion="3"] .sprio-module .workflow-ibm-orbit::before,
body[data-motion="3"] .sprio-module .workflow-ibm-orbit::after,
body[data-motion="3"] .sprio-module .workflow-ibm-orbit i,
body[data-motion="3"] .sprio-module .workflow-ibm-orbit b {
  border-color: transparent;
  border-top-color: rgba(105, 4, 242, 0.5);
  border-width: 2.5px;
  transform: rotate(-45deg);
}
body[data-motion="3"] .sprio-module .workflow-ibm-orbit::before { width: 120px; height: 120px; }
body[data-motion="3"] .sprio-module .workflow-ibm-orbit::after  { width: 186px; height: 186px; }
body[data-motion="3"] .sprio-module .workflow-ibm-orbit i       { width: 252px; height: 252px; }
body[data-motion="3"] .sprio-module .workflow-ibm-orbit b       { width: 318px; height: 318px; }

@keyframes wf-arc {
  0%, 70%, 100% { opacity: 0.18; }
  20%           { opacity: 1; }
}

.sprio-motion body[data-motion="3"] .sprio-module .workflow-ibm-orbit::before,
.sprio-motion body[data-motion="3"] .sprio-module .workflow-ibm-orbit::after,
.sprio-motion body[data-motion="3"] .sprio-module .workflow-ibm-orbit i,
.sprio-motion body[data-motion="3"] .sprio-module .workflow-ibm-orbit b {
  animation: wf-arc 3.6s ease-in-out infinite;
}
.sprio-motion body[data-motion="3"] .sprio-module .workflow-ibm-orbit::after { animation-delay: 0.28s; }
.sprio-motion body[data-motion="3"] .sprio-module .workflow-ibm-orbit i      { animation-delay: 0.56s; }
.sprio-motion body[data-motion="3"] .sprio-module .workflow-ibm-orbit b      { animation-delay: 0.84s; }

/* 4 — COLUMNS. Four bars rising and falling on their own cycles, the sphere
       small and steady above them: volume, not orbit. `border-radius` is set
       twice because the page-wide flatten reset would otherwise square the
       ends, the same rule that once made the phone a silver box. */
body[data-motion="4"] { --wf-orb-dur: 9s; }

body[data-motion="4"] .sprio-module .workflow-ibm-orbit::before,
body[data-motion="4"] .sprio-module .workflow-ibm-orbit::after,
body[data-motion="4"] .sprio-module .workflow-ibm-orbit i,
body[data-motion="4"] .sprio-module .workflow-ibm-orbit b {
  width: 26px;
  height: 150px;
  border: 0;
  border-radius: 14px !important;
  background: linear-gradient(180deg, rgba(105, 4, 242, 0.18), rgba(105, 4, 242, 0.62));
  transform-origin: 50% 100%;
  bottom: 26%;
  top: auto;
}
body[data-motion="4"] .sprio-module .workflow-ibm-orbit::before { margin-left: -117px; transform: scaleY(0.55); }
body[data-motion="4"] .sprio-module .workflow-ibm-orbit::after  { margin-left: -39px;  transform: scaleY(0.9); }
body[data-motion="4"] .sprio-module .workflow-ibm-orbit i       { margin-left: 39px;   transform: scaleY(0.68); }
body[data-motion="4"] .sprio-module .workflow-ibm-orbit b       { margin-left: 117px;  transform: scaleY(1); }

body[data-motion="4"] .sprio-module .workflow-ibm-orbit span {
  width: 46px;
  height: 46px;
  margin-bottom: 210px;
}

@keyframes wf-col {
  0%, 100% { transform: scaleY(0.4); }
  50%      { transform: scaleY(1); }
}

.sprio-motion body[data-motion="4"] .sprio-module .workflow-ibm-orbit::before,
.sprio-motion body[data-motion="4"] .sprio-module .workflow-ibm-orbit::after,
.sprio-motion body[data-motion="4"] .sprio-module .workflow-ibm-orbit i,
.sprio-motion body[data-motion="4"] .sprio-module .workflow-ibm-orbit b {
  animation: wf-col 2.8s ease-in-out infinite;
}
.sprio-motion body[data-motion="4"] .sprio-module .workflow-ibm-orbit::after { animation-duration: 3.7s; animation-delay: 0.4s; }
.sprio-motion body[data-motion="4"] .sprio-module .workflow-ibm-orbit i      { animation-duration: 2.3s; animation-delay: 0.8s; }
.sprio-motion body[data-motion="4"] .sprio-module .workflow-ibm-orbit b      { animation-duration: 4.1s; animation-delay: 0.2s; }

/* 5 — CONSTELLATION. Four filled dots of different sizes drifting around a
       centred sphere. The only variant where the pieces move independently, so
       it reads as a system of parts rather than one mechanism. */
body[data-motion="5"] { --wf-orb-dur: 8s; }

body[data-motion="5"] .sprio-module .workflow-ibm-orbit::before,
body[data-motion="5"] .sprio-module .workflow-ibm-orbit::after,
body[data-motion="5"] .sprio-module .workflow-ibm-orbit i,
body[data-motion="5"] .sprio-module .workflow-ibm-orbit b {
  border: 0;
  background: rgba(105, 4, 242, 0.42);
  border-radius: 50% !important;
}
body[data-motion="5"] .sprio-module .workflow-ibm-orbit::before { width: 30px; height: 30px; margin: -128px 0 0 -152px; }
body[data-motion="5"] .sprio-module .workflow-ibm-orbit::after  { width: 54px; height: 54px; margin: 96px 0 0 138px; background: rgba(105, 4, 242, 0.26); }
body[data-motion="5"] .sprio-module .workflow-ibm-orbit i       { width: 20px; height: 20px; margin: 118px 0 0 -168px; background: rgba(105, 4, 242, 0.55); }
body[data-motion="5"] .sprio-module .workflow-ibm-orbit b       { width: 40px; height: 40px; margin: -104px 0 0 168px; background: rgba(105, 4, 242, 0.34); }

@keyframes wf-float-a { 0%, 100% { transform: translate3d(0, -12px, 0); } 50% { transform: translate3d(10px, 12px, 0); } }
@keyframes wf-float-b { 0%, 100% { transform: translate3d(8px, 10px, 0); } 50% { transform: translate3d(-10px, -14px, 0); } }

.sprio-motion body[data-motion="5"] .sprio-module .workflow-ibm-orbit::before { animation: wf-float-a 11s ease-in-out infinite; }
.sprio-motion body[data-motion="5"] .sprio-module .workflow-ibm-orbit::after  { animation: wf-float-b 14s ease-in-out infinite; }
.sprio-motion body[data-motion="5"] .sprio-module .workflow-ibm-orbit i       { animation: wf-float-b 9s  ease-in-out infinite; }
.sprio-motion body[data-motion="5"] .sprio-module .workflow-ibm-orbit b       { animation: wf-float-a 13s ease-in-out infinite; }
.sprio-motion body[data-motion="5"] .sprio-module .workflow-ibm-orbit span    { animation-name: wf-orbit-drift; }

/* ------------------------------------------------ and the play control

   It plays nothing. There is no video behind the illustration and never was —
   it is a still from a template, and a button that does nothing is worse than
   no button, because someone will click it. The picture moves on its own now,
   which is what it was pretending to promise. */

.sprio-module .workflow-ibm-video button { display: none !important; }

/* ------------------------------------------------ and the hero's own void

   The export pushes the hero paragraph down with `margin-top: clamp(150px,
   18vh, 220px)` — 162px at a laptop height. That is right for the hero it was
   drawn for, where the paragraph is 25-38px type under a 108px headline. Ours
   is an 18px lede under a headline that has just come down 20%, so the same
   spacer reads as a hole rather than a pause. Scaled to the type it now sits
   between. */

.sprio-module--hero-service .workflow-enterprise-copy {
  margin-top: clamp(40px, 6vh, 72px) !important;
}

/* ============== 43 the bleed sections, on a page that is not the home page

   The FAQ, the contact form and the article strip are lifted from the home
   page, where each one sits in a stack that supplies its own spacing. Dropped
   onto a service page they bring that assumption with them, and it is wrong
   twice.

   The FAQ has no padding at all — first text flush with the top edge, last
   text flush with the bottom — so it touches whatever band is above it. It
   gets the same room every other section on the page has.

   The contact form carries a 101px bottom margin, which is the gap before
   whatever follows it on the home page. On a service page it is the last
   thing, so that margin is a strip of dead space between the page and the
   footer. Only the LAST module loses it — a contact form in the middle of a
   page still needs its gap.                                                 */

.sprio-module--faq-accordion { padding: clamp(64px, 6vw, 104px) 0 !important; }

.sprio .sprio-module:last-child > * { margin-bottom: 0 !important; }

/* ==================== 45 the step rule stops at the last step

   The line was one full-width bar behind the discs, so it ran off past the last
   one and trailed into empty space — the row read as unfinished.

   It is drawn as segments now: each step draws a line from its own disc across
   the gap to the next one, and the last step draws nothing. That makes the rule
   start at 1 and end at 4 whatever the count, without anyone having to tell the
   CSS how many steps there are.

   `overflow: hidden` on the track is what makes it safe when the row wraps. At
   narrow widths auto-fit drops to three columns and the fourth step moves to a
   second row; the third step's segment then points at nothing, and clipping it
   at the track's edge is what removes it — the segment reaches into the gap to
   its right, which for a last-in-row step is outside the track.             */

.sprio-module .mod-steps-track {
  --wf-step-gap: clamp(24px, 3vw, 48px);
  gap: var(--wf-step-gap);
  overflow: hidden;
}

.sprio-module .mod-steps-track::before { content: none; }

/* The disc is centred over its own column, and the copy under it with it — a
   disc centred over left-aligned text reads as a mistake rather than a choice.
   Say the word and the text goes back to the left. */
.sprio-module .mod-steps-track article {
  display: grid;
  justify-items: center;
  text-align: center;
}

.sprio-module .mod-steps-track article :is(h3, p) { max-width: 34ch; }

/* With the discs centred, a segment runs from one disc's right edge to the next
   disc's left edge: out to the middle of this column plus the disc's radius,
   and on across the gap and half of the next column, less that radius again. */
.sprio-module .mod-steps-track article::after {
  content: "";
  position: absolute;
  top: 36px;
  left: calc(50% + 36px);
  right: calc(36px - 50% - var(--wf-step-gap));
  height: 1px;
  background: var(--wf-violet);
}

.sprio-module .mod-steps-track article:last-child::after { content: none; }

/* The steps stack into one column at 1024, not at 767 — the theme's own tablet
   breakpoint. Measured rather than assumed: a connector drawn between steps
   that are above and below each other is a long horizontal line pointing at
   nothing, which is how the first version of this looked at 900px. */
@media (max-width: 1024px) {
  .sprio-module .mod-steps-track article::after { content: none; }
}

/* ============== 46 the hero's two buttons trade places

   Book a Demo is the black one and See All Agents is the white one, until the
   reader reaches for the white one — at which point the two swap, so whichever
   button the reader is about to press is always the solid black one and the
   other steps back. The pair is only ever one strong button and one quiet one;
   what changes is which is which.

   Driven by :hover and :focus-visible rather than by a click. A click on either
   of these leaves the page, so a state that only appears on click is a state
   nobody ever sees. Focus is included so the swap happens for a reader using
   the keyboard too.

   :has() on the row is what lets pointing at ONE button restyle the OTHER. A
   browser without it still gets the sensible half — the button under the
   pointer turns black — and simply does not fade the other one out.         */

.sprio-module--hero-service .workflow-enterprise-button {
  border: 1px solid var(--wf-ink) !important;
  transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease,
    transform 180ms ease;
}

.sprio-module--hero-service .workflow-enterprise-button-primary {
  background: var(--wf-ink) !important;
  color: #fff !important;
}

.sprio-module--hero-service .workflow-enterprise-button-secondary {
  background: #fff !important;
  color: var(--wf-ink) !important;
}

/* Reaching for the second button makes it the solid one. */
.sprio-module--hero-service .workflow-enterprise-button-secondary:hover,
.sprio-module--hero-service .workflow-enterprise-button-secondary:focus-visible {
  background: var(--wf-ink) !important;
  color: #fff !important;
}

/* …and the first one steps back, keeping its text readable on white. */
.sprio-module--hero-service .workflow-enterprise-actions:has(.workflow-enterprise-button-secondary:hover)
  .workflow-enterprise-button-primary,
.sprio-module--hero-service .workflow-enterprise-actions:has(.workflow-enterprise-button-secondary:focus-visible)
  .workflow-enterprise-button-primary {
  background: #fff !important;
  color: var(--wf-ink) !important;
}

/* ================= 48 the ribbon is not drawn when there is nothing in it

   The violet strip is part of the hero, and its words are hero fields. A page
   that leaves them blank was still getting the band — a stripe of brand colour
   across the top of the page saying nothing. It is content, so it behaves like
   content: no words, no ribbon. */

.sprio-module--hero-service .workflow-enterprise-alert:not(:has(strong:not(:empty))):not(:has(span:not(:empty))) {
  display: none !important;
}

/* ============ 50 the heading beside the content, when there is room for it

   Two faults, found together when a page used the side heading on a module that
   also had a standfirst.

   The first: with opt-head-side these containers are a two-column grid — a
   heading column and a content column — and their children are flat: kicker,
   heading, standfirst, then the block of cards. Section 40 above makes the
   kicker and the standfirst span both columns, which is right when the heading
   is on top and wrong here. The span closes the row, so the block of cards is
   auto-placed onto the NEXT row, in the first column: eight integration cards
   sharing a 340px column at 31px each, stat cards at 65. Six of the eight
   modules that offer the option were unaffected, which is how it survived — it
   needs the side heading and a standfirst together.

   The second: between 768 and 1080 the split leaves the content column too
   narrow whatever is placed in it. Capability cards came out at 97px and case
   studies at 94px there, side heading or not. Below 768 the layout already
   stacked; it simply stacked 300px too late.

   So: side by side above 1080, stacked below it, and in side mode the heading
   parts sit in the first column with the content pinned to the second. The rows
   have to be named explicitly for `1 / -1` to mean anything — against implicit
   rows it resolves to a single row and the fix does nothing.                 */

@media (min-width: 1080px) {
  .sprio-module.opt-head-side :is(.mod-statcards, .mod-integrations) {
    grid-template-rows: auto auto 1fr;
  }

  .sprio-module.opt-head-side :is(.mod-statcards, .mod-integrations)
    > :is(.mod-kicker, .mod-standfirst) {
    grid-column: 1;
  }

  .sprio-module.opt-head-side .mod-statcards > .mod-statcard-grid,
  .sprio-module.opt-head-side .mod-integrations > .mod-integration-grid {
    grid-column: 2;
    grid-row: 1 / -1;
    /* The 24px in section 39 is the gap under a heading that sits above the
       content. Beside it, the content starts level with the heading. */
    margin-top: 0 !important;
  }

  /* Beside a heading there is roughly two-thirds of the page to work with, so
     these grids take fewer columns than they do at full width. Eight
     integration cards across four columns of a 590px content column is 111px
     each, which is a title broken one word per line. */
  .sprio-module.opt-head-side .mod-integration-grid,
  .sprio-module.opt-head-side .mod-statcard-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1280px) {
  .sprio-module.opt-head-side .mod-integration-grid,
  .sprio-module.opt-head-side .mod-statcard-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Below 1080 the heading goes back on top and the content takes the full width,
   which is what the narrow layout always did — it just did it 300px too late. */
@media (max-width: 1079px) {
  .sprio-module.opt-head-side :is(.workflow-ibm-capabilities, .workflow-ibm-case-studies,
                                  .workflow-ibm-usecases, .mod-steps, .mod-table-block,
                                  .mod-integrations, .mod-statcards, .mod-figstrip) {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  .sprio-module.opt-head-side :is(.workflow-ibm-capabilities, .workflow-ibm-case-studies,
                                  .workflow-ibm-usecases, .mod-steps, .mod-table-block,
                                  .mod-integrations, .mod-statcards, .mod-figstrip) > * {
    grid-column: 1 / -1;
  }
}

/* ============================ 46 use case cards on a band, and their room

   The section reads as one plane: heading, a line of explanation, then the
   cards. What it was doing instead was pushing the first row of pictures up
   against the standfirst, so the sentence looked like a caption stuck to the
   photographs rather than an introduction to them. The rule below is the only
   thing standing between the two, so it has to be worth seeing.              */

.sprio-module--use-case-cards .workflow-ibm-card-grid {
  margin-top: clamp(20px, 2.2vw, 34px);
}

.sprio-module--use-case-cards .mod-standfirst {
  margin-bottom: 0;
  max-width: 62ch;
}

/* ---------------------------------------------------- the card on a band */

/* Glass, not a white slab: a fill this faint reads as a card without turning
   the row into six grey blocks on black. The hairline does the defining. */
.sprio-module--use-case-cards.opt-tone-dark .workflow-ibm-card-grid article,
.sprio-module--use-case-cards.opt-tone-blue .workflow-ibm-card-grid article {
  background: rgba(255, 255, 255, 0.045);
  border-color: rgba(255, 255, 255, 0.13) !important;
}

.sprio-module--use-case-cards.opt-tone-dark .workflow-ibm-card-grid article:hover,
.sprio-module--use-case-cards.opt-tone-blue .workflow-ibm-card-grid article:hover {
  background: rgba(255, 255, 255, 0.075);
  border-color: rgba(255, 255, 255, 0.3) !important;
}

.sprio-module--use-case-cards.opt-tone-dark .workflow-ibm-card-go,
.sprio-module--use-case-cards.opt-tone-blue .workflow-ibm-card-go {
  border-top-color: rgba(255, 255, 255, 0.14);
  color: rgba(255, 255, 255, 0.72);
}

/* #6904f2 is a fine hover colour on paper and close to unreadable on black.
   On a band the arrow goes white and moves; the violet stays where it works. */
.sprio-module--use-case-cards.opt-tone-dark .workflow-ibm-card-grid article:hover .workflow-ibm-card-go,
.sprio-module--use-case-cards.opt-tone-blue .workflow-ibm-card-grid article:hover .workflow-ibm-card-go {
  color: #fff;
}

.sprio-module--use-case-cards.opt-tone-dark .workflow-ibm-card-grid article:hover h3,
.sprio-module--use-case-cards.opt-tone-blue .workflow-ibm-card-grid article:hover h3 {
  color: #fff !important;
}

.sprio-module--use-case-cards.opt-tone-dark .workflow-ibm-card-grid article:focus-within,
.sprio-module--use-case-cards.opt-tone-blue .workflow-ibm-card-grid article:focus-within {
  outline-color: #fff;
}

/* ------------------------------------------------------------ narrow screens */

/* The picture goes shallower as the card goes wider, so a phone-width card is
   a poster rather than a postcard with a caption. */
@media (max-width: 639px) {
  .sprio-module--use-case-cards .workflow-ibm-card-art { aspect-ratio: 2 / 1; }

  .sprio-module--use-case-cards .workflow-ibm-card-grid article h3 { margin-top: 20px !important; }
}


/*
 * The site chrome: the header, its menus, and the footer.
 *
 * Separate from modules-local.css for one reason — that sheet is only loaded on
 * pages built from the module library, and the header is on EVERY page. Keeping
 * the menu's styles there meant the home page kept the old full-bleed dropdowns
 * and the violet seam under the bar while every other page was fixed, which is
 * the kind of difference nobody reports as a bug and everybody notices.
 *
 * So: anything that styles the header or the footer lives here and is loaded
 * everywhere. Anything that styles a module stays in modules-local.css.
 */

/* ============================= 44 the seam under the navigation

   The header reserves 94px and paints white for only 74 of them: the bar is
   inset 10px top and bottom, and those two strips are transparent. On the home
   page a pale gradient sits behind them and nobody notices. On a service page
   the hero's violet announcement bar is behind them, so a violet line shows
   under the navigation — and when a mega-menu is open it sits between the bar
   and the panel, which is what makes it look like the panel has come loose.

   The header is a block, so it is painted like one. Both copies: Sprio
   ships a fixed bar and a static placeholder of the same markup, and only
   painting both keeps the seam closed while the page is scrolled.            */

header > .sprio-element { background: #fff; }

/* --------------------------------------- and the gap under the menu bar

   The dropdown's container starts flush with the header, but the white panel
   inside it starts 20px lower — and the container is transparent, so those
   20px show whatever is behind. On a service page that is the hero's violet
   announcement bar, which reads as the panel having come loose from the bar it
   belongs to. The container is part of the panel, so it is painted like it. */

.e-n-menu-content.e-active { background: #fff; }

/* -------------------------- and the panel sits on the bar, not below it

   The dropdown's container carries `padding: 20px 0 0`, so the white panel
   started 20px under the header with the page showing through the gap. Painting
   that gap white (above) stopped it being violet; removing it altogether is
   what actually makes the panel meet the bar it belongs to, which is what the
   menu looks like it is meant to do. */

.e-n-menu-content { padding-top: 0 !important; }

/* ============== 47 the short dropdowns, sized to what is in them

   Product has two links, About has five. Both were drawn as the same full-bleed
   band as the AI Services panel, which has twelve things in it — so a two-item
   menu came out as a white strip across the whole window with a short column at
   the left and a great deal of nothing to the right.

   A short panel is now sized to its contents and sits under the item it belongs
   to, which is also what makes it obvious which menu it came from. Panels that
   actually fill the width — the card grid and the Solutions rail — are
   untouched; they are the reason the wide band exists.

   The class is put on by the navigation layer, which knows what is in each
   panel. See applyNav() in src/lib/nav.ts.                                   */

@media (min-width: 1025px) {
  /* The row scrolls on a phone, and an absolutely positioned panel inside a
     scroller is clipped by it — so this is desktop only, where the row does not
     scroll and the drawer is not in use.

     The theme sets this through its own custom property, so the property is set
     as well as the shorthand: overriding only the shorthand leaves
     `overflow-x: var(--n-menu-heading-overflow-x)` still resolving to auto, and
     a scroller clips a panel whatever its z-index says. */
  header .e-n-menu-heading,
  header .e-n-menu-wrapper,
  header .e-n-menu {
    --n-menu-heading-overflow-x: visible;
    overflow: visible !important;
  }

  /* The item is the thing the panel is positioned inside, so it has to be a
     positioning context — and it has to stay one. Written plainly this loses to
     any theme rule that sets `position: static` on the item at some width, and
     an absolutely positioned panel whose containing block is not its item ends
     up wherever the next positioned ancestor happens to be. Which is a fair
     description of what Karan is seeing. */
  header li.e-n-menu-item.e-n-menu-item { position: relative !important; }

  /*
     The panel sits under its own menu item.

     Absolutely positioned inside the item, centred on it, and then nudged back
     inside the window by nav-local.js when centring would hang it over an edge
     — a featured strip under Product is 760px wide and Product is near the left,
     so strict centring puts it off the page.

     The nudge is a variable inside the transform rather than a second `left`,
     so the browser still does the centring with the panel's real width. An
     earlier attempt measured the width in script instead and measured it while
     the panel was closed, which put every panel out by half its own width. */
  header li.e-n-menu-item .e-n-menu-content.mod-nav-compact {
    position: absolute !important;
    inset: auto !important;
    /* The item sits 30px above the bottom of the bar, so this lands the panel
       exactly on the header's lower edge — where the wide panels start. */
    top: calc(100% + 30px) !important;
    left: 50% !important;
    /* Marked important like everything else in this rule, and for the same
       reason: the theme animates these panels, and an animation is a transform.
       Without it the theme's transform replaces the centring rather than
       arriving alongside it, and the panel's left edge lands on the item's
       centre — half a panel to the right of where it belongs. */
    transform: translateX(calc(-50% + var(--nav-shift, 0px))) !important;
    width: max-content !important;
    min-width: 260px;
    /* Wide enough for a column of links beside three pictures. */
    max-width: min(980px, calc(100vw - 48px));
    background: transparent !important;
    box-shadow: none !important;
  }

  /* When the panel has ended up somewhere the CSS did not intend — see
     placePanel() in nav-local.js — it stops depending on its ancestors and is
     pinned to the window instead. Nothing but the window can move it there.

     The selector repeats `li.e-n-menu-item` for one reason: it has to out-rank
     the rule above, and !important does not settle a fight between two
     important declarations — specificity does. Written the obvious short way
     this rule computed to (0,3,1) against the other's (0,3,2) and lost, so the
     panel stayed absolute and the correction had no effect at all. Third time
     this exact trap has come up in this project. */
  header li.e-n-menu-item .e-n-menu-content.mod-nav-compact.mod-nav-pinned {
    position: fixed !important;
    top: var(--nav-top, 94px) !important;
    left: var(--nav-left, 24px) !important;
    transform: none !important;
  }

  /* The box inside the panel sits at the panel's own left edge, always.
     The export baked an inline `left: 662.359px` onto one of these — a frozen
     measurement from the original site's stretch-to-full-width script — which
     rendered the About links 662px to the right of the About panel while the
     panel itself was exactly where it belonged. The offsets are stripped from
     the markup now (see stripStaleOffsets in nav.ts); this is the guard for a
     header that arrives from somewhere else still carrying them. */
  header .e-n-menu-content.mod-nav-compact > .e-con {
    left: 0 !important;
    right: auto !important;
  }

  /* Links on the left, pictures on the right.

     The panel's box is already a flex container — the theme stacks it as a
     column. Turning it into a row is the whole change: the link list becomes
     the first column and the featured strip the second, so a dropdown with
     pictures reads as one wide menu instead of a narrow one with a gallery
     hanging off the bottom. */
  header .e-n-menu-content.mod-nav-compact > *:has(.mod-nav-featured) {
    flex-direction: row !important;
    align-items: stretch;
  }

  header .e-n-menu-content.mod-nav-compact > * > *:not(.mod-nav-featured) {
    flex: 1 1 auto;
    min-width: 240px;
  }

  header .mod-nav-featured {
    flex: 0 0 auto;
    /* The rule that separated the two blocks moves with them: it was the line
       above the pictures, and side by side it is the line beside them. */
    border-top: 0;
    border-left: 1px solid rgba(3, 3, 7, 0.08);
  }

  /* In a row the cards sit in a row too, however many there are, rather than
     wrapping into the three-column grid they use when stacked. */
  header .e-n-menu-content.mod-nav-compact .mod-nav-featured-row {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 168px;
  }

  header .e-n-menu-content.mod-nav-compact > * {
    width: 100% !important;
    border-radius: 0 !important;
  }

  /* A panel that is not the full width needs its own edge. */
  header .e-n-menu-content.mod-nav-compact > * {
    border: 1px solid rgba(3, 3, 7, 0.1);
    box-shadow: 0 22px 70px rgba(0, 0, 0, 0.16);
  }
}

/* ----------------------------------------------- an icon in front of a link

   The plain menu rows had none — only the AI Services cards did — which is why
   those dropdowns read as a list of words next to a menu that reads as a menu.
   The mark is the house icon set, at the same hairline weight as everywhere
   else, and it takes the colour of the row so it follows the hover. */

header .sprio-item.has-navicon {
  display: flex !important;
  align-items: center;
  gap: 12px;
}

header .mod-navicon {
  display: inline-flex;
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  color: var(--wf-violet, #6904f2);
}

header .mod-navicon svg { width: 100%; height: 100%; }

header .sprio-item:hover .mod-navicon { color: inherit; }

/* ------------------------------------------------------- featured products

   This block is the CMS's own — the export has no picture cards in the header,
   so there was nothing to clone and nothing to match. Kept deliberately plain:
   a picture, a name, one line, and the whole card is the link. */

.mod-nav-featured {
  padding: 22px 26px 26px;
  border-top: 1px solid rgba(3, 3, 7, 0.08);
}

.mod-nav-featured-head {
  margin: 0 0 14px;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(3, 3, 7, 0.58);
}

.mod-nav-featured-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(150px, 1fr));
  gap: 16px;
}

.mod-nav-featured-card {
  display: grid;
  /* Rows sized to their content and stacked from the top. Without this a card
     that has no description has one row fewer, so its picture stretches to fill
     the height the taller cards set — and because the picture has an aspect
     ratio, growing taller makes it wider, and it spills over the card beside
     it. */
  align-content: start;
  gap: 8px;
  text-decoration: none !important;
  color: var(--wf-ink, #030307);
}

.mod-nav-featured-art {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  background: #f1f0ee center / cover no-repeat;
  transition: transform 260ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.mod-nav-featured-card:hover .mod-nav-featured-art { transform: translateY(-3px); }

.mod-nav-featured-label { font-size: 15px; line-height: 1.3; }

.mod-nav-featured-desc {
  font-size: 13px;
  line-height: 1.4;
  color: rgba(3, 3, 7, 0.58);
}

@media (max-width: 1024px) {
  .mod-nav-featured-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mod-nav-featured { padding: 18px 20px 22px; }
}

/* ================================ 49 the menu drawer, on a phone

   The theme's own handler is missing from this export (see public/nav-local.js),
   and among the things it did was measure the open drawer and write its height
   into `--n-menu-dropdown-content-box-height`. Without it the variable is 0, so
   the drawer opened to nothing: the right items, the right markup, zero pixels
   tall.

   Rather than measure it in script, the drawer is given the room it can have —
   the window below the header — and allowed to scroll inside that. The width
   comes from the same place: the export leaves a desktop stretch of 1440px on
   it, which on a 390px screen puts most of the menu off the side of the page. */

.e-n-menu[data-layout='dropdown'] .e-n-menu-toggle[aria-expanded='true'] + .e-n-menu-wrapper {
  position: fixed;
  top: 94px;
  left: 0;
  right: 0;
  width: auto;
  max-width: none;
  max-height: calc(100vh - 94px);
  padding: 8px 0 24px;
  background: #fff;
  box-shadow: 0 22px 70px rgba(0, 0, 0, 0.16);
}

/* Inside the drawer a menu item is a row, not a chip. */
.e-n-menu[data-layout='dropdown'] .e-n-menu-heading {
  flex-direction: column;
  align-items: stretch;
}

.e-n-menu[data-layout='dropdown'] .e-n-menu-item {
  border-bottom: 1px solid rgba(3, 3, 7, 0.08);
}

.e-n-menu[data-layout='dropdown'] .e-n-menu-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 54px;
  padding: 6px 22px;
}

/* The export leaves a desktop stretch width on the row, so a menu item is
   1440px wide inside a 390px drawer. Everything is drawn from the left, so
   nothing looked wrong — but the page could be dragged sideways. */
.e-n-menu[data-layout='dropdown'] .e-n-menu-heading,
.e-n-menu[data-layout='dropdown'] .e-n-menu-item {
  width: 100%;
  max-width: 100%;
}

.e-n-menu[data-layout='dropdown'] .e-n-menu-title-container { flex: 1 1 auto; }

/* The links inside an opened panel, indented under the item they belong to. */
.e-n-menu[data-layout='dropdown'] .e-n-menu-content .sprio-item {
  padding: 12px 22px 12px 30px;
}

/* A panel in the drawer belongs under its own item, in the flow — not floating
   over the page the way it does on a wide screen. */
.e-n-menu[data-layout='dropdown'] .e-n-menu-content {
  position: static !important;
  inset: auto !important;
  width: auto !important;
  transform: none !important;
  max-width: none !important;
  min-width: 0 !important;
  box-shadow: none !important;
}

.e-n-menu[data-layout='dropdown'] .e-n-menu-content > * {
  border: 0 !important;
  box-shadow: none !important;
}

/* ================================ 49 the bands that sit on every page

   The client logo row and the article grid are held once and drawn into every
   page — see bands.ts. They are the design's own bands, so they need no styling
   of their own, with one exception.

   On the home page 60px of air sits above the logo row, contributed by the band
   that runs before it there. On a page built from modules there is nothing above
   it at all, so the row starts hard against the bottom of the hero. This is that
   air, put back, and only on the shared copy — the home page's own spacing is
   untouched. Outside any media query on purpose: a phone needs the gap more than
   a desktop does, not less.                                                   */

.sprio .mod-band--logos { padding-top: clamp(38px, 4.4vw, 72px); }

/* ============================== 51 how the shared bands move

   Three settings on the Logos screen, and this is what they mean.

   STILL is the design as it shipped and adds nothing.

   MARQUEE scrolls the row continuously. The row holds its content twice (see
   marqueeTrack in bands.ts) and the track travels exactly half its own width,
   so the second copy arrives where the first began and the loop has no seam. It
   pauses when the pointer is over it — a logo somebody is looking at should
   stop moving — and it does not run at all for a visitor who has asked their
   computer to reduce motion, who gets the row standing still.

   The band is masked at both ends so logos arrive and leave through a fade
   rather than appearing at a hard edge.

   FADE brings the row up once as it comes into view. The class is added by
   nav-local.js when the band reaches the viewport; before that the row is
   already in the page and readable — the animation only ever moves what is
   there, so nothing depends on the script having run.                        */

.mod-band--marquee { overflow: hidden; }

.mod-band--marquee .mod-logo-track {
  display: flex !important;
  flex-wrap: nowrap !important;
  width: max-content !important;
  animation: mod-logo-marquee var(--logo-marquee, 42s) linear infinite;
}

.mod-band--marquee .mod-logo-track:hover { animation-play-state: paused; }

.mod-band--speed-slow { --logo-marquee: 64s; }
.mod-band--speed-medium { --logo-marquee: 42s; }
.mod-band--speed-fast { --logo-marquee: 26s; }

@keyframes mod-logo-marquee {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-50%, 0, 0); }
}

/* The logo widgets are laid out by the theme; inside a moving track they must
   not stretch to fill it or the spacing changes as the row scrolls. */
.mod-band--marquee .mod-logo-track > * { flex: 0 0 auto; }

.mod-band--marquee .e-con-inner {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .mod-band--marquee .mod-logo-track { animation: none; transform: none; }
  .mod-band--marquee .e-con-inner { -webkit-mask-image: none; mask-image: none; }
}

/* The row lifts into place once, when it arrives. Only the transform and the
   opacity move, so it costs one compositor layer and no layout. */
@media (prefers-reduced-motion: no-preference) {
  .mod-band--fade .e-con-inner > * {
    opacity: 0;
    transform: translate3d(0, 18px, 0);
  }

  .mod-band--fade.is-in .e-con-inner > * {
    opacity: 1;
    transform: none;
    transition: opacity 620ms cubic-bezier(0.22, 0.61, 0.36, 1),
                transform 620ms cubic-bezier(0.22, 0.61, 0.36, 1);
  }

  /* The heading first, then the row of logos a beat later. */
  .mod-band--fade.is-in .e-con-inner > *:nth-child(2) { transition-delay: 90ms; }
}

/* ============================================= 52 the cookie notice

   A bar at the foot of the window in the site's own type, not a modal across
   the middle of the page. A modal makes the reader deal with cookies before
   they are allowed to see what they came for, which is the pattern everybody
   has learned to resent — and it measurably costs the visit. This asks once,
   quietly, and gets out of the way.

   It arrives from below rather than fading in on the spot: movement from an
   edge reads as something arriving, and a fade in the middle of the page reads
   as something that was already there and you had missed it.                */

.mod-consent {
  position: fixed;
  z-index: 2147483000;
  left: max(16px, env(safe-area-inset-left));
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  max-width: 760px;
  margin: 0 auto;
  background: #fff;
  color: #030307;
  border: 1px solid rgba(3, 3, 7, 0.1);
  border-radius: 14px;
  box-shadow: 0 24px 60px -24px rgba(3, 3, 7, 0.32), 0 2px 8px rgba(3, 3, 7, 0.06);
  transform: translate3d(0, 18px, 0);
  opacity: 0;
  transition: opacity 320ms ease, transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.mod-consent.is-in { opacity: 1; transform: none; }

.mod-consent-inner {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 16px 20px;
  flex-wrap: wrap;
}

.mod-consent-text {
  flex: 1 1 340px;
  margin: 0;
  font-family: "Instrument Sans", system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(3, 3, 7, 0.72);
}

.mod-consent-link { color: #6904f2; text-decoration: underline; text-underline-offset: 2px; }

.mod-consent-actions { display: flex; gap: 10px; flex: 0 0 auto; }

/* Every one of these is written as .mod-consent .mod-consent-btn rather than
   .mod-consent-btn alone, and the extra class is the whole point: the theme's
   kit paints EVERY button on the site black with a 60px radius, through
   ".sprio-kit-4 button". That selector is one class and one element, so a
   single class of mine loses to it — the Decline button came out identical to
   Accept, two solid black pills asking the reader to choose between them. Two
   classes outrank it, and nothing here needs !important. */

.mod-consent .mod-consent-btn {
  font-family: "Instrument Sans", system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.2;
  padding: 11px 20px;
  border-radius: 9px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 160ms ease, border-color 160ms ease, color 160ms ease;
}

.mod-consent .mod-consent-btn--solid { background: #030307; color: #fff; }
.mod-consent .mod-consent-btn--solid:hover { background: #6904f2; }
.mod-consent .mod-consent-btn--ghost {
  background: #fff;
  color: rgba(3, 3, 7, 0.72);
  border-color: rgba(3, 3, 7, 0.16);
}
.mod-consent .mod-consent-btn--ghost:hover { border-color: #030307; color: #030307; }
.mod-consent .mod-consent-btn:focus-visible {
  outline: 2px solid #6904f2;
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .mod-consent { transition: none; transform: none; }
}

@media (max-width: 560px) {
  .mod-consent-inner { padding: 14px 16px; gap: 12px; }
  .mod-consent-actions { width: 100%; }
  .mod-consent .mod-consent-btn { flex: 1 1 0; }
}

/* ============================================ 53 the certification mark

   In the footer beside the logo, because a certification is a fact about the
   company and the footer is where a reader looks for those. A band across the
   middle of a page would be an advertisement for it, which is the opposite of
   what a trust mark is for.                                                 */

/* The colour is set here rather than inherited, and that is not a nicety: the
   footer is dark, but the mark is a plain div, so it inherits from the body and
   came out black on black — present in the markup, measurable in the DOM, and
   invisible to a reader. Anything dropped into this footer has to say what
   colour it is. .mod-trust--light is for a footer that is ever made pale. */

.mod-trust {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 20px 0 0;
  padding: 12px 14px;
  color: #fff;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 10px;
  max-width: 320px;
}

.mod-trust--light {
  color: #030307;
  background: rgba(3, 3, 7, 0.03);
  border-color: rgba(3, 3, 7, 0.12);
}

.mod-trust-mark { width: 44px; height: 44px; object-fit: contain; flex: 0 0 auto; }

.mod-trust-text {
  display: grid;
  gap: 2px;
  font-family: "Instrument Sans", system-ui, sans-serif;
  line-height: 1.35;
  color: inherit;
}

.mod-trust .mod-trust-text strong { font-size: 14px; font-weight: 600; letter-spacing: 0.01em; color: inherit; }
.mod-trust .mod-trust-text span { font-size: 12.5px; opacity: 0.66; color: inherit; }

/* ==================================================== 54 the blog

   The article page and the index. Both are built from the same header, footer
   and bands as everything else; only the middle is new, and the middle is
   nothing but typography — which is the point. A blog that invents its own
   type scale stops looking like the site it is on.                          */

.mod-article,
.mod-article-index {
  width: min(1280px, calc(100vw - 48px));
  margin: 0 auto;
  padding: clamp(48px, 5vw, 88px) 0 clamp(56px, 6vw, 96px);
  font-family: "Instrument Sans", system-ui, sans-serif;
  color: #030307;
}

.mod-article-head { max-width: 760px; }

.mod-article-crumbs {
  display: flex;
  gap: 10px;
  font-size: 13.5px;
  color: rgba(3, 3, 7, 0.5);
  margin-bottom: 26px;
}
.mod-article-crumbs a { color: #6904f2; }

.mod-article-tag,
.mod-post-tag {
  display: inline-block;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 6px 12px;
  border-radius: 999px;
  background: #fff;
  color: #030307;
  border: 1px solid rgba(3, 3, 7, 0.1);
}

.mod-article h1 {
  font-size: clamp(34px, 4vw, 56px);
  line-height: 1.08;
  letter-spacing: -0.02em;
  font-weight: 500;
  margin: 18px 0 0;
}

.mod-article-standfirst {
  font-size: clamp(17px, 1.4vw, 21px);
  line-height: 1.5;
  color: rgba(3, 3, 7, 0.62);
  margin: 20px 0 0;
}

.mod-article-meta {
  display: flex;
  gap: 14px;
  font-size: 13.5px;
  color: rgba(3, 3, 7, 0.5);
  margin: 26px 0 0;
}

.mod-article-art { margin: clamp(32px, 4vw, 56px) 0 0; }
.mod-article-art img { width: 100%; height: auto; display: block; border-radius: 4px; }

.mod-article-body { max-width: 720px; margin: clamp(32px, 4vw, 56px) 0 0; }
.mod-article-body p { font-size: 17px; line-height: 1.68; color: rgba(3, 3, 7, 0.78); margin: 0 0 22px; }
.mod-article-body h2 {
  font-size: clamp(23px, 2vw, 30px);
  line-height: 1.2;
  font-weight: 500;
  letter-spacing: -0.01em;
  margin: 42px 0 16px;
}
.mod-article-body ul { margin: 0 0 22px; padding-left: 20px; }
.mod-article-body li { font-size: 17px; line-height: 1.68; color: rgba(3, 3, 7, 0.78); margin-bottom: 8px; }
/* ---------------------------------------------- what an article can contain

   The body is written as plain text and the marks in it become these. Every
   one of them is the site's own type at the site's own sizes, so an article
   pasted out of Word reads as part of the site rather than as a document
   dropped into it. */

.mod-article-body h3 {
  font-size: clamp(19px, 1.4vw, 22px);
  line-height: 1.28;
  font-weight: 500;
  letter-spacing: -0.005em;
  margin: 32px 0 12px;
}

.mod-article-body ol { margin: 0 0 22px; padding-left: 22px; }
.mod-article-body ol li { padding-left: 4px; }

.mod-article-body strong { font-weight: 600; color: rgba(3, 3, 7, 0.92); }
.mod-article-body em { font-style: italic; }

.mod-article-body a {
  color: #6904f2;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}
.mod-article-body a:hover { text-decoration-thickness: 2px; }

.mod-article-body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9em;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(105, 4, 242, 0.07);
  color: #4b0aa8;
}

.mod-article-body blockquote {
  margin: 28px 0;
  padding: 4px 0 4px 22px;
  border-left: 3px solid #6904f2;
  font-size: clamp(19px, 1.5vw, 22px);
  line-height: 1.45;
  color: rgba(3, 3, 7, 0.86);
}

.mod-article-rule {
  margin: 40px 0;
  border: 0;
  border-top: 1px solid rgba(3, 3, 7, 0.12);
}

.mod-article-figure { margin: 32px 0; }
.mod-article-figure img { width: 100%; height: auto; display: block; border-radius: 4px; }
.mod-article-figure figcaption {
  margin-top: 10px;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(3, 3, 7, 0.55);
}

/* A table is the one thing in an article that can be wider than the column of
   text. It gets to use the full width, and on a narrow screen it scrolls
   inside its own box rather than pushing the whole page sideways. */

.mod-article-table {
  margin: 32px 0;
  max-width: min(980px, 100%);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.mod-article-table table {
  width: 100%;
  min-width: 460px;
  border-collapse: collapse;
  font-size: 16px;
  line-height: 1.5;
}

.mod-article-table th {
  text-align: left;
  font-weight: 600;
  color: #030307;
  padding: 13px 18px 13px 0;
  border-bottom: 2px solid rgba(3, 3, 7, 0.82);
  white-space: nowrap;
}

.mod-article-table td {
  padding: 14px 18px 14px 0;
  border-bottom: 1px solid rgba(3, 3, 7, 0.1);
  color: rgba(3, 3, 7, 0.78);
  vertical-align: top;
}

.mod-article-table th:last-child,
.mod-article-table td:last-child { padding-right: 0; }
.mod-article-table tbody tr:last-child td { border-bottom: 1px solid rgba(3, 3, 7, 0.16); }

@media (max-width: 767px) {
  .mod-article-table table { font-size: 15px; }
  .mod-article-table th,
  .mod-article-table td { padding-right: 14px; }
}

.mod-article-back { margin: 48px 0 0; }
.mod-article-back a { color: #6904f2; font-size: 15px; }

.mod-article-index-head { margin-bottom: clamp(32px, 4vw, 56px); }
.mod-article-index-head h1 {
  font-size: clamp(34px, 4vw, 56px);
  line-height: 1.08;
  letter-spacing: -0.02em;
  font-weight: 500;
  margin: 10px 0 0;
}

.mod-post-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 2.6vw, 40px);
}

.mod-post-card { display: grid; gap: 12px; text-decoration: none; color: inherit; }

.mod-post-art {
  display: block;
  aspect-ratio: 4 / 3;
  border-radius: 4px;
  background: #eeecf6 center/cover no-repeat;
  position: relative;
  overflow: hidden;
}
.mod-post-art .mod-post-tag { position: absolute; top: 14px; left: 14px; }

.mod-post-card .mod-post-title { font-size: 20px; font-weight: 500; line-height: 1.25; }
.mod-post-card .mod-post-excerpt { font-size: 15px; line-height: 1.55; color: rgba(3, 3, 7, 0.6); }
.mod-post-card .mod-post-date { font-size: 13px; color: rgba(3, 3, 7, 0.42); }
.mod-post-card:hover .mod-post-title { color: #6904f2; }
.mod-article-empty { color: rgba(3, 3, 7, 0.55); }

@media (max-width: 1023px) { .mod-post-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .mod-post-grid { grid-template-columns: minmax(0, 1fr); } }


/* ===== 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;
}
