
/* The site is designed light-only with photo backgrounds. Chrome for Android
   "auto-dark" was inverting text to white while leaving the photos light —
   white copy on white fur/silk textures. Declaring only-light opts the whole
   site out of forced darkening (the <meta name="color-scheme"> in each page
   head does the same; this is the CSS-level backstop, injected on every page). */
:root { color-scheme: only light; }
/* ================================================================
   SPARK CUSTOM STORE — CANONICAL SPACING / RHYTHM
   spacing.css  ·  loaded LAST (after buttons.css + typography.css)

   Every page had grown its own vertical rhythm:
     section padding : 44px (home) · 48px (testimonials) · 100px (contact)
                       110px (services) · 80px (portfolio) · tokens elsewhere
     hero            : 100vh (home/products/services) · 88vh (about)
                       90px (portfolio) · 80px (faq/gallery/testimonials)
                       56px (custom-quote)  — plus a stray 96px hero padding-top

   This file collapses all of that into ONE scale so the sections and
   heroes breathe identically across the whole site.

   Selectors are DOUBLED (.x.x = 0,2,0) so they out-rank the page-level
   rules without touching any HTML.
   ================================================================ */

:root {
  /* one section rhythm, everywhere */
  --sp-section:     clamp(4rem, 5.5vw, 6.5rem);   /* 64px → 104px */

  /* heroes: top padding must also clear the 72px fixed header */
  --sp-hero-top:    clamp(7rem, 8.5vw, 9.5rem);   /* 112px → 152px */
  --sp-hero-bottom: clamp(3.5rem, 5vw, 5.5rem);   /* 56px  → 88px  */

  /* gap between a section header (tag + heading + desc) and its content */
  --sp-header-gap:  clamp(2.5rem, 3.4vw, 3.5rem);
  --sp-tag-gap:     1rem;      /* tag  → heading */
  --sp-head-gap:    1rem;      /* heading → description */
}

@media (min-width: 1600px) {
 /* DESKTOP-SCALE generated by tools/desktop-scale.mjs */

:root {
  --sp-section:     clamp(4rem, 7.3333vw, 6.5rem);
  --sp-hero-top:    clamp(7rem, 11.3333vw, 9.5rem);
  --sp-hero-bottom: clamp(3.5rem, 6.6667vw, 5.5rem);
  --sp-header-gap:  clamp(2.5rem, 4.5333vw, 3.5rem);
} }

/* ── 1 · HEROES ─────────────────────────────────────────────────── */

/* Full-bleed landing heroes — same height + same padding.
   (home / products / services were 100vh, about was 88vh.) */
.hero.hero {
  min-height: 100vh;
  min-height: 100svh;
  padding-top: var(--sp-hero-top);
  padding-bottom: var(--sp-hero-bottom);
}
@media (min-width: 1600px) {
 /* DESKTOP-SCALE generated by tools/desktop-scale.mjs */
.hero.hero {
  min-height: 133.3333vh;
  min-height: 133.3333svh;
} }

/* Inner-page heroes — same padding as above (they stay content-height,
   they just breathe on the same scale). */
.pf-hero.pf-hero,
.faq-hero.faq-hero,
.gl-hero.gl-hero,
.ts-hero.ts-hero,
.cq-hero.cq-hero,
.contact-hero.contact-hero,
.page-banner.page-banner,
.pc-hero.pc-hero,
.sc-hero.sc-hero,
.sd-hero.sd-hero {
  padding-top: var(--sp-hero-top);
  padding-bottom: var(--sp-hero-bottom);
}

/* The hero's inner wrapper shouldn't re-add its own top padding on top of
   ours — several pages did (products had a stray 96px). */
.hero.hero > .hero-inner,
.hero-inner.hero-inner,
.hero__inner.hero__inner {
  padding-top: 0;
}

/* ── 2 · SECTIONS — one vertical rhythm ─────────────────────────── */
.section-pad.section-pad,
.services-section.services-section,
.portfolio-section.portfolio-section,
.why-section.why-section,
.testimonials-section.testimonials-section,
.contact-section.contact-section,
.payment-strip.payment-strip,
.trust-bar.trust-bar,
.info-strip.info-strip,
.products-section.products-section,
.gallery-section.gallery-section,
.pipeline-section.pipeline-section,
.promise-section.promise-section,
.clients-section.clients-section,
.software-section.software-section,
.industries-section.industries-section,
.intro.intro,
.stats.stats,
.timeline.timeline,
.mission.mission,
.why.why,
.reviews.reviews,
.cta.cta,
.faq-content.faq-content,
.gl-grid-wrap.gl-grid-wrap,
.ts-orbit-section.ts-orbit-section,
.ts-stats-bar.ts-stats-bar,
.ts-mobile-grid.ts-mobile-grid {
  padding-block: var(--sp-section);
}

