/* ==========================================================================
   Secure Cloud Partners — main.css
   Tokens, base, layout, components. Media queries live in responsive.css.
   ========================================================================== */

:root {
  /* Brand — sampled from the Secure Cloud Partners shield + cloud mark */
  --navy-950: #071429;
  --navy-900: #0d2246;
  --navy-800: #143567;
  --navy-700: #1b4a8c;
  --blue-700: #0a5fd0;
  --blue-600: #1877f2;
  --blue-500: #3b9bff;
  --sky-400: #63c2ff;
  --sky-300: #9ad8ff;
  --teal-500: #12968f;
  --teal-400: #2fb8ae;

  /* AA-safe twins of the three light accents. Same hue and saturation, dropped
     in lightness only far enough to clear 4.5:1 on white AND on the 10% tint of
     the original accent. Used for small text and for white-on-accent labels;
     the originals still carry every icon, rule, fill and border, so the brand
     colour on screen is unchanged. */
  --blue-600-text: #0d68df;
  --teal-500-text: #0f7b75;
  --teal-400-text: #207c75;

  /* Ink + surfaces */
  --ink-900: #111c2e;
  --ink-800: #1f3049;
  --ink-700: #33486a;
  --ink-600: #4d6382;
  --ink-500: #6d829f;
  --line-300: #d7e0ec;
  --line-200: #e7edf5;
  --line-100: #f0f4f9;
  --bg-100: #f3f7fc;
  --bg-50: #f9fbfe;
  --white: #ffffff;

  /* Radii + shadow */
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 22px;
  --radius-xl: 32px;
  --shadow-sm: 0 8px 22px rgba(7, 20, 41, .07);
  --shadow-md: 0 16px 36px rgba(7, 20, 41, .12);
  --shadow-lg: 0 28px 64px rgba(7, 20, 41, .18);

  /* Space scale */
  --space-1: .25rem;
  --space-2: .5rem;
  --space-3: .75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;

  --max-width: 1160px;

  /* How far through the page the visitor is, 0 to 1, published by
     initSystemState(). Defaults to 1 — the resolved state — so anything
     driven by it is finished, not faint, when the script does not run. */
  --sys: 1;

  /* Motion */
  --ease-premium: cubic-bezier(.22, 1, .36, 1);
  --ease-swift: cubic-bezier(.4, 0, .2, 1);
  --dur-fast: 180ms;
  --dur-med: 320ms;
  --dur-slow: 620ms;

  /* Type */
  --font-display: "Manrope", "Segoe UI", system-ui, sans-serif;
  --font-body: "IBM Plex Sans", "Segoe UI", system-ui, sans-serif;

  /* Pillar accents (per the deck's own colour coding) */
  --accent-ai: var(--blue-600);
  --accent-security: var(--navy-800);
  --accent-workplace: var(--teal-500);
  --accent-managed: var(--blue-700);

  --accent-ai-text: var(--blue-600-text);
  --accent-security-text: var(--navy-800);
  --accent-workplace-text: var(--teal-500-text);
  --accent-managed-text: var(--blue-700);
}

/* --------------------------------------------------------- base --------- */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ink-700);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink-900);
  line-height: 1.14;
  margin: 0 0 var(--space-4);
  letter-spacing: -.015em;
}

h1 { font-size: clamp(2rem, 3.6vw, 2.9rem); font-weight: 800; }
h2 { font-size: clamp(1.75rem, 2.9vw, 2.45rem); font-weight: 700; }
h3 { font-size: 1.2rem; font-weight: 700; }
h4 { font-size: 1rem; font-weight: 700; }

p { margin: 0 0 var(--space-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--blue-700); text-decoration: none; }
a:hover { color: var(--navy-800); }

img { max-width: 100%; height: auto; display: block; }

ul, ol { margin: 0; padding: 0; list-style: none; }

/* Keep anchor targets clear of the sticky header. */
[id] { scroll-margin-top: 94px; }

:focus-visible {
  outline: 3px solid var(--blue-500);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Keyboard users can jump the header nav on every page. */
.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -3rem;
  z-index: 100;
  background: var(--navy-900);
  color: var(--white);
  font-family: var(--font-display);
  font-size: .9rem;
  font-weight: 700;
  padding: .7rem 1.1rem;
  border-radius: var(--radius-sm);
  transition: top var(--dur-fast) var(--ease-swift);
}
.skip-link:focus { top: var(--space-4); color: var(--white); }
main:focus { outline: none; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

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

/* Do NOT put overflow-x here. On a non-root element it computes the other axis
   to `auto`, which turns .page-shell into its own scroll container: the document
   then never scrolls, window.scrollY is pinned at 0, and #fragment links and the
   hero parallax both stop working. Decorative overflow is clipped by .hero and
   .page-hero, which each set overflow: hidden. */

/* ------------------------------------------------------- sections ------- */

.section-plain,
.section-alt,
.section-dark {
  padding-block: clamp(3.5rem, 7vw, 6rem);
}

.section-alt { background: var(--bg-100); }

.section-dark {
  background:
    radial-gradient(900px 480px at 82% -10%, rgba(24, 119, 242, .38), transparent 62%),
    linear-gradient(160deg, var(--navy-950), var(--navy-800));
  color: rgba(255, 255, 255, .82);
}
.section-dark h2, .section-dark h3, .section-dark h4 { color: var(--white); }
.section-dark .eyebrow { color: var(--sky-400); }
.section-dark .section-head p { color: rgba(255, 255, 255, .78); }

.section-head { max-width: 720px; margin-bottom: var(--space-10); }
.section-head.center { margin-inline: auto; text-align: center; }
/* Headings that are a list of short statements read badly broken mid-phrase.
   Give them the full container and a slightly smaller size so they hold one
   line on desktop; below ~1100px they wrap, which is fine. */
.section-head--wide { max-width: none; }
.section-head--wide h2 { font-size: clamp(1.45rem, 2.35vw, 2.12rem); }
.section-head p { font-size: 1.06rem; color: var(--ink-600); margin-bottom: 0; }

.eyebrow {
  display: block;
  font-family: var(--font-display);
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--blue-700);
  margin-bottom: var(--space-3);
}

/* -------------------------------------------------------- buttons ------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-display);
  font-size: .95rem;
  font-weight: 700;
  padding: .78rem 1.5rem;
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-swift),
              box-shadow var(--dur-fast) var(--ease-swift),
              background var(--dur-fast) var(--ease-swift),
              color var(--dur-fast) var(--ease-swift);
}
.btn:hover { transform: translateY(-2px); }

.btn-primary {
  background: linear-gradient(135deg, var(--blue-700), var(--blue-600));
  color: var(--white);
  box-shadow: 0 10px 24px rgba(10, 95, 208, .32);
}
.btn-primary:hover { color: var(--white); box-shadow: 0 16px 32px rgba(10, 95, 208, .4); }


.btn-ghost {
  background: rgba(255, 255, 255, .1);
  color: var(--white);
  border-color: rgba(255, 255, 255, .34);
}
.btn-ghost:hover { color: var(--white); background: rgba(255, 255, 255, .18); }

.btn-link {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: .92rem;
  color: var(--blue-700);
}
.btn-link::after {
  content: "";
  width: 14px; height: 14px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h13M13 6l6 6-6 6' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h13M13 6l6 6-6 6' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  transition: transform var(--dur-fast) var(--ease-swift);
}
.btn-link:hover::after { transform: translateX(4px); }

/* --------------------------------------------------------- header ------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line-200);
}

.nav-wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  min-height: 74px;
}

.brand { display: inline-flex; align-items: center; gap: .65rem; }
.brand-mark { width: 44px; height: auto; }
.brand-text { display: flex; flex-direction: column; line-height: 1; }
.brand-name {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: .98rem;
  letter-spacing: .13em;
  color: var(--navy-900);
  text-transform: uppercase;
}
.brand-tag {
  font-size: .62rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--blue-600-text);
  font-weight: 600;
  margin-top: .3rem;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

.nav-link {
  font-family: var(--font-display);
  font-size: .92rem;
  font-weight: 600;
  color: var(--ink-700);
  padding: .4rem 0;
  position: relative;
}
.nav-link:hover { color: var(--navy-900); }
.nav-link[aria-current="page"] { color: var(--blue-700); }
.nav-link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 2px;
  background: var(--blue-600);
  border-radius: 2px;
}

.nav-group { position: relative; }
.nav-group > button {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font-family: var(--font-display);
  font-size: .92rem;
  font-weight: 600;
  color: var(--ink-700);
  background: none;
  border: 0;
  padding: .4rem 0;
  cursor: pointer;
}
.nav-group > button::after {
  content: "";
  width: 9px; height: 9px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  transition: transform var(--dur-fast) var(--ease-swift);
}
.nav-group > button[aria-expanded="true"],
.nav-group > button.is-current { color: var(--blue-700); }
.nav-group > button[aria-expanded="true"]::after { transform: rotate(-135deg) translateY(-2px); }

.nav-group-menu {
  position: absolute;
  top: calc(100% + 14px);
  left: 50%;
  transform: translate(-50%, 8px);
  min-width: 290px;
  background: var(--white);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: var(--space-2);
  display: none;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-swift), transform var(--dur-fast) var(--ease-swift);
}
.nav-group-menu.open { display: block; opacity: 1; transform: translate(-50%, 0); }
/* Bridges the gap between the button and the menu. Without it the pointer leaves
   .nav-group on the way down, mouseleave fires, and the menu closes before you
   can click an item. */
.nav-group-menu::before {
  content: "";
  position: absolute;
  left: 0; right: 0;
  top: -18px;
  height: 18px;
}
.nav-group-menu a {
  display: block;
  padding: .6rem .8rem;
  border-radius: var(--radius-sm);
  font-size: .9rem;
  font-weight: 600;
  color: var(--ink-700);
}
.nav-group-menu a:hover { background: var(--bg-100); color: var(--navy-900); }
.nav-group-all {
  color: var(--blue-700) !important;
  border-bottom: 1px solid var(--line-200);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  margin-bottom: var(--space-2);
  padding-bottom: .7rem !important;
}
/* the parent item is a destination now, not just a toggle */
.nav-group > button[data-nav-href] { cursor: pointer; }

.header-cta { display: flex; gap: var(--space-3); }
.header-cta .btn { padding: .62rem 1.2rem; font-size: .88rem; }

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px; height: 44px;
  background: none;
  border: 1px solid var(--line-300);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.nav-toggle-line {
  display: block;
  width: 20px; height: 2px;
  margin-inline: auto;
  background: var(--navy-900);
  border-radius: 2px;
  transition: transform var(--dur-fast) var(--ease-swift), opacity var(--dur-fast) var(--ease-swift);
}
.nav-toggle[aria-expanded="true"] .nav-toggle-line:nth-child(2) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle-line:nth-child(3) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle-line:nth-child(4) { transform: translateY(-7px) rotate(-45deg); }

/* ----------------------------------------------------------- hero ------- */

.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(2.25rem, 4.5vw, 4rem) clamp(2.25rem, 4vw, 3.25rem);
  background:
    radial-gradient(1100px 620px at 78% -14%, rgba(24, 119, 242, .42), transparent 60%),
    radial-gradient(780px 460px at 8% 104%, rgba(99, 194, 255, .24), transparent 62%),
    linear-gradient(158deg, var(--navy-950) 0%, var(--navy-800) 58%, var(--navy-700) 100%);
  color: rgba(255, 255, 255, .84);
}
.hero h1 { color: var(--white); }
.hero .eyebrow { color: var(--sky-400); }

.hero-backdrop { position: absolute; inset: 0; pointer-events: none; }
.hero-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(46px);
  opacity: .5;
  will-change: transform;
}
.hero-orb--1 { width: 340px; height: 340px; top: -70px; right: 6%; background: radial-gradient(circle, rgba(59,155,255,.85), transparent 68%); }
.hero-orb--2 { width: 260px; height: 260px; bottom: -80px; left: 4%; background: radial-gradient(circle, rgba(47,184,174,.6), transparent 68%); }
.hero-orb--3 { width: 200px; height: 200px; top: 36%; left: 46%; background: radial-gradient(circle, rgba(154,216,255,.5), transparent 70%); }
/* The brand mark, large and very faint, the way the deck sets it behind its own
   slides. Painted through a mask so the colour comes from CSS, and derived from
   the real logo alpha so it stays sharp at hero size. Purely atmospheric: it
   carries no meaning, takes no pointer events, and is dropped on small screens
   where it would crowd the text. */
.hero-mark {
  position: absolute;
  right: var(--mark-right, 2%);
  top: 50%;
  transform: translateY(-46%);
  width: var(--mark-size, min(52vw, 760px));
  aspect-ratio: 1;
  background: var(--white);
  opacity: .055;
  pointer-events: none;
  -webkit-mask: url("../img/mark-silhouette.png") center/contain no-repeat;
  mask: url("../img/mark-silhouette.png") center/contain no-repeat;
}
/* interior heroes are shorter, so the mark is scaled to match */
.page-hero .hero-mark {
  --mark-size: min(34vw, 420px);
  --mark-right: 4%;
  opacity: .05;
}
/* Where the hero carries a note card, the mark is sized to sit around it rather
   than be sliced by it, so the card reads as resting on the mark. */
