/* ==========================================================================
   AI Mobile App Development Canada  —  /service/canada-mobile-app-development
   Page-scoped stylesheet. Every rule is namespaced under `.ca-page` (or a
   `.ca-` class) so nothing here can leak into the shared site styles.
   Section names follow the content, not the pages the layouts came from.
   ========================================================================== */

/* Global stylesheets set `overflow-x: hidden` on <body>, which makes it a
   scroll container and kills `position: sticky` inside. `clip` avoids the
   horizontal overflow without creating a scroll container. */
body:has(.ca-page) {
  overflow-x: clip;
}

.ca-page {
  --ca-blue: #3b7bf6;
  --ca-blue-deep: #1d5bdb;
  --ca-red: #ee2b2b;
  --ca-red-deep: #d81f28;
  --ca-ink: #10182a;
  --ca-body: #5c6675;
  --ca-muted: #8b94a3;
  --ca-tint: #f4f8ff;
  --ca-line: #e8eef9;
  --ca-radius: 22px;

  font-family:
    "Poppins",
    "Gabarito",
    system-ui,
    -apple-system,
    sans-serif;
  color: var(--ca-body);
  overflow-x: clip;
}

/* Zero-specificity resets so single-class rules below still win their margins. */
.ca-page h1,
.ca-page h2,
.ca-page h3 {
  font-family: "Poppins", "Gabarito", system-ui, sans-serif;
  color: var(--ca-ink);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0;
}

:where(.ca-page) p {
  margin: 0;
  line-height: 1.65;
}

:where(.ca-page) ul,
:where(.ca-page) ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Bootstrap's `ol, ul { padding-left: 2rem; margin-bottom: 1rem }` outranks the
   zero-specificity `:where()` reset above, so both have to be cleared again at
   class specificity. The margin is the subtle one: it left an unreachable 16px
   band under every list — visible as a white strip below the last row of the
   compliance ledger that no hover tint could cover. */
.ca-page ul,
.ca-page ol {
  padding-left: 0;
  margin-bottom: 0;
}

/* Same trap for paragraphs: Bootstrap's `p { margin-bottom: 1rem }` outranks the
   zero-specificity reset above, so every <p> carried a trailing 16px. It showed
   as dead space under the last line of the capability cards. */
.ca-page p {
  margin-bottom: 0;
}

/* The site stylesheet drop-shadows every <header> below 992px — that is meant
   for the site chrome, not these section headers. */
.ca-page header {
  box-shadow: none;
}

:where(.ca-page) img {
  max-width: 100%;
  height: auto;
  display: block;
}

.ca-accent {
  color: var(--ca-blue);
}

.ca-accent--red {
  color: var(--ca-red);
}

.ca-section {
  padding: 96px 0;
}

/* Shared centered section header. */
.ca-head {
  max-width: 900px;
  margin: 0 auto 56px;
  text-align: center;
}

.ca-head h2 {
  font-size: clamp(28px, 3.2vw, 42px);
  line-height: 1.22;
}

.ca-head p {
  margin-top: 16px;
  font-size: 16px;
  color: var(--ca-body);
}

/* -------------------------------------------------------------- reveal --- */
/* `.ca-anim` is set on <html> before first paint so targets never flash in. */
.ca-anim .ca-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition:
    opacity 0.55s ease,
    transform 0.55s cubic-bezier(0.22, 0.68, 0.35, 1);
}

.ca-anim .ca-reveal.is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .ca-anim .ca-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* -------------------------------------------------------------- buttons --- */
/* On hover the label and the arrow disc trade sides. The disc has to travel the
   label's width, which only JS can measure, so the blade script publishes it as
   --ca-btn-label-w. */
.ca-btn {
  --ca-btn-disc-w: 40px;
  --ca-btn-gap: 18px;
  --ca-btn-pad-l: 30px;
  --ca-btn-pad-r: 8px;

  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--ca-btn-gap);
  width: max-content;
  max-width: 100%;
  overflow: hidden;
  padding: 8px var(--ca-btn-pad-r) 8px var(--ca-btn-pad-l);
  border-radius: 999px;
  background: linear-gradient(
    100deg,
    var(--ca-blue) 0%,
    var(--ca-blue-deep) 100%
  );
  color: #fff;
  text-decoration: none;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  box-shadow: 0 14px 30px -14px rgba(29, 91, 219, 0.75);
  transition:
    transform 0.25s ease,
    box-shadow 0.25s ease,
    padding 0.5s cubic-bezier(0.65, 0, 0.35, 1);
}

.ca-btn:hover,
.ca-btn:focus-visible {
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 20px 38px -16px rgba(29, 91, 219, 0.85);
}

/* Only the arrow buttons swap sides; the flat pills keep their padding. */
.ca-btn:has(.ca-btn__disc):hover,
.ca-btn:has(.ca-btn__disc):focus-visible {
  padding-left: var(--ca-btn-pad-r);
  padding-right: var(--ca-btn-pad-l);
}

.ca-btn__label {
  display: inline-block;
  flex: none;
  white-space: nowrap;
  will-change: transform;
  transition: transform 0.5s cubic-bezier(0.65, 0, 0.35, 1);
}

.ca-btn__disc {
  display: grid;
  place-items: center;
  flex: none;
  width: var(--ca-btn-disc-w);
  height: var(--ca-btn-disc-w);
  border-radius: 50%;
  background: #0d1526;
  color: #fff;
  will-change: transform;
  transition: transform 0.5s cubic-bezier(0.65, 0, 0.35, 1);
}

.ca-btn__disc svg {
  width: 17px;
  height: 17px;
  transition: transform 0.4s cubic-bezier(0.65, 0, 0.35, 1);
}

.ca-btn:hover .ca-btn__disc svg,
.ca-btn:focus-visible .ca-btn__disc svg {
  transform: rotate(45deg);
}

.ca-btn:hover .ca-btn__label,
.ca-btn:focus-visible .ca-btn__label {
  transform: translateX(calc(var(--ca-btn-disc-w) + var(--ca-btn-gap)));
}

.ca-btn:hover .ca-btn__disc,
.ca-btn:focus-visible .ca-btn__disc {
  transform: translateX(
    calc(-1 * (var(--ca-btn-label-w, 200px) + var(--ca-btn-gap)))
  );
}

@media (prefers-reduced-motion: reduce) {
  .ca-btn,
  .ca-btn__label,
  .ca-btn__disc,
  .ca-btn__disc svg {
    transition: none;
  }

  .ca-btn:hover .ca-btn__label,
  .ca-btn:focus-visible .ca-btn__label,
  .ca-btn:hover .ca-btn__disc,
  .ca-btn:focus-visible .ca-btn__disc,
  .ca-btn:hover .ca-btn__disc svg,
  .ca-btn:focus-visible .ca-btn__disc svg {
    transform: none;
  }

  .ca-btn:has(.ca-btn__disc):hover,
  .ca-btn:has(.ca-btn__disc):focus-visible {
    padding-left: var(--ca-btn-pad-l);
    padding-right: var(--ca-btn-pad-r);
  }
}

