/* Hazen Systems — site stylesheet.
   Tokens and base component classes below are carried over from the
   "Nocturne" design system generated with the original Claude Design draft.
   Layout utility classes (.container, .section, .grid-auto, etc.) were
   added to turn the design into a real multi-page site. */

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
  --color-bg: #121020;
  --color-surface: #232532;
  --color-text: #f2f0f7;
  --color-accent: #9184d9;
  --color-accent-2: #a7a1db;
  --color-divider: color-mix(in srgb, var(--color-text) 12%, transparent);

  --color-neutral-100: #f3f5fe;
  --color-neutral-200: #e4e7f5;
  --color-neutral-300: #cfd3e5;
  --color-neutral-400: #b2b6ca;
  --color-neutral-500: #9397ab;
  --color-neutral-600: #75798c;
  --color-neutral-700: #595d6c;
  --color-neutral-800: #3f424d;
  --color-neutral-900: #292b31;

  --color-accent-100: #f5f4ff;
  --color-accent-200: #e7e5fe;
  --color-accent-300: #d2cefd;
  --color-accent-400: #b5abfc;
  --color-accent-500: #968ae0;
  --color-accent-600: #796cbf;
  --color-accent-700: #5d5294;
  --color-accent-800: #423a6a;
  --color-accent-900: #2b2741;

  --color-section: #262a60;
  --color-section-glow: #353b80;

  --font-heading: "Inter", system-ui, sans-serif;
  --font-heading-weight: 500;
  --font-body: "Inter", system-ui, sans-serif;

  --space-1: 3px;
  --space-2: 6px;
  --space-3: 8px;
  --space-4: 11px;
  --space-6: 17px;
  --space-8: 22px;

  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 14px;

  --shadow-sm: 0 0 0 1px #3f424d;
  --shadow-md: 0 0 0 1px #595d6c, 0 6px 18px rgba(0,0,0,0.55);
  --shadow-lg: 0 0 0 1px #9397ab, 0 16px 40px rgba(0,0,0,0.65);

  --max-width: 1280px;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background:
    radial-gradient(1000px 500px at 50% 100%, rgba(124, 91, 179, 0.10), transparent 60%),
    var(--color-bg);
  background-repeat: no-repeat;
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  font-weight: 400;
}

/* — hero backdrop: the real light-beam + grid-floor artwork, stretched
   tall enough to still be visible behind the tool marquee, with a soft
   fade at both the top and bottom so there's no hard seam either side — */
.hero-backdrop {
  position: absolute; top: 0; left: 0; width: 100%; height: 720px;
  overflow: hidden; z-index: -1; pointer-events: none;
}
.hero-beam {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 100%; min-width: 1440px; height: 100%;
  background-image: url('../images/hero-bg.webp?v=2');
  background-repeat: no-repeat;
  background-position: top center;
  background-size: 100% 100%;
}
.hero-fade {
  position: absolute; left: 0; right: 0; bottom: 0; height: 220px;
  background: linear-gradient(to bottom, transparent, var(--color-bg));
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  line-height: 1.12;
  letter-spacing: -0.015em;
  margin: 0 0 var(--space-2);
  color: var(--color-text);
}
h1 { font-size: 44px; color: #ffffff; }
h2 { font-size: 32px; }
h3 { font-size: 19px; }
h4 { font-size: 17px; }
h6 { font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; }

p { margin: 0 0 var(--space-3); }
a { color: var(--color-accent); text-underline-offset: 3px; }
img, svg { display: block; max-width: 100%; }

:focus { outline: none; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* — motion: smooth, subtle, and off for anyone who's asked for less — */
a, .btn, .tag, .card, .panel-link, .nav-dropdown a, .nav-mobile a, .footer-links a,
.footer-bottom-links a, .footer-social a {
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; scroll-behavior: auto !important; }
}
.reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.5s ease, transform 0.5s ease; }
.reveal.is-visible { opacity: 1; transform: translateY(0); }

/* The settled rule, site-wide: headlines and body paragraphs outside
   cards are full brightness, .card-title is accent (#d2cefd), and text
   inside a card stays muted. .text-muted itself used to always mean
   "dimmed", which is what let plenty of real subtext/paragraph copy
   (How It Works, every service/industry page's own intro line, the
   homepage bio and workflow-banner text) stay dim while card copy
   elsewhere got brightened, mixing the two inconsistently from page to
   page. Full brightness is now the default; .card .text-muted below
   re-dims the handful of genuinely card-internal uses (the pricing tier
   labels, the book-a-call ticks). */
.text-muted { color: var(--color-text); }
.card .text-muted { color: color-mix(in srgb, var(--color-text) 55%, transparent); }
/* A manual line break that only takes effect at the tablet/landscape
   width where a particular heading's natural wrap point stops matching
   its row-mates (see the 641-1053px tier below): hidden everywhere else
   so the heading wraps on its own as usual. */
.tablet-break { display: none; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* — layout — */
.container { max-width: var(--max-width); margin: 0 auto; padding: 0 40px; }
.section { padding: 64px 40px; max-width: var(--max-width); margin: 0 auto; }
.section-narrow { max-width: 900px; }
.section-hero { padding: 96px 40px 80px; max-width: var(--max-width); margin: 0 auto; position: relative; z-index: 1; }
.section-hero h1 { font-size: 56px; }

.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  color: #f2f0f7; font-size: 12px; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  background: var(--color-accent-800); border: 1px solid var(--color-accent-700);
  border-radius: 20px;
  padding: 6px 14px; margin-bottom: 24px;
}

.eyebrow-plain {
  color: var(--color-accent-300); font-size: 12px; font-weight: 500;
  letter-spacing: 0.06em; text-transform: uppercase; margin-bottom: 16px;
}

.kicker {
  font-size: 14px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--color-neutral-500);
  margin: 0 0 28px;
}

.grid-auto {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 24px;
}
.grid-auto-wide {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 20px;
}
.grid-auto-narrow {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0;
}
.grid-auto-stat {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 32px;
}

.panel {
  background: var(--color-surface); border: 1px solid var(--color-neutral-800);
  border-radius: var(--radius-lg); padding: 28px;
  position: relative;
}
.panel-link { display: block; text-decoration: none; }
.panel-link:hover { border-color: var(--color-accent); }

/* — proof-of-capability demo cards: a clickable thumbnail bleeding to the
   card's edges (opens the existing video-modal, see .video-trigger),
   with its own padded text block below — */
/* Subgrid, not a fixed reserved height: these titles run from one short
   line to a long two-sentence headline, needing anywhere from 2 lines at
   a wide desktop width to 7+ lines on a narrow phone, and that range
   shifts with every breakpoint's column count. A fixed reservation sized
   for the worst case would leave a huge dead gap under short titles at
   the wide end of the same column count. Subgridding the three rows
   (thumb, title, body) into the parent's row tracks instead sizes each
   row to the tallest sibling actually sharing it, at any width, with no
   guessed value to maintain. */
.proof-card { padding: 0; overflow: hidden; text-align: center; }
/* Scoped to .proof-grid specifically, not every .proof-card: blog posts
   reuse .proof-card on its own for a single embedded video thumbnail,
   with no .proof-grid parent to subgrid rows from and no title/body
   siblings to sync against. Subgridding it there anyway (an earlier
   version of this rule matched every .proof-card) left it requesting
   rows from a parent that isn't a grid at all, which collapsed the
   thumbnail instead of sizing it. */
/* A subgrid without its own gap inherits the parent grid's (.proof-grid,
   24px, from the shared .grid-auto base) for the rows it subgrids too,
   stacking on top of the title/body's own margins and spacing everything
   out much further than the flex layout this replaced ever did. Zeroing
   it here leaves each row's own margin as the only spacing again. */
.proof-grid .card.proof-card { display: grid; grid-template-rows: subgrid; grid-row: span 3; row-gap: 0; }
.proof-thumb {
  display: block; position: relative; width: 100%; aspect-ratio: 16 / 9;
  overflow: hidden; border: none; margin: 0; padding: 0; background: none;
}
.proof-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.35s ease; }
.proof-thumb:hover img { transform: scale(1.045); }
.proof-play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.proof-play::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10, 9, 15, 0) 45%, rgba(10, 9, 15, 0.6) 100%);
}
.proof-play svg {
  position: relative; z-index: 1; width: 22px; height: 22px; padding: 17px; box-sizing: content-box;
  border-radius: 50%; background: rgba(20, 18, 30, 0.72);
  border: 1.5px solid rgba(210, 206, 253, 0.5); fill: var(--color-accent-300);
  transition: transform 0.25s ease, background 0.25s ease, border-color 0.25s ease, fill 0.25s ease;
}
.proof-thumb:hover .proof-play svg {
  transform: scale(1.08); background: var(--color-accent); border-color: var(--color-accent); fill: #161826;
}
.proof-thumb-pending { cursor: default; }
.proof-thumb-pending img { filter: grayscale(0.35) brightness(0.65); }
.proof-pending-label {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(10, 9, 15, 0.4); color: var(--color-text);
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase;
}
/* .proof-card-body no longer wraps these two (it broke the title and
   body out of the subgrid's three direct-child rows), so its old padding
   moves onto the title (top + sides) and body (sides + bottom) directly.
   Both sizes match the rest of the site's cards now (20px/14.5px): phone
   and tablet already fold this title into the same shared size as every
   other card (see their "one heading size, site-wide" rules), so leaving
   it smaller only at desktop was its own inconsistency across viewports,
   not just against other cards at the same width. */
.proof-card .card-title { font-size: 20px; line-height: 1.35; margin: 22px 24px 10px; }
.proof-card .card-body { font-size: 14.5px; margin: 0 24px 26px; }
.proof-grid { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) {
  .proof-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .proof-grid { grid-template-columns: 1fr; }
}

.stat-band {
  background: var(--color-section); border-radius: var(--radius-lg);
  padding: 48px; display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 32px;
}
.stat-band .stat-figure { font-size: 38px; font-weight: 500; margin-bottom: 6px; }
/* 14.5px to match the now-unified card-body size everywhere else, not
   the older 13.5px this had been left at before that size was raised. */
.stat-band .stat-label { color: color-mix(in srgb, var(--color-text) 70%, transparent); font-size: 14.5px; }
.stat-note { color: color-mix(in srgb, var(--color-text) 45%, transparent); font-size: 12px; margin-top: 14px; }

.process-step { border-top: 2px solid var(--color-accent); padding-top: 18px; padding-right: 20px; }

