/* =====================================================================
   partners.sk — Homepage Mockup v2.1
   Path C: dark navy editorial baseline + one yellow moment (founder quote).
   Brand font: Univia Pro (from rollup banner), used for the logo wordmark.
   Display font: Montserrat (Black / ExtraBold / Bold). Body/labels: Inter.
   ===================================================================== */

/* Univia Pro Medium — brand font from the rollup banner. Used exclusively
   for the `partners.sk` wordmark in nav + footer, matching the print
   brand reference. Display/body typography stays Montserrat + Inter. */
@font-face {
  font-family: 'Univia Pro';
  src: url('../assets/fonts/univia-pro/UniviaPro-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* Default page zoom set to 110%. Martin reads the page comfortably at
   browser zoom 1.1× — bumping the baseline so every visitor lands on
   that scale without touching their browser. CSS `zoom` is non-standard
   but supported in all evergreen browsers (Chrome, Edge, Safari since
   forever; Firefox 126+, May 2024). Viewport units (vw, vh) and media
   queries still evaluate against the real browser width, so wide-viewport
   overrides at 1024 / 1100 / 1600 / 2400 trigger at the same physical
   widths as before — only the rendered content scales up. */
/* Page zoom — pumped 10% on desktop only. Mobile (touch) stays at
   100% because `html { zoom }` shifts sticky elements relative to
   iOS Safari's system chrome / safe-area inset (which are reported
   in unscaled CSS px), creating a visible gap between the iPhone
   status bar and the sticky nav. The (hover: hover) + (pointer: fine)
   query targets devices with a mouse — desktops/laptops — and excludes
   touchscreens. */
@media (hover: hover) and (pointer: fine) {
  html { zoom: 1.1; }
}

:root {
  /* Background scale */
  --navy-950: #0F1823;
  --navy-900: #1C2B3F;
  --navy-850: #1F2D43;  /* mid-tone for section variance */
  --navy-800: #263349;
  --navy-700: #334055;
  --navy-600: #475366;

  /* Text scale */
  --ink-50:   #F7F8FA;
  --ink-100:  #E5E9EF;
  --ink-200:  #CED4DE;
  --ink-400:  #8A93A3;
  --ink-600:  #5A6474;

  /* Signal — Brand Yellow (exact rollup banner colors) */
  --signal-500: #FEE566;   /* rollup creamy pastel yellow */
  --signal-600: #F5D23E;   /* darker hover */
  --signal-300: #FFEF9C;   /* lighter tint for subtle highlights */

  /* Rollup banner text color — warm slate navy. Used in brand signature
     block text where the print reference matters. Not for dark backgrounds. */
  --slate-navy: #404252;

  /* Motion */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out-quart: cubic-bezier(0.25, 1, 0.5, 1);

  /* TYPE SYSTEM — strict. 6 sizes, 4 weights. Every type element on the
     page picks from this list. No ad-hoc font-sizes anywhere else. */
  --t-xl:   clamp(52px, 8vw, 112px);     /* Stakes headline · Case numbers */
  --t-lg:   clamp(40px, 6.2vw, 84px);    /* Hero payoff · CTA title · Narrative headlines · Section titles · Brand stack */
  --t-md:   clamp(26px, 3.2vw, 44px);    /* Hero setup · Emphasis lines · Service titles · Founder quote */
  --t-sm:   clamp(17px, 1.4vw, 20px);    /* Narrative body · Hero subhead · Intro copy */
  --t-xs:   15px;                         /* Card body · Descriptors */
  --t-tiny: 12px;                         /* Eyebrows · FIG labels · Metadata */

  --w-black:  900;                        /* All display headlines */
  --w-bold:   700;                        /* Setup, emphasis, buttons, accent */
  --w-medium: 500;                        /* Label uppercase, nav */
  --w-reg:    400;                        /* Body text */

  /* Grid */
  --container-max: 1320px;
  --gutter: 24px;
  --gutter-lg: 48px;
}

/* =====================================================================
   RESET
   ===================================================================== */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* iOS rubber-band / overscroll exposes the <html> element's background
     (not body's), AND the safe-area zone above body uses html's color
     when env(safe-area-inset-top) extends the page edge-to-edge. Setting
     html bg to the same navy as the nav makes any pixel revealed above
     the page top — rubber-band, status-bar collapse animation, scroll
     restoration jitter — invisible. Standard iOS-Safari hardening
     (Stripe / Linear / WebKit guidance). */
  background-color: var(--navy-950);
  /* Tells iOS Safari to render its chrome (status bar, URL bar) in
     dark-mode style regardless of the user's system setting — pairs
     with the navy bg so iOS doesn't paint a light status-bar zone on
     top of our dark page. */
  color-scheme: dark;
}

/* Belt-and-suspenders: pin a navy slab in fixed coords above the visual
   viewport. Position fixed elements ARE part of the layer tree even when
   their box is partially or fully outside the viewport. iOS Safari paints
   them, so any moment the system reveals pixels above viewport y=0 (rubber
   band, status-bar collapse, scroll restoration animation) shows navy
   instead of html/body bg. Doesn't conflict with body::before noise grain. */
html::before {
  content: '';
  position: fixed;
  top: -200px;
  left: 0;
  right: 0;
  height: 200px;
  background: var(--navy-950);
  z-index: 9999;
  pointer-events: none;
}


body {
  font-family: 'Inter', system-ui, sans-serif;
  background: var(--navy-950);
  color: var(--ink-50);
  font-feature-settings: "liga", "calt", "ss01", "cv11";
  font-variant-numeric: tabular-nums;
  line-height: 1.5;
  /* `overflow-x: hidden` on body breaks `position: sticky` on iOS
     Safari — body becomes a scroll container, sticky elements try to
     stick to body (which never scrolls) instead of the viewport, so
     they stay glued to their document position and scroll away with
     the page. `overflow-x: clip` clips the same way visually but
     doesn't create a scroll container. Supported in Safari 16+. */
  overflow-x: clip;
  position: relative;
}

/* Subtle grain overlay on entire page — gives depth to dark backgrounds */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0.035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

img, svg { display: block; max-width: 100%; }
button { font: inherit; cursor: pointer; background: none; border: none; color: inherit; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; }

/* =====================================================================
   TYPOGRAPHY TOKENS
   ===================================================================== */

.font-display {
  font-family: 'Montserrat', system-ui, sans-serif;
  font-optical-sizing: auto;
}
.font-body { font-family: 'Inter', system-ui, sans-serif; }
.font-mono { font-family: 'Inter', sans-serif; text-transform: uppercase; letter-spacing: 0.15em; }

.eyebrow {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.18em;
  font-weight: 500;
  text-transform: uppercase;
  color: var(--ink-400);
  display: inline-block;
}

.eyebrow-signal { color: var(--signal-500); }

.eyebrow-rule {
  display: inline-flex;
  align-items: center;
  gap: 14px;
}
.eyebrow-rule::before {
  content: '';
  width: 32px;
  height: 1px;
  background: currentColor;
  display: inline-block;
}

/* =====================================================================
   LAYOUT
   ===================================================================== */

.container {
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}
@media (min-width: 960px) {
  .container { padding: 0 var(--gutter-lg); }
}
/* Scale the container up on large monitors so content doesn't feel marooned
   in the center of the viewport with huge navy margins on both sides. */
@media (min-width: 1800px) {
  :root { --container-max: 1520px; }
}
@media (min-width: 2400px) {
  :root { --container-max: 1720px; }
}

.section { padding: 96px 0; position: relative; }
.section-lg { padding: 144px 0; }
@media (max-width: 767px) {
  .section { padding: 72px 0; }
  .section-lg { padding: 96px 0; }
}

/* =====================================================================
   NAVIGATION
   ===================================================================== */

/* Single-layer translucent nav with backdrop-filter — the frosted-glass
   look is achieved by the translucent rgba bg letting page content blur
   through. We previously tried splitting into solid .nav + absolute
   .nav-glass child to satisfy iOS 26 Safari toolbar-tint sampling, but
   that split blocked the backdrop-filter from ever seeing through to
   page content (.nav's solid bg sat between the page and .nav-glass),
   killing the glass effect. The iOS-26 toolbar-tint concern doesn't
   apply on non-notch iPhones anyway: viewport-fit=cover doesn't extend
   the page into iOS chrome on those devices (verified via red-probe
   test), so Safari's sampling algorithm has nothing to tint with our
   nav. iOS chrome zone stays dark via color-scheme: dark on html. */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(15, 24, 35, 0.78);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid rgba(51, 64, 85, 0.4);
  /* Push contents below the iOS notch / Dynamic Island when the page
     extends edge-to-edge under it. On non-notch iPhones (SE-class) and
     on desktop the value is 0 — those contexts don't extend the page
     into iOS chrome (verified by the red-probe test: viewport-fit=cover
     leaves the status-bar zone iOS-controlled), so no extra padding is
     needed and the nav stays compact (matches the container's intrinsic
     height). Notch devices still get the ~47px env() value as required. */
  padding-top: env(safe-area-inset-top, 0px);
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 0;
}
.nav-logo {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: 'Univia Pro', 'Montserrat', sans-serif;
  font-weight: 500;
  font-size: 19px;
  letter-spacing: -0.01em;
  color: var(--ink-50);
  line-height: 1;
}
.nav-logo-name { line-height: 1; }
.brand-mark {
  width: 44px;
  height: 30px;
  fill: var(--signal-500);
  flex-shrink: 0;
}
.brand-mark-large {
  width: 60%;
  fill: var(--signal-500);
  opacity: 0.35;
  display: block;
  margin: 0 auto;
}

.nav-links {
  display: none;
  align-items: center;
  gap: 40px;
}
@media (min-width: 1024px) {
  .nav-links { display: flex; }
}
.nav-links a {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-200);
  border-bottom: 2px solid transparent;
  padding-bottom: 4px;
  transition: color 200ms var(--ease-out-quart),
              border-color 300ms var(--ease-out-quart);
}
.nav-links a:hover {
  color: var(--ink-50);
  border-bottom-color: var(--signal-500);
}

