/* nx-pages.css — shared design system for all subpages
   Uses the homepage's CSS variable tokens for perfect visual parity. */

/* === SECTION BASE === */
/* All section patterns get consistent spacing.
   Generic tag/utility selectors are scoped to .main-wrapper so they can never
   reach the injected nav/footer chrome (which are siblings of .main-wrapper). */
/* DO NOT reintroduce [class*="..."] selectors here.
   A substring selector like [class*="nx-faq-page-"] matches EVERY descendant
   whose class starts with that stem — on faq/index.html that was 53 elements
   (badges, spans, answer wraps) instead of the 2 real sections. Each one got
   7rem/2.5rem of padding, producing page-long vertical voids, and it turned
   the 2rem square .nx-faq-page-num into a ~7rem x 16rem box that
   border-radius:50% then rendered as a tall ellipse. 955 elements across
   29 pages were affected. `.main-wrapper section` already covers every real
   section, which is why the substring selectors were pure liability. */
.main-wrapper section,
.main-wrapper .section,
.sol-hero,
.sol-deepdive,
.sol-benefits,
.sol-how,
.sol-social,
.sol-cta,
.cta-section,
.content-section,
.nx-cta-fan {
  padding: var(--_sizes---section-padding-large, 7rem) var(--_sizes---padding-global, 2.5rem);
  position: relative;
}

/* Hero top padding clears the fixed nav. Exact classes only — the old
   [class*="nx-faq-page-hero"] form also matched .nx-faq-page-hero-inner,
   applying this 12rem padding-top a second time to the inner block. */
/* This list is exhaustive and was derived by parsing the first child of
   .main-wrapper on all 45 pages that load this file. Blog POSTS are the one
   exception: their hero is a <div class="blog-hero">, not a section, and it
   carries its own padding rule further down — it is deliberately absent here. */
.nx-about-hero,
.nx-price-hero-section,
.nx-contact-hero,
.nx-faq-page-hero,
.sol-hero,
.nx-blog-hero,
.nx-vid-hero,
.nx-legal-hero,
.nx-aff-hero,
.nx-uni-hero,
.tool-hero {
  padding-top: calc(var(--_sizes---section-padding-large, 7rem) + 5rem);
  padding-bottom: var(--_sizes---section-padding-large, 7rem);
}

/* === CONTAINERS === */
.main-wrapper .container-inner,
.main-wrapper .container,
[class*="nx-about-"] > .container-inner,
[class*="nx-price-"] > .container-inner,
[class*="sol-"] > .container,
.content-container,
.blog-article {
  width: 100%;
  max-width: 80rem;
  margin-left: auto;
  margin-right: auto;
  padding: 0;
  position: relative;
}