.about-hero-row { display: flex; gap: 32px; align-items: center; flex-wrap: wrap; }
.about-portrait {
  width: 220px; height: 220px; border-radius: 50%; object-fit: cover;
  border: 1px solid var(--color-neutral-800); flex-shrink: 0;
}
.about-positioning { font-size: 15px; color: var(--color-accent-300); font-weight: 500; margin: 4px 0 20px; }
.about-closer {
  font-size: 16px; line-height: 1.7; color: var(--color-text);
  border-top: 2px solid var(--color-accent); padding-top: 16px; margin-top: 24px;
}

/* — homepage founder teaser: a dark panel with a soft glow behind the
   portrait, condensed from the full About page bio — */
.about-teaser {
  display: flex; gap: 40px; align-items: center; justify-content: center; flex-wrap: wrap;
  background: var(--color-surface); border: 1px solid var(--color-neutral-800);
  border-radius: var(--radius-lg); padding: 48px;
  overflow: hidden; position: relative;
  max-width: 960px; margin: 0 auto;
}
.about-teaser-photo-col {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  flex-shrink: 0; position: relative; z-index: 1; gap: 4px;
}
.about-teaser-photo-col .eyebrow-plain { margin-bottom: 22px; }
.about-teaser-photo-col h2 { font-size: 26px; margin: 22px 0 4px; }
.about-teaser-photo { position: relative; }
.about-teaser-photo::before {
  content: ""; position: absolute; inset: -50px; z-index: 0;
  background: radial-gradient(circle, rgba(145, 132, 217, 0.3), transparent 70%);
}
.about-teaser-img {
  position: relative; z-index: 1; display: block;
  width: 300px; height: 300px; border-radius: 50%; object-fit: cover;
  border: 2px solid var(--color-accent-700);
  box-shadow: 0 0 0 6px rgba(145, 132, 217, 0.08), 0 20px 40px rgba(0, 0, 0, 0.45);
}
.about-teaser-text {
  flex: 1 1 420px; min-width: 280px; max-width: 540px;
  padding-left: 24px; position: relative; z-index: 1;
}
.about-teaser-role { font-weight: 600; color: var(--color-text); font-size: 15px; }
.about-teaser-text p { font-size: 15px; line-height: 1.65; margin: 0 0 14px; }
.about-teaser-text p:first-child { margin-top: 0; }
.about-teaser-tags { display: flex; flex-wrap: wrap; gap: 8px; margin: 20px 0 20px; }
.about-teaser-tags .tag { font-size: 11.5px; padding: 5px 12px; }
.about-teaser-link { color: var(--color-accent); font-size: 14px; text-decoration: none; font-weight: 500; }
@media (max-width: 640px) {
  .about-teaser { padding: 32px 24px; text-align: center; justify-content: center; }
  /* Centring suits the photo/name column above it, but the bio itself
     reads better left-aligned even stacked on mobile; the tags row
     underneath centres on its own via justify-content, not this. */
  .about-teaser-text { text-align: left; padding-left: 0; max-width: none; }
  .about-teaser-tags { justify-content: center; }
}

/* — About page: the portrait sits at the top, level with the bio text — */
.about-teaser-tall { align-items: flex-start; overflow: visible; }

/* — reusable "electrical circuit" pulse ring: a thin conic-gradient arc that
   continuously rotates around a card's border, size/aspect-independent so it
   works on any rounded-rect card regardless of its dimensions — */
@property --circuit-angle { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.circuit-border { position: relative; }
.circuit-border::after {
  content: ""; position: absolute; inset: -1.5px; border-radius: inherit;
  padding: 2px; pointer-events: none;
  background: conic-gradient(from var(--circuit-angle),
    transparent 0deg, transparent 290deg,
    rgba(210, 206, 253, 0.9) 316deg, var(--color-accent-300) 332deg, rgba(210, 206, 253, 0.9) 348deg,
    transparent 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  filter: drop-shadow(0 0 4px var(--color-accent)) drop-shadow(0 0 8px rgba(145, 132, 217, 0.6));
  animation: circuit-border-pulse 4s linear infinite;
}
@keyframes circuit-border-pulse { to { --circuit-angle: 360deg; } }
@media (prefers-reduced-motion: reduce) {
  .circuit-border::after { animation: none; }
}

/* — homepage "how it works": two steps side by side, the third spanning
   full width beneath, each card revealed once via the site's existing
   scroll-reveal (.card is already a reveal target), with a small
   continuous pulse on the numbered badge reusing .orbit-core's ring — */
.hiw-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.hiw-card-wide { grid-column: 1 / -1; max-width: calc(50% - 12px); margin: 0 auto; }
.hiw-card { text-align: center; padding: 40px 32px; min-height: 280px; justify-content: center; }
.hiw-card:hover { border-color: var(--color-accent); }
.hiw-badge {
  position: relative; width: 48px; height: 48px; border-radius: 50%;
  background: var(--color-accent); color: #161826;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; font-weight: 700; margin: 0 auto 20px;
}
.hiw-badge::before {
  content: ""; position: absolute; inset: -1px; border-radius: 50%;
  border: 1px solid var(--color-accent-300);
  animation: orbit-ping 2.6s cubic-bezier(0, 0.4, 0.6, 1) infinite;
}
.hiw-card .card-title { font-size: 20px; margin-bottom: 12px; }
.hiw-card .card-body { font-size: 14.5px; line-height: 1.65; }
@media (prefers-reduced-motion: reduce) {
  .hiw-badge::before { animation: none; }
}
@media (max-width: 640px) {
  .hiw-grid { grid-template-columns: 1fr; }
  .hiw-card-wide { grid-column: auto; max-width: none; }
}
@media (min-width: 641px) and (max-width: 1053px) {
  /* .hiw-grid's columns (two from 641px, one below that) are a fixed
     1fr, so a card simply grows to fill however much the column happens
     to be; at this width that's often 340px+ of mostly padding around a
     short card body. Excludes .hiw-card-wide (an odd card out, spanning
     both columns to sit centred under the row above, e.g. "Ongoing
     Support & Optimisation"): it carries the .hiw-card class too, and
     this rule's max-width would otherwise override its own, undoing
     that centring. */
  .hiw-card:not(.hiw-card-wide) { max-width: 300px; justify-self: center; }
  /* .hiw-card-wide's own max-width (calc(50% - 12px), sized to match the
     column width above it) only matches its siblings at full desktop
     width, where they aren't capped either; here the two siblings above
     are capped to 300px but the row width this calc() reads from keeps
     growing with the viewport, so the wide card grows past them instead
     of matching. A flat 300px cap undershoots the other way lower in
     this range (641-760px), where the grid's own columns haven't
     reached 300px yet and the siblings are still shrinking with it;
     mirroring their own formula (min of the 300px cap and an actual
     column's share of the row) keeps it matched at every width in
     between, not just the two ends. */
  .hiw-card-wide { max-width: min(300px, calc((100% - 24px) / 2)); }
  /* .hiw-card centres its whole badge+title+body stack as a group
     (.card's flex column + this class's own justify-content:center), so
     a card whose title happens to wrap to one line instead of two ends
     up with a shorter stack, centred lower in the card than a sibling's
     taller stack in the same row — visibly misaligning their badges.
     Pinning the stack to the top instead removes that dependency: every
     badge sits the same distance below the card's own top edge no
     matter how the title wraps, at the cost of uneven blank space at
     the bottom of shorter cards (the same trade already made in
     .book-call-info's own fix above). */
  .hiw-card { justify-content: flex-start; }
  /* Pinning the stack to the top (above) keeps every badge level, but a
     card whose title is naturally one line still starts its own body
     copy higher than a sibling whose title wraps to two – the same
     "text underneath starts level" problem the grid-auto-wide title
     reservation above already solves, just not applied to hiw-card's
     own title. Mirrors that rule here, scoped to this tier only so
     desktop (already fine) and phone keep their current rhythm. */
  .hiw-card .card-title {
    min-height: 2.24em; display: flex; align-items: center; justify-content: center;
  }
  .tablet-break { display: inline; }
  /* .card-title is itself a flex container (the two-line reservation
     rule above), which blockifies its direct children per the flex spec
     — including this forced <br>, which then lays out as its own
     block-level flex item instead of just breaking the text, scrambling
     the line count instead of fixing it. Dropping back to a plain block
     display for just these titles sidesteps that: the <br> behaves
     normally again, and since it now always produces exactly two lines
     there's nothing left for the flex reservation to even need to
     centre. */
  .card-title:has(.tablet-break) { display: block; white-space: nowrap; }
}

/* — "what we build" capability cards (How It Works page): icon + outcome
   line, distinct rhythm from the numbered .hiw-card stage grid on the same
   page, sharing only the reveal/circuit-border treatment — */
.capability-grid { grid-template-columns: repeat(6, 1fr); }
.capability-grid > .card { text-align: center; align-items: center; }
.capability-grid > .card:nth-child(1) { grid-column: 2 / span 2; }
.capability-grid > .card:nth-child(2) { grid-column: 4 / span 2; }
.capability-grid > .card:nth-child(3) { grid-column: 1 / span 2; }
.capability-grid > .card:nth-child(4) { grid-column: 3 / span 2; }
.capability-grid > .card:nth-child(5) { grid-column: 5 / span 2; }
@media (max-width: 900px) {
  .capability-grid { grid-template-columns: repeat(2, 1fr); }
  .capability-grid > .card:nth-child(n) { grid-column: auto; }
}
@media (max-width: 600px) {
  .capability-grid { grid-template-columns: 1fr; }
}
@media (min-width: 601px) and (max-width: 900px) {
  /* 5 cards in this fixed 2-column layout leaves the 5th ("Ongoing
     Optimisation") alone in column one instead of centred under the
     row above, the same lone-card problem as the auto-fit grids
     elsewhere, just via a different (fixed, not auto-fit) mechanism. */
  .capability-grid > .card:nth-child(5):last-child {
    grid-column: 1 / -1; justify-self: center; width: calc(50% - 12px);
  }
}
.capability-icon {
  width: 52px; height: 52px; border-radius: 12px; flex-shrink: 0;
  background: var(--color-accent-800); border: 1px solid var(--color-accent-700);
  color: var(--color-accent-300);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 18px;
  /* No-op in the flex cards that also use this class (pricing, grid-auto-
     wide), where centring already comes from the flex parent; needed in
     the capability-grid/audience-grid cards, now grid containers, whose
     default would otherwise place this fixed-width box at the start of
     its row instead of the middle. */
  justify-self: center;
}
.capability-outcome {
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--color-divider);
  font-size: 14.5px; color: var(--color-text);
}
.capability-outcome strong { color: var(--color-accent-300); }
/* Subgrid, same reasoning as the homepage proof cards: the body copy
   above this line runs 2-5 lines depending on width, so a fixed
   reservation would either undershoot at some widths or waste space at
   others. Subgridding icon/title/body/outcome into the parent's row
   tracks sizes each row to the tallest sibling actually sharing it,
   keeping the accent line level across a row at any width without a
   guessed value. The title's own min-height reservation (set elsewhere)
   stays in place as a fallback for browsers without subgrid support. */
/* align-items:center (below, and inline on .audience-grid's cards) was
   written for the old flex layout, where it governed horizontal centring
   on the cross axis; as a grid container it instead governs the
   block-axis (vertical) stretch of each row, so it was centring a short
   outcome line inside its now-taller shared track instead of stretching
   it to fill it, leaving an uneven gap above and below it that moved its
   visible starting line out of sync with a taller sibling's. That same
   switch also left the icon with no horizontal centring at all (grid's
   own default places a fixed-width item at the start of its row, not
   the middle) — restored below via the icon's own justify-self, since
   text-align:center still covers the title/body/outcome text itself.
   row-gap:0 clears the gap the subgrid otherwise inherits from the
   parent grid (24px, same as the proof cards above) on top of each
   row's own margin, which read as excessive, disconnected spacing
   compared to the tighter rhythm other cards on the site use. */
.capability-grid > .card { display: grid; grid-template-rows: subgrid; grid-row: span 4; align-items: stretch; row-gap: 0; }
/* audience-grid's cards carry an inline align-items:center (for the old
   flex layout), which otherwise wins over the external stretch above. */
.audience-grid > .card { display: grid; grid-template-rows: subgrid; grid-row: span 5; align-items: stretch !important; row-gap: 0; }

/* — About page: 4 audience segments, 2x2 — */
.audience-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; }
@media (max-width: 700px) { .audience-grid { grid-template-columns: 1fr; } }