.nav-right {
  display: flex;
  align-items: center;
  gap: 32px;
}
.nav-contact {
  font-size: 13.5px;
  color: var(--ink-50);
  font-weight: 500;
  display: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  transition: border-color 300ms var(--ease-out-quart);
}
.nav-contact:hover { border-bottom-color: var(--signal-500); }
@media (min-width: 768px) { .nav-contact { display: inline; } }

.lang-switcher {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.12em;
}
.lang-switcher .active { color: var(--ink-50); font-weight: 500; }
.lang-switcher .inactive { color: var(--ink-600); }
.lang-switcher .slash { color: var(--navy-600); }

/* =====================================================================
   INTRO REVEAL — 4-line cinematic opener + post-reveal tagline strip
   ===================================================================== */

/* Full-viewport overlay that covers the hero on first paint. Fades away
   once the JS orchestrator finishes staggering the 4 punchlines. */
.intro-reveal {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--navy-950);
  display: flex;
  align-items: center;
  opacity: 1;
  cursor: pointer;
  transition: opacity 800ms var(--ease-out-quart);
}
.intro-reveal.is-done {
  opacity: 0;
  pointer-events: none;
}
.intro-reveal-inner {
  max-width: 1100px;
  width: 100%;
  margin: 0 auto;
  padding: 0 40px;
}
.intro-line {
  font-family: 'Montserrat', sans-serif;
  font-weight: var(--w-black);
  font-size: clamp(20px, 2.4vw, 34px);
  line-height: 1.15;
  letter-spacing: -0.025em;
  color: var(--ink-50);
  margin: 0 0 22px;
  white-space: nowrap; /* each sentence on one line — wraps only below 640px */
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 700ms var(--ease-out-quart),
              transform 700ms var(--ease-out-quart);
}
.intro-line:last-child {
  margin-bottom: 0;
}
/* Second punchline ("Cutting costs and growing revenue is the hard part.")
   in signal yellow — that's the brand thesis line, the one Partners is
   built around. Narrow exception to "no inline yellow text" (§21):
   scoped to one line, on the intro overlay only, on first-load only.
   The other three punchlines stay --ink-50 (white). */