/* === HEADINGS === */
[class*="nx-about-"] h1,
[class*="nx-price-"] h1,
[class*="nx-contact-"] h1,
[class*="nx-faq-page-"] h1,
[class*="sol-"] h1,
[class*="blog-hero"] h1,
.blog-hero__title,
[class*="nx-vid-"] h1,
[class*="nx-legal-"] h1,
[class*="nx-aff-"] h1,
[class*="nx-uni-"] h1,
.tool-hero__heading {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-size: var(--_typography---h1--font-size, 3.5rem);
  line-height: 1.15;
  margin: 0 0 1.25rem;
  color: var(--_color-theme---ink, #0B0B1A);
}

[class*="nx-about-"] h2,
[class*="nx-price-"] h2,
[class*="nx-contact-"] h2,
[class*="nx-faq-page-"] h2,
[class*="sol-"] h2,
[class*="blog-"] h2,
[class*="nx-vid-"] h2,
[class*="nx-legal-"] h2,
[class*="nx-aff-"] h2,
[class*="nx-uni-"] h2,
.content-section__heading,
.cta-card__heading,
.nx-faq-page-still-title,
.nx-aff-steps-heading,
.nx-aff-faq-heading,
.nx-uni-courses-heading,
.section-header h2 {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-size: var(--_typography---h2--font-size, 3rem);
  line-height: 1.2;
  margin: 0 0 1.25rem;
  color: var(--_color-theme---ink, #0B0B1A);
}

[class*="nx-about-"] h3,
[class*="nx-price-"] h3,
[class*="sol-"] h3,
[class*="blog-"] h3,
[class*="nx-vid-"] h3,
[class*="nx-aff-"] h3,
[class*="nx-uni-"] h3,
.step-card__title,
.nx-uni-course-card h3 {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  letter-spacing: -0.02em;
  font-size: var(--_typography---h3--font-size, 2.5rem);
  line-height: 1.25;
  margin: 0 0 0.75rem;
  color: var(--_color-theme---ink, #0B0B1A);
}

/* === PARAGRAPHS === */
[class*="nx-about-"] p,
[class*="nx-price-"] p,
[class*="nx-contact-"] p,
[class*="nx-faq-page-"] p,
[class*="sol-"] p,
[class*="blog-"] p,
[class*="nx-vid-"] p,
[class*="nx-legal-"] p,
[class*="nx-aff-"] p,
[class*="nx-uni-"] p,
.cta-card__text,
.nx-faq-page-still-text,
.tool-hero__subtitle,
.content-section__text {
  font-family: 'Inter', sans-serif;
  font-size: var(--_typography---body--font-size, 1rem);
  line-height: 1.6;
  color: var(--shade--60, #0009);
  margin: 0 0 1rem;
}

/* === FLOW SPACING BASELINE ===
   WHY THIS EXISTS. The vendored Webflow sheet globally zeroes text margins:
   `h1,...,h6 { margin-top: 0; margin-bottom: 0 }` and `p { margin-bottom: 0 }`.
   Every bit of vertical rhythm on the site is therefore a RESTORATION on top
   of that reset. The HEADINGS/PARAGRAPHS blocks above restore it via an
   allowlist of ancestor substrings ([class*="nx-price-"] and friends), which
   fails OPEN: any container not on the list silently renders with a 0px gap.
   Real casualties found 2026-08-02 -- `.nx-pricing-cta` does NOT contain the
   stem "nx-price-", and `.nx-comparison-heading`, `.nx-vid-card-body`,
   `.blog-author-card__info`, `.nx-contact-detail-text` matched nothing at all.
   42 heading+paragraph pairs across 20 pages were butted together.

   The homepage was immune only because each of its hand-authored sections
   ships its own inline <style> block (e.g. `.nx-crew-copy p{margin:16px auto 0}`),
   so it never depended on the allowlist.

   This rule makes the system fail CLOSED instead: spacing is the default and
   components opt out, rather than spacing being opt-in via a list somebody
   must remember to extend.

   SPECIFICITY, deliberately (0,0,2):
     :where(...)   contributes 0
     :is(h1,h2)    contributes (0,0,1)
     :has(+ p)     contributes (0,0,1)
   That is exactly one notch above the bare `h4` reset (0,0,1) it must beat,
   and below every class-based component rule (0,1,x) -- so anything that
   states an opinion still wins and deliberate tight pairings survive
   (e.g. `.nx-about-stat h3` keeps its 0.25rem).

   Why margin-bottom on the heading and not margin-top on the paragraph: the
   PARAGRAPHS block above uses the shorthand `margin: 0 0 1rem`, which pins
   margin-top to 0 at (0,1,1). No (0,0,x) rule can outrank that.

   Why :has(+ p): a heading with no paragraph after it gains nothing, so this
   can never add a stray trailing gap inside a card or flex column. */
:where(.main-wrapper) :is(h1, h2):has(+ p) {
  margin-bottom: 1.25rem;
}

:where(.main-wrapper) :is(h3):has(+ p) {
  margin-bottom: 0.75rem;
}

:where(.main-wrapper) :is(h4, h5, h6):has(+ p) {
  margin-bottom: 0.5rem;
}

/* Sole exception site-wide, found by measuring every pair rather than guessing:
   .nx-test-left is a flex parent, so margins ADD to the gap instead of
   collapsing, and its paragraph already supplies margin-top:16px via
   .nx-test-sub. Without this the homepage testimonial gap would go 16px -> 32px.
   (0,1,1) beats the baseline above. */
.nx-test-left h2 {
  margin-bottom: 0;
}

/* === EYEBROWS === */
/* Exact classes. The substring forms also matched every *-eyebrow-dot child,
   handing the 6px dot a pill border and 0.375rem/1rem of padding; it only
   looked right because the dot rule below happens to reset padding+border.
   .nx-vid-pill and .nx-blog-eyebrow are added here: no selector in the old
   list reached them, so the video pages and the blog index rendered their
   eyebrow as unstyled inline text. */
.nx-about-eyebrow,
.nx-price-hero-eyebrow,
.nx-contact-eyebrow,
.nx-faq-page-eyebrow,
.sol-eyebrow,
.blog-hero__pill,
.nx-aff-eyebrow,
.nx-uni-eyebrow,
.nx-blog-eyebrow,
.nx-vid-pill,
.tool-hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background-color: var(--neutral--white, #fff);
  border: 1px solid var(--shade--10, #0000001a);
  border-radius: 100vw;
  padding: 0.375rem 1rem;
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--shade--60, #0009);
  margin-bottom: 1rem;
  text-decoration: none;
  white-space: nowrap;
}

.nx-about-eyebrow-dot,
.nx-contact-eyebrow-dot,
.nx-faq-page-eyebrow-dot,
.nx-vid-pill-dot,
.nx-aff-eyebrow-dot,
.nx-uni-eyebrow-dot,
.nx-blog-eyebrow-dot,
.nx-price-hero-eyebrow-dot {
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background-color: var(--_color-theme---1, #2C6BE0);
  display: inline-block;
  flex-shrink: 0;
  padding: 0;
  border: none;
}

/* === BUTTONS (scoped to .main-wrapper to avoid nav/footer conflicts) ===
   These rules style the hand-authored "flat" buttons only: an <a class="button-wrap">
   wrapping a <div class="button">, where the wrap IS the button surface.

   They must NOT touch real Webflow button components. Those nest a
   .button-bg-wrap layer and get their geometry/colour from the vendored shared
   stylesheet, where every variant is written as .button-wrap:where(.w-variant-…).
   :where() carries ZERO specificity, so any rule here silently outranks it —
   which repainted the white hero CTA indigo and, worse, replaced the wrap's
   `padding: 1px` (it is a 1px gradient border ring) with 0.875rem/1.75rem,
   ballooning the ring while `padding:0 !important` collapsed the inner button.

   :has(.button-bg-wrap) is the structural tell that separates the two forms.
   Do not remove these guards — see the 991px/background-image incident too. */
.main-wrapper .button-wrap:not(:has(.button-bg-wrap)),
[class*="nx-price-card-cta"],
[class*="nx-contact-submit"],
[class*="nx-faq-page-contact-btn"],
.sol-cta-actions .button-wrap:not(:has(.button-bg-wrap)),
.blog-cta .button-wrap:not(:has(.button-bg-wrap)),
.cta-btn-group .button-wrap:not(:has(.button-bg-wrap)) {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background-image: linear-gradient(180deg, var(--_color-theme---light, #6e9cf9), var(--_color-theme---1, #2C6BE0));
  border-radius: 2rem;
  padding: 0.875rem 1.75rem;
  font-family: 'Inter', sans-serif;
  font-size: 1rem;
  font-weight: 500;
  color: #fff;
  text-decoration: none;
  transition: opacity 0.2s;
  cursor: pointer;
  border: none;
  width: auto;
}

/* Prevent inner .button from adding a second border when nested inside .button-wrap.
   Guarded: on a real Webflow component the inner .button owns the height, padding,
   overflow:hidden and stacking that the .button-bg layers paint into — zeroing it
   collapses the button. */
.main-wrapper .button-wrap:not(:has(.button-bg-wrap)) .button {
  border: none !important;
  background: none !important;
  padding: 0 !important;
  color: inherit !important;
  width: auto !important;
  height: auto !important;
}

@media (max-width: 991px) {
  /* NOTE: no `background-image: none` here — it once made 34 CTAs invisible,
     since the colour lives entirely in the wrap's gradient. Also guarded against
     Webflow components, which already size themselves via `width: stretch`. */
  .main-wrapper .button-wrap:not(:has(.button-bg-wrap)),
  [class*="nx-price-card-cta"],
  [class*="nx-contact-submit"],
  [class*="nx-faq-page-contact-btn"],
  .sol-cta-actions .button-wrap:not(:has(.button-bg-wrap)),
  .blog-cta .button-wrap:not(:has(.button-bg-wrap)),
  .cta-btn-group .button-wrap:not(:has(.button-bg-wrap)) {
    display: flex;
    width: 100%;
    justify-content: center;
  }
}

.main-wrapper .button-wrap:not(:has(.button-bg-wrap)):hover,
[class*="nx-price-card-cta"]:hover,
[class*="nx-contact-submit"]:hover {
  opacity: 0.9;
}

.main-wrapper .button-wrap.button--white,
.main-wrapper .button-wrap.button--ghost,
.main-wrapper .button.button--white,
.main-wrapper .button.button--ghost {
  background: var(--neutral--white, #fff);
  color: var(--_color-theme---ink, #0B0B1A);
  border: 1px solid var(--shade--10, #0000001a);
}

.main-wrapper .button-wrap.button--indigo,
.main-wrapper .button.button--indigo {
  background-image: linear-gradient(180deg, var(--_color-theme---light, #6e9cf9), var(--_color-theme---1, #2C6BE0));
  color: #fff;
  border: none;
}

/* Footer/nav chrome intentionally NOT styled here — the injected nav & footer
   must render identically to the homepage, which loads only the shared core
   CSS. Any rule targeting .footer_component / .mega-nav is deliberately omitted. */

/* === CARDS === */
/* Exact classes: [class*="nx-price-card"] also matched -head, -icon, -name,
   -price, -desc, -features, -cta, plus the .nx-price-cards-section wrapper and
   .nx-price-cards-grid — giving every inner text node its own white box,
   1px border, 1.75rem radius and 2rem of padding. */
.nx-price-card,
.nx-about-value-card,
.sol-benefit-card,
.tool-card,
.step-card,
.nx-vid-card,
.nx-vid-cta-box,
.cta-card,
.nx-aff-step-card,
.nx-uni-course-card,
.blog-related__card {
  background: var(--neutral--white, #fff);
  border: 1px solid var(--shade--10, #0000001a);
  border-radius: 1.75rem;
  padding: 2rem;
  transition: box-shadow 0.2s;
}

.nx-about-value-card:hover,
.sol-benefit-card:hover,
.tool-card:hover,
.step-card:hover,
.nx-vid-card:hover,
.nx-aff-step-card:hover,
.nx-uni-course-card:hover,
.blog-related__card:hover {
  box-shadow: 0 4px 24px rgba(0,0,0,0.06);
}

/* Pricing card featured */
.nx-price-card.featured,
.nx-price-card--featured {
  background-image: linear-gradient(180deg, var(--_color-theme---light, #6e9cf9), var(--_color-theme---1, #2C6BE0));
  color: #fff;
}

.nx-price-card.featured h3,
.nx-price-card.featured p,
.nx-price-card--featured h3,
.nx-price-card--featured p {
  color: #fff;
}

/* === GRIDS === */
[class*="nx-about-values-grid"],
[class*="nx-price-cards-grid"],
[class*="sol-benefits-grid"],
[class*="nx-aff-steps-grid"],
[class*="nx-uni-courses-grid"],
.nx-vid-related-grid,
.blog-related__grid,
.steps-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 1.5rem;
}

/* === HERO SECTIONS === */
[class*="nx-about-hero-inner"],
[class*="nx-price-hero-inner"],
[class*="nx-contact-hero-inner"],
[class*="nx-faq-page-hero-inner"],
[class*="nx-aff-hero-inner"],
[class*="nx-uni-hero-inner"],
[class*="nx-vid-hero-inner"],
[class*="nx-legal-hero-inner"] {
  text-align: center;
  max-width: 48rem;
  margin: 0 auto;
}

/* === TWO-COLUMN LAYOUTS === */
/* NOTE: sol-deepdive is deliberately NOT in this list. [class*="sol-deepdive"]
   also matches .sol-deepdive-text and .sol-deepdive-visual, which turned all
   three into 2-col grids and halved the layout twice. See the dedicated
   "Deep dive: two-column" block below. */
/* The grid must sit on the element whose CHILDREN are the two columns.
   These sections each wrap their columns in a single .container-inner, so
   putting the grid on the section itself produced a 2-col grid with exactly
   one item — the columns stacked as ordinary blocks. Target the wrapper.
   .content-section is excluded: its .content-container holds a normal
   single-column article flow, not two columns. */
/* minmax(0, 1fr) rather than 1fr: a bare 1fr track has an implicit
   min-width of min-content, so a long unbroken string (a URL in an FAQ
   answer, a wide code span) forces the track wider than half the row and
   pushes the second column off-canvas. minmax(0, …) lets it shrink. */
.nx-contact-body > .container-inner,
.nx-faq-page-body > .container-inner,
.nx-aff-details > .container-inner > .nx-aff-details-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 3rem;
  align-items: start;
}

@media (max-width: 767px) {
  .nx-contact-body > .container-inner,
  .nx-faq-page-body > .container-inner,
  .nx-aff-details > .container-inner > .nx-aff-details-grid {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
}

/* === STATS === */
[class*="nx-about-stats-grid"],
[class*="nx-aff-details-stats"] {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

/* Exact: [class*="nx-about-stat"] also matched .nx-about-stats (the section)
   and .nx-about-stats-grid, adding 1.5rem padding to both wrappers. */
.nx-about-stat,
.nx-aff-detail-stat {
  text-align: center;
  padding: 1.5rem;
}

/* === MISSION / DEEP DIVE === */
[class*="nx-about-mission-list"],
[class*="nx-aff-benefits-list"] {
  list-style: none;
  padding: 0;
  margin: 0;
}

[class*="nx-about-mission-list"] li,
[class*="nx-aff-benefits-list"] li {
  font-family: 'Inter', sans-serif;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--shade--60, #0009);
  padding: 0.5rem 0 0.5rem 1.5rem;
  position: relative;
}

[class*="nx-about-mission-list"] li::before,
[class*="nx-aff-benefits-list"] li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.85rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background-color: var(--_color-theme---1, #2C6BE0);
}

/* === STEPS / NUMBERED === */
/* .sol-step only — [class*="sol-step"] also matched .sol-steps (the grid) and
   .sol-step-num (the circle), forcing flex + gap + margin onto both. */
/* .nx-aff-step-card, NOT .nx-aff-step — the latter does not exist in any
   markup, so the old substring form was only ever reaching the card by
   accident, while also forcing display:flex onto .nx-aff-steps-grid and
   overriding the display:grid it gets from the GRIDS block above. */
.sol-step,
.nx-aff-step-card,
/* A step card is a cell in a three-column grid, not a row.
   ────────────────────────────────────────────────────────
   This rule made it display:flex in the row direction, which is the layout the
   vertical step lists want — .sol-step and .nx-aff-step-card, which have their
   own rules and do not need this one. .step-card appears only inside
   .steps-grid, on the six free-tools pages, three to a row of about 380px. Laid
   out as a row, its icon, badge, title and description were dealt across that
   width: the title broke over three lines and the description was squeezed into
   a column too narrow to hold it, clipping mid-word.

   It stacks now, which is what the card style forty rules up always assumed. */
.step-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
  margin-bottom: 0;
}

.sol-step:last-child,
.nx-aff-step-card:last-child,
.step-card:last-child {
  margin-bottom: 0;
}

.nx-aff-step-num {
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background-color: var(--_color-theme---1, #2C6BE0);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 1rem;
}

/* Its content is "Step 1", not "1". A 40px circle cannot hold six characters
   and a space, so the text sat outside its own badge. A pill can. */
.step-card__number {
  display: inline-flex;
  align-items: center;
  border-radius: 100vw;
  padding: 0.25rem 0.7rem;
  background: var(--accent-wash, #EEF4FE);
  color: var(--_color-theme---1, #2C6BE0);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* === FAQ (ACCORDION) === */
[class*="nx-faq-page-item"],
[class*="nx-aff-faq-item"] {
  border-bottom: 1px solid var(--shade--10, #0000001a);
  padding: 1rem 0;
}

[class*="nx-faq-page-q"],
[class*="nx-aff-faq-heading"] {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 1.125rem;
  color: var(--_color-theme---ink, #0B0B1A);
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 0;
}

/* Exact .nx-faq-page-answer — the substring form also matched
   .nx-faq-page-answer-wrap, whose collapse animation relies on 0fr grid rows;
   giving it 0.5rem of block padding left a visible gap when closed.
   .nx-aff-faq-item p, not [class*="nx-aff-faq"] p, so the rule cannot reach
   paragraphs in the .nx-aff-faq section heading or list wrapper. */
.nx-faq-page-answer,
.nx-aff-faq-item p {
  font-family: 'Inter', sans-serif;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--shade--60, #0009);
  padding: 0.5rem 0;
}

/* === BLOG SPECIFIC === */
.blog-hero {
  position: relative;
  min-height: 20rem;
  display: flex;
  align-items: flex-end;
  padding: 2rem;
}

.blog-hero__content {
  position: relative;
  z-index: 2;
  max-width: 48rem;
}

.blog-hero__title {
  color: #fff;
  margin-bottom: 0.5rem;
}

.blog-hero__meta {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  color: rgba(255,255,255,0.75);
}

.blog-article {
  padding: 3rem var(--_sizes---padding-global, 2.5rem);
  max-width: 48rem;
}

.blog-article h2 {
  margin-top: 2.5rem;
}

.blog-article blockquote {
  border-left: 3px solid var(--_color-theme---1, #2C6BE0);
  padding-left: 1.5rem;
  margin: 1.5rem 0;
  font-style: italic;
  color: var(--shade--60, #0009);
}

.blog-author-card {
  max-width: 48rem;
  margin: 2rem auto;
  padding: 1.5rem;
  display: flex;
  gap: 1rem;
  align-items: center;
  background: var(--neutral--white, #fff);
  border: 1px solid var(--shade--10, #0000001a);
  border-radius: 1rem;
}

/* === VIDEO SPECIFIC === */
.nx-vid-player-wrap {
  position: relative;
  border-radius: 1.75rem;
  overflow: hidden;
  background: #000;
}

.nx-vid-player-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.nx-vid-play-btn {
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  display: flex;
  align-items: center;
  justify-content: center;
}

.nx-vid-chapter-item {
  display: flex;
  gap: 1rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--shade--10, #0000001a);
  cursor: pointer;
}

.nx-vid-chapter-item:last-child {
  border-bottom: none;
}

/* === FREE TOOLS SPECIFIC === */
.tool-card {
  max-width: 36rem;
  margin: 2rem auto;
}

.tool-input-group {
  margin-bottom: 1rem;
}

.tool-input-group label {
  display: block;
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--shade--60, #0009);
  margin-bottom: 0.375rem;
}

.tool-input-group input,
.tool-input-group select {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid var(--shade--10, #0000001a);
  border-radius: 0.75rem;
  font-family: 'Inter', sans-serif;
  font-size: 1rem;
  background: var(--neutral--white, #fff);
}

.tool-result {
  margin-top: 1.5rem;
  padding: 1.5rem;
  background: #F7F8FA;
  border-radius: 1rem;
  border-left: 3px solid var(--_color-theme---1, #2C6BE0);
}

/* Results are hidden until a calculation runs — otherwise every tool page
   loads showing an empty grey box with a stray label in it. */
.tool-result,
.no-results,
.loader {
  display: none;
}

.tool-result.is-visible,
.no-results.is-visible {
  display: block;
  animation: nx-tool-in 0.25s ease both;
}

.loader.is-visible {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.5rem;
}

@keyframes nx-tool-in {
  from { opacity: 0; transform: translateY(0.375rem); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .tool-result.is-visible,
  .no-results.is-visible { animation: none; }
}

/* Tone signalling — the accent bar carries the verdict so the number does not
   have to be recoloured (which would fight the design system's indigo). */
.tool-result[data-tone="good"] { border-left-color: #16A34A; }
.tool-result[data-tone="warn"] { border-left-color: #D97706; }
.tool-result[data-tone="bad"]  { border-left-color: #DC2626; }

.tool-result[data-tone="bad"] .tool-result__value { color: #DC2626; }

/* Sentence-length values (e.g. a number spelled out in words) need to step
   down from the 2rem figure size. */
.tool-result__value--text {
  font-size: 1.25rem;
  line-height: 1.5;
  word-break: break-word;
}

.no-results {
  margin-top: 1.5rem;
  padding: 1rem 1.25rem;
  background: #fff7ed;
  border-radius: 0.75rem;
  border-left: 3px solid #D97706;
  font-family: 'Inter', sans-serif;
  font-size: 0.9375rem;
  color: var(--shade--60, #0009);
}

/* --- interest explorer results --- */
.interests-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0.625rem;
}

.interest-chip {
  display: flex;
  flex-direction: column;
  gap: 0.1875rem;
  padding: 0.625rem 0.875rem;
  background: var(--neutral--white, #fff);
  border: 1px solid var(--shade--10, #0000001a);
  border-radius: 0.75rem;
}

.interest-chip__name {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--_color-theme---ink, #0B0B1A);
}

.interest-chip__tag {
  font-family: 'Inter', sans-serif;
  font-size: 0.6875rem;
  color: var(--shade--50, #00000080);
}

/* --- theme detector results --- */
.theme-card__title {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--_color-theme---ink, #0B0B1A);
  word-break: break-word;
}

.theme-card__badge {
  display: inline-block;
  margin-top: 0.5rem;
  padding: 0.2rem 0.6rem;
  border-radius: 100vw;
  background: #F7F8FA;
  font-family: 'Inter', sans-serif;
  font-size: 0.75rem;
  color: var(--shade--60, #0009);
}

.theme-card__note {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  line-height: 1.6;
  color: var(--shade--60, #0009);
  margin: 0.75rem 0 0;
}

.theme-card__steps {
  margin: 0.75rem 0 0;
  padding-left: 1.25rem;
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  line-height: 1.7;
  color: var(--shade--60, #0009);
}

/* --- loader --- */
.loader__dots {
  display: flex;
  gap: 0.375rem;
}

.loader__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--_color-theme---1, #2C6BE0);
  animation: nx-loader-bounce 1s ease-in-out infinite;
}

.loader__dot:nth-child(2) { animation-delay: 0.15s; }
.loader__dot:nth-child(3) { animation-delay: 0.3s; }

.loader__text {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  color: var(--shade--50, #00000080);
}

@keyframes nx-loader-bounce {
  0%, 80%, 100% { transform: translateY(0); opacity: 0.4; }
  40%           { transform: translateY(-0.3rem); opacity: 1; }
}

.tool-btn[disabled] {
  opacity: 0.6;
  cursor: default;
}

.tool-result__value {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 2rem;
  color: var(--_color-theme---1, #2C6BE0);
}

/* === LEGAL === */
.nx-legal-date {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  color: var(--shade--50, #00000080);
  margin-bottom: 2rem;
}

.nx-legal-body {
  max-width: 48rem;
  margin: 0 auto;
}

.nx-legal-body h3 {
  margin-top: 2rem;
}

/* === MAP PLACEHOLDER === */
.nx-contact-map-placeholder {
  width: 100%;
  height: 300px;
  background: #F7F8FA;
  border-radius: 1.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--shade--40, #0006);
  font-family: 'Inter', sans-serif;
}

/* === PIN === */
.nx-contact-map-pin {
  width: 1rem;
  height: 1rem;
}

/* === SOCIAL PROOF === */
[class*="sol-social"] {
  text-align: center;
  padding: 3rem var(--_sizes---padding-global, 2.5rem);
  background: #F7F8FA;
}

/* === REVEAL ANIMATION ===
   PROGRESSIVE ENHANCEMENT — do not remove the `.nx-js` gate.
   Content is visible by default. The hidden-then-animate state only applies
   once <html> carries `nx-js`, which the inline bootstrap in each page's
   <head> sets synchronously before first paint (so there is no flash) and
   removes again on a timer if js/nx-ui.js never runs. Writing these rules
   ungated makes every .nx-reveal element permanently invisible whenever the
   script fails to load — that shipped once already. */
.nx-js .nx-reveal {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.nx-js .nx-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.nx-js .nx-reveal-child {
  opacity: 0;
  transform: translateY(1rem);
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.nx-js .nx-reveal-child.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* === RESPONSIVE === */
/* These two blocks MUST mirror the selector list in SECTION BASE at the top of
   this file. They previously still carried the [class*="..."] forms, so every
   viewport under 991px re-applied the exact over-match the top block had been
   cleaned of — the desktop fix looked like it had done nothing. */
@media (max-width: 991px) {
  .main-wrapper section,
  .main-wrapper .section,
  .sol-hero,
  .sol-deepdive,
  .sol-benefits,
  .sol-how,
  .sol-social,
  .sol-cta,
  .cta-section,
  .content-section,
  .nx-cta-fan {
    padding: 5rem var(--_sizes---padding-global, 2.5rem);
  }

  .nx-about-hero,
  .nx-price-hero-section,
  .nx-contact-hero,
  .nx-faq-page-hero,
  .sol-hero,
  .nx-blog-hero,
  .nx-vid-hero,
  .nx-legal-hero,
  .nx-aff-hero,
  .nx-uni-hero,
  .tool-hero {
    padding-top: calc(5rem + 4rem);
    padding-bottom: 5rem;
  }
}

@media (max-width: 767px) {
  .main-wrapper section,
  .main-wrapper .section,
  .sol-hero,
  .sol-deepdive,
  .sol-benefits,
  .sol-how,
  .sol-social,
  .sol-cta,
  .cta-section,
  .content-section,
  .nx-cta-fan {
    padding: 3rem var(--_sizes---padding-global, 2.5rem);
  }

  .nx-about-hero,
  .nx-price-hero-section,
  .nx-contact-hero,
  .nx-faq-page-hero,
  .sol-hero,
  .nx-blog-hero,
  .nx-vid-hero,
  .nx-legal-hero,
  .nx-aff-hero,
  .nx-uni-hero,
  .tool-hero {
    padding-top: calc(3rem + 4rem);
    padding-bottom: 3rem;
  }

  .nx-about-stats-grid,
  .nx-aff-details-stats {
    grid-template-columns: 1fr;
  }
}

/* === BLOG HERO IMAGE/OVERLAY === */
.blog-hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.blog-hero__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0.3), rgba(0,0,0,0.7));
}

.blog-hero__meta-sep {
  margin: 0 0.5rem;
  opacity: 0.5;
}

.blog-hero__pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: rgba(255,255,255,0.15);
  border-radius: 100vw;
  padding: 0.25rem 0.75rem;
  font-size: 0.75rem;
  color: #fff;
  margin-bottom: 0.75rem;
}

/* === BLOG INDEX === */
/* SPECIFICITY NOTE — read before touching the card selectors below.
   The HEADINGS/PARAGRAPHS blocks near the top of this file contain
   `[class*="blog-"] h3` and `[class*="blog-"] p`. The card anchor's own class,
   `nx-blog-card`, CONTAINS the substring "blog-", so every h3/p inside a card
   matched those rules — and at (0,1,1) they outrank a plain single-class
   selector at (0,1,0) no matter how far down the file it sits. Result: card
   titles rendered at the h3 scale (2.5rem desktop) instead of 1.25rem and
   excerpts at 1rem/1.6 with the wrong colour, which is what blew the grid
   apart. The card rules are therefore QUALIFIED with the parent class to reach
   (0,2,0). Do not "simplify" them back to a single class, and do not remove
   `[class*="blog-"]` from the heading lists — the blog ARTICLE pages rely on it
   for their body copy. */
/* Same specificity trap as the cards: `.main-wrapper section` is (0,1,1), so a
   bare `.nx-blog-grid-section` at (0,1,0) would lose and this rule would appear
   to do nothing. Qualified to (0,2,0), which also beats the 991px/767px
   overrides of that same base rule without needing its own media queries.
   Zeroing the top padding leaves the hero's own 7rem bottom padding as the only
   gap; before this the two stacked into a ~14rem void above the first card. */
.main-wrapper .nx-blog-grid-section {
  padding-top: 0;
}

.nx-blog-grid {
  display: grid;
  /* auto-fit + 19rem keeps 3 up at 80rem, 2 up on tablet, 1 up on phones
     without needing a breakpoint of its own. */
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1.5rem;
  /* No padding here: the parent section already supplies the page gutter and
     .container-inner already caps the width at 80rem. The old
     `padding: 0 2.5rem` stacked a second gutter on top, so the grid sat
     narrower than every other section on the site. */
  width: 100%;
}

/* The card is a single <a> wrapping the whole tile, so the UA underline and
   link colour would otherwise inherit into the title, excerpt and CTA — that
   is the "everything is underlined" symptom. Reset both on the anchor.
   display:flex makes the tiles equal height with the CTA pinned to the bottom. */
.nx-blog-card {
  display: flex;
  flex-direction: column;
  background: var(--neutral--white, #fff);
  border: 1px solid var(--shade--10, #0000001a);
  border-radius: 1.25rem;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
}

.nx-blog-card:hover {
  box-shadow: 0 0.75rem 2rem rgba(11, 11, 26, 0.08);
  border-color: var(--shade--20, #0003);
  transform: translateY(-0.125rem);
}

.nx-blog-card-img {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
  display: block;
  flex-shrink: 0;
  background-color: #EDEEF4;   /* placeholder while the lazy image loads */
}

.nx-blog-card-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: 1.5rem;
}

/* align-self is load-bearing: as a flex-column child the pill would otherwise
   stretch to the full card width and stop looking like a pill. */
.nx-blog-card .nx-blog-card-pill {
  align-self: flex-start;
  background: #F7F8FA;
  border-radius: 100vw;
  padding: 0.25rem 0.75rem;
  font-family: 'Inter', sans-serif;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.4;
  color: var(--shade--60, #0009);
  margin: 0 0 0.75rem;
}

.nx-blog-card .nx-blog-card-title {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 1.125rem;
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--_color-theme---ink, #0B0B1A);
  margin: 0 0 0.5rem;
}

.nx-blog-card .nx-blog-card-excerpt {
  flex: 1 1 auto;
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--shade--50, #00000080);
  margin: 0 0 1.25rem;
}

.nx-blog-card .nx-blog-card-link {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 0.25rem;
  margin-top: auto;
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--_color-theme---1, #2C6BE0);
  text-decoration: none;
}

/* The inline chevron carries a viewBox but NO width/height attributes and had
   no CSS rule anywhere, so it fell back to the replaced-element default and
   rendered as a ~200px block. Size it explicitly; flex-shrink:0 stops it
   collapsing when the label wraps. */
.nx-blog-card .nx-blog-card-link svg {
  width: 1.125rem;
  height: 1.125rem;
  flex-shrink: 0;
  transition: transform 0.2s ease;
}

.nx-blog-card:hover .nx-blog-card-link svg {
  transform: translateX(0.125rem);
}

/* .nx-blog-eyebrow is deliberately NOT in this group. It is an inline-flex pill
   styled in the EYEBROWS block above; `margin: 0 auto` here silently zeroed the
   `margin-bottom: 1rem` that block gives it, collapsing the gap under it. */
.nx-blog-hero-inner {
  text-align: center;
  max-width: 48rem;
  margin: 0 auto;
}

.nx-blog-eyebrow-dot {
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background-color: var(--_color-theme---1, #2C6BE0);
  display: inline-block;
}

/* === RELATED BLOG CARDS === */
.blog-related {
  padding: 3rem var(--_sizes---padding-global, 2.5rem);
}

.blog-related__title {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 1.5rem;
  color: var(--_color-theme---ink, #0B0B1A);
  margin-bottom: 1.5rem;
  max-width: 48rem;
  margin-left: auto;
  margin-right: auto;
}

.blog-related__card-img {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
  border-radius: 0.75rem;
  margin-bottom: 1rem;
}

.blog-related__card-body {
  padding: 0;
}

.blog-related__card-pill {
  display: inline-block;
  background: #F7F8FA;
  border-radius: 100vw;
  padding: 0.2rem 0.6rem;
  font-size: 0.75rem;
  color: var(--shade--60, #0009);
  margin-bottom: 0.5rem;
}

.blog-related__card-title {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 1rem;
  color: var(--_color-theme---ink, #0B0B1A);
}

.blog-author-card__avatar {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.blog-author-card__info {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  color: var(--shade--60, #0009);
}

/* === PRICING === */
.nx-price-card-head {
  text-align: center;
  margin-bottom: 1.5rem;
}

.nx-price-card-name {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 1.5rem;
  color: var(--_color-theme---ink, #0B0B1A);
}

.nx-price-card-icon {
  width: 3rem;
  height: 3rem;
  margin-bottom: 1rem;
}

.nx-price-card-price {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 700;
  font-size: 2.5rem;
  color: var(--_color-theme---ink, #0B0B1A);
  margin: 0.5rem 0;
}

.nx-price-card-desc {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  color: var(--shade--50, #00000080);
  margin-bottom: 1.5rem;
}

.nx-price-card-features {
  list-style: none;
  padding: 0;
  margin: 0 0 1.5rem;
}

.nx-price-card-features li {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  color: var(--shade--60, #0009);
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--shade--10, #0000001a);
}

.nx-price-card.featured .nx-price-card-name,
.nx-price-card.featured .nx-price-card-price,
.nx-price-card.featured .nx-price-card-desc,
.nx-price-card.featured .nx-price-card-features li,
.nx-price-card--featured .nx-price-card-name,
.nx-price-card--featured .nx-price-card-price,
.nx-price-card--featured .nx-price-card-desc,
.nx-price-card--featured .nx-price-card-features li {
  color: #fff;
}

/* === COMPARISON === */
.nx-comparison-section {
  padding: var(--_sizes---section-padding-large, 7rem) var(--_sizes---padding-global, 2.5rem);
}

.nx-comparison-scroll {
  overflow-x: auto;
  max-width: 80rem;
  margin: 0 auto;
  border-radius: 1.75rem;
  border: 1px solid var(--shade--10, #0000001a);
}

/* The comparison "grid" is a CSS grid of divs built by an inline script on
   pricing/index.html — there is no <table>, so the old th/td rules below
   matched nothing. Four columns: feature label + one per plan. */
.nx-comparison-grid {
  display: grid;
  grid-template-columns: minmax(9rem, 1.6fr) repeat(3, minmax(0, 1fr));
  width: 100%;
  min-width: 40rem;
}

.nx-comparison-grid th,
.nx-comparison-grid td {
  padding: 1rem 1.5rem;
  text-align: left;
  border-bottom: 1px solid var(--shade--10, #0000001a);
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
}

.nx-comparison-grid th {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  background: #F7F8FA;
}

/* Header row */
.nx-cmp-tag-cell,
.nx-cmp-head {
  padding: 1.25rem 1.5rem;
  background: #F7F8FA;
  border-bottom: 1px solid var(--shade--10, #0000001a);
}

.nx-cmp-head {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  text-align: center;
}

.nx-cmp-name {
  font-size: 1rem;
  line-height: 1.3;
}

.nx-cmp-sub {
  font-family: 'Inter', sans-serif;
  font-weight: 400;
  font-size: 0.8125rem;
  color: var(--shade--60, #00000099);
  margin-top: 0.125rem;
}

/* Body cells */
.nx-cmp-feat,
.nx-cmp-cell {
  padding: 0.875rem 1.5rem;
  border-bottom: 1px solid var(--shade--10, #0000001a);
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  display: flex;
  align-items: center;
}

.nx-cmp-feat {
  color: var(--shade--60, #00000099);
}

.nx-cmp-cell {
  justify-content: center;
  text-align: center;
}

.nx-cmp-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
}

.nx-cmp-ic svg {
  width: 100%;
  height: 100%;
  display: block;
}

.nx-cmp-ic-yes { color: var(--_color-theme---1, #2C6BE0); }
.nx-cmp-ic-no  { color: var(--shade--40, #00000066); }

/* Plain-text values ("10", "Unlimited") rendered instead of an icon. */
.nx-cmp-val {
  font-weight: 500;
}

.nx-cmp-tag {
  display: inline-block;
  background: #e8f5e9;
  color: #2e7d32;
  border-radius: 100vw;
  padding: 0.2rem 0.6rem;
  font-size: 0.75rem;
}

/* === PRICING FAQ ===
   Distinct from the /faq/ accordion: pricing/index.html ships its own inline
   script that toggles an `.active` class and animates inline style.height,
   rather than the .is-open + grid-template-rows pattern used elsewhere. The
   CSS therefore has to collapse via height/overflow, and the no-JS escape
   hatch has to use height:auto. */
.nx-pricing-faq-section {
  padding: var(--_sizes---section-padding-large, 7rem) var(--_sizes---padding-global, 2.5rem);
}

.nx-pricing-faq-heading {
  max-width: 48rem;
  margin: 0 auto 3rem;
  text-align: center;
}

.nx-pricing-faq-list {
  max-width: 48rem;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

.nx-pricing-faq-item {
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--shade--10, #0000001a);
  cursor: pointer;
}

.nx-pricing-faq-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 0;
}

.nx-pricing-faq-num {
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: #F7F8FA;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--_color-theme---1, #2C6BE0);
}

.nx-pricing-faq-q {
  flex: 1;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.4;
}

/* Chevron drawn with two pseudo-element strokes, rotated when open. */
.nx-pricing-faq-toggle {
  flex-shrink: 0;
  width: 1.5rem;
  height: 1.5rem;
  position: relative;
  transition: transform 0.25s ease;
}

.nx-pricing-faq-toggle::before,
.nx-pricing-faq-toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 0.625rem;
  height: 2px;
  border-radius: 2px;
  background: var(--shade--60, #00000099);
}

.nx-pricing-faq-toggle::before {
  left: 0.125rem;
  transform: translateY(-50%) rotate(45deg);
}

.nx-pricing-faq-toggle::after {
  right: 0.125rem;
  transform: translateY(-50%) rotate(-45deg);
}

.nx-pricing-faq-item.active .nx-pricing-faq-toggle {
  transform: rotate(180deg);
}

.nx-pricing-faq-answer-wrap {
  height: 0;
  overflow: hidden;
  transition: height 0.28s ease;
}

.nx-pricing-faq-answer {
  padding: 0 0 1rem 3rem;
  font-family: 'Inter', sans-serif;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--shade--60, #00000099);
}

/* Without JS nothing sets style.height, so reveal the answers and hide the
   affordance that would otherwise look inert. */
html:not(.nx-js) .nx-pricing-faq-answer-wrap {
  height: auto;
}

html:not(.nx-js) .nx-pricing-faq-toggle {
  display: none;
}

.nx-pricing-cta {
  padding: var(--_sizes---section-padding-large, 7rem) var(--_sizes---padding-global, 2.5rem);
  text-align: center;
}

.nx-pricing-cta .cta-btn-group {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  margin-top: 2rem;
}

/* === PRICING CARD DETAILS === */
/* .amount / .period are unprefixed helper classes used only inside
   .nx-price-card-price; scope them so they cannot leak site-wide. */
.nx-price-card-price .amount {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 700;
  font-size: 2.25rem;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.nx-price-card-price .period {
  font-family: 'Inter', sans-serif;
  font-size: 0.9375rem;
  color: var(--shade--60, #00000099);
  margin-left: 0.25rem;
}

/* Tick badge in the feature list. */
.nx-price-card-features li .check {
  flex-shrink: 0;
  width: 1.125rem;
  height: 1.125rem;
  border-radius: 50%;
  background: var(--_color-theme---1, #2C6BE0);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 0.15rem;
}

.nx-price-card-features li .check svg {
  width: 0.75rem;
  height: 0.75rem;
  display: block;
}

.nx-price-card.featured .nx-price-card-features li .check {
  background: var(--neutral--white, #fff);
}

.nx-price-card.featured .nx-price-card-features li .check svg path {
  stroke: var(--_color-theme---1, #2C6BE0);
}

.nx-price-card.featured .nx-price-card-price .period {
  color: rgba(255, 255, 255, 0.7);
}

/* CTA variants — .primary/.secondary are modifiers on .nx-price-card-cta. */
.nx-price-card-cta.primary {
  background: var(--neutral--white, #fff);
  color: var(--_color-theme---1, #2C6BE0);
}

.nx-price-card-cta.secondary {
  background: transparent;
  color: var(--_color-theme---1, #2C6BE0);
  border: 1px solid var(--_color-theme---1, #2C6BE0);
}

.nx-comparison-heading {
  max-width: 48rem;
  margin: 0 auto 3rem;
  text-align: center;
}

.nx-comparison-card {
  max-width: 80rem;
  margin: 0 auto;
}

@media (max-width: 767px) {
  .nx-pricing-faq-answer {
    padding-left: 0;
  }

  .nx-price-card-price .amount {
    font-size: 1.875rem;
  }
}

/* === CONTACT FORM === */
.nx-contact-form-wrap {
  max-width: 36rem;
}

.nx-contact-form-title {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 1.25rem;
  color: var(--_color-theme---ink, #0B0B1A);
  margin-bottom: 1rem;
}

.nx-contact-form .nx-contact-field {
  margin-bottom: 1rem;
}

.nx-contact-field label {
  display: block;
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--shade--60, #0009);
  margin-bottom: 0.375rem;
}

.nx-contact-field input,
.nx-contact-field textarea {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid var(--shade--10, #0000001a);
  border-radius: 0.75rem;
  font-family: 'Inter', sans-serif;
  font-size: 1rem;
  background: var(--neutral--white, #fff);
}

.nx-contact-field textarea {
  min-height: 8rem;
  resize: vertical;
}

.nx-contact-details {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.nx-contact-detail-item {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}

.nx-contact-detail-icon {
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: #F7F8FA;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--_color-theme---1, #2C6BE0);
}

.nx-contact-detail-text {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  color: var(--shade--60, #0009);
}

/* === FAQ SPECIFIC === */
.nx-faq-page-left {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.nx-faq-page-right {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.nx-faq-page-row {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}

.nx-faq-page-num {
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: #F7F8FA;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--_color-theme---1, #2C6BE0);
}

.nx-faq-page-row {
  cursor: pointer;
}

.nx-faq-page-row:focus-visible {
  outline: 2px solid var(--_color-theme---1, #2C6BE0);
  outline-offset: 4px;
  border-radius: 0.5rem;
}

.nx-faq-page-q {
  flex: 1;
}

.nx-faq-page-toggle {
  flex-shrink: 0;
  width: 1.5rem;
  height: 1.5rem;
  position: relative;
  transition: transform 0.25s ease;
}

/* Toggle glyph: a plus drawn from two bars, rotating into a minus when open.
   The markup ships <span class="nx-faq-page-toggle"></span> with no content,
   so the glyph has to come from pseudo-elements. */
.nx-faq-page-toggle::before,
.nx-faq-page-toggle::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.75rem;
  height: 2px;
  border-radius: 2px;
  background: var(--_color-theme---1, #2C6BE0);
  transform: translate(-50%, -50%);
  transition: transform 0.25s ease, opacity 0.25s ease;
}

.nx-faq-page-toggle::after {
  transform: translate(-50%, -50%) rotate(90deg);
}

.nx-faq-page-item.is-open .nx-faq-page-toggle::after {
  transform: translate(-50%, -50%) rotate(0deg);
  opacity: 0;
}

/* Collapse the answer. Scoped to the wrap class exactly — the broader
   [class*="nx-faq-page-answer"] selector earlier in this file matches BOTH
   -answer-wrap and -answer, so putting the collapse there would also hide
   the text permanently. */
.nx-faq-page-answer-wrap {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  opacity: 0;
  transition: grid-template-rows 0.28s ease, opacity 0.28s ease;
}

.nx-faq-page-item.is-open > .nx-faq-page-answer-wrap {
  grid-template-rows: 1fr;
  opacity: 1;
}

.nx-faq-page-answer-wrap > * {
  min-height: 0;
}

.nx-faq-page-answer {
  padding-left: 3rem;
}

/* No-JS: nothing can add .is-open, so show every answer expanded rather than
   collapse the whole FAQ into unreadable headings. */
html:not(.nx-js) .nx-faq-page-answer-wrap {
  grid-template-rows: 1fr;
  opacity: 1;
}

html:not(.nx-js) .nx-faq-page-toggle {
  display: none;
}

/* === VIDEO SPECIFIC === */
.nx-vid-chapter-label {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  color: var(--_color-theme---ink, #0B0B1A);
  flex: 1;
}

.nx-vid-chapter-time {
  font-family: 'Inter', sans-serif;
  font-size: 0.75rem;
  color: var(--shade--50, #00000080);
  flex-shrink: 0;
}

.nx-vid-chapter-list {
  display: flex;
  flex-direction: column;
}

.nx-vid-chapters {
  max-width: 80rem;
  margin: 2rem auto;
  padding: 0 var(--_sizes---padding-global, 2.5rem);
}

.nx-vid-card-thumb {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
  border-radius: 0.75rem;
  margin-bottom: 0.75rem;
}

.nx-vid-card-body {
  padding: 0;
}

.nx-vid-card-play {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  display: flex;
  align-items: center;
  justify-content: center;
}

.nx-vid-player {
  max-width: 80rem;
  margin: 0 auto;
  padding: 0 var(--_sizes---padding-global, 2.5rem);
}

.nx-vid-related {
  padding: 3rem var(--_sizes---padding-global, 2.5rem);
}

.nx-vid-body {
  max-width: 80rem;
  margin: 0 auto;
  padding: 0 var(--_sizes---padding-global, 2.5rem);
}

.nx-vid-card-pill {
  display: inline-block;
  background: #F7F8FA;
  border-radius: 100vw;
  padding: 0.2rem 0.6rem;
  font-size: 0.75rem;
  color: var(--shade--60, #0009);
}

/* === AFFILIATE === */
.nx-aff-details-left,
.nx-aff-details-right {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.nx-aff-details-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}

.nx-aff-faq-list {
  display: flex;
  flex-direction: column;
  max-width: 48rem;
  margin: 0 auto;
}

/* === UNIVERSITY === */
.nx-uni-course-icon {
  width: 3rem;
  height: 3rem;
  border-radius: 0.75rem;
  margin-bottom: 1rem;
}

.nx-uni-course-meta {
  display: flex;
  gap: 0.75rem;
  font-family: 'Inter', sans-serif;
  font-size: 0.75rem;
  color: var(--shade--50, #00000080);
  margin-bottom: 0.5rem;
}

.nx-uni-course-badge {
  display: inline-block;
  background: #e8f5e9;
  color: #2e7d32;
  border-radius: 100vw;
  padding: 0.2rem 0.6rem;
  font-size: 0.75rem;
}

.nx-uni-course-lessons {
  font-family: 'Inter', sans-serif;
  font-size: 0.75rem;
  color: var(--shade--50, #00000080);
}

/* === ABOUT === */

/* Story section — two-column grid */
.nx-about-story > .container-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem;
  align-items: start;
}

@media (max-width: 767px) {
  .nx-about-story > .container-inner {
    grid-template-columns: 1fr;
    gap: 2rem;
  }
}

.nx-about-story-img {
  width: 100%;
  border-radius: 1.75rem;
  overflow: hidden;
}

.nx-about-story-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.nx-about-story-text {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* Value icons */
.nx-about-value-icon {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.75rem;
  margin-bottom: 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #EEF4FE;
  color: #2C6BE0;
}

.nx-about-value-icon svg {
  width: 1.375rem;
  height: 1.375rem;
}

/* Values heading — wraps h2 + p */
.nx-about-values-heading {
  margin-bottom: 1.5rem;
}

.nx-about-values-heading p {
  max-width: 36rem;
}

/* Stats section */
.nx-about-stat h3 {
  font-size: 2.5rem;
  font-weight: 700;
  color: var(--_color-theme---1, #2C6BE0);
  margin-bottom: 0.25rem;
}

.nx-about-stat p {
  font-size: 0.875rem;
}

/* CTA section */
.nx-about-cta {
  text-align: center;
}

.cta-btn-group {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 2rem;
}

/* === SECTION ALTERNATING BACKGROUNDS === */
.nx-about-hero {
  background: linear-gradient(180deg, #EEF4FE 0%, #FFFFFF 60%);
}

.nx-about-story {
  background: #F8FAFC;
}

.nx-about-stats {
  background: linear-gradient(135deg, #EEF4FE 0%, #E0E7FF 100%);
}

.nx-about-cta {
  background: linear-gradient(180deg, #F8FAFC 0%, #FFFFFF 100%);
}

/* Reduced motion: skip the reveal animation entirely.
   NOTE: this is NOT the no-JS fallback — it only fires when the reader has
   turned the OS-level setting on. The no-JS fallback is the `.nx-js` gate on
   the reveal rules above. */
@media (prefers-reduced-motion: reduce) {
  .nx-reveal,
  .nx-reveal-child {
    opacity: 1 !important;
    transform: none !important;
  }
  .nx-reveal-child > * {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* === ABOUT PAGE — TIGHTER SPACING & REFINEMENTS === */
/* Reduce excessive vertical padding on about sections (default 7rem is too large) */
.nx-about-hero {
  padding-top: 6rem;
  padding-bottom: 4rem;
}
.nx-about-mission,
.nx-about-story,
.nx-about-values,
.nx-about-stats,
.nx-about-cta {
  padding-top: 3rem;
  padding-bottom: 3rem;
}

@media (max-width: 991px) {
  .nx-about-hero {
    padding-top: 5rem;
    padding-bottom: 3rem;
  }
  .nx-about-mission,
  .nx-about-story,
  .nx-about-values,
  .nx-about-stats,
  .nx-about-cta {
    padding-top: 2.5rem;
    padding-bottom: 2.5rem;
  }
}

@media (max-width: 767px) {
  .nx-about-hero {
    padding-top: 4rem;
    padding-bottom: 2.5rem;
  }
  .nx-about-mission,
  .nx-about-story,
  .nx-about-values,
  .nx-about-stats,
  .nx-about-cta {
    padding-top: 2rem;
    padding-bottom: 2rem;
  }
}

/* Hero — larger heading for impact */
.nx-about-hero h1 {
  font-size: calc(var(--_typography---h1--font-size, 3.5rem) + 0.5rem);
  max-width: 42rem;
  margin-left: auto;
  margin-right: auto;
}

.nx-about-hero p {
  max-width: 36rem;
  margin-left: auto;
  margin-right: auto;
  font-size: 1.125rem;
}

/* Mission section — centered, narrower */
.nx-about-mission {
  text-align: center;
}
.nx-about-mission p {
  max-width: 48rem;
  margin-left: auto;
  margin-right: auto;
}

/* Values cards — consistent height */
.nx-about-value-card {
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
}

.nx-about-value-card::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: center;
}

.nx-about-value-card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(135deg, rgba(255,255,255,0.96) 0%, rgba(255,255,255,0.88) 60%, rgba(255,255,255,0.78) 100%);
}

.nx-about-value-card > * {
  position: relative;
  z-index: 1;
}

/* The photo this card used was deleted from Unsplash and 404s. It sits under
   a 78-96% white overlay, so it is texture rather than a picture — swapped for
   one already used on this page and confirmed to still resolve. */
.nx-about-value-card:nth-child(1)::before {
  background-image: url('https://images.unsplash.com/photo-1552664730-d307ca884978?w=600&q=80');
}

.nx-about-value-card:nth-child(2)::before {
  background-image: url('https://images.unsplash.com/photo-1522071820081-009f0129c71c?w=600&q=80');
}

.nx-about-value-card:nth-child(3)::before {
  background-image: url('https://images.unsplash.com/photo-1677442136019-21780ecad995?w=600&q=80');
}

.nx-about-value-card p {
  flex: 1;
}

/* Stats — higher contrast */
.nx-about-stat {
  padding: 2rem 1.5rem;
}
.nx-about-stat h3 {
  font-size: 2.75rem;
}
.nx-about-stat p {
  font-size: 0.9375rem;
  color: #0009;
}

/* CTA — larger heading */
.nx-about-cta h2 {
  font-size: calc(var(--_typography---h2--font-size, 3rem) + 0.25rem);
  max-width: 36rem;
  margin-left: auto;
  margin-right: auto;
}

/* === SOLUTIONS (module pages) ===
   Layout system for the 10 module pages. Mirrors the homepage design language:
   80rem container, 1.75rem radii, indigo accent, Plus Jakarta / Inter pairing.
   NOTE: section padding is applied by the SECTION BASE block to the six
   .sol-* section classes only — never to inner elements. */

/* --- Hero --- */
.sol-hero > .container {
  max-width: 56rem;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.sol-hero h1 {
  max-width: 20ch;
  margin-bottom: 1.25rem;
}

.sol-hero > .container > p {
  font-size: 1.125rem;
  line-height: 1.6;
  color: var(--shade--60, #0009);
  max-width: 60ch;
  margin: 0;
}

/* --- Deep dive: two-column ---
   Prefixed with .main-wrapper (0,3,0) so it outranks the shared core
   `.container { padding: 5em 6em }` and any [class*="sol-"] rules.
   minmax(0,1fr) prevents min-content blowout skewing the 50/50 split.
   The aspect-ratio lives on the WRAPPER (not the img) so the box keeps its
   size even while the remote image is loading or if it fails to load. */
.main-wrapper .sol-deepdive > .container {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 4rem;
  align-items: center;
  width: 100%;
  max-width: 80rem;
  margin-left: auto;
  margin-right: auto;
  padding: 0;
}

.main-wrapper .sol-deepdive-text {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  min-width: 0;
}

.main-wrapper .sol-deepdive-text h2 {
  margin-bottom: 0.5rem;
}

.main-wrapper .sol-deepdive-text p {
  margin: 0;
}

.main-wrapper .sol-deepdive-visual {
  position: relative;
  width: 100%;
  min-width: 0;
  /* 16:10, because that is what the captures are — 2880x1800.
     This box was 4/3 while the phone rule below said 16/10, so at every
     desktop width a 1.6 image was being covered into a 1.333 box and losing
     about seventeen percent of its width off both sides. On a screenshot that
     is the navigation down one edge and the panel down the other: the parts
     that show it is software. */
  aspect-ratio: 16 / 10;
  border-radius: 1.75rem;
  overflow: hidden;
  border: 1px solid var(--shade--10, #0000001a);
  box-shadow: 0 8px 40px rgba(0, 0, 0, 0.07);
  background-image: linear-gradient(135deg, #eef0fb, #e4e7f8);
}

.main-wrapper .sol-deepdive-visual img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  border-radius: inherit;
}

/* --- Section headers (benefits / how) --- */
.sol-benefits .section-header,
.sol-how .section-header {
  text-align: center;
  max-width: 44rem;
  margin: 0 auto 3.5rem;
}

.sol-benefits .section-header p,
.sol-how .section-header p {
  font-size: 1.125rem;
  color: var(--shade--60, #0009);
  margin: 0;
}

/* --- Benefits: tinted band for vertical rhythm (site-standard #F7F8FA) --- */
.main-wrapper .sol-benefits {
  background: #F7F8FA;
}

.sol-benefits-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

/* .sol-benefit-card picks up background/border/radius/padding from the CARDS block */
.sol-benefit-card h3 {
  margin: 0 0 0.75rem;
  font-size: 1.25rem;
}

.sol-benefit-card p {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--shade--60, #0009);
}

.sol-benefit-icon {
  width: 3rem;
  height: 3rem;
  border-radius: 0.875rem;
  margin-bottom: 1.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background-image: linear-gradient(180deg, var(--_color-theme---light, #6e9cf9), var(--_color-theme---1, #2C6BE0));
  color: #fff;
  flex-shrink: 0;
}

.sol-benefit-icon svg {
  width: 1.5rem;
  height: 1.5rem;
  display: block;
}

/* --- How it works: 3 steps --- */
.sol-steps {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  max-width: none;
  margin: 0;
}

.sol-step {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  /* .sol-steps is a grid with its own gap; the generic step rule's
     margin-bottom would double-space the rows. */
  margin-bottom: 0;
  position: relative;
}

.sol-step-num {
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  min-width: 2.75rem;
  padding: 0;
  border-radius: 50%;
  background-image: linear-gradient(180deg, var(--_color-theme---light, #6e9cf9), var(--_color-theme---1, #2C6BE0));
  background-color: transparent;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1;
  margin-bottom: 1rem;
}

.sol-step h3 {
  margin: 0 0 0.625rem;
  font-size: 1.1875rem;
}

.sol-step p {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--shade--60, #0009);
}

/* --- Social proof: slim divider strip, not a full section.
   Prefixed with .main-wrapper so it outranks `.main-wrapper section`. --- */
.main-wrapper .sol-social {
  text-align: center;
  padding-top: 4rem;
  padding-bottom: 4rem;
}

.sol-social h2 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 500;
  color: var(--shade--60, #0009);
  letter-spacing: -0.01em;
}

/* --- Closing CTA --- */
.sol-cta > .container {
  background-image: linear-gradient(180deg, var(--_color-theme---light, #6e9cf9), var(--_color-theme---1, #2C6BE0));
  border-radius: 2rem;
  padding: 4.5rem 2.5rem;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.sol-cta h2 {
  color: #fff;
  max-width: 22ch;
  margin: 0 0 1rem;
}

.sol-cta > .container > p {
  color: rgba(255, 255, 255, 0.85);
  font-size: 1.0625rem;
  margin: 0 0 2rem;
  max-width: 52ch;
}

.sol-cta-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  padding: 0;
}

/* On the indigo CTA panel the primary button becomes solid white,
   the secondary a translucent outline — matching the homepage footer CTA. */
.sol-cta-actions .button-wrap.button--indigo,
.sol-cta-actions .button-wrap .button--indigo {
  background-image: none;
  background-color: #fff;
  color: var(--_color-theme---ink, #0B0B1A);
}

.sol-cta-actions .button-wrap.button--indigo,
.sol-cta-actions .button-wrap:has(.button--indigo) {
  background-image: none;
  background-color: #fff;
  color: var(--_color-theme---ink, #0B0B1A);
}

.sol-cta-actions .button-wrap.button--ghost,
.sol-cta-actions .button-wrap:has(.button--ghost) {
  background-image: none;
  background-color: rgba(255, 255, 255, 0.12);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.45);
}

.sol-cta-actions .button-wrap:hover {
  opacity: 0.9;
}

/* --- Responsive --- */
@media (max-width: 991px) {
  .main-wrapper .sol-deepdive > .container {
    grid-template-columns: minmax(0, 1fr);
    gap: 2.5rem;
  }

  .sol-benefits-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .sol-steps {
    grid-template-columns: 1fr;
    gap: 2rem;
    max-width: 36rem;
    margin: 0 auto;
  }

  .sol-benefits .section-header,
  .sol-how .section-header {
    margin-bottom: 2.5rem;
  }

  .sol-cta > .container {
    padding: 3.5rem 2rem;
  }
}

@media (max-width: 767px) {
  .sol-hero > .container {
    text-align: left;
    align-items: flex-start;
  }

  .sol-hero h1 {
    max-width: none;
  }

  .sol-benefits-grid {
    grid-template-columns: 1fr;
  }

  .main-wrapper .sol-deepdive-visual {
    aspect-ratio: 16 / 10;
  }

  .main-wrapper .sol-social {
    padding-top: 2.5rem;
    padding-bottom: 2.5rem;
  }

  .sol-social h2 {
    font-size: 1.25rem;
  }

  .sol-cta > .container {
    padding: 2.5rem 1.5rem;
    border-radius: 1.5rem;
  }

  .sol-cta-actions {
    width: 100%;
    flex-direction: column;
  }
}

/* === FREE TOOLS === */
.step-card__desc {
  font-family: 'Inter', sans-serif;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--shade--60, #0009);
}

.step-card__icon {
  flex-shrink: 0;
  width: 2.5rem;
  height: 2.5rem;
}

.tool-area {
  max-width: 36rem;
  margin: 0 auto;
  padding: 0 var(--_sizes---padding-global, 2.5rem);
}

.tool-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background-image: linear-gradient(180deg, var(--_color-theme---light, #6e9cf9), var(--_color-theme---1, #2C6BE0));
  border-radius: 2rem;
  padding: 0.75rem 1.5rem;
  font-family: 'Inter', sans-serif;
  font-size: 1rem;
  font-weight: 500;
  color: #fff;
  text-decoration: none;
  border: none;
  cursor: pointer;
  transition: opacity 0.2s;
}

.tool-btn:hover {
  opacity: 0.9;
}

.tool-container {
  max-width: 80rem;
  margin: 0 auto;
  padding: 0 var(--_sizes---padding-global, 2.5rem);
}

.tool-result__label {
  font-family: 'Inter', sans-serif;
  font-size: 0.75rem;
  color: var(--shade--50, #00000080);
  margin-bottom: 0.25rem;
}

.tool-result__tag {
  display: inline-block;
  background: #F7F8FA;
  border-radius: 100vw;
  padding: 0.2rem 0.6rem;
  font-size: 0.75rem;
  color: var(--shade--60, #0009);
  margin-top: 0.5rem;
}

.tool-result__note {
  font-family: 'Inter', sans-serif;
  font-size: 0.75rem;
  color: var(--shade--50, #00000080);
  margin-top: 0.5rem;
}

/* === PRICING HERO === */
.nx-price-hero-eyebrow-dot {
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background-color: var(--_color-theme---1, #2C6BE0);
  display: inline-block;
}

/* === LEGAL === */
.nx-legal-cta {
  padding: 3rem var(--_sizes---padding-global, 2.5rem);
}

.content-section--alt {
  background: #F7F8FA;
}

/* === RESPONSIVE ADDITIONS === */
@media (max-width: 767px) {
  .nx-blog-grid {
    grid-template-columns: 1fr;
  }
  
  .nx-aff-details-grid {
    grid-template-columns: 1fr;
  }
  
  .nx-comparison-grid {
    font-size: 0.75rem;
  }
}

/* ============================================================
   Responsive line break — desktop only
   Used in the homepage "NexusOS modules" H2 so the big display
   heading wraps to two lines on desktop and stays inside the
   hero beam. Hidden below 992px, where the heading is smaller
   and natural word-wrap handles it.
   ============================================================ */
.nx-br-desktop {
  display: none;
}

@media (min-width: 992px) {
  .nx-br-desktop {
    display: inline;
  }
}

/* ============================================================
   Stable scrollbar gutter — kills the ~15px left-right layout
   shift when the scrollbar appears/disappears (page transitions
   swap <main> in and out, and short pages briefly have no
   scrollable overflow). Progressive enhancement: browsers
   without support simply keep today's behavior.
   ============================================================ */
html {
  scrollbar-gutter: stable;
}


/* ═══════════════════════════════════════════════════════════════════════════
   The ten module pages, redesigned.
   ─────────────────────────────────────────────────────────────────────────
   All ten share one structure — hero, deep dive, benefits, how, social, CTA —
   so this is one design pass rather than ten. Everything below is scoped to
   the .sol-* sections and reaches every module page at once.

   The thing that made them read as unfinished was not the layout. It was that
   the one picture on each page was a stock photograph from Unsplash, while its
   own alt text described the product: "Finance dashboard showing revenue and
   profitability per client" over a photograph of something else entirely. The
   images are now the real screens, and the styling below is mostly about
   giving a screenshot somewhere to sit.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── The hero ────────────────────────────────────────────────────────────
   Was centred text on white with nothing behind it, on all ten. It gets a
   ground: a soft wash rising from the top in the brand's blues, so the page
   opens with something rather than starting cold and staying cold. Drawn with
   gradients, not an image — nothing to load, nothing to go missing. */
.sol-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.sol-hero::before {
  content: "";
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 150%;
  z-index: -1;
  background:
    radial-gradient(46% 40% at 22% 0%, rgba(44, 107, 224, .16) 0%, rgba(44, 107, 224, 0) 62%),
    radial-gradient(40% 36% at 78% 6%, rgba(99, 149, 241, .14) 0%, rgba(99, 149, 241, 0) 60%),
    linear-gradient(180deg, #F4F7FE 0%, rgba(244, 247, 254, 0) 72%);
  pointer-events: none;
}
.sol-hero h1 {
  letter-spacing: -.028em;
  text-wrap: balance;
}
.sol-hero > .container > p { text-wrap: pretty; }

/* ── The screen ──────────────────────────────────────────────────────────
   A screenshot dropped straight onto a page reads as a loose rectangle, so it
   gets the frame the CIO section uses: an edge, a radius, and a shadow that
   lifts it rather than printing it flat. object-position pins the top so the
   crop keeps a screen's header — the part that says which screen it is —
   rather than centring on whitespace. */
.main-wrapper .sol-deepdive-visual {
  border: 1px solid rgba(11, 11, 26, .09);
  border-radius: 1.25rem;
  overflow: hidden;
  background: #fff;
  box-shadow:
    0 1px 2px rgba(11, 11, 26, .04),
    0 24px 48px -28px rgba(11, 11, 26, .28);
}
.main-wrapper .sol-deepdive-visual .sol-shot-img,
.main-wrapper .sol-deepdive-visual img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

/* ── Benefits ────────────────────────────────────────────────────────────
   Cards that were flat panels become things with an edge and a hover, so the
   grid reads as a set of items rather than a wall of text blocks. */


/* ── The closing call to action ──────────────────────────────────────────
   The last thing on the page was the same white as everything above it. It
   takes the brand's blue so the page ends on the product rather than fading
   out, and its type is reversed out of that. */
.main-wrapper .sol-cta {
  position: relative;
  isolation: isolate;
}
.main-wrapper .sol-cta::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(70% 60% at 50% 0%, rgba(78, 134, 240, .55) 0%, rgba(78, 134, 240, 0) 70%),
    linear-gradient(165deg, #2C6BE0 0%, #1E56BE 60%, #17418F 100%);
}
.main-wrapper .sol-cta h2,
.main-wrapper .sol-cta h2 * { color: #fff; }
.main-wrapper .sol-cta p { color: rgba(255, 255, 255, .82); }



/* ── The eyebrow was unstyled ─────────────────────────────────────────────
   .sol-eyebrow had no rule at all, so the module's name sat above the
   headline as a bare line of body text. It is the first thing on the page and
   the only thing that says which module you are on, so it gets to look like a
   label: a tinted pill, small, letterspaced, in the brand's blue. */
.sol-hero .sol-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: 1.25rem;
  padding: .4rem .85rem;
  border: 1px solid rgba(44, 107, 224, .18);
  border-radius: 999px;
  background: rgba(44, 107, 224, .07);
  color: #1E56BE;
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1;
}
/* A small mark before the word, so the pill reads as a status rather than a
   button somebody forgot to make clickable. */
.sol-hero .sol-eyebrow::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #2C6BE0;
  flex: 0 0 auto;
}

/* The headline carries the page, so it is set as display type rather than as
   a large paragraph: tighter tracking, a real scale, and balanced so the last
   line is never one orphaned word. */
.sol-hero h1 {
  font-size: clamp(2.125rem, 4.6vw, 3.5rem);
  line-height: 1.06;
  letter-spacing: -.032em;
  max-width: 18ch;
}

/* ── The benefit cards were not cards ────────────────────────────────────
   .sol-benefit-card had no rule of its own — only its h3 and p were styled —
   so three "cards" were three stacked blocks of text with an icon above each.
   Given a surface, an edge and somewhere to end, the section reads as a set
   of three things instead of one long column. */
.main-wrapper .sol-benefits .sol-benefit-card {
  position: relative;
  padding: 1.75rem 1.5rem;
  border: 1px solid rgba(11, 11, 26, .08);
  border-radius: 1.25rem;
  background: #fff;
  box-shadow: 0 1px 2px rgba(11, 11, 26, .03);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.main-wrapper .sol-benefits .sol-benefit-card:hover {
  transform: translateY(-3px);
  border-color: rgba(44, 107, 224, .3);
  box-shadow: 0 20px 40px -28px rgba(44, 107, 224, .5);
}
/* The icon sits in a tile rather than floating loose above the heading, so it
   has a relationship to the card's edges instead of hanging in the padding. */
.main-wrapper .sol-benefits .sol-benefit-icon {
  background: linear-gradient(140deg, #EEF4FE 0%, #E0EBFF 100%);
  border: 1px solid rgba(44, 107, 224, .12);
  color: #2C6BE0;
}
.main-wrapper .sol-benefits .sol-benefit-icon svg { color: #2C6BE0; }
.main-wrapper .sol-benefits .sol-benefit-card h3 { letter-spacing: -.012em; }

/* ── The steps are a sequence, so they look like one ─────────────────────
   Three numbered stages with nothing joining them read as three cards that
   happen to have numbers on. A hairline runs from each number to the next, so
   the eye is carried along the process rather than bouncing between boxes.
   The numbering is not decoration here: connect, log, act is an order, and
   doing them out of order does not work. */
.main-wrapper .sol-steps .sol-step { position: relative; }
.main-wrapper .sol-steps .sol-step-num {
  background: linear-gradient(140deg, #2C6BE0, #1E56BE);
  color: #fff;
  font-weight: 700;
  box-shadow: 0 6px 16px -8px rgba(44, 107, 224, .8);
  position: relative;
  z-index: 1;
}
@media (min-width: 861px) {
  .main-wrapper .sol-steps .sol-step:not(:last-child)::after {
    content: "";
    position: absolute;
    top: 1.375rem;
    left: calc(50% + 1.75rem);
    right: calc(-50% + 1.75rem);
    height: 1px;
    background: linear-gradient(90deg, rgba(44, 107, 224, .32), rgba(44, 107, 224, .08));
    z-index: 0;
  }
}

/* ── The proof line had nothing holding it ───────────────────────────────
   A single centred h2 on white, between two much heavier sections, read as a
   gap in the page rather than a statement in it. Rules either side make it a
   deliberate pause. */
.main-wrapper .sol-social > .container {
  max-width: 44rem;
  border-top: 1px solid rgba(11, 11, 26, .08);
  border-bottom: 1px solid rgba(11, 11, 26, .08);
  padding: 2.5rem 1.5rem;
}
.sol-social h2 {
  font-size: clamp(1.125rem, 2vw, 1.5rem);
  letter-spacing: -.015em;
  margin: 0;
}

/* ── The screen gets light behind it ─────────────────────────────────────
   A framed capture on flat white still sits on the page rather than above it.
   A soft bloom underneath, in the accent, lifts it — and it is drawn rather
   than baked into the image, so it costs nothing and cannot go stale when the
   capture is retaken. */
.main-wrapper .sol-deepdive-visual { isolation: isolate; }
.main-wrapper .sol-deepdive-visual::after {
  content: "";
  position: absolute;
  inset: auto 8% -14% 8%;
  height: 42%;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(44, 107, 224, .28) 0%, rgba(44, 107, 224, 0) 70%);
  filter: blur(14px);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .main-wrapper .sol-benefits .sol-benefit-card { transition: none; }
  .main-wrapper .sol-benefits .sol-benefit-card:hover { transform: none; }
}

/* ── A dark section, so the page has a rhythm ────────────────────────────
   The home page alternates: light, dark, light. These ten ran light the whole
   way down — six sections of the same white, which is why they read as one
   long page rather than a sequence of arguments.

   "How it works" takes the dark, and it is the right one to take. It is the
   middle of the page, it is the section furthest from the sell, and a numbered
   process is the part that most benefits from being set apart from everything
   around it. The palette is the home page's own dark values rather than a
   second set invented here — same ground, same hairlines, same lifted accent,
   because a lighter blue is what carries on a dark ground and #2C6BE0 does
   not. */
.main-wrapper .sol-how {
  --sol-dark-ink: #F2F3F8;
  --sol-dark-muted: #9297AB;
  --sol-dark-line: #23273A;
  --sol-dark-accent: #7FA6FF;

  position: relative;
  isolation: isolate;
  background: #0B0D16;
  color: var(--sol-dark-ink);
}
/* The same wash the home page's dark sections carry, so the ground is not a
   flat rectangle of near-black. */
.main-wrapper .sol-how::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(52% 44% at 18% 0%, rgba(44, 107, 224, .22) 0%, rgba(44, 107, 224, 0) 64%),
    radial-gradient(44% 40% at 84% 8%, rgba(127, 166, 255, .12) 0%, rgba(127, 166, 255, 0) 60%);
  pointer-events: none;
}
.main-wrapper .sol-how .section-header h2,
.main-wrapper .sol-how .sol-step h3 { color: var(--sol-dark-ink); }
.main-wrapper .sol-how .section-header p,
.main-wrapper .sol-how .sol-step p { color: var(--sol-dark-muted); }

/* The connector was drawn for a light ground and disappears on this one. */
@media (min-width: 861px) {
  .main-wrapper .sol-how .sol-step:not(:last-child)::after {
    background: linear-gradient(90deg, rgba(127, 166, 255, .45), rgba(127, 166, 255, .08));
  }
}
.main-wrapper .sol-how .sol-step-num {
  background: linear-gradient(140deg, #3D7BF7, #2C6BE0);
  box-shadow: 0 8px 22px -10px rgba(61, 123, 247, .9);
}

/* ── Movement, now that the reveal gate is armed ─────────────────────────
   The markup has carried .nx-reveal and .nx-reveal-child since it was ported
   and nothing ever moved, because the gate that hides them was never set. With
   it set, the default 1.5rem rise is right for a section but flat for a row of
   cards that arrive together — so the children stagger, and the two grids that
   are actually sets of things get a little more travel. */
.nx-js .sol-benefits-grid.nx-reveal-child.is-visible > *,
.nx-js .sol-steps.nx-reveal-child.is-visible > * {
  animation: sol-rise .55s cubic-bezier(.22, .68, .35, 1) both;
}
.nx-js .sol-benefits-grid.is-visible > *:nth-child(2),
.nx-js .sol-steps.is-visible > *:nth-child(2) { animation-delay: .08s; }
.nx-js .sol-benefits-grid.is-visible > *:nth-child(3),
.nx-js .sol-steps.is-visible > *:nth-child(3) { animation-delay: .16s; }
.nx-js .sol-benefits-grid.is-visible > *:nth-child(4),
.nx-js .sol-steps.is-visible > *:nth-child(4) { animation-delay: .24s; }

@keyframes sol-rise {
  from { opacity: 0; transform: translateY(1.25rem); }
  to   { opacity: 1; transform: translateY(0); }
}

/* The screen is the payoff of its section, so it arrives with a little more
   than the copy beside it. */
.nx-js .sol-deepdive-visual.nx-reveal {
  transform: translateY(2rem) scale(.985);
  transition: opacity .7s ease, transform .7s cubic-bezier(.22, .68, .35, 1);
}
.nx-js .sol-deepdive-visual.nx-reveal.is-visible {
  transform: translateY(0) scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .nx-js .sol-benefits-grid.is-visible > *,
  .nx-js .sol-steps.is-visible > * { animation: none; }
  .nx-js .sol-deepdive-visual.nx-reveal,
  .nx-js .sol-deepdive-visual.nx-reveal.is-visible { transform: none; transition: none; }
}

/* ── The hero had no way to act on it ────────────────────────────────────
   Ten module pages, each making a case, and not one of them offered a next
   step until the very bottom of the page. Somebody convinced by the headline
   had to scroll past everything to find out what to do about it. */
.sol-hero .sol-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  justify-content: center;
  margin-top: 2rem;
}
.sol-hero .sol-hero-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: .85rem 1.5rem;
  border-radius: 999px;
  font-size: .9375rem;
  font-weight: 600;
  text-decoration: none;
  transition: transform .15s ease, box-shadow .18s ease, background-color .18s ease;
}
.sol-hero .sol-hero-btn.is-primary {
  background: linear-gradient(140deg, #2C6BE0, #1E56BE);
  color: #fff;
  box-shadow: 0 10px 24px -12px rgba(44, 107, 224, .9);
}
.sol-hero .sol-hero-btn.is-primary:hover { transform: translateY(-1px); }
.sol-hero .sol-hero-btn.is-ghost {
  background: #fff;
  color: #1E56BE;
  border: 1px solid rgba(44, 107, 224, .24);
}
.sol-hero .sol-hero-btn.is-ghost:hover { background: #F5F8FF; }

/* ── A second screen, in context ─────────────────────────────────────────
   One screenshot on a page selling a module is thin, and it also leaves the
   central claim unevidenced: that these modules are one system rather than
   ten. Showing the neighbouring screen reading the same records is the
   evidence, and it is a real capture like the first. Full width, because it
   is the wider point being made. */
.main-wrapper .sol-context > .container { max-width: 72rem; }
.main-wrapper .sol-context-shot {
  margin: 2.5rem 0 0;
  position: relative;
  isolation: isolate;
  border: 1px solid rgba(11, 11, 26, .08);
  border-radius: 1.25rem;
  overflow: hidden;
  background: #fff;
  aspect-ratio: 16 / 10;
  box-shadow:
    0 1px 2px rgba(11, 11, 26, .04),
    0 30px 60px -34px rgba(11, 11, 26, .3);
}
.main-wrapper .sol-context-shot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

/* ── The rest of the system ──────────────────────────────────────────────
   A module page that ends without saying what else exists asks the reader to
   go back to a menu to find out. Nine cards, real names and real one-liners
   taken from the navigation, so the list cannot drift from the product. It
   also gives each page nine internal links it did not have. */
.main-wrapper .sol-related { background: #F7F9FD; }
.main-wrapper .sol-related > .container { max-width: 72rem; }
.sol-related-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: .75rem;
  margin-top: 2.25rem;
}
.sol-related-card {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: .25rem 1rem;
  padding: 1.1rem 1.25rem;
  border: 1px solid rgba(11, 11, 26, .08);
  border-radius: 1rem;
  background: #fff;
  text-decoration: none;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.sol-related-card:hover {
  transform: translateY(-2px);
  border-color: rgba(44, 107, 224, .32);
  box-shadow: 0 16px 32px -24px rgba(44, 107, 224, .6);
}
.sol-related-name {
  font-size: .9375rem;
  font-weight: 650;
  color: #0B0B1A;
  letter-spacing: -.01em;
}
.sol-related-desc {
  grid-column: 1 / -1;
  font-size: .8125rem;
  line-height: 1.45;
  color: #4B4F6B;
}
/* The arrow is the affordance, so it moves rather than just sitting there. */
.sol-related-go {
  color: #2C6BE0;
  font-size: 1rem;
  transition: transform .16s ease;
}
.sol-related-card:hover .sol-related-go { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .sol-hero .sol-hero-btn,
  .sol-related-card,
  .sol-related-go { transition: none; }
  .sol-hero .sol-hero-btn:hover,
  .sol-related-card:hover { transform: none; }
}
