/* ============================================================================
   mobile-polish.css — mobile rhythm + density pass
   ----------------------------------------------------------------------------
   The theme's spacing.css ships FIXED desktop values with NO media queries, so
   a `pt-145` put 145px of padding on a 375px phone exactly like on a 27" display.
   Stacked across ~14 sections that turned the homepage into 21 screens of
   scrolling and is the main reason mobile felt "heavy".
   Here every spacing utility the site actually uses is scaled down: ~62% on
   tablet, ~44% on phones. Loaded LAST so it wins the cascade.
   ========================================================================== */

@media (max-width: 991px) {
  .pt-250{padding-top:156px}
  .pt-200{padding-top:124px}
  .pt-160{padding-top:100px}
  .mt-150{margin-top:92px}
  .pb-150{padding-bottom:92px}
  .pt-150{padding-top:92px}
  .pb-145{padding-bottom:88px}
  .pt-145{padding-top:88px}
  .pt-140{padding-top:88px}
  .pb-130{padding-bottom:80px}
  .pt-130{padding-top:80px}
  .mt-120{margin-top:76px}
  .pb-120{padding-bottom:76px}
  .pt-120{padding-top:76px}
  .pb-110{padding-bottom:68px}
  .pt-110{padding-top:68px}
  .mb-100{margin-bottom:64px}
  .pb-100{padding-bottom:64px}
  .pt-100{padding-top:64px}
  .pb-90{padding-bottom:56px}
  .pt-90{padding-top:56px}
  .pt-85{padding-top:52px}
  .mb-80{margin-bottom:48px}
  .pb-80{padding-bottom:48px}
  .pt-80{padding-top:48px}
  .mt-70{margin-top:44px}
  .pb-70{padding-bottom:44px}
  .pt-70{padding-top:44px}
  .mb-65{margin-bottom:40px}
  .pb-65{padding-bottom:40px}
  .pt-65{padding-top:40px}
  .mb-60{margin-bottom:36px}
  .mt-60{margin-top:36px}
  .pb-60{padding-bottom:36px}
  .pt-60{padding-top:36px}
  .mb-55{margin-bottom:36px}
  .pt-55{padding-top:36px}
  .mb-50{margin-bottom:32px}
  .mt-50{margin-top:32px}
  .pb-50{padding-bottom:32px}
  .pt-50{padding-top:32px}
  .pb-45{padding-bottom:32px}

  /* Headings: desktop clamps still resolve big on small screens */

  /* Comfortable tap targets — scoped to real controls so inline text links
     inside body copy keep flowing normally. */
  button, .at-btn, .nd-funnel-btn,
  .nd-qb-cta, .nd-qb-cta2, .nd-sticky-btn, .filter-btn {
    min-height: 44px;
  }
}

@media (max-width: 575px) {
  .pt-250{padding-top:112px}
  .pt-200{padding-top:88px}
  .pt-160{padding-top:72px}
  .mt-150{margin-top:64px}
  .pb-150{padding-bottom:64px}
  .pt-150{padding-top:64px}
  .pb-145{padding-bottom:64px}
  .pt-145{padding-top:64px}
  .pt-140{padding-top:60px}
  .pb-130{padding-bottom:56px}
  .pt-130{padding-top:56px}
  .mt-120{margin-top:52px}
  .pb-120{padding-bottom:52px}
  .pt-120{padding-top:52px}
  .pb-110{padding-bottom:48px}
  .pt-110{padding-top:48px}
  .mb-100{margin-bottom:44px}
  .pb-100{padding-bottom:44px}
  .pt-100{padding-top:44px}
  .pb-90{padding-bottom:40px}
  .pt-90{padding-top:40px}
  .pt-85{padding-top:36px}
  .mb-80{margin-bottom:36px}
  .pb-80{padding-bottom:36px}
  .pt-80{padding-top:36px}
  .mt-70{margin-top:32px}
  .pb-70{padding-bottom:32px}
  .pt-70{padding-top:32px}
  .mb-65{margin-bottom:28px}
  .pb-65{padding-bottom:28px}
  .pt-65{padding-top:28px}
  .mb-60{margin-bottom:28px}
  .mt-60{margin-top:28px}
  .pb-60{padding-bottom:28px}
  .pt-60{padding-top:28px}
  .mb-55{margin-bottom:24px}
  .pt-55{padding-top:24px}
  .mb-50{margin-bottom:24px}
  .mt-50{margin-top:24px}
  .pb-50{padding-bottom:24px}
  .pt-50{padding-top:24px}
  .pb-45{padding-bottom:24px}

  /* Edge gutters: 24px reads tight on a phone, 20px is the sweet spot */
  .container, .container-fluid { padding-left: 20px !important; padding-right: 20px !important; }
}