.intro-line:nth-child(2) {
  color: var(--signal-500);
}
.intro-line.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (max-width: 639px) {
  .intro-reveal-inner { padding: 0 24px; }
  .intro-line {
    font-size: clamp(14px, 4.5vw, 22px);
    white-space: normal; /* wrap allowed on narrow screens */
    margin-bottom: 16px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .intro-reveal,
  .intro-line,
  .intro-line-clone {
    transition: none;
  }
}

/* =====================================================================
   HERO
   ===================================================================== */

.hero {
  position: relative;
  overflow: hidden;
}
.hero-content {
  position: relative;
  z-index: 2;
  /* No max-width cap — grid column sizes the text column; capping here
     would prevent the payoff from fitting on one line at wide viewports. */
  /* Vertical padding lives on the text column, not on the section — so
     the hero-visual on the right bleeds top-to-bottom of the section with
     no navy strip above/below. Content is centered vertically inside the
     stretched cell so it sits naturally in the middle of the fold. */
  padding: 48px 0 88px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
@media (max-width: 767px) {
  .hero-content { padding: 40px 0 72px; }
}

/* Two-column hero: content left, ambient oil painting right. Hero section
   takes the full viewport below the nav, so the painting feels like the
   fold, not a slice. Content column centers vertically inside its grid
   cell; visual stretches edge-to-edge via align-items: stretch. */
.hero-layout {
  position: relative;
  z-index: 2;
  display: grid;
  /* Image column carries the painting (hero-visual). Significantly widened
     from the original 0.78fr so the figure + grass + horizon read as the
     dominant element next to the headline. Payoff copy is capped at 18ch
     so the narrower text column doesn't force awkward wraps. These ratios
     are tuned for ≈ +50% absolute image width vs. the pre-widening values
     at each breakpoint — not just +50% ratio shift, which a fixed-total grid
     under-delivers. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: 72px;
  align-items: stretch;
  /* Hero height is driven by the text — so the picture scales with the
     content, and there's no oversized empty space around the text on wide
     monitors. Floor keeps it from collapsing if the content ever becomes
     very short. */
  min-height: 540px;
}
@media (max-width: 1023px) {
  .hero-layout {
    grid-template-columns: 1fr;
    gap: 56px;
    align-items: center;
    min-height: 0;
  }
}

/* Hero visual: atmospheric oil painting on the right. No framed box —
   dissolves into the navy canvas at the left edge, bleeds past the container
   at the right, and drifts vertically with scroll via a parallax transform
   on the still itself. FIG label puts it in the oil-painting-series vocabulary. */
.hero-visual {
  position: relative;
  /* Stay inside the container's right edge so the hero's right vertical guide
     lines up with every other section (insights title, cases grid header,
     trust logos, solution cards, founder quote, CTA). The old edge-bleed
     formula made the painting slide past the container at wide viewports,
     which broke the site's vertical rhythm and read as unprofessional — the
     image extended 240 px past the Insights title on a 1920 px screen with
     `--container-max: 1520`. Now: image sits flush inside its grid cell.
     The atmospheric fade into the text column stays — that's the mask below. */
  width: 100%;
  /* Height comes from the grid cell (stretched to match 100vh - nav). A
     floor for edge cases where the grid's min-height doesn't apply. */
  min-height: 520px;
  overflow: hidden;
  background: var(--navy-950);
  isolation: isolate;
  /* Left-edge dissolve — atmospheric haze that hands the visual off to the
     text column. Previously settled at 42% of element width, which was sized
     for the old edge-bleed formula (image extended past the container). Now
     that the image sits flush inside its grid cell, 42% ate too much of the
     visible painting and left a heavy navy gap between the headline and the
     figure. Compressed to settle at 18% — fade keeps the same smooth cubic
     shape, just on a shorter runway. */
  -webkit-mask-image: linear-gradient(to right,
    transparent 0%,
    rgba(0, 0, 0, 0.005) 3%,
    rgba(0, 0, 0, 0.03) 6%,
    rgba(0, 0, 0, 0.08) 9%,
    rgba(0, 0, 0, 0.18) 12%,
    rgba(0, 0, 0, 0.35) 15%,
    rgba(0, 0, 0, 0.58) 18%,
    rgba(0, 0, 0, 0.82) 21%,
    #000 25%,
    #000 100%);
  mask-image: linear-gradient(to right,
    transparent 0%,
    rgba(0, 0, 0, 0.005) 3%,
    rgba(0, 0, 0, 0.03) 6%,
    rgba(0, 0, 0, 0.08) 9%,
    rgba(0, 0, 0, 0.18) 12%,
    rgba(0, 0, 0, 0.35) 15%,
    rgba(0, 0, 0, 0.58) 18%,
    rgba(0, 0, 0, 0.82) 21%,
    #000 25%,
    #000 100%);
}
.hero-visual-still {
  position: absolute;
  left: 0;
  right: 0;
  top: -15%;
  height: 130%;
  width: 100%;
  object-fit: cover;
  /* Grasshill is landscape 16:9 with the figure in the right third of the
     composition. Shift the crop window rightward so he stays in frame when
     the portrait-ish container crops the landscape source horizontally. */
  object-position: 68% center;
  display: block;
  transform: translate3d(0, var(--hero-parallax, 0px), 0);
  will-change: transform;
}
/* Subtle scrim at the bottom so the FIG label reads cleanly over the image. */
.hero-visual-scrim {
  position: absolute;
  inset: auto 0 0 0;
  height: 42%;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(to top,
    rgba(15, 24, 35, 0.55) 0%,
    rgba(15, 24, 35, 0) 100%);
}
/* Hero visual caption styled as a small gallery plaque — an easter egg for
   anyone who looks closely. Title is italic humanist, meta line is all-caps
   letter-spaced like a museum label. Sits bottom-right, outside the left-edge
   mask fade, where the image is at full opacity. */
.hero-visual-fig {
  position: absolute;
  right: 24px;
  bottom: 16px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  max-width: 320px;
  text-align: right;
  font-family: 'Inter', system-ui, sans-serif;
  line-height: 1.25;
  color: rgba(247, 248, 250, 0.78);
}
.hero-visual-fig-title {
  font-size: 12px;
  font-weight: var(--w-medium);
  font-style: italic;
  letter-spacing: 0;
  color: rgba(247, 248, 250, 0.88);
}
.hero-visual-fig-meta {
  font-size: 8.5px;
  font-weight: var(--w-medium);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(247, 248, 250, 0.55);
}
@media (max-width: 1023px) {
  .hero-visual {
    aspect-ratio: 3 / 4;
    min-height: 0;
    /* Stacked under the text → full-bleed edge-to-edge. Negative margin-inline
       cancels the .container parent's horizontal padding so the visual aligns
       with the viewport's content edges. Transform isn't used here because
       .reveal-hero ships a reveal-up keyframe whose final `transform:
       translateY(0)` stomps any translate we set. No left-edge mask either
       (bleeds to both edges uniformly). */
    width: calc(100% + 2 * var(--gutter));
    max-width: none;
    margin-inline: calc(-1 * var(--gutter));
    -webkit-mask-image: none;
    mask-image: none;
  }
}
@media (min-width: 960px) and (max-width: 1023px) {
  /* .container switches to gutter-lg padding at 960 px — match the inset. */
  .hero-visual {
    width: calc(100% + 2 * var(--gutter-lg));
    margin-inline: calc(-1 * var(--gutter-lg));
  }
}
@media (max-width: 767px) {
  .hero-visual { aspect-ratio: 4 / 5; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-visual-still { transform: none; }
}


.hero-grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 1fr;
  gap: 64px;
  align-items: center;
}
@media (min-width: 960px) {
  .hero-grid {
    grid-template-columns: 7fr 5fr;
    gap: 80px;
  }
}

/* Hero headline — setup reads first (context), payoff reads second (promise).
   Payoff uses the same treatment as CTA title — both are "promise blocks" that
   bookend the page. Single yellow highlight per block, nothing else. */
.hero-headline {
  font-family: 'Montserrat', sans-serif;
  color: var(--ink-50);
  margin-bottom: 72px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  letter-spacing: -0.025em;
}
.hero-setup {
  font-weight: var(--w-bold);
  font-size: var(--t-sm);
  line-height: 1.35;
  max-width: 38ch;
  color: var(--ink-100);
}
.hero-payoff {
  font-weight: var(--w-black);
  font-size: var(--t-lg);
  line-height: 1.05;
  letter-spacing: -0.032em;
  max-width: 18ch;
}
.hero-hl {
  background-color: var(--signal-500);
  color: var(--slate-navy);
  padding: 0.04em 0.16em 0.1em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  border-radius: 0;
  white-space: nowrap;
}

.hero-subhead {
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--ink-200);
  max-width: 54ch;
  font-weight: var(--w-reg);
  margin-bottom: 40px;
}

/* Hero layout widens proportionally with viewport so "We help you" still
   fits on a single line inside the text column at large desktop widths.
   Hero type stays locked to the §3 scale (--t-sm / --t-lg) at every viewport —
   matching the CTA section's title/desc sizing as the shared "promise block"
   rhythm. Previously hero-payoff had a 5.83vw override capped at 150 px that
   outgrew CTA at ≥ 1600 px; reverted after it read as shouty. */
@media (min-width: 1600px) {
  .hero-layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); }
}
@media (min-width: 2400px) {
  .hero-layout { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); }
}

.hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 16px 28px;
  background: var(--signal-500);
  color: var(--navy-950);
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.01em;
  border: 1px solid var(--signal-500);
  transition: background 300ms var(--ease-out-quart), gap 300ms var(--ease-out-quart);
}
.hero-cta:hover {
  background: var(--signal-600);
  gap: 18px;
}
.hero-cta svg { width: 15px; height: 15px; }