/* Solid red pill on the maple CTA band. Colour only — the padding stays on the
   base rule, or the label/disc swap has no room to travel. */
.ca-btn--red {
  background: linear-gradient(100deg, #f7534b 0%, var(--ca-red-deep) 100%);
  box-shadow: 0 16px 34px -18px rgba(216, 31, 40, 0.8);
}

.ca-btn--red:hover,
.ca-btn--red:focus-visible {
  box-shadow: 0 22px 40px -18px rgba(216, 31, 40, 0.85);
}

/* Outlined blue pill — case study link. */
.ca-btn--ghost {
  background: transparent;
  color: var(--ca-blue);
  border: 1.5px solid var(--ca-blue);
  padding: 13px 28px;
  text-transform: none;
  letter-spacing: 0;
  font-size: 15px;
  box-shadow: none;
}

.ca-btn--ghost:hover,
.ca-btn--ghost:focus-visible {
  background: var(--ca-blue);
  color: #fff;
  box-shadow: 0 16px 30px -18px rgba(29, 91, 219, 0.8);
}

/* The outlined pill keeps a bare chevron — the filled disc belongs to the solid
   buttons only. */
.ca-btn--ghost .ca-btn__disc {
  width: 20px;
  height: 20px;
  background: none;
  color: inherit;
}

.ca-btn--ghost {
  --ca-btn-disc-w: 20px;
  --ca-btn-gap: 10px;
}

/* White pill on the blue FAQ aside — smaller disc, so its own swap distances. */
.ca-btn--white {
  --ca-btn-disc-w: 36px;
  --ca-btn-pad-l: 24px;
  --ca-btn-pad-r: 6px;

  background: #fff;
  color: var(--ca-ink);
  padding: 6px var(--ca-btn-pad-r) 6px var(--ca-btn-pad-l);
  text-transform: none;
  letter-spacing: 0;
  font-size: 15px;
  box-shadow: 0 12px 26px -16px rgba(0, 0, 0, 0.45);
}

.ca-btn--white:hover,
.ca-btn--white:focus-visible {
  color: var(--ca-ink);
}

.ca-btn--white .ca-btn__disc {
  background: var(--ca-ink);
  color: #fff;
}

/* =============================================================== HERO ==== */
/* The skyline artwork carries the sky wash; the gradient is only a fallback for
   the moment before the image lands. */
.ca-hero {
  position: relative;
  padding: 70px 0 110px;
  background: linear-gradient(160deg, #eef4ff 0%, #f3f8ff 45%, #ffffff 100%);
  overflow: clip;
}

.ca-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("../images/canada/hero-bg.png");
  background-position: center top;
  background-repeat: no-repeat;
  background-size: cover;
  z-index: 0;
}

.ca-hero > .container {
  z-index: 1;
}

.ca-hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.86fr);
  gap: 40px;
  align-items: center;
}

.ca-hero__title {
  font-size: clamp(34px, 4.4vw, 60px);
  line-height: 1.14;
}

.ca-hero__title em {
  display: block;
  font-style: italic;
  font-weight: 600;
}

/* The maple leaf trails the country name, sized off the headline. */
.ca-hero__leaf {
  display: inline-block;
  width: 0.42em;
  margin-left: 0.08em;
  vertical-align: 0.35em;
  transform: rotate(25deg);
}

.ca-hero__lead {
  margin-top: 22px;
  max-width: 720px;
  font-size: 15.5px;
  color: #4d5765;
  text-align: justify;
}

.ca-hero__points {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px 34px;
  margin: 42px 0 0;
  padding-left: 0;
  max-width: 780px;
}

.ca-hero__points li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ca-ink);
}

.ca-hero__ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: #dbe7ff;
  color: var(--ca-blue);
}

.ca-hero__ico img {
  width: 20px;
  height: 20px;
  object-fit: contain;
}

.ca-hero .ca-btn {
  margin-top: 42px;
}

.ca-hero__art {
  position: relative;
  justify-self: end;
  max-width: 520px;
}

.ca-hero__art img {
  width: 100%;
  filter: drop-shadow(0 40px 60px rgba(30, 60, 120, 0.22));
}

/* ============================================================ METRICS ==== */
/* Four counters on a pale blue strip, split by hairline dividers. */
.ca-metrics {
  padding: 62px 0 56px;
  background: #eef5ff;
}

.ca-metrics__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.ca-metric {
  padding: 6px 30px;
  border-left: 1px solid #d7e4fb;
  text-align: center;
}

.ca-metric:first-child {
  border-left: 0;
}

.ca-metric__value {
  display: flex;
  align-items: baseline;
  font-weight: 800;
  font-size: clamp(34px, 3.6vw, 50px);
  line-height: 1.1;
  color: var(--ca-blue);
  justify-content: center;
}

/* Its own element so the count-up script only ever rewrites the digits. */
.ca-metric__suffix {
  color: inherit;
}

.ca-metric__label {
  margin-top: 10px;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ca-ink);
}

/* ===================================================== ACCREDITATION ==== */
.ca-accreditation {
  padding: 78px 0 90px;
  background: linear-gradient(180deg, #ffffff 0%, #f4f8ff 40%, #f6fbff 100%);
  overflow: clip;
}

.ca-accreditation h2 {
  max-width: 900px;
  margin: 0 auto 48px;
  text-align: center;
  font-size: clamp(26px, 3vw, 38px);
  line-height: 1.3;
}

.ca-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    #000 6%,
    #000 94%,
    transparent
  );
  mask-image: linear-gradient(
    90deg,
    transparent,
    #000 6%,
    #000 94%,
    transparent
  );
}

.ca-marquee__track {
  display: flex;
  gap: 22px;
  width: max-content;
  animation: ca-scroll 46s linear infinite;
}

.ca-marquee:hover .ca-marquee__track {
  animation-play-state: paused;
}

@keyframes ca-scroll {
  to {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .ca-marquee__track {
    animation: none;
  }
}

.ca-badge {
  flex: 0 0 auto;
  width: 172px;
  margin: 0;
  padding: 20px 18px 18px;
  border-radius: 14px;
  background: #fff;
  text-align: center;
  box-shadow: 0 18px 34px -28px rgba(15, 22, 38, 0.55);
}

.ca-badge img {
  height: 116px;
  width: auto;
  margin: 0 auto 14px;
  object-fit: contain;
}

.ca-badge figcaption {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ca-ink);
  line-height: 1.35;
}

.ca-badge__rule {
  display: block;
  width: 34px;
  height: 2px;
  margin: 12px auto 0;
  border-radius: 2px;
  background: #2b3a4d;
}

