/* ============================================================
   Itransition replica — styles
   ============================================================ */

/* ---------- Design tokens ---------- */
:root {
  /* Primary sits 30% along the royal-blue-to-violet ramp below, i.e. pulled
     back toward blue from the halfway point. Pink is removed sitewide. */
  --c-blue: #402ce6;          /* PRIMARY — 30% along the blue-to-violet ramp */
  --c-blue-royal: #2d2deb;    /* the original royal blue — kept as the gradient start */
  --c-blue-deep: #3727c2;     /* deep primary for card backgrounds */
  --c-violet: #6d28d9;        /* the violet END of the gradient ramp */
  --c-accent: #461ee8;        /* bluish-purple accent (arrows, "Learn more") — replaces the old pink */
  --c-shadow-rgb: 45, 45, 235; /* rgb triplet behind light-bg shadows/tints — family pages remap it */
  --c-glow-rgb: 45, 45, 235;   /* rgb triplet behind glows on dark bands — family pages remap it */
  --c-grad: linear-gradient(90deg, var(--c-blue-royal) 0%, var(--c-violet) 100%);
  --c-grad-violet: var(--c-grad); /* alias — both ramps are now blue to violet */

  --c-dark: #0b0a28;          /* dark section base */
  --c-tile-navy: #091E6C;     /* solid case-study/insight tile navy — owner reference 2026-08-05 */
  --c-dark-2: #1b1146;        /* dark section purple */

  --c-ink: #14141c;           /* near-black headings */
  --c-body: #51515f;          /* body text */
  --c-muted: #7c7c8a;
  --c-ghost: #b7b7c2;         /* oversized ghost headings */

  --c-line: #e6e6ec;
  --c-surface: #ffffff;
  --c-surface-2: #f4f4f7;     /* footer / subtle panels */

  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --header-h: 84px;
  --container: 1240px;
  --radius: 4px;

  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  font-family: var(--font-sans);
  color: var(--c-ink);
  background: var(--c-surface);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
ul { list-style: none; }

.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: 32px; }

/* ---------- Reveal animation ---------- */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
/* directional variants — slide in from the side instead of up (desktop only;
   below 1081px the layout stacks to 1-2 columns so left/right no longer
   means anything, and the sideways offset was pushing tiles past the
   viewport edge and causing horizontal overflow) */
@media (min-width: 1081px) {
  .reveal.reveal-left { transform: translateX(-70px); }
  .reveal.reveal-right { transform: translateX(70px); }
  .reveal.reveal-left.is-in, .reveal.reveal-right.is-in { transform: none; }
}
/* Dense repeated items — ledger rows, tiles, list items — get a shorter rise
   and a quicker settle. At the full 22px a stack of seven reads as seven
   separate animations rather than one list arriving. */
.reveal-soft { transform: translateY(12px); transition-duration: .5s; }

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

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 44px; padding: 0 22px; border-radius: 999px;
  font-weight: 600; font-size: 15px; white-space: nowrap;
  transition: background .2s var(--ease), color .2s var(--ease), transform .2s var(--ease);
}
.btn-primary { background: var(--c-blue); color: #fff; }
.btn-primary:hover { background: #1f1fd0; }
.btn-magenta { background: #270e8a; color: #fff; }
.btn-magenta:hover { background: #210c76; }

/* ============================================================
   HEADER
   ============================================================ */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: #fff;
  border-bottom: 1px solid transparent;
  transition: box-shadow .25s var(--ease), border-color .25s var(--ease);
}
.site-header.is-scrolled { box-shadow: 0 6px 24px rgba(12, 10, 40, .07); border-bottom-color: var(--c-line); }

.header-inner {
  height: var(--header-h);
  max-width: none; margin-inline: 0; padding-left: 20px; padding-right: 28px;
  display: flex; align-items: center; gap: 22px;
}

/* brand reserves the left half so the nav begins at the page centre;
   `0 1 50%` lets it give back a few px on tight viewports (no scrollbar).
   The wrapper reserves the space; the home link (.brand-link) wraps ONLY the
   logos, so the empty right part of this reserved half is no longer clickable. */
.brand { display: flex; align-items: center; color: var(--c-ink); flex: 0 1 50%; min-width: 0; }
.brand-link { display: inline-flex; align-items: center; gap: 12px; color: inherit; }
.brand-mark { width: 30px; height: 30px; color: var(--c-ink); }
.brand-name { font-size: 22px; font-weight: 600; letter-spacing: -.02em; }

/* nav */
.nav { margin-left: 0; flex: 0 0 auto; }
.nav-list { display: flex; align-items: center; gap: 16px; }
.nav-item { position: static; }
.nav-link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 6px; font-size: 15px; font-weight: 500; color: var(--c-ink);
  position: relative;
}
.nav-link .caret { width: 9px; height: 6px; transition: transform .25s var(--ease); opacity: .8; }
.nav-link:hover { color: var(--c-blue); }

/* active underline (gradient) under the open / hovered item */
.nav-link::after {
  content: ""; position: absolute; left: 6px; right: 6px; bottom: 4px; height: 2px;
  background: var(--c-grad); border-radius: 2px;
  transform: scaleX(0); transform-origin: left; transition: transform .28s var(--ease);
}
.nav-item.is-open > .nav-link::after { transform: scaleX(1); }
.nav-item.is-open > .nav-link { color: var(--c-blue); }
.nav-item.is-open > .nav-link .caret { transform: rotate(180deg); }

.header-cta { margin-left: 0; flex: 0 0 auto; height: 38px; padding: 0 18px; font-size: 14px; }
.header-cta.btn-primary { background: var(--c-blue); }
.header-cta.btn-primary:hover { background: #1f1fd0; }

/* ============================================================
   MEGA MENU
   ============================================================ */
.mega {
  position: absolute; left: 0; right: 0; top: 100%;
  background: #fff; border-top: 1px solid var(--c-line);
  box-shadow: 0 24px 40px rgba(12, 10, 40, .10);
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity .22s var(--ease), transform .22s var(--ease), visibility .22s;
  pointer-events: none;
}
.nav-item.is-open > .mega { opacity: 1; visibility: visible; transform: none; pointer-events: auto; }

.mega-inner { max-width: 1180px; margin-inline: auto; padding: 40px 32px 36px; display: grid; gap: 32px; }
.mega-inner.cols-4 { grid-template-columns: repeat(4, 1fr); }

.mega-head { font-size: 16px; font-weight: 700; letter-spacing: normal; text-transform: uppercase; color: #505051; line-height: 1.6; margin-bottom: 18px; }
.mega-links li + li { margin-top: 13px; }
.mega-links a { font-size: 16px; font-weight: 300; color: #323232; transition: color .18s var(--ease); }
.mega-links a:hover { color: var(--c-blue); }
.mega-links-lg a { font-size: 17px; }
.mega-links.two-up { columns: 2; column-gap: 28px; }
.mega-links.two-up li { break-inside: avoid; }
.mega-links-cols li + li { margin-top: 13px; }
.mega-links-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0,1fr));
    column-gap: 40px;
    row-gap: 16px;
}

    .mega-links-grid a {
        display: block;
        font-size: 16px;
        font-weight: 300;
        color: #323232;
        line-height: 1.5;
        transition: color .18s var(--ease);
    }

        .mega-links-grid a:hover {
            color: var(--c-blue);
        }

/* feature image layout (Industries / Company) */
.mega-feature-layout { grid-template-columns: 1.1fr 1.4fr; align-items: stretch; }
.mega-feature {
  position: relative; min-height: 280px; border-radius: 14px; overflow: hidden;
  background: var(--feat) center/cover no-repeat, var(--c-dark);
  display: flex; align-items: flex-end; padding: 24px;
}
.mega-feature::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(11,10,40,.15), rgba(11,10,40,.78)); }
.mega-feature-label { position: relative; color: #fff; font-size: 18px; font-weight: 600; max-width: 16ch; }

/* ============================================================
   HERO
   ============================================================ */
/* The site header is position:fixed and transparent, so it sits ON TOP of the
   hero. Centring in the full 100vh therefore centres behind the header and
   reads ~half a header too high — padding-top reserves that band so the flex
   centring happens in the area the user can actually see (box-sizing is
   border-box, so this stays inside the min-height rather than adding to it).
   100dvh tracks the *visible* viewport on mobile, where 100vh resolves to the
   larger URL-bar-hidden height and pushes the content down off-centre. */
.hero {
  position: relative;
  min-height: 640px;
  min-height: 100vh;   /* fallback: browsers without dvh support */
  min-height: 100dvh;
  padding-top: var(--header-h);
  display: flex; align-items: center; overflow: hidden;
}
.hero-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.hero-overlay {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(95deg, rgba(8,8,26,.78) 0%, rgba(8,8,26,.45) 42%, rgba(8,8,26,.15) 72%, rgba(8,8,26,.05) 100%),
    linear-gradient(180deg, rgba(8,8,26,.12), rgba(8,8,26,.30));
}
.hero-content { position: relative; z-index: 2; padding-block: 60px; text-align: center; }
.hero-title {
    color: #fff;
    font-weight: 700;
    letter-spacing: -.02em;
    font-size: clamp(32px, 4.2vw, 56px);
    line-height: 1.12;
    max-width: 28ch;
    margin-inline: auto;
    text-shadow: 0 2px 30px rgba(0,0,0,.25);
}
.hero-pills { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 38px; max-width: 720px; }
.pill {
  display: inline-flex; align-items: center; gap: 14px;
  padding: 11px 12px 11px 22px; border-radius: 999px;
  background: rgba(255,255,255,.10); border: 1px solid rgba(255,255,255,.45);
  color: #fff; font-size: 15px; font-weight: 500; -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  transition: background .2s var(--ease), border-color .2s var(--ease), transform .2s var(--ease);
}
.pill:hover { background: rgba(255,255,255,.20); transform: translateY(-2px); }
.pill-arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 999px; border: 1px solid rgba(255,255,255,.6);
}
.pill-arrow svg { width: 15px; height: 15px; }
.pill:hover .pill-arrow { background: #fff; color: var(--c-ink); border-color: #fff; }

/* temp placeholder note */
.section { padding-block: 80px; }
.placeholder-note p { color: var(--c-muted); font-size: 15px; border: 1px dashed var(--c-line); border-radius: 8px; padding: 22px; text-align: center; }

/* ============================================================
   MOBILE NAV TOGGLE (hidden on desktop)
   ============================================================ */
.nav-toggle { display: none; width: 42px; height: 42px; flex-direction: column; justify-content: center; gap: 5px; margin-left: auto; }
.nav-toggle span { display: block; height: 2px; width: 24px; margin-inline: auto; background: var(--c-ink); border-radius: 2px; transition: transform .25s var(--ease), opacity .2s var(--ease); }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1080px) {
  .header-inner { gap: 16px; }
  .nav-link { padding: 10px 10px; }
  .header-cta { display: none; }
}

@media (max-width: 940px) {
  .nav-toggle { display: flex; }
  .brand { flex: 0 0 auto; }
  .nav {
    position: fixed; inset: var(--header-h) 0 0 0; margin: 0; background: #fff;
    transform: translateX(100%); transition: transform .3s var(--ease);
    overflow-y: auto; padding: 16px 0 60px;
  }
  body.menu-open .nav { transform: none; }
  body.menu-open { overflow: hidden; }
  .nav-list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav-item { border-bottom: 1px solid var(--c-line); }
  .nav-link { width: 100%; justify-content: space-between; padding: 18px 32px; font-size: 17px; }
  .nav-link::after { display: none; }

  /* mega menus become inline accordions */
  .mega {
    position: static; opacity: 1; visibility: visible; transform: none; pointer-events: auto;
    box-shadow: none; border-top: none; background: var(--c-surface-2);
    display: none;
  }
  .nav-item.is-open > .mega { display: block; }
  .mega-inner { padding: 20px 32px 28px; gap: 22px; }
  .mega-inner.cols-4, .mega-inner.cols-3, .mega-feature-layout { grid-template-columns: 1fr; }
  .mega-feature { display: none; }
  .mega-links.two-up { columns: 1; }

  /* hamburger → X when menu is open */
  body.menu-open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  body.menu-open .nav-toggle span:nth-child(2) { opacity: 0; }
  body.menu-open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  /* Contact Us CTA: full-width pill pinned to the bottom of the open mobile menu */
  body.menu-open .header-cta {
    display: inline-flex;
    position: fixed;
    left: 24px; right: 24px; bottom: 28px;
    z-index: 10;
    width: auto; height: 54px;
    font-size: 16px;
    box-shadow: 0 12px 30px rgba(12, 10, 40, .18);
  }
}

