/* ============================================================
   NEXO — DESIGN TOKENS
   Single source of truth for the visual language. Loaded on
   every page immediately after styles.css, before page CSS.

   Nothing here touches the navbar or footer.
   ============================================================ */

:root {
  /* ---- radius scale ---- */
  --r-xs:  10px;
  --r-sm:  14px;
  --r-md:  18px;   /* default card */
  --r-lg:  24px;   /* feature card / media */
  --r-xl:  30px;   /* hero panels, CTA */
  --r-pill: 999px;

  /* ---- elevation scale ---- */
  --sh-1: 0 6px 18px -10px rgba(12,21,38,0.18);
  --sh-2: 0 14px 34px -18px rgba(12,21,38,0.22);
  --sh-3: 0 28px 60px -28px rgba(12,21,38,0.26);
  --sh-4: 0 46px 96px -40px rgba(12,21,38,0.34);
  --sh-blue:  0 22px 48px -18px rgba(0,70,255,0.42);
  --sh-blue-l:0 34px 72px -26px rgba(0,70,255,0.52);

  /* ---- spacing scale ---- */
  --s-1: 6px;   --s-2: 10px;  --s-3: 14px;  --s-4: 18px;
  --s-5: 24px;  --s-6: 32px;  --s-7: 44px;  --s-8: 60px;
  --sec-y:  clamp(56px, 6.4vw, 92px);   /* vertical section rhythm */
  --sec-x:  clamp(20px, 5vw, 48px);     /* page gutter */
  --gap:    clamp(14px, 1.7vw, 22px);   /* grid gap */
  --measure: 1200px;                    /* content max-width */
  --head-measure: 780px;                /* centred heading block */

  /* ---- type scale ---- */
  --t-h1:    clamp(32px, 4.6vw, 56px);
  --t-h2:    clamp(26px, 3.4vw, 42px);
  --t-h3:    clamp(18px, 1.5vw, 22px);
  --t-lead:  clamp(15px, 1.15vw, 17px);
  --t-body:  15px;
  --t-sm:    13.5px;
  --t-xs:    12.5px;
  --lh-tight: 1.14;
  --lh-body:  1.68;
  --ls-head: -1.1px;

  /* ---- motion ---- */
  --ease:      cubic-bezier(.2,.8,.2,1);
  --dur-fast:  .25s;
  --dur:       .4s;
  --dur-slow:  .7s;
}

/* ============================================================
   TYPOGRAPHY — one scale everywhere
   ============================================================ */
body { font-family: var(--font-body); font-size: var(--t-body); line-height: var(--lh-body); color: var(--text); }

h1, h2, h3, h4 { font-family: var(--font-head); letter-spacing: var(--ls-head); line-height: var(--lh-tight); }
main h1 { font-size: var(--t-h1); font-weight: 800; }
main h2 { font-size: var(--t-h2); font-weight: 800; }
main h3 { font-size: var(--t-h3); font-weight: 700; letter-spacing: -.3px; }
main p  { line-height: var(--lh-body); }
.lead, .ind-lead, .svx-lead { font-size: var(--t-lead); line-height: 1.72; color: var(--text-soft); }

/* ============================================================
   SECTION RHYTHM + ALIGNMENT
   Every band shares the same vertical rhythm and gutter, so
   section edges line up down the whole page.
   ============================================================ */
main > section,
.ind-sec,
.svx-sec { padding-top: var(--sec-y); padding-bottom: var(--sec-y); }

.ind-wrap,
.svx-inner,
.container,
.section-head,
.ind-head,
.svx-head { margin-left: auto; margin-right: auto; }

.ind-wrap, .container { max-width: var(--measure); padding-left: var(--sec-x); padding-right: var(--sec-x); }

/* consistent head block spacing */
.ind-head, .svx-head, .section-head { margin-bottom: clamp(28px, 3.2vw, 46px); }

/* ============================================================
   CARDS — one card language
   ============================================================ */