.ca-badge__rule--blue {
  background: #2f8bd6;
}

/* =========================================================== SERVICES ==== */
.ca-services {
  background: #fff;
}

.ca-services__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
  gap: 56px;
  align-items: start;
}

.ca-services__copy h2 {
  font-size: clamp(28px, 3.4vw, 44px);
  line-height: 1.2;
}

.ca-services__copy > p {
  margin-top: 22px;
  font-size: 15.5px;
  text-align: justify;
}

.ca-services__media {
  margin-top: 40px;
  border-radius: var(--ca-radius);
  overflow: hidden;
  background: linear-gradient(140deg, #cddcf7, #e6eefc);
}

.ca-services__media img {
  width: 100%;
  aspect-ratio: 100 / 63;
  object-fit: cover;
}

.ca-services__list {
  display: grid;
  gap: 14px;
}

/* The copy column is the short one, so it rides along while the much taller
   service list scrolls past it. */
.ca-services__copy {
  position: sticky;
  top: 100px;
  align-self: start;
}

@media (max-width: 991px) {
  .ca-services__copy {
    position: static;
  }
}

.ca-service {
  padding: 16px 24px;
  border-radius: 16px;
  background: var(--ca-tint);
  border: 1px solid transparent;
  transition:
    background 0.25s ease,
    border-color 0.25s ease,
    transform 0.25s ease;
}

.ca-service:hover {
  transform: translateX(4px);
}

/* The first card ships expanded: outlined, with the body copy shown. */
.ca-service.is-open,
.ca-service:hover {
  background: #f7faff;
  border-color: #cddcf7;
}

.ca-service h3 {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.4;
  margin: 0;
  cursor: pointer;
  transition: margin-bottom 0.3s ease;
}

/* The open card's breathing room lives on the heading, not inside the
   collapsing row — padding on the row's item survives the 0fr track. */
.ca-service.is-open h3,
.ca-service:hover h3 {
  margin-bottom: 10px;
}

.ca-service__dot {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  margin-top: 10px;
  border-radius: 50%;
  background: var(--ca-blue);
}

/* Collapsed body: 0fr -> 1fr animates to the content's own height without JS
   measuring it. The child needs overflow:hidden for the row to clip. */
.ca-service__body {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  opacity: 0;
  transition:
    grid-template-rows 0.3s ease,
    opacity 0.25s ease;
}

.ca-service.is-open .ca-service__body,
.ca-service:hover .ca-service__body {
  grid-template-rows: 1fr;
  opacity: 1;
}

.ca-service__body p {
  overflow: hidden;
  margin: 0;
  padding-left: 18px;
  font-size: 14px;
  color: var(--ca-muted);
  text-align: justify;
}

/* ========================================================= MARKET CTA ==== */
/* Warm maple band: skyline + 3D props live in the background art, so the block
   only owns the copy column. */
.ca-market {
  position: relative;
  padding: 96px 0 104px;
  background: #fdf2ec url("../images/canada/band-bg.png") center / cover
    no-repeat;
  text-align: center;
  overflow: hidden;
}

.ca-market__inner {
  position: relative;
  z-index: 1;
  max-width: 760px;
  margin: 0 auto;
}

.ca-market h2 {
  font-size: clamp(26px, 3vw, 40px);
  line-height: 1.25;
}

.ca-market p {
  margin-top: 18px;
  font-size: 15.5px;
  color: #4a4340;
}

.ca-market .ca-btn {
  margin-top: 34px;
}

/* Second pass of the same band, further down the page: winter skyline art and
   the page's blue pill instead of the maple red one. */
.ca-market--winter {
  background-color: #eef4fb;
  background-image: url("../images/canada/band-winter-bg.png");
}

.ca-market--winter p {
  color: #4a5361;
}

/* ============================================================== STACK ==== */
/* One marquee row (the design shows a single lane, unlike the two-row logistics
   treatment this layout came from). */
.ca-stack {
  padding: clamp(60px, 7vw, 100px) 0;
  background: #fff;
}

/* Full-bleed lane. `overflow: hidden` clips the oversized track, so the block is
   padded (and pulled back by an equal negative margin) to leave room for the
   tiles' hover lift and shadow. */
.ca-stack__marquee {
  margin: -18px calc(50% - 50vw);
  padding: 18px 0;
  overflow: hidden;
  background: linear-gradient(180deg, #fbfcff 0%, #f5f8ff 100%);
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent,
    #000 5%,
    #000 95%,
    transparent
  );
  mask-image: linear-gradient(
    90deg,
    transparent,
    #000 5%,
    #000 95%,
    transparent
  );
}

.ca-stack__track {
  display: flex;
  gap: 22px;
  width: max-content;
  padding: 22px 0;
  animation: ca-marquee 40s linear infinite;
}

@keyframes ca-marquee {
  to {
    transform: translateX(-50%);
  }
}

.ca-stack__marquee:hover .ca-stack__track {
  animation-play-state: paused;
}

/* Fixed width because the tiles sit in a flex track rather than a grid; flex
   `stretch` keeps every tile in the lane the same height. */
.ca-stack__item {
  display: flex;
  flex: none;
  width: clamp(172px, 15vw, 216px);
  flex-direction: column;
  align-items: center;
  gap: 18px;
  padding: 30px 14px 24px;
  border: 1px solid #eef1f6;
  border-radius: 18px;
  background: #fff;
  text-align: center;
  transition:
    transform 0.35s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.35s ease,
    border-color 0.35s ease;
}

.ca-stack__item:hover {
  transform: translateY(-8px);
  border-color: rgba(59, 123, 246, 0.28);
  box-shadow: 0 18px 34px rgba(15, 40, 90, 0.12);
}

/* The logos sit bare — the tinted disc behind them was removed. Kept as an
   element so the tile's flex column still has one child per row. */
.ca-stack__disc {
  display: grid;
  place-items: center;
}

.ca-stack__item img {
  width: 72px;
  height: 72px;
  object-fit: contain;
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.ca-stack__item:hover img {
  transform: scale(1.12);
}

.ca-stack__item span {
  font-size: 15px;
  font-weight: 600;
  color: var(--ca-ink);
  transition: color 0.35s ease;
}

.ca-stack__item:hover span {
  color: var(--ca-blue);
}

/* ========================================================== PORTFOLIO ==== */
.ca-portfolio {
  padding: 0 0 clamp(60px, 7vw, 100px);
  background: #fff;
}

.ca-portfolio__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 40px;
  align-items: start;
}

.ca-portfolio__showcase {
  position: sticky;
  top: 100px;
  align-self: start;
}

/* Stacked, there is no second column to scroll past it, so a sticky stage just
   pins the slider over the copy below it. */
@media (max-width: 991px) {
  .ca-portfolio__showcase {
    position: static;
  }
}

.ca-portfolio__stage {
  position: relative;
  border-radius: 18px;
  overflow: hidden;
  background: #f3f6fc;
  /* Drag to scrub between cases. */
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
}

.ca-portfolio__stage.is-grabbing {
  cursor: grabbing;
}

.ca-portfolio__stage img {
  -webkit-user-drag: none;
}

/* All slides stack; only the active one is painted, so the stage keeps the
   height of the tallest shot instead of jumping between cases. */
.ca-portfolio__slide {
  grid-area: 1 / 1;
  width: 100%;
  opacity: 0;
  transition: opacity 0.4s ease;
}

.ca-portfolio__stage {
  display: grid;
}

.ca-portfolio__slide.is-on {
  opacity: 1;
}

.ca-portfolio__nav {
  display: flex;
  justify-content: center;
  gap: 12px;
  margin-top: 20px;
}

.ca-portfolio__arrow {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: 50%;
  background: var(--ca-blue);
  color: #fff;
  cursor: pointer;
  transition:
    background 0.25s ease,
    transform 0.25s ease;
}

.ca-portfolio__arrow:hover {
  transform: translateY(-2px);
}

.ca-portfolio__arrow[disabled] {
  background: #cfe0ff;
  cursor: default;
  transform: none;
}

.ca-portfolio__arrow svg {
  width: 18px;
  height: 18px;
}

.ca-portfolio__card {
  padding: 40px 42px;
  border: 1px solid var(--ca-line);
  border-radius: 18px;
  background: #fff;
  box-shadow: 0 24px 50px -44px rgba(15, 22, 38, 0.5);
}

.ca-portfolio__title {
  font-size: clamp(20px, 2vw, 26px);
  line-height: 1.3;
}

.ca-portfolio__facts {
  display: grid;
  gap: 22px;
  margin-top: 28px;
}

.ca-portfolio__fact {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  column-gap: 14px;
  row-gap: 6px;
}

.ca-portfolio__fact-ico {
  grid-row: 1 / 3;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: var(--ca-blue);
}

.ca-portfolio__fact-ico svg {
  width: 22px;
  height: 22px;
}

.ca-portfolio__fact--solution .ca-portfolio__fact-ico {
  color: #38b96a;
}
.ca-portfolio__fact--result .ca-portfolio__fact-ico {
  color: #a468f5;
}

.ca-portfolio__fact dt {
  align-self: center;
  font-size: 16px;
  font-weight: 700;
  color: var(--ca-ink);
}

.ca-portfolio__fact dd {
  margin: 0;
  font-size: 15px;
  color: var(--ca-body);
  text-align: justify;
}

.ca-portfolio__card .ca-btn {
  margin-top: 30px;
}

/* ========================================================= INDUSTRIES ==== */
/* Full-bleed drifting rail of industry cards, each with an outlined index that
   straddles the top edge. */
.ca-industries {
  padding: 0 0 clamp(60px, 7vw, 100px);
  background: #fff;
  overflow: hidden;
}

.ca-industries__rail {
  /* No scroll-snap: it fights the continuous auto-scroll. */
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Stop scroll re-anchoring on image load, which fights the drag. */
  overflow-anchor: none;
  /* overflow-x also makes overflow-y `auto`, so the outlined numbers — whose
       glyphs overflow their line box — need headroom or they get clipped. The
       negative margin keeps the section's spacing unchanged. */
  padding: 26px 0 10px;
  margin-top: -26px;
  cursor: grab;
  /* Entrance: the rail slides up into place when the section arrives. */
  opacity: 0;
  transform: translateY(40px);
  transition:
    opacity 0.7s ease,
    transform 0.7s ease;
}

.ca-industries__rail.is-inview {
  opacity: 1;
  transform: none;
}

.ca-industries__rail::-webkit-scrollbar {
  display: none;
}

.ca-industries__rail.is-grabbing {
  cursor: grabbing;
  user-select: none;
}

.ca-industries__rail.is-grabbing img {
  pointer-events: none;
}

.ca-industries__track {
  display: flex;
  gap: 23px;
  /* Aligns the first card with the container's left edge while the rail itself
       stays full-bleed. */
  padding: 0 max(20px, calc((100vw - 1240px) / 2));
}

.ca-indcard {
  position: relative;
  flex: none;
  width: 380px;
  /* Room for the number, which straddles the top edge of the card. */
  padding-top: 30px;
}

.ca-indcard__num {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 42px;
  height: 60px;
  line-height: 60px;
  font-family: "Poppins", sans-serif;
  font-weight: 600;
  font-size: 84px;
  letter-spacing: -3.4px;
  color: transparent;
  -webkit-text-stroke: 3px var(--ca-blue);
  pointer-events: none;
}

.ca-indcard__media {
  position: relative;
  height: 380px;
  border-radius: 28px;
  overflow: hidden;
  box-shadow: 0 5px 28px rgba(15, 40, 90, 0.1);
}

.ca-indcard__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease;
}