/* Scroll indicator below hero */
.scroll-indicator {
  position: absolute;
  bottom: 32px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.scroll-indicator .line {
  width: 1px;
  height: 24px;
  background: var(--ink-600);
  position: relative;
  overflow: hidden;
}
.scroll-indicator .line::after {
  content: '';
  position: absolute;
  top: -24px;
  left: 0;
  width: 100%;
  height: 24px;
  background: var(--signal-500);
  animation: scroll-drop 2400ms var(--ease-out-expo) infinite;
}
@keyframes scroll-drop {
  0%   { top: -24px; }
  60%  { top: 24px; }
  100% { top: 24px; }
}

/* =====================================================================
   SOLUTION — what we do. Three service blocks.
   Clean editorial cards, numbered, no illustrations.
   ===================================================================== */

.solution {
  background: var(--navy-950);
}

/* Solution layout mirrors the hero: text column on the left, atmospheric
   scene on the right with a bleed to the viewport edge on wide screens.
   The scene's video loops ambiently (muted, autoplay) alongside the text. */
.solution-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 48px;
  margin-bottom: 88px;
  align-items: stretch;
  width: 100%;
}
@media (min-width: 960px) {
  .solution-layout {
    /* Image column widened from 0.62fr so the park-bench scene carries the
       same weight as the text column. Text side shrinks by the matching
       absolute amount (grid total is fixed); the section-intro paragraphs
       are short enough not to suffer wrap issues at the narrower column. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    gap: 72px;
  }
}
.solution-header {
  max-width: 860px;
  margin-bottom: 0;
}
.solution-header .section-title {
  margin-bottom: 36px;
}

.solution-scene {
  position: relative;
  width: 100%;
  min-height: 420px;
  overflow: hidden;
  background: var(--navy-900);
  isolation: isolate;
}
@media (min-width: 960px) {
  .solution-scene {
    margin-top: -96px;
    /* Stay inside container's right edge — match hero-visual (§8.2) and all
       other sections. The previous edge-bleed to viewport right broke the
       vertical rhythm at wide viewports (image extended past insights title
       / cases header / CTA by up to --container-max/2 px). */
    width: 100%;
    /* Left-edge cubic dissolve — matches the compressed hero-visual runway
       (settles at 18% instead of the legacy 42% which was sized for the old
       edge-bleed). Works because object-position pushes the people into
       the right portion of the frame; the fade falls on the trees/
       atmosphere on the left, not on the figures. */
    /* Solution scene is narrower than hero-visual (~594 px vs ~847 px at
       desktop), so its 25 % runway would only be ~148 px absolute vs hero's
       ~212 px and read sharper. Settle pushed to 33 % so the absolute runway
       matches hero's softness. */
    -webkit-mask-image: linear-gradient(to right,
      transparent 0%,
      rgba(0, 0, 0, 0.005) 4%,
      rgba(0, 0, 0, 0.03) 8%,
      rgba(0, 0, 0, 0.08) 12%,
      rgba(0, 0, 0, 0.18) 16%,
      rgba(0, 0, 0, 0.35) 20%,
      rgba(0, 0, 0, 0.58) 24%,
      rgba(0, 0, 0, 0.82) 28%,
      #000 33%,
      #000 100%);
    mask-image: linear-gradient(to right,
      transparent 0%,
      rgba(0, 0, 0, 0.005) 4%,
      rgba(0, 0, 0, 0.03) 8%,
      rgba(0, 0, 0, 0.08) 12%,
      rgba(0, 0, 0, 0.18) 16%,
      rgba(0, 0, 0, 0.35) 20%,
      rgba(0, 0, 0, 0.58) 24%,
      rgba(0, 0, 0, 0.82) 28%,
      #000 33%,
      #000 100%);
  }
}
.solution-scene-still,
.solution-scene-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Center crop — the figure sits in the middle of the painting. */
  object-position: center center;
  display: block;
}
.solution-scene-still { z-index: 1; }
.solution-scene-video {
  z-index: 2;
  opacity: 0;
  transition: opacity 600ms ease;
}
.solution-scene-video.is-ready { opacity: 1; }
.solution-scene-fig {
  position: absolute;
  right: 24px;
  bottom: 18px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  max-width: 320px;
  text-align: right;
  font-family: 'Inter', system-ui, sans-serif;
  line-height: 1.25;
  color: rgba(247, 248, 250, 0.82);
}
.solution-scene-fig-title {
  font-size: 12px;
  font-weight: var(--w-medium);
  font-style: italic;
  color: rgba(247, 248, 250, 0.9);
}
.solution-scene-fig-meta {
  font-size: 8.5px;
  font-weight: var(--w-medium);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(247, 248, 250, 0.55);
}
@media (max-width: 959px) {
  .solution-scene {
    aspect-ratio: 4 / 3;
    min-height: 0;
    max-width: 560px;
    margin: 0 auto;
  }
}
@media (prefers-reduced-motion: reduce), (hover: none) {
  .solution-scene-video { display: none; }
}
.section-intro + .section-intro {
  margin-top: 24px;
}

.solution-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
}
@media (min-width: 768px) {
  .solution-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
  }
}

.solution-card {
  background: var(--navy-900);
  border: 1px solid var(--navy-800);
  padding: 40px 36px 36px;
  display: flex;
  flex-direction: column;
  transition: border-color 400ms var(--ease-out-quart),
              background-color 400ms var(--ease-out-quart),
              transform 400ms var(--ease-out-quart);
}
.solution-card:hover {
  border-color: var(--signal-500);
  background: var(--navy-800);
  transform: translateY(-3px);
}
.solution-num {
  font-family: 'Montserrat', sans-serif;
  font-size: var(--t-md);
  font-weight: var(--w-black);
  letter-spacing: -0.025em;
  color: var(--signal-500);
  margin-bottom: 24px;
  line-height: 1;
}
.solution-card-category {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: var(--t-tiny);
  font-weight: var(--w-medium);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-400);
  margin-bottom: 16px;
}
.solution-card-title {
  font-family: 'Montserrat', sans-serif;
  font-size: var(--t-md);
  font-weight: var(--w-black);
  letter-spacing: -0.02em;
  color: var(--ink-50);
  line-height: 1.1;
  margin-bottom: 20px;
}
.solution-card-body {
  font-size: var(--t-sm);
  line-height: 1.65;
  color: var(--ink-200);
  margin-bottom: 28px;
  flex: 1;
}
.solution-card-link {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: var(--t-tiny);
  font-weight: var(--w-medium);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--signal-500);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: gap 300ms var(--ease-out-quart);
}
.solution-card:hover .solution-card-link { gap: 14px; }

.solution-close {
  margin-top: 72px;
  margin-bottom: 64px;
  max-width: 48ch;
  padding-left: 20px;
  border-left: 2px solid var(--signal-500);
  font-family: 'Montserrat', sans-serif;
  font-size: var(--t-md);
  font-weight: var(--w-bold);
  line-height: 1.3;
  letter-spacing: -0.015em;
  color: var(--ink-50);
}

/* =====================================================================
   NARRATIVE SECTIONS — Manifesto, Proof, Stakes
   Shared editorial typography. Alternating navy-900 / navy-950 for rhythm.
   ===================================================================== */

.narrative {
  padding: 136px 0;
  position: relative;
  overflow: hidden;
}
@media (max-width: 767px) {
  .narrative { padding: 88px 0; }
}
.narrative--dark { background: var(--navy-950); }
.narrative--mid  { background: var(--navy-900); }

.narrative-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 40px;
  color: var(--signal-500);
}
.narrative-eyebrow::before {
  content: '';
  width: 32px;
  height: 1px;
  background: currentColor;
}

.narrative-title {
  font-family: 'Montserrat', sans-serif;
  font-weight: var(--w-black);
  font-size: var(--t-lg);
  line-height: 1.02;
  letter-spacing: -0.028em;
  color: var(--ink-50);
  margin-bottom: 48px;
  max-width: 20ch;
  text-wrap: balance;
}
/* Stakes variant — short headline, can go bigger. Uses --t-xl token. */
.narrative-title--huge {
  font-size: var(--t-xl);
  line-height: 0.98;
  letter-spacing: -0.035em;
  max-width: 14ch;
  margin-bottom: 56px;
}

.narrative-body {
  max-width: 60ch;
  color: var(--ink-200);
  font-size: var(--t-sm);
  line-height: 1.7;
}
.narrative-body p + p { margin-top: 24px; }

/* Emphasis line — yellow left-border pull-out. Uses display-md scale so
   it reads as a separate beat from body. */