.about-page .hero-mark,
.platform-page .hero-mark,
.not-found-page .hero-mark {
  --mark-size: min(40vw, 500px);
  --mark-right: 6%;
  transform: translateY(-50%);
  opacity: .045;
}
@media (max-width: 1080px) { .hero-mark { display: none; } }

.hero-mesh {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(rgba(255,255,255,.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.055) 1px, transparent 1px);
  background-size: 62px 62px;
  mask-image: radial-gradient(70% 70% at 50% 40%, #000 40%, transparent 100%);
  -webkit-mask-image: radial-gradient(70% 70% at 50% 40%, #000 40%, transparent 100%);
}

.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(0, .92fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.hero-lede {
  font-size: 1.12rem;
  color: rgba(255, 255, 255, .8);
  max-width: 52ch;
}

.hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-6); }

.hero-proof {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, .16);
}
.hero-proof > div { flex: 1 1 140px; min-width: 0; }
.hero-proof div strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 800;
  color: var(--white);
}
.hero-proof div span { font-size: .84rem; color: rgba(255, 255, 255, .66); }

/* hero visual — pillar orbit card */
.hero-visual {
  position: relative;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: var(--radius-xl);
  padding: var(--space-6);
  backdrop-filter: blur(8px);
  box-shadow: var(--shadow-lg);
}
.hero-visual-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid rgba(255, 255, 255, .14);
  margin-bottom: var(--space-4);
}
.hero-visual-head strong {
  font-family: var(--font-display);
  color: var(--white);
  font-size: .96rem;
}
.hero-visual-head span {
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sky-400);
  border: 1px solid rgba(99, 194, 255, .4);
  border-radius: 999px;
  padding: .22rem .6rem;
  white-space: nowrap;
}
.pillar-orbit { display: grid; gap: var(--space-2); }
.pillar-orbit li { display: block; }
.pillar-orbit a {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: .6rem 2.1rem .6rem .85rem;
  position: relative;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .1);
  color: inherit;
  transition: background var(--dur-med) var(--ease-swift),
              transform var(--dur-med) var(--ease-swift),
              border-color var(--dur-med) var(--ease-swift);
}
.pillar-orbit a:hover,
.pillar-orbit a:focus-visible {
  background: rgba(255, 255, 255, .14);
  border-color: rgba(99, 194, 255, .5);
  transform: translateX(4px);
  color: inherit;
}
/* chevron, so it reads as a link rather than decoration */
.pillar-orbit a::after {
  content: "";
  position: absolute;
  right: .95rem;
  width: 14px; height: 14px;
  background: var(--sky-400);
  opacity: .7;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 5l7 7-7 7' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 5l7 7-7 7' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  transition: transform var(--dur-fast) var(--ease-swift), opacity var(--dur-fast) var(--ease-swift);
}
.pillar-orbit a:hover::after { transform: translateX(3px); opacity: 1; }
.pillar-orbit svg { width: 20px; height: 20px; flex: none; color: var(--sky-400); }
.pillar-orbit strong {
  display: block;
  font-family: var(--font-display);
  font-size: .9rem;
  color: var(--white);
  font-weight: 700;
}
.pillar-orbit small { font-size: .78rem; color: rgba(255, 255, 255, .62); }

/* interior page hero */
.page-hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(3rem, 6vw, 5rem);
  background:
    radial-gradient(900px 480px at 84% -20%, rgba(24, 119, 242, .4), transparent 62%),
    linear-gradient(155deg, var(--navy-950), var(--navy-800));
  color: rgba(255, 255, 255, .82);
}
.page-hero h1 { color: var(--white); }
.page-hero .eyebrow { color: var(--sky-400); }
.page-hero p { max-width: 62ch; color: rgba(255, 255, 255, .8); font-size: 1.06rem; }

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  font-size: .82rem;
  color: rgba(255, 255, 255, .6);
  margin-bottom: var(--space-5);
}
.breadcrumb a { color: rgba(255, 255, 255, .78); }
.breadcrumb a:hover { color: var(--white); }
.breadcrumb span[aria-hidden] { opacity: .5; }

.page-hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: center;
}
/* About keeps the card beside the heading. The tagline is short, so a small
   size step is all it needs to hold one line in the narrower column. */
.about-page .page-hero h1 { font-size: clamp(1.85rem, 3.3vw, 2.65rem); }

.promise-card {
  /* At 7% white this was effectively transparent, so the hero topology behind
     it ran straight across its text. It is a surface now: a navy tint that
     covers what is behind, with a small blur so the graphic still reads as
     depth rather than stopping dead at the card edge. Darker than before, so
     the white text on it gained contrast rather than losing any. */
  background: rgba(11, 27, 56, .58);
  -webkit-backdrop-filter: blur(7px);
  backdrop-filter: blur(7px);
  border: 1px solid rgba(255, 255, 255, .16);
  border-left: 3px solid var(--sky-400);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}
.promise-card h2 {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sky-300);
  margin-bottom: var(--space-2);
}
.promise-card p {
  color: rgba(255, 255, 255, .82);
  font-size: .92rem;
  line-height: 1.55;
  margin-bottom: 0;
}

/* --------------------------------------------------------- cards -------- */

.cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
  gap: var(--space-6);
}
.cards-grid.cols-3 { grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }

.card {
  background: var(--white);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
  transition: transform var(--dur-med) var(--ease-premium),
              box-shadow var(--dur-med) var(--ease-premium),
              border-color var(--dur-med) var(--ease-premium);
}
.card:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); }

.service-card {
  --accent: var(--blue-600);
  --accent-text: var(--blue-600-text);
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
  padding-top: var(--space-8);
}
.service-card::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: var(--accent);
}
.service-card:hover { border-color: color-mix(in srgb, var(--accent) 40%, var(--line-200)); }
.service-card--ai { --accent: var(--accent-ai); --accent-text: var(--accent-ai-text); }
.service-card--security { --accent: var(--accent-security); --accent-text: var(--accent-security-text); }
.service-card--workplace { --accent: var(--accent-workplace); --accent-text: var(--accent-workplace-text); }
.service-card--managed { --accent: var(--accent-managed); --accent-text: var(--accent-managed-text); }

.service-pill {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: .4rem;
  font-family: var(--font-display);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-text);
  background: color-mix(in srgb, var(--accent) 10%, var(--white));
  border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--white));
  border-radius: 999px;
  padding: .26rem .7rem;
  margin-bottom: var(--space-4);
}

.service-icon {
  width: 44px; height: 44px;
  color: var(--accent);
  margin-bottom: var(--space-4);
}

/* The names run to one or two lines depending on the pillar, so the title and
   the promise line each reserve their second line: without that, the four
   offering lists below start at four different heights. */
.service-card h3 {
  margin-bottom: var(--space-2);
  line-height: 1.3;
  min-height: calc(2 * 1.3em);
  display: flex;
  align-items: flex-start;
}
.service-card > p {
  font-size: .95rem;
  color: var(--ink-600);
  line-height: 1.55;
  min-height: calc(2 * 1.55em);
}

.cap-list {
  display: grid;
  gap: .5rem;
  margin: var(--space-4) 0 var(--space-6);
  font-size: .9rem;
}
.cap-list li {
  position: relative;
  padding-left: 1.5rem;
  color: var(--ink-700);
}
.cap-list li::before {
  content: "";
  position: absolute;
  left: 0; top: .48em;
  width: 8px; height: 8px;
  border-radius: 2px;
  background: var(--accent, var(--blue-600));
  opacity: .65;
}
.service-card .btn-link { margin-top: auto; color: var(--accent-text); }

/* ------------------------------------------------------- catalogue ------ */

.catalogue {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-5);
  counter-reset: cat;
}
.catalogue-item {
  --accent: var(--blue-600);
  --accent-text: var(--blue-600-text);
  display: flex;
  gap: var(--space-4);
  background: var(--white);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-md);
  padding: var(--space-5);
  transition: border-color var(--dur-med) var(--ease-swift), box-shadow var(--dur-med) var(--ease-swift);
}
.catalogue-item:hover {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--line-200));
  box-shadow: var(--shadow-sm);
}
.catalogue-item::before {
  counter-increment: cat;
  content: counter(cat, decimal-leading-zero);
  font-family: var(--font-display);
  font-size: .82rem;
  font-weight: 800;
  letter-spacing: .04em;
  color: var(--accent-text);
  background: color-mix(in srgb, var(--accent) 10%, var(--white));
  border-radius: var(--radius-sm);
  width: 38px; height: 38px;
  flex: none;
  display: grid;
  place-items: center;
}
.catalogue-item h3 { font-size: 1rem; margin-bottom: .25rem; }
.catalogue-item p { font-size: .9rem; color: var(--ink-600); margin: 0; }

/* launch focus panel */
.launch-focus {
  --accent: var(--blue-600);
  --accent-text: var(--blue-600-text);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
  background: color-mix(in srgb, var(--accent) 7%, var(--white));
  border: 1px solid color-mix(in srgb, var(--accent) 22%, var(--white));
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.launch-focus svg { width: 40px; height: 40px; color: var(--accent); }
.launch-focus h3 {
  font-size: .78rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin-bottom: var(--space-3);
}
/* two short offerings in a full-width panel left two thirds of it empty, which
   read as unfinished rather than as breathing room. Let them spread. */
.launch-focus ul {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: .55rem var(--space-6);
}
.launch-focus li {
  position: relative;
  padding-left: 1.1rem;
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink-900);
  font-size: .98rem;
}
.launch-focus li::before {
  content: "";
  position: absolute;
  left: 0; top: .55em;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--accent);
}

/* ---------------------------------------------- operational domains ----- */

/* The estate is one thing with six parts, which is what the heading claims. Six
   separately bordered cards with air between them said the opposite: six
   unrelated products. They are now cells of a single panel, divided by hairlines
   and nothing else.

   The rules come from the grid's own 1px gap showing the panel's background
   through, so they appear wherever the columns actually break — two across,
   one across — with no :nth-child arithmetic to get wrong. */
.domain-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(310px, 100%), 1fr));
  gap: 1px;
  background: var(--line-200);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.domain {
  --accent: var(--blue-600);
  --accent-text: var(--blue-600-text);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  background: var(--white);
  padding: var(--space-5);
  transition: background var(--dur-med) var(--ease-swift);
}
/* the whole cell answers, not a border on it — inside a seamless panel a
   thickening outline reads as a misalignment rather than as a hover */
.domain:hover { background: color-mix(in srgb, var(--accent) 6%, var(--white)); }

/* the accent lives in the icon tile, so six domains can each carry their own
   colour without six coloured rules fighting across one panel */
.domain-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  color: var(--accent-text);
  background: color-mix(in srgb, var(--accent) 15%, var(--white));
  transition: background var(--dur-med) var(--ease-swift);
}
.domain:hover .domain-icon { background: color-mix(in srgb, var(--accent) 24%, var(--white)); }
.domain svg { width: 22px; height: 22px; display: block; }
.domain h3 { font-size: 1rem; margin: 0 0 .15rem; }
.domain p { font-size: .86rem; color: var(--ink-600); margin: 0; }

/* --------------------------------------------------- delivery track ----- */

.delivery-track {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
}
.delivery-step {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: var(--white);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  overflow: hidden;
}
.delivery-step::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--blue-700), var(--sky-400));
  transform-origin: left;
  transition: transform var(--dur-slow) var(--ease-premium);
}
html.js .delivery-step::after { transform: scaleX(0); }
html.js .delivery-step.active::after,
html.reveal-all .delivery-step::after { transform: scaleX(1); }
.delivery-step-index { display: inline-flex; flex: none; }
.delivery-step-index b {
  display: grid;
  place-items: center;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--blue-700);
  color: var(--white);
  font-size: .72rem;
}
.delivery-step h3 { font-size: .98rem; margin: 0; }
.delivery-step p { font-size: .88rem; color: var(--ink-600); margin: 0; }

.section-dark .delivery-step {
  background: rgba(255, 255, 255, .07);
  border-color: rgba(255, 255, 255, .14);
}
.section-dark .delivery-step p { color: rgba(255, 255, 255, .72); }
.section-dark .delivery-step-index { color: var(--sky-400); }
.section-dark .delivery-step-index b { background: var(--sky-400); color: var(--navy-950); }

/* ------------------------------------------------------- platform ------- */