.ca-indcard:hover .ca-indcard__media img {
  transform: scale(1.05);
}

.ca-indcard__shade {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 150px;
  background: linear-gradient(180deg, rgba(6, 16, 34, 0.05), #061022 78%);
  filter: blur(3px);
  pointer-events: none;
}

.ca-indcard__label {
  position: absolute;
  left: 32px;
  right: 32px;
  bottom: 28px;
  font-weight: 700;
  font-size: 36px;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: #fff;
}

/* ========================================================= CAPABILITY ==== */
/* Four AI capability cards. The tinted wash and the index only appear on hover,
   so the resting grid stays quiet and the hovered card clearly leads. */
.ca-capability {
  background: #fff;
}

.ca-capability__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
}

.ca-capability__card {
  position: relative;
  padding: 40px 30px 36px;
  border: 1px solid var(--ca-line);
  border-radius: 22px;
  background: #fff;
  overflow: hidden;
  transition:
    transform 0.35s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.35s ease,
    border-color 0.35s ease;
}

/* Wash that rises from the card's foot on hover. A pseudo-element rather than a
   background transition so the card's own white stays available underneath. */
.ca-capability__card::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 100%;
  background: linear-gradient(
    180deg,
    rgba(59, 123, 246, 0) 35%,
    rgba(59, 123, 246, 0.09) 100%
  );
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
}

.ca-capability__card:hover {
  transform: translateY(-8px);
  border-color: rgba(59, 123, 246, 0.3);
  box-shadow: 0 24px 44px -28px rgba(15, 40, 90, 0.45);
}

.ca-capability__card:hover::after {
  opacity: 1;
}

.ca-capability__card > * {
  position: relative;
  z-index: 1;
}

.ca-capability__index {
  position: absolute;
  top: 22px;
  right: 26px;
  font-size: 34px;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: transparent;
  -webkit-text-stroke: 1.4px rgba(59, 123, 246, 0.28);
  transition: opacity 0.35s ease;
}