/* Never let a long word or wide element cause sideways scroll on a phone */
@media (max-width: 991px) {
  body { overflow-x: hidden; }
  h1, h2, h3, h4, p { overflow-wrap: break-word; }
}


/* ============================================================================
   Site-wide width + display-type caps (review: "full width and big font issue")
   The theme stretches sections to 2200px and inflates display type to
   120-290px on large monitors. Cap everything at a comfortable reading width
   and sane display sizes. Loaded last, so these win.
   ========================================================================== */
@media (min-width: 1400px) {
  /* Widths stay THEME-DEFAULT (review: capping read as "too compacted").
     Only oversized display type is tamed. */
  .fz-120, .fz-ds-1 { font-size: 88px !important; }
}

/* ============================================================================
   Touch targets (review: "many issues on mobile responsiveness")
   Measured on a 375px viewport: 26 interactive elements were under 40px tall,
   12 of them footer links at 28px. A tap target that small is hard to hit
   accurately and is flagged by Lighthouse/Search Console as "tap targets too
   close". Give links in the footer and nav a comfortable minimum height
   WITHOUT changing their type size or the layout around them — min-height on
   an inline-flex box grows the hit area, not the text.
   Scoped to phones so desktop hover layouts are untouched.
   ========================================================================== */
@media (max-width: 767.98px) {
  .at-footer-area .alt-footer-link-item ul li a,
  .at-footer-area .at-hero-social a,
  .at-footer-copyright-area a {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
  }
  /* The footer nav columns list one link per row; tighten the gap that the
     taller hit areas would otherwise introduce. */
  .at-footer-area .alt-footer-link-item ul li.mb-15 { margin-bottom: 2px !important; }
}



/* ============================================================================
   Offcanvas open state — added after the mobile audit.
   ----------------------------------------------------------------------------
   The floating header pill is position:fixed at z-index 999; main.css puts
   .at-offcanvas at z-index 997. At scroll-top on a phone the pill therefore
   painted ON TOP of the open menu and covered its close button (measured: the
   pill spans y 14-68, the close button y 40-84). The hamburger underneath could
   not close it either. Rather than fight the stacking order, the pill is hidden
   for as long as a menu is open, and page scroll is locked so a swipe moves the
   menu rather than the page behind it.
   MainLayout toggles body.nd-menu-open.
   ========================================================================== */
body.nd-menu-open .nd-fixed-header {
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(-140%) !important;
}
body.nd-menu-open {
  overflow: hidden;
  /* iOS Safari ignores overflow:hidden on <body> for touch scrolling. */
  touch-action: none;
}
/* The panel itself must still scroll, or tall menus become unreachable once the
   page behind it is locked. */
body.nd-menu-open .at-offcanvas,
body.nd-menu-open .at-offcanvas-2-wrapper {
  max-height: 100dvh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}

/* ============================================================================
   Card-stack flattening — added after the mobile audit.
   ----------------------------------------------------------------------------
   main.css stacks the capability cards with
     .scroll-section .item:not(:first-child){ position:absolute }
   so every card after the first sits ON TOP of the first, and only GSAP's
   yPercent tween separates them. Two consequences:

   1. PHONES. The pin ran on every viewport. Each .item is min-height:100vh and
      the scrub window is (cards x 50%), so a 4-card block measured a 2726px pin
      spacer around an 1102px section on a 375x812 phone — ~1600px of blank
      scroll on /services and all 7 /services-details/* pages. The pin is now
      gated to >=992px in ScrollSectionEffects.tsx.
   2. CRAWLERS. GlobalEffects returns null for bots, so the tween never runs and
      the absolute cards collapse onto each other — Google saw ONE card. The
      html.nd-bot class was already being set for exactly this, but no CSS ever
      defined it.

   Both cases need the same thing: undo the stacking and let the cards flow.
   ========================================================================== */