/* — vertical numbered timeline (How It Works page, 4-stage process):
   chronological top-to-bottom, connected by a line, reusing .hiw-badge for
   the pulsing numbered circle instead of the grid-based .hiw-card layout — */
.timeline-step { display: flex; gap: 28px; padding-bottom: 40px; position: relative; }
.timeline-step:last-child { padding-bottom: 0; }
.timeline-connector { position: absolute; left: 23px; top: 48px; bottom: 0; width: 1px; background: var(--color-divider); }
.timeline-step h3 { font-size: 22px; margin: 0 0 10px; }
.timeline-step p { max-width: 600px; margin: 0; }

.timeline-layout { display: flex; gap: 56px; align-items: flex-start; max-width: 1100px; margin: 0 auto; }
.timeline-layout > .timeline-col { flex: 1 1 480px; min-width: 280px; }
.timeline-visual { flex: 1 1 320px; min-width: 260px; display: flex; justify-content: center; align-self: center; }
.timeline-visual canvas { width: 100%; max-width: 380px; aspect-ratio: 1; display: block; animation: globe-float 7s ease-in-out infinite; }
@keyframes globe-float {
  0%, 100% { transform: translateY(-12px); }
  50% { transform: translateY(12px); }
}
@media (max-width: 900px) {
  /* The 56px gap above is meant for two columns side by side; stacked,
     it reads as the globe floating disconnected below the steps. */
  .timeline-layout { flex-direction: column; gap: 24px; }
  .timeline-visual { max-width: 320px; margin: 0 auto; }
}
@media (max-width: 400px) {
  /* Stacked by the rule above, but the column's own 280px floor still
     forced it wider than very small phones. */
  .timeline-layout > .timeline-col { min-width: 0; }
}

.process-step .step-num { color: var(--color-accent-300); font-size: 12px; font-weight: 600; margin-bottom: 8px; }
.step-circle {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  border: 1px solid var(--color-accent); color: var(--color-accent-300);
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 600; margin-bottom: 12px;
}

.hr {
  height: 1px; border: 0; margin: var(--space-4) 0;
  background: linear-gradient(to right, transparent, var(--color-divider) 48px,
    var(--color-divider) calc(100% - 48px), transparent);
}