.narrative-emph {
  font-family: 'Montserrat', sans-serif;
  font-weight: var(--w-bold);
  font-size: var(--t-md);
  line-height: 1.22;
  letter-spacing: -0.02em;
  color: var(--ink-50);
  max-width: 30ch;
  margin-top: 48px !important;
  padding-left: 20px;
  border-left: 2px solid var(--signal-500);
}

/* Pull-out: the CBRE anecdote. Yellow left rule, slight inset, distinct tone. */
.narrative-pullout {
  margin: 48px 0;
  padding: 4px 0 4px 32px;
  border-left: 2px solid var(--signal-500);
  color: var(--ink-100);
}
.narrative-pullout p { margin: 0; }
.narrative-pullout p + p { margin-top: 20px; }
.narrative-pullout-meta {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--ink-400);
  text-transform: uppercase;
  margin-bottom: 16px;
  display: block;
}

/* =====================================================================
   SECTION 3 — INSIGHTS STRIP
   ===================================================================== */

.insights {
  background: var(--navy-900);
  border-top: 1px solid var(--navy-800);
}

.insights-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 64px;
  flex-wrap: wrap;
  gap: 16px;
}
.insights-title {
  font-family: 'Montserrat', sans-serif;
  font-size: var(--t-lg);
  font-weight: var(--w-black);
  letter-spacing: -0.028em;
  color: var(--ink-50);
  max-width: 14ch;
  line-height: 1.02;
}
.insights-see-all {
  font-size: 13px;
  color: var(--ink-200);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: gap 300ms var(--ease-out-quart), color 200ms;
}
.insights-see-all:hover { gap: 14px; color: var(--signal-500); }

/* 3 insight cards — asymmetric: 1 large + 2 small stacked OR 3 equal on desktop */
.insights-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}
@media (min-width: 768px) {
  .insights-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
  }
}

.insight-card {
  background: var(--navy-850);
  /* See .case-card for why box-shadow instead of border. */
  box-shadow: 0 0 0 1px var(--navy-800);
  transition: box-shadow 400ms var(--ease-out-quart),
              transform 400ms var(--ease-out-quart),
              background-color 400ms var(--ease-out-quart);
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.insight-card:hover {
  box-shadow: 0 0 0 1px var(--signal-500);
  background: var(--navy-800);
  transform: translateY(-3px);
}
.insight-card:hover .insight-card-image {
  transform: scale(1.03);
}
.insight-card-image-wrapper {
  width: 100%;
  aspect-ratio: 16 / 10;  /* approx golden-adjacent, feels right */
  overflow: hidden;
  background: var(--navy-800);
  position: relative;
}
.insight-card-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: transform 800ms var(--ease-out-quart);
}
.insight-card-body {
  padding: 28px 28px 32px;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.insight-card-meta {
  color: var(--ink-400);
  margin-bottom: 16px;
}
.insight-card-title {
  font-family: 'Montserrat', sans-serif;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink-50);
  line-height: 1.3;
  margin-bottom: 12px;
}
.insight-card-excerpt {
  font-size: 14.5px;
  color: var(--ink-200);
  line-height: 1.6;
  margin-bottom: 24px;
  flex: 1;
}
.insight-card-cta {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--signal-500);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: gap 300ms var(--ease-out-quart);
  font-weight: 500;
}
.insight-card:hover .insight-card-cta { gap: 14px; }

/* Peaceful oil painting scene cards — video loop with still poster fallback.
   Implementation per CLAUDE.md "Visual language" section. */
.insight-card-scene-wrap {
  position: relative;
  overflow: hidden;
  aspect-ratio: 16 / 10;
  background: var(--navy-950);
}
.insight-card-scene-still,
.insight-card-scene-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 800ms var(--ease-out-quart);
}
/* Still sits at z-index 1, video on top at z-index 2 when active.
   Video starts invisible; JS reveals it once it can play. */
.insight-card-scene-still { z-index: 1; }
.insight-card-scene-video {
  z-index: 2;
  opacity: 0;
  transition: opacity 600ms ease, transform 800ms var(--ease-out-quart);
}
.insight-card-scene-video.is-playing { opacity: 1; }

/* Scrim: subtle dark gradient bottom-left so FIG label stays legible. */
.insight-card-scene-scrim {
  position: absolute;
  inset: auto 0 0 0;
  height: 50%;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(to top,
    rgba(15, 24, 35, 0.5) 0%,
    rgba(15, 24, 35, 0) 100%);
}
/* Insight card caption styled as a small gallery plaque — same vocabulary
   as the hero visual plaque (italic title + uppercase letter-spaced meta). */
.insight-card-scene-fig {
  position: absolute;
  left: 16px;
  bottom: 14px;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-width: 80%;
  pointer-events: none;
  font-family: 'Inter', system-ui, sans-serif;
  line-height: 1.25;
  color: rgba(247, 248, 250, 0.78);
}
.insight-card-scene-fig-title {
  font-size: 11.5px;
  font-weight: var(--w-medium);
  font-style: italic;
  letter-spacing: 0;
  color: rgba(247, 248, 250, 0.88);
}
.insight-card-scene-fig-meta {
  font-size: 8.5px;
  font-weight: var(--w-medium);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(247, 248, 250, 0.55);
}

/* Hover: slight scale on scene card, matching other cards */
.insight-card:hover .insight-card-scene-still,
.insight-card:hover .insight-card-scene-video {
  transform: scale(1.02);
}

/* Reduced motion: no video, no hover scale. Just the still. */
@media (prefers-reduced-motion: reduce) {
  .insight-card-scene-video { display: none; }
  .insight-card:hover .insight-card-scene-still {
    transform: none;
    transition: none;
  }
}

/* Mobile: serve the still only (video file is ~14MB). */
@media (max-width: 767px) {
  .insight-card-scene-video { display: none; }
}

/* =====================================================================
   SECTION 4 — TRUST LINE
   ===================================================================== */

.trust {
  padding: 80px 0;
  background: var(--navy-950);
  border-top: 1px solid var(--navy-800);
  border-bottom: 1px solid var(--navy-800);
}
.trust-label {
  text-align: center;
  margin-bottom: 40px;
  color: var(--ink-400);
}
.trust-logos {
  display: grid;
  /* minmax(0, 1fr) caps track width at the viewport share — without it, split-logo
     images with `max-width: none` can force 1fr tracks wider than the container and
     clip the right column off the viewport on narrow screens. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 32px 20px;
  align-items: center;
  justify-items: center;
}
@media (min-width: 640px) {
  .trust-logos { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 44px 32px; }
}
@media (min-width: 960px) {
  /* 5 columns × 2 rows = 10 logos, clean geometric grid on desktop. */
  .trust-logos { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 56px 48px; }
}
/* Trust logos: real client marks rendered as white silhouettes for a
   uniform, quiet row. On hover, the filter lifts and native brand colors
   return. "It is about us, not them" — uniform presence, never dominant,
   but genuine when the eye catches them. */
.trust-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Height scales with viewport: phone 40px, tablet+ 48px. Smaller cells at
     phone width keep split-logo content within the track and reduce visual
     weight of the trust row on tiny screens. */
  height: 40px;
  width: 100%;
  max-width: 160px;
  color: var(--ink-100);
  opacity: 0.6;
  transition: opacity 400ms var(--ease-out-quart),
              filter 400ms var(--ease-out-quart),
              color 400ms var(--ease-out-quart);
  cursor: default;
}
@media (min-width: 640px) {
  .trust-logo { height: 48px; }
}
.trust-logo img {
  max-height: 100%;
  max-width: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
  /* brightness(0) invert(1) turns any non-transparent pixel white —
     transparent areas stay transparent, so the logo reads as a clean
     white silhouette on navy. */
  filter: brightness(0) invert(1);
  transition: filter 400ms var(--ease-out-quart);
}
/* Ford has a solid blue oval with white text — the white-silhouette filter
   flattens the whole logo to a white blob. Desaturate + brighten instead
   so the oval shape remains readable as a light grey wordmark. */