.platform-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  gap: var(--space-5);
}
.platform-module {
  --accent: var(--blue-600);
  --accent-text: var(--blue-600-text);
  position: relative;
  background: var(--white);
  border: 1px solid var(--line-200);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
  padding: var(--space-10) var(--space-5) var(--space-5) var(--space-6);
  transition: transform var(--dur-med) var(--ease-premium), box-shadow var(--dur-med) var(--ease-premium);
}
.platform-module:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.platform-module--operate { --accent: var(--blue-700); --accent-text: var(--blue-700); }
.platform-module--ai { --accent: #7c3fd4; --accent-text: #7c3fd4; }
.platform-module--secure { --accent: var(--navy-800); --accent-text: var(--navy-800); }
.platform-module--workplace { --accent: var(--teal-500); --accent-text: var(--teal-500-text); }
.platform-module--measure { --accent: var(--teal-400); --accent-text: var(--teal-400-text); }

/* Badge pinned to the card corner, as the deck lays it out, so every badge
   lines up regardless of how long the module name is. */
.module-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 34px;
  margin-bottom: var(--space-4);
}
.module-head svg { width: 30px; height: 30px; color: var(--accent); flex: none; }
.module-head h3 { font-size: 1.02rem; margin: 0; }
.module-tag {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  font-family: var(--font-display);
  font-size: .6rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--white);
  background: var(--accent-text);
  border-radius: 999px;
  padding: .22rem .6rem;
  white-space: nowrap;
}
.module-gives {
  font-size: .94rem;
  color: var(--ink-700);
  margin: 0 0 var(--space-4);
}

.module-caps {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  padding-top: var(--space-4);
  border-top: 1px solid var(--line-200);
}
.module-caps li {
  font-size: .76rem;
  color: var(--ink-600);
  background: var(--bg-50);
  border: 1px solid var(--line-200);
  border-radius: 999px;
  padding: .18rem .6rem;
}

/* orchestration core */
.core-panel {
  background: linear-gradient(150deg, var(--navy-900), var(--blue-700));
  border-radius: var(--radius-xl);
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
  color: rgba(255, 255, 255, .84);
}
.core-panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
.core-panel-head h2 { color: var(--white); font-size: 1.5rem; margin: 0; }
.core-panel-head span { font-size: .86rem; color: rgba(255, 255, 255, .7); }
.core-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: var(--space-4);
}
.core-block {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: rgba(255, 255, 255, .95);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}
.core-block svg { width: 26px; height: 26px; color: var(--blue-700); flex: none; }
.core-block strong {
  font-family: var(--font-display);
  font-size: .92rem;
  color: var(--ink-900);
  font-weight: 700;
}

/* Governed autonomy and the shared platform foundation answer two different
   questions - what automation may do, and what the modules share - so they are
   built as one component with two accents rather than two unrelated boxes. */

/* --------------------------------------------------------- stages ------- */

.stage-flow {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-4);
}
.stage-card {
  position: relative;
  border-radius: var(--radius-md);
  padding: var(--space-5);
  color: var(--white);
  overflow: hidden;
}
.stage-card:nth-child(1) { background: var(--navy-950); }
.stage-card:nth-child(2) { background: var(--navy-800); }
.stage-card:nth-child(3) { background: var(--navy-700); }
.stage-card:nth-child(4) { background: var(--blue-700); }
.stage-card span {
  display: block;
  font-family: var(--font-display);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .92);
  margin-bottom: var(--space-3);
}
/* Two of the four stage names wrap to a second line and two do not, so the
   descriptions started at four different heights and the cards looked
   accidentally uneven. The title block reserves its second line, and the
   description is pushed to the bottom, so every card reads on one baseline. */
.stage-card {
  display: flex;
  flex-direction: column;
  gap: .4rem;
}
.stage-card h3 {
  color: var(--white);
  font-size: 1.05rem;
  line-height: 1.3;
  min-height: calc(2 * 1.3em);
  margin: 0;
}
.stage-card p {
  font-size: .86rem;
  color: rgba(255, 255, 255, .88);
  margin: 0;
  margin-top: auto;
  padding-top: var(--space-2);
}

/* ------------------------------------------------------- outcomes ------- */

.outcome-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-5);
}
.outcome {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .13);
}
.outcome svg { width: 30px; height: 30px; color: var(--sky-400); }
.outcome strong {
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--white);
}
.outcome p { font-size: .88rem; margin: 0; color: rgba(255, 255, 255, .72); }

/* ------------------------------------------------------ principles ------ */

/* Five commitments, not a sequence - so no numbering. A ruled row reads as a
   set of equals and holds together better than five near-empty cards. */
.principle-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}
.principle {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex: 1 1 auto;
  background: var(--white);
  border: 1px solid var(--line-200);
  border-left: 3px solid var(--blue-600);
  border-radius: var(--radius-sm);
  padding: var(--space-4) var(--space-5);
}
.principle::before {
  content: "";
  flex: none;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--blue-600);
  opacity: .55;
}
.principle h3 {
  font-size: .95rem;
  margin: 0;
  white-space: nowrap;
}

/* -------------------------------------------------------- contact ------- */

.contact-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-5);
}
.contact-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--white);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.contact-card svg { width: 32px; height: 32px; color: var(--blue-700); }
.contact-card h3 { font-size: 1rem; margin: 0; }
.contact-card p { font-size: .92rem; color: var(--ink-600); margin: 0; }
.contact-card a {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  word-break: break-word;
}
.contact-card .contact-value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  color: var(--ink-900);
  margin: 0;
}

.challenge-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--space-4);
}
.challenge {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  background: var(--white);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
}
.challenge-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: .97rem;
  color: var(--ink-900);
  flex: 1 1 auto;
}
.challenge-impact {
  position: relative;
  flex: none;
  padding-left: 2rem;
  font-size: .9rem;
  color: var(--ink-600);
}
.challenge-impact::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: 20px; height: 10px;
  transform: translateY(-50%);
  background: var(--blue-600);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cpath d='M0 6h19M14 1l6 5-6 5' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 12'%3E%3Cpath d='M0 6h19M14 1l6 5-6 5' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* ------------------------------------------------------- cta panel ------ */

.section-final-cta { padding-block: clamp(3rem, 6vw, 5rem); }

.cta-panel {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-xl);
  padding: clamp(2rem, 5vw, 3.5rem);
  background:
    radial-gradient(760px 420px at 88% -30%, rgba(99, 194, 255, .4), transparent 62%),
    linear-gradient(140deg, var(--navy-950), var(--blue-700));
  color: rgba(255, 255, 255, .84);
  text-align: center;
}
.cta-panel h2 { color: var(--white); max-width: 22ch; margin-inline: auto; }
.cta-panel p { max-width: 58ch; margin-inline: auto; color: rgba(255, 255, 255, .8); }
.cta-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

/* --------------------------------------------------------- footer ------- */

.site-footer {
  background: var(--navy-950);
  color: rgba(255, 255, 255, .66);
  padding-block: var(--space-16) var(--space-8);
  font-size: .9rem;
}
.footer-grid {
  display: grid;
  /* Five columns carrying very different loads, so they are not sized alike.
     Services holds the two longest labels on the site and gets the widest nav
     track; Company and Legal hold one-word links and give that width up. The
     contact column keeps its 215px floor so the address and the domain each stay
     on one line. Equal nav tracks left Services wrapping two of its four links
     while Legal sat half empty beside it. */
  grid-template-columns:
    minmax(0, 1.25fr) minmax(0, 1.25fr) minmax(0, .8fr) minmax(0, .8fr) minmax(215px, 1.15fr);
  gap: var(--space-6) var(--space-5);
}
.footer-col h3 {
  color: var(--white);
  font-size: .76rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  margin-bottom: var(--space-4);
}
.footer-col a {
  display: block;
  color: rgba(255, 255, 255, .66);
  padding: .26rem 0;
  /* last-resort break: nothing in a nav label needs it, but it stops a long
     address from ever pushing the document wider than the viewport */
  overflow-wrap: anywhere;
}
/* Get in touch: the address and the domain each read as one token, so keep each
   on a single line and let the type size do the fitting. */
.footer-col:last-child a {
  font-size: .92rem;
  letter-spacing: -.005em;
}
.footer-col a:hover { color: var(--white); }
.footer-brand { display: inline-flex; align-items: center; gap: .65rem; margin-bottom: var(--space-4); }
.footer-brand .brand-mark { width: 40px; }
.footer-brand .brand-name { color: var(--white); }
.footer-brand .brand-tag { color: var(--sky-400); }
.footer-note { max-width: 40ch; color: rgba(255, 255, 255, .6); }
.footer-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  justify-content: space-between;
  margin-top: var(--space-10);
  padding-top: var(--space-6);
  border-top: 1px solid rgba(255, 255, 255, .12);
  font-size: .82rem;
  color: rgba(255, 255, 255, .5);
}


/* ---------------------------------------------------------- legal ------- */

/* The body is set to a reading measure, which on a 1160 container left the whole
   right half of the page as blank white. It now sits in a two-column layout with
   the page's own section list beside it: the same width is used, and used for
   something — a legal page is read by jumping to one clause, not top to bottom. */
.legal-layout {
  display: grid;
  /* The right track is the reading measure itself, not "the rest of the row" —
     a 1fr track just moved the blank gutter inside the column. The pair is then
     centred, so what is left over falls evenly on both sides and reads as margin
     rather than as an unfinished right-hand side. */
  grid-template-columns: minmax(0, 15rem) minmax(0, 40rem);
  justify-content: center;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.legal-toc {
  position: sticky;
  top: calc(var(--header-h, 76px) + var(--space-6));
  padding-right: var(--space-5);
  border-right: 1px solid var(--line-200);
}
.legal-toc h2 {
  font-family: var(--font-display);
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-600);
  margin: 0 0 var(--space-4);
}
.legal-toc ol {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: .1rem;
  /* the numbers are the clause order, which is information on a legal page */
  counter-reset: clause;
}
.legal-toc li { counter-increment: clause; }
.legal-toc a {
  display: grid;
  grid-template-columns: 1.6rem minmax(0, 1fr);
  gap: .2rem;
  padding: .34rem 0;
  font-size: .88rem;
  line-height: 1.35;
  color: var(--ink-700);
  text-decoration: none;
  border-radius: var(--radius-sm);
  transition: color var(--dur-fast) var(--ease-swift);
}
.legal-toc a::before {
  content: counter(clause, decimal-leading-zero);
  font-family: var(--font-display);
  font-size: .72rem;
  font-weight: 700;
  color: var(--line-300);
  padding-top: .12em;
}
.legal-toc a:hover,
.legal-toc a:focus-visible { color: var(--blue-600-text); }
.legal-toc a:hover::before,
.legal-toc a:focus-visible::before { color: var(--blue-600-text); }

/* the anchors land under the fixed header without a scroll-margin they would sit
   behind it */
.legal-block { scroll-margin-top: calc(var(--header-h, 76px) + var(--space-6)); }

/* One column below the point where two reading measures no longer fit. The list
   stays: it is more useful on a phone than on a desktop. */
@media (max-width: 900px) {
  .legal-layout { grid-template-columns: minmax(0, 1fr); gap: var(--space-8); }
  .legal-body { max-width: 40rem; margin-inline: auto; }
  .legal-toc {
    position: static;
    padding: var(--space-5);
    padding-right: var(--space-5);
    border-right: 0;
    border: 1px solid var(--line-200);
    border-radius: var(--radius-md);
    background: var(--bg-100);
  }
}

/* The measure is the grid track, not this element: a ch-based max-width here
   resolves against the body font while the track resolved against the root, so
   the text stopped ~95px short of its own column and the gutter came back. */
.legal-body { display: grid; gap: var(--space-8); }
.legal-block h2 {
  font-size: 1.25rem;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--line-200);
}
.legal-block p { font-size: .97rem; }

/* ------------------------------------------------ platform stack -------- */
/* Deck p8 draws the platform as one connected stack rather than a set of
   separate boxes. The flow marks between layers carry that connection; they are
   decorative and hidden from assistive tech, which reads the layers in order. */

.stack { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }

.stk-layer {
  background: var(--white);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-lg);
  padding: var(--space-5) var(--space-6);
}
.stk-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.stk-head svg { width: 24px; height: 24px; flex: none; color: var(--accent, var(--blue-700)); }
.stk-head h3 {
  font-size: .78rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--accent-text, var(--blue-700));
  margin: 0;
}
.stk-note { margin-left: auto; font-size: .82rem; color: var(--ink-600); }

/* inline chip rows, used by the experience and governed layers */
.stk-inline { display: flex; flex-wrap: wrap; gap: .4rem; }
.stk-inline li {
  font-size: .84rem;
  color: var(--ink-700);
  background: var(--bg-50);
  border: 1px solid var(--line-200);
  border-radius: 999px;
  padding: .24rem .75rem;
}

.stk-layer--experience { --accent: var(--blue-700); --accent-text: var(--blue-700); border-top: 3px solid var(--blue-700); }
.stk-layer--governed   { --accent: var(--teal-500); --accent-text: var(--teal-500-text); border-top: 3px solid var(--teal-500); }

/* the four pillars sitting between experience and core */
.stk-pillars {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: var(--space-4);
}
.stk-pillar {
  --accent: var(--blue-600);
  --accent-text: var(--blue-600-text);
  display: flex;
  flex-direction: column;
  gap: .3rem;
  position: relative;
  background: var(--white);
  border: 1px solid var(--line-200);
  border-top: 3px solid var(--accent);
  border-radius: var(--radius-md);
  padding: var(--space-5) var(--space-5) var(--space-6);
  color: inherit;
  transition: transform var(--dur-med) var(--ease-swift),
              box-shadow var(--dur-med) var(--ease-swift),
              border-color var(--dur-med) var(--ease-swift);
}
.stk-pillar:hover,
.stk-pillar:focus-visible {
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line-200));
  color: inherit;
}
.stk-pillar--ai        { --accent: var(--accent-ai); --accent-text: var(--accent-ai-text); }
.stk-pillar--security  { --accent: var(--accent-security); --accent-text: var(--accent-security-text); }
.stk-pillar--workplace { --accent: var(--accent-workplace); --accent-text: var(--accent-workplace-text); }
.stk-pillar--managed   { --accent: var(--accent-managed); --accent-text: var(--accent-managed-text); }
.stk-pillar > svg { width: 26px; height: 26px; color: var(--accent); margin-bottom: var(--space-2); }
/* One pillar name wraps to two lines and the other three do not, which left the
   four role lines and chevrons at different heights. Reserve the second line. */