html.nd-bot .scroll-section .item:not(:first-child),
html.nd-bot .scroll-section .item,
html.nd-bot .scroll-section .item:first-child {
  position: relative !important;
  min-height: 0 !important;
  height: auto !important;
  transform: none !important;
  opacity: 1 !important;
}

@media (max-width: 991.98px) {
  .scroll-section .item:not(:first-child),
  .scroll-section .item,
  .scroll-section .item:first-child {
    position: relative !important;
    min-height: 0 !important;
    height: auto !important;
    transform: none !important;
    opacity: 1 !important;
  }
  /* The pin is off here, so the section must size to its content. */
  .section-fix,
  .scroll-section.vertical-section,
  .scroll-section .wrapper,
  .scroll-section .list {
    height: auto !important;
    min-height: 0 !important;
  }
  /* Cards were flush when they overlapped; they need rhythm once they flow. */
  .scroll-section .item + .item { margin-top: 20px; }
}

/* ============================================================================
   Mobile audit fixes — forms, tap targets, and a clipped address.
   ========================================================================== */

/* iOS Safari ZOOMS the whole page when a focused form control is under 16px, and it
   does not zoom back out on blur. The contact form's .nd-cs-input is 15px and the
   theme default for inputs is 14px, so tapping any field on an iPhone shifted the
   layout and pushed the submit button off-screen. 16px is the exact threshold. */
@media (max-width: 991.98px) {
  input[type="text"], input[type="email"], input[type="tel"], input[type="url"],
  input[type="search"], input[type="password"], input[type="number"],
  select, textarea, .nd-cs-input {
    font-size: 16px !important;
  }
  /* A control also has to be comfortably tappable, not just readable. */
  input:not([type="checkbox"]):not([type="radio"]), select, textarea, .nd-cs-input {
    min-height: 44px;
  }
  textarea, textarea.nd-cs-input { min-height: 96px; }
}

/* Nav rows in both offcanvas panels were 36px tall and vertically adjacent, and the
   hamburger's own hit area was the 24x16 SVG. Below 44px these are hard to hit and
   Search Console reports them as "tap targets too close together". */