.ind-chal-card, .ind-why-card, .ci-card, .ind-stat,
.card, .acc-item {
  border-radius: var(--r-md);
  box-shadow: var(--sh-2);
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              border-color var(--dur-fast) ease;
}
.ind-chal-card:hover, .ind-why-card:hover, .ci-card:hover {
  transform: translateY(-8px);
  box-shadow: var(--sh-blue);
  border-color: rgba(0,70,255,0.30);
}

/* media + feature panels share the larger radius */
.ind-ph, .ind-area-card, .ind-serv-row.panel, .c-item { border-radius: var(--r-lg); }
.ind-final-card, .cta-strip, .svx-final { border-radius: var(--r-xl); }

/* uniform icon tiles */
.ind-chal-ic, .ind-why-ic, .ind-serv-ic, .ind-area-ic, .ci-ph-ic, .mq-ic {
  border-radius: var(--r-sm);
  transition: transform var(--dur) var(--ease), background var(--dur-fast) ease, color var(--dur-fast) ease;
}

/* ============================================================
   BUTTONS — one button language
   ============================================================ */
.btn, .ind-btn, .svx-btn, .nav-cta, .bc-viewall, .foot-cta, .ci-cta, .ind-sticky-cta {
  border-radius: var(--r-pill);
  font-family: var(--font-head);
  font-weight: 600;
  letter-spacing: .1px;
  transition: transform var(--dur-fast) var(--ease),
              background var(--dur-fast) ease,
              box-shadow var(--dur-fast) ease,
              color var(--dur-fast) ease;
}
.btn:hover, .ind-btn:hover, .svx-btn:hover, .bc-viewall:hover, .foot-cta:hover { transform: translateY(-3px); }
.btn:active, .ind-btn:active, .svx-btn:active { transform: translateY(-1px); }

/* consistent focus ring sitewide */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}

/* ============================================================
   IMAGES — never distort, never overflow
   ============================================================ */
img { max-width: 100%; }
.ind-ph img, .ci-art img, .c-img, .bc-image img { object-fit: cover; }

/* real photo dropped into a slot fills it edge to edge */
.ind-ph.has-img { background: none; aspect-ratio: 4 / 3; min-height: 0; }
.ind-ph.has-img::before { display: none; }
.ind-ph.has-img img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border-radius: inherit;
  transition: transform 1.1s var(--ease);
}
.ind-ph.has-img:hover img { transform: scale(1.06); }

/* ============================================================
   SCROLL REVEAL — shared timing
   ============================================================ */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--dur-slow) ease, transform var(--dur-slow) var(--ease);
  will-change: opacity, transform;
}
.reveal.left  { transform: translateX(-30px); }
.reveal.right { transform: translateX(30px); }
.reveal.zoom  { transform: scale(.95); }
.reveal.in    { opacity: 1; transform: none; }

/* ============================================================
   RESPONSIVE GUARDS
   ============================================================ */
@media (max-width: 900px) {
  :root { --sec-y: clamp(44px, 8vw, 64px); }
}
@media (max-width: 640px) {
  :root { --sec-y: 40px; --gap: 14px; }
  main h1 { font-size: clamp(28px, 8vw, 36px); }
  main h2 { font-size: clamp(23px, 6.4vw, 30px); }
}

/* NOTE: do not put overflow on html/body. It makes them a scroll
   container and silently breaks position:sticky everywhere (it broke
   the coverage slider). The cross-page audit shows scrollWidth ==
   clientWidth on every page, so no sideways-scroll guard is needed. */

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1 !important; transform: none !important; transition: none !important; }
  .ind-ph.has-img img { transition: none; }
}

/* ============================================================
   ALIGNMENT FIX
   Audit showed centred heading blocks resolving to three
   different widths (265 / 245 / 239px left edge at 1269px), so
   section content did not line up between pages. One measure
   for headings, one gutter for inner wrappers.
   ============================================================ */
.ind-head, .svx-head, .section-head, .contact-head, .svc-hub-head {
  max-width: var(--head-measure);
  margin-left: auto;
  margin-right: auto;
}