.stk-pillar h4 {
  font-size: .95rem;
  line-height: 1.32;
  min-height: calc(2 * 1.32em);
  margin: 0;
}
.stk-role {
  font-family: var(--font-display);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0;
}
/* chevron, so the box reads as a route into the pillar */
.stk-pillar::after {
  content: "";
  position: absolute;
  right: var(--space-5);
  bottom: var(--space-4);
  width: 14px; height: 14px;
  background: var(--accent);
  opacity: .6;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 5l7 7-7 7' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 5l7 7-7 7' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  transition: transform var(--dur-fast) var(--ease-swift);
}
.stk-pillar:hover::after { transform: translateX(3px); opacity: 1; }

/* the core is the heart of the stack, so it carries the weight */
.stk-layer--core {
  background: linear-gradient(150deg, var(--navy-900), var(--blue-700));
  border-color: transparent;
}
.stk-layer--core .stk-head svg,
.stk-layer--core .stk-head h3 { color: var(--sky-300); }
.stk-layer--core .stk-note { color: rgba(255, 255, 255, .75); }
/* six blocks: a 250px floor gave four columns and left two empty cells in the
   second row. A 300px floor lands three and three. */
.stk-core {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: var(--space-3);
}
.stk-core li {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: rgba(255, 255, 255, .95);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
}
.stk-core svg { width: 22px; height: 22px; flex: none; color: var(--blue-700); }
.stk-core span {
  font-family: var(--font-display);
  font-size: .88rem;
  font-weight: 700;
  color: var(--ink-900);
}

.stk-connectors {
  /* size to the sentence so it holds one line, and only wrap when the
     viewport genuinely cannot fit it */
  width: max-content;
  max-width: 100%;
  margin-inline: auto;
  text-align: center;
  font-size: .86rem;
  color: var(--ink-700);
  background: var(--white);
  border: 1px dashed var(--line-300);
  border-radius: 999px;
  padding: .5rem var(--space-5);
}
.stk-connectors strong { font-family: var(--font-display); color: var(--navy-900); }

.stk-layer--env { --accent: var(--navy-900); --accent-text: var(--navy-900); background: var(--bg-50); }
.stk-env {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
  gap: var(--space-3);
}
.stk-env li {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: var(--white);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  font-size: .86rem;
  color: var(--ink-900);
  font-family: var(--font-display);
  font-weight: 600;
}
.stk-env svg { width: 20px; height: 20px; flex: none; color: var(--blue-700); }

/* the connection itself: short vertical rules between layers */
.stk-flow {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  height: var(--space-6);
  padding-inline: 12%;
}
.stk-flow--single { grid-template-columns: 1fr; padding-inline: 0; }
.stk-flow span {
  width: 2px;
  height: 100%;
  margin-inline: auto;
  background: linear-gradient(var(--line-300), var(--blue-500));
  border-radius: 1px;
}
.stk-flow--up span { background: linear-gradient(var(--blue-500), var(--line-300)); }

/* ------------------------------------------------- everyday example ----- */

.example {
  --accent: var(--blue-600);
  --accent-text: var(--blue-600-text);
  background:
    radial-gradient(760px 420px at 88% -30%, rgba(24, 119, 242, .30), transparent 62%),
    linear-gradient(155deg, var(--navy-950), var(--navy-800));
  border: 1px solid rgba(255, 255, 255, .10);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
  box-shadow: var(--shadow-md);
}

/* status strip: what stage the walkthrough is on right now */
html.js .example-progress i { transform: scaleX(0); }
html.reveal-all .example-progress i { transform: scaleX(1); }

.example-status {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding-bottom: var(--space-4);
  border-bottom: 1px solid rgba(255, 255, 255, .16);
  margin-bottom: var(--space-6);
}
.example-live {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--font-display);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .72);
}
.example-live i {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--sky-400);
  animation: examplePulse 1.8s var(--ease-swift) infinite;
}
@keyframes examplePulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .35; transform: scale(.7); }
}
.example-stage {
  font-family: var(--font-display);
  font-size: .92rem;
  font-weight: 700;
  color: var(--sky-300);
  margin-right: auto;
}
.example-progress {
  position: relative;
  width: 160px;
  height: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .18);
  overflow: hidden;
  flex: none;
}
.example-progress i {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--sky-400), var(--sky-300));
  transform-origin: left;
  transition: transform var(--dur-med) var(--ease-premium);
}

/* three connected steps, left to right */
.example-flow {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-6);
  counter-reset: step;
}
.example-step {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line-200);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
  transition: background var(--dur-med) var(--ease-swift),
              border-color var(--dur-med) var(--ease-swift),
              box-shadow var(--dur-med) var(--ease-swift),
              transform var(--dur-med) var(--ease-swift);
}
/* pending steps recede by surface, not by opacity, so their text keeps full
   strength. .94 is the lightest recede that still clears 4.5:1 for the two
   lighter pillar accents used by .example-step h3. */
html.js .example-step { background: rgba(255, 255, 255, .94); box-shadow: none; }
html.js .example-step.is-complete,
html.reveal-all .example-step { background: var(--white); }
.example-step.is-active {
  background: var(--white);
  transform: translateY(-4px);
  border-color: var(--sky-400);
  box-shadow: 0 16px 34px rgba(7, 20, 41, .45);
}

/* connector: faint track that fills with colour as the flow advances */
.example-step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 50%;
  right: calc(var(--space-6) * -1);
  width: var(--space-6);
  height: 12px;
  transform: translateY(-50%);
  background-image: linear-gradient(90deg, var(--sky-400) 50%, rgba(255, 255, 255, .26) 50%);
  background-size: 200% 100%;
  background-position: 0 0;
  transition: background-position var(--dur-med) var(--ease-premium);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 12'%3E%3Cpath d='M0 6h26M21 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 12'%3E%3Cpath d='M0 6h26M21 1l5 5-5 5' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
}
html.js .example-step:not(:last-child)::after { background-position: 100% 0; }
html.js .example-step.is-complete:not(:last-child)::after,
html.reveal-all .example-step:not(:last-child)::after { background-position: 0 0; }

.example-step-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--line-200);
  margin-bottom: var(--space-4);
}
.example-step-icon {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  flex: none;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 12%, var(--white));
  color: var(--accent);
  transition: background var(--dur-med) var(--ease-swift), color var(--dur-med) var(--ease-swift);
}
.example-step.is-active .example-step-icon,
.example-step.is-complete .example-step-icon {
  background: var(--accent);
  color: var(--white);
}
.example-step-icon svg { width: 18px; height: 18px; }
.example-step h3 {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-text);
  margin: 0;
}
.example-step p { font-size: .95rem; color: var(--ink-700); margin: 0; }
.example-step::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  font-family: var(--font-display);
  font-size: .78rem;
  font-weight: 800;
  color: var(--line-300);
}

@media (prefers-reduced-motion: reduce) {
  .example-step { opacity: 1; transform: none; }
  .example-step:not(:last-child)::after { background-position: 0 0; }
  .example-live i { animation: none; }
  .example-progress i { transform: scaleX(1); }
}

/* --------------------------------------------------------- reveal ------- */

/* Visible by default. The hidden state is applied only when the inline head
   script has confirmed JS is running, and `.reveal-all` is the escape hatch that
   script sets if anything goes wrong. Content can never end up stranded at
   opacity 0 because a script failed to load or an observer never reported. */
.reveal {
  transition: opacity var(--dur-slow) var(--ease-premium), transform var(--dur-slow) var(--ease-premium);
}
html.js .reveal { opacity: 1; transform: none; transition: none; }
html.js .reveal.active,
html.reveal-all .reveal { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .hero-orb { display: none; }
  .delivery-step::after { transform: scaleX(1); }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* =========================================================================
   Light and motion layer
   Added after the launch-readiness pass, on request, to give the site more
   depth and to show the stack's connections as you scroll to them.

   Three rules held throughout:
     1. Nothing here carries meaning. Every effect is decoration on content
        that is already fully readable without it.
     2. Nothing here touches text colour or its background, so the WCAG AA
        measurements from revision 6 still hold. Card glows are painted on
        the border only, through a mask, never as a wash over the card.
     3. Everything is inside `prefers-reduced-motion: no-preference`, and the
        pointer effects are additionally inside `hover: hover` so they never
        arm on touch.
   ========================================================================= */

/* --------------------------------------------- 1. scroll progress ------- */
/* A hairline under the sticky header showing how far down the page you are.
   Built by main.js, so it simply does not exist if the script fails. */
/* A faint full-width track sits under the fill. Without it the bar reads as a
   stray blue border that stops in the middle of the header rather than as a
   proportion of something — you cannot see progress without seeing the whole
   it is a part of. */
.scroll-progress {
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  overflow: hidden;
  pointer-events: none;
  background: var(--line-200);
}
.scroll-progress i {
  display: block;
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--blue-700), var(--blue-500), var(--sky-400));
  /* the leading edge is the part worth seeing */
  box-shadow: 0 0 6px color-mix(in srgb, var(--blue-500) 55%, transparent);
}

/* ------------------------------------------- 2. cursor edge light ------- */
/* The card's border lights up where the pointer is. Painted into a 1px ring
   with a mask so it can never sit over the text: the contrast inside the card
   is byte-for-byte what it was before this file grew. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .service-card, .card, .platform-module, .domain,
  .outcome, .catalogue-item, .stk-pillar { position: relative; }

  .service-card::after,
  .card::after,
  .platform-module::after,
  .domain::after,
  .outcome::after,
  .catalogue-item::after,
  .stk-pillar::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--dur-med) var(--ease-swift);
    background: radial-gradient(180px circle at var(--mx, 50%) var(--my, 50%),
      color-mix(in srgb, var(--accent, var(--blue-600)) 85%, transparent),
      transparent 68%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
  }
  .service-card:hover::after,
  .card:hover::after,
  .platform-module:hover::after,
  .domain:hover::after,
  .outcome:hover::after,
  .catalogue-item:hover::after,
  .stk-pillar:hover::before { opacity: 1; }

  /* on the dark outcomes band the accent is too deep to read as light */
  .outcome::after {
    background: radial-gradient(180px circle at var(--mx, 50%) var(--my, 50%),
      rgba(99, 194, 255, .9), transparent 68%);
  }
}

/* ------------------------------------------- 3. stack flow pulse -------- */
/* A pulse of light runs down each connector while the stack is on screen, so
   the diagram reads as one system rather than six stacked boxes. The static
   gradient line underneath is unchanged, so with motion off or JS dead the
   connectors look exactly as they did. */
.stk-flow span { position: relative; overflow: hidden; }

@media (prefers-reduced-motion: no-preference) {
  .stack.is-live .stk-flow span::after {
    content: "";
    position: absolute;
    left: 0; right: 0;
    height: 42%;
    border-radius: 1px;
    background: linear-gradient(var(--sky-300), var(--white), var(--sky-300));
    box-shadow: 0 0 8px 1px rgba(99, 194, 255, .85);
    animation: stk-pulse 2.6s var(--ease-swift) infinite;
  }
  .stack.is-live .stk-flow--up span::after { animation-name: stk-pulse-up; }

  /* stagger across the four connectors so it reads as flow, not a blink */
  .stack.is-live .stk-flow span:nth-child(2)::after { animation-delay: .18s; }
  .stack.is-live .stk-flow span:nth-child(3)::after { animation-delay: .36s; }
  .stack.is-live .stk-flow span:nth-child(4)::after { animation-delay: .54s; }
}

@keyframes stk-pulse {
  0%        { top: -50%; opacity: 0; }
  12%       { opacity: 1; }
  70%, 100% { top: 108%;  opacity: 0; }
}
@keyframes stk-pulse-up {
  0%        { top: 108%; opacity: 0; }
  12%       { opacity: 1; }
  70%, 100% { top: -50%; opacity: 0; }
}

/* ------------------------------------- 4. stack layer sequencing -------- */
/* Layers arrive top to bottom in the order the diagram is read. Each one is
   visible by default; the offset state applies only once JS has confirmed it
   can animate, the same contract the rest of the site uses. */
html.js .stack[data-stack-seq] > * {
  opacity: 1;
  transform: none;
  transition: none;
}
html.js .stack[data-stack-seq] > .stk-on,
html.reveal-all .stack[data-stack-seq] > * {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  html.js .stack[data-stack-seq] > * { opacity: 1; transform: none; transition: none; }
}

/* ------------------------------------------------ 5. hero aurora -------- */
/* A very slow sheen drifting behind the hero copy. Sits inside .hero-backdrop,
   which is already absolute, pointer-events-none decoration. */