.trust-logo.logo-ford img {
  filter: grayscale(1) brightness(1.3) contrast(0.95);
}
/* Catensys, Petit Press, and Synchronix each render as two images — a
   colored mark on the left (returns to native colors on hover, like
   other logos) and a near-black wordmark on the right (stays locked to
   white silhouette even on hover, since its native ink would vanish
   against navy). */
.trust-logo.logo-catensys,
.trust-logo.logo-petitpress,
.trust-logo.logo-synchronix {
  gap: 10px;
  max-width: 190px;
}
.trust-logo.logo-catensys img,
.trust-logo.logo-petitpress img {
  height: 100%;
  max-height: 100%;
  width: auto;
  max-width: none;
}
/* Synchronix is unusually wide (~7:1). Explicit image height keeps the
   combined mark + wordmark rendering at a size consistent with other
   logos instead of overflowing the cell. Scales with `.trust-logo` height
   (phone 40→20px, tablet+ 48→24px). */
.trust-logo.logo-synchronix img {
  height: 20px;
  width: auto;
  max-width: none;
}
@media (min-width: 640px) {
  .trust-logo.logo-synchronix img { height: 24px; }
}
.trust-logo.logo-catensys:hover img.catensys-text,
.trust-logo.logo-petitpress:hover img.petitpress-text,
.trust-logo.logo-synchronix:hover img.synchronix-text {
  filter: brightness(0) invert(1);
}
.trust-logo svg {
  height: 28px;
  width: auto;
}
.trust-logo:hover {
  opacity: 1;
}
.trust-logo:hover img {
  filter: none;
}

/* =====================================================================
   SECTION 5 — CAPABILITIES (big editorial cards)
   ===================================================================== */

.capabilities {
  padding-top: 144px;
  padding-bottom: 144px;
}
@media (max-width: 767px) {
  .capabilities { padding-top: 96px; padding-bottom: 96px; }
}

.capabilities-header {
  margin-bottom: 80px;
  max-width: 720px;
}
.section-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 28px;
  color: var(--signal-500);
}
.section-eyebrow::before {
  content: '';
  width: 28px;
  height: 1px;
  background: currentColor;
}
.section-title {
  font-family: 'Montserrat', sans-serif;
  font-size: var(--t-lg);
  font-weight: var(--w-black);
  letter-spacing: -0.028em;
  color: var(--ink-50);
  line-height: 1.02;
  margin-bottom: 24px;
}
.section-intro {
  font-size: var(--t-sm);
  color: var(--ink-200);
  line-height: 1.6;
  max-width: 58ch;
}

.cap-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
}
@media (min-width: 768px) {
  .cap-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
  }
}
@media (min-width: 1200px) {
  .cap-grid { gap: 32px; }
}

.cap-card {
  position: relative;
  background: var(--navy-900);
  border: 1px solid var(--navy-800);
  padding: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: border-color 500ms var(--ease-out-quart),
              transform 500ms var(--ease-out-quart),
              background-color 500ms var(--ease-out-quart);
}
.cap-card:hover {
  border-color: var(--signal-500);
  background: var(--navy-800);
}
.cap-card:hover .cap-card-visual { transform: scale(1.04); }

.cap-card-visual-wrap {
  width: 100%;
  aspect-ratio: 16 / 10;
  background: var(--navy-850);
  overflow: hidden;
  position: relative;
  border-bottom: 1px solid var(--navy-800);
}
.cap-card-visual {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: transform 1000ms var(--ease-out-quart);
}

.cap-card-body {
  padding: 36px 32px 40px;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.cap-card-number {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.15em;
  color: var(--ink-400);
  margin-bottom: 20px;
}
.cap-card-title {
  font-family: 'Montserrat', sans-serif;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.015em;
  color: var(--ink-50);
  line-height: 1.15;
  margin-bottom: 16px;
}
.cap-card-desc {
  font-size: 15px;
  color: var(--ink-200);
  line-height: 1.6;
  margin-bottom: 32px;
  flex: 1;
}
.cap-card-link {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--signal-500);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  transition: gap 300ms var(--ease-out-quart);
}
.cap-card:hover .cap-card-link { gap: 16px; }

/* =====================================================================
   SECTION 6 — APPROACH (horizontal steps with big numbers)
   ===================================================================== */

.approach {
  background: var(--navy-900);
  padding: 144px 0;
  position: relative;
  overflow: hidden;
}
@media (max-width: 767px) { .approach { padding: 96px 0; } }

/* Shared decorative — giant brand cluster echo in section backgrounds.
   z-index 0 + container above with z-index 1 ensures the cluster is
   always BEHIND the foreground text, never overlapping it. */
.section-bg-cluster {
  position: absolute;
  pointer-events: none;
  fill: var(--signal-500);
  opacity: 0.04;
  z-index: 0;
}
.founder .container {
  position: relative;
  z-index: 1;
}
.founder .bg-star {
  position: absolute;
  top: 50%;
  right: -140px;
  transform: translateY(-50%);
  width: 820px;
  height: 600px;
  opacity: 0.04;
  pointer-events: none;
  fill: var(--signal-500);
}

.approach-header {
  margin-bottom: 96px;
  max-width: 720px;
  position: relative;
  z-index: 2;
}

.approach-steps {
  display: grid;
  grid-template-columns: 1fr;
  gap: 64px;
  position: relative;
  z-index: 2;
}
@media (min-width: 960px) {
  .approach-steps {
    grid-template-columns: repeat(3, 1fr);
    gap: 48px;
  }
}

.step {
  position: relative;
  padding-top: 48px;
  border-top: 1px solid var(--navy-700);
}
.step-number {
  font-family: 'Montserrat', sans-serif;
  font-size: 72px;
  font-weight: 900;
  line-height: 0.9;
  letter-spacing: -0.04em;
  color: var(--signal-500);
  margin-bottom: 32px;
  display: inline-block;
  position: relative;
}
.step-number-label {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10px;
  letter-spacing: 0.2em;
  color: var(--ink-400);
  position: absolute;
  top: 12px;
  right: -64px;
  text-transform: uppercase;
  white-space: nowrap;
}
.step-title {
  font-family: 'Montserrat', sans-serif;
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--ink-50);
  line-height: 1.2;
  margin-bottom: 20px;
}
.step-desc {
  font-size: 15px;
  color: var(--ink-200);
  line-height: 1.65;
}

/* =====================================================================
   SECTION 7 — CASE STUDIES (editorial card stack)
   ===================================================================== */

.cases {
  padding: 144px 0;
  background: var(--navy-900);
}
@media (max-width: 767px) { .cases { padding: 96px 0; } }

.cases-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: 80px;
  flex-wrap: wrap;
  gap: 32px;
}

.cases-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: 0 var(--gutter);
  box-sizing: border-box;
}
@media (min-width: 960px) {
  .cases-grid { padding-inline: var(--gutter-lg); }
}
@media (min-width: 768px) {
  /* 2-col tablet layout; first card spans both cols as an editorial-weight cue */
  .cases-grid { grid-template-columns: 1fr 1fr; }
  .case-card:first-child { grid-column: 1 / -1; }
}
@media (min-width: 1100px) {
  /* 3-col desktop — all cards equal size (no 1.2 / 1 / 1 bias). */
  .cases-grid {
    grid-template-columns: 1fr 1fr 1fr;
  }
  .case-card:first-child { grid-column: auto; }
}