.ca-capability__ico {
  display: grid;
  place-items: center;
  width: 72px;
  height: 72px;
  border-radius: 20px;
  background: var(--ca-tint);
  transition: background 0.35s ease;
}

.ca-capability__card:hover .ca-capability__ico {
  background: #e2ecff;
}

.ca-capability__ico img {
  width: 40px;
  height: 40px;
  object-fit: contain;
}

.ca-capability__card h3 {
  margin-top: 24px;
  font-size: 19px;
  font-weight: 600;
  line-height: 1.35;
}

.ca-capability__card p {
  margin-top: 12px;
  font-size: 14.5px;
  color: var(--ca-body);
  text-align: justify;
  /* The card column is narrow enough that justification would open rivers
     between words without it. */
  hyphens: auto;
}

/* =============================================================== COST ==== */
/* The four tiers are drawn as a column chart, so the vertical space carries the
   budget progression instead of being padding. Bar heights come from
   --ca-cost-bar as a percentage of the plot area; the price rides above its own
   bar, and the names sit in a separate grid on the same track count so they all
   start on one baseline however many lines they wrap to. */
.ca-cost {
  background: linear-gradient(180deg, #fbfcff 0%, #f2f7ff 100%);
}

.ca-cost__chart {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 26px;
  margin: 0;
  --ca-cost-plot: 420px;
  /* Faint plot rules plus the solid floor the bars stand on. The floor is
       painted on the chart, not bordered on each label, so it runs unbroken
       across the column gaps. */
  background-image:
    repeating-linear-gradient(
      180deg,
      rgba(59, 123, 246, 0.09) 0 1px,
      transparent 1px 84px
    ),
    linear-gradient(#dbe6f7, #dbe6f7);
  background-size:
    100% var(--ca-cost-plot),
    100% 2px;
  background-position:
    left top,
    left var(--ca-cost-plot);
  background-repeat: repeat, no-repeat;
}

.ca-cost__col {
  display: grid;
  grid-template-rows: var(--ca-cost-plot) auto;
}

.ca-cost__plot {
  position: relative;
  display: flex;
  align-items: flex-end;
}

/* One ramp shared by every column: the gradient is sized to the plot area and
   pinned to its floor, so a short bar only reaches the blue part and the tall
   ones climb into the Canada red. Sizing it to the bar instead would give every
   column the identical sweep and encode nothing. */
.ca-cost__bar {
  width: 100%;
  height: var(--ca-cost-bar, 20%);
  border-radius: 16px 16px 0 0;
  background-image: linear-gradient(
    180deg,
    var(--ca-red) 0%,
    var(--ca-blue-deep) 100%
  );
  background-size: 100% var(--ca-cost-plot, 420px);
  background-position: left bottom;
  background-repeat: no-repeat;
  transform-origin: bottom center;
  transform: scaleY(0);
  transition: transform 0.85s cubic-bezier(0.22, 1, 0.36, 1);
}

.ca-cost__range {
  position: absolute;
  left: 0;
  right: 0;
  /* Sits just clear of its own bar's head, so the labels stagger upward with
       the columns rather than sitting on one dead line. */
  bottom: calc(var(--ca-cost-bar, 20%) + 16px);
  text-align: center;
  font-size: clamp(14px, 1.15vw, 17px);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ca-ink);
  white-space: nowrap;
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.5s ease 0.35s,
    transform 0.5s ease 0.35s;
}

/* The chart grows once it scrolls into view — `.ca-reveal` is already on the
   chart, so this reuses the observer rather than adding a second one. */
.ca-cost__chart.is-in .ca-cost__bar {
  transform: none;
}

.ca-cost__chart.is-in .ca-cost__range {
  opacity: 1;
  transform: none;
}

/* Without the reveal script (no-JS, reduced motion) the chart ships drawn. */
html:not(.ca-anim) .ca-cost__bar {
  transform: none;
}

html:not(.ca-anim) .ca-cost__range {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .ca-cost__bar,
  .ca-cost__range {
    transform: none;
    opacity: 1;
    transition: none;
  }
}

.ca-cost__label {
  display: grid;
  gap: 8px;
  padding-top: 20px;
}

.ca-cost__no {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--ca-red);
}

.ca-cost__name {
  font-size: 16.5px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ca-ink);
}

/* Closing row. Deliberately unboxed: the chart above is already a large filled
   shape, and a second solid panel directly under it fought with it. A hairline
   with a short red segment at its head carries the accent instead. */
.ca-cost__foot {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  margin-top: 52px;
  padding-top: 38px;
  border-top: 1px solid var(--ca-line);
  text-align: center;
}

/* Short red segment centred on the hairline, carrying the accent without a
   second solid panel under the chart. */
.ca-cost__foot::before {
  content: "";
  position: absolute;
  top: -2px;
  left: 50%;
  width: 68px;
  height: 4px;
  margin-left: -34px;
  border-radius: 999px;
  background: var(--ca-red);
}

.ca-cost__foot p {
  max-width: 680px;
  font-size: 17.5px;
  font-weight: 600;
  line-height: 1.55;
  color: var(--ca-ink);
}

/* ============================================================ REASONS ==== */
/* Ten rows over two columns of five — an exact fill, so the last row can never
   be half empty. Rules rather than cards: the points are one-line claims and
   boxes around them just manufacture whitespace. */
.ca-reasons {
  background: #fff;
}

.ca-reasons__ladder {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-template-rows: repeat(5, auto);
  /* Column-major, so 01–05 run down the left column instead of snaking. */
  grid-auto-flow: column;
  column-gap: 70px;
  margin: 0;
}

.ca-reason {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 22px;
  padding: 24px 8px 24px 0;
  border-bottom: 1px solid var(--ca-line);
}

/* Last row of each column keeps no rule — the ladder ends on the copy. */
.ca-reason:nth-child(5n) {
  border-bottom: 0;
}