@media (prefers-reduced-motion: no-preference) {
  .hero-backdrop::before,
  .hero-backdrop::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    filter: blur(70px);
    pointer-events: none;
  }
  .hero-backdrop::before {
    width: 46vw; height: 46vw;
    max-width: 620px; max-height: 620px;
    top: -18%; left: 52%;
    background: radial-gradient(circle, rgba(59, 155, 255, .34), transparent 66%);
    animation: aurora-a 19s ease-in-out infinite alternate;
  }
  .hero-backdrop::after {
    width: 34vw; height: 34vw;
    max-width: 460px; max-height: 460px;
    bottom: -22%; left: 10%;
    background: radial-gradient(circle, rgba(47, 184, 174, .26), transparent 66%);
    animation: aurora-b 24s ease-in-out infinite alternate;
  }
}
@keyframes aurora-a {
  from { transform: translate3d(0, 0, 0)        scale(1);    opacity: .75; }
  to   { transform: translate3d(-9%, 7%, 0)     scale(1.16); opacity: 1;   }
}
@keyframes aurora-b {
  from { transform: translate3d(0, 0, 0)        scale(1.1);  opacity: .6;  }
  to   { transform: translate3d(11%, -8%, 0)    scale(1);    opacity: .95; }
}

/* A lede that reads better unbroken than wrapped. Lifts the head's own 720px
   cap, which is what was breaking it, and keeps the heading centred with it. */
.section-head--lede { max-width: 920px; }
.section-head p.lede-wide { max-width: none; }

/* the "and there is more over here" link that closes a teaser section */
.section-more { margin: var(--space-8) 0 0; }

/* =========================================================================
   System spine
   A rail down the left margin whose track fills as you scroll and whose
   nodes light as their section arrives, so the home page reads as one
   connected run rather than eight unrelated blocks.

   Built by main.js from [data-spine] and marked aria-hidden: it is a
   progress indicator, not a second navigation, and if the script dies it
   simply never appears. Only shown where there is real margin to put it in
   (>= 1320px), so it can never crowd the text.
   ========================================================================= */
/* the rail belongs to the page's story; it fades out once the footer arrives
   rather than sitting over it */
.spine.is-done {
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-med) var(--ease-swift), visibility var(--dur-med) linear;
}
.spine {
  opacity: 1;
  visibility: visible;
  transition: opacity var(--dur-med) var(--ease-swift), visibility var(--dur-med) linear;
  position: fixed;
  top: 50%;
  left: max(20px, calc((100vw - var(--max-width)) / 2 - 62px));
  transform: translateY(-50%);
  z-index: 40;
  display: none;
  pointer-events: none;
}
@media (min-width: 1320px) and (prefers-reduced-motion: no-preference) {
  .spine { display: block; }
}

.spine-track {
  position: absolute;
  left: 4px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  border-radius: 1px;
  background: var(--line-300);
  overflow: hidden;
}
.spine-track i {
  display: block;
  width: 100%;
  height: 100%;
  transform: scaleY(0);
  transform-origin: 50% 0;
  background: linear-gradient(var(--blue-700), var(--blue-500) 55%, var(--sky-400));
}

.spine ol {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-5);
}
.spine li { position: relative; display: flex; align-items: center; gap: .6rem; }

.spine-dot {
  position: relative;
  width: 10px; height: 10px;
  flex: none;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--line-300);
  transition: border-color var(--dur-med) var(--ease-swift),
              background var(--dur-med) var(--ease-swift);
}
/* every section already passed */
.spine li.is-done .spine-dot { border-color: var(--blue-600); background: var(--blue-600); }
/* the section you are reading */
.spine li.is-current .spine-dot {
  border-color: var(--blue-600);
  background: var(--white);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue-600) 16%, transparent);
}
.spine li.is-current .spine-dot::after {
  content: "";
  position: absolute;
  inset: 1px;
  border-radius: 50%;
  background: var(--blue-600);
  animation: spine-beat 2.4s var(--ease-swift) infinite;
}
@keyframes spine-beat { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

.spine-label {
  font-family: var(--font-display);
  font-size: .64rem;
  font-weight: 700;
  letter-spacing: .15em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink-600);
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity var(--dur-med) var(--ease-swift),
              transform var(--dur-med) var(--ease-swift);
}
.spine li.is-current .spine-label { opacity: 1; transform: none; }

/* on a dark section the rail has to invert or it disappears into the ground */
.spine.on-dark .spine-track { background: rgba(255, 255, 255, .22); }
.spine.on-dark .spine-dot { background: var(--navy-950); border-color: rgba(255, 255, 255, .38); }
.spine.on-dark li.is-done .spine-dot { background: var(--sky-400); border-color: var(--sky-400); }
.spine.on-dark li.is-current .spine-dot {
  background: var(--navy-950);
  border-color: var(--sky-400);
  box-shadow: 0 0 0 4px rgba(99, 194, 255, .18);
}
.spine.on-dark li.is-current .spine-dot::after { background: var(--sky-400); }
.spine.on-dark .spine-label { color: var(--sky-300); }

/* =========================================================================
   Hero: the Big Dipper
   Seven stars at their true proportions — J2000 RA/Dec projected flat,
   rotated so the bowl leads on the left and the handle runs off right, then
   uniformly scaled clear of the headline column. Star sizes come from visual
   magnitude, so Alioth and Dubhe read brightest and Megrez stays faint.

   This replaced a connected node topology after both were built and compared
   side by side on the live page. Two animations it used are shared with the
   service-page, CTA and About marks, so they stay, renamed to say so.
   ========================================================================= */
@keyframes sig-travel {
  0%          { stroke-dashoffset: 476; opacity: 0; }
  5%          { opacity: 1; }
  42%         { stroke-dashoffset: 0;   opacity: 1; }
  48%, 100%   { stroke-dashoffset: 0;   opacity: 0; }
}
@keyframes sig-halo    { 0%, 100% { opacity: 1; transform-box: fill-box; } 50% { opacity: .35; } }

/* =========================================================================
   Section texture and transitions
   The page was reading as white block, white block, white block, dark block.
   Two devices fix that without touching a single word or colour of content:
   a faint dot field on the tinted sections, and soft bridges at the seams
   where a light section meets a dark one, so the change of ground is a
   gradient rather than a cut.
   Everything here is background: nothing sits above content, and every value
   is low enough that the text is unaffected.
   ========================================================================= */
.section-alt,
.section-dark,
.section-final-cta { position: relative; isolation: isolate; }

.section-alt > *,
.section-dark > *,
.section-final-cta > * { position: relative; z-index: 1; }