/* Cases section bg "breath" — symmetric on entry and exit. As the section
   approaches the viewport center, bg lightens navy-950 → navy-900 (matches
   solution above on entry, founder below on exit). At the center: navy-900.
   Pure scroll-driven, single CSS var, no full-bleed tray. JS sets
   `--cases-breath` 0 → 1 → 0 in lockstep with how centered the section is.
   Below 1100 px or under reduced-motion: var stays unset, bg falls back to
   the static `.cases { background: var(--navy-900) }` rule above. */
@media (min-width: 1100px) {
  .cases {
    background: color-mix(in srgb, var(--navy-950), var(--navy-900) calc(var(--cases-breath, 0) * 100%));
  }
  @media (prefers-reduced-motion: reduce) {
    .cases { --cases-breath: 1; }
  }
}

.case-card {
  background: var(--navy-900);
  /* Frame uses outset box-shadow instead of `border`. With html { zoom: 1.1 }
     and the card's inner overflow: hidden + transform on hover, regular
     1 px borders rasterize inconsistently — sometimes a side disappears at
     fractional pixel boundaries. Box-shadow renders crisply on all 4 sides
     regardless of subpixel offsets and doesn't affect box dimensions. */
  box-shadow: 0 0 0 1px var(--navy-800);
  transition: box-shadow 500ms var(--ease-out-quart),
              transform 500ms var(--ease-out-quart),
              background-color 500ms var(--ease-out-quart);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.case-card:hover {
  box-shadow: 0 0 0 1px var(--signal-500);
  background: var(--navy-800);
  transform: translateY(-3px);
}
.case-card:hover .case-card-visual { transform: scale(1.05); }

.case-card-visual-wrap {
  width: 100%;
  aspect-ratio: 16 / 11;
  background: var(--navy-850);
  overflow: hidden;
  position: relative;
}
.case-card-visual {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transition: transform 1000ms var(--ease-out-quart);
}
.case-card-client-badge {
  position: absolute;
  top: 20px;
  left: 20px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-50);
  background: rgba(15, 24, 35, 0.78);
  backdrop-filter: blur(8px);
  padding: 8px 12px;
  border: 1px solid rgba(138, 147, 163, 0.3);
}
.case-card-body {
  padding: 36px 32px 40px;
  flex: 1;
  display: flex;
  flex-direction: column;
  /* Hairline divider keeps the visual (painting + scrim) and the body
     (text) clearly separated regardless of what tones the painting
     happens to push through the scrim near the bottom of the visual.
     navy-700 reads as a deliberate horizontal rule against both zones. */
  border-top: 1px solid var(--navy-700);
  background: var(--navy-850);
}
.case-card-result {
  font-family: 'Montserrat', sans-serif;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--ink-50);
  line-height: 1.25;
  margin-bottom: 20px;
  flex: 1;
}
.case-card-meta {
  font-size: 13px;
  color: var(--ink-400);
  margin-bottom: 20px;
  line-height: 1.5;
}
.case-card-link {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--signal-500);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  transition: gap 300ms var(--ease-out-quart);
}
.case-card:hover .case-card-link { gap: 16px; }

/* =====================================================================
   SECTION 8 — FOUNDER QUOTE
   ===================================================================== */

/* Founder quote — dark editorial, warm yellow accent restricted to a single
   detail (the quote mark). Not a yellow moment — the brand-signature band is. */
.founder {
  background: var(--navy-950);
  padding: 160px 0;
  position: relative;
  overflow: hidden;
}
@media (max-width: 767px) { .founder { padding: 104px 0; } }

.founder-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 64px;
  align-items: center;
  position: relative;
  z-index: 2;
}
@media (min-width: 960px) {
  .founder-grid {
    grid-template-columns: 5fr 7fr;
    gap: 96px;
  }
}

.founder-photo {
  position: relative;
  aspect-ratio: 4 / 5;
  background: var(--navy-850);
  border: 1px solid var(--navy-800);
  overflow: hidden;
  max-width: 460px;
}
/* Real Martin photo — fills the 4:5 frame, slight top crop bias so the
   gaze doesn't sit dead-center under the bottom label strip. */
.founder-photo-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 30%;
  display: block;
}
/* Placeholder kept in stylesheet so the SVG fallback still works if/when
   we need a different role (or for the second founder slot in the
   future). Not currently referenced from homepage HTML. */
.founder-photo-placeholder {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at 50% 40%, var(--navy-800) 0%, var(--navy-900) 50%, var(--navy-950) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
}
.founder-photo-placeholder .brand-mark-large {
  width: 52%;
  opacity: 0.14;
  fill: var(--signal-500);
}
.founder-photo-label {
  position: absolute;
  bottom: 24px;
  left: 24px;
  right: 24px;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  font-family: 'Inter', system-ui, sans-serif;
}
.founder-photo-label .left-meta {
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-400);
}
.founder-photo-label .left-meta strong {
  display: block;
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  letter-spacing: -0.01em;
  text-transform: none;
  font-weight: 700;
  color: var(--ink-50);
  margin-bottom: 4px;
}
.founder-quote-wrap {
  position: relative;
}
.founder-quote-mark {
  position: absolute;
  top: -40px;
  left: -8px;
  font-family: 'Montserrat', sans-serif;
  font-size: 160px;
  line-height: 1;
  font-weight: 900;
  color: var(--signal-500);
  opacity: 0.14;
  pointer-events: none;
  user-select: none;
}
.founder-quote {
  font-family: 'Montserrat', sans-serif;
  font-size: var(--t-md);
  font-weight: var(--w-medium);
  line-height: 1.35;
  letter-spacing: -0.012em;
  color: var(--ink-50);
  margin-bottom: 40px;
  position: relative;
  z-index: 2;
  max-width: 28ch;
}
.founder-attribution {
  border-top: 1px solid var(--navy-700);
  padding-top: 24px;
  max-width: 400px;
}
.founder-attribution-name {
  font-family: 'Montserrat', sans-serif;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink-50);
  margin-bottom: 4px;
}
.founder-attribution-role {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 11px;
  color: var(--ink-400);
  letter-spacing: 0.05em;
  line-height: 1.6;
}

/* =====================================================================
   SECTION 9 — QUIET CTA
   ===================================================================== */

.cta {
  padding: 160px 0;
  background: var(--navy-900);
  text-align: center;
  position: relative;
  overflow: hidden;
  border-top: 1px solid var(--navy-800);
}
@media (max-width: 767px) { .cta { padding: 112px 0; } }


.cta-inner {
  position: relative;
  z-index: 2;
  max-width: 720px;
  margin: 0 auto;
}
.cta-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 32px;
  color: var(--signal-500);
}
.cta-eyebrow::before, .cta-eyebrow::after {
  content: '';
  width: 32px;
  height: 1px;
  background: currentColor;
}
.cta-title {
  font-family: 'Montserrat', sans-serif;
  font-size: var(--t-lg);
  font-weight: var(--w-black);
  letter-spacing: -0.032em;
  color: var(--ink-50);
  line-height: 1.02;
  margin-bottom: 32px;
  max-width: 18ch;
  margin-left: auto;
  margin-right: auto;
}
.cta-title .cta-accent {
  background-color: var(--signal-500);
  color: var(--slate-navy);
  padding: 0.04em 0.16em 0.1em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.cta-desc {
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--ink-200);
  margin-bottom: 44px;
}
.cta-button {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 18px 32px;
  background: var(--signal-500);
  color: var(--navy-950);
  font-family: 'Montserrat', sans-serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.02em;
  border: 1px solid var(--signal-500);
  transition: background 300ms var(--ease-out-quart), gap 300ms var(--ease-out-quart);
}
.cta-button:hover {
  background: var(--signal-600);
  gap: 20px;
}
.cta-button svg { width: 16px; height: 16px; }