/* Thin utility strips stay compact — a full section rhythm would bloat them */
.trust-bar.trust-bar,
.info-strip.info-strip,
.gl-filter-bar.gl-filter-bar,
.faq-tabs-wrap.faq-tabs-wrap {
  padding-block: clamp(1.25rem, 2vw, 2rem);
}
@media (min-width: 1600px) {
 /* DESKTOP-SCALE generated by tools/desktop-scale.mjs */
.trust-bar.trust-bar,
.info-strip.info-strip,
.gl-filter-bar.gl-filter-bar,
.faq-tabs-wrap.faq-tabs-wrap {
  padding-block: clamp(1.25rem, 2.6667vw, 2rem);
} }

/* The products marquee is a slim moving band — the section rhythm left a big
   empty gap above/below it, so keep it tight (was in the list above). */
.marquee-section.marquee-section {
  padding-block: clamp(0.85rem, 1.3vw, 1.35rem);
}
@media (min-width: 1600px) {
 /* DESKTOP-SCALE generated by tools/desktop-scale.mjs */
.marquee-section.marquee-section {
  padding-block: clamp(0.85rem, 1.7333vw, 1.35rem);
} }

/* The stats band (4 big numbers on the red strip) doesn't need the full
   section rhythm either — the client saw too much empty space. Moderate it. */
.stats-section.stats-section {
  padding-block: clamp(2.25rem, 3.5vw, 3.25rem);
}
@media (min-width: 1600px) {
 /* DESKTOP-SCALE generated by tools/desktop-scale.mjs */
.stats-section.stats-section {
  padding-block: clamp(2.25rem, 4.6667vw, 3.25rem);
} }

/* ── 3 · SECTION HEADERS — one gap under the header, one gap between
      the tag / heading / description ───────────────────────────── */
.section-header.section-header,
.testi-header.testi-header,
.why-top.why-top,
.pc-grid-header.pc-grid-header {
  margin-bottom: var(--sp-header-gap);
}

.section-tag.section-tag,
.section-label.section-label,
.eyebrow.eyebrow,
.marquee-label.marquee-label,
.pf-hero-tag.pf-hero-tag,
.reviews__eyebrow.reviews__eyebrow,
.mission__tag.mission__tag {
  margin-bottom: var(--sp-tag-gap);
}

.section-h2.section-h2,
.section-title.section-title,
.section-heading.section-heading,
.services-section-h2.services-section-h2,
.why-heading.why-heading,
.about-heading.about-heading {
  margin-top: 0;
  margin-bottom: var(--sp-head-gap);
}

.section-desc.section-desc,
.section-sub.section-sub {
  margin-top: 0;
  margin-bottom: 0;
}

/* ── 4 · Mobile — tighten the same scale, don't invent a new one ── */
@media (max-width: 768px) {
  :root {
    --sp-section:     clamp(2.75rem, 9vw, 3.75rem);
    --sp-hero-top:    clamp(6rem, 18vw, 7rem);
    --sp-hero-bottom: clamp(2.5rem, 8vw, 3.25rem);
    --sp-header-gap:  2rem;
  }
}

/* ================================================================
   HORIZONTAL RHYTHM — one container, one gutter, every page
   ----------------------------------------------------------------
   The hero content started at a different x on every page because four
   stylesheets each redefined `.container`, and some heroes bypassed it:

     home       padding-left: 5%              ->  72px  (furthest left)
     services   .container pad 3vw            -> 114px
     products   .container pad 4vw            -> 128px  <- client: "good"
     portfolio  own 1200-2200px container     -> 154px
     about      TWO stacked paddings (6vw+6vw)-> 171px  (too far in)

   Everything below now resolves to the SAME content edge, using the
   products geometry as the reference the client approved.
   ================================================================ */