/* the dot field: an 18px lattice at ~3% ink, invisible until you look for it */
.section-alt::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(circle at center,
    color-mix(in srgb, var(--navy-800) 9%, transparent) 1px, transparent 1.2px);
  background-size: 22px 22px;
  /* strongest at the top edge, gone by a third of the way down, so it reads as
     the section arriving rather than as wallpaper */
  -webkit-mask-image: linear-gradient(#000, transparent 42%);
  mask-image: linear-gradient(#000, transparent 42%);
  opacity: .5;
}

/* dark sections get the same lattice in light ink, plus a soft crown so the
   jump from a white section above is a fade, not an edge */
.section-dark::before,
.section-final-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(circle at center, rgba(154, 216, 255, .16) 1px, transparent 1.2px);
  background-size: 26px 26px;
  -webkit-mask-image: linear-gradient(#000, transparent 55%);
  mask-image: linear-gradient(#000, transparent 55%);
  opacity: .5;
}
.section-dark::after {
  content: "";
  position: absolute;
  z-index: 0;
  left: 0; right: 0; top: 0;
  height: 190px;
  pointer-events: none;
  background: radial-gradient(60% 100% at 50% 0%, rgba(99, 194, 255, .16), transparent 72%);
}

/* --------------------------------------- stack: the live relationship --- */
/* The connector belonging to the pillar under the pointer or the keyboard is
   brought up; hovering the core brings up all four at once. The connectors
   themselves never carry information, so losing this changes nothing. */
.stack[data-stk] .stk-flow span { transition: background var(--dur-med) var(--ease-swift); }

.stack[data-stk="ai"]        .stk-flow span:nth-child(1),
.stack[data-stk="security"]  .stk-flow span:nth-child(2),
.stack[data-stk="workplace"] .stk-flow span:nth-child(3),
.stack[data-stk="managed"]   .stk-flow span:nth-child(4),
.stack[data-stk="core"]      .stk-flow span {
  background: var(--live, var(--blue-500));
  box-shadow: 0 0 9px color-mix(in srgb, var(--live, var(--blue-500)) 60%, transparent);
}
.stack[data-stk="ai"]        { --live: var(--accent-ai); }
.stack[data-stk="security"]  { --live: var(--accent-security); }
.stack[data-stk="workplace"] { --live: var(--accent-workplace); }
.stack[data-stk="managed"]   { --live: var(--accent-managed); }
.stack[data-stk="core"]      { --live: var(--sky-400); }

/* the chosen pillar leads; the others step back by surface only, never by
   opacity, so no card's text contrast moves */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .stack[data-stk="ai"]        .stk-pillar:not(.stk-pillar--ai),
  .stack[data-stk="security"]  .stk-pillar:not(.stk-pillar--security),
  .stack[data-stk="workplace"] .stk-pillar:not(.stk-pillar--workplace),
  .stack[data-stk="managed"]   .stk-pillar:not(.stk-pillar--managed) {
    box-shadow: none;
    border-color: var(--line-100);
  }
  .stack[data-stk="core"] .stk-layer--core {
    box-shadow: 0 0 0 1px rgba(99, 194, 255, .45), var(--shadow-md);
  }
}

/* ------------------------------------------------- CTA convergence ------ */
/* Four pillar nodes running down into one point directly above the panel: the
   same picture the hero opens with, closed. Sits in the section's own padding,
   above nothing and behind nothing, and is dropped entirely on narrow screens
   where the four columns it describes no longer exist. */
.cta-net {
  display: block;
  width: 100%;
  height: clamp(74px, 9vw, 118px);
  margin-bottom: -14px;
  pointer-events: none;
}
.cn-link { stroke: color-mix(in srgb, var(--navy-800) 22%, transparent); stroke-width: 1.1; }

.cn-node--ai        { fill: color-mix(in srgb, var(--accent-ai) 55%, transparent); }
.cn-node--security  { fill: color-mix(in srgb, var(--accent-security) 55%, transparent); }
.cn-node--workplace { fill: color-mix(in srgb, var(--accent-workplace) 55%, transparent); }
.cn-node--managed   { fill: color-mix(in srgb, var(--accent-managed) 55%, transparent); }

.cn-core      { fill: color-mix(in srgb, var(--blue-700) 72%, transparent); }
.cn-core-halo { fill: color-mix(in srgb, var(--blue-600) 12%, transparent); }

.cn-pulse {
  stroke: var(--blue-600);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-dasharray: 12 420;
  stroke-dashoffset: 432;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .cn-pulse { animation: cn-travel 6.4s linear infinite; }
  .cn-pulse--1 { animation-delay: 0s; }
  .cn-pulse--2 { animation-delay: .5s; }
  .cn-pulse--3 { animation-delay: 1s; }
  .cn-pulse--4 { animation-delay: 1.5s; }
  .cn-core-halo { animation: sig-halo 6.4s var(--ease-swift) infinite; }
}
@keyframes cn-travel {
  0%        { stroke-dashoffset: 432; opacity: 0; }
  6%        { opacity: .95; }
  34%       { stroke-dashoffset: 0;   opacity: .95; }
  40%, 100% { stroke-dashoffset: 0;   opacity: 0; }
}
@media (max-width: 760px) { .cta-net { display: none; } }

/* =========================================================================
   Service page topology
   One visual language, four arrangements — routed signals for AI, a perimeter
   for Cybersecurity, a hub and endpoints for Digital Workplace, a monitored
   run for Managed Services. Same lines, same nodes, same signal; only the
   shape and the pillar accent change, so the four pages read as related and
   still tell you which one you are on.
   Background only, inside .hero-backdrop, behind the h1 and breadcrumb.
   ========================================================================= */
.page-topo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* the accent is a dark ink on a navy hero, so the graphic is drawn in light
     and only tinted by it — never filled with it */
  color: color-mix(in srgb, var(--accent, var(--blue-600)) 34%, var(--sky-300));
  /* The headline lives on the left. The viewBox is sliced, so where any node
     lands depends on the viewport — rather than chase that, the whole graphic
     is masked out of the half the text occupies. It can never compete with the
     h1 at any width, which is the actual requirement. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, transparent 34%,
    rgba(0, 0, 0, .5) 52%, #000 70%);
  mask-image: linear-gradient(90deg, transparent 0%, transparent 34%,
    rgba(0, 0, 0, .5) 52%, #000 70%);
}

.pt-link { stroke: currentColor; stroke-width: 1.1; opacity: .26; }
.pt-node { fill: currentColor; opacity: .40; }
.pt-hub  { fill: currentColor; opacity: .46; }
.pt-hub-halo { fill: currentColor; opacity: .05; }

.pt-pulse {
  stroke: var(--white);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-dasharray: 14 460;
  stroke-dashoffset: 474;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .pt-pulse { animation: pt-travel 7.2s linear infinite; }
  .pt-pulse--1 { animation-delay: 0s; }
  .pt-pulse--2 { animation-delay: 1.8s; }
  .pt-pulse--3 { animation-delay: 3.6s; }
  .pt-pulse--4 { animation-delay: 5.4s; }
  .pt-hub-halo { animation: sig-halo 7s var(--ease-swift) infinite; }
}
@keyframes pt-travel {
  0%        { stroke-dashoffset: 474; opacity: 0; }
  5%        { opacity: .85; }
  38%       { stroke-dashoffset: 0;   opacity: .85; }
  44%, 100% { stroke-dashoffset: 0;   opacity: 0; }
}

/* on a phone the arrangement is mostly off-canvas and adds nothing */
@media (max-width: 760px) { .page-topo { opacity: .45; } }

/* =========================================================================
   About: introduction, the three modes, and the promise
   Supplied copy, set in the existing system — no new components beyond the
   three pieces below, and no new colours.
   ========================================================================= */
/* Heading on the left, the three paragraphs on the right. A single 74ch column
   left the whole right half of the section empty, which read as unfinished
   rather than as air. */
.about-lead {
  display: grid;
  grid-template-columns: minmax(0, .88fr) minmax(0, 1.12fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.about-lead .section-head { margin-bottom: 0; max-width: none; }
/* the column is already narrow; the display size for a full-width head breaks
   this one a word per line, so it steps down here */
.about-lead .section-head h2 {
  font-size: clamp(1.5rem, 2.1vw, 1.95rem);
  text-wrap: balance;
}
/* one column once the two tracks would each be too narrow to set text in */
@media (max-width: 900px) {
  .about-lead { grid-template-columns: minmax(0, 1fr); }
  .about-lead .section-head { max-width: none; margin-bottom: var(--space-4); }
}

.about-intro {
  display: grid;
  gap: var(--space-4);
  /* Justified, but never hyphenated: splitting words across lines reads worse
     than the uneven word spacing it was there to prevent. */
  text-align: justify;
  hyphens: manual;
  -webkit-hyphens: manual;
  /* keeps the last line from being left with a single short word */
  text-wrap: pretty;
}
/* the opening paragraph stays ragged: it is display size, where justification
   shows every uneven gap */
.about-intro p:first-child { text-align: left; }

.about-intro p { margin: 0; font-size: 1.04rem; color: var(--ink-700); }
.about-intro p:first-child {
  font-size: 1.16rem;
  color: var(--ink-800);
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.5;
}

/* Transform / Secure / Operate.
   These were three bordered cards, which made a three-word brand statement
   read as a product grid. The chrome is gone: three columns divided by a hair
   rule, each headed by its own accent bar. Same information, less furniture. */
.tso-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: clamp(1.75rem, 3.6vw, 3rem);
}
.tso {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-top: var(--space-5);
  border-top: 2px solid var(--accent);
}
/* a hair rule between columns, never before the first or after a wrapped row */
@media (min-width: 900px) {
  .tso + .tso {
    border-left: 1px solid var(--line-200);
    padding-left: clamp(1.75rem, 3.6vw, 3rem);
    margin-left: calc(clamp(1.75rem, 3.6vw, 3rem) * -.5);
  }
}
.tso-mark { display: block; color: var(--accent-text); }
.tso-mark svg { width: 28px; height: 28px; }
.tso h3 {
  font-size: 1.22rem;
  letter-spacing: -.01em;
  margin: 0;
  color: var(--accent-text);
}
.tso p { margin: 0; color: var(--ink-700); }

/* the closing statement: centred, quiet, and signed off with the tagline */
/* The closing statement sits on the tinted band now: centred text on plain
   white left the width either side reading as blank page rather than as a
   deliberate pause. The band carries the section dot texture, so the sides
   are part of the composition. */
.promise-block {
  max-width: none;
  margin-inline: auto;
  text-align: center;
  display: grid;
  gap: var(--space-3);
  justify-items: center;
}
.promise-block .eyebrow { margin-bottom: var(--space-1); }
.promise-block .promise-sign { margin-top: var(--space-4); }
/* the statement itself runs the width of the band; only the supporting line
   below it keeps a reading measure */
.promise-block > p:not(.promise-lead):not(.promise-sign) { max-width: 74ch; }
/* two short rules flanking the sign-off, so the line reads as a close */
.promise-sign {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
}
.promise-sign::before,
.promise-sign::after {
  content: "";
  height: 1px;
  width: clamp(28px, 8vw, 90px);
  background: linear-gradient(90deg, transparent, var(--line-300));
}
.promise-sign::after { background: linear-gradient(90deg, var(--line-300), transparent); }
.promise-block h2 { margin: 0; }
/* The statement IS the promise, so it is the heading — it was a paragraph set
   larger than the h2 above it, which inverted the hierarchy and left two
   labels ("In short" / "Our promise") doing one job. One eyebrow, one
   statement, one supporting line, one sign-off. */
.promise-lead {
  margin: 0;
  max-width: 34ch;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.3rem, 2.5vw, 1.95rem);
  line-height: 1.3;
  letter-spacing: -.012em;
  color: var(--ink-900);
  text-wrap: balance;
}
@media (min-width: 900px) { .promise-lead { max-width: 46ch; } }
.promise-block p { margin: 0; color: var(--ink-700); }
.promise-sign {
  margin: var(--space-2) 0 0;
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  font-size: .82rem;
  color: var(--blue-600-text);
}

/* =========================================================================
   Four pillars as one system                                  [RESTORED]
   This block was lost when the canvas hero-network was stripped: the removal
   truncated the file at that marker and took everything after it. The markup
   in index.html kept rendering, unstyled — a hub and an estate label sitting
   as bare text with no rail and no drop lines.

   The deck draws the pillars running on one platform and reaching one estate.
   The cards alone read as four unrelated products, so the platform sits above
   them and the estate below, joined by drop lines that land exactly on the
   card centres: the connector uses the same grid and gap as the cards, so the
   two stay aligned at every width without a line of JavaScript.
   Decorative and aria-hidden — it carries nothing that is not already written
   out on this page and on platform.html.
   ========================================================================= */
.pillar-link,
.pillar-foot {
  display: grid;
  justify-items: center;
  margin-bottom: var(--space-2);
}
.pillar-foot { margin: var(--space-2) 0 0; }

.pillar-link-hub {
  font-family: var(--font-display);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--blue-600-text);
  background: var(--white);
  border: 1px solid color-mix(in srgb, var(--blue-600) 26%, var(--white));
  border-radius: 999px;
  padding: .4rem 1rem;
  text-align: center;
}
.pillar-link-hub--estate {
  color: var(--ink-600);
  border-color: var(--line-300);
  letter-spacing: .08em;
  text-transform: none;
  font-size: .78rem;
  font-weight: 600;
}

/* the rail the four drops hang from */
.pillar-link-bar {
  position: relative;
  width: min(100%, 78%);
  height: 2px;
  border-radius: 1px;
  background: linear-gradient(90deg, transparent, var(--line-300) 12%,
              var(--line-300) 88%, transparent);
  margin-block: var(--space-4);
}
.pillar-link-bar::after {
  content: "";
  position: absolute;
  left: 50%; top: calc(var(--space-4) * -1);
  width: 2px; height: var(--space-4);
  background: var(--line-300);
}
.pillar-foot .pillar-link-bar::after { top: auto; bottom: calc(var(--space-4) * -1); }

/* four drops on the card grid's own tracks, so they land on the card centres */
.pillar-link-drops {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-6);
  width: 100%;
}
.pillar-link-drops i {
  display: block;
  width: 2px;
  height: var(--space-5);
  margin-inline: auto;
  border-radius: 1px;
  background: var(--line-300);
  transition: background var(--dur-med) var(--ease-swift),
              box-shadow var(--dur-med) var(--ease-swift);
}

/* the live path: the pillar under the pointer or the keyboard lights its own
   drop line above and below the cards */
[data-pillar="ai"]        .pillar-link-drops i:nth-child(1),
[data-pillar="security"]  .pillar-link-drops i:nth-child(2),
[data-pillar="workplace"] .pillar-link-drops i:nth-child(3),
[data-pillar="managed"]   .pillar-link-drops i:nth-child(4) {
  background: var(--live, var(--blue-600));
  box-shadow: 0 0 8px color-mix(in srgb, var(--live, var(--blue-600)) 55%, transparent);
}
[data-pillar] .pillar-link-hub {
  border-color: color-mix(in srgb, var(--live, var(--blue-600)) 45%, var(--white));
}
[data-pillar="ai"]        { --live: var(--accent-ai); }
[data-pillar="security"]  { --live: var(--accent-security); }
[data-pillar="workplace"] { --live: var(--accent-workplace); }
[data-pillar="managed"]   { --live: var(--accent-managed); }

/* The unselected cards step back by surface, never by opacity: dimming on a
   light ground drags text toward the background and would undo the contrast
   work in one hover state. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  [data-pillar] .service-card {
    transition: box-shadow var(--dur-med) var(--ease-swift),
                border-color var(--dur-med) var(--ease-swift),
                transform var(--dur-med) var(--ease-premium);
  }
  [data-pillar="ai"]        .service-card:not(.service-card--ai),
  [data-pillar="security"]  .service-card:not(.service-card--security),
  [data-pillar="workplace"] .service-card:not(.service-card--workplace),
  [data-pillar="managed"]   .service-card:not(.service-card--managed) {
    box-shadow: none;
    border-color: var(--line-100);
  }
}

/* The drops only describe the layout while the cards are in four columns.
   .cards-grid needs 4x258 plus three gaps of content width for that, so it
   breaks to three somewhere under 1152px: the diagram goes before it can
   misalign. This is why it must never render as bare text — if this rule is
   missing the markup still shows, which is exactly what happened. */
@media (max-width: 1159px) {
  .pillar-link, .pillar-foot { display: none; }
}

.cn-node { fill: color-mix(in srgb, var(--blue-600) 55%, transparent); }

/* ------------------------------------------------- section rhythm ------- */
/* The standard band is sized for a section with a head, a standfirst and a
   grid of cards. Three sections on the About page hold a single short row
   each, and at full padding they read as mostly empty rather than as spacious.
   They get a shorter band. */
.section--tight { padding-block: clamp(2.5rem, 4.4vw, 3.75rem); }

/* A head with no standfirst should sit closer to what it introduces; the
   space-10 gap is sized for the three-line version.
   This read var(--space-7), which is not one of the defined steps — the whole
   declaration was invalid and dropped, so the rule had never done anything. */
.section-head:not(:has(p)) { margin-bottom: var(--space-6); }

/* The About hero ring is centred on the brand mark, which lives on the right,
   so it needs less of a left fade than the service-page arrangements. */