/* =====================================================================
   FOOTER
   ===================================================================== */

.footer {
  background: var(--navy-950);
  padding: 96px 0 40px;
  border-top: 1px solid var(--navy-800);
}
.footer-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 64px;
  margin-bottom: 80px;
}
@media (min-width: 768px) {
  .footer-grid {
    /* Contact column widened to 2fr so the full legal name fits on one line. */
    grid-template-columns: 2fr 1fr 2fr 1fr;
    gap: 48px;
  }
}

.footer-brand .nav-logo { margin-bottom: 20px; }

.footer-col-title {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-600);
  margin-bottom: 20px;
  font-weight: 500;
}
.footer-col ul li { margin-bottom: 12px; }
.footer-col ul a {
  font-size: 14px;
  color: var(--ink-200);
  transition: color 200ms;
}
.footer-col ul a:hover { color: var(--ink-50); }

.footer-address {
  font-size: 13px;
  color: var(--ink-400);
  line-height: 1.8;
}
.footer-address strong {
  color: var(--ink-200);
  font-weight: 500;
  display: block;
  margin-bottom: 6px;
}

.footer-bottom {
  padding-top: 32px;
  border-top: 1px solid var(--navy-800);
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
}
.footer-copyright {
  font-size: 12px;
  color: var(--ink-600);
  font-family: 'Inter', system-ui, sans-serif;
  letter-spacing: 0.05em;
}
.footer-legal {
  display: flex;
  gap: 24px;
}
.footer-legal a {
  font-size: 12px;
  color: var(--ink-400);
  font-family: 'Inter', system-ui, sans-serif;
  letter-spacing: 0.05em;
}
.footer-legal a:hover { color: var(--ink-200); }

/* =====================================================================
   FOOTER BRAND STACK — compact rotating "Your [X] Partners" signature,
   sits in the footer brand column under the brand statement.
   ===================================================================== */
.footer-brand-stack {
  font-family: 'Montserrat', sans-serif;
  font-weight: var(--w-black);
  font-size: 26px;
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--slate-navy);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  margin-top: 28px;
  max-width: 36ch;
}
.footer-brand-stack br { display: none; }
.footer-brand-stack mark {
  background-color: var(--signal-500);
  color: var(--slate-navy);
  padding: 0.14em 0.2em 0.16em;
  border-radius: 0;
}
/* Rotating middle words — fade the text color, not the block opacity,
   so the yellow block never goes semi-transparent during the swap. */
.footer-brand-stack .rot.is-fading .rot-word {
  color: transparent;
  transition: color 280ms cubic-bezier(0.4, 0, 0.2, 1);
}


/* =====================================================================
   ANIMATIONS (page load choreography for hero)
   ===================================================================== */

@keyframes reveal-up {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes reveal-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes constellation-in {
  from { opacity: 0; transform: scale(0.96); }
  to   { opacity: 1; transform: scale(1); }
}

.reveal-hero {
  opacity: 0;
  animation: reveal-up 900ms var(--ease-out-expo) forwards;
}
.reveal-d1 { animation-delay: 100ms; }
.reveal-d2 { animation-delay: 280ms; }
.reveal-d3 { animation-delay: 480ms; }
.reveal-d4 { animation-delay: 680ms; }

.reveal-constellation {
  opacity: 0;
  animation: constellation-in 1800ms var(--ease-out-expo) 500ms forwards;
}

/* Constellation star twinkle */
@keyframes twinkle {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 1; }
}
.twinkle-1 { animation: twinkle 3000ms ease-in-out infinite; animation-delay: 1500ms; }
.twinkle-2 { animation: twinkle 4000ms ease-in-out infinite; animation-delay: 2200ms; }
.twinkle-3 { animation: twinkle 3500ms ease-in-out infinite; animation-delay: 1800ms; }


/* =====================================================================
   ARTICLE PAGES — bi.html, technology-transformation.html, process-transformation.html
   Long-form reading layout for capability deep-dives. Reuses tokens above.
   ===================================================================== */

.article {
  background: var(--navy-950);
  padding: 72px 0 112px;
  position: relative;
}
@media (max-width: 767px) {
  .article { padding: 56px 0 88px; }
}

.article-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-400);
  font-family: 'Inter', sans-serif;
  font-size: var(--t-tiny);
  font-weight: var(--w-medium);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin-bottom: 64px;
  transition: color 200ms var(--ease-out-quart),
              gap 300ms var(--ease-out-quart);
}
.article-back:hover { color: var(--ink-50); gap: 14px; }
.article-back--bottom {
  margin-top: 72px;
  margin-bottom: 0;
}

.article-hero {
  max-width: 860px;
  margin: 0 auto 80px;
}
.article-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 32px;
  color: var(--signal-500);
  font-family: 'Inter', sans-serif;
  font-size: var(--t-tiny);
  font-weight: var(--w-medium);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.article-eyebrow::before {
  content: '';
  width: 32px;
  height: 1px;
  background: currentColor;
}
.article-title {
  font-family: 'Montserrat', sans-serif;
  font-weight: var(--w-black);
  font-size: var(--t-xl);
  line-height: 1.0;
  letter-spacing: -0.035em;
  color: var(--ink-50);
  margin-bottom: 36px;
  max-width: 16ch;
  text-wrap: balance;
}
.article-lead {
  font-family: 'Inter', sans-serif;
  font-size: var(--t-md);
  font-weight: var(--w-reg);
  line-height: 1.4;
  color: var(--ink-100);
  max-width: 44ch;
}

.article-illustration {
  margin: 0 auto 96px;
  max-width: 960px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}
.article-illustration img {
  width: 100%;
  height: auto;
  display: block;
  border: 1px solid var(--navy-800);
  background: var(--ink-50);
}
.article-illustration figcaption {
  margin-top: 20px;
  font-family: 'Inter', sans-serif;
  font-size: var(--t-tiny);
  font-weight: var(--w-medium);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-400);
}

.article-body {
  max-width: 62ch;
  margin: 0 auto;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 18px;
  line-height: 1.75;
  color: var(--ink-200);
}
.article-body > p {
  margin-bottom: 24px;
}
.article-body > p:last-child {
  margin-bottom: 0;
}
.article-body strong {
  color: var(--ink-50);
  font-weight: var(--w-bold);
}
.article-body em {
  font-style: italic;
  color: var(--ink-100);
}
.article-body ul {
  margin: 0 0 28px;
  padding-left: 20px;
  list-style: none;
}
.article-body ul li {
  position: relative;
  margin-bottom: 16px;
  padding-left: 20px;
  line-height: 1.65;
}
.article-body ul li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.75em;
  width: 8px;
  height: 1px;
  background: var(--signal-500);
}
.article-body h2 {
  font-family: 'Montserrat', sans-serif;
  font-size: var(--t-md);
  font-weight: var(--w-black);
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ink-50);
  margin: 72px 0 24px;
  max-width: 24ch;
}

.article-close {
  max-width: 62ch;
  margin: 96px auto 0;
  padding-top: 56px;
  border-top: 1px solid var(--navy-800);
}
.article-close-quote {
  font-family: 'Montserrat', sans-serif;
  font-size: var(--t-md);
  font-weight: var(--w-bold);
  line-height: 1.25;
  letter-spacing: -0.015em;
  color: var(--ink-50);
  padding-left: 20px;
  border-left: 2px solid var(--signal-500);
  margin-bottom: 40px;
  max-width: 28ch;
}
.article-close .hero-cta {
  display: inline-flex;
}

@media (min-width: 768px) {
  .article-title { font-size: 72px; }
  .article-lead { font-size: 24px; }
  .article-body h2 { font-size: 30px; }
  .article-close-quote { font-size: 28px; }
}