/* .svx-inner used a 64px gutter while .ind-wrap/.container used 48px */
.svx-inner {
  max-width: var(--measure);
  padding-left: var(--sec-x);
  padding-right: var(--sec-x);
}

/* ============================================================
   STICKY FIX — the actual cause of the huge blank band
   styles.css sets `overflow-x: hidden` on html and body, and
   `overflow-x: clip` on .section. Each makes a scroll container,
   which disables position:sticky for everything inside. The
   showcase stage therefore scrolled away instead of pinning,
   leaving the rest of its runway empty.

   Measured: no page on this site overflows horizontally
   (scrollWidth == clientWidth everywhere), so these guards were
   never doing anything except breaking sticky.
   ============================================================ */
html, body { overflow-x: visible; }
.section { overflow-x: visible; }
/* keep the guard only where it is actually needed: the marquee row
   and the old carousel genuinely scroll sideways */
.svx-marq, .lw-viewport, .ind-carousel { overflow-x: clip; }

/* ============================================================
   NAVBAR STACKING — dropdown was unclickable
   .nav-wrap had z-index:50, which creates a stacking context.
   The dd-panel's z-index:70 only competes INSIDE that context,
   so the whole dropdown sat at 50 against the page and hero
   content painted over it — elementFromPoint on a dropdown item
   returned the hero <h1>, so clicks never reached the link.
   200 keeps the nav above page content while staying below the
   service-detail modal (z-index 300).
   ============================================================ */
.nav-wrap { z-index: 200; }

/* The .open state did not reveal the Services mega panel — measured
   visibility:hidden with .open applied. Desktop hover masked it, but the
   mobile .dd-toggle relies on .open, so that dropdown could not be opened
   by click at all. Make .open explicit for both panel types. */
.has-dd.open > .dd-panel,
.has-dd.open > .dd-mega {
  opacity: 1 !important;
  visibility: visible !important;
  pointer-events: auto !important;
  transition-delay: 0s !important;
}

/* ============================================================
   MOBILE — measured fixes (audited at 390px)
   ============================================================ */

/* ROOT CAUSE of sideways scroll on about / city-* / industries:
   .reveal.left/.right sit at translateX(±30px) before they animate
   in. On a narrow screen a full-width block + 30px runs past the
   viewport, so the page scrolls sideways until the animation fires.
   On mobile, reveal vertically instead — same effect, no overflow. */
@media (max-width: 900px) {
  .reveal.left,
  .reveal.right { transform: translateY(24px); }
}

/* Ambient blur orbs are decorative and frequently overrun the
   viewport (about.html measured 508px wide vs a 379px screen).
   They also cost real paint time on phones. */
@media (max-width: 900px) {
  .orb, .orb-a, .orb-b, .orb-c,
  .svx-bg .o1, .svx-bg .o2, .prob-bg span { display: none; }
}

@media (max-width: 640px) {
  /* comfortable tap targets (Apple/Google guidance is 44px) */
  .nav-links > li > a,
  .footer ul a,
  .dd-item,
  .loc-card,
  .cml-card { min-height: 44px; }

  .foot-socials a,
  .tb-soc { width: 40px; height: 40px; }

  /* buttons go full width so they are easy to hit and line up */
  .btn, .ind-btn, .svx-btn, .city-btn {
    width: 100%;
    justify-content: center;
    min-height: 48px;
  }
  .city-cta-row, .cta-actions, .ind-cta-row, .svx-cta-row, .loc-cta-row {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }

  /* stop long words/URLs forcing horizontal scroll */
  h1, h2, h3, p, a { overflow-wrap: anywhere; }

  /* tighten oversized display type on small screens */
  .city-hero h1 { font-size: clamp(28px, 8.4vw, 38px); }
  .city-hero .lead { font-size: 15px; }
  .city-hero-stats { gap: 8px; }
  .city-hero-stat { flex: 1 1 calc(50% - 4px); padding: 12px 14px; }
  .city-hero-stat b { font-size: 19px; }
}

/* media never forces the page wider than the screen */
img, video, svg, iframe, table { max-width: 100%; }