@media (max-width: 1199.98px) {
  .at-offcanvas-menu nav a,
  .at-offcanvas-2-area .at-offcanvas-menu nav a {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  .at-offcanvas-menu nav li { position: relative; }
  /* The generated submenu chevron is its own control and needs its own target. */
  .at-offcanvas-menu button.at-menu-close {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .at-menu-bar, .at-header-sidebar-btn {
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  /* Social row in the panel: 19px tall links, below the 24px minimum. */
  .at-offcanvas-social__link { min-height: 44px; display: flex; align-items: center; }
}

/* The office address is marked .text-nowrap, but main.css kills every <br> under 768px
   (`br{display:none}`), so the two address lines join into one unbreakable string that
   overflows its column and gets clipped mid-word. Allow it to wrap on phones — the
   nowrap only exists to keep the line intact on desktop. */
@media (max-width: 991.98px) {
  .at-address-item h6.text-nowrap,
  .at-contact-info h6.text-nowrap,
  h6.text-nowrap { white-space: normal !important; }
}


/* The offcanvas close controls became real <button>s (they were <span role="button">
   with no key handler). Strip the UA button chrome so they look exactly as before. */
button.hamburger-close-btn,
button.close-btn.close-sidebar {
  background: transparent;
  border: 0;
  padding: 0;
  color: inherit;
  cursor: pointer;
  font: inherit;
}
.at-categories-empty { opacity: 0.75; margin: 8px 0 0; }

/* ============================================================================
   Desktop reading width.
   ----------------------------------------------------------------------------
   main.css sets `@media (min-width:1400px){ .container{ max-width:1750px } }`.
   The floating nav pill, though, is `min(1240px, calc(100% - 24px))`. So on a
   1920px screen the nav sat 1240px wide while everything beneath it ran 1750px
   — the content was visibly wider than the header framing it, body copy ran to
   ~150 characters a line, and the hero left a dead gap between the headline and
   the globe. Matching the content to the nav makes the page read as one column
   of a known width instead of stretching to fill whatever monitor it lands on.

   1280px (inner ~1256px after Bootstrap's 12px gutters) lines the content edges
   up with the 1240px nav. Explicit opt-ins (.container-2200 for full-bleed
   bands, .container-1136 for narrow prose) are deliberately left alone.
   ========================================================================== */
@media (min-width: 1400px) {
  .container { max-width: 1440px; }

  /* The homepage hero and the other index-8 sections wrap their content in
     `container-fluid` plus a marker class that was never given any CSS — so they
     ran the FULL viewport width. On a 1920px screen that pushed the headline to
     the far left and the globe to the far right with a dead gap between them,
     which is the "everything spanned" complaint. These marker classes sit on the
     INNER div, never on the <section>, so the full-bleed backgrounds behind them
     are untouched. .container-2200 is a deliberate full-bleed opt-in and is left
     alone. */
  .h8-container,
  .sec-3-home-8__container,
  .sec-6-home-8__container,
  .sec-7-home-8__container,
  .sec-8-home-8__container,
  .sec-9-home-8__container {
    max-width: 1440px;
    margin-left: auto;
    margin-right: auto;
  }
}

/* ============================================================================
   Per-frame scroll costs found while chasing the /services lag (2026-09-02).
   ========================================================================== */
/* .px-blur-bottom is a fixed, full-width, 80px-tall backdrop-filter strip mounted on
   every page. A fixed backdrop-filter re-samples and re-blurs everything behind it on
   every scrolled frame — a constant GPU tax on an otherwise cheap native scroll, paid
   on all ~460 pages for a subtle bottom-edge fade. Off until scrolling is judged
   fast; delete this rule to bring the fade back. */
.px-blur-bottom { display: none; }

/* ============================================================================
   UI sweep fixes (2026-09-02): phone gutter overhang + tap targets.
   ========================================================================== */
/* The 20px phone container gutter is narrower than a .g-5 row's 24px negative
   margin, so those rows overhung the viewport by 4px each side on /services,
   /portfolio and /pricing. A 40px gutter puts the row's negative margin at
   exactly -20px — flush with the container edge. */
@media (max-width: 575.98px) {
  .row.g-5 { --bs-gutter-x: 2.5rem; }
}
@media (max-width: 991.98px) {
  /* Blog card titles are the card's tap target but only 18px tall. Padding plus
     a matching negative margin grows the touch area without moving anything. */
  .blog-card__title-link { display: inline-block; padding: 12px 0; margin: -12px 0; }
  /* The earlier min-height:44px on .at-btn never applied to the text-link
     variants ("View all FAQs", "All articles") — they lay out inline, and
     min-height is inert on inline boxes. */
  a.at-btn { display: inline-flex; align-items: center; min-height: 44px; }
}


/* ============================================================================
   Design critique batch (2026-09-02): one typographic system.
   ========================================================================== */
/* Headlines: balance line breaks. (The italic accent phrase is retired — every <em>
   in a heading is now the two-tone drop from nd-system.css and wraps like any word.) */
.nd-svc-title, .nd-ben-title, .nd-ws-title, .nd-wdo-title, .nd-team-title, .nd-sw-title,
.nd-cs-title, .nd-pf-title, .nd-qb-h1, .nd-work h1 { text-wrap: balance; }

.at-btn.common-black.bg-transparent.p-0 > i { display: none; }


/* Section rhythm: one token (--nd-sec, owned by nd-system.css — the Plane
   clamp(64px, 8.3vw, 120px)). Utilities like pt-120/pb-145 gave 96-240px gaps. */
@media (min-width: 992px) {
  .nd-svc, .nd-logowall, .nd-sw, .nd-wdo, .nd-ben, .nd-ws, .nd-team, .nd-cs, .nd-pf-grid-wrap,
  .sec-2-services, .sec-2-about, .sec-4-services-details, .sec-3-about, .sec-4-about,
  .sec-2-archive-1, .alt-faq-area, .at-sec13-thumb { padding-block: var(--nd-sec); }
  /* Shell gutters for the containers OUTSIDE <main> — the floating header pill
     and the footer, which sit inside their own width caps and are measured
     against those, not against the content grid.
     The content containers inside <main> are no longer governed here: this rule
     resolved to 43.2px at 1440 and let the grid run 1354px wide, 122px past the
     spec's 1232 content column, while /work (which caps its own container at
     1232) sat at a different left edge from every other page. nd-system.css
     section 12 now owns `main .container` — spec 3's clamp(20px,4vw,56px)
     gutter with the 1232px cap — so this value is deliberately left alone
     rather than raised to 56px, which would have narrowed the nav pill's inner
     width by 25.6px on every page for no content benefit. */
  .container { padding-inline: clamp(24px, 3vw, 48px); }
}

/* The nav's "More" toggle is now a <button> (it was an <a href="#">). The theme's
   hover-swap label CSS is scoped to `>li>a`, so the button showed both label copies
   ("MoreMore"). Same rules, for the button. */
.at-main-menu>nav>ul>li>.nd-more-toggle .at-link-swap{ position:relative; display:inline-block; overflow:hidden; vertical-align:top; line-height:inherit; }
.at-main-menu>nav>ul>li>.nd-more-toggle .at-link-swap .text-1,
.at-main-menu>nav>ul>li>.nd-more-toggle .at-link-swap .text-2{ display:block; line-height:inherit; transition:transform .45s cubic-bezier(.5,1.5,.35,1); }
.at-main-menu>nav>ul>li>.nd-more-toggle .at-link-swap .text-1{ position:relative; }
.at-main-menu>nav>ul>li>.nd-more-toggle .at-link-swap .text-2{ position:absolute; top:0; left:0; right:0; transform:translateY(calc(100% + var(--link-desc-room, 0px))); }
.at-main-menu>nav>ul>li:hover>.nd-more-toggle .at-link-swap .text-1{ transform:translateY(calc(-100% - var(--link-desc-room, 0px))); }
.at-main-menu>nav>ul>li:hover>.nd-more-toggle .at-link-swap .text-2{ transform:translateY(0); }
.nd-fixed-header .at-main-menu .nd-more-toggle{ color:#101010; }
[data-bs-theme="dark"] .nd-fixed-header .at-main-menu .nd-more-toggle{ color:#fff; }

/* Service-detail capability cards: a static 2x2 grid instead of the pinned card stack.
   The stack pinned the page for four cards of ~40 words each, which the founder read
   as "empty, just an animation". .nd-no-stack also skips the GSAP pin. */
.nd-no-stack .scroll-section .wrapper,
.nd-no-stack .scroll-section .list{ height:auto !important; min-height:0 !important; }
.nd-no-stack .scroll-section .list{ display:grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap:16px; }
.nd-no-stack .scroll-section .item,
.nd-no-stack .scroll-section .item:first-child,
.nd-no-stack .scroll-section .item:not(:first-child){ position:relative !important; min-height:0 !important; height:auto !important; transform:none !important; opacity:1 !important; }
.nd-no-stack .scroll-section .item > .container{ height:100%; }
.nd-no-stack .scroll-section .item .rectangular{ display:none; }
@media (max-width: 767.98px){ .nd-no-stack .scroll-section .list{ grid-template-columns:1fr; } }

/* nd-no-stack cards: kill the double container padding so copy gets the width */
.nd-no-stack .scroll-section .item > .container{ padding:6px 10px !important; max-width:none; }
.nd-no-stack .scroll-section .item .p-md-5{ padding:26px 22px !important; }
.nd-no-stack .scroll-section .item h5{ font-size:clamp(19px,1.4vw,22px); margin-bottom:12px !important; }
.nd-no-stack .scroll-section .item p{ font-size:16px; line-height:1.55; }
@media (max-width:575px){ .nd-no-stack .scroll-section .list{ grid-template-columns:1fr; } }