:root {
  /* Container width. The 1280px floor holds ~1400px screens exactly where they
     look good; the vw term was raised 78vw -> 90vw so on 1600-1920px monitors
     the container (and therefore every card/grid/banner inside it) widens to
     fill the page instead of sitting in a narrow centred column. */
  --sp-max:    clamp(1280px, 90vw, 2200px);   /* the reference container   */
  --sp-pad:    clamp(48px, 4vw, 120px);       /* its inline padding        */
  /* The exact left/right content edge of that container, at any viewport.
     Mirrors how a centred max-width container resolves:
        left = max(pad, (parentWidth - max) / 2 + pad)                     */
  --sp-gutter: max(var(--sp-pad), calc((100% - var(--sp-max)) / 2 + var(--sp-pad)));
}
@media (min-width: 1600px) {
 /* DESKTOP-SCALE generated by tools/desktop-scale.mjs */
:root {
  --sp-max:    clamp(1280px, 120vw, 2200px);
  --sp-pad:    clamp(48px, 5.3333vw, 120px);
} }

/* ONE container everywhere (home / about / services / products each had
   their own max-width + padding, which is what pulled the heroes apart).

   The footer is excluded on purpose: it's a full-bleed band that aligns with
   the NAVBAR's inset rather than the page content grid (footer.css goes
   `max-width: none` above 1600px to do exactly that). Capping it here would
   undo that. */
.container.container:not(.site-footer *) {
  width: 100%;
  max-width: var(--sp-max);
  margin-inline: auto;
  padding-inline: var(--sp-pad);
}

/* --- Heroes that BYPASS .container: pin them to the same gutter --- */

/* HOME — content sits directly in .hero, which used `padding: 0 5%`.
   `:has(> .hero-content)` scopes this to home only: on products the
   .hero-content is nested inside a .container, not a direct child. */
.hero:has(> .hero-content) {
  padding-left: var(--sp-gutter);
  padding-right: var(--sp-gutter);
}

/* ABOUT — was stacking TWO paddings (.hero__columns + .hero__inner),
   which pushed the content ~171px in. Collapse to a single gutter. */
.hero__columns.hero__columns { padding-inline: var(--sp-gutter); }
.hero__inner.hero__inner     { padding-inline: 0; }

/* PORTFOLIO — had its own 1200-2200px container */
.pf-hero-inner.pf-hero-inner {
  width: 100%;
  max-width: var(--sp-max);
  margin-inline: auto;
  padding-inline: var(--sp-pad);
}

/* Heroes whose content is intentionally CENTRED stay centred */
.ts-hero-inner.ts-hero-inner { margin-inline: auto; }

/* HOME · "Our Advantage" — .why-container had NO css rule at all, so the
   section's `padding: 7.5rem 5%` was the only horizontal constraint. That
   let the image hang out past the left gutter and the cards past the right
   one. Move the gutter onto the inner box so the grid narrows to the same
   content width as every other section. */
.why-section.why-section { padding-inline: 0; }
.why-container.why-container {
  width: 100%;
  max-width: var(--sp-max);
  margin-inline: auto;
  padding-inline: var(--sp-pad);
}

/* --- Data-driven pages (product/service category + detail) ---------
   These never used .container — they each rolled their own centred box:
     .pc-* : 1200px + 28px pad
     .pd-* : 1220px + 28px pad
     .sc-* / .sd-* : 1100px + 24px pad  -> content started at ~177px,
                                           the furthest-in hero on the site.
   Every wrapper on those pages is retuned together, so the hero and the
   sections beneath it stay on the SAME vertical grid line.               */
.pc-hero-inner.pc-hero-inner,
.pc-video-section.pc-video-section,
.pc-grid-section.pc-grid-section,
.pc-related-inner.pc-related-inner,
.pd-breadcrumb-inner.pd-breadcrumb-inner,
.pd-main.pd-main,
.pd-related-inner.pd-related-inner,
.sc-hero-inner.sc-hero-inner,
.sc-stats-bar-inner.sc-stats-bar-inner,
.sc-main.sc-main,
.sd-hero-inner.sd-hero-inner,
.sd-info-strip-inner.sd-info-strip-inner,
.sd-content.sd-content,
.sd-related-inner.sd-related-inner {
  width: 100%;
  max-width: var(--sp-max);
  margin-inline: auto;
  padding-inline: var(--sp-pad);   /* padding-inline only — each keeps its
                                      own vertical padding */
}

/* --- Mobile: one gutter, not five --------------------------------- */
@media (max-width: 768px) {
  :root {
    --sp-pad: 20px;   /* clamp()'s 48px floor is too wide on a phone */
  }
}