@media (max-width: 600px) {
  .container, .header-inner { padding-inline: 20px; }
  .hero-pills { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
  .pill { justify-content: space-between; gap: 8px; min-width: 0; padding: 10px 12px 10px 16px; font-size: 14px; white-space: nowrap; }
}

/* ============================================================
   OUR SERVICES (tabbed explorer)
   ============================================================ */
.services { padding-block: 44px 48px; background: #fff; }
.services-grid { display: grid; grid-template-columns: 360px 1fr; gap: 56px; align-items: start; }
.services-panels { margin-top: calc(1 * clamp(26px, 2.6vw, 34px) + 18px); }

.services-title {
    font-size: clamp(38px, 5vw, 64px);
    font-weight: 700;
    line-height: .98;
    letter-spacing: -.025em;
    color: var(--c-ink);
   /* margin-bottom: 30px;*/
    margin-top: -20px; /* Upar le jane ke liye */

}
/* this heading wraps to 2-3 lines at nearly every screen size (mobile through
   desktop) — the shared .98 line-height above is tuned for single-line display
   type and crams wrapped lines together, so give this instance its own looser
   spacing everywhere instead of just one breakpoint */
#transformation-areas .services-title { line-height: 1.4; }
/* inside the tabbed explorer's narrow column, keep the heading to one line */
.services-aside .services-title {
    font-size: clamp(32px, 3.2vw, 44px);
    line-height: 1.15;
    margin-bottom: 18px;
    white-space: nowrap;
    text-align: left;
}

.services-tabs { display: flex; flex-direction: column; border-top: 1px solid var(--c-line); }
.svc-tab {
  position: relative; width: 100%; text-align: left;
  padding: 13px 2px; font-size: 18px; font-weight: 600; color: var(--c-ink);
  border-bottom: 1px solid var(--c-line); transition: color .2s var(--ease);
}
.svc-tab::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 3px;
  background: var(--c-grad); transform: scaleX(0); transform-origin: left;
  transition: transform .3s var(--ease);
}
.svc-tab:hover { color: var(--c-blue); }
.svc-tab.is-active { color: var(--c-ink); }
.svc-tab.is-active::after { transform: scaleX(1); }

/* panels */
.svc-panel[hidden] { display: none; }
.svc-panel.is-active { animation: svcFade .4s var(--ease); }
@keyframes svcFade { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.svc-panel-title { font-size: 28px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 12px; }
.svc-panel-intro { font-size: 17px; color: var(--c-body); max-width: 700px; line-height: 1.62; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 8px; margin-top: 14px;
  color: var(--c-accent); font-weight: 700; font-size: 20px; line-height: 1.2;
}
.link-arrow svg { width: 18px; height: 16px; transition: transform .2s var(--ease); }
.link-arrow:hover svg { transform: translateX(4px); }

.svc-cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; margin-top: 34px; }
.svc-card {
  position: relative; display: flex; flex-direction: column;
  border: 1px solid #c4c4c4; border-radius: var(--radius);
  padding: 31px; min-height: 182px; color: var(--c-ink);
  transition: border-color .22s var(--ease), box-shadow .22s var(--ease), transform .22s var(--ease);
}
.svc-card h4 { font-size: 20px; font-weight: 700; line-height: 1.4; margin-bottom: 10px; }
.svc-card p { font-size: 16px; font-weight: 300; color: #323232; line-height: 1.6; flex: 1; }
.card-arrow {
  align-self: flex-end; margin-top: 18px; color: var(--c-accent);
  display: flex; align-items: center; justify-content: center;
  width: 60px; height: 60px; border: 1px solid #c4c4c4; border-radius: var(--radius); flex-shrink: 0;
}
.card-arrow svg { width: 26px; height: 24px; transition: transform .22s var(--ease); }
.svc-card:hover { border-color: var(--c-accent); box-shadow: 0 14px 30px rgba(20,20,40,.08); transform: translateY(-2px); }
.svc-card:hover .card-arrow { border-color: var(--c-accent); }
/* solutions.html uses a blue theme instead of the sitewide accent */
#sap-solutions .card-arrow { color: var(--c-blue); }
#sap-solutions .svc-card:hover { border-color: var(--c-blue); }
#sap-solutions .svc-card:hover .card-arrow { border-color: var(--c-blue); }
/* match the grey used for index.html section headings (.services-title, .why-glance-title) */
.pg-service-detail .svc-dir-head h2 { color: #52525c; }
/* the services/ detail pages run their section headings in the sitewide
   near-black instead. Same specificity as the grey above, so it has to stay
   below it. */
.pg-consulting .svc-dir-head h2,
.pg-implementation .svc-dir-head h2,
.pg-migration .svc-dir-head h2,
.pg-integration .svc-dir-head h2,
.pg-ams .svc-dir-head h2,
.pg-support .svc-dir-head h2,
.pg-training .svc-dir-head h2,
.pg-analytics .svc-dir-head h2 { color: var(--c-ink); }

/* Case studies/Insights bento — the 4 plain-color insight tiles were 300px
   tall boxes holding a single bottom-aligned heading (mostly empty space);
   tightened rows/padding and matched s4hana.html's eyebrow-tag convention */
/* (service-detail bento size overrides retired 2026-08-05 — the band is
   the home bento verbatim on every page now) */
.svc-card:hover .card-arrow svg { transform: translateX(4px); }

/* Homepage svc-cards (Featured Transformation Areas, Our SAP services, Why VISCAP):
   pin the arrow to the bottom-right corner instead of letting the paragraph
   stretch and push it down with a big gap */
#transformation-areas .svc-card, #services .svc-card, #why-viscap .svc-card,
#sap-solutions .svc-card { padding-bottom: 68px; }
#transformation-areas .svc-card p, #services .svc-card p, #why-viscap .svc-card p,
#sap-solutions .svc-card p { flex: none; }
#transformation-areas .card-arrow, #services .card-arrow, #why-viscap .card-arrow,
#sap-solutions .card-arrow {
  position: absolute; right: 0; bottom: 0; margin-top: 0;
  /* The arrow is absolutely positioned against the card's padding box, so it sits
     1px inside the card's border: the card's inner curve is (--radius - 1px), and
     the arrow's bottom-right has to match that or a hairline of card shows through
     at the corner. A no-op at 4px, but it reads once the radius opens up. */
  border-radius: var(--radius) 0 calc(var(--radius) - 1px) 0;
}

/* ---------- Home page: softer 14px corners on the card/tile blocks ----------
   Matches the 14px already used by the .fam-* cards on the services detail pages
   and the .ind-tile industry tiles, so the home page reads as part of the same set.

   SITEWIDE since 2026-08-05 (owner: uniformity): 14px is the card radius on
   every page — all card/media blocks in this file and the family sheets carry
   it directly now, and the case-study quilt rounds as one block.

   Deliberately NOT rounded, so the intent is on the record:
     .svc-tab        list rows separated by border rules, not boxes.
     .g-num          gradient display text (background-clip: text), not a block.
     form inputs     left on the sitewide 4px; changing those is a call about the
                     form as a whole, not about these blocks.
     icon squares    (.scope-ic and kin) and small chips keep their small radii —
                     they are controls and badges, not cards. */
.svc-card { --radius: 14px; }  /* token, so the nested .card-arrow follows */

/* compact horizontal row list — used where cards are title-only (no body copy) */
.svc-cards--rows { display: flex; flex-direction: column; gap: 0; }
.svc-cards--rows .svc-card {
  flex-direction: row; align-items: center; justify-content: space-between;
  min-height: auto; padding: 24px 4px; border: none; border-radius: 0;
  border-bottom: 1px solid var(--c-line); transform: none;
}
.svc-cards--rows .svc-card:first-child { border-top: 1px solid var(--c-line); }
.svc-cards--rows .svc-card h4 { margin-bottom: 0; }
.svc-cards--rows .svc-card .card-arrow { margin-top: 0; width: 48px; height: 48px; }
.svc-cards--rows .svc-card .card-arrow svg { width: 22px; height: 20px; }
.svc-cards--rows .svc-card:hover { box-shadow: none; transform: none; border-bottom-color: var(--c-accent); }
@media (max-width: 560px) {
  .svc-cards--rows .svc-card { padding: 18px 2px; gap: 12px; }
  .svc-cards--rows .svc-card h4 { font-size: 17px; }
}

/* media card (full-width, image + text) */
.svc-card--media { grid-column: 1 / -1; flex-direction: row; padding: 0; overflow: hidden; }
.svc-card-media { flex: 0 0 290px; background: var(--img) center/cover no-repeat, #d9d9e2; min-height: 210px; }
.svc-card-body { display: flex; flex-direction: column; padding: 26px 26px 22px; flex: 1; }
.svc-card-body h4 { font-size: 20px; font-weight: 700; line-height: 1.4; margin-bottom: 10px; }
.svc-card-body p { font-size: 16px; font-weight: 300; color: #323232; line-height: 1.6; flex: 1; }

@media (max-width: 940px) {
  .services { padding-block: 64px 72px; }
  .services-grid { grid-template-columns: 1fr; gap: 28px; }
  .services-title { margin-bottom: 8px; }
  .services-panels { margin-top: 0; }
  .svc-cards { grid-template-columns: 1fr; }
  .svc-card--media { flex-direction: column; }
  .svc-card-media { flex-basis: 200px; width: 100%; }

  /* tab list becomes a horizontal, swipeable strip instead of a stacked list —
     the next tab peeking in at the edge signals that it scrolls.
     min-width: 0 stops the grid/flex ancestors from stretching to fit the
     unwrapped tab row instead of letting it scroll within its own box. */
  .services-grid { min-width: 0; }
  .services-aside { min-width: 0; }
  .services-tabs {
    flex-direction: row;
    border-top: none;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    gap: 28px;
    scrollbar-width: none;
    padding-bottom: 2px;
    min-width: 0;
  }
  .services-tabs::-webkit-scrollbar { display: none; }
  .svc-tab {
    flex: 0 0 auto;
    width: auto;
    white-space: nowrap;
    border-bottom: none;
    padding: 8px 2px 14px;
  }
}

/* ============================================================
   800+ CLIENTS SERVED (dark)
   ============================================================ */
.clients {
  padding-block: 44px 48px; color: #fff;
  background: linear-gradient(108deg, #1b0f40 0%, #0d0a2c 52%, #0b0a26 100%);
}
.clients-grid { display: grid; grid-template-columns: 0.95fr 1.05fr; gap: 64px; align-items: center; }

.clients-logos { display: grid; grid-template-columns: repeat(4, 1fr); gap: 30px 18px; }
.client-logo {
  display: flex; align-items: center; justify-content: center; text-align: center;
  min-height: 40px; font-size: 18px; font-weight: 700; letter-spacing: -.01em;
  color: rgba(216, 210, 246, .42); transition: color .2s var(--ease);
  -webkit-user-select: none; user-select: none;
}
.client-logo:hover { color: rgba(230, 226, 252, .9); }

.clients-title {
  font-size: clamp(40px, 5vw, 66px); font-weight: 700; line-height: 1.0;
  letter-spacing: -.02em; color: #dad5f8; margin-bottom: 42px;
}
.client-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 40px 48px; }
.client-stat { display: flex; flex-direction: column; }
.stat-num { font-size: 34px; font-weight: 700; line-height: 1; margin-bottom: 8px; color: #fff; }
.stat-sub { font-size: 17px; font-weight: 600; line-height: 1.3; margin-bottom: 12px; color: #fff; }
.client-stat p { font-size: 14px; color: rgba(255, 255, 255, .62); line-height: 1.55; flex: 1; }
.stat-link { display: flex; align-items: center; margin-top: 20px; color: var(--c-accent); }
.stat-link span { flex: 1; height: 1px; background: rgba(255, 255, 255, .22); margin-right: 14px; transition: background .2s var(--ease); }
.stat-link svg { width: 22px; height: 22px; transition: transform .2s var(--ease); }
.stat-link:hover svg { transform: translateX(4px); }
.stat-link:hover span { background: rgba(255, 255, 255, .45); }

@media (max-width: 940px) {
  .clients { padding-block: 60px 68px; }
  .clients-grid { grid-template-columns: 1fr; gap: 44px; }
  .client-stats { gap: 32px; }
}
@media (max-width: 560px) {
  .clients-logos { grid-template-columns: repeat(3, 1fr); gap: 24px 12px; }
  .client-stats { grid-template-columns: 1fr; }
}

/* ============================================================
   INDUSTRIES — expanding-panel slider (hover-swaps bg photo)
   ============================================================ */
.ind { position: relative; min-height: 620px; overflow: hidden; background: var(--c-dark); }
.ind-bg {
  position: absolute; inset: 0; background: var(--img) center/cover no-repeat;
  opacity: 0; transform: scale(1.05); transition: opacity .8s var(--ease), transform 7s linear;
}
.ind-bg.is-active { opacity: 1; transform: scale(1); }
.ind-bg[data-ind="pharma"] { background-position: 22% 35%; }
.ind-overlay {
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(180deg, rgba(8,8,26,.55) 0%, rgba(8,8,26,.30) 38%, rgba(8,8,26,.78) 100%);
}
.ind-inner { position: relative; z-index: 2; min-height: 620px; display: flex; flex-direction: column; }
.ind-head { padding: 50px 0 6px 35px; }
.ind-title { color: #fff; font-size: clamp(44px, 6.6vw, 88px); font-weight: 700; letter-spacing: -.025em; line-height: 1; }
.ind-panels { flex: 1; display: flex; align-items: stretch; }
@media (min-width: 941px) {
  /* let the divider lines/panels span the section's full height (from the
     very top edge) instead of starting below the heading — the heading
     floats on top of the panels row instead of pushing it down */
  .ind-head { position: absolute; top: 0; left: 0; z-index: 3; }
  .ind-panels { position: absolute; inset: 0; }
}
.ind-panel {
  position: relative; flex: 1 1 0%; text-align: left; color: #fff;
  display: flex; flex-direction: column; justify-content: flex-end; padding: 36px 24px 44px 28px;
  border-left: 1px solid rgba(255,255,255,.35); cursor: pointer;
  transition: flex-grow .55s var(--ease), background .4s var(--ease), border-color .4s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.ind-panel:first-child { border-left: none; }
.ind-panel:hover { background: rgba(255,255,255,.04); }
.ind-panel.is-active { flex-grow: 2.7; }
.ind-panel.is-active, .ind-panel.is-active + .ind-panel { border-left-color: rgba(255,255,255,.75); }
/* darker scrim on whichever panel is currently active, so it's clearly
   distinguished from its neighbors — "I am on this one" */
.ind-panel::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: rgba(0,0,0,0); transition: background .4s var(--ease); pointer-events: none;
}
.ind-panel.is-active::before { background: rgba(0,0,0,.28); }
.ind-name { position: relative; z-index: 1; }
.ind-detail { position: relative; z-index: 1; }
.ind-name {
    font-size: clamp(19px, 1.5vw, 26px);
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1.2;
    /* Add these */
    word-break: normal;
    overflow-wrap: normal;
    white-space: normal;
    hyphens: none;
}
/* nav arrows — hidden on mobile (swipe + autoplay already handle navigation there) */
.ind-nav {
  display: none; position: absolute; top: 50%; z-index: 4;
  width: 44px; height: 44px; border-radius: 50%; transform: translateY(-50%);
  align-items: center; justify-content: center; color: #fff;
  background: rgba(8,8,26,.35); border: 1px solid rgba(255,255,255,.5);
  cursor: pointer; transition: background .2s var(--ease), border-color .2s var(--ease);
}
.ind-nav:hover { background: rgba(8,8,26,.65); border-color: #fff; }
.ind-nav:disabled { opacity: .3; cursor: default; pointer-events: none; }
.ind-nav svg { width: 20px; height: 20px; }
.ind-nav--prev { left: 20px; }
.ind-nav--next { right: 20px; }
@media (min-width: 941px) {
  /* show only 3 of the 6 industries at once, arrow-navigated, instead of
     cramming all 6 into view — equal-width columns (no grow-on-hover) so the
     sliding math stays exact regardless of which panel is active */
  /* the arrows page a whole set of 3, so the strip travels half its width in
     one go — it has to slide, not snap. .55s matches the panel scrim and the
     detail text so the whole swap lands together (mobile has its own .45s
     further down, sized for a single-card step) */
  .ind-panels { width: 200%; transition: transform .55s var(--ease); }
  .ind-panel { flex: 0 0 16.6667%; }
  .ind-panel.is-active { flex-grow: 0; }
  .ind-nav { display: flex; }
}
@media (prefers-reduced-motion: reduce) {
  /* two-class selector so this beats the mobile .45s rule further down the
     file regardless of source order */
  .ind .ind-panels { transition: none; }
}
.ind-detail {
  max-height: 0; opacity: 0; overflow: hidden; transform: translateY(22px);
  transition: max-height .55s var(--ease), opacity .4s var(--ease), margin-top .55s var(--ease), transform .5s var(--ease);
}
.ind-panel.is-active .ind-detail { max-height: 240px; opacity: 1; margin-top: 16px; transform: translateY(0); }
.ind-detail p { font-size: 15px; line-height: 1.6; color: rgba(255,255,255,.84); max-width: 44ch; }
.ind-detail .link-arrow { margin-top: 14px; }

/* ============================================================
   WHY VISCAP — 4-column stat grid
   ============================================================ */
.why-glance { background: var(--c-surface-2); padding-block: 64px; }
.why-glance-title { text-align: center; font-size: clamp(34px, 4vw, 52px); font-weight: 800; letter-spacing: -.02em; color: var(--c-ink); margin-bottom: 44px; }
.why-glance-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; }
/* the columns are equal-height grid tracks, but each dark stat card was sized
   by its own content — the "UAE, USA, UK, and India presence" label wraps to a
   second line, which pushed that card (and its accent border) lower than the
   other three. Let the card absorb whatever height is left in its column so
   all four bottom out on the same line. */
.why-glance-col { display: flex; flex-direction: column; }
.why-glance-copy { font-size: 16px; line-height: 1.55; color: var(--c-ink); margin-bottom: 24px; }
.why-glance-stat { flex: 1; background: var(--c-dark); border-radius: 14px; padding: 26px 22px 20px; border-bottom: 3px solid var(--c-accent); }
.why-glance-num { font-size: clamp(30px, 2.6vw, 40px); font-weight: 800; letter-spacing: -.02em; line-height: 1; color: #fff; }
.why-glance-label { margin-top: 10px; font-size: 15px; line-height: 1.4; color: rgba(255,255,255,.72); }
@media (max-width: 940px) {
  .why-glance-grid { grid-template-columns: repeat(2, 1fr); gap: 24px; }
}
@media (max-width: 560px) {
  .why-glance { padding-block: 48px; }
  .why-glance-grid { grid-template-columns: 1fr; gap: 22px; }
}

/* ============================================================
   ITRANSITION AT A GLANCE (dark stat band)
   ============================================================ */
.glance { background: linear-gradient(108deg, #1b0f40 0%, #0d0a2c 52%, #0b0a26 100%); color: #fff; padding-block: 44px; }
.glance-head { max-width: 760px; margin-bottom: 50px; }
.glance-head h2 { font-size: clamp(38px, 5vw, 66px); font-weight: 700; letter-spacing: -.02em; line-height: 1.02; }
.glance-head p { margin-top: 18px; font-size: 18px; line-height: 1.6; color: rgba(255,255,255,.72); }
/* centre, not start: the media column is taller than the stats block, so
   top-aligning left it hanging well below the last stat. Centring balances the
   overhang above and below. In the stacked layout (<=940px) the grid is a
   single column, so this has no effect there. */
.glance-grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: 60px; align-items: center; }
.glance-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 44px 48px; }
.g-num { font-size: clamp(44px, 5vw, 70px); font-weight: 700; line-height: 1; letter-spacing: -.02em;
  background: var(--c-grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.g-label { margin-top: 10px; font-size: 16px; line-height: 1.4; color: rgba(255,255,255,.74); }
.glance-media { border-radius: 14px; overflow: hidden; min-height: 380px; background: var(--img) center/cover no-repeat, #1b1146; box-shadow: 0 30px 60px rgba(0,0,0,.35); }
/* nudge the media 20px right of its grid column. position/left rather than
   transform (the element also carries .reveal, whose entrance animation owns
   `transform`) or margin (which would shrink the box instead of moving it).
   Side-by-side layout only — below 941px the section stacks and the image goes
   full-width, where a shift would just push it against the screen edge. */
@media (min-width: 941px) {
  .glance-media { position: relative; left: 40px; bottom: 15px; }
}

/* ============================================================
   FEATURED — Insights + Case studies mosaic (edge-to-edge bento)
   ============================================================ */
/* clip horizontal overflow — the reveal-left/right tiles sit offset ±70px
   before they scroll into view, which can push them past the section edge */
.featured { background: #fff; overflow-x: hidden; }
/* (the .featured-grid / .feat-tile bento library that lived here was retired
   2026-08-05 — every insights/case-studies band, home included, is now the
   case-studies quilt: .cs-mosaic--band. The .featured section wrapper stays;
   it still provides the white backdrop and overflow clipping.) */

/* ============================================================
   CONTACT (home form)
   ============================================================ */
.contact-grid {
    display: grid;
    grid-template-columns: 0.40fr 0.60fr;
    gap: 32px;
    align-items: center; /* vertically balance the short aside against the taller form card */
}
.contact-aside h2 { font-size: clamp(34px, 4vw, 52px); font-weight: 700; letter-spacing: -.02em; line-height: 1.05; }
.contact-aside {
    padding-top: 20px; /* adjust 10-40px if needed */
    margin-top: -40px; /* nudge up from the vertically-centered position */
}
.contact-aside p { margin-top: 18px; font-size: 17px; line-height: 1.6; color: var(--c-body); max-width: 42ch; }

/* The aside was vertically centered against the taller form card, leaving
   "Contact Us" floating well below where the card actually starts — top-align
   it instead so the heading sits near the card's top edge.

   .contact-section is the opt-in for pages carrying no .pg-service-detail:
   index.html has no body class at all and services.html only .pg-services.
   Adding pg-service-detail to those two would have done this in one word, but
   it also brings its FAQ frames, bento-tile sizing and hero padding with it —
   none of which belongs on the homepage. */
.pg-service-detail .contact-grid,
.contact-section .contact-grid { align-items: start; }
.pg-service-detail .contact-aside,
.contact-section .contact-aside { margin-top: 0; padding-top: 6px; }

.ccard-head { display: flex; align-items: center; gap: 12px; margin-bottom: 24px; }
.ccard-icon { width: 40px; height: 40px; border-radius: 999px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; background: var(--c-blue); color: #fff; }
.ccard-icon svg { width: 19px; height: 19px; }
.ccard-eyebrow { font-size: 13px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--c-muted); }

/* premium card wrapper around the homepage contact form.
   This was previously two rules with the same selector — the second won on
   padding/shadow/border, and the only declaration surviving from the first was
   a transform: translateX(-20px). That offset was dead on arrival: .reveal.is-in
   (0,2,0) outranks .contact-card (0,1,0) and resets the transform to none the
   moment the card scrolls in. The :hover rule carried the -20px forward anyway,
   so hovering yanked the card 20px sideways out of alignment. Merged into one
   rule, with the phantom offset gone. */
.contact-card {
  position: relative;   /* anchors the ::before edge sweep */
  overflow: hidden;     /* clips that sweep to the 22px corner radius */
  background: #fff;
  border: 1px solid #e8e8ef;
  border-radius: 14px;
  padding: 38px;
  max-width: 820px;
  margin-left: auto;
  box-shadow: 0 18px 45px rgba(0,0,0,.08);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
}
/* the sitewide blue→violet ramp wipes left-to-right across the top edge on
   hover — same gradient .numlist--accent uses, so it reads as house style */
.contact-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--c-grad);
  transform: scaleX(0); transform-origin: left;
  transition: transform .5s var(--ease);
}
.contact-card:hover::before { transform: scaleX(1); }
.contact-card:hover {
  transform: translateY(-6px);   /* lift only — no horizontal drift */
  border-color: var(--c-blue);
  box-shadow: 0 30px 70px rgba(var(--c-shadow-rgb), .16);
}
/* the lift and the sweep are decoration, not information */
@media (prefers-reduced-motion: reduce) {
  .contact-card, .contact-card::before { transition: none; }
  .contact-card:hover { transform: none; }
  .contact-card:hover::before { transform: scaleX(1); }
}
.cform { display: grid; gap: 12px; }
.cfield { display: flex; flex-direction: column; gap: 7px; }
.cfield label { font-size: 13px; font-weight: 600; color: var(--c-ink); }
.cfield input, .cfield textarea, .cfield select {
  font: inherit; font-size: 15px; color: var(--c-ink); background: #fff;
  border: 1px solid var(--c-line); border-radius: var(--radius); padding: 13px 14px; width: 100%;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
/* owner call 2026-08-05: no glow on the active field — a darkened neutral
   border is the only cue (outline stays suppressed or Chrome's own ring returns) */
.cfield input:focus, .cfield textarea:focus, .cfield select:focus { outline: none; border-color: var(--c-muted); box-shadow: none; }
.cfield textarea { min-height: 90px; resize: vertical; }
.cfield select { cursor: pointer; }
.cform-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.cform-note { font-size: 13px; color: var(--c-muted); line-height: 1.5; }
.cform-note a { color: var(--c-blue); font-weight: 600; }
.cf-agree { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; color: var(--c-body); line-height: 1.5; cursor: pointer; }
.cf-agree input[type="checkbox"] { margin-top: 2px; width: 16px; height: 16px; flex-shrink: 0; accent-color: var(--c-blue); cursor: pointer; }
.cf-agree a { color: var(--c-blue); font-weight: 600; }

/* ============================================================
   FOOTER ("Let's connect" — dark)
   ============================================================ */
.site-footer { background: #000; color: rgba(255,255,255,.86); padding-block: 56px 0; }

.footer-connect-title { font-size: clamp(36px, 4.4vw, 56px); font-weight: 300; letter-spacing: -.01em; color: #fff; margin-bottom: 36px; }

.footer-connect-grid {
    display: flex;
    align-items: flex-start;
    gap: 90px;
    margin-bottom: 24px;
}
.footer-connect-primary { display: flex; flex-direction: column; gap: 14px; flex: 0 0 auto; }
.footer-connect-primary a { font-size: 24px; font-weight: 400; color: rgba(255,255,255,.92); transition: color .2s var(--ease); }
.footer-connect-primary a:hover { color: var(--c-accent); }
.footer-connect-col { display: flex; flex-direction: column; flex: 0 0 auto; }
.footer-connect-secondary { display: flex; flex-direction: column; gap: 12px; flex: 0 0 auto; }
.footer-connect-secondary a { font-size: 16px; font-weight: 300; color: rgba(255,255,255,.66); transition: color .2s var(--ease); }
.footer-connect-secondary a:hover { color: #fff; }

.footer-col-label { display: block; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.4); margin-bottom: 16px; }

.footer-connect-social { display: flex; flex-direction: column; gap: 14px; margin-left: auto; }
.footer-contact-line { font-size: 15px; font-weight: 500; color: rgba(255,255,255,.85); transition: color .2s var(--ease); }
.footer-contact-line:hover { color: var(--c-accent); }
.footer-social { display: flex; gap: 12px; margin-top: 4px; }
.footer-social a {
  display: flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 50%;
  color: rgba(255,255,255,.92);
  transition: color .2s var(--ease);
}
.footer-social a:hover { color: var(--c-accent); }
.footer-social svg { width: 17px; height: 17px; }

/* brand + certification badges */
.footer-brand-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 20px; border-top: 1px solid rgba(255,255,255,.16); padding-block: 12px; }
.footer-brand-logo { height: 26px; width: auto; }
.footer-cert-badges { display: flex; align-items: center; gap: 26px; }
.footer-cert-badges img { height: 36px; width: auto; object-fit: contain; }

/* bottom bar */
.footer-bottom { padding-block: 10px 14px; display: flex; flex-wrap: wrap; align-items: center; gap: 14px 26px; }
.footer-bottom .copy { font-size: 13px; color: rgba(255,255,255,.5); margin-right: auto; }
.footer-policies { display: flex; flex-wrap: wrap; gap: 22px; }
.footer-policies a { font-size: 13px; color: rgba(255,255,255,.5); transition: color .2s var(--ease); }
.footer-policies a:hover { color: #fff; }

/* ============================================================
   RESPONSIVE — new home sections
   ============================================================ */
@media (max-width: 940px) {
  .ind { min-height: 440px; }
  .ind-inner { min-height: 440px; }
  /* heading floats on top of the panels row instead of pushing it down, so
     the divider lines/panels span the section's full height from the top —
     same treatment as desktop */
  .ind-head { position: absolute; top: 0; left: 0; z-index: 3; }
  /* auto-advancing, swipe-navigable carousel — every panel stays rendered
     side by side (slid into place via JS translateX) so the next one's
     name + divider peek in at the right edge as a "swipe for more" hint */
  .ind-panels { flex-direction: row; position: absolute; inset: 0; min-height: 440px; touch-action: pan-y; transition: transform .45s var(--ease); }
    .ind-panel, .ind-panel.is-active {
        display: flex;
        flex: 0 0 84%;
        width: 84%;
        border-left: 1px solid rgba(255,255,255,.35);
        padding: 28px 22px 34px;
    }
    .ind-panel:first-child { border-left: none; }

    .ind-name {
        font-size: clamp(24px, 7vw, 32px);
        word-break: keep-all;
    }
  .ind-panel .ind-detail { max-height: 0; }
  .ind-panel.is-active .ind-detail { max-height: 280px; }
  .glance { padding-block: 64px; }
  .glance-grid { grid-template-columns: 1fr; gap: 40px; }
  .glance-media { min-height: 260px; order: -1; }
  .contact-grid { grid-template-columns: 1fr; gap: 36px; }
  /* the card goes full-width once the grid stacks. The hover no longer needs
     overriding here — the desktop rule is a plain lift now, so both match. */
  .contact-card { margin-left: 0; max-width: none; }
  .footer-connect-grid { gap: 32px 40px; margin-bottom: 28px; }
  .footer-connect-title { margin-bottom: 28px; }
}
@media (max-width: 560px) {
  /* these headings' clamp() minimums were tuned for desktop/tablet and hit
     their floor on narrow phones, wrapping to 3-4 heavy lines — give phones
     their own smaller, still-responsive scale so 2 lines is the norm */
    .hero-content { padding-inline: 20px; }
    .hero-title {
        font-size: clamp(23px, 6vw, 30px);
        max-width: 22ch;
        margin-inline: auto;
    }
    .services-title {
        font-size: clamp(26px, 7.5vw, 34px);
    }
    #transformation-areas .services-title {
        margin-inline: -20px;
        width: calc(100% + 40px);
    }
  .glance-head h2 { font-size: clamp(26px, 7.5vw, 34px); }
  .glance-stats { grid-template-columns: 1fr 1fr; gap: 30px 20px; }
  .cform-row { grid-template-columns: 1fr; }
  .contact-card { padding: 26px; border-radius: 14px; }
  .site-footer { padding-top: 40px; }
  /* 2-column grid instead of one long stacked list of 12+ links —
     Primary + Company share row 1, Resources + Get in touch share row 2 */
  .footer-connect-grid { display: grid; grid-template-columns: 1fr 1fr; column-gap: 20px; row-gap: 30px; margin-bottom: 20px; }
  .footer-connect-primary, .footer-connect-col, .footer-connect-social { min-width: 0; }
  .footer-connect-primary a { font-size: 17px; }
  .footer-connect-primary { gap: 12px; }
  .footer-connect-secondary a { font-size: 14px; }
  .footer-connect-title { margin-bottom: 24px; }
  .footer-connect-social { margin-left: 0; }
  .footer-brand-row { flex-direction: column; align-items: flex-start; }
  .footer-bottom { flex-direction: column; align-items: flex-start; }
  .footer-bottom .copy { margin-right: 0; }
}

/* ============================================================
   SHARED — logo image + 2-col mega (used by VISCAP rebrand)
   ============================================================ */
.brand-logo { height: 50px; width: auto; display: block; }
/* partner / award badges: full-colour art shown on the header's own
   background (transparent PNGs — no white chip). The .brand-badge class also
   exempts them from the white-invert filter applied over the dark hero. */
.mega-inner.cols-2 { grid-template-columns: 1fr 1fr; max-width: 1080px; column-gap: 48px; }
.mega-inner.cols-2 .mega-col { border-right: 1px solid #c4c4c4; padding-right: 32px; }
.mega-inner.cols-2 .mega-col:last-child { border-right: none; padding-right: 0; }
.mega-head a { color: inherit; }
.mega-head a:hover { color: var(--c-blue); }
/* Services | Solutions | Technologies — three ruled groups in one panel.
   The tracks are not equal thirds: Solutions runs two link columns while the
   other two run one each, so the middle track carries the extra width. */
.mega-inner.cols-3 { grid-template-columns: 1fr 1.5fr .95fr; max-width: 1240px; column-gap: 0; }
.mega-inner.cols-3 .mega-col { border-right: 1px solid #c4c4c4; padding-right: 44px; }
.mega-inner.cols-3 .mega-col + .mega-col { padding-left: 44px; }
.mega-inner.cols-3 .mega-col:last-child { border-right: none; padding-right: 0; }

/* single-column link list (Services, Technologies) */
.mega-links-grid.one-up { grid-template-columns: 1fr; }

/* Two link columns that read DOWN then across. .mega-links-grid is a CSS grid,
   so it reads across then down and any two-line title leaves a hole beside it
   — the row sizes to the taller cell. Multi-column flows vertically instead. */
.mega-links-flow { columns: 2; column-gap: 40px; }
.mega-links-flow a {
  display: block; break-inside: avoid; margin-bottom: 16px;
  font-size: 16px; font-weight: 300; color: #323232; line-height: 1.5;
  transition: color .18s var(--ease);
}
.mega-links-flow a:last-child { margin-bottom: 0; }
.mega-links-flow a:hover { color: var(--c-blue); }

@media (max-width: 1180px) {
  .mega-inner.cols-3 .mega-col { padding-right: 30px; }
  .mega-inner.cols-3 .mega-col + .mega-col { padding-left: 30px; }
}
@media (max-width: 940px) {
  .mega-inner.cols-2 { grid-template-columns: 1fr; max-width: none; }
  .mega-inner.cols-2 .mega-col { border-right: none; padding-right: 0; }
  .mega-inner.cols-3 { grid-template-columns: 1fr; max-width: none; }
  .mega-inner.cols-3 .mega-col { border-right: none; padding-right: 0; }
  .mega-inner.cols-3 .mega-col + .mega-col {
    padding-left: 0; padding-top: 20px; border-top: 1px solid #ededf0;
  }
  .mega-links-flow { columns: 1; }
  .mega-links-cols { columns: 1; }
}

/* ============================================================
   ============================================================
   INTERIOR PAGE COMPONENTS (services / detail / industries / etc.)
   Modeled on itransition's interior pages. Reused by both the
   replica interior pages and the VISCAP interior pages.
   ============================================================
   ============================================================ */

/* ---------- Full-bleed photo page hero ---------- */
.phero { position: relative; min-height: 420px; display: flex; align-items: center; overflow: hidden; color: #fff; }
.phero-bg { position: absolute; inset: 0; background: var(--img) center/cover no-repeat, var(--c-dark); z-index: 0; }
.phero::after { content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, rgba(8,8,26,.82) 0%, rgba(8,8,26,.62) 45%, rgba(8,8,26,.42) 100%), linear-gradient(180deg, rgba(8,8,26,.2), rgba(8,8,26,.5)); }
.phero .container { position: relative; z-index: 2; padding-block: 70px; }
.phero h1 { font-size: clamp(36px, 5vw, 64px); font-weight: 700; letter-spacing: -.025em; line-height: 1.04; max-width: 20ch; }
.phero .lead { margin-top: 18px; font-size: clamp(17px, 1.6vw, 20px); line-height: 1.55; color: rgba(255,255,255,.82); max-width: 56ch; }
.phero-pills { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }

/* breadcrumb strip (under hero) */
.crumb-strip { background: #fff; border-bottom: 1px solid var(--c-line); }
.crumb-strip .container { display: flex; align-items: center; padding-block: 13px; }
.breadcrumb { display: flex; flex-wrap: wrap; gap: 8px; font-size: 13px; color: var(--c-muted); }
.breadcrumb a { color: var(--c-muted); }
.breadcrumb a:hover { color: var(--c-blue); }
.breadcrumb .sep { opacity: .5; }
.breadcrumb .cur { color: var(--c-ink); font-weight: 600; }

/* ---------- Anchor sub-nav (sticky) ---------- */
.anchor-nav { background: #fff; border-bottom: 1px solid var(--c-line); position: sticky; top: var(--header-h); z-index: 40; }
.anchor-nav .container { display: flex; flex-wrap: wrap; gap: 6px; padding-block: 9px; }
.anchor-nav a { padding: 9px 16px; border-radius: 999px; font-size: 16px; font-weight: 700; color: var(--c-body); transition: background .2s var(--ease), color .2s var(--ease); }
.anchor-nav a:hover { background: var(--c-surface-2); color: var(--c-blue); }
[id] { scroll-margin-top: 130px; }

/* ---------- Generic section + heading ---------- */
.psection {
    padding: 40px 0 90px;
    background: #fff;
}
.psection--alt { background: var(--c-surface-2); }
.psection--dark { color: #fff; background: linear-gradient(108deg, #1b0f40 0%, #0d0a2c 52%, #0b0a26 100%); }
.psection--tight { padding-block: 64px; }
.psection--tightbottom { padding-bottom: 44px; }
.psection--tighttop { padding-top: 18px; }
/* two classes so this reliably beats the equal-specificity ".svc-dir-head h2"
   base rule (and its ≤900px override) at every width below the 1240px
   freeze — previously lost that tie by source order and rendered at the
   much larger base size on tablet/mobile instead of this "sm" size */
.svc-dir-head.svc-dir-head--sm h2 { font-size: clamp(24px, 2.6vw, 34px); }
.shead { max-width: 760px; margin-bottom: 46px; }
.shead.center { margin-inline: auto; text-align: center; }
.eyebrow { display: inline-block; font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--c-blue); margin-bottom: 14px; }
.psection--dark .eyebrow { color: #b9a6ff; }
.stitle { font-size: clamp(32px, 4.6vw, 64px); font-weight: 900; line-height: .95; letter-spacing: -.02em; color: #737373; }
.psection--dark .stitle { color: #fff; }
.slead { font-size: 18px; font-weight: 300; line-height: 1.6; color: #323232; margin-top: 18px; }
.psection--dark .slead { color: rgba(255,255,255,.72); }
.prose p { font-size: 16px; font-weight: 300; line-height: 1.7; color: #323232; }
.prose p + p { margin-top: 16px; }

/* ---------- Key directions (3-col, gradient top border) ---------- */
.kgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 40px; }
.kcol { padding-top: 22px; border-top: 3px solid transparent; border-image: var(--c-grad) 1; }
.kcol h3 { font-size: 22px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 12px; }
.kcol p { font-size: 15px; line-height: 1.6; color: var(--c-body); }
.kcol .link-arrow { margin-top: 14px; }
.kcol ul { margin-top: 14px; display: grid; gap: 9px; }
.kcol ul li { position: relative; padding-left: 18px; font-size: 14.5px; color: var(--c-body); line-height: 1.5; }
.kcol ul li::before { content: ""; position: absolute; left: 0; top: 8px; width: 7px; height: 7px; border-radius: 2px; background: var(--c-grad); }

/* ---------- Split (alternating image / text) ---------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
.split + .split { margin-top: 80px; }
.split--reverse .split-media { order: 2; }
.split-media { border-radius: 14px; overflow: hidden; min-height: 320px; background: var(--img) center/cover no-repeat, #d9d9e2; box-shadow: 0 24px 50px rgba(20,20,40,.12); }
.split-body h2 { font-size: clamp(26px, 3vw, 38px); font-weight: 700; letter-spacing: -.02em; line-height: 1.1; margin-bottom: 16px; }
.split-body .prose { margin-bottom: 8px; }
.split-body .proj-title-sm { font-size: clamp(22px, 2.2vw, 30px); }
.split-body .proj-stat-lg { font-size: clamp(30px, 3.2vw, 46px); }
.tick-list { display: grid; gap: 12px; margin: 18px 0 6px; }
.tick-list li { position: relative; padding-left: 30px; font-size: 15px; line-height: 1.55; color: var(--c-body); }
.tick-list li::before { content: ""; position: absolute; left: 0; top: 2px; width: 19px; height: 19px; border-radius: 999px; background: var(--c-grad);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 10l3 3 7-7' stroke='black' stroke-width='2.2' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/14px no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 10l3 3 7-7' stroke='black' stroke-width='2.2' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/14px no-repeat; }

/* ---------- Plain card grid (reuses .svc-card) ---------- */
.cardgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.cardgrid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.svc-card .kicker { display: block; font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--c-accent); margin-bottom: 10px; }
.svc-card.plain { min-height: auto; }

/* ---------- Journey (numbered steps) ---------- */
.journey { display: grid; grid-template-columns: repeat(6, 1fr); gap: 0; counter-reset: step; }
.journey--5 { grid-template-columns: repeat(5, 1fr); }
.journey-step { position: relative; padding: 0 18px 8px; }
.journey-step::before { counter-increment: step; content: counter(step); display: flex; align-items: center; justify-content: center; width: 42px; height: 42px; border-radius: 999px; margin-bottom: 18px; background: var(--c-grad); color: #fff; font-weight: 700; font-size: 16px; }
.journey-step::after { content: ""; position: absolute; left: 42px; top: 21px; right: 0; height: 2px; background: var(--c-line); z-index: -1; }
.journey-step:last-child::after { display: none; }
.journey-step h4 { font-size: 16px; font-weight: 700; margin-bottom: 7px; }
.journey-step p { font-size: 13.5px; color: var(--c-body); line-height: 1.5; }
.psection--dark .journey-step::after { background: rgba(255,255,255,.2); }
.psection--dark .journey-step p { color: rgba(255,255,255,.66); }

/* ---------- Metrics row ---------- */
.metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; }
.metric .mnum { font-size: clamp(36px, 4vw, 56px); font-weight: 900; line-height: 1; letter-spacing: -.02em; background: var(--c-grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.psection--dark .metric .mnum { background: none; color: #fff; }
.metric .mlabel { margin-top: 10px; font-size: 14px; color: var(--c-body); line-height: 1.45; }
.psection--dark .metric .mlabel { color: rgba(255,255,255,.66); }

/* ---------- CTA band ---------- */
.cta-band { position: relative; overflow: hidden; color: #fff; background: linear-gradient(108deg, #1b0f40 0%, #0d0a2c 52%, #0b0a26 100%); padding-block: 76px; }
.cta-band::after { content: ""; position: absolute; left: -6%; bottom: -50%; width: 540px; height: 540px; background: radial-gradient(circle, rgba(var(--c-glow-rgb), .4), transparent 62%); pointer-events: none; }
.cta-band .container { position: relative; z-index: 1; display: grid; grid-template-columns: 1.5fr auto; gap: 36px; align-items: center; }
.cta-band h2 { font-size: clamp(28px, 3.4vw, 44px); font-weight: 700; letter-spacing: -.02em; line-height: 1.08; max-width: 20ch; }
.cta-band p { color: rgba(255,255,255,.74); margin-top: 14px; font-size: 17px; max-width: 56ch; }
.btn-light { background: #fff; color: var(--c-ink); }
.btn-light:hover { background: #ece9ff; }
.btn-lg { height: 52px; padding: 0 30px; font-size: 16px; }
.btn-ghost { border: 1px solid rgba(255,255,255,.5); color: #fff; }
.btn-ghost:hover { background: rgba(255,255,255,.12); }

/* ---------- Offices (contact page) ---------- */
.office-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
.office-card { border: 1px solid var(--c-line); border-radius: 14px; padding: 20px 22px; }
.office-card h4 { font-size: 16px; font-weight: 700; margin-bottom: 8px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.office-card .flag { font-size: 11.5px; font-weight: 700; color: var(--c-blue); border: 1px solid var(--c-line); border-radius: 999px; padding: 2px 8px; }
.office-card p { font-size: 14px; color: var(--c-body); line-height: 1.55; }

/* ---------- Responsive (interior) ---------- */
@media (max-width: 1080px) { .kgrid, .cardgrid { grid-template-columns: repeat(2, 1fr); } .journey { grid-template-columns: repeat(3, 1fr); row-gap: 30px; } .journey-step::after { display: none; } .metrics { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 860px) {
  .psection { padding-block: 60px; }
  .phero .container { padding-block: 54px; }
  .kgrid, .cardgrid, .cardgrid.cols-2, .office-list { grid-template-columns: 1fr; }
  .split, .split + .split { grid-template-columns: 1fr; gap: 30px; margin-top: 48px; }
  .split--reverse .split-media { order: 0; }
  .split-media { min-height: 240px; }
  .cta-band .container { grid-template-columns: 1fr; }
  .anchor-nav { display: none; }
}
@media (max-width: 560px) { .journey, .metrics { grid-template-columns: 1fr; } }

/* ============================================================
   ============================================================
   ITRANSITION ACCENT COMPONENTS (per-page colour decorum)
   From references: magenta/blue CTA bands, service-scope icon
   grid, "driven by results" cards, numbered service list,
   tech-ecosystem dark cards, reasons list, FAQ, testimonials.
   ============================================================
   ============================================================ */

/* ---------- CTA band colour variants ---------- */
.cta-band--magenta { background: linear-gradient(95deg, #3917c0 0%, #461ee8 55%, #633ff2 100%); }
.cta-band--magenta::after { display: none; }
.cta-band--blue { background: linear-gradient(95deg, #2330cc 0%, #2d2deb 70%, #3a52ff 100%); }
.cta-band--blue::after { display: none; }
.cta-band--magenta .btn-light:hover, .cta-band--blue .btn-light:hover { background: #fff; transform: translateY(-2px); }

/* ---------- Service scope (light icon cards) ---------- */
.scope-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.scope-card { border: 1px solid var(--c-line); border-radius: 14px; padding: 26px 22px; background: #fff; transition: box-shadow .2s var(--ease), transform .2s var(--ease), border-color .2s var(--ease); }
.scope-card:hover { box-shadow: 0 14px 30px rgba(20,20,40,.08); transform: translateY(-2px); border-color: #c9c9f0; }
.scope-ic { width: 46px; height: 46px; border-radius: 12px; background: linear-gradient(135deg, rgba(var(--c-shadow-rgb), .14), rgba(232,30,140,.14)); display: flex; align-items: center; justify-content: center; color: var(--c-blue); margin-bottom: 16px; }
.scope-ic svg { width: 24px; height: 24px; }
.scope-card h4 { font-size: 16px; font-weight: 700; margin-bottom: 8px; }
.scope-card p { font-size: 13.5px; color: var(--c-body); line-height: 1.55; }

/* ---------- Driven by results (photo case cards) ---------- */
.result-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.result-card { display: flex; flex-direction: column; border: 1px solid var(--c-line); border-radius: 14px; overflow: hidden; background: #fff; transition: box-shadow .25s var(--ease), transform .25s var(--ease); }
.result-card:hover { box-shadow: 0 22px 44px rgba(20,20,40,.10); transform: translateY(-3px); }
.result-media { min-height: 180px; background: var(--img) center/cover no-repeat, #d9d9e2; }
.result-body { padding: 24px; display: flex; flex-direction: column; flex: 1; }
.result-body .tag { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--c-accent); margin-bottom: 10px; }
.result-body h4 { font-size: 18px; font-weight: 700; line-height: 1.3; margin-bottom: 10px; }
.result-body p { font-size: 14px; color: var(--c-body); line-height: 1.55; flex: 1; }
.result-body .link-arrow { margin-top: 14px; }

/* ---------- Numbered service list (ERP-style) ---------- */
.numlist { border-top: 1px solid var(--c-line); }
.numrow { display: grid; grid-template-columns: 70px 1fr 28px; gap: 24px; align-items: start; padding: 30px 4px; border-bottom: 1px solid var(--c-line); transition: background .2s var(--ease); }
.numrow:hover { background: var(--c-surface-2); }
.numrow .n { font-size: 26px; font-weight: 700; line-height: 1; background: var(--c-grad); -webkit-background-clip: text; background-clip: text; color: transparent; }
.numrow h4 { font-size: 21px; font-weight: 700; margin-bottom: 8px; letter-spacing: -.01em; }
.numrow p { font-size: 15px; color: var(--c-body); line-height: 1.6; max-width: 76ch; }
.numrow .go { color: var(--c-accent); align-self: center; }
.numrow .go svg { width: 24px; height: 24px; transition: transform .2s var(--ease); }
.numrow:hover .go svg { transform: translateX(4px); }

/* ---------- Tech-ecosystem dark cards ---------- */
.darkcard { border: 1px solid rgba(255,255,255,.14); border-radius: 14px; padding: 32px; background: rgba(255,255,255,.04); }
.darkcard h3 { font-size: 22px; font-weight: 700; margin-bottom: 12px; }
.darkcard p { color: rgba(255,255,255,.7); font-size: 15px; line-height: 1.6; }
.darkcard .chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.darkcard .chips span { font-size: 12.5px; font-weight: 600; color: rgba(255,255,255,.82); border: 1px solid rgba(255,255,255,.2); border-radius: 999px; padding: 6px 13px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }

/* ---------- Reasons list (why-us) ---------- */
.reasons { display: grid; grid-template-columns: repeat(2, 1fr); gap: 28px 48px; }
.reason { display: grid; grid-template-columns: 26px 1fr; gap: 16px; }
.reason .rn { color: var(--c-accent); font-weight: 700; font-size: 15px; }
.reason h4 { font-size: 17px; font-weight: 700; margin-bottom: 6px; }
.reason p { font-size: 14.5px; color: var(--c-body); line-height: 1.6; }
.psection--dark .reason p { color: rgba(255,255,255,.7); }
.psection--dark .reason h4 { color: #fff; }

/* ---------- FAQ accordion ---------- */
.faq { max-width: 860px; }
.faq-item { border-bottom: 1px solid var(--c-line); }
.faq-q { width: 100%; text-align: left; display: flex; justify-content: space-between; align-items: center; gap: 20px; padding: 22px 2px; font-size: 18px; font-weight: 600; color: var(--c-ink); cursor: pointer; }
.faq-q .pm { flex-shrink: 0; width: 22px; height: 22px; position: relative; }
.faq-q .pm::before, .faq-q .pm::after { content: ""; position: absolute; background: var(--c-blue); border-radius: 2px; transition: transform .25s var(--ease); }
.faq-q .pm::before { left: 0; top: 10px; width: 22px; height: 2px; }
.faq-q .pm::after { left: 10px; top: 0; width: 2px; height: 22px; }
.faq-item.open .pm::after { transform: scaleY(0); }
.faq-a { max-height: 0; overflow: hidden; transition: max-height .3s var(--ease); }
.faq-item.open .faq-a { max-height: 320px; }
.faq-a p { font-size: 15px; color: var(--c-body); line-height: 1.6; padding: 0 2px 22px; max-width: 76ch; }

/* this page's FAQ list left a big empty gap on the right at wide viewports —
   let it fill the container instead of capping at 860px, and size the type
   up a touch so the wider row doesn't look sparse */
.pg-service-detail .faq { max-width: none; margin-top: 44px; }
.pg-service-detail .faq-q { font-size: 19px; padding: 26px 2px; }
.pg-service-detail .faq-a p { font-size: 16px; max-width: 90ch; }

/* each FAQ row as its own rounded, bordered box; hovering lifts it up
   slightly instead of just changing the border, so the effect reads as
   the box "coming up" to meet the cursor */
.pg-service-detail .faq-item {
  border: 1px solid var(--c-line); border-radius: 14px; padding: 0 22px;
  margin-bottom: 14px;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease);
}
.pg-service-detail .faq-item:last-child { margin-bottom: 0; }
.pg-service-detail .faq-item:hover, .pg-service-detail .faq-item.open { border-color: var(--c-blue); box-shadow: 0 10px 24px rgba(20,20,40,.08); }
.pg-service-detail .faq-item:hover { transform: translateY(-4px); }

/* ---- consulting: FAQ rows slide in alternately from left and right ----
   Direction comes from the sitewide .reveal-left/.reveal-right (a flat ±70px
   on the X axis, gated to ≥1081px). Only the transition needs fixing here:
   the list on ".pg-service-detail .faq-item" above (0,2,0) outranks .reveal's
   own (0,1,0) and omits opacity, so without this the rows would slide but
   snap to full opacity instead of fading. 0.45s serves both jobs — slow
   enough to read as a slide, quick enough that the hover lift sharing this
   list still feels crisp. */
.pg-consulting .faq-item.reveal,
.pg-implementation .faq-item.reveal,
.pg-migration .faq-item.reveal,
.pg-integration .faq-item.reveal,
.pg-ams .faq-item.reveal,
.pg-support .faq-item.reveal,
.pg-training .faq-item.reveal,
.pg-analytics .faq-item.reveal {
  transition: opacity .45s var(--ease), transform .45s var(--ease),
              border-color .3s var(--ease), box-shadow .3s var(--ease);
}
/* The ±70px start offset pushes a row past the container edge at viewports
   between ~1080px and ~1320px (narrower than that and the directional variants
   are off anyway). Clip the track rather than let the page scroll sideways;
   the clip margin keeps the hover shadow from being shaved off at rest. */
.pg-consulting .faq,
.pg-implementation .faq,
.pg-migration .faq,
.pg-integration .faq,
.pg-ams .faq,
.pg-support .faq,
.pg-training .faq,
.pg-analytics .faq {
  overflow-x: hidden;      /* fallback */
  overflow-x: clip;        /* no scroll container, so overflow-y stays visible */
  overflow-clip-margin: 30px;
}

/* touch devices never see the :hover states above (or on the cards below) —
   a quick press-down gives the same "the page is responding to me" feedback
   that a mouse cursor gets from hover, instead of taps feeling inert */
@media (hover: none) {
  .approach-row:active,
  .ind-strip-item:active,
  #sap-solutions .svc-card:active,
  .pg-service-detail .faq-item:active {
    transform: scale(0.97);
    transition: transform .15s var(--ease);
  }
}

/* ---------- Testimonial / quote ---------- */
.quote-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.quote-card { border: 1px solid var(--c-line); border-radius: 14px; padding: 30px; background: #fff; }
.quote-card .mark { font-size: 44px; line-height: .6; color: var(--c-accent); font-weight: 800; }
.quote-card p { font-size: 16px; color: var(--c-ink); line-height: 1.6; margin: 10px 0 18px; }
.quote-card .who { font-size: 14px; font-weight: 700; }
.quote-card .who span { display: block; font-weight: 500; color: var(--c-muted); font-size: 13px; margin-top: 2px; }

/* ---------- Donut stat (market overview) ---------- */
.donut-row { display: flex; flex-wrap: wrap; gap: 48px; }
.donut { display: flex; flex-direction: column; align-items: center; text-align: center; }
.donut .ring { width: 132px; height: 132px; border-radius: 999px; display: grid; place-items: center; background: conic-gradient(var(--c-blue) calc(var(--p) * 1%), #e6e6ec 0); }
.donut .ring::before { content: ""; position: absolute; width: 100px; height: 100px; border-radius: 999px; background: #fff; }
.donut .ring b { position: relative; font-size: 26px; font-weight: 700; color: var(--c-ink); }
.donut .dlabel { margin-top: 14px; font-size: 14px; color: var(--c-body); max-width: 22ch; }

/* ---------- responsive (accents) ---------- */
@media (max-width: 1080px) { .scope-grid { grid-template-columns: repeat(2, 1fr); } .result-grid { grid-template-columns: repeat(2, 1fr); } .reasons, .quote-grid, .grid-2 { grid-template-columns: 1fr; } }
@media (max-width: 860px) {
  .scope-grid, .result-grid { grid-template-columns: 1fr; }
  .numrow { grid-template-columns: 46px 1fr; gap: 16px; padding: 22px 2px; }
  .numrow .go { display: none; }
}

/* ============================================================
   INDUSTRY IMAGE CARDS (industries page tiles)
   ============================================================ */
.industry-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.industry-card { position: relative; min-height: 300px; border-radius: 14px; overflow: hidden; color: #fff; background: var(--img) center/cover no-repeat, var(--c-dark); display: flex; flex-direction: column; justify-content: flex-end; padding: 26px; transition: transform .3s var(--ease), box-shadow .3s var(--ease); }
.industry-card::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(11,10,40,.12) 0%, rgba(11,10,40,.55) 55%, rgba(11,10,40,.86) 100%); transition: background .3s var(--ease); }
.industry-card:hover { transform: translateY(-4px); box-shadow: 0 24px 44px rgba(11,10,40,.28); }
.industry-card:hover::after { background: linear-gradient(180deg, rgba(var(--c-shadow-rgb), .30) 0%, rgba(11,10,40,.62) 55%, rgba(11,10,40,.9) 100%); }
.industry-card > * { position: relative; z-index: 1; }
.industry-card h3 { font-size: 21px; font-weight: 700; margin-bottom: 8px; }
.industry-card p { font-size: 14px; color: rgba(255,255,255,.82); line-height: 1.5; }
.industry-card .more { margin-top: 14px; display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; color: #fff; }
.industry-card .more svg { width: 16px; height: 16px; transition: transform .2s var(--ease); }
.industry-card:hover .more svg { transform: translateX(4px); }
@media (max-width: 1080px) { .industry-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .industry-grid { grid-template-columns: 1fr; } }

/* Industries carousel — a continuous sliding track (arrow/swipe-navigated);
   collapsed items show icon/heading/description, hovering rises a photo up
   to cover the whole card with a dark scrim + white text (desktop only) */
.ind-carousel { position: relative; margin-top: 40px; }
.ind-viewport { overflow: hidden; padding: 0 7px; box-sizing: border-box; }
.ind-track { display: flex; gap: 22px; transition: transform .5s var(--ease); }

/* arrows float over the card row (like the homepage industries slider),
   vertically centered, sitting in the small side margin around the cards */
.ind-carousel-btn {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 5;
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--c-line); background: #fff; color: var(--c-blue);
  box-shadow: 0 6px 18px rgba(20,20,40,.14);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.ind-carousel-btn--prev { left: 0; }
.ind-carousel-btn--next { right: 0; }
.ind-carousel-btn svg { width: 20px; height: 20px; }
.ind-carousel-btn:hover { border-color: var(--c-blue); background: rgba(var(--c-shadow-rgb), .06); }
.ind-carousel-btn:disabled { opacity: .3; cursor: default; pointer-events: none; }

.ind-strip-item {
  position: relative; flex: 0 0 calc((100% - 44px) / 3); min-width: 0; min-height: 360px;
  display: flex; flex-direction: column; text-decoration: none; color: inherit;
  background: var(--c-surface-2); border-radius: 14px; padding: 28px 24px 24px;
  overflow: hidden; isolation: isolate;
}
.ind-icon {
  width: 52px; height: 52px; border-radius: 10px; flex-shrink: 0;
  background: rgba(var(--c-shadow-rgb), .1); color: var(--c-blue); position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: center; margin-bottom: 22px;
  transition: background .35s var(--ease), color .35s var(--ease);
}
.ind-icon svg { width: 26px; height: 26px; }
.ind-strip-item h3 { position: relative; z-index: 2; font-size: 19px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 14px; transition: color .35s var(--ease); }
.ind-strip-item p { position: relative; z-index: 2; font-size: 14.5px; line-height: 1.55; color: var(--c-body); margin-bottom: 8px; transition: color .35s var(--ease); }
.ind-photo {
  position: absolute; left: 0; right: 0; bottom: 0; top: 100%; z-index: 1;
  border-radius: 14px; background: var(--img) center/cover no-repeat, var(--c-dark);
  transition: top .45s var(--ease);
}
.ind-photo::after {
  content: ''; position: absolute; inset: 0; opacity: 0; transition: opacity .45s var(--ease);
  background: linear-gradient(180deg, rgba(11,10,40,.08) 0%, rgba(11,10,40,.55) 55%, rgba(11,10,40,.9) 100%);
}
.ind-more { position: relative; z-index: 2; display: none; margin-top: 18px; align-items: center; gap: 8px; font-weight: 600; font-size: 14px; color: #fff; }
.ind-more svg { width: 16px; height: 16px; transition: transform .2s var(--ease); }
.ind-strip-item:hover .ind-more svg { transform: translateX(4px); }

/* mouse devices reveal on hover; touch devices use .is-touched instead (see
   the JS below — a normal tap sets it immediately, no long-press needed).
   Touch browsers apply :hover on a long-press rather than a quick tap, so
   :hover is gated to real pointer devices to avoid that "have to hold it"
   feeling competing with the tap-driven reveal. */
@media (hover: hover) {
  .ind-strip-item:hover .ind-photo { top: 0; border-radius: 14px; }
  .ind-strip-item:hover .ind-photo::after { opacity: 1; }
  .ind-strip-item:hover .ind-icon { background: rgba(255,255,255,.16); color: #fff; }
  .ind-strip-item:hover h3, .ind-strip-item:hover p { color: #fff; }
  .ind-strip-item:hover .ind-more { display: inline-flex; }
}
.ind-strip-item.is-touched .ind-photo { top: 0; border-radius: 14px; }
.ind-strip-item.is-touched .ind-photo::after { opacity: 1; }
.ind-strip-item.is-touched .ind-icon { background: rgba(255,255,255,.16); color: #fff; }
.ind-strip-item.is-touched h3, .ind-strip-item.is-touched p { color: #fff; }
.ind-strip-item.is-touched .ind-more { display: inline-flex; }
@media (max-width: 1080px) {
  .ind-strip-item { flex-basis: calc((100% - 22px) / 2); min-height: auto; }
}
@media (max-width: 640px) {
  /* arrows floating beside one card look odd on a single-column carousel —
     swipe drives navigation here instead, same convention as the homepage
     industries slider */
  .ind-carousel-btn { display: none; }
  .ind-strip-item { flex-basis: 100%; }
}


/* ============================================================
   SERVICES / INDUSTRIES DIRECTORY (alternating white + magenta
   sections; category rows with sub-link tags + boxed arrow).
   From the full-page itransition Services reference.
   ============================================================ */
.phero--center .container { text-align: center; }
.phero--center h1, .phero--center .lead { margin-inline: auto; }

.psection--magenta { color: #fff; background: linear-gradient(168deg, #3917c2 0%, #2c158a 38%, #1f144a 72%, #2c1336 100%); }
.psection--magenta .eyebrow { color: #c2b3ff; }

.dir-head { display: grid; grid-template-columns: 1.1fr 1fr; gap: 48px; align-items: start; margin-bottom: 36px; }
.dir-head h2 { font-size: clamp(32px, 3.8vw, 50px); font-weight: 700; letter-spacing: -.02em; line-height: 1.06; }
.dir-head p { font-size: 15px; line-height: 1.7; color: var(--c-body); padding-top: 6px; }
.psection--magenta .dir-head p { color: rgba(255,255,255,.82); }

.dirlist { border-top: 1px solid var(--c-line); }
.psection--magenta .dirlist { border-top-color: rgba(255,255,255,.22); }
.dir-row {
  display: grid; grid-template-columns: 1fr 50px; gap: 28px; align-items: center;
  padding: 24px 4px; border-bottom: 1px solid var(--c-line);
  transition: background .2s var(--ease), padding-left .2s var(--ease); color: inherit;
}
.psection--magenta .dir-row { border-bottom-color: rgba(255,255,255,.18); }
.dir-row:hover { background: var(--c-surface-2); padding-left: 14px; }
.psection--magenta .dir-row:hover { background: rgba(255,255,255,.05); }
.dir-row h3 { font-size: 20px; font-weight: 700; letter-spacing: -.01em; color: var(--c-ink); }
.psection--magenta .dir-row h3 { color: #fff; }
.dir-tags { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 7px 18px; }
.dir-tags a, .dir-tags span { font-size: 14px; color: var(--c-muted); transition: color .18s var(--ease); }
.dir-tags a:hover { color: var(--c-blue); }
.psection--magenta .dir-tags a, .psection--magenta .dir-tags span { color: rgba(255,255,255,.66); }
.psection--magenta .dir-tags a:hover { color: #fff; }
.dir-arrow {
  width: 50px; height: 50px; border: 1px solid var(--c-line); border-radius: 6px;
  display: flex; align-items: center; justify-content: center; color: #f5821f; flex-shrink: 0;
  transition: background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
}
.psection--magenta .dir-arrow { border-color: rgba(255,255,255,.38); }
.dir-arrow svg { width: 20px; height: 20px; transition: transform .2s var(--ease); }
.dir-row:hover .dir-arrow { background: #f5821f; border-color: #f5821f; color: #fff; }
.dir-row:hover .dir-arrow svg { transform: translateX(2px); }

/* full-bleed photo band between sections */
.photo-band { min-height: 360px; background: var(--img) center/cover no-repeat, var(--c-dark); }

@media (max-width: 860px) {
  .dir-head { grid-template-columns: 1fr; gap: 14px; margin-bottom: 24px; }
  .dir-row { grid-template-columns: 1fr 44px; gap: 16px; padding: 20px 2px; }
  .dir-arrow { width: 44px; height: 44px; }
  .photo-band { min-height: 220px; }
}

/* ============================================================
   EXACT SERVICES DIRECTORY (2-column category blocks)
   Built precisely from the full-res itransition Services ref.
   ============================================================ */
.psection--magenta { background: linear-gradient(110deg, #351c9a 0%, #2c1a74 55%, #1f1645 100%) !important; color: #fff; }

.svc-title {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
}

    .svc-title .eyebrow {
        margin-bottom: 18px;
    }

    .svc-title h2 {
        margin: 0;
    }

.svc-dir-head {
    display: flex;
    flex-direction: column;
    gap: 30px;
}
 .svc-dir-head h2 { font-size: clamp(38px, 4.4vw, 62px); font-weight: 900; letter-spacing: -.025em; line-height: 1.0; display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
    .svc-dir-head .intro {
        font-size: 17px;
        font-weight: 300;
        line-height: 1.62;
        color: #323232;
        padding-top: 50px;
        max-width: 900px; 
    }
.psection--magenta .svc-dir-head .intro { color: rgba(255,255,255,.86); }
.head-arrow { width: 46px; height: 46px; border: 1px solid var(--c-line); border-radius: 4px; display: inline-flex; align-items: center; justify-content: center; color: #f5821f; transition: background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease); }
.head-arrow:hover { background: #f5821f; border-color: #f5821f; color: #fff; }
.head-arrow svg { width: 22px; height: 22px; }

.svc-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 64px; margin-top: 46px; align-items: start; }
.svc-col { display: flex; flex-direction: column; }

.cat { display: grid; grid-template-columns: 1fr 60px; gap: 28px; align-items: center; padding: 26px 0; border-bottom: 1px solid var(--c-line); }
.psection--magenta .cat { border-bottom-color: rgba(255,255,255,.18); }
.cat h3 { font-size: 21px; font-weight: 800; letter-spacing: -.01em; line-height: 1.2; }
.cat h3 a { color: var(--c-ink); transition: color .15s var(--ease); }
.cat:hover h3 a { color: #3917c0; }
.psection--magenta .cat h3 a { color: #fff; }
.cat .subs { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 12px 22px; }
.cat .subs a, .cat .subs span { font-size: 16px; color: var(--c-body); line-height: 1.3; transition: color .15s var(--ease); }
.cat .subs a:hover { color: #3917c0; }
.psection--magenta .cat .subs a, .psection--magenta .cat .subs span { color: rgba(255,255,255,.78); }
.psection--magenta .cat .subs a:hover { color: #fff; }
.cat-arrow { width: 60px; height: 60px; border: 1px solid #c4c4c4; border-radius: 4px; display: flex; align-items: center; justify-content: center; color: var(--c-accent); align-self: center; transition: background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease); }
.psection--magenta .cat-arrow { border-color: rgba(255,255,255,.32); }
.cat-arrow svg { width: 26px; height: 24px; transition: transform .2s var(--ease); }
.cat:hover .cat-arrow { background: var(--c-accent); border-color: var(--c-accent); color: #fff; }
.cat:hover .cat-arrow svg { transform: translateX(3px); }
.cat--plain { grid-template-columns: 1fr; position: relative; }
.cat--plain .subs a, .cat--plain .subs span { color: var(--c-body); }
/* double underline that frames the whole card (heading + paragraph), not
   just the heading text, scaling in from opposite ends on hover */
.cat--plain::after, .cat--plain::before {
  content: ''; position: absolute; left: 0; width: 100%; height: 2px;
  background: var(--c-grad-violet); transform: scaleX(0); transition: transform .4s ease-out;
}
.cat--plain::after { bottom: 0; transform-origin: right; }
.cat--plain::before { top: 0; transform-origin: left; }
/* mouse devices only — touch browsers apply :hover on a long-press instead
   of a normal tap, which is exactly the "have to hold it" problem; touch
   gets .is-inview instead (added by JS below as each card scrolls into view) */
@media (hover: hover) {
  .cat--plain:hover::after, .cat--plain:hover::before { transform: scaleX(1); }
}
.cat--plain.is-inview::after, .cat--plain.is-inview::before { transform: scaleX(1); }
.cat-body p { margin-top: 12px; font-size: 16px; line-height: 1.62; color: var(--c-body); }
.psection--magenta .cat-body p { color: rgba(255,255,255,.82); }

.svc-photo { min-height: 300px; background: var(--img) center/cover no-repeat, var(--c-dark); margin-top: 10px; }
.svc-panel { background: var(--c-surface-2); border-radius: 14px; padding: 4px 32px; }

/* thin gradient bar used as a lightweight section divider instead of extra
   vertical whitespace */
.grad-divider { height: 3px; border-radius: 2px; background: var(--c-grad-violet); margin: 28px 0; }

/* column grid — one stage per column (heading over description) instead of
   full-width rows, so the section uses horizontal space instead of leaving
   a gap next to each short description */
/* No align-items: start here — the default stretch is load-bearing. It sizes
   every card in the row to the tallest one, so the boxes come out the same
   height however much copy each stage carries. Their width is the other half
   of "same size", and that comes from the .apx-on track further down. */
.approach-rows { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-top: 46px; }
/* V-shaped stagger: columns dip down toward the middle card, then rise back
   up — only while all 5 sit in one row (see the 940px breakpoint below).

   The dip is a translate, NOT a margin. Margins are layout, so they fed back
   into the row height and left every card a different size (the deeper the
   dip, the shorter the card). translate paints outside layout, so the cards
   stay equal-size and only their position moves. It is also the one transform
   channel that survives here: .approach-carousel drives the six-phase converge
   on `transform` and resets it with `transform: none`, which would wipe a
   transform-based dip — `translate` composes with it instead of fighting it.

   Because the dip is outside layout, the grid box ends at the un-shifted row:
   the deepest card needs matching bottom padding or it overhangs the section. */
@media (min-width: 941px) {
  .approach-rows { padding-bottom: 72px; }
  .approach-row:nth-child(1) { translate: 0 0; }
  .approach-row:nth-child(2) { translate: 0 40px; }
  .approach-row:nth-child(3) { translate: 0 72px; }
  .approach-row:nth-child(4) { translate: 0 40px; }
  .approach-row:nth-child(5) { translate: 0 0; }
}
.approach-row {
  padding: 20px 16px; border: 1px solid transparent; border-top: 3px solid var(--c-line);
  border-radius: 14px; position: relative;
  /* Top-aligned, NOT centred. Centring was tried and reverted: it pushed each
     card's block down by half its own leftover space, so cards with shorter
     copy sat their heading lower than their neighbours and the row of headings
     stopped reading as a line. Anchored to the top, every heading and every
     paragraph's first line falls on the same baseline across the row, and the
     leftover space collects at the bottom — where the card has no visible edge
     at rest anyway (only the 3px top rule shows), so it costs nothing. */
  display: flex; flex-direction: column; justify-content: flex-start;
  transition: background .35s var(--ease), box-shadow .35s var(--ease), transform .35s var(--ease), border-color .35s var(--ease);
}
.approach-row:hover {
  background: #fff; transform: translateY(-4px);
  box-shadow: 0 14px 30px rgba(20,20,40,.10);
  border-color: var(--c-blue);
}
/* stagger the stages in as the section arrives (add .reveal + data-delay in
   the markup). The transition above (0,1,0) outranks .reveal's own (0,1,0) on
   source order and omits opacity, so it has to be restated here with opacity
   folded in — otherwise the cards rise but snap to full opacity. The hover
   lift keeps working: its transform (0,2,0) still outranks .reveal.is-in. */
.approach-row.reveal {
  transition: opacity .45s var(--ease), transform .45s var(--ease),
              background .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
}
/* stepped down from 20/15.5 so the wordiest stage still fits inside the square
   the column width allows. Where it doesn't, nothing breaks — the row just
   grows past square — but the type is what decides how often that happens. */
.approach-row h4 { font-size: 18px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 9px; }
.approach-row p { font-size: 14.5px; line-height: 1.55; color: var(--c-body); }
/* No aspect-ratio here any more. Forcing a square was tried and reverted: it
   set the height from the card's WIDTH, so a page whose stages are written
   short — implementation-rollout averages 134 characters against roughly 370
   the square could hold — got a third of a card of copy above two thirds of
   empty. Height comes from the copy again, and the grid's stretch keeps every
   card in a row equal to the tallest, which is what stops them going ragged.
   Uniform card WIDTH across pages is handled by the track below instead. */
/* below 941px there's no room for 5 columns in one row — swipe through them
   instead of collapsing to a flat stack, so the V-shape stagger survives.
   align-items: stretch (not flex-start) for the same reason as the grid above:
   it is what keeps the swipe cards a uniform size. */
@media (max-width: 940px) {
  .approach-rows {
    display: flex; grid-template-columns: none; align-items: stretch;
    gap: 16px; overflow-x: auto; scroll-snap-type: x mandatory;
    /* 40px deepest dip + the 10px the swipe track already wanted */
    padding-bottom: 50px; -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .approach-rows::-webkit-scrollbar { display: none; }
  .approach-row { flex: 0 0 46%; scroll-snap-align: start; }
  .approach-row:nth-child(1) { translate: 0 0; }
  .approach-row:nth-child(2) { translate: 0 22px; }
  .approach-row:nth-child(3) { translate: 0 40px; }
  .approach-row:nth-child(4) { translate: 0 22px; }
  .approach-row:nth-child(5) { translate: 0 0; }
}
@media (max-width: 560px) {
  .approach-row { flex-basis: 78%; }
}
/* four-stage variant (services/consulting.html). The base grid reserves five
   columns; with four stages that leaves a dead column on the right and the
   V-shape dips off-centre. Four columns, and the dip is shared by the middle
   pair so the arc stays symmetric. */
.approach-rows--4 { grid-template-columns: repeat(4, 1fr); }
@media (min-width: 941px) {
  .approach-rows--4 { padding-bottom: 56px; }
  .approach-rows--4 .approach-row:nth-child(1) { translate: 0 0; }
  .approach-rows--4 .approach-row:nth-child(2) { translate: 0 56px; }
  .approach-rows--4 .approach-row:nth-child(3) { translate: 0 56px; }
  .approach-rows--4 .approach-row:nth-child(4) { translate: 0 0; }
}
/* below 941px .approach-rows turns into a swipe row — same symmetric pairing,
   shallower, so the four cards read as one arc on a phone too */
@media (max-width: 940px) {
  .approach-rows--4 { padding-bottom: 40px; }
  .approach-rows--4 .approach-row:nth-child(1) { translate: 0 0; }
  .approach-rows--4 .approach-row:nth-child(2) { translate: 0 30px; }
  .approach-rows--4 .approach-row:nth-child(3) { translate: 0 30px; }
  .approach-rows--4 .approach-row:nth-child(4) { translate: 0 0; }
}
/* six-stage variant (services/implementation-rollout.html — the six SAP Activate
   phases). Six columns rather than the base five, and the V dips across the
   middle pair so the arc stays symmetric with an even number of stages. */
.approach-rows--6 { grid-template-columns: repeat(6, 1fr); }
@media (min-width: 941px) {
  .approach-rows--6 { padding-bottom: 68px; }
  .approach-rows--6 .approach-row:nth-child(1) { translate: 0 0; }
  .approach-rows--6 .approach-row:nth-child(2) { translate: 0 38px; }
  .approach-rows--6 .approach-row:nth-child(3) { translate: 0 68px; }
  .approach-rows--6 .approach-row:nth-child(4) { translate: 0 68px; }
  .approach-rows--6 .approach-row:nth-child(5) { translate: 0 38px; }
  .approach-rows--6 .approach-row:nth-child(6) { translate: 0 0; }
}
/* below 941px the row becomes a swipe track — same arc, shallower, and the
   sixth card needs its own reset or it inherits nothing from the 1–5 list */
@media (max-width: 940px) {
  .approach-rows--6 { padding-bottom: 50px; }
  .approach-rows--6 .approach-row:nth-child(1) { translate: 0 0; }
  .approach-rows--6 .approach-row:nth-child(2) { translate: 0 22px; }
  .approach-rows--6 .approach-row:nth-child(3) { translate: 0 40px; }
  .approach-rows--6 .approach-row:nth-child(4) { translate: 0 40px; }
  .approach-rows--6 .approach-row:nth-child(5) { translate: 0 22px; }
  .approach-rows--6 .approach-row:nth-child(6) { translate: 0 0; }
}
/* six columns of body copy get tight before the 941px swipe kicks in — one
   step below the (already reduced) sitewide size */
@media (min-width: 941px) and (max-width: 1200px) {
  .approach-rows--6 .approach-row { padding: 16px 12px; }
  .approach-rows--6 .approach-row h4 { font-size: 16.5px; }
  .approach-rows--6 .approach-row p { font-size: 13.5px; line-height: 1.5; }
}

/* ---- horizontal reveal track (JS-gated) ---------------------------------
   Fitting every stage into one row meant the column count set the card size:
   ~285px squares on the four-stage page but ~186px on the six-stage one. Here
   the card takes ONE fixed size on every page and the row is allowed to run
   past the right edge instead, travelling left as the section crosses the
   viewport — so the later stages arrive as you scroll rather than being
   shrunk to fit alongside the first.

   Pinned: the page holds still until every stage has passed through the frame,
   then releases. That makes two pinned sections on these pages — "What VISCAP
   Delivers" higher up is the other — so the scroll distance is kept to the
   minimum the snap steps need rather than being drawn out.

   .apx-on is added by services-scroll.js and removed again below 941px, so
   with JS or GSAP unavailable — or on a phone, where .approach-rows is
   already a native swipe track — none of this applies and the grid above
   stands unchanged. */
@media (min-width: 941px) {
  /* Clip at the CONTENT COLUMN, not at the section. Clipping full-bleed let
     the row run out to the viewport edge, which left a half card cut through
     the middle of a word at both ends. This wrapper is injected by
     services-scroll.js and carries no padding of its own, so its edges are
     exactly where the text column starts and stops: a card leaving is gone at
     the same line the heading begins on, and the row rests on four whole
     cards. No overflow-clip-margin — a margin here would show a slice of the
     next card beyond the column, which is the thing being fixed.

     clip, not hidden: it creates no scroll container, so the cards' downward
     V-dip and the hover lift still overflow vertically. */
  .apx-on .apx-view { overflow-x: hidden; overflow-x: clip; margin-top: 46px; }
  /* The row's 46px top margin moves onto the frame. overflow-x: clip does not
     form a block formatting context but the overflow-x: hidden fallback does,
     so on the browsers that take the fallback the row's own margin would stop
     collapsing through and quietly add 46px. Pinning it to the frame makes the
     spacing identical either way. On implementation-rollout the carousel
     wrapper already supplies that gap, so the frame must not repeat it. */
  .apx-on .approach-carousel .apx-view { margin-top: 0; }
  /* width: 100%, NOT max-content. The card basis below is a percentage, and a
     percentage resolves against the flex container — size the container to its
     content and that reference goes circular. At 100% the cards simply
     overflow to the right, which is exactly what the track wants. */
  .apx-on .approach-rows {
    display: flex; grid-template-columns: none; width: 100%; gap: 12px;
    margin-top: 0;
  }
  /* Exactly four cards across the content column at rest, on every page —
     the same four-up opening as the consulting grid, whether the page has
     four stages or six. Stages five and six start beyond the right edge and
     are what the scroll brings in. Four × basis + three × 12px gap = 100%. */
  .apx-on .approach-row { flex: 0 0 calc((100% - 36px) / 4); }
  /* The cards' own .reveal fade is an IntersectionObserver in main.js, and the
     track parks the later cards outside the clip above — where they report a
     ratio of 0, never receive .is-in and would stay invisible permanently.
     This is the same trap documented on .approach-carousel below. The track is
     their reveal now, so the fade is stood down rather than left to misfire. */
  .apx-on .approach-row.reveal { opacity: 1; transform: none; }
  /* implementation-rollout drives these same six cards from its own converge
     animation, which would fight the track. (0,3,0) stands it down — enough to
     outrank both its base rule and its per-column nth-child offsets (0,2,1). */
  .apx-on .approach-carousel .approach-row {
    opacity: 1; transform: none; transition-delay: 0s;
  }
  /* that wrapper clips at the content column for its own animation; the
     section's clip governs now, or the track would be cut off early */
  .apx-on .approach-carousel { overflow: visible; }
  /* The 941–1200px step-down above exists because six grid columns squeezed a
     card to ~146px. On the track a card is a quarter of the row whatever the
     stage count — 225px at a 1000px viewport — so that shrunken type is no
     longer paying for anything. Restore the sitewide size. (0,3,0) beats the
     step-down's (0,2,0), and this sits after it in source order. */
  .apx-on .approach-rows--6 .approach-row { padding: 20px 16px; }
  .apx-on .approach-rows--6 .approach-row h4 { font-size: 18px; }
  .apx-on .approach-rows--6 .approach-row p { font-size: 14.5px; line-height: 1.55; }
}

/* ---- the two halves converge -------------------------------------------
   Phases 1–3 arrive from the left edge, 4–6 from the right, meeting in the
   middle of the V. Travel is scaled per column — the outermost pair crosses
   the most ground, the middle pair barely moves — which is what makes the
   group read as closing rather than as six separate slides.

   main.js observes the WRAPPER, not the cards, and the cards animate off its
   .is-in. This is load-bearing, not a preference. Putting .reveal on the cards
   themselves deadlocks them: IntersectionObserver intersects with ancestor clip
   rects, so a card parked 260px outside the clip below reports a ratio of 0,
   never crosses the observer's 0.15 threshold, never receives .is-in, and stays
   parked off-screen permanently — which is exactly how phases 1 and 6 went
   missing. The wrapper is never displaced, so it is always observable. */
.approach-carousel .approach-row {
  opacity: 0;
  transition: opacity .7s var(--ease), transform .7s var(--ease),
              background .35s var(--ease), box-shadow .35s var(--ease),
              border-color .35s var(--ease);
}
/* the wrapper carries .reveal only so the observer picks it up — it should not
   itself fade or travel, or the whole block would move as well as the cards */
.approach-carousel.reveal { opacity: 1; transform: none; transition: none; }
@media (min-width: 1081px) {
  .approach-carousel .approach-row:nth-child(1) { transform: translateX(-260px); }
  .approach-carousel .approach-row:nth-child(2) { transform: translateX(-170px); }
  .approach-carousel .approach-row:nth-child(3) { transform: translateX(-85px); }
  .approach-carousel .approach-row:nth-child(4) { transform: translateX(85px); }
  .approach-carousel .approach-row:nth-child(5) { transform: translateX(170px); }
  .approach-carousel .approach-row:nth-child(6) { transform: translateX(260px); }
}
/* below 1081px the row is 1–2 columns wide, where left and right stop meaning
   anything — fall back to the sitewide rise */
@media (max-width: 1080px) {
  .approach-carousel .approach-row { transform: translateY(22px); }
}
/* mirrored stagger: each pair lands together, outermost first, so the movement
   resolves inward toward the point of the V */
.approach-carousel .approach-row:nth-child(1),
.approach-carousel .approach-row:nth-child(6) { transition-delay: 0s; }
.approach-carousel .approach-row:nth-child(2),
.approach-carousel .approach-row:nth-child(5) { transition-delay: .08s; }
.approach-carousel .approach-row:nth-child(3),
.approach-carousel .approach-row:nth-child(4) { transition-delay: .16s; }
/* the extra .approach-rows in the selector is deliberate: it lifts this to
   (0,4,0) so it outranks the nth-child offsets above (0,3,0) on specificity
   rather than on source order, which a later edit could quietly reverse */
.approach-carousel.is-in .approach-rows .approach-row { opacity: 1; transform: none; }
/* the hover lift is a transform too, so the rule above would otherwise cancel
   it — and the stagger delay has to come off as well, or a hover would idle up
   to 160ms before responding */
.approach-carousel.is-in .approach-rows .approach-row:hover {
  transform: translateY(-4px); transition-delay: 0s;
}
@media (prefers-reduced-motion: reduce) {
  .approach-carousel.reveal .approach-rows .approach-row {
    opacity: 1; transform: none; transition: none;
  }
}
/* The offsets above park the outer cards well past the container edge on the
   way in, which would otherwise scroll the whole page sideways. Clip on the
   wrapper rather than the section: the cards then emerge from the edge of the
   content column, which is the line the eye already reads as the page margin.
   overflow-x: clip, not hidden — clip creates no scroll container, so the
   vertical hover lift still overflows freely, and the clip margin keeps that
   card's shadow from being shaved off at rest. */
.approach-carousel {
  margin-top: 46px;
  overflow-x: hidden;      /* fallback */
  overflow-x: clip;
  overflow-clip-margin: 40px;
}
.approach-carousel .approach-rows { margin-top: 0; }

/* Delivery-approach "pipeline" — a horizontal connector line threading
   through 5 numbered nodes, each with its stage below (support-optimization
   page). Reads as an actual flow/process rather than a card grid. */
.approach-flow { position: relative; margin-top: 54px; }
.approach-flow::before {
  content: ''; position: absolute; top: 26px; left: 9%; right: 9%; height: 2px;
  background: var(--c-grad-violet); z-index: 0;
}
.approach-track { display: flex; gap: 0; text-align: center; }
.approach-step { flex: 1; position: relative; z-index: 1; padding: 0 14px; }
.approach-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: 50%; margin-bottom: 20px;
  background: var(--c-grad-violet); color: #fff; font-weight: 800; font-size: 17px;
  letter-spacing: -.02em; box-shadow: 0 10px 22px rgba(var(--c-shadow-rgb), .28);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.approach-step:hover .approach-num { transform: translateY(-5px) scale(1.08); box-shadow: 0 16px 30px rgba(var(--c-shadow-rgb), .36); }
.approach-step h4 { font-size: 19px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 10px; }
.approach-step p { font-size: 14.5px; line-height: 1.55; color: var(--c-body); }
.approach-dots { display: none; }

@media (max-width: 900px) {
  /* single-slide-at-a-time slider: plays through all 5 steps once as soon
     as it scrolls into view, then the user takes over with a swipe (see
     the JS in main.js) — dots below show position instead of the line */
  .approach-flow { overflow: hidden; margin-top: 34px; }
  .approach-flow::before { display: none; }
  .approach-track { transition: transform .5s var(--ease); }
  .approach-step { flex: 0 0 100%; padding: 0 6px; }
  .approach-dots { display: flex; justify-content: center; gap: 8px; margin-top: 26px; }
  .approach-dots span { width: 7px; height: 7px; border-radius: 50%; background: var(--c-line); transition: background .3s var(--ease), transform .3s var(--ease); }
  .approach-dots span.is-active { background: var(--c-blue); transform: scale(1.3); }
}
@media (max-width: 480px) {
  .approach-num { width: 44px; height: 44px; font-size: 15px; }
}

/* heading left, intro paragraph right, side by side instead of stacked.
   Fixed (non-fluid) sizes from 901px up so both the layout and the
   title/paragraph text-top alignment are pixel-identical on every
   laptop/desktop screen, not just visually close on some. */
.svc-dir-head--split { flex-direction: row; align-items: flex-start; justify-content: space-between; gap: 60px; }
.svc-dir-head--split .svc-title { flex: 0 1 460px; }
.svc-dir-head--split .intro { flex: 0 1 560px; }
@media (min-width: 901px) {
  .svc-dir-head--split h2 { font-size: 44px; }
  .svc-dir-head--split .intro { margin-top: -20px; }
  /* Cap-height alignment across the split head. The intro's first line starts
     ~39px below the container top (the 50px padding less the 20px above, plus
     half-leading); the 44px heading's cap starts at ~6px, so left the heading
     floats a third of a line above the paragraph it sits beside. Drop it by
     the difference so the two cap-heights read off one line.

     Scoped to .pg-services — services.html (all three split heads) and every
     services/ detail page, which all carry it. solutions.html is excluded,
     since its titles lead with an .eyebrow that already sits where the
     paragraph starts.

     Inside the 901px query deliberately: below it the head stacks vertically
     and the title belongs flush at the top. */
  .pg-services .svc-dir-head--split .svc-title { margin-top: 32px; }
}

@media (max-width: 900px) {
  .svc-dir-head { grid-template-columns: 1fr; gap: 16px; }
  .svc-dir-head h2 { font-size: clamp(34px, 8vw, 44px); }
  .svc-dir-head--split { flex-direction: column; gap: 16px; }
  .svc-dir-head--split .svc-title, .svc-dir-head--split .intro { flex: none; margin-top: 0; }
  .svc-cols { grid-template-columns: 1fr; gap: 0; margin-top: 30px; }
  .cat { grid-template-columns: 1fr 64px; gap: 16px; padding: 22px 0; }
  .cat-arrow { width: 64px; height: 52px; }
  .cat-arrow svg { width: 22px; height: 22px; }
  .svc-panel { padding: 2px 18px; margin-top: 8px; }
  .svc-photo { min-height: 220px; }
}

/* ============================================================
   TRANSPARENT HEADER OVER HERO  →  solid white after scroll-past
   (Header overlays the top hero image/video; turns white once the
    header crosses past the bottom of that hero. JS toggles
    .is-scrolled at the hero's bottom edge.)
   ============================================================ */
.site-header { position: fixed; left: 0; right: 0; background: transparent; border-bottom-color: transparent; }
.site-header .header-inner { position: relative; z-index: 2; }
.site-header::before {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, rgba(8,8,26,.46) 0%, rgba(8,8,26,.16) 58%, transparent 100%);
  opacity: 1; transition: opacity .3s var(--ease);
}
.site-header.is-scrolled { background: #fff; box-shadow: 0 6px 24px rgba(12,10,40,.07); border-bottom-color: var(--c-line); }
.site-header.is-scrolled::before { opacity: 0; }

/* over-hero (transparent) → light logo + nav */
.site-header:not(.is-scrolled) .brand,
.site-header:not(.is-scrolled) .brand-name,
.site-header:not(.is-scrolled) .brand-mark { color: #fff; }
body:not(.menu-open) .site-header:not(.is-scrolled) .brand-logo:not(.brand-badge) { filter: brightness(0) invert(1); }
.site-header:not(.is-scrolled) .nav-link { color: #fff; }
.site-header:not(.is-scrolled) .nav-link:hover { color: #fff; opacity: .8; }
.site-header:not(.is-scrolled) .nav-toggle span { background: #fff; }

/* mobile menu open → force solid so the white menu's links stay readable */
body.menu-open .site-header { background: #fff; }
body.menu-open .site-header::before { opacity: 0; }
body.menu-open .site-header .brand,
body.menu-open .site-header .brand-name,
body.menu-open .site-header .brand-mark { color: var(--c-ink); }
body.menu-open .site-header .brand-logo { filter: none; }
body.menu-open .site-header .nav-link { color: var(--c-ink); }
body.menu-open .site-header .nav-toggle span { background: var(--c-ink); }

/* ============================================================
   ============================================================
   IT-CONSULTING PAGE COMPONENTS
   (split CTA band, scope photo tiles, results carousel, blue
   "tech ecosystem" two-col + bubbles, why-list, 2-up case band)
   Built precisely from the full-page itransition IT-consulting ref.
   ============================================================
   ============================================================ */

/* ---------- Two-column section head (heading left / paragraph right) ---------- */
.lead-split { display: grid; grid-template-columns: 1.05fr 1fr; gap: 56px; align-items: start; margin-bottom: 44px; }
.lead-split h2 { font-size: clamp(34px, 4vw, 54px); font-weight: 800; letter-spacing: -.025em; line-height: 1.02; }
.lead-split .intro { font-size: 15.5px; line-height: 1.72; color: var(--c-body); padding-top: 6px; }
.psection--blue .lead-split .intro { color: rgba(255,255,255,.82); }
@media (max-width: 860px) { .lead-split { grid-template-columns: 1fr; gap: 16px; margin-bottom: 30px; } }

/* ---------- Split CTA band (navy text-block + solid magenta action) ---------- */
.cta-split {
  position: relative; color: #fff; overflow: hidden;
  background: linear-gradient(100deg, #161046 0%, #201962 100%);
  display: grid; grid-template-columns: 1fr clamp(260px, 30%, 432px); align-items: stretch;
}
.cta-split .csp-text {
  display: flex; flex-direction: column; justify-content: center; gap: 7px;
  padding-block: 30px; padding-right: 44px;
  padding-left: max(32px, calc((100vw - var(--container)) / 2 + 32px));
}
.cta-split .csp-text h2 { font-size: clamp(20px, 2.1vw, 27px); font-weight: 700; line-height: 1.2; letter-spacing: -.01em; max-width: 30ch; }
.cta-split .csp-text p { color: rgba(255,255,255,.74); font-size: 15px; }
.cta-split .csp-cta {
  background: #461ee8;
  display: flex; align-items: center; justify-content: center; gap: 14px;
  padding: 24px 32px; color: #fff; font-weight: 700; font-size: clamp(18px, 1.7vw, 25px);
  line-height: 1.15; text-align: center; transition: filter .2s var(--ease);
}
.cta-split .csp-cta:hover { filter: brightness(1.07); }
.cta-split .csp-cta svg { width: 26px; height: 26px; flex-shrink: 0; transition: transform .2s var(--ease); }
.cta-split .csp-cta:hover svg { transform: translateX(4px); }
@media (max-width: 760px) {
  .cta-split { grid-template-columns: 1fr; }
  .cta-split .csp-text { padding: 26px 24px; }
  .cta-split .csp-cta { padding: 20px 24px; justify-content: space-between; font-size: 20px; }
}

/* ---------- Scope card grid: photo tile fills a grid cell ---------- */
.cardgrid .card-photo { border-radius: var(--radius); background: var(--img) center/cover no-repeat, var(--c-dark); min-height: 182px; }

/* ---------- Driven by results — horizontal card carousel (flat cards) ---------- */
.results { position: relative; }
.results-track {
  display: grid; grid-auto-flow: column; grid-auto-columns: calc((100% - 48px) / 2.15); gap: 24px;
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; padding-bottom: 6px;
  -ms-overflow-style: none; scrollbar-width: none;
}
.results-track::-webkit-scrollbar { display: none; }
.rcard { scroll-snap-align: start; display: flex; flex-direction: column; }
.rmedia { min-height: 248px; background: var(--img) center/cover no-repeat, #d9d9e2; }
.rbar { height: 4px; background: var(--c-grad); }
.rbody { padding: 18px 0 0; display: flex; flex-direction: column; flex: 1; }
.rbody .rstat { font-size: clamp(34px, 3.4vw, 50px); font-weight: 800; letter-spacing: -.02em; line-height: 1; margin-bottom: 8px; }
.rbody h4 { font-size: 22px; font-weight: 700; line-height: 1.25; margin-bottom: 8px; letter-spacing: -.01em; }
.rbody p { font-size: 14.5px; color: var(--c-body); line-height: 1.55; flex: 1; max-width: 44ch; }
.rbody .link-arrow { margin-top: 14px; }
.results-nav { position: absolute; top: 0; left: -26px; right: -26px; height: 248px; display: flex; align-items: center; justify-content: space-between; pointer-events: none; }
.results-nav button {
  pointer-events: auto; width: 52px; height: 52px; border-radius: 999px; background: #e7e7ee;
  border: none; box-shadow: 0 6px 18px rgba(20,20,40,.10);
  display: flex; align-items: center; justify-content: center; color: var(--c-ink);
  transition: background .2s var(--ease), color .2s var(--ease);
}
.results-nav button:hover { background: var(--c-blue); color: #fff; }
.results-nav svg { width: 22px; height: 22px; }
@media (max-width: 1080px) { .results-track { grid-auto-columns: calc((100% - 24px) / 1.6); } .results-nav { left: -12px; right: -12px; } }
@media (max-width: 680px) { .results-track { grid-auto-columns: 86%; } .results-nav { display: none; } }

/* ---------- Blue "Transforming your tech ecosystem" section (flat royal blue) ---------- */
.psection--blue { color: #fff; background: linear-gradient(115deg, #2231c8 0%, #2942da 100%); }
.psection--blue .eyebrow { color: #c9d0ff; }
.psection--blue .stitle, .psection--blue h2, .psection--blue h3 { color: #fff; }
.eco-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; margin-top: 4px; }
.eco-col h3 { font-size: clamp(22px, 2.4vw, 30px); font-weight: 700; margin-bottom: 14px; letter-spacing: -.01em; }
.eco-col p { color: rgba(255,255,255,.8); font-size: 15px; line-height: 1.66; }
.eco-links { margin-top: 18px; display: flex; flex-wrap: wrap; gap: 10px; }
.eco-links a { font-size: 13.5px; font-weight: 600; color: #fff; border: 1px solid rgba(255,255,255,.34); border-radius: 999px; padding: 7px 15px; transition: background .2s var(--ease), border-color .2s var(--ease); }
.eco-links a:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.6); }
.bubbles { position: relative; min-height: 240px; margin-top: 22px; }
.bubble { position: absolute; border-radius: 999px; display: flex; align-items: center; justify-content: center; text-align: center; font-size: 12.5px; font-weight: 600; color: #fff; line-height: 1.25; padding: 10px; border: 1px solid rgba(255,255,255,.5); background: rgba(255,255,255,.10); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
@media (max-width: 860px) { .eco-grid { grid-template-columns: 1fr; gap: 36px; } .bubbles { min-height: 220px; } }

/* ---------- Why-list (definition rows under accented heading) ---------- */
.why-head { position: relative; padding-bottom: 20px; border-bottom: 1px solid var(--c-line); margin-bottom: 4px; }
.why-head::after { content: ""; position: absolute; left: 0; bottom: -2px; width: 128px; height: 3px; background: var(--c-grad); }
.why-head h2 { font-size: clamp(30px, 3.6vw, 46px); font-weight: 700; letter-spacing: -.02em; line-height: 1.06; }
.whyrow { display: grid; grid-template-columns: .92fr 1.6fr; gap: 48px; padding: 28px 2px; border-bottom: 1px solid var(--c-line); }
.whyrow h4 { font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.whyrow p { font-size: 15px; color: var(--c-body); line-height: 1.66; }
@media (max-width: 760px) { .whyrow { grid-template-columns: 1fr; gap: 8px; padding: 22px 2px; } }

/* ---------- 2-up Case-study band ---------- */
.case2 { display: grid; grid-template-columns: 1fr 1fr; }
.case-tile { position: relative; min-height: 340px; display: flex; overflow: hidden; color: #fff; transition: filter .2s var(--ease); }
.case-tile:hover { filter: brightness(1.05); }
.case-tile.blue { background: var(--c-blue-deep); }
.ct-photo { flex: 0 0 42%; background: var(--img) center/cover no-repeat, #1b1146; }
.ct-body { flex: 1; display: flex; flex-direction: column; justify-content: center; padding: 36px 38px; position: relative; z-index: 1; }
.case-tile.dark { background: var(--img) center/cover no-repeat, var(--c-dark); }
.case-tile.dark::before { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(11,10,40,.25), rgba(11,10,40,.82)); }
.case-tile.dark .ct-body { justify-content: flex-end; }
.ct-tag { font-size: 13px; font-weight: 600; opacity: .82; margin-bottom: 12px; }
.ct-body h3 { font-size: clamp(20px, 1.8vw, 26px); font-weight: 700; line-height: 1.22; letter-spacing: -.01em; }
.ct-body p { margin-top: 12px; font-size: 14px; line-height: 1.55; opacity: .86; max-width: 46ch; }
.ct-body .link-arrow { margin-top: 16px; color: #fff; }
.ct-body .link-arrow:hover svg { transform: translateX(4px); }
@media (max-width: 760px) { .case2 { grid-template-columns: 1fr; } .case-tile.blue { flex-direction: column; } .ct-photo { flex: 0 0 180px; } }

/* ---------- Contact form: attach-file row + help dot ---------- */
.cform-actions { display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap; margin-top: 6px; }
.cform-attach { display: inline-flex; align-items: center; gap: 12px; }
.btn-attach { border: 1px solid var(--c-line); color: var(--c-ink); }
.btn-attach:hover { border-color: var(--c-blue); color: var(--c-blue); }
.cform-help { width: 22px; height: 22px; border-radius: 999px; border: 1px solid var(--c-line); color: var(--c-muted); display: inline-flex; align-items: center; justify-content: center; font-size: 13px; }

/* ---------- Numbered list — magenta→blue accent above each row ---------- */
.numlist--accent .numrow { position: relative; }
.numlist--accent .numrow::before { content: ""; position: absolute; top: 0; left: 0; width: 116px; height: 2px; background: var(--c-grad); }

/* ---------- Centered photo hero: title sits in the lower third ---------- */
.phero--center { align-items: flex-end; }
.phero--center .container { padding-block: 110px 56px; }
.pg-service-detail .phero--center .container { padding-block: 110px 120px; }

/* ============================================================
   INDUSTRIES DIRECTORY  (industry blocks: heading + magenta
   arrow + description + wrapped sub-link tag cloud; alternating
   white / blue panel / full-bleed photo split treatments).
   Namespaced .idir-* so it never collides with the home .ind
   expanding-slider. Built from the itransition Industries ref.
   ============================================================ */
.idir-title { display: flex; align-items: center; gap: 16px; }
.idir-title h2 { font-size: clamp(30px, 3.4vw, 44px); font-weight: 800; letter-spacing: -.025em; line-height: 1.0; }
.idir-arrow { color: var(--c-accent); flex-shrink: 0; display: inline-flex; transition: transform .2s var(--ease); }
.idir-arrow svg { width: 30px; height: 30px; }
.idir-arrow:hover { transform: translateX(4px); }
.idir-desc { font-size: 15px; line-height: 1.7; color: var(--c-body); }
.idir-tags { display: flex; flex-wrap: wrap; gap: 13px 28px; }
.idir-tags a { font-size: 16px; color: var(--c-body); line-height: 1.3; transition: color .15s var(--ease); }
.idir-tags a:hover { color: var(--c-accent); }

/* full-width white industry block (heading | description, then tags) */
.idir-sec { padding-block: 56px; }
.idir-head { display: grid; grid-template-columns: 1fr 1fr; gap: 50px; align-items: start; margin-bottom: 28px; }
.idir-head .idir-title { align-self: start; }
@media (max-width: 860px) { .idir-head { grid-template-columns: 1fr; gap: 14px; } }

/* full-bleed 2-col split (photo / content pane) */
.idir-split { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; }
.idir-photo { background: var(--img) center/cover no-repeat, var(--c-dark); min-height: 400px; }
.idir-pane { display: flex; flex-direction: column; justify-content: center; padding: 60px 48px; }
.idir-split > .idir-pane:first-child { padding-left: max(48px, calc((100vw - var(--container)) / 2 + 32px)); }
.idir-split > .idir-pane:last-child { padding-right: max(48px, calc((100vw - var(--container)) / 2 + 32px)); }
.idir-pane .idir-title { margin-bottom: 18px; }
.idir-pane .idir-desc { max-width: 52ch; margin-bottom: 22px; }
.idir-pane.is-blue { background: var(--c-blue-deep); color: #fff; }
.idir-pane.is-blue h2 { color: #fff; }
.idir-pane.is-blue .idir-desc { color: rgba(255,255,255,.82); }
.idir-pane.is-blue .idir-tags a { color: rgba(255,255,255,.82); }
.idir-pane.is-blue .idir-tags a:hover { color: #fff; }

/* full-width blue band (e.g. Construction) */
.idir-band-blue { background: var(--c-blue-deep); color: #fff; padding-block: 56px; }
.idir-band-blue h2 { color: #fff; }
.idir-band-blue .idir-head { margin-bottom: 24px; }
.idir-band-blue .idir-desc { color: rgba(255,255,255,.82); }
.idir-band-blue .idir-tags a { color: rgba(255,255,255,.82); }
.idir-band-blue .idir-tags a:hover { color: #fff; }

@media (max-width: 860px) {
  .idir-split { grid-template-columns: 1fr; }
  .idir-photo { min-height: 240px; }
  .idir-pane, .idir-split > .idir-pane:first-child, .idir-split > .idir-pane:last-child { padding: 40px 24px; }
}

/* ============================================================
   MANUFACTURING — article-style industry page (purple accent)
   Left hero + date + byline + TOC, horizontal/vertical tab
   explorers, purple/teal split CTA, platforms logo row,
   services accordion w/ purple feature panel, about facts,
   insights/case bento (purple), more-about link columns.
   ============================================================ */

/* page-scoped purple accent (remaps the blue token for this page) */

/* left hero with date subtitle */
.phero .pdate { margin-top: 14px; font-size: 14px; font-weight: 600; color: rgba(255,255,255,.86); }
.phero--article h1 { max-width: 26ch; }

/* article intro: byline + intro + table of contents */
.artintro { display: grid; grid-template-columns: 1.55fr 1fr; gap: 60px; align-items: start; }
.byline { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.byline .avatar { width: 40px; height: 40px; border-radius: 999px; background: var(--img) center/cover no-repeat, var(--c-surface-2); flex-shrink: 0; }
.byline b { font-weight: 700; font-size: 14px; }
.byline span { color: var(--c-muted); font-size: 14px; }
.toc { border-left: 1px solid var(--c-line); padding-left: 32px; }
.toc h4 { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--c-muted); margin-bottom: 18px; }
.toc ul { columns: 2; column-gap: 28px; }
.toc li { margin-bottom: 13px; break-inside: avoid; }
.toc a { font-size: 14.5px; color: var(--c-ink); font-weight: 500; }
.toc a:hover { color: var(--c-blue); }
@media (max-width: 900px) { .artintro { grid-template-columns: 1fr; gap: 30px; } .toc { border-left: none; padding-left: 0; } }

/* horizontal tab explorer (Solutions we deliver / Industry 4.0) */
.htabs { display: flex; flex-wrap: wrap; gap: 4px 16px; border-bottom: 1px solid var(--c-line); margin-bottom: 34px; }
.htab { position: relative; padding: 14px 4px 16px; font-size: 17px; font-weight: 600; color: var(--c-body); cursor: pointer; }
.htab:hover, .htab.is-active { color: var(--c-ink); }
.htab::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 3px; background: var(--c-grad); transform: scaleX(0); transform-origin: left; transition: transform .25s var(--ease); }
.htab.is-active::after { transform: scaleX(1); }
.htab-panel[hidden] { display: none; }
.htab-panel h3 { font-size: clamp(24px, 2.6vw, 32px); font-weight: 700; letter-spacing: -.01em; margin-bottom: 14px; }
.htab-panel .lead2 { font-size: 15px; line-height: 1.7; color: var(--c-body); max-width: 60ch; margin-bottom: 22px; }

/* two-column magenta-dot bullet list */
.bullets { display: grid; grid-template-columns: 1fr 1fr; gap: 11px 40px; }
.bullets li { position: relative; padding-left: 20px; font-size: 14.5px; color: var(--c-body); line-height: 1.5; }
.bullets li::before { content: ""; position: absolute; left: 0; top: 8px; width: 7px; height: 7px; border-radius: 2px; background: var(--c-grad); }
@media (max-width: 760px) { .bullets { grid-template-columns: 1fr; } }

/* split CTA colour variants (purple body + teal action) */
.cta-split--purple { background: linear-gradient(100deg, #4a1d8f 0%, #6c2bd9 100%); }
.csp-cta--teal { background: #0e9c9c; }

/* platforms logo row */
.logo-row { display: flex; flex-wrap: wrap; align-items: center; gap: 34px 64px; margin-top: 8px; }
.plogo { font-size: 24px; font-weight: 800; letter-spacing: -.02em; color: #aeaeba; -webkit-user-select: none; user-select: none; }

/* services accordion + purple feature panel */
.svc-acc { display: grid; grid-template-columns: .92fr 1.08fr; gap: 48px; align-items: start; }
.feature-purple { border-radius: 14px; overflow: hidden; }
.feature-purple .fp-top { background: linear-gradient(135deg, #5a23b8, #6c2bd9); color: #fff; padding: 42px 36px; }
.feature-purple .fp-top h2 { font-size: clamp(28px, 3vw, 40px); font-weight: 700; letter-spacing: -.02em; line-height: 1.05; }
.feature-purple .fp-photo { min-height: 280px; background: var(--img) center/cover no-repeat, var(--c-dark); }
@media (max-width: 900px) { .svc-acc { grid-template-columns: 1fr; gap: 28px; } }

/* security side-nav (vertical tabs) */
.vtabs-wrap { display: grid; grid-template-columns: 210px 1fr; gap: 48px; align-items: start; }
.vtabs { display: flex; flex-direction: column; border-left: 2px solid var(--c-line); }
.vtab { text-align: left; padding: 12px 18px; font-size: 17px; font-weight: 600; color: var(--c-body); border-left: 2px solid transparent; margin-left: -2px; cursor: pointer; }
.vtab.is-active { color: var(--c-ink); border-left-color: var(--c-blue); }
@media (max-width: 760px) {
  .vtabs-wrap { grid-template-columns: 1fr; gap: 24px; }
  .vtabs { flex-direction: row; border-left: none; border-bottom: 2px solid var(--c-line); }
  .vtab { border-left: none; border-bottom: 2px solid transparent; margin-left: 0; margin-bottom: -2px; }
  .vtab.is-active { border-bottom-color: var(--c-blue); }
}

/* about facts (2-col, hairline-separated) */
.facts { display: grid; grid-template-columns: 1fr 1fr; gap: 0 64px; }
.fact { padding: 22px 0; border-top: 1px solid var(--c-line); font-size: 15px; line-height: 1.5; color: var(--c-body); }
.fact b { color: var(--c-ink); font-weight: 700; }
@media (max-width: 760px) { .facts { grid-template-columns: 1fr; } }


/* more-about link columns */
.morelinks { display: grid; grid-template-columns: 1.4fr 1fr; gap: 50px; }
.morelinks h4 { font-size: 18px; font-weight: 700; color: var(--c-muted); margin-bottom: 18px; }
.morelinks .ml { display: flex; flex-wrap: wrap; gap: 14px 26px; }
.morelinks .ml a { font-size: 17px; font-weight: 700; color: var(--c-ink); letter-spacing: -.01em; }
.morelinks .ml a:hover { color: var(--c-blue); }
@media (max-width: 760px) { .morelinks { grid-template-columns: 1fr; gap: 30px; } }

/* ============================================================
   ERP / Solution detail page (erp.html / s4hana.html)
   ============================================================ */
/* services-offered grid: top-accent cells, hairlines, orange arrow box */
.erp-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 56px; }
.erp-card { position: relative; display: flex; flex-direction: column; padding: 30px 0 36px; border-top: 1px solid var(--c-line); }
.erp-card::before { content: ""; position: absolute; top: -1px; left: 0; width: 76px; height: 3px; background: var(--c-grad); }
.erp-card h3 { font-size: 22px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 12px; }
.erp-card p { font-size: 15px; line-height: 1.6; color: var(--c-body); flex: 1; }
.erp-card .erp-go { align-self: flex-start; margin-top: 22px; width: 46px; height: 46px; border: 1px solid var(--c-line); display: inline-flex; align-items: center; justify-content: center; color: #f5821f; transition: background .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease); }
.erp-card .erp-go svg { width: 20px; height: 20px; }
.erp-card:hover .erp-go { background: #f5821f; border-color: #f5821f; color: #fff; }
@media (max-width: 980px) { .erp-cards { grid-template-columns: 1fr 1fr; gap: 0 40px; } }
@media (max-width: 640px) { .erp-cards { grid-template-columns: 1fr; } }

/* capability rows: name + description, hairlines, gradient top rule */
.cap-rule { height: 2px; background: var(--c-grad); margin-bottom: 4px; }
.caprow { display: grid; grid-template-columns: .82fr 1.7fr; gap: 48px; padding: 24px 0; border-bottom: 1px solid var(--c-line); align-items: start; }
.caprow h3 { font-size: 19px; font-weight: 700; letter-spacing: -.01em; display: flex; align-items: center; gap: 14px; }
.caprow h3 .cap-go { color: #f5821f; flex-shrink: 0; display: inline-flex; }
.caprow h3 .cap-go svg { width: 20px; height: 20px; }
.caprow p { font-size: 15px; line-height: 1.6; color: var(--c-body); }
@media (max-width: 760px) { .caprow { grid-template-columns: 1fr; gap: 8px; } }

/* magenta implementation roadmap (numbered steps on magenta) */
.roadmap { display: grid; grid-template-columns: repeat(3, 1fr); gap: 34px 56px; margin-top: 36px; }
.road-step { position: relative; padding-top: 22px; border-top: 1px dashed rgba(255,255,255,.32); }
.road-step .rs-n { font-size: 22px; font-weight: 800; color: #f5a623; margin-bottom: 12px; }
.road-step h3 { font-size: 18px; font-weight: 700; color: #fff; margin-bottom: 10px; letter-spacing: -.01em; }
.road-step p { font-size: 14px; line-height: 1.6; color: rgba(255,255,255,.82); }
@media (max-width: 900px) { .roadmap { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px) { .roadmap { grid-template-columns: 1fr; } }

/* platform tab detail: title + logo, then info columns */
.plat-top { display: grid; grid-template-columns: 1.5fr 1fr; gap: 40px; align-items: start; margin-bottom: 28px; }
.plat-top h3 { display: flex; align-items: center; gap: 14px; }
.plat-logo { justify-self: end; text-align: right; font-size: 24px; font-weight: 800; letter-spacing: -.02em; color: #aeaeba; line-height: 1.2; }
.plat-cols { display: grid; grid-template-columns: 1.7fr 1fr 1fr; gap: 40px; border-top: 1px solid var(--c-line); padding-top: 26px; }
.plat-col h5 { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 700; color: var(--c-ink); margin-bottom: 14px; }
.plat-col .feat2 { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 24px; }
.plat-col p, .plat-col li { font-size: 14px; line-height: 1.5; color: var(--c-body); }
.plat-col ul { display: grid; gap: 8px; }
@media (max-width: 900px) { .plat-top, .plat-cols { grid-template-columns: 1fr; } .plat-logo { justify-self: start; text-align: left; } .plat-col .feat2 { grid-template-columns: 1fr 1fr; } }

/* split CTA — magenta body + orange action (ERP / solution pages) */
.cta-split--magenta { background: linear-gradient(100deg, #26146d 0%, #270e8a 100%); }
.csp-cta--orange { background: #e8821e; }

/* ============================================================
   Case studies — portfolio masonry + filter bar (case-studies.html)
   ============================================================ */
.cs-top { padding-top: 104px; }
.cs-title { font-size: clamp(38px, 5vw, 60px); font-weight: 800; letter-spacing: -.02em; line-height: 1.02; margin-bottom: 26px; }

/* category tabs — plain words, the active one carries the accent. No rule
   under the row and no underline bar: the chip row below is the visual
   boundary, and a second horizontal line competed with it. */
.cs-filter-cats { display: flex; flex-wrap: wrap; gap: 14px 34px; margin-bottom: 22px; }
.cs-cat { position: relative; background: none; border: none; padding: 0; font-size: clamp(16px, 1.7vw, 20px); font-weight: 700; color: var(--c-ink); cursor: pointer; letter-spacing: -.01em; transition: color .18s var(--ease); }
.cs-cat:hover { color: var(--c-accent); }
.cs-cat.is-active { color: var(--c-accent); }
.cs-chipset[hidden] { display: none; }
.cs-chips { display: flex; flex-wrap: wrap; gap: 8px; }

/* chips are filled tiles, not text links — a tap target with an obvious
   selected state, since these now drive the grid rather than decorate it */
.cs-chip {
  border: none; border-radius: 0; padding: 6px 11px;
  background: rgba(0,0,0,.03); color: var(--c-body);
  font-size: 14px; font-weight: 400; line-height: 1.45; cursor: pointer;
  transition: background-color .18s var(--ease), color .18s var(--ease);
}
.cs-chip:hover { background: rgba(0,0,0,.06); color: var(--c-ink); }

/* ------------------------------------------------------------------
   PORTFOLIO MOSAIC
   A seamless quilt: no gutters anywhere, tiles butting straight up
   against each other. Every card carries the same markup (.cs-img +
   .cs-body); which shape it takes is decided by main.js from its
   position in the *filtered* list, not baked into the card. That is
   what keeps the mosaic whole after a filter — bake the variants in
   and the first filter punches holes in it.

   The rhythm repeats every four tiles:
     0 → full-width band, image one side, copy the other
     1 → third-width, copy on top, image below
     2 → third-width, image on top, copy below
     3 → third-width, copy on top, image below
   Alternating 1/2/3 that way is what makes the columns interlock
   instead of reading as three separate stacks.
   ------------------------------------------------------------------ */
/* --cols is the single source of truth for how wide the grid runs. The media
   queries below move it, the tile widths derive from it, and main.js reads it
   back so its cycle length matches. Keeping the count in one place is what
   stops the tablet width from ending a row one tile short — the JS used to
   assume three regardless and left a hole at every breakpoint but the widest. */
/* the quilt rounds as ONE block (14px, the sitewide card radius) — tiles are
   flush inside it, so per-tile rounding would notch every interior join */
.cs-mosaic { --cols: 3; --tile-h: 660px; display: flex; flex-wrap: wrap; align-items: stretch; margin-top: 6px; border-radius: 14px; overflow: hidden; }
/* the insights/case-studies band every page carries (owner call 2026-08-05:
   the band IS the case-studies quilt — wide photo+text pair on top, three
   tall stacked tiles below; tiles flush, block contained) */
.cs-mosaic--band { margin-top: 28px; }
/* the band's two-colour pair: the wide panel is the dark (--c-tile-navy,
   family deep on family pages) and the middle tall tile's text half is the
   vivid — home royal, family primary via the bridge */
.cs-mosaic--band .cs-tile--vivid .cs-body { background: var(--c-blue-royal); color: #fff; }
.cs-mosaic--band .cs-tile--vivid .cs-body p { color: rgba(255,255,255,.82); }
.cs-mosaic--band .cs-tile--vivid .cs-kicker { color: rgba(255,255,255,.72); }
.cs-mosaic .cs-tile { display: flex; overflow: hidden; color: var(--c-ink); background: #fff; }

/* the image is a fixed frame; the thing that scales on hover is inside it,
   so the tile edges stay put and only the picture moves */
.cs-tile .cs-img { position: relative; overflow: hidden; background: var(--c-surface-2); flex: none; }
.cs-tile .cs-img::after {
  content: ""; position: absolute; inset: 0;
  background: var(--img) center/cover no-repeat;
  transition: transform 1s var(--ease);
}
.cs-tile:hover .cs-img::after { transform: scale(1.08); }
.cs-tile:hover h3 { text-decoration: underline; text-underline-offset: 3px; }

.cs-tile .cs-body { padding: 36px; display: flex; flex-direction: column; justify-content: center; overflow: hidden; }
.cs-tile h3 { font-size: 24px; font-weight: 800; line-height: 1.25; letter-spacing: -.01em; margin-bottom: 12px; }
.cs-tile p { font-size: 15px; line-height: 1.6; color: var(--c-body); }

/* The copy on each tile is written to fit the half it sits in, so these
   should never actually bite. They are here so that an editor adding a
   longer headline later gets a clean truncation instead of text running out
   through the bottom of a fixed-height tile. */
.cs-tile h3 { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.cs-tile--tall p { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
/* Tiles carrying a meta strip still have room for a fourth line — measured at
   258px of content space against 214px used, so the earlier 3-line limit was
   clipping copy that fitted perfectly well. */
.cs-tile--tall .cs-body:has(.cs-meta) p { -webkit-line-clamp: 4; }
.cs-tile--wide p { display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }

/* --- full-width band (every 4th tile) --- */
/* A band is exactly as tall as one half of a tall tile, so bands and tiles
   share a single vertical rhythm and every band matches every other band.
   With min-height the bands grew to their own copy and no two were alike. */
.cs-tile--wide { width: 100%; flex-direction: row; height: calc(var(--tile-h) / 2); }
.cs-tile--wide .cs-img { width: 50%; }
.cs-tile--wide .cs-body { width: 50%; }
.cs-tile--wide.is-flip { flex-direction: row-reverse; }

/* --- third-width tile --- */
/* calc, not 33.3333% — the decimal left a 0.02px sliver of page background
   showing at the right edge of every full row, and the whole point of this
   grid is that no background shows through it */
.cs-tile--tall { width: calc(100% / var(--cols)); flex-direction: column; height: var(--tile-h); }

/* Fixed height, and the picture takes exactly half of it.

   Letting the image absorb the leftover space (flex:1) meant its height was
   set by however long that tile's copy ran, so the image/copy seam landed at
   a different place in every column and the rows read as ragged. Splitting
   the tile down the middle puts every seam on the same line: the checkerboard
   then comes from which half is on top, which is the point, rather than from
   tiles being different shapes. */
.cs-tile--tall .cs-img { flex: none; height: calc(var(--tile-h) / 2); width: 100%; }
.cs-tile--tall .cs-body { flex: none; height: calc(var(--tile-h) / 2); }
.cs-tile--tall.is-flip { flex-direction: column-reverse; }
/* the last row rarely divides by three. Rather than leave a hole in a quilt
   whose whole point is that it has no holes, the one or two tiles left over
   share the row between them.

   The basis has to stay a full column, not 0: with a zero basis these fit on
   the preceding full-width band's flex line instead of wrapping past it, and
   collapsed to nothing because that line had no free space left to grow into.
   A column's width guarantees the wrap, and grow then divides the new line
   evenly. Deriving it from --cols also keeps this rule — two classes, so it
   outranks the plain width above — correct at every breakpoint. */
.cs-tile--tall.is-fill { width: auto; flex: 1 1 calc(100% / var(--cols)); }

/* --- surfaces ---
   scoped under .cs-mosaic to match the specificity of the base .cs-tile rule
   above; as bare single-class selectors they lost the background to it */
.cs-mosaic .cs-tile--tint { background: #f8f8f8; }
/* owner call 2026-08-05: blue tiles stay blue; the near-black navy is
   replaced by the reference tile navy (--c-tile-navy) */
.cs-mosaic .cs-tile--dark { background: var(--c-tile-navy); color: #fff; }
.cs-mosaic .cs-tile--blue { background: var(--c-blue-deep); color: #fff; }
.cs-mosaic .cs-tile--dark p, .cs-mosaic .cs-tile--blue p { color: rgba(255,255,255,.82); }

/* Below three columns the interlock has nothing to interlock with, so the
   tiles become plain stacked cards — image on top either way. Keeping
   column-reverse here would leave copy stranded above an image with no
   neighbouring column to answer it. */
/* ---------- related case studies, foot of a detail page ----------
   The same tile as the portfolio grid rather than a second, bordered card
   style, so a reader meets one case-study card design across the whole site.
   itransition does the same thing: their "Related cases" strip reuses the
   portfolio tile rather than inventing a card for it.

   Always exactly three, so the interlock (low / high / low) is written into
   the markup — main.js only deals variants on the filtered listing page, and
   there is no filter here. */
.cs-mosaic--related { --tile-h: 600px; }

@media (max-width: 1080px) {
  /* wider column, so the same copy needs fewer lines and the tile can lose
     some height without the text getting closer to its clamp */
  .cs-mosaic { --cols: 2; --tile-h: 600px; }
  /* three tiles across two columns would leave the second row half empty,
     and there is no JS here to redistribute them — so stack instead */
  .cs-mosaic--related { --cols: 1; --tile-h: 560px; }
  .cs-mosaic--related .cs-tile--tall.is-flip { flex-direction: column; }
}
@media (max-width: 760px) {
  .cs-mosaic { --cols: 1; --tile-h: 580px; }
  /* the band stacks here, so image and copy each need their own room —
     a half-tile height would crush them together */
  .cs-tile--wide { width: 100%; height: var(--tile-h); }
  .cs-tile--wide, .cs-tile--wide.is-flip { flex-direction: column; }
  .cs-tile--tall.is-flip { flex-direction: column; }
  .cs-tile--wide .cs-img, .cs-tile--wide .cs-body { width: 100%; }
  .cs-tile--wide .cs-img { min-height: 240px; }
  .cs-tile .cs-body { padding: 28px 24px; }
  .cs-tile h3 { font-size: 21px; }
}

/* ============================================================
   Company / About page (company.html)
   ============================================================ */
.head-arrow--mag { color: var(--c-accent); }
.head-arrow--mag:hover { background: var(--c-accent); border-color: var(--c-accent); color: #fff; }

/* blue full section + arrow colour inside */
.psection--blue { background: var(--c-blue-deep); color: #fff; }
.psection--blue .stitle, .psection--blue h2 { color: #fff; }
.psection--blue p { color: rgba(255,255,255,.82); }

/* two-column block (heading | content) */
.about-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }
@media (max-width: 860px) { .about-2col { grid-template-columns: 1fr; gap: 30px; } }

/* mission quote (borderless, with avatar) */
.about-quote .mark { font-size: 44px; line-height: .5; color: var(--c-accent); font-weight: 800; }
.about-quote .qt { font-size: clamp(17px, 1.7vw, 20px); color: var(--c-ink); line-height: 1.55; margin: 8px 0 22px; font-weight: 500; }
.about-quote .who { display: flex; align-items: center; gap: 14px; }
.about-quote .who .avatar { width: 46px; height: 46px; border-radius: 999px; background: var(--img) center/cover no-repeat, var(--c-surface-2); flex-shrink: 0; }
.about-quote .who b { font-size: 15px; font-weight: 700; display: block; }
.about-quote .who span { font-size: 13px; color: var(--c-muted); }

/* stat grid — gradient top rule (talent pool / differentiators) */
.statgrid { display: grid; gap: 34px 40px; }
.statgrid--3 { grid-template-columns: repeat(3, 1fr); }
.statgrid--4 { grid-template-columns: repeat(4, 1fr); }
.stat { padding-top: 16px; border-top: 2px solid; border-image: var(--c-grad) 1; }
.stat .s-num { font-size: clamp(22px, 2.3vw, 30px); font-weight: 900; letter-spacing: -.01em; margin-bottom: 8px; }
.stat .s-label { font-size: 14px; font-weight: 300; line-height: 1.5; color: var(--c-body); }
.psection--blue .stat .s-num { color: #fff; }
.psection--blue .stat .s-label { color: rgba(255,255,255,.78); }
@media (max-width: 760px) { .statgrid--3, .statgrid--4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 460px) { .statgrid--3, .statgrid--4 { grid-template-columns: 1fr; } }

/* logo wall — grayscale text logos */
.logo-wall { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px 30px; align-items: center; }
.logo-wall .plogo { font-size: 18px; }
.logo-wall.on-blue .plogo { color: rgba(255,255,255,.6); }
@media (max-width: 560px) { .logo-wall { grid-template-columns: repeat(2, 1fr); } }
/* 5-across variant (client roster). Was an inline style on the element, which
   beat every media query below and forced 5 columns onto phones — the tracks
   then blew out to min-content and scrolled the whole page sideways. */
.logo-wall--5 { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 860px) { .logo-wall--5 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 560px) { .logo-wall--5 { grid-template-columns: repeat(2, 1fr); } }

/* values list (Commitment / Excellence / Passion / Clarity) */
.values-list { display: grid; gap: 26px; }
.values-list h3 { font-size: 24px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 8px; }
.values-list p { font-size: 14.5px; line-height: 1.6; color: var(--c-body); }

/* customer quotes — 3-col borderless */
.cust-quotes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px 36px; }
.cust-quote .mark { font-size: 40px; line-height: .5; color: var(--c-accent); font-weight: 800; }
.cust-quote p { font-size: 14px; line-height: 1.6; color: var(--c-ink); margin: 10px 0 14px; }
.cust-quote .readorig { color: #3917c0; font-weight: 600; font-size: 13px; }
.cust-quote .who { margin-top: 14px; font-size: 14px; font-weight: 700; }
.cust-quote .who span { display: block; font-weight: 500; color: var(--c-muted); font-size: 13px; margin-top: 2px; }
@media (max-width: 900px) { .cust-quotes { grid-template-columns: 1fr; } }

/* full-bleed split (image | colour pane) */
.split-bleed { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; }
.split-bleed .sb-col { display: flex; flex-direction: column; }
.split-bleed .sb-img { background: var(--img) center/cover no-repeat, var(--c-surface-2); min-height: 300px; flex: 1; }
.split-bleed .sb-pane { padding: clamp(40px, 6vw, 80px) clamp(28px, 5vw, 64px); display: flex; flex-direction: column; justify-content: center; }
.split-bleed .sb-pane--gray { background: var(--c-surface-2); }
.split-bleed .sb-pane--blue { background: var(--c-blue-deep); color: #fff; }
.split-bleed .sb-pane h2, .split-bleed .sb-pane h3 { font-size: clamp(26px, 3vw, 38px); font-weight: 700; letter-spacing: -.02em; line-height: 1.12; }
.split-bleed .sb-pane--blue .industries-bold { font-size: clamp(18px, 1.9vw, 22px); font-weight: 700; line-height: 1.7; }
.split-bleed .sb-pane--blue .industries-rest a, .split-bleed .sb-pane--blue .industries-bold a { color: #fff; }
@media (max-width: 760px) { .split-bleed { grid-template-columns: 1fr; } .split-bleed .sb-img { min-height: 240px; } }

/* ============================================================
   Careers page (career.html) — open positions list
   ============================================================ */
.job-list { border-top: 1px solid var(--c-line); margin-top: 8px; }
.job-row { display: grid; grid-template-columns: 1.7fr 1fr 84px; gap: 24px; align-items: center; padding: 22px 4px; border-bottom: 1px solid var(--c-line); transition: background .2s var(--ease); }
.job-row:hover { background: var(--c-surface-2); }
.job-row h3 { font-size: 19px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; }
.job-row .job-meta { font-size: 14px; color: var(--c-body); display: flex; flex-wrap: wrap; gap: 6px 16px; }
.job-row .job-meta span { white-space: nowrap; }
.job-row .cat-arrow { justify-self: end; }
@media (max-width: 700px) { .job-row { grid-template-columns: 1fr 64px; } .job-row .job-meta { grid-column: 1; } }

/* ---- Careers sub-site (career.html, itransition-style) ---- */
/* hero job-search bar */
.career-hero { position: relative; min-height: 460px; display: flex; align-items: flex-end; overflow: hidden; }
.career-hero .ch-bg { position: absolute; inset: 0; background: var(--img) center/cover no-repeat, var(--c-dark); }
.career-hero .ch-bg::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(11,10,40,.35) 0%, rgba(11,10,40,.2) 40%, rgba(11,10,40,.72) 100%); }
.career-hero .container { position: relative; z-index: 2; padding-bottom: 0; }
.career-hero h1 { color: #fff; font-size: clamp(34px, 5vw, 60px); font-weight: 800; letter-spacing: -.02em; line-height: 1.02; margin-bottom: 26px; }
.job-search { display: grid; grid-template-columns: 1.5fr 1fr 1fr auto; background: rgba(20,18,40,.55); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); border: 1px solid rgba(255,255,255,.18); border-radius: 14px; overflow: hidden; }
.job-search .js-field { display: flex; align-items: center; padding: 0 18px; border-right: 1px solid rgba(255,255,255,.16); position: relative; }
.job-search input, .job-search select { width: 100%; background: transparent; border: none; color: #fff; font-size: 15px; font-family: inherit; height: 64px; outline: none; -webkit-appearance: none; appearance: none; cursor: pointer; }
.job-search input { cursor: text; }
.job-search input::placeholder { color: rgba(255,255,255,.7); }
.job-search select option { color: #14141c; }
.job-search .js-field--sel::after { content: ""; position: absolute; right: 16px; top: 50%; width: 9px; height: 9px; border-right: 2px solid #806bd3; border-bottom: 2px solid #806bd3; transform: translateY(-65%) rotate(45deg); pointer-events: none; }
.job-search .js-btn { display: flex; align-items: center; justify-content: center; gap: 12px; background: var(--c-accent); color: #fff; border: none; font-weight: 700; font-size: 17px; padding: 0 40px; cursor: pointer; transition: filter .2s var(--ease); }
.job-search .js-btn:hover { filter: brightness(1.07); }
.job-search .js-btn svg { width: 20px; height: 20px; }
@media (max-width: 820px) { .job-search { grid-template-columns: 1fr; } .job-search .js-field { border-right: none; border-bottom: 1px solid rgba(255,255,255,.16); } .job-search .js-btn { padding: 16px; } }

/* magenta full-bleed pane (dual CTA) */
.split-bleed .sb-pane--magenta { background: var(--c-accent); color: #fff; }
.cta-duo { display: flex; flex-direction: column; }
.cta-duo a { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: clamp(26px,3vw,40px) clamp(28px,4vw,48px); color: #fff; font-size: clamp(19px,2vw,26px); font-weight: 700; letter-spacing: -.01em; transition: filter .2s var(--ease); }
.cta-duo a:hover { filter: brightness(1.08); }
.cta-duo a svg { width: 26px; height: 26px; flex-shrink: 0; transition: transform .2s var(--ease); }
.cta-duo a:hover svg { transform: translateX(5px); }
.cta-duo .duo-mag { background: var(--c-accent); }
.cta-duo .duo-blue { background: var(--c-blue-deep); }

/* selected projects */
.proj-tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 16px; }
.proj-tag { font-size: 13px; font-weight: 600; color: var(--c-body); background: var(--c-surface-2); border-radius: 999px; padding: 5px 14px; }
.proj-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px 48px; margin-top: 18px; }
.proj-card { border-bottom: 1px solid var(--c-line); padding-bottom: 26px; }
.proj-card h3 { font-size: 20px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 4px; }
.proj-card p { font-size: 14px; line-height: 1.6; color: var(--c-body); }
.proj-card .cat-arrow { margin-top: 16px; }
@media (max-width: 820px) { .proj-grid { grid-template-columns: 1fr; } }

/* benefits blue 2-col blurbs */
.ben-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px 48px; margin-top: 8px; }
.ben-grid p { color: rgba(255,255,255,.82); font-size: 15px; line-height: 1.6; }
.ben-grid p b { color: #fff; font-weight: 700; }
@media (max-width: 760px) { .ben-grid { grid-template-columns: 1fr; } }

/* ============================================================
   Contact page (contact.html) — Our offices grid
   ============================================================ */
.contact-intro { display: grid; grid-template-columns: 1.3fr 1fr; gap: 40px; margin-bottom: 40px; }
.contact-intro p { font-size: 15px; line-height: 1.6; color: var(--c-body); }
.contact-intro a { color: var(--c-blue); font-weight: 600; }
@media (max-width: 760px) { .contact-intro { grid-template-columns: 1fr; gap: 14px; margin-bottom: 30px; } }

.contact-offices { display: grid; grid-template-columns: repeat(4, 1fr); gap: 44px 28px; }
.off-card .off-country { font-size: 19px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 16px; }
.off-card .off-img { aspect-ratio: 16 / 10; background: var(--img) center/cover no-repeat, var(--c-surface-2); border-radius: 14px; margin-bottom: 16px; }
.off-card .off-city { font-size: 16px; font-weight: 700; margin-bottom: 8px; }
.off-card .off-addr { font-size: 14px; color: var(--c-body); line-height: 1.5; }
.off-card .off-phone { font-size: 14px; font-weight: 600; color: var(--c-ink); margin-top: 12px; }
.off-card .off-note { font-size: 13px; color: var(--c-muted); margin-top: 2px; }
@media (max-width: 1000px) { .contact-offices { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Desktop size freeze ----------
   Headings/spacing above use clamp(min, Xvw, max) so they scale fluidly with
   the viewport. .container itself stops growing at 1240px (--container), but
   several clamp()s don't reach their own max until well past that point —
   so a 1366-1440px laptop shows visibly smaller type/padding than a 1920-2560px
   monitor even though the boxed layout is identical width on both. Freezing
   every affected value at its max as soon as the container also freezes (1240px)
   keeps the design pixel-identical on any laptop or desktop screen. Placed last
   in the file so it wins the cascade over same-specificity rules above. */
@media (min-width: 1240px) {
  .hero-title { font-size: 56px; }
  .services-panels { margin-top: 52px; }
  .services-title { font-size: 64px; }
  .services-aside .services-title { font-size: 44px; }
  .clients-title { font-size: 66px; }
  .ind-title { font-size: 88px; }
  .ind-name { font-size: 26px; }
  .glance-head h2 { font-size: 66px; }
  .g-num { font-size: 70px; }
  .contact-aside h2 { font-size: 52px; }
  .footer-connect-title { font-size: 56px; }
  .phero h1 { font-size: 64px; }
  .phero .lead { font-size: 20px; }
  .stitle { font-size: 64px; }
  .split-body h2 { font-size: 38px; }
  .metric .mnum { font-size: 56px; }
  .cta-band h2 { font-size: 44px; }
  .dir-head h2 { font-size: 50px; }
  .svc-dir-head h2 { font-size: 62px; }
  .svc-dir-head--split h2 { font-size: 44px; }
  .svc-dir-head.svc-dir-head--sm h2 { font-size: 34px; }
  .lead-split h2 { font-size: 54px; }
  .cta-split .csp-text h2 { font-size: 27px; }
  .cta-split .csp-cta { font-size: 25px; }
  .rbody .rstat { font-size: 50px; }
  .eco-col h3 { font-size: 30px; }
  .why-head h2 { font-size: 46px; }
  .ct-body h3 { font-size: 26px; }
  .idir-title h2 { font-size: 44px; }
  .feature-purple .fp-top h2 { font-size: 40px; }
  .cs-tile--wide .cs-body { padding: 52px; }
  .cs-tile--wide h3 { font-size: 30px; }
  .stat .s-num { font-size: 30px; }
  .split-bleed .sb-pane { padding: 80px 64px; }
  .split-bleed .sb-pane h2, .split-bleed .sb-pane h3 { font-size: 38px; }
  .cta-duo a { padding: 40px 48px; font-size: 26px; }
  .split-body .proj-title-sm { font-size: 30px; }
  .split-body .proj-stat-lg { font-size: 46px; }
  .why-glance-title { font-size: 52px; }
  .why-glance-num { font-size: 40px; }
}
@media (max-width: 540px) { .contact-offices { grid-template-columns: 1fr; } }

/* ============================================================
   FAQ — native <details> accordion (zero-JS, used on technology.html)
   ============================================================ */
.faq { max-width: 900px; border-top: 1px solid var(--c-line); }
.faq details { border-bottom: 1px solid var(--c-line); }
.faq summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 22px 2px;
  font-size: clamp(16px, 1.4vw, 19px); font-weight: 700; letter-spacing: -.01em; color: var(--c-ink);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex: 0 0 auto; width: 11px; height: 11px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform .25s var(--ease);
}
.faq details[open] summary::after { transform: rotate(-135deg); }
.faq details > p { padding: 0 2px 24px; margin: 0; font-size: 15px; line-height: 1.66; color: var(--c-body); max-width: 74ch; }
.faq details > p a { color: var(--c-blue); font-weight: 600; }

/* ============================================================
   FAMILY PALETTES — the parent-page theming contract
   ============================================================
   Set on <body> as .pg-services / .pg-solutions / .pg-technology.
   Every component below reads these ROLES and never a literal
   family colour, so adding a family costs exactly one block: fill
   in the roles and the whole component library re-themes.

   ROLE                WHAT READS IT
   --fam-900           deep band base, image scrims
   --fam-800           deep band gradient mid-stop
   --fam-700           PRIMARY — hover headings, icons, rules, CTAs
   --fam-500           reserved interactive step
   --fam-400           gradient end / borders on LIGHT surfaces
   --fam-300           accent on DARK bands (lit bars, chevrons)
   --fam-200           sub-text on DARK bands
   --fam-tint / -2     pale band + panel fills
   --fam-chip          icon-tile fill
   --fam-line / -2     panel + tag borders
   --fam-rule / -2     inner dividers
   --fam-num           resting numeral
   --fam-dot           sub-link separator
   --fam-ink-2 / -3    tag text + sub-link text
   --fam-shadow        "r,g,b" for primary-tinted shadows
   --fam-shadow-900    "r,g,b" for darkest-tinted scrims
   --fam-glow          "r,g,b" for the lit-edge bloom
   --fam-grad          the family gradient

   --fam-400 and --fam-300 stay SEPARATE roles even though Services
   assigns both the same value. On a light card the gradient wants
   the most saturated light step; on a dark band the accent has to
   clear the background's own lightness. In this blue set those two
   happened to coincide — in other hues they do not, so collapsing
   them here would have quietly broken the next family.

   The shadow/glow roles are bare "r,g,b" triples, not colours, so a
   single token can serve every alpha the components need via
   rgba(var(--fam-shadow), .12) rather than one token per opacity.
   ------------------------------------------------------------ */
.pg-services {
  /* palettepoint blue set, darkest → lightest. Scoped to this family:
     --c-blue and the sitewide .btn-primary / Contact Us fill (#402ce6)
     are deliberately untouched. */
  --fam-900: #011C71;   /* Long-Haul Flight    */
  --fam-800: #012a86;
  --fam-700: #0436AB;   /* Blue Hour — PRIMARY */
  --fam-500: #2861E3;   /* Veteran's Day Blue  */
  --fam-400: #5C91FB;   /* Blue Chaos          */
  --fam-300: #5C91FB;   /* Blue Chaos          */
  --fam-200: #88C6FD;   /* Platonic Blue       */

  --fam-tint:   #f2f6fd;
  --fam-tint-2: #f5f8fe;
  --fam-chip:   #e7effc;
  --fam-line:   #e4ebf8;
  --fam-line-2: #dde5f2;
  --fam-rule:   #e2e9f6;
  --fam-rule-2: #eaf0fa;
  --fam-num:    #c3d7f7;
  --fam-dot:    #b9c5db;
  --fam-ink-2:  #414c66;
  --fam-ink-3:  #4a5570;

  --fam-shadow:     4,54,171;
  --fam-shadow-900: 1,28,113;
  --fam-glow:       92,145,251;

  /* primary → light end rather than a same-lightness pair: the row-hover
     wipe is only 2px tall, and luminance movement is what makes it read as
     a gradient at that size (a same-lightness ramp just looks like a rule) */
  --fam-grad: linear-gradient(90deg, var(--fam-700) 0%, var(--fam-400) 100%);

  /* The deep band. Was written inline on .psection--deep and nowhere else;
     tokenised because the glass cards now take the same fill, and two copies
     of one gradient is how they drift apart. Defined per family rather than
     once at :root — var() inside a custom property resolves against the
     element the property is declared on, so a single global copy would freeze
     the blue ramp and never pick up the violet overrides below. */
  --fam-grad-deep: linear-gradient(155deg,
    var(--fam-900) 0%, var(--fam-800) 55%, var(--fam-700) 100%);
}

.pg-solutions {
  /* Violet reference set, darkest → lightest. #491AB1 is the primary.
     The reference supplies seven saturated steps but no pale tints, so the
     surface tokens below are DERIVED rather than guessed: each one keeps its
     blue counterpart's saturation and lightness exactly and rotates the hue
     +36.6° (222° Blue Hour → 258.7° here). That is what makes a violet page
     carry the same visual weight as the blue one instead of merely the same
     layout — #D0BCFC as a section background would read as a lavender block,
     not as a tint. */
  --fam-900: #34117E;
  --fam-800: #3D1595;   /* the blue band's mid stop sits at t=0.45; matched */
  --fam-700: #491AB1;   /* PRIMARY — 10.2:1 on white */
  --fam-500: #6631DB;
  --fam-400: #7B45F0;   /* gradient end on light — 5.3:1 on white */
  --fam-300: #A981FF;   /* accent on dark    — 4.8:1 on --fam-900 */
  --fam-200: #B796FE;   /* sub-text on dark  — 5.8:1 on --fam-900 */
  --fam-100: #D0BCFC;   /* hairlines and glass edges on dark */

  --fam-tint:   #F5F2FD;
  --fam-tint-2: #F8F5FE;
  --fam-chip:   #EEE7FC;
  --fam-line:   #EAE4F8;
  --fam-line-2: #E4DDF2;
  --fam-rule:   #E8E2F6;
  --fam-rule-2: #EFEAFA;
  --fam-num:    #D3C3F7;
  --fam-dot:    #C4B9DB;
  --fam-ink-2:  #4D4166;
  --fam-ink-3:  #564A70;

  --fam-shadow:     73,26,177;
  --fam-shadow-900: 52,17,126;
  --fam-glow:       169,129,255;

  --fam-grad: linear-gradient(90deg, var(--fam-700) 0%, var(--fam-400) 100%);
  --fam-grad-deep: linear-gradient(155deg,
    var(--fam-900) 0%, var(--fam-800) 55%, var(--fam-700) 100%);
}

/* ============================================================
   TECHNOLOGY FAMILY  (.pg-technology)
   ============================================================
   The third family in the --fam-* contract, plus the four
   components the Technology page is built from. Photographs
   carry the weight, every list is a hairline rule rather than a
   card, and the family colour only appears on hover — at rest
   the page is ink and neutral rules, the way Services and
   Solutions are.

   Only six of the sixteen files in assets/images show enterprise
   work; the rest are unrelated stock (a beach, fireworks, a
   baseball glove, a vintage camera). The six used here are named
   at each call site so a future edit does not reach for a
   filename that sounds right and get a sunset.
   ------------------------------------------------------------ */
/* ------------------------------------------------------------
   FAMILY IDENTITY BRIDGE (owner call 2026-08-05)
   The shared components — header, contact card, eyebrows, tick
   lists, teaser bands, CTA bands, dark tiles — are wired to the
   home tokens above. Re-pointing those tokens inside each family
   scope recolours every shared component on every family page at
   once; all four family blocks define the same --fam-* names, so
   one rule serves them all. Pages with no pg-* class (home,
   company, career, contact, insights, case studies) keep the
   home palette.
   The legacy moss-green .pg-technology token block that lived
   here is deleted — tech-family.css (blue→cyan) is the only
   technology palette now.
   ------------------------------------------------------------ */
.pg-services, .pg-solutions, .pg-technology, .pg-industries {
  --c-blue:        var(--fam-700);
  --c-blue-royal:  var(--fam-700);   /* gradient start */
  --c-blue-deep:   var(--fam-800);   /* dark tiles and panes */
  --c-accent:      var(--fam-700);   /* arrows, kickers, "Learn more" */
  --c-grad:        var(--fam-grad);
  --c-grad-violet: var(--fam-grad);
  --c-violet:      var(--fam-400);   /* gradient end stop (solid teaser tiles) */
  --c-tile-navy:   var(--fam-900);   /* the band's wide text panel wears the family deep */
  --c-shadow-rgb:  var(--fam-shadow);
  --c-glow-rgb:    var(--fam-glow);
}
/* the dark device that hardcodes home colours instead of reading tokens */
.pg-services .cta-band--blue, .pg-solutions .cta-band--blue,
.pg-technology .cta-band--blue, .pg-industries .cta-band--blue { background: var(--fam-grad-deep); }
/* the footer is black: a fam-700 primary (Industries teal is 2.2:1 there)
   disappears on it, so hover accents inside the footer take the light shade */
.pg-services .site-footer, .pg-solutions .site-footer,
.pg-technology .site-footer, .pg-industries .site-footer { --c-accent: var(--fam-300); }
.pg-technology .head-arrow { color: var(--fam-700); border-color: var(--c-line); }
.pg-technology .head-arrow:hover { background: var(--fam-700); border-color: var(--fam-700); color: #fff; }
/* the FAQ answer links are globally --c-blue; on a green page that is simply
   a blue link on a green section */
.pg-technology .faq details > p a { color: var(--fam-700); }

/* ---- shared photograph treatment --------------------------- */
/* The library is cool and blue-lit; the family is warm olive. The
   desaturation and the near-neutral wash are what stop the two fighting. */
.ph { position: relative; overflow: hidden; }
.ph-img {
  position: absolute; inset: 0; background: var(--img) center/cover no-repeat;
  filter: saturate(.68) contrast(1.05);
  transition: transform 1.1s var(--ease);
}
.ph::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(172deg, rgba(var(--ph-scrim), .06) 0%,
                                      rgba(var(--ph-scrim), .26) 52%,
                                      rgba(var(--ph-scrim), .62) 100%);
}
/* Where TEXT sits on the photograph. A near-even wash, not a side-lit one:
   the band lays six items across the full width, so a left-dark gradient
   would leave the right-hand column on a 26% scrim at 3:1. The floor is the
   alpha that still clears AA over the brightest part of the picture. */
.ph--text::after {
  background:
    linear-gradient(112deg, rgba(var(--ph-scrim), .90) 0%,
                            rgba(var(--ph-scrim), .78) 45%,
                            rgba(var(--ph-scrim), .74) 100%),
    linear-gradient(180deg, rgba(var(--ph-scrim), 0) 0%,
                            rgba(var(--ph-scrim), .12) 100%);
}
.bx-plate {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: 26px 28px 26px 30px; background: rgba(var(--fam-shadow-900), .78);
  backdrop-filter: blur(7px); border-top: 2px solid var(--fam-300);
}
.bx-plate strong { display: block; font-size: 19px; font-weight: 700; letter-spacing: -.015em; color: #fff; line-height: 1.3; }
.bx-plate span { display: block; margin-top: 9px; font-size: 14px; line-height: 1.55; color: var(--fam-200); }

/* ============================================================
   §1 — THE THREE ECOSYSTEMS  (.ax-*)
   A photograph per ecosystem, sides alternating down the page.
   nth-of-type, not nth-child: the section head is a sibling, so
   nth-child would count it and flip every pairing.
   ============================================================ */
.ax-head { margin-bottom: 84px; }
.ax-chapter { display: grid; grid-template-columns: minmax(0,.94fr) minmax(0,1.06fr);
  gap: 0 64px; align-items: center; transition: opacity .3s var(--ease); }
.ax-chapter + .ax-chapter { margin-top: 104px; }
.ax-chapter:nth-of-type(even) .ax-photo { order: 2; }
.ax-chapter:nth-of-type(even) .ax-text  { order: 1; }
.ax-photo { aspect-ratio: 4 / 3.3; border-radius: 3px; }
@media (hover: hover) {
  .ax-list:hover .ax-chapter { opacity: .42; }
  .ax-list .ax-chapter:hover { opacity: 1; }
}
.ax-chapter:focus-within { opacity: 1; }
.ax-chapter:hover .ph-img { transform: scale(1.05); }

.ax-kicker { display: block; font-size: 11.5px; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--fam-ink-3); margin-bottom: 14px;
  transition: color .3s var(--ease); }
.ax-mark { position: relative; font-size: clamp(50px, 6vw, 86px); font-weight: 800;
  letter-spacing: -.05em; line-height: .88; color: var(--c-ink); transition: color .3s var(--ease); }
.ax-mark::after { content: ""; position: absolute; left: 0; bottom: -10px; width: 64px; height: 3px;
  border-radius: 2px; background: var(--fam-grad); transform: scaleX(0); transform-origin: left;
  transition: transform .44s var(--ease); }
.ax-chapter:hover .ax-mark, .ax-chapter:focus-within .ax-mark { color: var(--fam-700); }
.ax-chapter:hover .ax-kicker, .ax-chapter:focus-within .ax-kicker { color: var(--fam-700); }
.ax-chapter:hover .ax-mark::after, .ax-chapter:focus-within .ax-mark::after { transform: scaleX(1); }
.ax-claim { margin-top: 26px; font-size: 20px; font-weight: 600; letter-spacing: -.015em;
  color: var(--c-ink); line-height: 1.3; max-width: 24ch; }
.ax-lede { margin-top: 12px; font-size: 15.5px; line-height: 1.66; color: var(--fam-ink-2); max-width: 46ch; }
.ax-plat { margin-top: 26px; max-width: 46ch; border-top: 1px solid var(--fam-rule); }
.ax-plat li { display: flex; align-items: baseline; gap: 14px; padding: 10px 0;
  border-bottom: 1px solid var(--fam-rule); font-size: 15px; color: var(--c-ink);
  transition: transform .34s var(--ease); }
.ax-plat i { font-style: normal; font-size: 11px; font-weight: 700; letter-spacing: .06em;
  color: var(--fam-ink-3); flex-shrink: 0; }
/* the delay lives in the hover rule only, so the list steps out on enter and
   snaps back together on leave rather than unravelling twice */
.ax-chapter:hover .ax-plat li, .ax-chapter:focus-within .ax-plat li { transform: translateX(8px); }
.ax-chapter:hover .ax-plat li:nth-child(1) { transition-delay: 0s; }
.ax-chapter:hover .ax-plat li:nth-child(2) { transition-delay: .05s; }
.ax-chapter:hover .ax-plat li:nth-child(3) { transition-delay: .1s; }
.ax-chapter:hover .ax-plat li:nth-child(4) { transition-delay: .15s; }
.ax-go { display: inline-flex; align-items: center; gap: 10px; margin-top: 26px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--c-ink); padding-bottom: 5px; border-bottom: 2px solid var(--c-line);
  transition: color .26s var(--ease), border-color .26s var(--ease); }
.ax-go svg { width: 17px; height: 17px; transition: transform .26s var(--ease); }
.ax-go:hover, .ax-go:focus-visible { color: var(--fam-700); border-bottom-color: var(--fam-400); }
.ax-go:hover svg { transform: translateX(4px); }
@media (max-width: 1000px) {
  .ax-head { margin-bottom: 52px; }
  .ax-chapter { grid-template-columns: 1fr; gap: 26px; }
  .ax-chapter + .ax-chapter { margin-top: 64px; }
  .ax-chapter:nth-of-type(even) .ax-photo { order: 0; }
  .ax-chapter:nth-of-type(even) .ax-text  { order: 0; }
  .ax-photo { aspect-ratio: 16 / 9; }
  .ax-mark::after { display: none; }
}

/* ============================================================
   §2 — WHAT A PROGRAMME COVERS  (.bcore-*)
   ============================================================ */
.bcore { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 0 40px; }
.bcore-head { grid-column: 1 / -1; }
/* neutral at rest, family colour on hover — six 380px rules in --fam-700
   tinted the whole section green before anyone touched it */
.bcore-item { padding: 30px 0 34px; border-top: 1px solid var(--c-line);
  background-image: linear-gradient(90deg, rgba(255,255,255,.9) 0%, transparent 74%);
  background-repeat: no-repeat; background-size: 0 100%;
  transition: border-top-color .28s var(--ease), background-size .52s var(--ease); }
.bcore-item:hover { border-top-color: var(--fam-700); background-size: 100% 100%; }
.bcore-n { display: block; color: var(--fam-num); margin-bottom: 16px; }
.bcore-n, .bcore-item h3 { transition: color .3s var(--ease), transform .34s var(--ease); }
.bcore-item:hover .bcore-n { color: var(--fam-700); }
.bcore-item:hover h3 { color: var(--fam-700); }
.bcore-item:hover .bcore-n, .bcore-item:hover h3 { transform: translateX(7px); }
.bcore-item p { margin-top: 11px; font-size: 15px; line-height: 1.64; color: var(--fam-ink-2); }
/* full width, not one track: as a single cell it sat alone with two empty
   tracks beside it, which reads as a gap rather than a deliberate break */
.bcore-photo { grid-column: 1 / -1; min-height: 300px; margin-top: 34px; border-radius: 3px; }
@media (max-width: 980px) { .bcore { grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px) { .bcore { grid-template-columns: 1fr; } .bcore-photo { min-height: 200px; } }

/* ============================================================
   §3 — WHAT DECIDES THE DIRECTION  (.tband / .tdec-*)
   The page's dark moment, and the only band that is a
   photograph rather than a flat gradient.
   ============================================================ */
.tband { position: relative; overflow: hidden; padding: 104px 0 108px; color: #fff; }
.tband > .container { position: relative; z-index: 1; }
.tband > .ph { position: absolute; inset: 0; }
.tband .svc-dir-head h2 { color: #fff; }
.tband .svc-dir-head .intro { color: rgba(255,255,255,.84); }
.tband .eyebrow { color: var(--fam-300); }

.tdec { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 0 46px; }
.tdec-item { padding: 26px 0 30px; border-top: 1px solid rgba(255,255,255,.3);
  transition: opacity .3s var(--ease), border-top-color .3s var(--ease); }
.tdec-n { display: block; font-size: 12px; font-weight: 700; letter-spacing: .12em;
  color: var(--fam-300); margin-bottom: 12px;
  transition: color .3s var(--ease), transform .34s var(--ease); }
.tdec-item h3 { color: #fff; transition: transform .34s var(--ease); }
.tdec-item p { margin-top: 10px; font-size: 15px; line-height: 1.62; color: rgba(255,255,255,.8); }
@media (hover: hover) {
  .tdec:hover .tdec-item { opacity: .46; }
  .tdec .tdec-item:hover { opacity: 1; border-top-color: var(--fam-300); }
}
.tdec-item:hover .tdec-n { color: #fff; transform: translateX(5px); }
.tdec-item:hover h3 { transform: translateX(5px); }
.tdec-closer {
  margin-top: 42px; padding-left: 20px; border-left: 3px solid var(--fam-300);
  font-size: 17px; line-height: 1.6; color: rgba(255,255,255,.9); max-width: 74ch;
}
@media (max-width: 980px) { .tdec { grid-template-columns: 1fr 1fr; gap: 0 34px; } }
@media (max-width: 600px) { .tdec { grid-template-columns: 1fr; } }

/* ============================================================
   §4 — INDUSTRIES  (.tind-*)
   A pointer to the Industries page, not a section in its own
   right — a low strip of ruled links.
   ============================================================ */
.tind { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 0 46px;
  border-top: 1px solid var(--c-line); }
.tind-item { display: block; padding: 22px 0 24px; border-bottom: 1px solid var(--c-line);
  transition: opacity .28s var(--ease); }
.tind-item h3 { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  color: var(--c-ink); transition: color .26s var(--ease); }
.tind-item h3 svg { width: 17px; height: 17px; flex-shrink: 0; color: var(--fam-700);
  opacity: 0; transform: translateX(-5px);
  transition: opacity .24s var(--ease), transform .24s var(--ease); }
.tind-item p { margin-top: 8px; font-size: 14px; line-height: 1.55; color: var(--fam-ink-3); }
@media (hover: hover) {
  .tind:hover .tind-item { opacity: .5; }
  .tind .tind-item:hover { opacity: 1; }
}
.tind-item:hover h3, .tind-item:focus-visible h3 { color: var(--fam-700); }
.tind-item:hover h3 svg, .tind-item:focus-visible h3 svg { opacity: 1; transform: none; }
@media (max-width: 900px) { .tind { grid-template-columns: 1fr 1fr; gap: 0 32px; } }
@media (max-width: 560px) { .tind { grid-template-columns: 1fr; } }

/* ---- house type scale ------------------------------------- */
/* §1 lays its head out with its own grid, but the SIZES, WEIGHTS and COLOURS
   have to be the ones .svc-dir-head uses on Services and Solutions, or
   Technology reads as a different site rather than a third family in the same
   one. The house is 900 / -.025em with a 17px LIGHT intro. */
.ax-head { display: grid; grid-template-columns: minmax(0,1.15fr) minmax(0,1fr);
  gap: 18px 64px; align-items: end; }
.ax-head h2 { font-size: clamp(38px, 4.4vw, 62px); font-weight: 900; letter-spacing: -.025em;
  line-height: 1.0; color: var(--c-ink); }
.ax-head p { font-size: 17px; font-weight: 300; line-height: 1.62; color: #323232; padding-bottom: 8px; }
@media (max-width: 1000px) { .ax-head { grid-template-columns: 1fr; align-items: start; } }
/* item headings match .iq-card h3 / .gw-row h3; the numeral matches .dx-num */
.bcore-item h3, .tdec-item h3, .tind-item h3 {
  font-size: 20px; font-weight: 700; letter-spacing: -.02em; line-height: 1.25;
}
.bcore-n { font-size: 40px; font-weight: 800; letter-spacing: -.03em; line-height: .9; }

@media (prefers-reduced-motion: reduce) {
  .ph-img, .ax-chapter, .ax-mark, .ax-mark::after, .ax-kicker, .ax-plat li, .ax-go, .ax-go svg,
  .bcore-item, .bcore-n, .bcore-item h3,
  .tdec-item, .tdec-n, .tdec-item h3,
  .tind-item, .tind-item h3, .tind-item h3 svg { transition: none; }
  .ax-chapter:hover .ph-img, .ax-chapter:hover .ax-plat li,
  .ax-chapter:focus-within .ax-plat li,
  .bcore-item:hover .bcore-n, .bcore-item:hover h3,
  .tdec-item:hover .tdec-n, .tdec-item:hover h3 { transform: none; }
}

/* ---- retire the #f5821f orange, per family ------------------------
   ".head-arrow" ships orange sitewide. Each family opts out on its own
   line, so pages that have not been through the redesign keep their
   current look until their turn comes.
   ------------------------------------------------------------------ */
.pg-solutions .head-arrow { color: var(--fam-700); border-color: var(--c-line); }
.pg-solutions .head-arrow:hover { background: var(--fam-700); border-color: var(--fam-700); color: #fff; }

/* ============================================================
   DIRECTORY INDEX — numbered editorial rows
   The parent-page directory component, replacing the 2-column
   ".cat" grid. Structure lives here once; each page family only
   restates colour through the roles above, so the parents share a
   feel without forking the component. Child pages inherit from
   whichever family class sits on <body>.
   ============================================================ */
.dx-index {
  /* falls back to the site blue when no family class is present */
  --dx-accent: var(--fam-700, #402ce6);
  --dx-accent-2: var(--fam-400, #6d28d9);
  --dx-grad: var(--fam-grad, linear-gradient(90deg, var(--dx-accent) 0%, var(--dx-accent-2) 100%));
  --dx-rule: var(--c-line);
  /* blue-tinted rather than neutral grey, so the resting numerals belong to
     the ramp instead of reading as leftover placeholder grey */
  --dx-num: var(--fam-num, #c3d7f7);
  --dx-title: var(--c-ink);
  --dx-sub: var(--c-body);
  /* row wash — an alpha of the family primary rather than a flat grey, so the
     sweep belongs to the ramp on every family. Overridden on dark bands. */
  --dx-sweep: rgba(var(--fam-shadow, 45,45,235), .055);

  margin-top: 52px;
  border-top: 1px solid var(--dx-rule);
}

/* row: numeral | title + links | CTA. The CTA gets a fixed track so
   titles align on a single left edge regardless of CTA label length. */
.dx-item {
  position: relative;
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr) 168px;
  gap: 0 32px;
  align-items: start;
  padding: 34px 0 32px;
  border-bottom: 1px solid var(--dx-rule);
  /* wash anchored at the left edge, gone by 64% — the eye is pulled toward
     the numeral rather than the whole strip lighting up like a table
     selection. Revealed by growing background-size so it wipes in from the
     left instead of just fading up. */
  background-image: linear-gradient(90deg, var(--dx-sweep) 0%, transparent 64%);
  background-repeat: no-repeat;
  background-size: 0 100%;
  transition: background-size .5s var(--ease), opacity .3s var(--ease);
}
/* gradient rule wipes across the row's bottom edge on hover — replaces the
   nine permanent 60px outlined arrow boxes as the "this is clickable" signal */
.dx-item::after {
  content: ""; position: absolute; left: 0; bottom: -1px; width: 100%; height: 2px;
  background: var(--dx-grad); transform: scaleX(0); transform-origin: left;
  transition: transform .45s var(--ease);
}
@media (hover: hover) {
  .dx-item:hover::after { transform: scaleX(1); }
}
.dx-item:focus-within::after { transform: scaleX(1); }

.dx-num {
  position: relative;
  font-size: 40px; font-weight: 800; letter-spacing: -.03em; line-height: .9;
  color: var(--dx-num); font-variant-numeric: tabular-nums;
  transition: color .3s var(--ease), transform .38s var(--ease);
}
.dx-item:hover .dx-num, .dx-item:focus-within .dx-num { color: var(--dx-accent); }
/* gradient tick under the numeral — the one place the family gradient appears
   at the head of the row rather than only along its bottom edge */
.dx-num::after {
  content: ""; position: absolute; left: 0; bottom: -13px; width: 32px; height: 3px; border-radius: 2px;
  background: var(--dx-grad); transform: scaleX(0); transform-origin: left;
  transition: transform .42s var(--ease);
}
.dx-item:hover .dx-num::after, .dx-item:focus-within .dx-num::after { transform: scaleX(1); }

/* 700, not the 900 the old ".svc-dir-head h2" scale used — at row size the
   heavier weight read as shouting rather than as hierarchy */
.dx-title { font-size: 27px; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; }
.dx-title a { color: var(--dx-title); transition: color .18s var(--ease); }
.dx-item:hover .dx-title a { color: var(--dx-accent); }

/* fixed 2-column track so sub-links form real columns instead of the
   ragged inline wrap the flex ".subs" list produced */
.dx-tags { margin-top: 18px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 11px 34px; }
.dx-tags a, .dx-tags span {
  position: relative; padding-left: 22px;
  font-size: 15.5px; line-height: 1.45; color: var(--dx-sub);
  transition: color .18s var(--ease);
}
.dx-tags a::before, .dx-tags span::before {
  content: ""; position: absolute; left: 0; top: .62em; width: 10px; height: 1px;
  background: currentColor; opacity: .45;
  transition: width .22s var(--ease), opacity .22s var(--ease);
}
/* ---- row-level hover ------------------------------------------------
   Five things move together, all cheap: the list dims so the hovered row
   is the only lit one, the wash wipes in, numeral and copy step right,
   the numeral's tick draws, and the sub-link dashes extend in sequence
   rather than all snapping at once.

   The step is a transform on the CONTENT, not padding on the row: padding
   would narrow the 1fr track and re-wrap the two-column sub-link grid on
   every hover, which reads as a flinch.
   --------------------------------------------------------------------- */
.dx-body { transition: transform .38s var(--ease); }

@media (hover: hover) {
  .dx-index:hover .dx-item { opacity: .45; }
  .dx-index .dx-item:hover { opacity: 1; }
  .dx-item:hover { background-size: 100% 100%; }
  .dx-item:hover .dx-num, .dx-item:hover .dx-body { transform: translateX(9px); }

  /* dashes extend left-to-right down the list. Delay lives in the hover
     rule only, so they retract immediately on leave instead of unwinding. */
  .dx-item:hover .dx-tags a::before { width: 15px; opacity: .8; }
  .dx-item:hover .dx-tags a:nth-child(1)::before { transition-delay: 0s; }
  .dx-item:hover .dx-tags a:nth-child(2)::before { transition-delay: .04s; }
  .dx-item:hover .dx-tags a:nth-child(3)::before { transition-delay: .08s; }
  .dx-item:hover .dx-tags a:nth-child(4)::before { transition-delay: .12s; }
  .dx-item:hover .dx-tags a:nth-child(5)::before { transition-delay: .16s; }
  .dx-item:hover .dx-tags a:nth-child(n+6)::before { transition-delay: .2s; }
}

/* keyboard parity — same state without depending on a pointer */
.dx-item:focus-within { background-size: 100% 100%; }
.dx-item:focus-within .dx-num, .dx-item:focus-within .dx-body { transform: translateX(9px); }

/* pointing AT a sub-link still beats the row treatment. Scoped through
   .dx-index so it outranks ".dx-item:hover .dx-tags a::before", which is
   one class heavier than the bare ".dx-tags a:hover" this replaces. */
.dx-index .dx-tags a:hover { color: var(--dx-accent); }
.dx-index .dx-tags a:hover::before { width: 20px; opacity: 1; transition-delay: 0s; }

/* The CTA owns a 168px track. As bare 13px text centred in that track it read
   as a word floating in a void — the track is ~44px of type in ~170x150px of
   air. Two changes fix it without touching the grid: the label becomes a pill
   that FILLS its track (so the column holds an object, not a fragment), and it
   aligns to the title rather than to the row's vertical centre (so it belongs
   to the heading it acts on instead of hovering beside the sub-links).

   space-between pushes label and arrow to opposite ends, which is what gives
   the pill its width honestly rather than by padding it out. */
.dx-cta {
  justify-self: stretch; align-self: start; margin-top: -4px;
  display: inline-flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 18px; border-radius: 999px;
  border: 1px solid var(--dx-accent);
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--dx-accent); white-space: nowrap;
  opacity: 0; transform: translateX(-10px);
  transition: opacity .3s var(--ease), transform .3s var(--ease),
              background .25s var(--ease), color .25s var(--ease);
}
.dx-cta svg { width: 18px; height: 18px; flex-shrink: 0; transition: transform .25s var(--ease); }
.dx-item:hover .dx-cta, .dx-item:focus-within .dx-cta { opacity: 1; transform: none; }
/* outlined while the ROW is lit, solid only when the pointer is on the pill
   itself — the row highlight and the button state stay distinguishable */
.dx-cta:hover, .dx-cta:focus-visible { background: var(--dx-accent); color: var(--dx-cta-on, #fff); }
.dx-cta:hover svg { transform: translateX(3px); }
/* touch has no hover state to reveal it, so it stays visible there */
@media (hover: none) {
  .dx-cta { opacity: 1; transform: none; }
}

/* magenta band inversion — same rows, white-on-magenta */
.psection--magenta .dx-index {
  --dx-accent: #fff;
  --dx-grad: linear-gradient(90deg, #fff 0%, rgba(255,255,255,.2) 100%);
  --dx-rule: rgba(255,255,255,.18);
  --dx-num: rgba(255,255,255,.3);
  --dx-title: #fff;
  --dx-sub: rgba(255,255,255,.78);
  /* a primary-tinted wash is invisible on a dark band — the sweep has to
     come from the light side there */
  --dx-sweep: rgba(255,255,255,.09);
  /* --dx-accent is #fff here, so a filled CTA needs dark type, not white */
  --dx-cta-on: var(--c-ink);
}

/* motion is decoration here, not information: every state the hover layers
   express is also carried by colour, so they can all stop moving. The dim
   and the wash stay — they are position, not animation. */
@media (prefers-reduced-motion: reduce) {
  .dx-item, .dx-item::after, .dx-num, .dx-num::after, .dx-body,
  .dx-title a, .dx-tags a, .dx-tags a::before, .dx-cta { transition: none; }
  .dx-item:hover .dx-num, .dx-item:hover .dx-body,
  .dx-item:focus-within .dx-num, .dx-item:focus-within .dx-body { transform: none; }
  .dx-item:hover .dx-tags a::before { transition-delay: 0s; }
}

/* full-width photo band — the old ".svc-photo" could not stay a column tile
   once rows went full width. Radius + bottom scrim + caption so it reads as
   a deliberate image rather than a bare placeholder rectangle. */
.dx-band {
  position: relative; margin-top: 46px; min-height: 300px;
  border-radius: 14px; overflow: hidden;
  background: var(--img) center/cover no-repeat, var(--c-dark);
}
.dx-band::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,8,26,0) 40%, rgba(8,8,26,.74) 100%);
}
.dx-band-cap {
  position: absolute; left: 30px; right: 30px; bottom: 24px; z-index: 1;
  color: #fff; font-size: 15.5px; font-weight: 500; letter-spacing: -.01em; max-width: 62ch;
}

@media (max-width: 1080px) {
  /* CTA drops under the copy instead of squeezing the title track */
  .dx-item { grid-template-columns: 88px minmax(0, 1fr); }
  .dx-cta { grid-column: 2; justify-self: start; align-self: start; margin-top: 20px; opacity: 1; transform: none; }
}
@media (max-width: 700px) {
  .dx-index { margin-top: 32px; }
  .dx-item { grid-template-columns: 1fr; gap: 0; padding: 26px 0 24px; }
  /* numeral is no longer a gutter, so it sits inline above the title and
     takes the accent colour outright — there is no hover to earn it */
  .dx-num { font-size: 24px; line-height: 1; margin-bottom: 12px; color: var(--dx-accent); }
  /* the numeral is inline above the title here, not in a gutter — the tick
     would land on the heading, and the numeral already carries the accent
     outright since there is no hover to earn it */
  .dx-num::after { display: none; }
  .dx-title { font-size: 22px; }
  .dx-tags { grid-template-columns: 1fr; gap: 9px; margin-top: 14px; }
  .dx-cta { grid-column: 1; margin-top: 16px; font-size: 12px; }
  .dx-band { min-height: 210px; margin-top: 30px; }
  .dx-band-cap { left: 20px; right: 20px; bottom: 18px; font-size: 14px; }
}

/* ============================================================
   GATEWAY BAND — split claim + destination list
   Used where a section points OUT to another page family rather
   than listing the page's own content (e.g. "SAP solutions" on
   the Services page — every link there leaves the page). The
   left column argues, the right column lists. No surfaces, so
   rows are exactly as tall as their content.
   ============================================================ */
.psection--deep {
  color: #fff;
  background: var(--fam-grad-deep,
    linear-gradient(155deg, #011C71 0%, #012a86 55%, #0436AB 100%));
}
.psection--deep .svc-dir-head .intro { color: rgba(255,255,255,.84); }
.psection--deep .eyebrow { color: var(--fam-300, #5C91FB); }

.gw-split { display: grid; grid-template-columns: .82fr 1.18fr; gap: 0 70px; align-items: start; }

/* ---- left: the claim ---- */
.gw-claim { position: sticky; top: 118px; }
.gw-claim h2 { font-size: clamp(38px, 4vw, 54px); font-weight: 800; letter-spacing: -.03em; line-height: 1.0; }
.gw-claim p { margin-top: 20px; font-size: 16px; font-weight: 300; line-height: 1.62; color: rgba(255,255,255,.8); max-width: 40ch; }
.gw-claim .btn { margin-top: 28px; gap: 10px; }
.gw-claim .btn svg { width: 20px; height: 20px; transition: transform .25s var(--ease); }
.gw-claim .btn:hover svg { transform: translateX(4px); }

/* ---- right: the destinations ---- */
.gw-list { border-top: 1px solid rgba(255,255,255,.16); }

.gw-row {
  position: relative;
  display: grid; grid-template-columns: minmax(0,1fr) 44px; align-items: center; gap: 20px;
  padding: 22px 0 20px;
  border-bottom: 1px solid rgba(255,255,255,.16);
  /* sweep, not a flat tint — strongest at the accent edge and gone by
     mid-row, so the eye is pulled left toward the bar rather than the whole
     strip lighting up like a table selection. Painted as the row's own
     background (not a z-index:-1 pseudo, which paints unpredictably against
     the section background) and revealed by growing background-size, which
     wipes it in from the left rather than just fading it up. */
  background-image: linear-gradient(90deg, rgba(255,255,255,.1) 0%, rgba(255,255,255,.02) 46%, transparent 78%);
  background-repeat: no-repeat;
  background-size: 0 100%;
  transition: padding-left .34s var(--ease), opacity .3s var(--ease), background-size .42s var(--ease);
}
/* accent bar wipes up the left edge, with a soft bloom so it reads as lit
   rather than drawn */
.gw-row::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; border-radius: 2px;
  background: linear-gradient(180deg, var(--fam-300) 0%, #fff 100%);
  box-shadow: 0 0 14px rgba(var(--fam-glow, 92,145,251),.75);
  transform: scaleY(0); transform-origin: bottom;
  transition: transform .38s var(--ease);
}

.gw-row h3 { font-size: 21px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }
/* inline-block so the underline tracks the text width, not the grid cell */
.gw-row h3 a { color: #fff; position: relative; display: inline-block; }
.gw-row h3 a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -3px; height: 2px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform .4s var(--ease);
}

/* every sub-item stays an individual link — dots are drawn in CSS so all 29
   links survive instead of collapsing into one grey sentence */
.gw-subs { margin-top: 9px; display: flex; flex-wrap: wrap; align-items: baseline; }
.gw-subs a {
  font-size: 13.5px; line-height: 1.5; color: var(--fam-200);
  transition: color .22s var(--ease);
}
.gw-subs a:hover { color: #fff; }
.gw-subs a:not(:last-child)::after { content: "·"; margin: 0 9px; color: rgba(255,255,255,.34); }

.gw-chev {
  width: 44px; height: 44px; border-radius: 50%; justify-self: end;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid transparent; color: var(--fam-300);
  transition: background .28s var(--ease), border-color .28s var(--ease), color .28s var(--ease), transform .28s var(--ease);
}
.gw-chev svg { width: 21px; height: 21px; }

/* ---- hover / focus state -------------------------------------------
   Sibling dimming: hovering the list drops every row, then the hovered
   row is restored. Reads as focus rather than as decoration, and costs
   one extra selector.
   -------------------------------------------------------------------- */
@media (hover: hover) {
  .gw-list:hover .gw-row { opacity: .45; }
  .gw-list .gw-row:hover { opacity: 1; }
  .gw-row:hover { padding-left: 20px; }
  .gw-row:hover::before { transform: scaleY(1); }
  .gw-row:hover { background-size: 100% 100%; }
  .gw-row:hover h3 a::after { transform: scaleX(1); }
  .gw-row:hover .gw-subs a { color: rgba(255,255,255,.92); }
  .gw-row:hover .gw-chev { background: #fff; border-color: #fff; color: var(--fam-700); transform: translateX(4px); }
}
/* keyboard parity — same treatment without depending on a pointer */
.gw-row:focus-within { padding-left: 20px; opacity: 1; }
.gw-row:focus-within::before { transform: scaleY(1); }
.gw-row:focus-within { background-size: 100% 100%; }
.gw-row:focus-within h3 a::after { transform: scaleX(1); }
.gw-row:focus-within .gw-chev { background: #fff; border-color: #fff; color: var(--fam-700); }

@media (prefers-reduced-motion: reduce) {
  .gw-row, .gw-row::before, .gw-row h3 a::after, .gw-chev, .gw-subs a, .gw-claim .btn svg { transition: none; }
  .gw-row:hover { padding-left: 0; }
}

@media (max-width: 1000px) {
  .gw-split { grid-template-columns: 1fr; gap: 40px; }
  .gw-claim { position: static; }
  .gw-claim p { max-width: 62ch; }
}
@media (max-width: 640px) {
  .gw-split { gap: 30px; }
  .gw-row { grid-template-columns: minmax(0,1fr) 34px; padding: 18px 0 16px; gap: 12px; }
  .gw-row h3 { font-size: 18px; }
  .gw-subs a { font-size: 12.5px; }
  .gw-subs a:not(:last-child)::after { margin: 0 7px; }
  .gw-chev { width: 34px; height: 34px; }
  .gw-chev svg { width: 18px; height: 18px; }
}

/* ---- retire the #f5821f orange on this family --------------------
   ".head-arrow" ships orange sitewide. Scoped to .pg-services only,
   so solutions.html / technology.html keep their current look until
   those families get their own palettes.
   ------------------------------------------------------------------ */
.pg-services .head-arrow { color: var(--fam-700); border-color: var(--c-line); }
.pg-services .head-arrow:hover { background: var(--fam-700); border-color: var(--fam-700); color: #fff; }
.psection--deep .head-arrow { color: #fff; border-color: rgba(255,255,255,.38); }
.psection--deep .head-arrow:hover { background: #fff; border-color: #fff; color: var(--fam-700, #0436AB); }

/* ============================================================
   CREDENTIAL SPLIT — image anchor + capability stack
   For proof sections rather than directories: the sub-items are
   <span>, not links, so tags are outlined spec labels with NO
   hover state — a pill that lights up would promise a click that
   never comes.
   ============================================================ */
/* tighter gap than a normal two-column split: these are a matched PAIR of
   panels, not two independent columns, and 50px+ read as unrelated */
.tl-split { display: grid; grid-template-columns: .92fr 1.08fr; gap: 0 24px; align-items: stretch; margin-top: 46px; }

/* ---- left: the anchor ---- */
.tl-figure {
  position: relative; min-height: 560px; border-radius: 14px; overflow: hidden;
  background: var(--img) center/cover no-repeat, var(--fam-900);
}
.tl-figure::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(var(--fam-shadow-900, 1,28,113),0) 30%, rgba(var(--fam-shadow-900, 1,28,113),.6) 60%, rgba(var(--fam-shadow-900, 1,28,113),.95) 100%);
}
.tl-figure-stats {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  display: grid; grid-template-columns: 1fr 1fr; gap: 24px 18px;
  padding: 32px 32px 30px;
}
.tl-stat .n {
  font-size: 40px; font-weight: 900; line-height: .95; letter-spacing: -.035em; color: #fff;
  font-variant-numeric: tabular-nums;
}
.tl-stat .l { margin-top: 6px; font-size: 13px; line-height: 1.4; color: var(--fam-200); }

/* ---- right: the capability stack ----------------------------------
   Carries the SAME shell as the image — 14px radius, matched height —
   so the two halves read as a pair. Bare text on white next to a solid
   dark card looks unfinished, whatever the spacing.
   space-between at natural row height rather than flex:1: equal rows
   would centre short content and leave lopsided internal gaps.
   -------------------------------------------------------------------- */
.tl-stack {
  display: flex; flex-direction: column; justify-content: space-between;
  background: var(--fam-tint-2, #f5f8fe); border: 1px solid var(--fam-line, #e4ebf8); border-radius: 14px;
  padding: 30px 32px;
}
.tl-row { padding-bottom: 22px; border-bottom: 1px solid var(--fam-rule, #e2e9f6); }
.tl-row:last-child { padding-bottom: 0; border-bottom: none; }

/* label left, count right, on a shared baseline with a gradient tick
   tying the group back to the family ramp */
.tl-row-head { display: flex; align-items: center; gap: 11px; margin-bottom: 16px; }
.tl-row-head::before {
  content: ""; width: 3px; height: 15px; border-radius: 2px; flex-shrink: 0;
  background: var(--fam-grad);
}
.tl-row h3 {
  font-size: 13px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
  color: var(--fam-700);
}

.tl-tags { display: flex; flex-wrap: wrap; gap: 9px; }
/* white on the tinted panel — the previous white-on-white left them with
   no edge and made the whole column look like loose text */
.tl-tags span {
  font-size: 13px; font-weight: 500; line-height: 1;
  padding: 9px 13px; border-radius: 6px;
  border: 1px solid var(--fam-line-2, #dde5f2); color: var(--fam-ink-2, #414c66); background: #fff;
}

/* certifications carry the real marks — stronger proof than the words,
   and it stops the shortest group looking underfed. Equal min-width so a
   square seal and a wide wordmark still sit as a matched row. */
.tl-badges { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.tl-badge {
  display: flex; align-items: center; justify-content: center;
  min-width: 112px; height: 60px; padding: 0 18px;
  border: 1px solid var(--fam-line-2, #dde5f2); border-radius: 8px; background: #fff;
}
.tl-badge img { max-height: 40px; max-width: 104px; width: auto; object-fit: contain; }
.tl-badge--text { font-size: 13px; font-weight: 600; color: var(--fam-ink-2, #414c66); letter-spacing: -.01em; }

/* ---- head-arrow wrap fix ------------------------------------------
   ".svc-dir-head h2" is a flex row, so a long title and the arrow are
   two unshrinkable items and the arrow drops to its own line. Wrapping
   the text in a span lets the TEXT wrap instead, keeping the arrow
   beside it. Scoped to --split, where the column is narrow enough for
   this to bite.
   -------------------------------------------------------------------- */
/* line-height: the sitewide heading leading is 1.0, which at this weight and
   size closes the gap between wrapped lines to almost nothing — "& Rollout"
   sat tight under "SAP Implementation". Only the split-head title wraps often
   enough for it to matter, so the looser leading is scoped here. */
.svc-dir-head--split .svc-title h2 { flex-wrap: nowrap; align-items: center; line-height: 1.12; }
.svc-dir-head--split .svc-title h2 > span { min-width: 0; }

/* ---- "SAP" as a separate word ---------------------------------------
   The service-detail intro headings read "SAP <service name>", and at this
   size the heading's -.025em tracking pulls the two into one word. Widen
   the space between them.

   It has to be a nested span inside the wrapper span above, NOT a second
   flex item: the row is nowrap and centre-aligned, so a title that wraps
   ("SAP Implementation & Rollout" in a 460px column) would leave "SAP"
   floating vertically centred beside a two-line block. As inline content
   it wraps as ordinary text and stays on the first line.

   The markup carries NO literal space either side of this span, so the
   margin IS the whole gap — roughly double a word space at this size,
   which is what makes the two read as separate words rather than one.
   ---------------------------------------------------------------------- */
.svc-title h2 .h-sap { margin-right: .45em; }

@media (max-width: 940px) {
  .tl-split { grid-template-columns: 1fr; gap: 18px; margin-top: 32px; }
  .tl-figure { min-height: 340px; }
  .tl-stack { gap: 22px; padding: 26px 24px; }
  .tl-row { padding-bottom: 20px; }
}
@media (max-width: 560px) {
  .tl-figure { min-height: 280px; }
  .tl-figure-stats { padding: 24px 20px 20px; gap: 18px 14px; }
  .tl-stat .n { font-size: 30px; }
  .tl-stat .l { font-size: 12px; }
  .tl-stack { padding: 22px 20px; }
  .tl-badge { min-width: 0; height: 50px; padding: 0 14px; }
  .tl-badge img { max-height: 30px; max-width: 84px; }
}

/* ============================================================
   ICON QUADRANT — four capabilities as four cards
   For short capability sets that a full directory row would
   over-house. Introduces iconography, the one visual device the
   other sections do not use, and pairs each item with a line of
   copy rather than a bare title over 2-3 links.
   ============================================================ */
/* light blue band — keeps section 4 inside the family without
   spending the deep band a second time after the section 2 gateway */
.psection--tint { background: var(--fam-tint, #f2f6fd); }

.iq-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 46px; }
.iq-card {
  position: relative; display: flex; flex-direction: column;
  background: #fff; border: 1px solid var(--fam-line, #e4ebf8); border-radius: 14px;
  padding: 30px 30px 26px; overflow: hidden;
  transition: transform .32s var(--ease), box-shadow .32s var(--ease), border-color .32s var(--ease);
}
.iq-card::before {
  content: ""; position: absolute; left: 0; top: 0; height: 3px; width: 100%;
  background: var(--fam-grad); transform: scaleX(0); transform-origin: left;
  transition: transform .45s var(--ease); z-index: 3;
}
/* diagonal sheen passing across the card on hover — reads as light moving
   over a surface rather than the card simply changing colour */
.iq-card::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: -60%; width: 45%;
  background: linear-gradient(100deg, transparent 0%, rgba(var(--fam-glow, 92,145,251),.13) 50%, transparent 100%);
  transform: skewX(-14deg); pointer-events: none; z-index: 2; opacity: 0;
  transition: left .75s var(--ease), opacity .3s var(--ease);
}
@media (hover: hover) {
  .iq-card:hover { transform: translateY(-4px); box-shadow: 0 18px 38px rgba(var(--fam-shadow, 4,54,171),.12); border-color: var(--fam-400); }
  .iq-card:hover::before { transform: scaleX(1); }
  .iq-card:hover::after { left: 115%; opacity: 1; }
}
.iq-card:focus-within::before { transform: scaleX(1); }
/* keep real content above both decorative layers */
.iq-card > * { position: relative; z-index: 4; }

/* oversized ghost repeat of the card's own icon. Anchored TOP-RIGHT:
   it echoes the solid icon tile diagonally opposite at top-left, and it
   is as far as possible from the arrow — the bottom-right position read
   as a collision because the glyph ran through the arrow's ring. */
.iq-watermark {
  position: absolute; right: -20px; top: -24px; z-index: 1;
  color: var(--fam-700); opacity: .055; pointer-events: none;
  transition: opacity .4s var(--ease), transform .5s var(--ease);
}
.iq-watermark svg { width: 150px; height: 150px; }
/* drifts gently inward, nowhere near the arrow at the opposite corner */
.iq-card:hover .iq-watermark { opacity: .1; transform: translate(-5px, 5px) rotate(-4deg); }

.iq-icon {
  width: 48px; height: 48px; border-radius: 12px; margin-bottom: 20px;
  display: flex; align-items: center; justify-content: center;
  background: var(--fam-chip, #e7effc); color: var(--fam-700);
  transition: background .3s var(--ease), color .3s var(--ease), transform .35s var(--ease), box-shadow .35s var(--ease);
}
.iq-icon svg { width: 24px; height: 24px; }
.iq-card:hover .iq-icon {
  background: var(--fam-grad); color: #fff;
  transform: translateY(-2px) scale(1.06);
  box-shadow: 0 10px 22px rgba(var(--fam-shadow, 4,54,171),.28);
}

.iq-card h3 { font-size: 20px; font-weight: 700; letter-spacing: -.02em; line-height: 1.25; }
.iq-card h3 a { color: var(--c-ink); transition: color .18s var(--ease); }
.iq-card:hover h3 a { color: var(--fam-700); }
.iq-card > p { margin-top: 10px; font-size: 14.5px; line-height: 1.6; color: var(--c-body); max-width: 42ch; }

/* the rule above the sub-links grows in from the left on hover instead of
   sitting as a static divider */
.iq-subs {
  margin-top: 18px; padding-top: 16px; display: flex; flex-wrap: wrap; align-items: baseline;
  background-image: linear-gradient(90deg, var(--fam-400) 0%, var(--fam-rule-2, #eaf0fa) 100%);
  background-repeat: no-repeat; background-position: 0 0; background-size: 34px 1px;
  transition: background-size .5s var(--ease);
}
.iq-card:hover .iq-subs { background-size: 100% 1px; }
.iq-subs a { font-size: 13.5px; color: var(--fam-ink-3, #4a5570); transition: color .18s var(--ease); }
.iq-subs a:hover { color: var(--fam-700); }
.iq-subs a:not(:last-child)::after { content: "·"; margin: 0 9px; color: var(--fam-dot, #b9c5db); }

.iq-go { margin-top: auto; padding-top: 22px; display: flex; justify-content: flex-end; }
.iq-go span {
  width: 42px; height: 42px; border-radius: 50%;
  border: 1px solid var(--fam-line-2, #dde5f2); display: flex; align-items: center; justify-content: center;
  /* solid fill, not transparent — an unfilled ring lets whatever sits
     behind it (watermark, sheen) show through the middle */
  background: #fff; color: var(--fam-700);
  transition: background .25s var(--ease), border-color .25s var(--ease), color .25s var(--ease);
}
.iq-go svg { width: 19px; height: 19px; transition: transform .25s var(--ease); }
.iq-card:hover .iq-go span { background: var(--fam-700); border-color: var(--fam-700); color: #fff; }
.iq-card:hover .iq-go svg { transform: translateX(3px); }

@media (max-width: 860px) {
  .iq-grid { grid-template-columns: 1fr; gap: 14px; margin-top: 30px; }
  .iq-card { padding: 24px 22px 20px; }
  .iq-icon { width: 42px; height: 42px; margin-bottom: 16px; }
  .iq-card h3 { font-size: 18px; }
  /* at one column the card is narrow enough that the watermark sits right
     behind the title and description instead of clear of them */
  .iq-watermark { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .iq-card, .iq-card::before, .iq-card::after, .iq-icon, .iq-watermark, .iq-subs, .iq-go span, .iq-go svg { transition: none; }
  .iq-card::after { display: none; }
  .iq-card:hover { transform: none; }
}
  

/* ============================================================
   INDUSTRY TILES + OFFER STRIP
   Section 5 held three unrelated things in one grid: six verticals,
   a productised offer, and a credibility block. Split in two —
   industries lead as image tiles (each vertical has a matching
   image already in the library), and the two offers close the
   section as a paired strip so they stop competing with the
   sector list.
   ============================================================ */
.ig-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 46px; }

.ig-tile {
  position: relative; display: flex; flex-direction: column; justify-content: flex-end;
  aspect-ratio: 4 / 3.1; border-radius: 14px; overflow: hidden;
  background: var(--fam-900);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
/* separate media layer so the image can scale without dragging the caption */
.ig-media {
  position: absolute; inset: 0; background: var(--img) center/cover no-repeat;
  transition: transform .7s var(--ease);
}
.ig-tile::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(var(--fam-shadow-900, 1,28,113),.05) 30%, rgba(var(--fam-shadow-900, 1,28,113),.62) 62%, rgba(var(--fam-shadow-900, 1,28,113),.93) 100%);
  transition: background .35s var(--ease);
}
@media (hover: hover) {
  .ig-tile:hover { transform: translateY(-4px); box-shadow: 0 20px 40px rgba(var(--fam-shadow-900, 1,28,113),.24); }
  .ig-tile:hover .ig-media { transform: scale(1.07); }
  .ig-tile:hover::after { background: linear-gradient(180deg, rgba(var(--fam-shadow-900, 1,28,113),.2) 20%, rgba(var(--fam-shadow, 4,54,171),.74) 58%, rgba(var(--fam-shadow, 4,54,171),.96) 100%); }
}

.ig-body { position: relative; z-index: 1; padding: 22px 22px 20px; }
.ig-body h3 { font-size: 19px; font-weight: 700; letter-spacing: -.02em; line-height: 1.25; }
.ig-body h3 a { color: #fff; display: inline-flex; align-items: center; gap: 9px; }
.ig-body h3 svg { width: 18px; height: 18px; opacity: 0; transform: translateX(-6px); transition: opacity .28s var(--ease), transform .28s var(--ease); }
.ig-tile:hover h3 svg, .ig-tile:focus-within h3 svg { opacity: 1; transform: none; }
.ig-tags { margin-top: 8px; display: flex; flex-wrap: wrap; align-items: baseline; }
.ig-tags a { font-size: 12.5px; line-height: 1.5; color: var(--fam-200); transition: color .18s var(--ease); }
.ig-tags a:hover { color: #fff; }
.ig-tags a:not(:last-child)::after { content: "·"; margin: 0 7px; color: rgba(255,255,255,.4); }
/* touch has no hover to reveal the arrow */
@media (hover: none) { .ig-body h3 svg { opacity: 1; transform: none; } }

/* ---- the two offers, kept out of the industry grid ---- */
.of-strip { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 18px; }
.of-card {
  position: relative; border-radius: 14px; padding: 28px 30px; overflow: hidden;
  background: var(--fam-tint, #f2f6fd); border: 1px solid var(--fam-line, #e4ebf8);
  transition: border-color .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
.of-card::before {
  content: ""; position: absolute; left: 0; top: 0; height: 3px; width: 100%;
  background: var(--fam-grad); transform: scaleX(0); transform-origin: left;
  transition: transform .45s var(--ease);
}
@media (hover: hover) {
  .of-card:hover { border-color: var(--fam-400); transform: translateY(-3px); box-shadow: 0 16px 34px rgba(var(--fam-shadow, 4,54,171),.1); }
  .of-card:hover::before { transform: scaleX(1); }
}
.of-card:focus-within { border-color: var(--fam-400); }
.of-card:focus-within::before { transform: scaleX(1); }
.of-card .eyebrow { margin-bottom: 10px; }
.of-card h3 { font-size: 22px; font-weight: 700; letter-spacing: -.025em; line-height: 1.2; }
.of-card h3 a { color: var(--c-ink); transition: color .18s var(--ease); }
.of-card:hover h3 a { color: var(--fam-700); }
.of-card > p { margin-top: 10px; font-size: 14.5px; line-height: 1.6; color: var(--c-body); max-width: 46ch; }
.of-chips { margin-top: 16px; display: flex; flex-wrap: wrap; gap: 8px; }
.of-chips a {
  font-size: 12.5px; font-weight: 500; line-height: 1; padding: 8px 12px; border-radius: 999px;
  background: #fff; border: 1px solid var(--fam-line-2, #dde5f2); color: var(--fam-ink-2, #414c66);
  transition: background .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
}
.of-chips a:hover { background: var(--fam-700); border-color: var(--fam-700); color: #fff; }

@media (max-width: 1000px) {
  .ig-grid { grid-template-columns: 1fr 1fr; }
  .of-strip { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  .ig-grid { grid-template-columns: 1fr; gap: 14px; margin-top: 30px; }
  .ig-tile { aspect-ratio: 16 / 10; }
  .of-strip { gap: 14px; }
  .of-card { padding: 24px 22px; }
  .of-card h3 { font-size: 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .ig-tile, .ig-media, .ig-tile::after, .ig-body h3 svg, .of-card, .of-card::before { transition: none; }
  .ig-tile:hover, .of-card:hover { transform: none; }
}

/* ============================================================================
   SOLUTIONS FAMILY COMPONENTS
   ============================================================================
   Every rule below reads the --fam-* role contract and never a literal family
   colour, so these components work on any family that fills in the roles.

   Design note that shaped the whole set: the image library cannot support a
   photographic Solutions page. The filenames promise subjects the files do not
   contain (svc-ai.jpg is a night street, svc-app.jpg a baseball glove,
   ind-finance.jpg fireworks), and a decorative photo under a heading like
   "Analytics, planning & data" reads as filler. So Solutions is typographic
   and gradient-led where Services is photographic. Same structure, different
   surface — which also means the violet carries the page rather than competing
   with whatever colour happens to dominate a stock frame.
   ========================================================================= */


/* ---- statement variant of the closing band ------------------------
   .dx-band ships as a photo with a small caption tucked along the
   bottom edge. This variant keeps the photograph but grades it hard
   into the family's darkest step and floats a statement over it at
   headline size, so the image reads as a surface the type sits on
   rather than as a picture with a caption bolted underneath.

   The scrim runs on the DIAGONAL, not top-to-bottom like the base
   band — the type sits left, so the density has to be left too, and
   the photograph stays readable on the right where nothing overlaps.
   ------------------------------------------------------------------- */
.dx-band--statement { min-height: 340px; display: flex; align-items: center; }
.dx-band--statement::after {
  background: linear-gradient(104deg,
    rgba(52,17,126,.92) 0%, rgba(52,17,126,.72) 38%,
    rgba(73,26,177,.42) 68%, rgba(73,26,177,.22) 100%);
}
.dx-band--statement .dx-band-cap {
  position: static; padding: 0 44px; max-width: 40ch;
  font-size: clamp(20px, 2.1vw, 27px); font-weight: 500; letter-spacing: -.022em; line-height: 1.38;
}
.dx-band-cap b { font-weight: 700; color: var(--fam-300); }
@media (max-width: 700px) {
  .dx-band--statement { min-height: 260px; }
  .dx-band--statement .dx-band-cap { padding: 0 22px; max-width: none; }
}

/* The gateway band deliberately carries NO photograph. Measured at
   1240px the claim column is 506px against the list's 549px — the two
   already balance, and the apparent gap under the CTA is the sticky
   claim moving relative to the list while scrolling, not a short
   column. Any figure there pushes the left side ~230px past the right.
   The photographs live in §1's band and §5's route tiles instead. */


/* ============================================================
   §3 DESIGN B — LAYERED DATA STACK  (.ds-*)
   Analytics is the one section on this page with a real internal
   order: a data foundation at the bottom, consumption at the top.
   Drawn as a stack with a consumption/foundation axis beside it,
   the five groups stop being an alphabetised list and start being
   an architecture.

   Nothing here is a link — the source markup is <span> — so no
   rule below lights up on hover. A chip that responds to the
   pointer promises a click that never comes.
   ============================================================ */
.ds-stack { display: grid; grid-template-columns: 66px minmax(0, 1fr); gap: 0 22px; margin-top: 46px; }

.ds-axis { display: flex; flex-direction: column; align-items: center; padding: 4px 0; }
.ds-axis b {
  font-size: 10px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  color: var(--fam-700); writing-mode: vertical-rl; text-orientation: mixed; white-space: nowrap;
}
.ds-axis b:last-child { color: var(--fam-ink-3); }
.ds-axis-line {
  flex: 1; width: 3px; min-height: 40px; margin: 12px 0; border-radius: 2px;
  background: linear-gradient(180deg, var(--fam-400) 0%, var(--fam-700) 100%);
}

.ds-layers { display: flex; flex-direction: column; gap: 10px; }
.ds-layer {
  position: relative; overflow: hidden;
  display: grid; grid-template-columns: minmax(0, 290px) minmax(0, 1fr); gap: 0 28px; align-items: center;
  padding: 20px 24px 20px 26px;
  background: var(--fam-tint); border: 1px solid var(--fam-line); border-radius: 14px;
}
.ds-layer::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--fam-grad);
}
.ds-layer-head { display: flex; align-items: center; gap: 12px; }
.ds-tier {
  flex-shrink: 0; font-size: 11px; font-weight: 800; letter-spacing: .06em;
  padding: 5px 9px; border-radius: 5px;
  background: var(--fam-chip); color: var(--fam-700);
}
.ds-layer h3 { font-size: 17px; font-weight: 700; letter-spacing: -.02em; line-height: 1.24; color: var(--c-ink); }
.ds-chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: flex-end; }
.ds-chips span {
  font-size: 12.5px; font-weight: 500; line-height: 1;
  padding: 8px 12px; border-radius: 6px;
  background: #fff; border: 1px solid var(--fam-line-2); color: var(--fam-ink-2);
}

@media (max-width: 900px) {
  /* the axis stops earning its column at this width — the stack order is
     still legible from the tier badges alone */
  .ds-stack { grid-template-columns: 1fr; }
  .ds-axis { display: none; }
  .ds-layer { grid-template-columns: 1fr; gap: 14px 0; padding: 20px 22px 20px 24px; }
  .ds-chips { justify-content: flex-start; }
}
@media (max-width: 560px) {
  .ds-layer h3 { font-size: 16px; }
  .ds-chips span { font-size: 12px; padding: 7px 10px; }
}


/* ============================================================
   TOOLCHAIN STRIP  (.tc-*)
   Shared closer for §5 designs A and C. The six tools in this
   section are not deployment routes — they are what we bring to
   any route — so they sit apart from the routes rather than in
   the same grid pretending to be siblings.
   ============================================================ */
.tc-panel {
  margin-top: 18px;
  display: grid; grid-template-columns: minmax(0, 220px) minmax(0, 1fr); gap: 0 32px; align-items: center;
  background: var(--fam-tint); border: 1px solid var(--fam-line); border-radius: 14px;
  padding: 26px 30px;
}
.tc-head .eyebrow { margin-bottom: 6px; }
.tc-head h3 { font-size: 19px; font-weight: 700; letter-spacing: -.025em; line-height: 1.2; color: var(--c-ink); }
.tc-list { display: flex; flex-wrap: wrap; gap: 10px; }
.tc-item {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 10px 14px; border-radius: 8px;
  background: #fff; border: 1px solid var(--fam-line-2);
  font-size: 13.5px; font-weight: 500; line-height: 1; color: var(--fam-ink-2);
  transition: border-color .2s var(--ease), color .2s var(--ease), box-shadow .2s var(--ease);
}
.tc-item svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--fam-700); transition: color .2s var(--ease); }
a.tc-item:hover, a.tc-item:focus-visible {
  border-color: var(--fam-400); color: var(--fam-700);
  box-shadow: 0 8px 18px rgba(var(--fam-shadow), .1);
}

@media (max-width: 820px) {
  .tc-panel { grid-template-columns: 1fr; gap: 18px 0; padding: 24px 22px; }
}
@media (prefers-reduced-motion: reduce) { .tc-item, .tc-item svg { transition: none; } }


/* ============================================================
   §5 ROUTE TILES
   Reuses the industry-tile geometry from the Services page. The
   photographs show the kind of landscape each route serves — a
   process plant for RISE, a consumer business for GROW, an in-house
   IT floor for the hyperscaler build — rather than trying to
   picture the route itself, which has no photograph.

   .ig-tile's scrim already resolves through --fam-shadow-900, so
   these grade violet with no extra rule.
   ============================================================ */
/* .ig-tile's scrim is near-transparent at the top — it is built to darken the
   BOTTOM, where the caption sits. So the route mark needs to carry its own
   backdrop rather than trusting the image behind it: at 11px uppercase it is
   not large text, and over a bright frame (the plant, the supermarket) an
   unbacked --fam-300 drops to ~2.6:1. Solid-ish violet plate + white gets it
   past 5:1 on any photograph in the library. */
.ig-mark {
  position: absolute; top: 18px; left: 18px; z-index: 2;
  padding: 6px 11px; border-radius: 999px;
  background: rgba(var(--fam-shadow-900), .72);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 1px solid rgba(208,188,252,.22);
  font-size: 10.5px; font-weight: 800; letter-spacing: .11em; text-transform: uppercase;
  color: #fff;
}

/* ============================================================
   SERVICES — PINNED HORIZONTAL DIRECTORY
   The heading block pins at the top of the screen; underneath it
   the service rows travel sideways, one card at a time.

   Each service becomes its own tinted card. Type scale, colours and
   hover behaviour are the authored ones — only the box changes.

   Gated behind ".dxh-on", added by js/services-scroll.js only once
   GSAP + ScrollTrigger are live and motion is allowed. With JS off,
   or on prefers-reduced-motion, none of this applies and the
   directory keeps its original vertical layout.

   The 26px gap is read back by js/services-scroll.js to size each
   step, so cards and scroll stay in register — no magic number.
   ============================================================ */
.dxh-on {
  position: relative;
  z-index: 1;
  /* the run hands straight over to the SAP solutions band */
  padding-bottom: 0;
}

/* Fills the screen while pinned so no dead white band is left under the
   cards. min-height, not height: if a card's copy ever outgrows the
   viewport the stage grows with it instead of clipping the copy. */
.dxh-on .dxh-stage {
  overflow: hidden;        /* clips the services still queued off to the right */
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - var(--header-h) - 48px);
  min-height: calc(100svh - var(--header-h) - 48px);   /* stable on mobile */
  /* room inside the clip for the top card's shadow to fall */
  padding-bottom: 30px;
  /* The clip box reaches 16px into the container's gutter so the card being
     covered can show a sliver of its edge. Equal padding cancels the
     negative margin, so the heading and cards do not move. 16px is inside
     the narrowest gutter the container uses (20px), so nothing overflows. */
  margin-inline: -16px;
  padding-inline: 16px;
  /* Opaque: while pinned this element is position:fixed, and anything it
     ever overlaps must not read through it. Transparent, it showed the hero
     straight through the cards during the scroll-up handoff. */
  background: #fff;
}

/* the frame the cards stack inside. Every card is absolutely positioned
   on top of it, so an incoming service COVERS the one already there
   instead of pushing it along. */
.dxh-on .dx-index {
  position: relative;
  flex: 1 1 auto;          /* takes whatever height the heading leaves */
  min-height: 430px;       /* stage grows rather than crushing the cards */
  display: block;
  border-top: 0;           /* the card edge replaces the list rule */
}

/* one service = one tinted card filling the frame */
.dxh-on .dx-item {
  position: absolute;
  inset: 0;
  width: auto;
  padding: 44px 46px 40px;
  background-color: var(--fam-tint, #f2f6fd);
  border-radius: 14px;
  border-bottom: 0;
  /* the row fills the card, and align-items:start (inherited) keeps the
     number and heading pinned to the top of it */
  align-content: stretch;
  /* wider numeral gutter — the card-scale numeral needs more than the
     104px the compact row gave it */
  grid-template-columns: clamp(120px, 12vw, 186px) minmax(0, 1fr) 168px;
  will-change: transform;
  /* No shadow here on purpose. Six stacked cards all casting one piles the
     halos up around the top card, which is what looked wrong. The shadow is
     switched on for the card on top of the pile and off again once the next
     card covers it — see SHADOW in js/services-scroll.js. */
}
/* the row's bottom rule would sit outside the rounded corner */
.dxh-on .dx-item::after { display: none; }

/* Each card is inset:0 inside a viewport-height frame, so a card whose copy
   runs longer than the card is tall painted its tail OUTSIDE its own rounded
   box — visible under the card on top of it, reading as stray text belonging
   to nothing. Clip to the card. This is a backstop, not a licence for long
   copy: a card's copy still has to fit the shortest viewport it will be read
   on (~700px tall laptop), or the tail is now silently cut instead. */
.dxh-on .dx-item { overflow: hidden; }

/* ---- kill the list-hover behaviours ---------------------------------
   Both were written for a vertical list of rows and misfire on a stack.

   The dimming is the important one: it fades every card except the one
   under the cursor, so mid-slide — cursor still over the OLD card — the
   incoming card renders at 45% and you see straight through it.

   The wash is a left-anchored gradient meant to light one row of a list;
   across a full card it just reads as a smudge. ------------------------- */
.dxh-on .dx-index:hover .dx-item,
.dxh-on .dx-index .dx-item:hover { opacity: 1; }
.dxh-on .dx-item,
.dxh-on .dx-item:hover { background-image: none; }

/* ---- card-scale type ---------------------------------------------
   Bigger heading, bigger sub-links — both fluid so they track the card
   rather than being pinned to the compact-row sizes. ------------------ */
.dxh-on .dx-title { font-size: clamp(30px, 2.7vw, 46px); line-height: 1.1; }
/* the heading carries the accent outright rather than earning it on hover.
   The second rule outranks ".dx-item:hover .dx-title a", which is one class
   heavier than the first — without it the hover would still win. */
.dxh-on .dx-title a { color: var(--dx-accent); }
/* …and where the card's heading is plain text rather than a link (a service
   whose sub-items have no page of their own — services/consulting.html), the
   colour has to land on the heading itself or it falls back to ink. */
.dxh-on .dx-title { color: var(--dx-accent); }
.dxh-on .dx-item:hover .dx-title a,
.dxh-on .dx-item:focus-within .dx-title a { color: var(--dx-accent); }
.dxh-on .dx-tags {
  margin-top: clamp(22px, 3vh, 38px);
  /* roomy but even. Rows breathe into the card without being flung to its
     far corners — a little space left under the shorter lists is fine. */
  gap: clamp(16px, 2.7vh, 34px) 44px;
}
/* span as well as a: on a service page the sub-items are statements, not
   links, and without this they stay at compact-row size on a full-size card */
.dxh-on .dx-tags a,
.dxh-on .dx-tags span {
  font-size: clamp(16px, 1.2vw, 21px);
  padding-left: 28px;
}
.dxh-on .dx-tags a::before,
.dxh-on .dx-tags span::before { width: 14px; }
.dxh-on .dx-item:hover .dx-tags a::before,
.dxh-on .dx-item:hover .dx-tags span::before { width: 20px; }

/* ---- card lede -----------------------------------------------------
   A sentence of real context under each heading, which is what fills the
   card rather than stretched whitespace. Hidden outside the stage so the
   plain vertical fallback keeps its authored two-line row. ------------- */
.dx-lede { display: none; }
.dxh-on .dx-lede {
  display: block;
  margin-top: clamp(12px, 1.6vh, 20px);
  max-width: 68ch;
  font-size: clamp(15px, 1.05vw, 18.5px);
  line-height: 1.62;
  color: var(--dx-sub);
}

/* NOTE: the link rows are deliberately NOT stretched to the card's full
   height. Forcing space-between flung a 2-row list to the card's top and
   bottom edges with a void between them, which read as broken rather than
   spacious. The even gap above does the filling instead. */

/* ---- numeral, at card scale --------------------------------------
   Sized off viewport height so it grows with the card rather than
   fighting it. Hover only deepens the same light blue by one step —
   the sitewide rule jumps it to the full accent, which is far too
   loud on a numeral this large. -------------------------------------- */
/* The colour is set straight on the numeral, NOT routed through a variable
   on .dxh-on: --dx-accent is declared on .dx-index, a descendant of the
   section, so a "--dxh-num: var(--dx-accent)" declared up there resolves
   against nothing and the numeral silently falls back to inheriting ink. */
.dxh-on .dx-num {
  font-size: clamp(46px, 7.5vh, 104px);
  color: var(--dx-accent);   /* the exact blue .dx-title a uses */
}
.dxh-on .dx-item:hover .dx-num,
.dxh-on .dx-item:focus-within .dx-num { color: var(--fam-800, #012a86); }

@media (max-width: 1080px) {
  /* numeral sits above the copy once the gutter is gone. Only the copy row
     absorbs the spare height — without this, stretch would pad out the
     numeral and CTA rows too. */
  .dxh-on .dx-item {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr auto;
  }
  .dxh-on .dx-cta { grid-column: 1; }
  .dxh-on .dx-num { margin-bottom: 14px; }
}
@media (max-width: 700px) {
  .dxh-on .dxh-stage { min-height: calc(100svh - var(--header-h) - 32px); }
  .dxh-on .dx-item { padding: 26px 22px 24px; }
  .dxh-on .dx-num { font-size: clamp(32px, 5vh, 48px); color: var(--dx-accent); }
}

/* Certified SAP talent — the two halves travel toward the viewport edges as
   they converge in. The section is full-bleed, so clipping here lands on the
   viewport edge (never visible) and prevents a horizontal scrollbar.
   overflow-x: clip where supported, since it creates no scroll container. */
.tl-converge { overflow-x: hidden; overflow-x: clip; }

/* the deep-blue band rises over the services section on exit */
.dxh-next {
  position: relative;
  z-index: 2;
  box-shadow: 0 -26px 60px -18px rgba(11, 10, 38, .32);
}

/* ============================================================
   INTELLIGENCE & AUTOMATION — blue curtain cards
   At rest a --fam-grad curtain covers the card and only the title
   shows, set large and centred. On hover the curtain rolls up off
   the top edge, uncovering the original white card while the body
   expands from zero height beneath the title. CSS only — no JS.
   ============================================================ */
.iq-card {
  /* white underneath — it is what the curtain uncovers */
  background: #fff;
  border-color: transparent;
  color: #fff;
  justify-content: center;      /* title centred while the body is collapsed */
  text-align: center;
  min-height: 250px;
  padding: 34px 30px;
}
/* the icon and its oversized ghost repeat both go */
.iq-icon, .iq-watermark { display: none; }

.iq-card h3 {
  font-size: clamp(24px, 2.3vw, 34px);
  line-height: 1.18;
  transition: font-size .35s var(--ease);
}
.iq-card h3 a { color: #fff; }
/* steps down as the body arrives, so the two share the card comfortably */
.iq-card:hover h3, .iq-card:focus-within h3 { font-size: clamp(20px, 1.7vw, 25px); }

/* Collapsed until hover. max-height rather than the grid-rows trick so a
   single wrapper is enough — the value only needs to clear the tallest body.

   NO transform here on purpose: a transform would make this element the
   containing block for the absolutely positioned .iq-go below, trapping the
   corner arrow inside this box and its overflow clip. */
.iq-reveal {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height .45s var(--ease), opacity .3s var(--ease);
}
.iq-card:hover .iq-reveal,
.iq-card:focus-within .iq-reveal {
  max-height: 340px;
  opacity: 1;
}

/* copy colours for the dark card */
.iq-card > .iq-reveal > p {
  margin: 16px auto 0;
  max-width: 44ch;
  font-size: 15px;
  line-height: 1.62;
  color: rgba(255,255,255,.82);
}
/* divider rule above the sub-links removed — it cut the card in half */
.iq-subs {
  justify-content: center;
  background-image: none;
  margin-top: 18px;
  padding-top: 0;
}
.iq-subs a { font-size: 14px; color: rgba(255,255,255,.74); }
.iq-subs a:hover { color: #fff; }
.iq-subs a:not(:last-child)::after { color: rgba(255,255,255,.4); transition: color .18s var(--ease); }

/* ---- arrow, welded into the bottom-right corner --------------------
   It must be a DIRECT child of .iq-card in the markup: ".iq-card > *"
   gives every direct child position:relative, so while this lived inside
   .iq-reveal that wrapper was its containing block and the button floated
   in the middle of the card, clipped by the wrapper's overflow.

   right/bottom: 0 pins it to the card's inner corner, and the -1px offsets
   pull it over the card's own border so the two edges meet flush.
   -------------------------------------------------------------------- */
.iq-go {
  position: absolute;
  right: -1px;
  bottom: -1px;
  z-index: 4;
  width: 58px;
  height: 58px;
  margin: 0;
  padding: 0;
  /* flex, not grid: the authored rule is "display:flex; justify-content:
     flex-end" at the same specificity, so this restates both properties
     rather than leaving the old alignment to win */
  display: flex;
  align-items: center;
  justify-content: center;
  /* square where it meets the card, rounded only on the outer corner so it
     follows the card's own radius — no soft corner cutting into the card */
  border-left: 1px solid var(--fam-400, #5C91FB);
  border-top: 1px solid var(--fam-400, #5C91FB);
  border-radius: 0 0 14px 0;
  background: #fff;
  /* hidden behind the curtain, arriving as it lifts past the corner */
  opacity: 0;
  transition: opacity .3s var(--ease);
}
.iq-card:hover .iq-go,
.iq-card:focus-within .iq-go { opacity: 1; transition-delay: .28s; }
/* The inner circle goes — the corner square is the button now. The span is
   stretched to fill that square and centres the icon itself, so the arrow is
   dead centre no matter what the outer box's alignment resolves to. */
.iq-card .iq-go span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  color: var(--fam-700, #0436AB);
}
.iq-card .iq-go svg { width: 20px; height: 20px; }
/* the authored ".iq-card:hover .iq-go span" fills the inner span blue to make
   the old circular button — matched here at equal specificity, later in the
   file, so the corner square keeps its clean outline and the arrow stays blue
   on white however you hover it */
.iq-card:hover .iq-go span,
.iq-card:focus-within .iq-go span,
.iq-card .iq-go:hover span { background: none; color: var(--fam-700, #0436AB); }
/* keeps the sub-links clear of the corner button on a narrow card */
.iq-subs { max-width: calc(100% - 56px); margin-inline: auto; }
/* top hairline reads white while the curtain is down */
.iq-card::before { background: linear-gradient(90deg, #fff 0%, var(--fam-200, #88C6FD) 100%); }

@media (max-width: 700px) {
  /* no hover on touch — the body stays open so nothing is unreachable */
  .iq-card { min-height: 0; padding-bottom: 66px; }
  .iq-reveal { max-height: 340px; opacity: 1; }
  .iq-card h3 { font-size: 22px; }
  .iq-go { opacity: 1; }
}

/* ---- the curtain has to open INSIDE the card, never past it ----------
   On services.html every card's revealed body fits inside the 250px floor
   above, so the card is the same height open or shut and the hover is pure
   crossfade — nothing in the grid moves.

   The services/ detail pages carry longer card copy. Measured settled
   heights there ran 269–336px against that same 250px floor, so opening a
   card grew it, grew its GRID ROW with it, and shunted the card beside it
   plus everything below down the page mid-animation. That reflow is what
   read as juddering next to services.html's version — the transition is
   identical, the layout thrash is not.

   Fix is to reserve the space rather than to shorten the copy: the floor
   here is the tallest measured open state per width band, so the card is
   already big enough before the curtain lifts. Three bands because the need
   RISES as the viewport narrows — the two columns get narrower, the body
   rewraps taller — and peaks at 861px, the last width before the 860px
   switch to a single column widens every card again.

   Above 700px only: below that the rule above zeroes the floor and holds
   every body open, which is what touch needs. --------------------------- */
@media (min-width: 701px) {
  .pg-service-detail .iq-card { min-height: 310px; }
}
@media (min-width: 701px) and (max-width: 1280px) {
  .pg-service-detail .iq-card { min-height: 345px; }
}
@media (min-width: 861px) and (max-width: 940px) {
  .pg-service-detail .iq-card { min-height: 365px; }
}

/* ---- hover: the card returns to its original white treatment --------
   A white layer crossfades over the gradient (background-image itself
   cannot be transitioned) and every colour goes back to the authored
   light-surface value. The layer sits at z-index 1, under the content
   at z-index 4, so nothing is washed out.

   This repurposes ".iq-card::after", which was the diagonal sheen — that
   effect was tuned for a white card and has nothing to do on one that is
   already turning white.
   -------------------------------------------------------------------- */
.iq-card::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  width: auto;
  bottom: 0;
  height: auto;
  opacity: 1;
  /* scaleY from the top edge, NOT height or clip-path:
     - height:100% can resolve to auto against an auto-height card, and
       auto -> 0 does not animate at all, which is what killed the roll.
     - a clipped box paints its gradient against the full card, so the lit
       edge would sit still while the blue slid past it.
     Scaling takes the whole painted panel — gradient, hairline and glow —
     up with the edge, and collapses them to nothing at the top. */
  transform: scaleY(1);
  transform-origin: top center;
  z-index: 1;
  pointer-events: none;
  /* Layer stack, front to back:
     1. GRAIN — sub-pixel noise across the whole panel. It breaks the banding
        every large gradient produces on 8-bit displays and gives the surface
        a material instead of the plastic look of pure vector colour. Inline
        SVG, so no image request. This is the single biggest difference
        between a stock gradient and a finished one.
     2. edge light, kept tight — broad white bands fog the panel and read
        cheap, so these are a few percent deep: lit edges at rest, and they
        still ride the roll in motion.
     3. the specular, with its boundary kept but the light dialled right
        down. Real glass reflects a little, not a lot.
     4-6. THREE light sources rather than one ramp. A two-stop gradient is
        what reads flat and synthetic however good the two colours are;
        depth comes from separate glows landing in different places, in
        slightly different hues, the way light actually falls.
     7. a near-black navy base, so the glows above have somewhere dark to
        sit. The old body was mid-blue end to end — one flat value, with
        nothing for the light to read against. */
  background-image:
    /* 1. grain — breaks gradient banding, gives the pane a material */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.32'/%3E%3C/svg%3E"),
    /* 2. edge light: top rim, and the band that rides the leading edge */
    linear-gradient(180deg,
      rgba(255,255,255,.2) 0%,
      rgba(255,255,255,.03) 5%,
      rgba(255,255,255,0) 92%,
      rgba(255,255,255,.32) 100%),
    /* 3. the sheet's own reflection, running off the top-left corner */
    linear-gradient(134deg,
      rgba(255,255,255,.24) 0%,
      rgba(255,255,255,.07) 24%,
      rgba(255,255,255,0) 52%),
    /* 4-6. Out-of-focus shapes reading THROUGH the glass. Glassmorphism is
       blurred colour behind a translucent pane — with an opaque white card
       behind it there is nothing for backdrop-filter to blur, so the blobs
       are painted here instead, soft enough to read as defocused. */
    radial-gradient(44% 58% at 20% 16%, rgba(255,255,255,.15) 0%, rgba(255,255,255,0) 70%),
    radial-gradient(46% 60% at 82% 10%, rgba(160,196,255,.2) 0%, rgba(160,196,255,0) 68%),
    radial-gradient(58% 72% at 88% 92%, rgba(1,28,113,.4) 0%, rgba(1,28,113,0) 72%),
    /* 7. THE fill: the same deep band the .psection--deep gateway section
       uses, so a glass card and the blue band it sits near are one colour
       rather than two blues in the same eyeful. It was --fam-grad before —
       the primary→light ramp — which read as a distinctly paler, mid-blue
       card. Solid, not translucent; the glass comes from the layers above. */
    var(--fam-grad-deep,
      linear-gradient(155deg, #011C71 0%, #012a86 55%, #0436AB 100%));
  background-blend-mode: overlay, normal, normal, normal, normal, normal, normal;
  box-shadow:
    /* the pane's own rim, all the way round — the frosted-edge highlight
       that makes a glass sheet read as a separate surface */
    inset 0 0 0 1px rgba(255,255,255,.3),
    /* lit left edge, the bright rail from the reference */
    inset 2px 0 0 rgba(255,255,255,.36),
    /* fine hairlines top and bottom — the thickness of the pane */
    inset 0 1px 0 rgba(255,255,255,.45),
    inset 0 -1px 0 rgba(255,255,255,.6),
    /* the glass sits slightly proud: shade gathering under its lower edge */
    inset 0 -16px 26px -20px rgba(0,10,58,.55),
    /* light bleeding onto whatever the roll has already uncovered */
    0 12px 28px -8px rgba(var(--fam-shadow-900, 1,28,113), .34);
  transition: transform .55s var(--ease);
}
/* Rolls up off the top edge, bottom to top, its lit edge travelling with it.

   left/right/opacity are restated here because the authored sheen rule
   ".iq-card:hover::after { left: 115%; opacity: 1 }" is still in play at the
   same specificity — it was sliding this panel sideways off the card, which
   is what turned the vertical roll into a horizontal exit. */
.iq-card:hover::after,
.iq-card:focus-within::after {
  transform: scaleY(0);
  left: 0;
  right: 0;
  opacity: 1;
}

/* the colour flip is delayed so it happens as the curtain sweeps past the
   copy, not before it. No delay on the way back — the curtain falls from the
   top, so the text must be white again immediately. */
.iq-card:hover h3 a,
.iq-card:focus-within h3 a { color: var(--fam-700); transition: color .2s var(--ease) .26s; }
.iq-card:hover .iq-reveal p,
.iq-card:focus-within .iq-reveal p { color: var(--c-body); transition: color .2s var(--ease) .3s; }
/* Same delay as the heading. Without it these turned dark while the curtain
   was still behind them, which is what made the sub-links read muddy. */
.iq-card:hover .iq-subs a,
.iq-card:focus-within .iq-subs a { color: var(--fam-ink-3, #4a5570); transition: color .2s var(--ease) .3s; }
.iq-card:hover .iq-subs a:hover { color: var(--fam-700); transition-delay: 0s; }
.iq-card:hover .iq-subs a:not(:last-child)::after,
.iq-card:focus-within .iq-subs a:not(:last-child)::after { color: var(--fam-dot, #b9c5db); transition: color .2s var(--ease) .3s; }
.iq-card:hover::before { background: var(--fam-grad); }

@media (hover: hover) {
  /* lift and edge restated for the white surface it lands on */
  .iq-card:hover {
    border-color: var(--fam-400);
    box-shadow: 0 18px 38px rgba(var(--fam-shadow, 4,54,171), .12);
  }
}

@media (max-width: 700px) {
  /* touch has no hover, so the curtain stays up and the card reads white */
  .iq-card::after { transform: scaleY(0); }
  .iq-card h3 a { color: var(--fam-700); }
  .iq-card .iq-reveal p { color: var(--c-body); }
  .iq-card .iq-subs a { color: var(--fam-ink-3, #4a5570); }
  .iq-card .iq-go span { border-color: var(--fam-line, #e4ebf8); color: var(--fam-700); }
}

/* ---- the roll ends AS the line -------------------------------------
   The glass collapses into the card's top edge and the hairline lights up
   at exactly that moment, so it reads as the panel compressing into a line
   rather than disappearing.

   The authored hairline wipes in left-to-right (scaleX 0 -> 1); that is a
   separate gesture and fights the read, so it is pinned open and revealed
   with opacity instead. The .42s delay is the roll's .55s travel minus the
   fade, and lives only in the hover rule — coming back, the line must go
   the instant the glass starts down again.
   -------------------------------------------------------------------- */
.iq-card::before {
  height: 4px;
  background: var(--fam-grad);
  transform: scaleX(1);
  opacity: 0;
  z-index: 3;
  transition: opacity .18s var(--ease);
}
@media (hover: hover) {
  .iq-card:hover::before { transform: scaleX(1); opacity: 1; transition-delay: .42s; }
}
.iq-card:focus-within::before { transform: scaleX(1); opacity: 1; transition-delay: .42s; }

@media (max-width: 700px) {
  /* no hover on touch: the glass is already rolled up, so the line stays */
  .iq-card::before { opacity: 1; }
}

/* ---- card polish ----------------------------------------------------
   A wider radius and a deeper, tighter shadow: the authored 14px/soft-blur
   pair was tuned for a small white tile in a list, and on a large panel it
   reads flat. -22px spread keeps the shadow under the card rather than
   haloing it, which is the difference between "raised" and "glowing".
   -------------------------------------------------------------------- */
.iq-grid { gap: 22px; }
.iq-card {
  border-radius: 14px;
  box-shadow:
    0 2px 4px rgba(var(--fam-shadow-900, 1,28,113), .06),
    0 18px 40px -22px rgba(var(--fam-shadow-900, 1,28,113), .42);
}
.iq-card::after { border-radius: inherit; }
/* the roll lands in the top edge, so the line follows the same corners */
.iq-card::before { border-radius: 14px 14px 0 0; }
/* the corner button's outer radius has to match the card's new one */
.iq-go { border-radius: 0 0 14px 0; }

/* tighter tracking and a heavier cut — at display size the authored -.02em
   at 700 reads loose */
.iq-card h3 { font-weight: 800; letter-spacing: -.03em; }

@media (hover: hover) {
  .iq-card:hover {
    box-shadow:
      0 2px 4px rgba(var(--fam-shadow-900, 1,28,113), .08),
      0 26px 52px -24px rgba(var(--fam-shadow-900, 1,28,113), .5);
  }
}

@media (max-width: 700px) {
  .iq-card { border-radius: 14px; }
  .iq-card::before { border-radius: 14px 14px 0 0; }
  .iq-go { border-radius: 0 0 14px 0; }
}

/* (the .featured--contained bleed system that lived here was retired
   2026-08-05 — every case-study band now uses the home page's
   .featured-grid--bento structure verbatim) */

/* ---- services: industries carousel arrows -------------------------
   Bigger, and moved off the cards into the page gutter so they stop
   sitting on top of the copy. Scoped by the body class, so the same
   carousel on the service detail pages keeps its authored placement.
   -------------------------------------------------------------------- */
.pg-services .ind-carousel-btn {
  width: 68px;
  height: 68px;
  box-shadow: 0 12px 30px rgba(20, 20, 40, .17);
}
.pg-services .ind-carousel-btn svg { width: 28px; height: 28px; }

/* Only once the gutter can actually hold them. From the carousel's content
   edge there is (100vw - 1240)/2 + 32 of room, so at 1420px the 100px
   offset still leaves a margin before the viewport edge. Narrower than
   that they stay overlaid on the cards — the authored behaviour, and
   better than arrows hanging off the screen where they cannot be clicked. */
@media (min-width: 1420px) {
  .pg-services .ind-carousel-btn--prev { left: -100px; }
  .pg-services .ind-carousel-btn--next { right: -100px; }
}

/* ==========================================================================
   CASE STUDIES — working chip filter + case-study detail pages
   ==========================================================================
   The chip rows under the category tabs used to be decoration: main.js only
   swapped which row was visible. They now filter the masonry for real.

   Model: OR inside a category, AND across categories. Pick "Pharma" and
   "Manufacturing" and you get either; add "SuccessFactors & HXM" on top and
   you get pharma-or-manufacturing AND SuccessFactors. That is the behaviour
   people expect from faceted filters, and it is the only one that keeps
   adding a chip from narrowing the result set monotonically.

   Some chips legitimately match nothing (Automotive, AWS, Azure — no case
   study covers them yet). That is intended: the empty state below says so
   plainly rather than the page silently going blank.
   -------------------------------------------------------------------- */

/* selected chip — the fill inverts, so a scan of the row shows what is on
   without having to read it */
.cs-chip.is-on { background: var(--c-accent); color: #fff; }
.cs-chip.is-on:hover { background: var(--c-blue-deep); color: #fff; }
/* a chip that cannot match anything from here is still clickable — it just
   says so first, rather than letting the reader find out by emptying the grid */
.cs-chip.is-void { color: var(--c-muted); opacity: .6; }
.cs-chip.is-void.is-on { color: #fff; opacity: 1; }

/* active-filter bar — the selected chips live in one place, because the
   chip that switched off the grid is usually in a category tab you are no
   longer looking at */
.cs-filterbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px;
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--c-line);
}
.cs-filterbar[hidden] { display: none; }
.cs-count { font-size: 14px; color: var(--c-body); }
.cs-count strong { color: var(--c-ink); font-weight: 700; }
.cs-active { display: flex; flex-wrap: wrap; gap: 8px; }
.cs-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 11px 6px 13px; border: 1px solid var(--c-line); border-radius: 999px;
  background: var(--c-surface-2); font-size: 13px; font-weight: 600;
  color: var(--c-ink); cursor: pointer; transition: border-color .18s var(--ease), color .18s var(--ease);
}
.cs-pill:hover { border-color: var(--c-accent); color: var(--c-accent); }
.cs-pill svg { width: 10px; height: 10px; flex: none; }
.cs-clear {
  background: none; border: none; padding: 0; font-size: 13.5px; font-weight: 700;
  color: var(--c-accent); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px;
}

/* a filtered-out tile has to leave the flow entirely or it holds its slot in
   the quilt. [hidden] alone loses to the display:flex on .cs-tile. */
.cs-mosaic [hidden] { display: none !important; }

.cs-empty {
  padding: 54px 26px; text-align: center;
  background: var(--c-surface-2); border-radius: 14px;
}
.cs-empty[hidden] { display: none; }
.cs-empty h3 { font-size: 21px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 10px; }
.cs-empty p { font-size: 14.5px; line-height: 1.6; color: var(--c-body); max-width: 52ch; margin-inline: auto; }
.cs-empty .cs-clear { margin-top: 16px; font-size: 14.5px; }

/* card meta strip — scale and duration under the real case studies, so the
   cards carry a fact before the click and not only a claim */
.cs-meta {
  display: flex; flex-wrap: wrap; gap: 5px 9px; margin-top: 16px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--c-muted);
}
.cs-meta span + span::before { content: "·"; margin-right: 9px; opacity: .6; }
.cs-tile--dark .cs-meta, .cs-tile--blue .cs-meta { color: rgba(255,255,255,.68); }

/* ---------- case-study detail page ---------- */
.cs-detail .phero h1 { max-width: 24ch; }

/* fact band under the hero — the four numbers that frame the story */
.cs-facts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 28px; }
@media (max-width: 900px) { .cs-facts { grid-template-columns: repeat(2, 1fr); row-gap: 34px; } }
@media (max-width: 460px) { .cs-facts { grid-template-columns: 1fr; } }

/* ---------- Background: copy beside a picture ----------
   The heading and background paragraph only ever filled the left half of the
   measure, leaving a hole to their right. A picture fills it and gives the
   section something to hold the eye while the copy is read. */
.cs-bg { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 72px); align-items: stretch; }
.cs-bg-copy { display: flex; flex-direction: column; justify-content: center; max-width: 56ch; }
.cs-bg-copy h2 {
  font-size: clamp(26px, 3.2vw, 40px); font-weight: 800; letter-spacing: -.022em;
  line-height: 1.08; margin-bottom: 18px;
}
.cs-bg-copy p { font-size: 16px; font-weight: 300; line-height: 1.72; color: #323232; }
/* matched to .split-media in the Client Overview above — same 8px radius and
   the same drop shadow, so the two photographs on this page are handled
   identically rather than one being rounded and one square */
.cs-bg-img {
  min-height: 340px; overflow: hidden; border-radius: 14px;
  background: var(--img) center/cover no-repeat, var(--c-surface-2);
  box-shadow: 0 24px 50px rgba(20, 20, 40, .12);
}
@media (max-width: 900px) {
  .cs-bg { grid-template-columns: 1fr; gap: 32px; }
  /* picture first on a phone: it establishes the client faster than the
     paragraph does, and stops the section opening on a wall of text */
  .cs-bg-img { min-height: 240px; order: -1; }
}

/* ---------- The challenge ledger ----------
   Hairline rows rather than cards or bullets: number, the challenge in the
   source's own words, and a one-word tag for whoever is scanning. Holds its
   shape from two challenges to a dozen, which matters because the four case
   studies range from two to five. */
.cs-ledger { margin-top: clamp(38px, 5vw, 58px); }
.cs-ledger-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 20px;
  padding: 0 12px 14px 0;
}
.cs-ledger-head h3 { font-size: 20px; font-weight: 800; letter-spacing: -.01em; }
.cs-ledger-head span {
  font-size: 12.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--c-muted);
}
.cs-ledger-row {
  display: grid; grid-template-columns: 58px 1fr 210px; gap: 26px; align-items: baseline;
  padding: 22px 12px 22px 0; border-top: 1px solid var(--c-line);
  transition: background-color .18s var(--ease);
}
.cs-ledger-row:last-child { border-bottom: 1px solid var(--c-line); }
.cs-ledger-row:hover { background: #fafafc; }
.cs-ledger-row .n {
  font-size: 20px; font-weight: 900; letter-spacing: -.02em;
  background: var(--c-grad); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.cs-ledger-row p { font-size: 16px; line-height: 1.6; color: var(--c-ink); }
.cs-ledger-row .tag {
  font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--c-muted); text-align: right;
}
@media (max-width: 820px) {
  .cs-ledger-row { grid-template-columns: 42px 1fr; gap: 8px 18px; }
  .cs-ledger-row .tag { grid-column: 2; text-align: left; margin-top: 6px; }
}

/* timeline callout — one line, but it is the line clients read first */
.cs-timeline {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px;
  margin-top: 30px; padding: 20px 24px;
  background: var(--c-surface-2); border-left: 3px solid transparent; border-image: var(--c-grad) 1;
}
.cs-timeline .cs-tl-label {
  font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--c-accent);
}
.cs-timeline p { font-size: 15.5px; line-height: 1.55; color: var(--c-ink); font-weight: 600; margin: 0; }

/* .svc-dir-head's 30px gap only separates its own children, so it leaves no
   bottom spacing. On the service pages nothing follows it inside the section;
   here the benefits .kgrid does, and its .kcol gradient top-borders landed
   right under the intro's last line. */
.cs-detail .svc-dir-head--split + .kgrid { margin-top: 38px; }

/* module chips — which SuccessFactors modules went live */
.cs-modules { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }
.cs-modules span {
  padding: 7px 14px; border: 1px solid var(--c-line); border-radius: 999px;
  font-size: 13.5px; font-weight: 600; color: var(--c-ink); background: #fff;
}

/* ==========================================================================
   INSIGHTS — the mosaic again, with a byline and a date
   ==========================================================================
   itransition run their blog on exactly the same tile system as their
   portfolio: same flex-wrap quilt, same 4-tile cycle, same navy/blue bands.
   The only differences are an author line above the title, a date below the
   copy, and taller tiles to hold them (654 vs 584 on their tall tiles).

   So this reuses .cs-mosaic / .cs-tile wholesale rather than forking a second
   grid, and adds only what the extra two lines need.
   -------------------------------------------------------------------- */
.cs-mosaic--insights { --tile-h: 740px; }
/* Bands need more room here than the tall-tile half gives them: at >=1240px a
   band's body carries 52px padding and a 30px headline, leaving 266px against
   a tall tile's 298px — and an insights card has two more lines to fit than a
   case-study card. Since the filter can promote any tile to a band, every card
   has to fit the band shape, so the band is sized to the worst case rather
   than left at half the tile. */
.cs-mosaic--insights .cs-tile--wide { height: 420px; }

/* top line: the author on a published article, the topic on a tile that is
   still only a title. Same slot either way, so the grid stays even. */
.cs-tile .cs-kicker {
  display: block; font-size: 13.5px; font-weight: 600; line-height: 1.4;
  color: var(--c-muted); margin-bottom: 14px;
}
.cs-mosaic .cs-tile--dark .cs-kicker,
.cs-mosaic .cs-tile--blue .cs-kicker { color: rgba(255,255,255,.72); }

.cs-tile .cs-date {
  display: block; margin-top: 20px;
  font-size: 14px; font-weight: 600; color: var(--c-muted);
}
.cs-mosaic .cs-tile--dark .cs-date,
.cs-mosaic .cs-tile--blue .cs-date { color: rgba(255,255,255,.7); }

/* a tile with a date carries two extra lines, so its copy gets one line less
   than a plain tile — measured against the 298px of content space a 740px
   insights tile leaves after padding */
.cs-tile--tall .cs-body:has(.cs-date) p { -webkit-line-clamp: 4; }

/* "Read time" / unpublished marker — an honest label for the tiles that are
   a headline and nothing more yet */
.cs-tile .cs-soon {
  display: inline-block; margin-top: 20px; padding: 4px 10px;
  background: rgba(0,0,0,.05); font-size: 12px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--c-muted);
}
.cs-mosaic .cs-tile--dark .cs-soon,
.cs-mosaic .cs-tile--blue .cs-soon { background: rgba(255,255,255,.14); color: rgba(255,255,255,.8); }

/* ---------- long-form article body ---------- */
.article-body { max-width: 74ch; }
.article-body h2 {
  font-size: clamp(24px, 2.6vw, 32px); font-weight: 800; letter-spacing: -.02em;
  line-height: 1.15; margin: 46px 0 16px;
}
.article-body h3 {
  font-size: clamp(19px, 2vw, 23px); font-weight: 700; letter-spacing: -.01em;
  line-height: 1.25; margin: 34px 0 12px;
}
.article-body p { font-size: 16.5px; font-weight: 300; line-height: 1.75; color: #323232; }
.article-body p + p { margin-top: 16px; }
/* list-style:none on both — the base reset only covers ul, so the ol kept its
   native marker alongside the counter below and rendered "1. 1." */
.article-body ul, .article-body ol { display: grid; gap: 11px; margin: 18px 0 6px; list-style: none; }
.article-body li { position: relative; padding-left: 24px; font-size: 16px; line-height: 1.65; color: var(--c-body); }
.article-body ul li::before { content: ""; position: absolute; left: 0; top: 11px; width: 10px; height: 2px; background: var(--c-grad); }
.article-body ol { counter-reset: ab; }
.article-body ol li { padding-left: 32px; }
.article-body ol li::before {
  counter-increment: ab; content: counter(ab) "."; position: absolute; left: 0; top: 0;
  font-size: 15px; font-weight: 800; color: var(--c-accent);
}
.article-body strong { font-weight: 700; color: var(--c-ink); }
.article-body .lede { font-size: 19px; line-height: 1.65; color: var(--c-ink); font-weight: 300; }

/* a definition block for the custom tables the payroll article documents */
.article-table { margin: 22px 0 8px; border-top: 1px solid var(--c-line); }
.article-table > div { display: grid; grid-template-columns: 190px 1fr; gap: 26px; padding: 15px 0; border-bottom: 1px solid var(--c-line); }
@media (max-width: 620px) { .article-table > div { grid-template-columns: 1fr; gap: 5px; } }
.article-table dt { font-size: 14px; font-weight: 800; color: var(--c-ink); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.article-table dd { font-size: 15.5px; line-height: 1.6; color: var(--c-body); }

/* byline strip under an article hero */
.article-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 22px;
  font-size: 14.5px; color: var(--c-muted);
}
.article-meta strong { font-weight: 700; color: var(--c-ink); }
.article-meta .dot { opacity: .5; }

/* ---------- Article layout: body + sticky contents ----------
   The article measure is ~75 characters, which left the right third of the
   container empty on every screen. A contents list fills it and gives a dense
   technical piece the navigation it needs. Built by main.js from the h2s, so
   any future article gets one without extra markup. */
.article-layout { display: grid; grid-template-columns: 1fr 250px; gap: 72px; align-items: start; }
@media (max-width: 1040px) { .article-layout { grid-template-columns: 1fr; gap: 30px; } }
.article-body h2 { scroll-margin-top: 116px; }

.article-toc { position: sticky; top: 116px; }
.article-toc[hidden] { display: none; }
@media (max-width: 1040px) {
  /* nothing to stick to once it sits above the copy, so it becomes a boxed
     summary instead */
  .article-toc { position: static; border: 1px solid var(--c-line); padding: 22px 24px; }
}
.article-toc h2 {
  font-size: 12px; font-weight: 800; letter-spacing: .09em; text-transform: uppercase;
  color: var(--c-muted); margin: 0 0 14px;
}
.article-toc a {
  display: block; padding: 9px 0 9px 16px; border-left: 2px solid var(--c-line);
  font-size: 14px; line-height: 1.45; color: var(--c-muted);
  transition: color .18s var(--ease), border-color .18s var(--ease);
}
.article-toc a:hover { color: var(--c-ink); }
.article-toc a.is-on { color: var(--c-accent); border-left-color: var(--c-accent); }
@media (max-width: 1040px) {
  .article-toc a { border-left: none; padding: 5px 0; }
  .article-toc a.is-on { border-left: none; }
}

/* ============================================================
   LENIS INERTIA SCROLLING
   js/lenis.min.js stamps these classes on <html> at runtime, so
   every rule here is inert for reduced-motion visitors, where
   js/smooth-scroll.js never starts the library.
   ============================================================ */
html.lenis, html.lenis body { height: auto; }
/* Native jumps (hash on page load, keyboard focus below the fold)
   must land instantly for Lenis to sync to them; the sitewide
   scroll-behavior:smooth would tug against the library's animator. */
html.lenis { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: clip; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