/* Accent rule that wipes across the row on hover. */
.ca-reason::after {
  content: "";
  position: absolute;
  inset: auto 0 -1px 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.ca-reason:hover::after {
  transform: none;
}

.ca-reason {
  color: var(--ca-blue);
}

.ca-reason__no {
  font-size: clamp(30px, 3vw, 42px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  color: currentColor;
}

/* Outlined numerals. `-webkit-text-fill-color`, not `color: transparent` — the
   stroke reads `currentColor` too, so blanking `color` would blank the outline
   along with the fill and leave nothing on screen. Guarded so browsers without
   text-stroke keep solid numerals rather than invisible ones. */
@supports (-webkit-text-stroke: 1px red) {
  .ca-reason__no {
    -webkit-text-fill-color: transparent;
    -webkit-text-stroke: 1.6px currentColor;
    transition: -webkit-text-fill-color 0.35s ease;
  }

  .ca-reason:hover .ca-reason__no {
    -webkit-text-fill-color: currentColor;
  }
}

.ca-reason__label {
  font-size: clamp(16px, 1.5vw, 19px);
  font-weight: 600;
  line-height: 1.35;
  color: var(--ca-ink);
}

.ca-reasons__close {
  max-width: 900px;
  margin: 52px auto 0;
  text-align: center;
  font-size: 15.5px;
  color: var(--ca-body);
}

/* ========================================================= COMPLIANCE ==== */
/* One ledger split by a centre spine, not two separate cards. Six standards a
   side means the row hairlines meet across the spine, so the two lists read as a
   single table and neither half can run out before the other. Local wears the
   Canada red, international the page blue. */
.ca-compliance {
  background: linear-gradient(180deg, #f7faff 0%, #ffffff 100%);
}

.ca-compliance__ledger {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border: 1px solid var(--ca-line);
  border-radius: 24px;
  background: #fff;
  box-shadow: 0 30px 60px -50px rgba(15, 22, 38, 0.6);
  overflow: hidden;
}

.ca-compliance__col {
  --ca-comp-accent: var(--ca-blue);

  display: flex;
  flex-direction: column;
}

.ca-compliance__col--local {
  --ca-comp-accent: var(--ca-red);
}

/* The spine runs beside the rows only. Putting it on the column carried the
   hairline up through the header too, drawing a pale line between the red and
   blue bands where they should meet edge to edge. */
.ca-compliance__col + .ca-compliance__col .ca-compliance__list {
  border-left: 1px solid var(--ca-line);
}

.ca-compliance__head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 26px 34px;
  background: linear-gradient(
    120deg,
    var(--ca-comp-accent) 0%,
    color-mix(in srgb, var(--ca-comp-accent) 72%, #000) 100%
  );
}

.ca-compliance__head h3 {
  font-size: 19px;
  font-weight: 700;
  color: #fff;
}

.ca-compliance__mark {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
}

.ca-compliance__mark svg {
  width: 19px;
  height: 19px;
}

.ca-compliance__list {
  display: grid;
  /* Equal rows in both halves, so the hairlines line up across the spine even
       when one label wraps and its opposite number does not. `align-content`
       stops the last row absorbing the column's leftover height. */
  grid-auto-rows: minmax(64px, auto);
  align-content: start;
  /* No bottom padding: it left a white band under the last row that the hover
       tint could not reach, so the highlight read as a stripe floating above the
       card's edge. Rows now run flush to it, like the header band at the top. */
  padding: 0;
}

/* The inset lives on the row, not the list — a padded list would stop every
   hairline short of the spine and the card edge, which is what made the two
   halves read as ragged rather than as one table. */
.ca-compliance__list li {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-inline: 34px;
  border-bottom: 1px solid var(--ca-line);
  font-size: 15.5px;
  font-weight: 600;
  color: var(--ca-ink);
  transition:
    color 0.25s ease,
    background 0.25s ease;
}

.ca-compliance__list li:hover {
  background: color-mix(in srgb, var(--ca-comp-accent) 5%, #fff);
}

.ca-compliance__list li:last-child {
  border-bottom: 0;
}

.ca-compliance__list li:hover {
  color: var(--ca-comp-accent);
}

.ca-compliance__tick {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ca-comp-accent) 13%, #fff);
  color: var(--ca-comp-accent);
  transition:
    background 0.25s ease,
    color 0.25s ease;
}

.ca-compliance__tick svg {
  width: 14px;
  height: 14px;
}

.ca-compliance__list li:hover .ca-compliance__tick {
  background: var(--ca-comp-accent);
  color: #fff;
}

/* ============================================================= LAUNCH ==== */
/* Closing CTA. A solid blue panel rather than a third photographic band, so the
   page ends on the brand colour instead of a fourth skyline. */
.ca-launch {
  padding: 0 0 clamp(70px, 8vw, 110px);
  background: #fff;
}

.ca-launch__panel {
  position: relative;
  padding: clamp(48px, 6vw, 78px) clamp(28px, 5vw, 80px);
  border-radius: 30px;
  background: linear-gradient(
    115deg,
    var(--ca-blue-deep) 0%,
    var(--ca-blue) 55%,
    #6ba4ff 100%
  );
  text-align: center;
  overflow: hidden;
}

/* Two soft light pools, drawn rather than imported — they keep the panel from
   reading as one flat rectangle at large sizes. */
.ca-launch__panel::before,
.ca-launch__panel::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  pointer-events: none;
}

.ca-launch__panel::before {
  width: 340px;
  height: 340px;
  top: -140px;
  left: -90px;
}

.ca-launch__panel::after {
  width: 260px;
  height: 260px;
  right: -80px;
  bottom: -130px;
}

.ca-launch__panel > * {
  position: relative;
  z-index: 1;
}

.ca-launch h2 {
  max-width: 820px;
  margin: 0 auto;
  color: #fff;
  font-size: clamp(26px, 3vw, 40px);
  line-height: 1.24;
}

.ca-launch__accent {
  color: #ffd7d7;
}

.ca-launch p {
  max-width: 660px;
  margin: 18px auto 0;
  font-size: 15.5px;
  color: rgba(255, 255, 255, 0.88);
}

.ca-launch .ca-btn {
  margin-top: 34px;
}

/* ================================================================ FAQ ==== */
.ca-faq {
  padding: 80px 0 110px;
  background: linear-gradient(160deg, #fbfcff 0%, #eef3fb 60%, #f4f7fd 100%);
}

.ca-faq__grid {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr);
  gap: 60px;
  align-items: start;
}

/* Headline + CTA card ride along while the (much taller) question list scrolls. */
.ca-faq__intro {
  position: sticky;
  top: 100px;
}

.ca-faq h2 {
  font-size: clamp(34px, 4.4vw, 58px);
  line-height: 1.1;
}

.ca-faq__aside {
  margin-top: 90px;
  padding: 34px 36px 36px;
  border-radius: 18px;
  background: linear-gradient(115deg, var(--ca-blue-deep) 0%, #6ba4ff 100%);
  color: #fff;
  max-width: 540px;
}

.ca-faq__aside h3 {
  color: #fff;
  font-size: 21px;
  font-weight: 600;
}

.ca-faq__aside p {
  margin-top: 8px;
  font-size: 13.5px;
  color: rgba(255, 255, 255, 0.86);
}

.ca-faq__aside .ca-btn {
  margin-top: 26px;
}

.ca-faq__list {
  display: grid;
  gap: 18px;
}

.ca-faq__item {
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 18px 36px -32px rgba(15, 22, 38, 0.55);
  transition: padding-bottom 0.3s ease;
}

/* The answer's own padding cannot collapse with the row, so the open state's
   bottom space lives here instead — the services accordion does the same with a
   margin on its heading. */
.ca-faq__item.is-open,
.ca-faq__item:hover {
  padding-bottom: 26px;
}

.ca-faq__q {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  width: 100%;
  padding: 24px 28px;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: 17px;
  font-weight: 500;
  text-align: left;
  color: var(--ca-ink);
  cursor: pointer;
}

/* Plus that becomes a minus when the item is open — or merely hovered. */
.ca-faq__mark {
  position: relative;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 3px;
}

.ca-faq__mark::before,
.ca-faq__mark::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 2px;
  margin-top: -1px;
  background: var(--ca-ink);
  transition:
    transform 0.25s ease,
    opacity 0.25s ease;
}

.ca-faq__mark::after {
  transform: rotate(90deg);
}

.ca-faq__item.is-open .ca-faq__mark::after,
.ca-faq__item:hover .ca-faq__mark::after {
  transform: rotate(0);
  opacity: 0;
}

/* Collapsed body: 0fr -> 1fr animates to the content's own height without JS
   measuring it. The child needs overflow:hidden for the row to clip. Same
   mechanism as the services accordion, which is what lets hover open it. */
.ca-faq__a-wrap {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  opacity: 0;
  transition:
    grid-template-rows 0.3s ease,
    opacity 0.25s ease;
}

.ca-faq__item.is-open .ca-faq__a-wrap,
.ca-faq__item:hover .ca-faq__a-wrap {
  grid-template-rows: 1fr;
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .ca-faq__a-wrap {
    transition: none;
  }
}

.ca-faq__a {
  overflow: hidden;
  padding: 0 28px;
  font-size: 14.5px;
  color: var(--ca-muted);
  text-align: justify;
}

/* ============================================================ PROCESS ==== */
.ca-process {
  background: #fff;
}

.ca-process__list {
  position: relative;
  max-width: 1120px;
  margin: 0 auto;
  padding: 20px 0;
}

/* Vertical spine the step nodes sit on: a grey track (::before) with a coloured
   progress fill (::after) that only reaches as far as the reader has scrolled.
   The offsets are measured from the first and last node so the rail starts and
   stops exactly on them; the fallbacks only apply before the script runs.
   `z-index` keeps both layers above the active step's card. */
.ca-process__list::before,
.ca-process__list::after {
  content: "";
  position: absolute;
  top: var(--ca-rail-top, 40px);
  left: 50%;
  z-index: 1;
  width: 2px;
  margin-left: -1px;
}

.ca-process__list::before {
  bottom: var(--ca-rail-bottom, 40px);
  background: #e7eaf1;
}

/* `background-size` is pinned to the full rail length so each colour stays put as
   the fill grows, instead of the whole gradient squeezing into the filled part. */
.ca-process__list::after {
  height: var(--ca-rail-progress, 0px);
  background-image: linear-gradient(180deg, #8fb6ff, #3b7bf6, #1d5bdb);
  background-repeat: no-repeat;
  background-size: 2px var(--ca-rail-length, 100%);
  transition: height 0.45s ease;
}

.ca-step {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 40px;
  align-items: center;
  padding: 26px 30px;
  border-radius: 24px;
  transition: background 0.45s ease;
}

.ca-step + .ca-step {
  margin-top: 18px;
}

/* The step under the scroll focus line gets the tinted card treatment. */
.ca-step.is-active {
  background: #f0f5ff;
}

/* The artwork + number pair sits centred in its half of the row; the copy stays
   out on the row's edge, held clear of the spine by its inner padding. */
.ca-step__aside {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 26px;
}

.ca-step__copy {
  max-width: 330px;
  margin: 0 auto;
}

.ca-step__aside img {
  order: -1;
  width: 108px;
  height: 108px;
  border-radius: 22px;
  object-fit: contain;
  padding: 12px;
  background: #fdf1f4;
}

.ca-step__num {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: #fff;
  color: var(--ca-ink);
  font-size: 18px;
  font-weight: 600;
  box-shadow: 0 12px 26px -18px rgba(15, 22, 38, 0.7);
}

.ca-step__copy h3 {
  font-size: 24px;
  font-weight: 600;
}

.ca-step__copy p {
  margin-top: 12px;
  font-size: 15.5px;
  color: #3e4756;
  text-align: justify;
  /* The last line is the only one justification leaves ragged, so it is pinned
     to the side the step reads from. */
  text-align-last: left;
}

/* The dot welded onto the spine. The fill is always present but collapsed, so the
   active state can grow it instead of popping a new pseudo-element into place. */
.ca-step__node {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  border-radius: 50%;
  border: 2px solid currentColor;
  background: #fff;
  color: var(--ca-blue);
  transition:
    border-color 0.45s ease,
    box-shadow 0.45s ease;
}

/* Steps still ahead of the reader keep a hollow, greyed-out dot. */
.ca-step:not(.is-done) .ca-step__node {
  border-color: #dfe3ec;
}

.ca-step__node::after {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: currentColor;
  transform: scale(0);
  opacity: 0;
  transition:
    transform 0.45s cubic-bezier(0.22, 0.68, 0.35, 1),
    opacity 0.45s ease;
}

.ca-step.is-active .ca-step__node {
  box-shadow: 0 0 0 6px #dfeaff;
}

.ca-step.is-done .ca-step__node::after {
  transform: none;
  opacity: 1;
}

/* One blue thumb tint for every step — the per-step violet/green/amber
   modifiers went with the multicolour rail and nothing sets those classes. */
.ca-step__aside img {
  background: #e9f2ff;
}

/* Odd steps: copy on the left (right-aligned), art on the right. */
.ca-step--left .ca-step__copy {
  order: -1;
  text-align: right;
}

.ca-step--left .ca-step__copy p {
  text-align-last: right;
}

.ca-step--left .ca-step__aside img {
  order: 1;
}

/* ========================================================= RESPONSIVE ==== */
@media (max-width: 1199px) {
  .ca-hero__points {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .ca-portfolio__card {
    padding: 32px 28px;
  }

  .ca-capability__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 991px) {
  .ca-section,
  .ca-hero,
  .ca-accreditation,
  .ca-market {
    padding-top: 64px;
    padding-bottom: 68px;
  }

  .ca-hero__inner,
  .ca-services__grid,
  .ca-portfolio__layout,
  .ca-faq__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .ca-faq__intro {
    position: static;
  }

  .ca-faq__aside {
    margin-top: 32px;
  }

  .ca-compliance__head,
  .ca-compliance__list {
    padding-left: 24px;
    padding-right: 24px;
  }

  .ca-cost__chart {
    --ca-cost-plot: 320px;
    gap: 18px;
    background-image:
      repeating-linear-gradient(
        180deg,
        rgba(59, 123, 246, 0.09) 0 1px,
        transparent 1px 64px
      ),
      linear-gradient(#dbe6f7, #dbe6f7);
  }

  .ca-reasons__ladder {
    column-gap: 40px;
  }

  /* Phones first, CTA under them. The button sits inside the copy block, so
       the copy is dissolved with `display: contents` — its children become grid
       items and `order` can then move the button past the artwork. */
  .ca-hero__inner {
    gap: 0;
  }

  .ca-hero__copy {
    display: contents;
  }

  .ca-hero .ca-btn {
    order: 1;
    margin-top: 30px;
  }

  .ca-hero__art {
    justify-self: center;
    max-width: 420px;
    margin-top: 34px;
  }

  .ca-metrics__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 34px;
  }

  .ca-metric:nth-child(odd) {
    border-left: 0;
  }

  /* Timeline collapses to a single left-hand spine — the fill (::after) has to
       move with the track (::before) or it paints down the middle of the page. */
  .ca-process__list::before,
  .ca-process__list::after {
    left: 26px;
  }

  .ca-step,
  .ca-step--left {
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
    padding-left: 62px;
  }

  .ca-step__node {
    left: 26px;
  }

  .ca-step__aside,
  .ca-step--left .ca-step__aside {
    justify-content: flex-start;
  }

  .ca-step--left .ca-step__copy,
  .ca-step__copy {
    order: 0;
    text-align: left;
    max-width: none;
    margin: 0;
  }

  .ca-step--left .ca-step__aside img,
  .ca-step__aside img {
    order: -1;
  }
}

@media (max-width: 767px) {
  .ca-hero__points {
    grid-template-columns: minmax(0, 1fr);
  }

  .ca-hero__title {
    font-size: 34px;
  }

  .ca-faq__q {
    padding: 20px;
    font-size: 15.5px;
  }

  .ca-faq__a {
    padding: 0 20px;
  }

  .ca-capability__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked, the spine turns horizontal — the second half sits under the
       first with a rule between rather than beside it. */
  .ca-compliance__ledger {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked, the blue header band is itself the divider — no rule needed. */
  .ca-compliance__col + .ca-compliance__col .ca-compliance__list {
    border-left: 0;
  }

  .ca-compliance__list {
    grid-auto-rows: minmax(58px, auto);
  }

  /* Four columns are unlabellable at phone width and a 2x2 grid would put one
       tier's price on top of the row above it, so the chart lies down: one tier
       per row, bars growing left to right off a shared ramp. The label lives in
       the column, so it comes along instead of detaching from its bar. */
  .ca-cost__chart {
    grid-template-columns: minmax(0, 1fr);
    gap: 22px;
    background-image: none;
  }

  .ca-cost__col {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--ca-line);
  }

  .ca-cost__col:last-child {
    border-bottom: 0;
    padding-bottom: 0;
  }

  .ca-cost__label {
    order: -1;
    grid-auto-flow: column;
    justify-content: start;
    align-items: baseline;
    gap: 12px;
    padding-top: 0;
  }

  /* Stacked, not side by side: the price reads under its own bar, and the bar
       gets the row's full width to grow across. */
  .ca-cost__plot {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }

  .ca-cost__bar {
    width: var(--ca-cost-bar, 20%);
    height: 12px;
    border-radius: 999px;
    background-image: linear-gradient(
      90deg,
      var(--ca-blue-deep) 0%,
      var(--ca-red) 100%
    );
    /* Same trick as the vertical ramp: size the gradient to the row's full
           width so a short bar only shows the blue end. */
    background-size: calc(100vw - 40px) 100%;
    background-position: left center;
    transform-origin: left center;
    transform: scaleX(0);
  }

  .ca-cost__chart.is-in .ca-cost__bar {
    transform: none;
  }

  .ca-cost__range {
    position: static;
    flex: none;
    order: 1;
    text-align: left;
    font-size: 15px;
    white-space: nowrap;
  }

  /* Ten rows in one column is long but it never leaves a gap. */
  .ca-reasons__ladder {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    grid-auto-flow: row;
  }

  .ca-reason:nth-child(5n) {
    border-bottom: 1px solid var(--ca-line);
  }

  .ca-reason:last-child {
    border-bottom: 0;
  }

  .ca-indcard {
    width: 280px;
    padding-top: 22px;
  }

  .ca-indcard__media {
    height: 280px;
  }

  .ca-indcard__num {
    left: 28px;
    height: 44px;
    line-height: 44px;
    font-size: 62px;
    letter-spacing: -2.4px;
    -webkit-text-stroke-width: 2px;
  }

  .ca-indcard__label {
    left: 24px;
    right: 24px;
    bottom: 22px;
    font-size: 27px;
  }
}

@media (max-width: 575px) {
  .ca-metrics__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .ca-metric {
    border-left: 0;
    padding: 0;
  }

  /* Full-width pills so long labels can wrap instead of overflowing. The
       label/disc swap needs room the phone width does not have — the disc ends
       up outside the pill and clipped — so it is switched off here. */
  /* Not full-width: stretching the pill leaves the label marooned from its
     disc, and each CTA ends up a different width anyway because its container's
     padding differs. Sizing to the label keeps them consistent and balanced. */
  .ca-btn {
    --ca-btn-disc-w: 34px;

    width: auto;
    max-width: 100%;
    justify-content: center;
    gap: 12px;
    padding: 12px 18px;
    font-size: 12px;
    letter-spacing: 0.02em;
    text-align: center;
  }

  /* `flex: none` on the base rule keeps the label at its full one-line width
       and pushes the disc past the pill's edge — let it shrink and wrap. */
  .ca-btn__label {
    flex: 0 1 auto;
    white-space: normal;
  }

  .ca-btn:hover .ca-btn__label,
  .ca-btn:focus-visible .ca-btn__label,
  .ca-btn:hover .ca-btn__disc,
  .ca-btn:focus-visible .ca-btn__disc,
  .ca-btn:hover .ca-btn__disc svg,
  .ca-btn:focus-visible .ca-btn__disc svg {
    transform: none;
  }

  .ca-btn:has(.ca-btn__disc):hover,
  .ca-btn:has(.ca-btn__disc):focus-visible {
    padding-left: 18px;
    padding-right: 18px;
  }

  .ca-btn--red,
  .ca-btn--ghost,
  .ca-btn--white {
    justify-content: center;
    padding: 10px 22px;
    text-align: center;
  }

  .ca-stack__item {
    width: 158px;
  }

  .ca-stack__item img {
    width: 60px;
    height: 60px;
  }

  .ca-cost__foot {
    padding: 26px 22px;
  }

  .ca-compliance__head,
  .ca-compliance__list {
    padding-left: 20px;
    padding-right: 20px;
  }

  .ca-capability__card {
    padding: 32px 24px 30px;
  }

  .ca-step,
  .ca-step--left {
    padding: 22px 18px 22px 56px;
  }
}