/* — floating stat chip, overlaid on a corner of a .panel — */
.floating-chip {
  position: absolute; top: -18px; right: 28px;
  display: flex; align-items: center; gap: 10px;
  background: linear-gradient(180deg, #2c2f3d 0%, #1c1e28 100%);
  border: 1px solid var(--color-neutral-800);
  border-radius: 14px; padding: 10px 16px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 12px 28px rgba(0, 0, 0, 0.5);
  transform: rotate(-2deg);
}
.floating-chip-icon {
  width: 30px; height: 30px; flex-shrink: 0; border-radius: 50%;
  background: color-mix(in srgb, var(--color-accent) 16%, transparent);
  color: var(--color-accent-300);
  display: flex; align-items: center; justify-content: center;
}
.floating-chip-value { font-size: 15px; font-weight: 600; color: var(--color-text); }
.floating-chip-label { font-size: 11px; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.floating-chip-static { position: static; transform: none; flex-shrink: 0; }
@media (max-width: 640px) {
  .floating-chip { position: static; transform: none; margin-bottom: 16px; }
}

/* — sticky stacking cards: each card sticks below the header as the next
   one scrolls up and covers it, like layered panels — */
.stack-wrap { display: flex; flex-direction: column; gap: 24px; max-width: 1020px; margin: 0 auto; }
.stack-card {
  position: sticky; top: 88px; z-index: 1;
  display: flex; align-items: center; justify-content: space-between; gap: 32px; flex-wrap: wrap;
  background: linear-gradient(160deg, var(--color-surface), #1a1c28);
  border: 1px solid var(--color-neutral-800);
  border-radius: var(--radius-lg);
  padding: 40px 44px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
  min-height: 220px;
}
.stack-card:nth-child(1) { z-index: 1; }
.stack-card:nth-child(2) { z-index: 2; }
.stack-card:nth-child(3) { z-index: 3; }
.stack-card:nth-child(4) { z-index: 4; }
@media (prefers-reduced-motion: reduce) {
  .stack-card { position: relative; top: auto; }
}
/* — stack-card visual: the card's custom illustration set in a glow panel,
   with a small floating status chip overlapping the bottom edge, so all
   three stay visually identical in structure and only the artwork/labels
   change per card — */
.section-problems .grid-auto { gap: 32px; }
.section-problems .card { text-align: center; padding: 36px 32px; }
/* No font-size here any more: this used to run larger (28px/16px) as its
   own "hero" treatment shared only with .stack-card-text, which read as
   inconsistent with every other card's title/body once those were
   unified to one size (20px/14.5px, the .card-title/.card-body
   defaults). Letting it inherit those instead keeps this section's
   cards the same size as every other card on the site. min-height stays
   in em so the two-line reservation keeps working at the font-size this
   now inherits at narrower tiers too. */
.section-problems .card-title { margin-bottom: 18px; min-height: 2.24em; display: flex; align-items: center; justify-content: center; }
/* The 2.24em (two-line) reservation above still comes up short wherever
   a title actually needs a third line (it happens at a few widths, this
   section's titles being that bit longer than most), so the shorter
   sibling in that row no longer reliably matches. Subgrid replaces it
   with the same approach used elsewhere on the site for titles whose
   natural line count swings too widely for one fixed reservation to
   cover: the title row sizes to whichever card in that row actually
   needs the extra line, and the body text below starts level either
   way. */
/* row-gap:0 for the same reason as the capability/audience cards above:
   without it, the subgrid also inherits this section's own 32px gap
   between its rows, on top of the title's own margin-bottom. */
.section-problems .grid-auto > .card { display: grid; grid-template-rows: subgrid; grid-row: span 2; align-items: stretch; row-gap: 0; }
/* The same "What's Actually Going Wrong." 3-card problem section repeats
   on every service and industry page as a plain .grid-auto (no wrapping
   .section-problems class there), each card icon+title+body rather than
   just title+body, so it never picked up either of the fixes above and
   kept the same misaligned-body-copy problem. Matched by the icon's
   presence rather than a dedicated class, since every page already
   shares this exact markup. Excludes .capability-grid: it's also a
   .grid-auto and its cards also contain a .capability-icon, but it has
   a 4th row (the outcome line) and its own span:4 rule above — this
   selector's extra :has() otherwise outranks that rule's specificity
   and would wrongly cut it back to 3. */
/* !important: these cards carry an inline align-items:center (for the
   old flex layout), which otherwise wins over the external stretch. */
.grid-auto:not(.capability-grid) > .card:has(.capability-icon) {
  display: grid; grid-template-rows: subgrid; grid-row: span 3; align-items: stretch !important; row-gap: 0;
}
.stack-card-text {
  text-align: left; flex: 0 1 400px; min-width: 240px;
  max-width: 400px; margin-left: 28px;
}
@media (max-width: 400px) {
  .stack-card-text { min-width: 0; margin-left: 0; }
}
/* Title is a deliberate exception to the site-wide 20px card-title size:
   this card is bigger than every other card (its own orbit diagram runs
   noticeably larger than a normal card's icon), and at the standard size
   the heading read as undersized against it. Body stays at the unified
   14.5px – only the heading needed the bump. */
.stack-card-text h3 { font-size: 24px; line-height: 1.25; margin: 0 0 20px; color: var(--color-accent-300); }
.stack-card-text .card-body { font-size: 14.5px; line-height: 1.65; margin: 0 0 32px; }
.stack-card-text .btn { font-size: 14px; padding: 12px 26px; margin: 8px 0 0; }
/* A second copy of the same "Learn More" link, placed after .stack-visual
   in the markup so it can sit below the diagram on mobile; hidden here
   since desktop keeps the original, inside the text column. */
.stack-card .stack-visual-link { display: none; }
/* Scoped to .stack-card rather than just .stack-card-text so the
   duplicate "Learn More" link placed after .stack-visual (which sits
   outside .stack-card-text) gets the same purple styling instead of
   falling back to .btn-outline's default dark one. */
.stack-card .btn-outline {
  background: var(--color-accent-800); border: 1px solid var(--color-accent-700); color: #f2f0f7;
}
.stack-card .btn-outline:hover { background: var(--color-accent-700); }
.stack-visual { position: relative; flex-shrink: 0; width: 380px; margin-right: 28px; }
.stack-visual-panel {
  background:
    radial-gradient(circle at 30% 20%, rgba(145, 132, 217, 0.28), transparent 65%),
    linear-gradient(160deg, #262838, #1a1c28);
  border: 1px solid var(--color-neutral-800); border-radius: var(--radius-lg);
  padding: 32px; min-height: 300px;
  display: flex; align-items: center; justify-content: center;
}
/* — orbit visual: an animated radial diagram replacing the static
   illustrations — a pulsing core, two counter-rotating rings, a bright
   pulse of light that travels around the outer ring (the actual flow of
   data through the system), and three status nodes that light up in
   sequence as the light passes them, built entirely from HTML/CSS so it
   stays sharp, on-brand, and consistent across all three cards — */
.orbit-visual { position: relative; width: 236px; height: 236px; flex-shrink: 0; }
.orbit-backdrop {
  position: absolute; inset: 0; border-radius: 50%;
  background: radial-gradient(circle, rgba(145, 132, 217, 0.16), transparent 72%);
}
.orbit-ring {
  position: absolute; top: 50%; left: 50%; border-radius: 50%;
  border: 1px dashed var(--color-accent-700);
}
.orbit-ring-outer { width: 200px; height: 200px; transform: translate(-50%, -50%); animation: orbit-spin 34s linear infinite; }
.orbit-ring-inner {
  width: 140px; height: 140px; transform: translate(-50%, -50%);
  border-style: solid; border-color: color-mix(in srgb, var(--color-accent-700) 60%, transparent);
  animation: orbit-spin-reverse 24s linear infinite;
}
@keyframes orbit-spin { to { transform: translate(-50%, -50%) rotate(360deg); } }
@keyframes orbit-spin-reverse { to { transform: translate(-50%, -50%) rotate(-360deg); } }
/* the flow light: an arc riding exactly on the outer ring's path (same
   200px circle), traced with a colored top border so only a short bright
   segment shows, then rotated continuously past each node in turn */
.orbit-flow {
  position: absolute; top: 50%; left: 50%; z-index: 1;
  width: 200px; height: 200px; border-radius: 50%;
  transform: translate(-50%, -50%);
  border: 3px solid transparent;
  border-top-color: var(--color-accent-300);
  filter: drop-shadow(0 0 3px var(--color-accent-300)) drop-shadow(0 0 9px var(--color-accent));
  animation: orbit-flow-spin 3.6s linear infinite;
}
@keyframes orbit-flow-spin { to { transform: translate(-50%, -50%) rotate(360deg); } }
.orbit-core {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 68px; height: 68px; border-radius: 50%; z-index: 2;
  background: linear-gradient(160deg, #3a3560, #211f38);
  border: 1px solid var(--color-accent-700);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-accent-300);
  box-shadow: 0 0 0 1px rgba(210, 206, 253, 0.08), 0 12px 24px rgba(0, 0, 0, 0.45);
}
.orbit-core::before {
  content: ""; position: absolute; inset: -1px; border-radius: 50%;
  border: 1px solid var(--color-accent-300);
  animation: orbit-ping 2.6s cubic-bezier(0, 0.4, 0.6, 1) infinite;
}
@keyframes orbit-ping {
  0% { transform: scale(1); opacity: 0.55; }
  100% { transform: scale(1.9); opacity: 0; }
}
.orbit-node {
  position: absolute; transform: translate(-50%, -50%);
  display: flex; align-items: center; gap: 6px;
  background: linear-gradient(180deg, #2c2f3d 0%, #1c1e28 100%);
  border: 1px solid var(--color-neutral-800);
  border-radius: 999px; padding: 6px 12px 6px 8px;
  font-size: 11.5px; font-weight: 600; color: var(--color-text);
  white-space: nowrap; box-shadow: 0 8px 18px rgba(0, 0, 0, 0.4);
  z-index: 3;
}
.orbit-node-dot {
  width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
  background: var(--color-accent-700);
  box-shadow: 0 0 0 0 rgba(210, 206, 253, 0.5);
  animation: orbit-node-pulse 3.6s ease-in-out infinite;
}
.orbit-node-1 { top: 18px; left: 118px; animation: orbit-node-float 3.6s ease-in-out infinite; }
.orbit-node-2 { top: 168px; left: 205px; animation: orbit-node-float 3.6s ease-in-out infinite; animation-delay: 1.2s; }
.orbit-node-3 { top: 168px; left: 31px; animation: orbit-node-float 3.6s ease-in-out infinite; animation-delay: 2.4s; }
.orbit-node-1 .orbit-node-dot { animation-delay: 0s; }
.orbit-node-2 .orbit-node-dot { animation-delay: 1.2s; }
.orbit-node-3 .orbit-node-dot { animation-delay: 2.4s; }
@keyframes orbit-node-pulse {
  0%, 100% { background: var(--color-accent-700); box-shadow: 0 0 0 0 rgba(210, 206, 253, 0); }
  15% { background: var(--color-accent-300); box-shadow: 0 0 0 5px rgba(210, 206, 253, 0.18); }
  35% { background: var(--color-accent-700); box-shadow: 0 0 0 0 rgba(210, 206, 253, 0); }
}
@keyframes orbit-node-float {
  0%, 100% { transform: translate(-50%, -50%); }
  50% { transform: translate(-50%, calc(-50% - 3px)); }
}
@media (max-width: 940px) {
  .stack-visual { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .orbit-flow, .orbit-ring-outer, .orbit-ring-inner, .orbit-core::before, .orbit-node-dot, .orbit-node { animation: none; }
}
.stack-visual .floating-chip {
  position: absolute; top: auto; bottom: 22px; left: -68px; right: auto; z-index: 4;
  transform: none;
  flex-direction: column; align-items: flex-start; gap: 6px;
  width: 108px; padding: 15px; border-radius: 16px;
}
.stack-visual .floating-chip-icon { width: 30px; height: 30px; }
.stack-visual .floating-chip-value { font-size: 15px; }
.stack-visual .floating-chip-label { font-size: 11.5px; }

/* — workflow banner: circuit-trace decoration + floating status cards
   around a centered headline, matching the template reference's
   "Who Says..." composition — */
.workflow-banner-inner {
  position: relative; overflow: hidden;
  padding: 80px 40px;
  text-align: center;
  min-height: 480px;
  display: flex; align-items: center; justify-content: center;
}
.workflow-mist {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background:
    radial-gradient(ellipse 280px 210px at 38% 44%, rgba(178, 155, 230, 0.26), rgba(124, 91, 179, 0.09) 55%, transparent 100%),
    radial-gradient(ellipse 280px 210px at 63% 55%, rgba(178, 155, 230, 0.26), rgba(124, 91, 179, 0.09) 55%, transparent 100%);
  mix-blend-mode: screen;
}
.workflow-banner-content { position: relative; z-index: 3; max-width: 560px; }
.workflow-banner-content h2 { font-size: 42px; margin-bottom: 14px; }
/* Matches every other section-intro paragraph's size (16px): this one
   had no font-size set at all, so it fell back to the 15px site default,
   a 1px mismatch against its own siblings elsewhere on the page. */
.workflow-banner-content p { font-size: 16px; }
.workflow-banner-content .btn { margin-top: 14px; }

.circuit-lines {
  position: absolute; width: 500px; height: 250px; z-index: 1; overflow: visible;
}
.circuit-lines-tl { top: 0; left: -280px; }
.circuit-lines-br { bottom: -14px; right: -280px; }
.circuit-groove-shadow {
  fill: none; stroke: rgba(0, 0, 0, 0.8); stroke-width: 3.5; stroke-linecap: round;
  transform: translate(-1px, -1px);
}
.circuit-groove-highlight {
  fill: none; stroke: rgba(255, 255, 255, 0.07); stroke-width: 1.5; stroke-linecap: round;
  transform: translate(1px, 1px);
}
.circuit-pulse {
  fill: none; stroke: var(--color-accent-300); stroke-width: 2; stroke-linecap: round;
  stroke-dasharray: 0.12 1; stroke-dashoffset: 1;
  filter: drop-shadow(0 0 3px var(--color-accent));
  animation: circuit-flow 1.7s linear infinite;
}
@keyframes circuit-flow {
  from { stroke-dashoffset: 1; }
  to { stroke-dashoffset: -0.12; }
}
@media (prefers-reduced-motion: reduce) {
  .circuit-pulse { animation: none; opacity: 0; }
}

.workflow-float {
  position: absolute; z-index: 1; overflow: hidden;
  background: linear-gradient(160deg, rgba(46, 42, 74, 0.5), rgba(24, 22, 38, 0.42));
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border: 1px solid rgba(210, 206, 253, 0.14);
  border-radius: 14px; padding: 18px 22px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 16px 36px rgba(0, 0, 0, 0.45),
    0 0 30px rgba(145, 132, 217, 0.14);
  font-size: 14px; text-align: left;
}
.workflow-float::before {
  content: ""; position: absolute; inset: -60% -30%; z-index: -1;
  background: linear-gradient(115deg,
    transparent 38%, rgba(255, 255, 255, 0.1) 47%,
    rgba(255, 255, 255, 0.18) 50%, rgba(255, 255, 255, 0.1) 53%, transparent 62%);
  transform: translateX(-55%);
  animation: wf-shine 6.5s ease-in-out infinite;
  pointer-events: none;
}
@keyframes wf-shine {
  0%, 100% { transform: translateX(-55%); }
  50% { transform: translateX(55%); }
}
@media (prefers-reduced-motion: reduce) {
  .workflow-float::before { animation: none; transform: translateX(0); }
}
.wf-left { top: 14%; left: 7%; min-height: 140px; width: 220px; text-align: center; }
.wf-left .wf-status { align-self: center; }
.wf-right {
  top: 7%; right: 6%; min-height: 190px; width: 230px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; text-align: center;
}
.wf-right-text { width: 100%; }
.wf-bottom {
  bottom: 1%; left: 3%; width: 380px; min-height: 175px;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  text-align: center;
}
.wf-bottom-right { bottom: 9%; right: 7%; width: 320px; }
.wf-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; padding: 6px 0; }
.wf-row + .wf-row { border-top: 1px solid var(--color-neutral-800); }
.wf-row-status { color: #7ee2a8; font-weight: 600; }
@media (max-width: 900px) {
  .workflow-float { display: none; }
}

.wf-status {
  display: inline-block; font-size: 12px; font-weight: 600; color: #7ee2a8;
  background: rgba(126, 226, 168, 0.12); padding: 3px 9px; border-radius: 6px; margin-bottom: 7px;
  align-self: flex-start;
}
.wf-title { font-weight: 600; color: var(--color-text); font-size: 15px; }
.wf-meta { font-size: 12.5px; color: color-mix(in srgb, var(--color-text) 55%, transparent); margin-top: 3px; }
.wf-badge {
  width: 42px; height: 42px; border-radius: 50%; background: var(--color-accent); color: #161826;
  display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 18px; flex-shrink: 0;
}

/* — workflow-banner card animations: content slides in/out on a loop once
   the section scrolls into view. .workflow-banner-inner joins the site's
   existing scroll-reveal targets purely to gain .is-visible at the right
   moment; its own generic reveal fade is cancelled below so only the
   cards' own choreography plays. Card 1 defaults to its first state
   sitting statically in place (a safe no-JS fallback); the others start
   from an off-stage position that only matters once animated. — */
.workflow-banner-inner.reveal { opacity: 1; transform: none; transition: none; }

/* card 1 (wf-left): three states relay through the card, one per 6s beat
   (an 18s lap for all three) — entering, holding and exiting at exactly
   the same milliseconds (900/4200/5100) as the bottom two cards, so
   every card turns over on the same shared clock */
.wf-left .rotator-state {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: center;
  opacity: 1; transform: translateX(420px);
  pointer-events: none;
}
.wf-left .rotator-state:first-child { transform: translateX(0); }
.workflow-banner-inner.is-visible .wf-left .rotator-state { animation: wf-relay-slow 18s ease-in-out infinite; }
.workflow-banner-inner.is-visible .wf-left .rotator-state:nth-child(1) { animation-delay: 0s; }
.workflow-banner-inner.is-visible .wf-left .rotator-state:nth-child(2) { animation-delay: 6s; }
.workflow-banner-inner.is-visible .wf-left .rotator-state:nth-child(3) { animation-delay: 12s; }
@keyframes wf-relay-slow {
  0%      { transform: translateX(-420px); }
  5%      { transform: translateX(0); }
  23.33%  { transform: translateX(0); }
  28.33%  { transform: translateX(420px); }
  100%    { transform: translateX(420px); }
}

/* card 2 (wf-right): badge and title redo their zoom-then-settle
   choreography once per 6s beat, settling at the 900ms mark — the same
   moment the bottom cards finish sliding in — then hold to 4200ms and
   exit by 5100ms, exactly matching cards 1, 3 and 4. Each status line
   below only starts sliding in once the badge has settled. */
.wf-right .wf-badge { transform: translateY(46px) scale(0.4); opacity: 0; }
.workflow-banner-inner.is-visible .wf-right .wf-badge {
  animation: wf-badge-cycle 6s cubic-bezier(0.22, 1, 0.36, 1) infinite;
}
@keyframes wf-badge-cycle {
  0%   { transform: translateY(46px) scale(0.4); opacity: 0; }
  7%   { transform: translateY(46px) scale(2.1); opacity: 1; }
  15%  { transform: translateY(0) scale(1); opacity: 1; }
  70%  { transform: translateY(0) scale(1); opacity: 1; }
  85%  { transform: translateY(10px) scale(0.6); opacity: 0; }
  100% { transform: translateY(46px) scale(0.4); opacity: 0; }
}
.wf-right .wf-title { opacity: 0; transform: translateY(22px); }
.workflow-banner-inner.is-visible .wf-right .wf-title {
  animation: wf-title-cycle 6s ease-in-out infinite;
}
@keyframes wf-title-cycle {
  0%   { opacity: 0; transform: translateY(22px); }
  5%   { opacity: 0; transform: translateY(22px); }
  15%  { opacity: 1; transform: translateY(0); }
  70%  { opacity: 1; transform: translateY(0); }
  85%  { opacity: 0; transform: translateY(-14px); }
  100% { opacity: 0; transform: translateY(22px); }
}
.wf-meta-rotator { position: relative; height: 17px; overflow: hidden; width: 100%; }
.wf-meta-rotator .wf-meta {
  position: absolute; inset: 0; margin: 0; transform: translateX(-420px);
}
.workflow-banner-inner.is-visible .wf-meta-rotator .wf-meta { animation: wf-meta-sync 18s ease-in-out infinite; }
.workflow-banner-inner.is-visible .wf-meta-rotator .wf-meta:nth-child(2) { animation-delay: 6s; }
.workflow-banner-inner.is-visible .wf-meta-rotator .wf-meta:nth-child(3) { animation-delay: 12s; }
@keyframes wf-meta-sync {
  0%      { transform: translateX(-420px); }
  5.17%   { transform: translateX(-420px); }
  6.67%   { transform: translateX(0); }
  23.33%  { transform: translateX(0); }
  28.33%  { transform: translateX(420px); }
  100%    { transform: translateX(420px); }
}

/* card 3 (wf-bottom): the pill flow and caption cross paths on a loop —
   pills travel left-to-right, the caption travels right-to-left */
.workflow-banner-inner.is-visible .wf-bottom .wf-flow { animation: wf-slide-lr 6s ease-in-out infinite; }
.workflow-banner-inner.is-visible .wf-bottom .wf-meta { animation: wf-slide-rl 6s ease-in-out infinite; }

/* card 4 (wf-bottom-right): the title dips down into view and retreats
   back up, while the two rows cross paths the same way as card 3 */
.workflow-banner-inner.is-visible .wf-bottom-right .wf-title { animation: wf-slide-td 6s ease-in-out infinite; }
.workflow-banner-inner.is-visible .wf-bottom-right .wf-row:nth-child(2) { animation: wf-slide-lr 6s ease-in-out infinite; }
.workflow-banner-inner.is-visible .wf-bottom-right .wf-row:nth-child(3) { animation: wf-slide-rl 6s ease-in-out infinite; }
@keyframes wf-slide-lr {
  0%   { transform: translateX(-420px); }
  15%  { transform: translateX(0); }
  70%  { transform: translateX(0); }
  85%  { transform: translateX(420px); }
  100% { transform: translateX(420px); }
}
@keyframes wf-slide-rl {
  0%   { transform: translateX(420px); }
  15%  { transform: translateX(0); }
  70%  { transform: translateX(0); }
  85%  { transform: translateX(-420px); }
  100% { transform: translateX(-420px); }
}
@keyframes wf-slide-td {
  0%   { transform: translateY(-50px); }
  15%  { transform: translateY(0); }
  70%  { transform: translateY(0); }
  85%  { transform: translateY(-50px); }
  100% { transform: translateY(-50px); }
}
@media (prefers-reduced-motion: reduce) {
  .wf-left .rotator-state,
  .wf-right .wf-badge,
  .wf-right .wf-title,
  .wf-meta-rotator .wf-meta,
  .wf-bottom .wf-flow,
  .wf-bottom .wf-meta,
  .wf-bottom-right .wf-title,
  .wf-bottom-right .wf-row {
    animation: none !important;
    transform: none !important;
    opacity: 1 !important;
  }
  .wf-left .rotator-state:not(:first-child) { display: none; }
  .wf-meta-rotator .wf-meta:not(:first-child) { display: none; }
}

.wf-flow { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 9px; flex-wrap: wrap; }
.wf-flow-node {
  font-size: 14.5px; font-weight: 600; color: var(--color-text);
  background: rgba(145, 132, 217, 0.14); border: 1px solid var(--color-accent-800);
  padding: 7px 15px; border-radius: 20px; white-space: nowrap;
}
.wf-flow-arrow { color: var(--color-accent-300); font-size: 15px; }

/* — logo marquee: real integration tools, scrolling strip — */
.marquee {
  overflow: hidden;
  padding: 24px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.marquee-track { display: flex; gap: 64px; width: max-content; animation: marquee-scroll 56s linear infinite; }
.marquee-track span {
  font-size: 18px; font-weight: 600; letter-spacing: 0.02em; white-space: nowrap;
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
}
@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

/* — buttons: neumorphic pills — soft embossed layered shadows, matching the
   template reference's signature button styling, in the brand purple — */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  font-family: var(--font-heading); font-weight: 600;
  font-size: 15px; line-height: 1.2; white-space: nowrap;
  border-radius: 999px; padding: 14px 28px;
  border: 1px solid transparent;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.btn-primary {
  color: #ffffff;
  background: linear-gradient(180deg, #9184d9 0%, #6b4fa3 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -3px 6px rgba(30, 20, 60, 0.3),
    0 10px 24px rgba(124, 91, 179, 0.4),
    0 2px 6px rgba(0, 0, 0, 0.3);
}
.btn-primary:hover {
  background: linear-gradient(180deg, #a08cd9 0%, #7c5bb3 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.3),
    inset 0 -3px 6px rgba(30, 20, 60, 0.3),
    0 14px 34px rgba(124, 91, 179, 0.55),
    0 2px 6px rgba(0, 0, 0, 0.35);
  transform: translateY(-1px);
}
.btn-secondary {
  color: var(--color-text); font-weight: 500;
  background: color-mix(in srgb, var(--color-surface) 70%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 4px 14px rgba(0, 0, 0, 0.3);
}
.btn-secondary:hover { box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 6px 18px rgba(0, 0, 0, 0.35); transform: translateY(-1px); }
.btn-outline {
  color: var(--color-text); font-weight: 500;
  background: linear-gradient(180deg, #2c2f3d 0%, #1c1e28 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    inset 0 -2px 4px rgba(0, 0, 0, 0.4),
    0 6px 16px rgba(0, 0, 0, 0.35);
}
.btn-outline:hover {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    inset 0 -2px 4px rgba(0, 0, 0, 0.4),
    0 8px 20px rgba(0, 0, 0, 0.4);
  transform: translateY(-1px);
}
/* — pricing tiles: a muted purple secondary button that fills to the
   primary style on hover — */
.btn-tier {
  color: var(--color-accent-300); font-weight: 600;
  background: linear-gradient(180deg, rgba(145, 132, 217, 0.22) 0%, rgba(107, 79, 163, 0.28) 100%);
  border-color: rgba(145, 132, 217, 0.45);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 6px 18px rgba(124, 91, 179, 0.22);
}
.btn-tier:hover {
  color: #ffffff; border-color: transparent;
  background: linear-gradient(180deg, #9184d9 0%, #6b4fa3 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 10px 24px rgba(124, 91, 179, 0.4);
  transform: translateY(-1px);
}

/* — cards used on Home for industries, on Case Studies for demos — */
.card {
  background: var(--color-surface); border: 1px solid var(--color-neutral-800);
  border-radius: var(--radius-lg); padding: 28px;
  display: flex; flex-direction: column;
}
.card-video-link { margin-top: auto; padding-top: 14px; align-self: flex-start; }
.video-trigger { cursor: pointer; background: none; font: inherit; }
.video-trigger:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }

.video-modal-overlay {
  position: fixed; inset: 0; background: rgba(10, 10, 16, 0.85); z-index: 200;
  display: none; align-items: center; justify-content: center; padding: 24px;
}
.video-modal-overlay.is-open { display: flex; }
.video-modal { position: relative; width: 100%; max-width: 900px; }
.video-modal-frame { width: 100%; aspect-ratio: 16 / 9; background: #000; border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-lg); }
.video-modal-frame iframe { width: 100%; height: 100%; border: 0; display: block; }
.video-modal-close {
  position: absolute; top: -42px; right: 0; background: none; border: none; color: var(--color-text);
  font-size: 28px; line-height: 1; cursor: pointer; padding: 4px 8px;
}
.video-modal-close:hover { color: var(--color-accent-300); }
.card-eyebrow { font-size: 12px; color: var(--color-accent-300); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 10px; }
/* 20px to match .hiw-card's own title size below: at desktop, every other
   tier (phone, tablet) already forces one shared size across every card
   type (see the "one size per heading tier, site-wide" media queries),
   so this was the one place a plain card's title was still smaller than
   the rest for no content-driven reason. */
/* Accent colour, matching what the "Manual Tasks" cards already set
   per-title via an inline style: now that .card-body is full brightness
   too, a plain var(--color-text) title (the h1-h6 default) was the same
   colour as its own body copy, with nothing to tell the two apart. */
.card-title { font-size: 20px; margin: 0 0 8px; color: var(--color-accent-300); }
/* — centred cards: reserve two lines for the title and centre it, so the
   text underneath starts level across a row at any screen width. Covers
   two ways a card ends up centred: an inline style (most grid-auto/
   grid-auto-wide cards) or .capability-grid's own CSS rule, which
   centres its cards without an inline style and so never matched the
   attribute selector alone. */
:where(.grid-auto, .grid-auto-wide) > :where(.card[style*="text-align:center"], .capability-grid > .card) > .card-title {
  min-height: 2.24em; display: flex; align-items: center; justify-content: center;
}
/* 14.5px to match .hiw-card's own body size below, same reasoning as the
   title above: phone and tablet already unify every card's body text to
   one size, and this was sitting noticeably below both that and the
   site's own 15px plain-paragraph text at desktop specifically.
   Muted colour: the settled site-wide rule is headlines and body
   paragraphs outside cards are full brightness, .card-title is accent
   (#d2cefd), and card body copy itself stays muted – this was briefly
   brightened to match the "Manual Tasks" cards, which made card titles
   and card body read as the same colour once titles also became accent,
   and is reverted here now that titles carry that contrast instead. */
.card-body { color: color-mix(in srgb, var(--color-text) 55%, transparent); font-size: 14.5px; line-height: 1.6; margin: 0; }

/* — pricing tiers: same idea as the centred-card title reservation above,
   for the plain divs these cards use instead of .card-title/.card-body.
   The eyebrow label ("Discovery Call & Systems Diagnostic" vs "Project
   Builds") and the optional note under the price ("Fee credited against
   a build...", absent on two of the four tiers) both vary in length, so
   without reserving their height the price and the bullet list below it
   start at different rows from one tier to the next. Reserved at the
   inherited body line-height (1.55), since these are plain divs, not
   headings. Tiers with no note keep an empty .pricing-tier-sub div in
   the markup so the reserved row is still there to collapse down to. */
.pricing-tier-label { min-height: 3.1em; display: flex; align-items: center; justify-content: center; }
.pricing-tier-sub { min-height: 3.1em; display: flex; align-items: center; justify-content: center; }

/* — tag / pill — */
.tag {
  display: inline-flex; align-items: center; font-size: 13px;
  letter-spacing: 0.02em; padding: 6px 14px;
  border-radius: 20px; text-decoration: none;
}
.tag-outline { border: 1px solid var(--color-accent); color: var(--color-accent-300); }
.tag-outline:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }

/* — navigation — */
.site-header {
  position: relative; z-index: 20;
  background: transparent;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 40px; height: 72px;
}
.nav-brand { color: var(--color-text); font-size: 18px; font-weight: 600; text-decoration: none; letter-spacing: -0.01em; flex-shrink: 0; display: flex; align-items: center; }
.nav-logo {
  height: 60px; width: auto; display: block;
  filter:
    drop-shadow(0 0 3px rgba(255, 255, 255, 1))
    drop-shadow(0 0 3px rgba(255, 255, 255, 1))
    drop-shadow(0 0 8px rgba(255, 255, 255, 1))
    drop-shadow(0 0 16px rgba(255, 255, 255, 0.95))
    drop-shadow(0 0 32px rgba(255, 255, 255, 0.8));
}
.nav-brand--baked .nav-logo { height: auto; width: 245px; filter: none; margin: -3px 0 -3px -34px; }
.nav-desktop { display: flex; align-items: center; justify-content: center; gap: 28px; flex: 1; margin-top: 30px; }
.nav-desktop a { color: var(--color-text); font-size: 14px; text-decoration: none; }
.nav-desktop a:hover, .nav-desktop a[aria-current="page"] { color: var(--color-accent-300); }
.nav-cta {
  flex-shrink: 0; margin-left: 28px;
  color: #ffffff; background: linear-gradient(180deg, #9184d9 0%, #6b4fa3 100%);
  border-color: transparent; font-weight: 600; padding: 9px 20px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.2),
    inset 0 -3px 6px rgba(30, 20, 60, 0.3),
    0 4px 16px rgba(124, 91, 179, 0.5);
}
.nav-cta:hover {
  background: linear-gradient(180deg, #a08cd9 0%, #7c5bb3 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.3),
    inset 0 -3px 6px rgba(30, 20, 60, 0.3),
    0 6px 26px rgba(145, 132, 217, 0.75);
  transform: translateY(-1px);
}

.nav-item { position: relative; }
.nav-item > span {
  color: var(--color-text); font-size: 14px; cursor: pointer;
  display: flex; align-items: center; gap: 4px; padding: 24px 0;
}
.nav-item:hover > span,
.nav-item:focus-within > span { color: var(--color-accent-300); }
.nav-item > span.is-active { color: var(--color-accent-300); }
.nav-item .caret { font-size: 10px; }
.nav-dropdown {
  position: absolute; top: 62px; left: 0;
  background: var(--color-surface); border: 1px solid var(--color-neutral-800);
  border-radius: var(--radius-md); padding: 8px; min-width: 280px;
  box-shadow: var(--shadow-md);
  display: flex; flex-direction: column;
  opacity: 0; visibility: hidden; transform: translateY(-6px); pointer-events: none;
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
}
.nav-item:hover .nav-dropdown,
.nav-item:focus-within .nav-dropdown {
  opacity: 1; visibility: visible; transform: translateY(0); pointer-events: auto;
}
.nav-dropdown a { color: var(--color-text); font-size: 13px; text-decoration: none; padding: 9px 10px; border-radius: 6px; }
.nav-dropdown a:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); color: var(--color-accent-300); }

.nav-toggle {
  display: none; background: var(--color-surface); border: 1px solid var(--color-neutral-800);
  border-radius: var(--radius-md); width: 40px; height: 40px;
  flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  cursor: pointer;
}
.nav-toggle span { width: 18px; height: 1.5px; background: var(--color-text); }

.nav-mobile {
  display: flex; flex-direction: column; padding: 0 24px; gap: 2px;
  /* A solid surface colour (not the page background) plus a shadow, so the
     open menu reads as its own panel rather than blending into whatever
     is behind it, including the homepage's glowing hero backdrop. */
  background: var(--color-surface); border-bottom: 0 solid var(--color-divider);
  box-shadow: 0 16px 32px rgba(0, 0, 0, 0.45);
  /* .site-header is position:relative with z-index:20, which lifts its
     own contents (including the logo's glow, which paints outside the
     logo's box via a CSS filter) onto a stacking layer above ordinary
     content. Without its own higher z-index, this menu sits below that
     layer despite coming later in the markup, so the glow bled over it. */
  position: relative; z-index: 21;
  max-height: 0; overflow: hidden; opacity: 0;
  transition: max-height 0.3s ease, opacity 0.25s ease, padding 0.3s ease;
}
/* Without this, flex shrinks the toggles/panels/links to fit the open
   menu's capped height instead of letting the menu itself scroll. */
.nav-mobile > * { flex-shrink: 0; }
.nav-mobile.is-open {
  max-height: min(560px, calc(100vh - 88px)); overflow-y: auto;
  opacity: 1; padding: 16px 24px; border-bottom-width: 1px;
}
.nav-mobile .group-label {
  color: color-mix(in srgb, var(--color-text) 55%, transparent); font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.08em; margin: 10px 0 4px;
}
.nav-mobile a { color: var(--color-text); font-size: 14px; text-decoration: none; padding: 8px 0; }
.nav-mobile .btn { text-align: center; margin-top: 12px; }

/* — mobile nav groups: Services/Industries collapse behind a toggle so the
   open menu isn't one long scroll of 20-odd links — */
.nav-mobile-toggle {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  background: transparent; border: 0; padding: 11px 0; margin: 0; cursor: pointer;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
  font: inherit; font-size: 13px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
}
.nav-mobile-toggle:first-child { padding-top: 2px; }
.nav-mobile-chevron { flex-shrink: 0; transition: transform 0.2s ease; }
.nav-mobile-toggle[aria-expanded="true"] .nav-mobile-chevron { transform: rotate(180deg); }
.nav-mobile-panel {
  display: flex; flex-direction: column; max-height: 0; overflow: hidden;
  transition: max-height 0.25s ease;
}
.nav-mobile-panel.is-open { max-height: 600px; }
.nav-mobile-panel a { padding: 7px 0 7px 6px; font-size: 13.5px; }

@media (max-width: 900px) {
  html, body { overflow-x: clip; }
}

@media (max-width: 980px) {
  .nav-desktop { display: none; }
  .nav-toggle { display: flex; }
}

/* — footer — */
.site-footer { padding: 56px 40px 28px; }
.footer-grid { display: flex; flex-wrap: wrap; gap: 48px; max-width: var(--max-width); margin: 0 auto 40px; }
.footer-col { flex: 1 1 200px; min-width: 200px; }
.footer-col.wide { flex-basis: 220px; }
.footer-brand { font-size: 17px; font-weight: 600; margin-bottom: 28px; }
.footer-logo { display: block; height: auto; width: 170px; margin: -6px 0 -4px -8px; }
.footer-desc { font-size: 13px; color: color-mix(in srgb, var(--color-text) 55%, transparent); line-height: 1.6; max-width: 260px; }
.footer-heading {
  font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em;
  color: color-mix(in srgb, var(--color-text) 55%, transparent); margin-bottom: 14px;
}
.footer-links { display: flex; flex-direction: column; gap: 9px; }
.footer-links a { color: var(--color-text); font-size: 13px; text-decoration: none; }
.footer-links a:hover { color: var(--color-accent-300); }

@media (max-width: 980px) {
  /* Three link columns sit two-up instead of one long stacked list; the
     brand column keeps the full row to itself. Below 980px because that's
     also where the header switches to the hamburger menu, and the footer
     has the same "flex-wrap leaves uneven gaps" problem at tablet widths
     as it did on phones. */
  .footer-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 30px 20px; }
  .footer-col.wide { grid-column: 1 / -1; }
  .footer-col { min-width: 0; }
  .footer-links { gap: 8px; }
  .footer-links a { font-size: 12.5px; }
}
.footer-bottom {
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between;
  max-width: var(--max-width); margin: 20px auto 0; font-size: 12px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.footer-bottom-links { display: flex; gap: 20px; }
.footer-bottom-links a { color: color-mix(in srgb, var(--color-text) 55%, transparent); text-decoration: none; }
.footer-bottom-links a:hover { color: var(--color-accent-300); }
.footer-bottom-legal { display: flex; flex-direction: column; gap: 4px; }
.footer-reg { font-size: 11px; color: color-mix(in srgb, var(--color-text) 40%, transparent); }
.footer-social { display: flex; gap: 10px; margin-top: 16px; }
.footer-social a {
  width: 30px; height: 30px; border-radius: 50%; border: 1px solid var(--color-neutral-800);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600; color: color-mix(in srgb, var(--color-text) 65%, transparent);
  text-decoration: none; transition: border-color 0.15s, color 0.15s;
}
.footer-social a:hover { border-color: var(--color-accent); color: var(--color-accent-300); }

/* — CTA band — */
.cta-section {
  background: var(--color-surface); border: 1px solid var(--color-neutral-800);
  border-radius: var(--radius-lg); padding: 56px 48px;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 28px;
}
.cta-section h2 { font-size: 28px; margin: 0 0 10px; }
.cta-section p { color: color-mix(in srgb, var(--color-text) 55%, transparent); font-size: 15px; margin: 0; max-width: 560px; }
/* The text block (h2+p) is a bare, unconstrained flex item, so how much
   room it takes before the button wraps onto its own row (and, once
   alone there, lands at the start instead of staying right-aligned)
   depended on how long that particular page's heading happened to be.
   A fixed basis/cap makes every page's CTA wrap at the same width,
   regardless of its own copy length. */
.cta-section:not(.cta-section-centered) > div { flex: 1 1 420px; max-width: 560px; }
.cta-section-centered {
  flex-direction: column; justify-content: center; text-align: center;
}
.cta-section-centered > div { display: flex; flex-direction: column; align-items: center; }
.cta-section-centered h2 { font-size: 32px; }
.cta-section-centered p { max-width: 520px; }
.cta-section-note {
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
  font-size: 13.5px; line-height: 1.6; margin: 4px 0 0;
}

/* — FAQ accordion, built on native <details> — no JS needed — */
.faq-list { display: flex; flex-direction: column; }
.faq-item { border-top: 1px solid var(--color-divider); }
.faq-item summary {
  list-style: none; cursor: pointer; padding: 20px 0;
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  font-size: 16px; font-weight: 500; color: var(--color-text);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary .plus { color: var(--color-accent); font-size: 18px; flex-shrink: 0; transition: transform 0.15s ease; }
.faq-item[open] summary .plus { transform: rotate(45deg); }
.faq-item p { margin: 0 0 22px; color: color-mix(in srgb, var(--color-text) 55%, transparent); font-size: 14.5px; line-height: 1.65; max-width: 720px; }

/* — forms — */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.field label { font-size: 13px; color: color-mix(in srgb, var(--color-text) 70%, transparent); }
.input {
  width: 100%; min-height: 42px; padding: 10px 12px; font: inherit; font-size: 14px;
  color: var(--color-text); caret-color: var(--color-accent);
  background: var(--color-surface); border: 1px solid var(--color-neutral-800);
  border-radius: var(--radius-md);
}
.input:hover { border-color: var(--color-neutral-600); }
.input:focus-visible { border-color: var(--color-accent); }
.form-status { font-size: 13.5px; margin: 10px 0 0; min-height: 1.2em; }
.form-status-success { color: var(--color-accent-300); }
.form-status-error { color: #e5484d; }
textarea.input { min-height: 130px; resize: vertical; }

/* — tables (pricing / comparisons) — */
.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th { text-align: left; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-neutral-500); padding: var(--space-3); border-bottom: 1px solid var(--color-divider); }
.table td { padding: var(--space-3); border-bottom: 1px solid var(--color-divider); }

@media (max-width: 640px) {
  /* — one size per heading tier, site-wide —
     Desktop intentionally varies heading sizes by context (a 42px section
     header vs. a 28px CTA header, say); at mobile width that hierarchy
     reads as "some headings are just randomly bigger than others", so
     every H1 becomes one size, every H2 another, and every H3 (including
     .card-title, which isn't always literally an h3 tag) a third. Most of
     these carry an inline font-size or their own class-based override, so
     plain h1/h2/h3 rules can't reach them; the affected selectors are
     listed explicitly instead. */
  h1,
  h1[style*="font-size:38px"],
  h1[style*="font-size:34px"],
  .section-hero h1 { font-size: 30px !important; }

  h2,
  h2[style*="font-size:42px"],
  h2[style*="font-size:22px"],
  h2[style*="font-size:20px"],
  .cta-section h2, .cta-section-centered h2,
  .about-teaser-photo-col h2 { font-size: 24px !important; }

  h3, .card-title,
  .proof-card .card-title,
  .hiw-card .card-title,
  .timeline-step h3,
  .section-problems .card-title,
  .stack-card-text h3 { font-size: 19px !important; }
  /* — one size for supporting/body copy, site-wide — */
  .card-body,
  .proof-card .card-body,
  .hiw-card .card-body,
  .section-problems .card-body,
  .stack-card-text .card-body,
  .faq-item p,
  .section-hero p:not(.text-muted),
  .section-narrow > h2 + p,
  article p { font-size: 14px !important; }

  .section, .section-hero { padding-left: 28px; padding-right: 28px; }
  /* Closes the gap above the heading in every section, the same issue as
     the hero: 64px (40px here) is sized for the desktop heading, and
     reads as empty space above the smaller mobile one. */
  .section { padding-top: 40px; padding-bottom: 40px; }
  /* Bottom padding was still the 80px desktop value, which stacked with
     the next section's own 40px top padding (see .section above) into a
     120px gap before the next heading, on every page. */
  .section-hero { padding-top: 48px; padding-bottom: 40px; }
  .site-header { padding: 0 20px; }
  .cta-section { padding: 36px 28px; }

  /* The stat band's big figures ("19 years", "16") were sized to stand
     out from body text; at 38px they're now larger than the page's own
     H1 (30px), which reads as broken rather than emphasised. */
  .stat-band .stat-figure { font-size: 26px; }
  .stat-band .stat-label { font-size: 14px; }

  /* Narrow-measure intro statements (e.g. "Automation Built for Scrutiny.")
     read as left-aligned body text at desktop width; centred, they read as
     a short statement instead, which suits a single mobile column. */
  .section-narrow > h2:has(+ p) { text-align: center; }
  .section-narrow > h2 + p { text-align: center; margin-left: auto; margin-right: auto; }

  /* About's "Why Automation?" block has an eyebrow, a second paragraph
     and a closing link that the generic h2+p rule above doesn't reach,
     leaving the heading and first paragraph centred but the rest left,
     a mix rather than a deliberate choice either way. */
  .section-why-automation { text-align: center; }
  .tool-agnostic-tags { justify-content: center; }

  /* Privacy and Terms are reading pages, not statement blocks: this
     overrides .section-narrow > h2 + p above, which was catching every
     paragraph straight after a heading and centring it, alongside the
     rest of the page staying left. */
  .section-legal > h2 + p { text-align: left; margin-left: 0; margin-right: 0; }

  /* "Systems That Talk To Each Other" cards: centre the text column, and
     bring back the orbit diagrams that .stack-visual hides below 940px
     (that breakpoint predates this pass and was sized for a tablet-width
     squeeze, not a phone). The diagram itself is a fixed 236px, so the
     panel around it just needs to stop being forced to 380px wide. */
  .stack-card-text { text-align: center; margin-left: 0; }
  /* Swap which copy of "Learn More" shows: the one after the diagram
     instead of the one directly under the paragraph, so the card reads
     heading, text, diagram, button instead of button, then diagram. */
  .stack-card-text > .btn { display: none; }
  .stack-card .stack-visual-link { display: inline-flex; margin: 16px auto 0; }
  .stack-visual {
    display: flex !important; width: auto; max-width: 100%;
    /* .stack-card's own 32px flex gap already separates this from the
       text above it; this extra top margin was stacking on top of that. */
    margin: 0 auto; justify-content: center;
  }
  /* The diagram itself (rings, core, the three node labels) is one fixed
     236px block with every child positioned in hand-tuned pixels, so it's
     scaled as a whole rather than resized property by property. The
     negative margin collapses the layout space transform doesn't shrink,
     so the now-smaller diagram doesn't leave a ring of empty padding. */
  .orbit-visual { transform: scale(0.66); margin: -40px; }
  .stack-visual-panel { padding: 16px; min-height: 190px; }
  /* The three node labels sit top-centre, bottom-left and bottom-right of
     the diagram (see .orbit-node-1/2/3 above), so top-right is the only
     corner this chip can sit in without landing on one of them; shrunk
     and pulled half outside the panel's corner so it doesn't crowd the
     also-much-smaller diagram underneath it. */
  .stack-visual .floating-chip {
    left: auto; right: -44px; top: -18px; bottom: auto;
    width: 74px; padding: 9px; gap: 3px;
  }
  .stack-visual .floating-chip-icon { width: 20px; height: 20px; }
  .stack-visual .floating-chip-value { font-size: 12px; }
  .stack-visual .floating-chip-label { font-size: 9.5px; }

  /* .cta-section-centered's flex column uses align-items: center, which
     sizes its heading/paragraph to their own content (fit-content) rather
     than the available width. Combined with their fixed max-width, that
     can render wider than the screen instead of wrapping to fit it. */
  .cta-section-centered > div,
  .cta-section-centered h2, .cta-section-centered p { max-width: 100%; }
  /* Long button labels (e.g. "Book Your Free Discovery Call") don't fit
     on one line at this width; .btn is nowrap by design everywhere else,
     so this only relaxes it inside a CTA block. */
  .cta-section .btn { max-width: 100%; white-space: normal; text-align: center; }

}

/* These two narrow-phone breakpoints come after the ≤640px block above on
   purpose: .site-header's padding is set at both widths with the same
   specificity, and the one later in the file wins whenever both apply. */
@media (max-width: 400px) {
  /* .grid-auto/.grid-auto-wide's minmax() column floor (260/280px) is
     wider than the available content width below ~400px, which was
     forcing the single column onto a track wider than the screen instead
     of shrinking to fit it. Untouched above this width, where auto-fit's
     normal column count is unaffected. */
  .grid-auto, .grid-auto-wide { grid-template-columns: 1fr; }
  /* Case Studies' "Any Industry" grid sets its own minmax() inline, which
     a class selector can't reach. */
  [style*="minmax(300px"] { grid-template-columns: 1fr !important; }
  /* Contact page's two flex columns set their own min-width inline. */
  [style*="min-width:280px"] { min-width: 0 !important; }
}

@media (max-width: 480px) {
  .site-header { padding-left: 16px; padding-right: 16px; }
  /* The header's own "Book a Call" pill is redundant with the hamburger
     menu (which has its own, matching button) and was crowding the logo
     against the edge, so it's dropped at this width. */
  .nav-cta { display: none; }
  /* max-width: none overrides the site-wide img{max-width:100%} reset,
     which otherwise fights the explicit width here and renders the logo
     smaller than specified. */
  .nav-brand--baked .nav-logo { width: 190px; max-width: none; margin-left: -12px; }
  .nav-logo { margin-left: 6px; }
}

@media (max-width: 360px) {
  .nav-brand--baked .nav-logo { width: 165px; max-width: none; margin-left: -10px; }
  .nav-logo { margin-left: 8px; }
}

@media (max-width: 760px) {
  /* The floating status tiles that make this banner legible are already
     hidden below 900px (see .workflow-float), leaving only a headline
     over decorative lines. Hiding the section avoids showing a section
     that no longer demonstrates anything at this width. */
  .workflow-banner-section { display: none; }
}

/* — tablet range (641px–980px): the same boundary the header already uses
   to switch to the hamburger menu. Phones get the aggressive treatment
   above; a tablet has more room, so these are lighter versions of the
   same fixes rather than a copy of the phone block. Kept as its own
   range (not just widening max-width:640px) so none of the phone-tuned
   rules above have to be re-verified. — */
@media (min-width: 641px) and (max-width: 1053px) {
  /* The header's own pill is redundant with the hamburger menu's own
     Book a Call button, same reasoning as the phone-width fix above. */
  .nav-cta { display: none; }

  /* One size per heading tier, as above, but a step up from the phone
     sizes since there's more width to use. */
  h1,
  h1[style*="font-size:38px"],
  h1[style*="font-size:34px"],
  .section-hero h1 { font-size: 36px !important; }

  h2,
  h2[style*="font-size:42px"],
  h2[style*="font-size:22px"],
  h2[style*="font-size:20px"],
  .cta-section h2, .cta-section-centered h2,
  .about-teaser-photo-col h2 { font-size: 28px !important; }

  h3, .card-title,
  .proof-card .card-title,
  .hiw-card .card-title,
  .timeline-step h3,
  .section-problems .card-title { font-size: 20px !important; }
  /* Exception, same reasoning as the desktop rule: this card's own
     diagram runs bigger than a normal card's icon, so its heading stays
     a step above the rest instead of dropping to the shared 20px. Only
     at this tier and desktop, where the diagram is actually shown full
     size — phone's version of this card hides it, so there's no "small
     heading next to a big visual" problem there to fix. */
  .stack-card-text h3 { font-size: 24px !important; }

  .card-body,
  .proof-card .card-body,
  .hiw-card .card-body,
  .section-problems .card-body,
  .stack-card-text .card-body,
  .faq-item p,
  .section-hero p:not(.text-muted),
  .section-narrow > h2 + p,
  article p { font-size: 15px !important; }

  /* The stat band's big figures ("Fixed price", "Full audit trail,
     documented") were never reduced at this width, only at phone width;
     38px reads too large next to the rest of the now-reduced type. */
  .stat-band .stat-figure { font-size: 30px; }
  .stat-band > div { text-align: center; }

  /* "Systems That Talk To Each Other": the diagrams are hidden below
     940px (see .stack-visual above), which also covers most of this
     range. There's enough room at tablet width to show them at their
     original size, rather than the shrunk phone treatment. */
  .stack-visual { display: flex !important; }

  /* Same gap-above-every-heading problem as phone width, a step lighter
     since there's more room: 64/96px top padding sized for the desktop
     heading leaves visible dead space above a tablet-sized one. */
  .section { padding-top: 48px; padding-bottom: 48px; }
  .section-hero { padding-top: 56px; padding-bottom: 48px; }
  /* Privacy/Terms and the FAQ page's last two sections all set their own
     larger inline padding (80-96px, more breathing room around a long
     reading page than the 64px .section default), which an inline style
     wins over the plain .section reduction above — so at this tier they
     were left at their full desktop size instead of easing back with
     everything else, reading as excess space above the heading and
     above the footer. */
  .section-legal { padding-top: 64px !important; padding-bottom: 64px !important; }
  .faq-body-section { padding-bottom: 64px !important; }
  .faq-cta-section { padding-bottom: 56px !important; }
}

/* The stacking cards' two columns (400px text + 380px diagram + gaps)
   need roughly 1050px of content width to sit side by side; below that
   they wrap, same as phone, but this was never actually handled between
   641-1050px: the diagram was just hidden, and once shown again (above)
   it fell back to the untouched desktop rules, which don't centre a
   wrapped item or account for a narrower wrapped column. This used to be
   split into two ranges (641-980px for nav/typography above, 641-1053px
   here for the diagram), leaving a 981-1053px gap where every card's
   layout was still tablet-narrow but its heading and body text had
   already jumped back up to full desktop size — cramped-looking text
   that was also visibly a different size than the exact same card one
   pixel narrower. The block above now reaches 1053px too, so there's no
   longer a width where the two disagree. */
@media (min-width: 641px) and (max-width: 1053px) {
  /* Text stays left-aligned with its button in place (as at desktop);
     shrinking the diagram instead, the same way phone width does, keeps
     both columns side by side rather than needing to stack them. With
     flex-wrap on, the row wraps rather than shrinking text below its
     400px flex-basis, so that basis needs reducing too: at this width,
     the full 400px text column plus even a shrunk diagram doesn't fit a
     single line, and wrapping is tried before shrinking either one. */
  .stack-card-text { flex-basis: 220px; min-width: 200px; }
  .stack-visual { width: auto; }
  .orbit-visual { transform: scale(0.75); margin: -29.5px; }
  .stack-visual-panel { padding: 20px; min-height: 217px; }
  /* Pulled in from the full desktop -68px bleed, which at this width
     would reach back far enough to overlap the text column instead of
     just the card's own edge; -24px wasn't far enough the other way and
     landed on the ring itself (its own left edge sits ~34px in from the
     panel/visual's edge at this scale), so it needs clearing by more
     than that, not less. */
  .stack-visual .floating-chip {
    left: -45px; right: auto; bottom: -45px; top: auto;
    width: 92px; padding: 12px; gap: 5px;
  }
  /* Now deliberately overlaps all three cards' diagrams at the bottom
     corner (see the shared rule above), so the old per-card nudge that
     kept the chip clear of "Approved" (the longest of the three
     orbit-node labels it now overlaps) no longer applies — covering
     part of that label is the same trade the other two cards already
     make covering theirs. */
  .stack-visual .floating-chip-icon { width: 24px; height: 24px; }
  .stack-visual .floating-chip-value { font-size: 13px; }
  .stack-visual .floating-chip-label { font-size: 10px; }

  /* top:88px holds each card 88px below the viewport top while it's
     stuck; the site header isn't itself sticky, so that's just picked
     for breathing room, not to clear anything fixed in place. At a
     short landscape height, 88px plus the card's own height (up to
     ~330px here) can run past the bottom of the screen before the next
     card's turn to stack, cutting the current one off mid-card instead
     of showing its full bottom edge first. A smaller offset leaves more
     of the screen's height for the card itself. */
  .stack-card { top: 24px; }
}

/* Book a Call: the two-column hero (text, then Calendly) wraps below
   ~940px, leaving the text column at its 340px cap with a wide empty gap
   beside it, and the calendar stretching to claim the rest. Centring the
   text as its own full-width block above a width-capped calendar reads
   better than a narrow column floating next to a very wide one. The
   checklist sits in its own centred 2x2 grid, each tick centred within
   its own cell so the block as a whole reads centred on the page. */
@media (min-width: 641px) and (max-width: 1040px) {
  .book-call-info {
    /* The element's own inline max-width:340px (its desktop column cap)
       otherwise wins over this regardless of specificity. */
    flex: 1 1 100%; max-width: 620px !important; margin: 0 auto; text-align: center;
  }
  /* A single centred column of ticks reads as a ragged, off-centre list;
     a 2x2 grid instead gives it a shape that sits properly centred as
     a block, each tick its own cell rather than one long stack. The
     inline style sets flex directly, so display needs !important here. */
  .book-call-checks {
    display: grid !important; grid-template-columns: 1fr 1fr; gap: 10px 24px;
    width: 100%; max-width: 480px; margin: 4px auto 0; text-align: center;
  }
  .book-call-panel { flex: 1 1 100%; max-width: 600px; margin: 0 auto; }
}

/* "Manual Tasks Are Costing You More Than Time.": the 3-card row wraps to
   two columns from 641px up, leaving the third card alone in column one
   instead of centred under the row above; capped at 923px, just under
   where this particular grid (32px gap, 260px card floor) naturally
   reaches three columns and the fix is no longer needed. */
@media (min-width: 641px) and (max-width: 938px) {
  .section-problems .grid-auto > .card:nth-child(3):last-child {
    grid-column: 1 / -1; justify-self: center; width: calc(50% - 16px);
  }
}

/* Same fix, generic .grid-auto (24px gap, 260px floor): About's "The
   Approach" and Healthcare's "What's Actually Going Wrong", both 3-card
   rows. Reaches three columns a little earlier (924px) than the 32px-gap
   version above. */
@media (min-width: 641px) and (max-width: 922px) {
  .grid-auto > .card:nth-child(3):last-child {
    grid-column: 1 / -1; justify-self: center; width: calc(50% - 12px);
  }
}

/* Same again, .grid-auto-wide (20px gap, 280px floor): Case Studies'
   Professional Services and Healthcare rows, both 3 cards. Reaches three
   columns later (980px) since each card has more room to claim. */
@media (min-width: 641px) and (max-width: 975px) {
  .grid-auto-wide > .card:nth-child(3):last-child {
    grid-column: 1 / -1; justify-self: center; width: calc(50% - 10px);
  }
}

/* Stat bands with 3 stats (every service and industry page bar the
   homepage, which has 4): same lone-last-card problem, 200px floor,
   32px gap, reaching two columns from 600px and three from 865px. */
@media (min-width: 600px) and (max-width: 863px) {
  .stat-band > div:nth-child(3):last-child {
    grid-column: 1 / -1; justify-self: center; width: calc(50% - 16px);
  }
}