.page-topo--ring {
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, transparent 40%,
    rgba(0, 0, 0, .5) 56%, #000 72%);
  mask-image: linear-gradient(90deg, transparent 0%, transparent 40%,
    rgba(0, 0, 0, .5) 56%, #000 72%);
}


/* AI & Automation's two decision points are gates, not nodes: a diamond reads
   as "a choice is made here" where another disc would just have added to the
   count of dots. */
.pt-gate { fill: none; stroke: currentColor; stroke-width: 1.6; opacity: .5; }

/* Platform's band rules: the horizontal lines that make the stack read as
   layers rather than as a mesh. */
.pt-band { stroke: currentColor; stroke-width: 1; opacity: .13; }




/* ---------------------------------------- pillar cards, aligned --------- */
/* On the service pages these cards carry the pillars' full names, so one pill
   wraps to two lines and the others do not — which pushed that card's icon,
   title, description and link a whole line lower than its neighbours. The pill
   reserves its second line here; the title and promise line do it where they
   are defined, above. */
.service-card .service-pill {
  display: flex;
  align-items: center;
  min-height: calc(2 * 1.45em);
  line-height: 1.45;
}
/* The home page's pills are short and always hold one line, so they keep their
   natural height. The names do not: two of the four wrap, which is why the
   title reservation applies there as well — exempting it left two cards'
   offering lists a line lower than the others. */
.home-page .service-card .service-pill { min-height: 0; }


/* The Dipper carries its own weights: at ambient opacity it was invisible,
   and a constellation has to be seen whole to read as one. */
.hero-net { -webkit-mask-image: none; mask-image: none; }
.dp-link  { stroke: rgba(180, 220, 255, .55); stroke-width: 1.4; }
.dp-dot   { fill: rgba(164, 214, 255, .35); }
.dp-star  { fill: rgba(232, 246, 255, .95); }
.dp-glow  { fill: rgba(140, 200, 255, .13); }
.dp-pulse {
  stroke: var(--white);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 16 460;
  stroke-dashoffset: 476;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .dp-pulse { animation: sig-travel 5.6s linear infinite; }
  .dp-pulse--1 { animation-delay: 0s; }
  .dp-pulse--2 { animation-delay: 1.4s; }
  .dp-pulse--3 { animation-delay: 2.8s; }
  .dp-pulse--4 { animation-delay: 4.2s; }
  .dp-glow { animation: sig-halo 6s var(--ease-swift) infinite; }
}

/* =========================================================================
   About lead mark
   The brand mark drawn in the site's node language: the shield filled and in
   front, the cloud outlined behind, and a triangulated mesh inside the shield.
   Shield and cloud are traced separately from logo-mark.png by colour, so the
   outline follows the real logo rather than an approximation of it.

   One block. Earlier passes appended a replacement each time instead of
   editing this one, which left three overlapping copies and an unbalanced
   brace — caught by counting braces, not by looking at the page.
   ========================================================================= */
.lead-mark {
  display: block;
  width: min(100%, 20.5rem);
  margin-top: var(--space-8);
  /* a deeper ink than the hero uses: this one has to hold on white */
  color: var(--blue-700);
  overflow: visible;
}

.lm-cloud-line  { fill: none; stroke: currentColor; stroke-width: 1.2; opacity: .38;
                  stroke-linejoin: round; stroke-linecap: round; }
/* gradient rather than a flat wash: it gives the shield a surface */
.lm-shield-fill { fill: url(#shieldFill); }
.lm-shield-line { fill: none; stroke: currentColor; stroke-width: 2.4; opacity: 1;
                  stroke-linejoin: round; }

/* the mesh: an outer ring, an inner ring and a few spokes to the centre. An
   earlier version ran every line from the centre to the rim, which read as a
   pie chart rather than a network. */
.lm-mesh      { stroke: currentColor; stroke-width: .9; opacity: .3; }
.lm-mesh--in  { opacity: .45; }
.lm-mesh-node { fill: currentColor; opacity: .55; }

.lm-node       { fill: currentColor; opacity: 1; r: 3.1px; }
.lm-node--soft { opacity: .45; r: 2.6px; }
.lm-core       { fill: currentColor; opacity: 1; r: 5.5px; }
.lm-core-halo  { fill: var(--white); opacity: .85; r: 13px; }

.lm-pulse {
  stroke: var(--sky-400);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-dasharray: 10 200;
  stroke-dashoffset: 196;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .lm-pulse { animation: lm-travel 6.6s linear infinite; }
  .lm-pulse--1 { animation-delay: 0s; }
  .lm-pulse--2 { animation-delay: 1.65s; }
  .lm-pulse--3 { animation-delay: 3.3s; }
  .lm-pulse--4 { animation-delay: 4.95s; }
}
@keyframes lm-travel {
  0%        { stroke-dashoffset: 196; opacity: 0; }
  10%       { opacity: 1; }
  46%       { stroke-dashoffset: 0;   opacity: 1; }
  54%, 100% { stroke-dashoffset: 0;   opacity: 0; }
}
@media (max-width: 900px) { .lead-mark { display: none; } }


/* =========================================================================
   Scroll state
   Three things read --sys. Opacity only: nothing here touches layout, so the
   scroll handler costs one custom-property write per frame and no reflow.

   Each starts at roughly two thirds strength and resolves, so the page is
   never dim at the top — it settles rather than switches on.
   ========================================================================= */

/* the pillar diagram's rail and drops firm up as the page is worked through */
.pillar-link-bar,
.pillar-link-drops i { opacity: calc(.62 + var(--sys) * .38); }

/* the dot field over tinted and dark sections comes in as the system connects */
.section-alt::before { opacity: calc(.34 + var(--sys) * .3); }
.section-dark::before { opacity: calc(.3 + var(--sys) * .34); }

/* the four accent nodes above the CTA are brightest at the end of the story */
.cn-link { opacity: calc(.45 + var(--sys) * .55); }
.cn-node--ai, .cn-node--security,
.cn-node--workplace, .cn-node--managed { opacity: calc(.5 + var(--sys) * .5); }

/* Reduced motion never runs the handler, so --sys stays 1 and everything above
   is simply at its resolved value. Stated explicitly so it is not mistaken for
   an oversight. */

/* ------------------------------------- the operating model, drawn ------- */
/* Five columns by five rows: card / connector / core / connector / card in both
   directions. The connectors are grid cells of their own, so they start and end
   exactly on the things they join at every width, with no measuring and no
   JavaScript. Built in this site's own language — hairlines, one navy core, the
   pillar accents already in use — not as a lit console.

   Deliberately absent: any "connected" or "synchronised" indicator. A static
   page cannot know that, and saying it would be a claim about a running system
   nobody has checked. */
.opmodel {
  position: relative;
  display: grid;
  grid-template-columns:
    minmax(0, 1fr) var(--space-8) minmax(220px, 20rem) var(--space-8) minmax(0, 1fr);
  grid-template-rows: auto var(--space-8) auto var(--space-8) auto;
  align-items: center;
  justify-items: stretch;
  gap: 0;
  max-width: 1000px;
  margin: 0 auto var(--space-10);
}

/* the compass points */
.opm-card--n { grid-area: 1 / 3; }
.opm-card--w { grid-area: 3 / 1; }
.opm-core    { grid-area: 3 / 3; }
.opm-card--e { grid-area: 3 / 5; }
.opm-card--s { grid-area: 5 / 3; }
.opm-link--n { grid-area: 2 / 3; }
.opm-link--w { grid-area: 3 / 2; }
.opm-link--e { grid-area: 3 / 4; }
.opm-link--s { grid-area: 4 / 3; }

.opm-card {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: var(--white);
  border: 1px solid var(--line-200);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-md);
  text-decoration: none;
  /* Two of the four names wrap and two do not. Reserving the second line inside
     the title fixed the heights but left a visible hole between title and
     description on the short ones, so the card reserves it instead: two title
     lines plus two description lines plus its own padding. The slack then falls
     at the foot of the card, where it reads as air. */
  min-height: calc(2 * 1.3em + 2 * 1.45em + 2 * var(--space-4) + 2px);
  transition: border-color var(--dur-med) var(--ease-swift),
              box-shadow var(--dur-med) var(--ease-swift),
              transform var(--dur-med) var(--ease-premium);
}
.opm-card:hover,
.opm-card:focus-visible {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line-200));
  border-left-color: var(--accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.opm-icon { color: var(--accent-text); flex: none; line-height: 0; }
.opm-icon svg { width: 22px; height: 22px; }
.opm-body { display: grid; gap: .18rem; min-width: 0; }
.opm-body strong {
  font-family: var(--font-display);
  font-size: .98rem;
  line-height: 1.3;
  color: var(--ink-900);
}
.opm-body span { font-size: .86rem; line-height: 1.45; color: var(--ink-600); }

/* the core: the one filled object in the arrangement, so it reads as the thing
   everything else hangs off */
.opm-core {
  position: relative;
  z-index: 1;
  display: grid;
  justify-items: center;
  gap: .25rem;
  text-align: center;
  padding: var(--space-6) var(--space-5);
  border-radius: var(--radius-lg);
  color: var(--white);
  background: linear-gradient(150deg, var(--navy-950), var(--blue-700));
  box-shadow: var(--shadow-lg);
  transition: box-shadow var(--dur-med) var(--ease-swift);
}
/* the same dot field the dark sections carry, at the density of a small panel */
.opm-core::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image: radial-gradient(rgba(255, 255, 255, .22) 1px, transparent 1px);
  background-size: 14px 14px;
  opacity: .3;
  pointer-events: none;
}
/* A halo behind the core, outside its box so it never moves anything.
   First attempt was a 1px hairline at 34% opacity sixteen pixels out: correct in
   principle, invisible in practice — the reviewer's response was "what ring?".
   A soft field carries much further on a light ground than a thin line does, and
   it reads at a glance without turning the panel into a console. */
.opm-core::after {
  content: "";
  position: absolute;
  inset: calc(var(--space-8) * -1);
  border-radius: 50%;
  background: radial-gradient(closest-side,
    color-mix(in srgb, var(--blue-500) 30%, transparent) 0%,
    color-mix(in srgb, var(--blue-500) 12%, transparent) 55%,
    transparent 100%);
  pointer-events: none;
  z-index: -1;
}
@media (prefers-reduced-motion: no-preference) {
  .opm-core::after { animation: opm-halo-breathe 5.6s var(--ease-swift) infinite; }
}
@keyframes opm-halo-breathe {
  0%, 100% { transform: scale(.94); opacity: .55; }
  50%      { transform: scale(1.06); opacity: 1; }
}
.opm-core-mark {
  color: var(--sky-300);
  line-height: 0;
  margin-bottom: var(--space-2);
}
.opm-core-mark svg { width: 34px; height: 34px; }
.opm-core-eyebrow {
  font-family: var(--font-display);
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--sky-300);
}
.opm-core strong {
  font-family: var(--font-display);
  font-size: 1.12rem;
  line-height: 1.3;
  color: var(--white);
}
.opm-core-sub { font-size: .85rem; color: rgba(255, 255, 255, .78); }

/* the connectors */
.opm-link {
  display: block;
  position: relative;
  align-self: stretch;
  justify-self: stretch;
  background: var(--line-300);
  transition: background var(--dur-med) var(--ease-swift);
}
/* a node where each line meets the core — the same mark the pillar diagram and
   the hero use, so the page has one vocabulary for "a connection lands here" */
.opm-link::before {
  content: "";
  position: absolute;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--blue-500);
  opacity: .9;
  transition: transform var(--dur-med) var(--ease-premium),
              border-color var(--dur-med) var(--ease-swift);
}
.opm-link--n::before { left: 50%; bottom: -4px; transform: translateX(-50%); }
.opm-link--s::before { left: 50%; top: -4px;    transform: translateX(-50%); }
.opm-link--w::before { top: 50%;  right: -4px;  transform: translateY(-50%); }
.opm-link--e::before { top: 50%;  left: -4px;   transform: translateY(-50%); }
.opm-link--n, .opm-link--s { width: 2px; margin-inline: auto; }
.opm-link--w, .opm-link--e { height: 2px; margin-block: auto; }

/* Hover a pillar and the line it sits on comes up, its node opens, and the core
   answers. Hover the core and all four do. This is the same behaviour the
   platform stack already has, so the page reads as one system and not as two
   different ideas about what hovering means. Pointer devices only, and never a
   change that moves anything. */
@media (hover: hover) {
  .opmodel:has(.opm-card--n:hover) .opm-link--n,
  .opmodel:has(.opm-card--w:hover) .opm-link--w,
  .opmodel:has(.opm-card--e:hover) .opm-link--e,
  .opmodel:has(.opm-card--s:hover) .opm-link--s,
  .opmodel:has(.opm-core:hover) .opm-link { background: var(--blue-500); }

  .opmodel:has(.opm-card--n:hover) .opm-link--n::before,
  .opmodel:has(.opm-card--w:hover) .opm-link--w::before,
  .opmodel:has(.opm-card--e:hover) .opm-link--e::before,
  .opmodel:has(.opm-card--s:hover) .opm-link--s::before,
  .opmodel:has(.opm-core:hover) .opm-link::before { border-color: var(--blue-600); }
  .opmodel:has(.opm-card--n:hover) .opm-link--n::before,
  .opmodel:has(.opm-card--s:hover) .opm-link--s::before,
  .opmodel:has(.opm-core:hover) .opm-link--n::before,
  .opmodel:has(.opm-core:hover) .opm-link--s::before { transform: translateX(-50%) scale(1.35); }
  .opmodel:has(.opm-card--w:hover) .opm-link--w::before,
  .opmodel:has(.opm-card--e:hover) .opm-link--e::before,
  .opmodel:has(.opm-core:hover) .opm-link--w::before,
  .opmodel:has(.opm-core:hover) .opm-link--e::before { transform: translateY(-50%) scale(1.35); }

  .opmodel:has(.opm-card:hover) .opm-core,
  .opm-core:hover {
    box-shadow: var(--shadow-lg),
                0 0 0 1px color-mix(in srgb, var(--blue-500) 55%, transparent);
  }
}
/* keyboard gets the same answer as the mouse */
.opmodel:has(.opm-card--n:focus-visible) .opm-link--n,
.opmodel:has(.opm-card--w:focus-visible) .opm-link--w,
.opmodel:has(.opm-card--e:focus-visible) .opm-link--e,
.opmodel:has(.opm-card--s:focus-visible) .opm-link--s { background: var(--blue-500); }

/* one signal travelling inward on each line, on the same clock as the rest of
   the page's marks */
@media (prefers-reduced-motion: no-preference) {
  .opm-link::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(var(--dir, 180deg), transparent 0%,
      var(--blue-500) 45%, var(--blue-500) 55%, transparent 100%);
    background-size: 100% 220%;
    animation: opm-travel 4.8s linear infinite;
  }
  .opm-link--w::after, .opm-link--e::after {
    background-size: 220% 100%;
    animation-name: opm-travel-x;
  }
  .opm-link--w::after { --dir: 90deg; }
  .opm-link--e::after { --dir: 270deg; }
  .opm-link--s::after { --dir: 0deg; }
  .opm-link--n::after { animation-delay: 0s; }
  .opm-link--w::after { animation-delay: 1.2s; }
  .opm-link--e::after { animation-delay: 2.4s; }
  .opm-link--s::after { animation-delay: 3.6s; }
}
@keyframes opm-travel {
  0%   { background-position: 0 -120%; opacity: 0; }
  12%  { opacity: 1; }
  60%  { background-position: 0 120%; opacity: 1; }
  70%, 100% { background-position: 0 120%; opacity: 0; }
}
@keyframes opm-travel-x {
  0%   { background-position: -120% 0; opacity: 0; }
  12%  { opacity: 1; }
  60%  { background-position: 120% 0; opacity: 1; }
  70%, 100% { background-position: 120% 0; opacity: 0; }
}

/* Below this the cross has no room: the side cards would be narrower than their
   own titles. It becomes a plain column — core first, because it is the thing
   the four are delivered on — and the connectors go, since there is no longer a
   geometry for them to describe. */
@media (max-width: 900px) {
  .opmodel {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
    gap: var(--space-4);
    max-width: 30rem;
  }
  .opm-core, .opm-card--n, .opm-card--w, .opm-card--e, .opm-card--s { grid-area: auto; }
  .opm-core { order: -1; }
  .opm-link { display: none; }
  .opm-core::after { display: none; }
  .opm-card { min-height: 0; }
}

/* ------------------------------------- operational domains, connected --- */
/* The platform reaches an estate; the domains are that estate. These drops use
   the domain grid's own tracks and gap, so they land on the column centres at
   any width, and they go when the grid stops being three columns. */
.domain-link { display: grid; justify-items: center; margin-bottom: var(--space-2); }
/* The rail ends on the outer drops, not past them. The shared 78% is sized for
   the four-column diagram; over three columns it left ~95px of line hanging off
   each end with nothing under it, which is what made the whole arrangement read
   as a stray mark. Outer drop centres sit half a column in, so the rail spans
   the full width less one column: W - (W - 2 * gap) / 3. */
.domain-link .pillar-link-bar {
  width: calc(100% - (100% - 2px) / 3);
  margin-block: 0 var(--space-4);
  /* the shared rail fades out over its outer 12%, which is right when the ends
     are hanging free; here they terminate on the drops, so they hold */
  background: var(--line-300);
}
/* The four-column diagram's centre stub points up at its hub. There is no hub
   here, and at three columns the stub landed exactly on the middle drop and
   doubled its length. */
.domain-link .pillar-link-bar::after { content: none; }
.domain-link-drops {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  width: 100%;
}
.domain-link-drops i {
  display: block;
  width: 2px;
  height: var(--space-5);
  margin-inline: auto;
  border-radius: 1px;
  background: var(--line-300);
  opacity: calc(.55 + var(--sys) * .45);
}
/* .domain-grid needs 3 x 310px plus two gaps of content width for three
   columns; below that the drops would describe a layout that is not there */
@media (max-width: 1040px) { .domain-link { display: none; } }

/* ------------------------------------- hero: the system under the sky --- */
/* A quarter of the Dipper's weight. It is there to be felt, not read. */
.sysnet {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.sysnet-link { stroke: rgba(150, 200, 255, .18); stroke-width: 1; }
.sysnet-node { fill: rgba(164, 214, 255, .3); }
.sysnet-core { fill: rgba(196, 232, 255, .42); }
.sysnet-pulse {
  stroke: rgba(214, 240, 255, .75);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-dasharray: 12 340;
  stroke-dashoffset: 352;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .sysnet-pulse { animation: sig-travel 8.4s linear infinite; }
  .sysnet-pulse--1 { animation-delay: 0s; }
  .sysnet-pulse--2 { animation-delay: 2.1s; }
  .sysnet-pulse--3 { animation-delay: 4.2s; }
  .sysnet-pulse--4 { animation-delay: 6.3s; }
}
/* on a phone the Dipper alone is enough */
@media (max-width: 760px) { .sysnet { display: none; } }

/* Revision 9: product clarity, visible content and responsive examples. */
[id] { scroll-margin-top: 100px; }
.platform-page .page-hero .eyebrow { font-size: 1rem; letter-spacing: .08em; }
.platform-page .page-hero .cta-actions { margin-top: 1.6rem; }
.gahana-light-link { display: inline-block; color: #fff; text-decoration: underline; margin-top: 1rem; }
.module-caps li, .stk-inline li { font-size: .875rem; color: #334761; background: #edf3fa; }
.platform-grid { align-items: start; }
.product-details { margin-top: 1.3rem; border-top: 1px solid #dce5f0; padding-top: 1rem; }
.product-details summary { cursor: pointer; color: #075ab1; font-weight: 600; padding: .35rem 0; }
.product-details h4 { margin: 1rem 0 .4rem; font-size: .95rem; }
.product-details p { font-size: .94rem; line-height: 1.65; }
.product-note { padding: .8rem; background: #edf3fa; border-radius: 8px; }
.workflow-example { background: #fff; border: 1px solid #cad9eb; border-radius: 20px; overflow: hidden; }
.workflow-caption { padding: 1rem 1.5rem; background: #10294e; color: #fff; display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.workflow-caption span { color: #d7e7ff; font-size: .9rem; }
.gahana-flow { list-style: none; padding: 1.5rem; margin: 0; display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: 1rem; }
.gahana-flow li { padding: 1.3rem; border: 1px solid #dce5f0; border-radius: 12px; background: #f6f9fd; }
.flow-number { display: inline-flex; width: 2rem; height: 2rem; align-items: center; justify-content: center; border-radius: 50%; color: #fff; background: #075ab1; font-size: .85rem; }
.gahana-flow h3 { margin: .8rem 0 .4rem; font-size: 1.15rem; }
.gahana-flow strong { font-size: .88rem; color: #075ab1; }
.gahana-flow p { margin: .65rem 0 0; font-size: .95rem; }
.workflow-foot { margin: 0; padding: 1rem 1.5rem; border-top: 1px solid #dce5f0; font-size: .9rem; }
.gahana-note { color: #435570; margin-top: 1.5rem; font-size: .95rem; max-width: 85ch; }
.gahana-options { display: grid; grid-template-columns: repeat(3,minmax(0,1fr)); gap: 1.2rem; }
.gahana-options article { padding: 1.6rem; border: 1px solid #dce5f0; border-radius: 16px; background: #fff; }
.gahana-options h3 { margin: .8rem 0; }
.gahana-options .btn-link { margin-top: 1rem; }
.maturity-list { list-style: none; padding: 0; display: grid; gap: .7rem; }
.maturity-list li { display: flex; align-items: start; gap: 1rem; padding: 1rem 1.3rem; background: #fff; border: 1px solid #dce5f0; border-radius: 12px; }
.maturity-number { flex: 0 0 2rem; text-align: center; padding: .25rem; background: #e3f1fb; color: #075ab1; border-radius: 6px; font-weight: 700; }
.maturity-list h3 { font-size: 1rem; margin: 0 0 .2rem; }
.maturity-list p { margin: 0; }
.product-details summary:focus-visible, .gahana-light-link:focus-visible { outline: 3px solid #149ba5; outline-offset: 4px; }
.platform-page .page-hero .cta-actions { justify-content: flex-start; }

/* Revision 10: concise, customer-focused homepage. */
.scp10-hero { padding: 80px 0; background: linear-gradient(125deg,#f0f6ff,#fff 55%,#ecf9f8); }
.scp10-hero-grid { display:grid; grid-template-columns:1.15fr 1fr; gap:56px; align-items:center; }
.scp10-hero h1 { font-size:clamp(2.3rem,4.1vw,3.6rem); line-height:1.12; letter-spacing:-.045em; color:#10233f; margin:18px 0 24px; }
.scp10-hero p { font-size:1.1rem; color:#4c6179; line-height:1.75; }
.scp10-actions { display:flex; flex-wrap:wrap; gap:12px; margin-top:28px; }
.scp10-secondary { background:white; border:1px solid #bbcadc; color:#10233f; }
.scp10-console { background:#10233f; color:#fff; border-radius:22px; padding:28px; box-shadow:0 24px 60px #12375c24; }
.scp10-console-top { display:flex; justify-content:space-between; align-items:center; gap:12px; font-size:.82rem; font-weight:700; letter-spacing:.06em; }
.scp10-badge { color:#bfe9f0; border:1px solid #476078; border-radius:30px; padding:5px 9px; font-size:.7rem; letter-spacing:0; }
.scp10-console h2 { color:white; font-size:1.4rem; line-height:1.3; margin:26px 0 8px; }
.scp10-console p { color:#bacde2; font-size:.86rem; margin:0; }
.scp10-console-grid { display:grid; grid-template-columns:1fr 1fr; gap:12px; margin-top:22px; }
.scp10-console-grid>div { background:#1b3757; padding:16px; border-radius:12px; }
.scp10-console-grid small { color:#c1d4eb; font-size:.75rem; }
.scp10-console-grid strong { display:block; line-height:1.4; margin:7px 0; font-size:1rem; }
.scp10-console-grid span { color:#b1c9e2; font-size:.75rem; }
.scp10-case { background:#18314e; border:1px solid #35516e; border-radius:12px; padding:18px; margin-top:14px; }
.scp10-case-label { font-size:.66rem; letter-spacing:.07em; color:#a4dce8; }
.scp10-case ol { list-style:none; padding:0; margin:14px 0 0; display:grid; gap:14px; }
.scp10-case li { display:flex; align-items:center; gap:12px; font-size:.83rem; }
.scp10-case b { color:#85d4de; font-size:.75rem; }
.scp10-console .scp10-caption { margin-top:15px; font-size:.72rem; color:#b4c7db; }
.scp10-pillars { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:18px; }
.scp10-pillars article { padding:26px; border:1px solid #dce5f0; border-top:3px solid #1769e0; border-radius:14px; display:flex; flex-direction:column; }
.scp10-pillars article:nth-child(even) { border-top-color:#008b91; }
.scp10-number { color:#075ab1; font-weight:700; margin-bottom:18px; }
.scp10-pillars h3 { font-size:1.18rem; line-height:1.4; margin-bottom:14px; }
.scp10-pillars p { color:#4c6179; font-size:.95rem; }
.scp10-pillars .scp10-scope { font-size:.82rem; border-top:1px solid #e2eaf3; padding-top:16px; margin-top:16px; }
.scp10-pillars .btn-link { margin-top:auto; padding-top:20px; }
.scp10-platform { background:#10233f; padding:72px 0; color:#fff; }
.scp10-platform .eyebrow { color:#81d5e1; }
.scp10-platform h2 { color:white; font-size:clamp(1.8rem,3vw,2.5rem); margin-top:12px; }
.scp10-platform-head { display:grid; grid-template-columns:1fr 1fr; align-items:center; gap:48px; }
.scp10-platform-head p { color:#c5d4e6; line-height:1.8; }
.scp10-products { display:flex; flex-wrap:wrap; gap:12px; margin-top:32px; }
.scp10-products a { display:flex; align-items:center; gap:22px; padding:14px 18px; border:1px solid #466181; border-radius:10px; color:white; font-size:.95rem; background:#193553; }
.scp10-products a:hover { background:#24496f; }
.scp10-products a span { color:#81d5e1; }
.scp10-dark-secondary { color:white; border:1px solid #7891ae; }
.scp10-platform-note { font-size:.85rem; color:#b5c9df; margin-top:18px; }
.scp10-workflow { list-style:none; padding:0; display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:24px; margin:0 0 28px; }
.scp10-workflow li { border-top:3px solid #168f99; padding:22px 0 0; }
.scp10-workflow span { color:#075ab1; font-size:.8rem; text-transform:uppercase; font-weight:700; }
.scp10-workflow h3 { font-size:1.15rem; margin:12px 0; }
.scp10-workflow p { font-size:.95rem; color:#4c6179; }
.scp10-reasons { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:24px; }
.scp10-reasons article { padding:28px; background:white; border:1px solid #dce5f0; border-radius:14px; }
.scp10-reasons h3 { font-size:1.15rem; margin-bottom:14px; }
.scp10-reasons p { color:#4c6179; font-size:.95rem; }

/* Revision 11: experience and Asia-Pacific reach. */
.scp11-proof { background:#10233f; color:#fff; padding:26px 0; }
.scp11-proof>.container { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:24px; }
.scp11-proof strong { display:block; font-size:1.25rem; color:#fff; margin-bottom:6px; }
.scp11-proof span { color:#c4d8ed; font-size:.85rem; }
.scp11-region-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:22px; }
.scp11-region-grid article { background:#fff; border:1px solid #d4e1ee; border-top:3px solid #168b98; border-radius:14px; padding:26px; }
.scp11-region-grid h3 { margin-bottom:18px; font-size:1.2rem; color:#10233f; }
.scp11-region-grid ul { list-style:none; padding:0; margin:0; display:flex; flex-wrap:wrap; gap:9px; }
.scp11-region-grid li { background:#edf4fb; color:#294766; border-radius:6px; padding:7px 12px; font-size:.94rem; }
.scp11-region .btn-link { margin-top:18px; }
.scp11-experience-grid { display:grid; grid-template-columns:1fr 1.2fr; gap:50px; align-items:start; }
.scp11-experience h2 { font-size:clamp(1.8rem,3vw,2.5rem); line-height:1.2; margin-top:14px; }
.scp11-experience p { color:#4c6179; margin-bottom:18px; }
