/* ============================================================
   Shared homepage section patterns
   Import in any section component that uses the sticky badge rail.

   Provides: .hp-section shell, .hp-rail sticky rail,
   .hp-badge pill, .hp-heading, .hp-body
   ============================================================ */


/* ---- Section shell ----------------------------------------
   Background-color is intentionally omitted — each section
   sets its own via a single-rule override. */

.hp-section {
  position:       relative;
  display:        flex;
  flex-direction: column;
  align-items:    center;
  gap:            4rem;      /* 64px */
  padding:        8rem 0;   /* 128px top + bottom */
  font-family:    var(--font-family-default);
  width:          100%;
  box-sizing:     border-box;

}

/* Tablet (≤991px) */
@media (max-width: 991px) {
  .hp-section {
    padding: 6rem 0;
    gap:     3rem;
  }
}

/* Mobile (≤767px) */
@media (max-width: 767px) {
  .hp-section {
    padding: 4rem 0;
    gap:     2rem;
  }
}

/* ---- Tight modifier -----------------------------------------
   Used by the AIR product page, where the default 128px rhythm reads
   as too loose. Same 0.75 / 0.5 tablet/mobile scaling as .hp-section
   above, just off a 96px desktop baseline instead of 128px. Add
   alongside .hp-section (e.g. className="hp-section hp-section--tight
   air-cta"); a section can still override further for anything that
   doesn't fit (see AirHowItWorksSection's mobile padding). */
.hp-section--tight {
  padding-block: 6rem;   /* 96px */
}

@media (max-width: 991px) {
  .hp-section--tight {
    padding-block: 4.5rem;   /* 72px */
  }
}

@media (max-width: 767px) {
  .hp-section--tight {
    padding-block: 3rem;   /* 48px */
  }
}


/* ---- Sticky badge rail ------------------------------------
   Absolutely positioned inside the first .container, pushed
   left via right: calc(100% - 80px).  The offset skips the
   container's left padding so the rail anchors to the content
   edge rather than the padding edge.  .container has
   position: relative so the rail is bounded to the container's
   height — badge stops when the container ends.
   Width = gutter between container (1024px) and container-wide
   (1384px): (1384 − 1024) / 2 = 180px.
   Shown only at ≥1480px — when container-wide is at max-width
   and the gutter is a fixed, predictable size. */

.hp-rail {
  display:        none;
  position:       absolute;
  right:          calc(100% - 80px);   /* 80px = container left padding */
  top:            0;
  bottom:         0;
  width:          calc((1384px - 1024px) / 2);   /* 180px */
  pointer-events: none;
}

.hp-rail__sticky {
  position:        sticky;
  top:             var(--nav-section-offset, 8rem);
  display:         flex;
  justify-content: flex-end;
  align-items:     flex-start;
  padding-right:   12px;   /* 12px gap from the container's left edge */
}

@media (min-width: 1480px) {
  .hp-rail {
    display:         flex;
    justify-content: flex-start;
    align-items:     flex-start;
  }

  .container[data-hp-rail-overflow] > .hp-rail {
    visibility: hidden;
  }
}


/* ---- Badge pill -------------------------------------------
   Base pill used in the sticky rail and as the inline badge.
   .hp-badge--inline controls visibility relative to breakpoint. */

.hp-badge {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  gap:             6px;
  height:          26px;
  padding:         0 var(--spacing-3);
  background:      var(--card);
  border-radius:   var(--radius-full);
  font-size:       var(--font-size-xs);
  font-weight:     var(--font-weight-medium);
  line-height:     var(--line-height-xs);
  color:           var(--foreground);
  white-space:     nowrap;
}

/* Inline variant — shown below 1480px, hidden at and above (matches the rail
   breakpoint so there's never a gap where neither badge shows).

   It carries NO margin: `.section-header` owns badge→heading spacing via its
   24px `gap`. The one exception is a header that deliberately wants margin-
   driven spacing (DemoSection, `gap: 0`), which adds its own
   `.x .hp-badge--inline { margin-bottom }`. */
@media (min-width: 1480px) {
  .hp-badge--inline {
    display: none;
  }

  .container[data-hp-rail-overflow] .hp-badge--inline {
    display: inline-flex;
  }
}

/* Live indicator dot (DemoSection "Live demo" badge) */
.hp-badge__dot {
  display:          block;
  width:            6px;
  height:           6px;
  border-radius:    var(--radius-full);
  background-color: var(--primary);
  flex-shrink:      0;
}

/* ---- Chip variant -----------------------------------------
   A badge with a leading highlight chip + label, e.g.
   "New · Quality Studio". Put .hp-badge--chip on the badge and
   .hp-badge__chip on the leading element. Works in both the
   sticky rail (via <SectionRail className="hp-badge--chip">) and
   the inline position. */

.hp-badge--chip {
  gap:     4px;
  padding: 4px 12px 4px 4px;   /* py-4, pr-12, tight pl-4 so the chip hugs the edge */
}

.hp-badge__chip {
  display:       inline-flex;
  align-items:   center;
  height:        100%;
  padding:       0 8px;
  border-radius: var(--radius-full);
  background:    var(--opacity-primary-20);
  color:         var(--primary);
}


/* ---- Section header --------------------------------------
   Sitewide convention for the badge + heading + body block at
   the top of a section. Use directly (do not clone into a
   per-section class). The inline badge is the first child; the
   heading+body live in `__text`. Spacing is owned here so it is
   identical across every section:
     badge → 24px → text → 36px (heading→body) → 24px → actions

   align-items: flex-start is what keeps the inline badge from
   stretching full-width on small screens. */

.section-header {
  display:        flex;
  flex-direction: column;
  align-items:    flex-start;
  gap:            var(--spacing-6);   /* 24px — owns badge→heading spacing */
}

.section-header__text {
  display:        flex;
  flex-direction: column;
  align-items:    flex-start;         /* don't stretch children — buttons keep their
                                         natural width (paragraphs still wrap at max-width) */
  gap:            var(--spacing-9);   /* 36px */
  max-width:      50rem;              /* 800px readable measure (heading + body) */
}

/* The body keeps the readable measure even when the block is widened (--wide),
   so a wide heading never drags the body to full width. This is the universal
   cap — sections should NOT add their own `.x .hp-body { max-width }`. */
.section-header__text .hp-body {
  max-width: 50rem;
}

/* Modifiers */
.section-header--center {
  align-items: center;
  text-align:  center;
}
/* Heading uses the full width; the body stays capped by the rule above. */
.section-header__text--wide {
  max-width: none;
}

.section-header__text--gap-36 {
  gap: var(--spacing-9);
}

@media (max-width: 767px) {
  .section-header       { gap: var(--spacing-4); }   /* 16px */
  .section-header__text { gap: var(--spacing-6); }   /* 24px */
  .section-header__text--gap-36 { gap: var(--spacing-9); }   /* 36px */
}


/* ---- Section intro row ------------------------------------
   Full-width text-left / action-right row. The copy slot expands to push
   actions to the far edge; text inside keeps the standard 50rem measure. */

.section-intro-row {
  display:     flex;
  align-items: center;
  gap:         2.25rem;   /* 36px */
  width:       100%;
}

.section-intro-row__copy {
  flex:      1;
  min-width: 0;
}

.section-intro-row__copy > .hp-body {
  max-width: 50rem;
}

.section-intro-row__actions {
  flex-shrink: 0;
}

@media (max-width: 767px) {
  .section-intro-row {
    flex-direction: column;
    align-items:    flex-start;
    gap:            2.25rem;   /* 36px */
  }
}


/* ---- Section heading --------------------------------------
   36px regular weight; .fw-bold inside uses bold. */

.hp-heading {
  margin:      0;
  font-size:   2.25rem;
  font-weight: var(--font-weight-regular);
  line-height: 2.5rem;
  color:       var(--foreground);
}

.hp-heading.fw-bold {
  font-weight: var(--font-weight-bold);
}



/* ---- Section subheading -----------------------------------
   24px — used beneath headings as a secondary label. */

.hp-subheading {
  margin:      0;
  font-size:   1.5rem;
  line-height: 2rem;
  color:       var(--foreground);
}


/* ---- Section body text ------------------------------------
   20px regular — used in header intro blocks. */

.hp-body {
  margin:      0;
  font-size:   1.25rem;
  line-height: 1.75rem;
  color:       var(--foreground);
}

@media (max-width: 767px) {
  .hp-heading {
    font-size:   1.875rem;  /* 30px */
    line-height: 2.25rem;   /* 36px */
  }

  .hp-subheading {
    font-size:   1.25rem;   /* 20px */
    line-height: 1.75rem;   /* 28px */
  }

  .hp-body {
    font-size:   1.125rem;  /* 18px */
    line-height: 1.75rem;   /* 28px */
  }
}


/* ---- Shared card shell ------------------------------------
   Secondary background + hairline border + 12px radius.
   Use alongside component class for layout-specific rules. */

.card-secondary {
  background:    var(--secondary);
  border:        0.5px solid var(--border);
  border-radius: 12px;
  box-sizing:    border-box;
}


/* ---- 26px number pill -------------------------------------
   Circular badge used for step numbers.
   Color (background) set per-component. */

.num-pill {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  width:           26px;
  height:          26px;
  flex-shrink:     0;
  border-radius:   var(--radius-full);
  font-size:       var(--font-size-xs);
  font-weight:     var(--font-weight-medium);
  line-height:     1;
  color:           var(--foreground);
}


/* ---- Card typography --------------------------------------
   Base/bold title and base/regular muted body.
   Color overrides applied per-component as needed. */

.card-title {
  margin:      0;
  font-size:   var(--font-size-base);
  font-weight: var(--font-weight-bold);
  line-height: var(--line-height-base);
}

.card-body {
  margin:      0;
  font-size:   var(--font-size-base);
  font-weight: var(--font-weight-regular);
  line-height: var(--line-height-base);
  color:       var(--muted-foreground);
}


/* ---- Page H1 — shared display heading --------------------- */

.page-h1 {
  margin:      0;
  font-size:   3rem;    /* 48px */
  line-height: 1.15;
  font-weight: var(--font-weight-light);
  color:       var(--foreground);
}

.page-h1__line {
  display: block;
}

@media (max-width: 767px) {
  .page-h1 { font-size: 2.25rem; }
}

@media (max-width: 479px) {
  .page-h1 { font-size: 2rem; }

  /* Opt-out of the portrait-mobile shrink: holds the ≤767 size (36px) below
     480px. Add alongside `.page-h1` when a mobile Figma frame keeps the larger
     headline (e.g. AirHeroSection). Replicate the pattern for other heading
     classes if/when the same need arises. */
  .page-h1--no-portrait-shrink { font-size: 2.25rem; }
}


/* ---- Button pair — wrap row + content-driven equal width ---
   A two-(or-more)-button CTA row that never clips or overflows: flex-wrap
   means it stacks instead of clipping when space runs out. Pair with the
   `buttonPairStyle()` helper (src/utils/buttonPair.ts), which sets
   --btn-pair-min-w from the longest label's own character count (a `ch`
   value — scales with the font) — NOT a guessed pixel breakpoint. min-width
   only ever WIDENS a button toward the longest one; it can never shrink a
   button below its own text, so there's no clipping risk either way.

   Applies the equal-ish-width treatment at every size by default. To scope
   it to one breakpoint only (e.g. mobile-only, like AirCtaSection), add a
   local override in the consuming component's CSS:
     .my-actions .btn { min-width: 0; }                          // reset
     @media (max-width: 767px) {
       .my-actions .btn { min-width: var(--btn-pair-min-w, 0); } // re-enable
     }
   Full writeup: docs/shared-css-classes.md → "Button pair". */

.btn-pair {
  display:   flex;
  flex-wrap: wrap;
  gap:       0.75rem;   /* 12px */
}

.btn-pair .btn {
  min-width: var(--btn-pair-min-w, 0);
}

/* ============================================================
   HomepageHero — Homepage hero section
   Design tokens from src/styles/tokens.css.
   ============================================================ */

/* ---- Outer section ---- */
.homepage-hero {
  position:         relative;
  z-index:          150;
  display:          flex;
  flex-direction:   column;
  align-items:      center;
  padding-top:      8rem;      /* 128px — matches Figma pt-[128px] */
  width:            100%;
  font-family:      var(--font-family-default);
  background:       linear-gradient(180deg, var(--background) 0%, var(--secondary) 100%);
  box-sizing:       border-box;
}

/* ---- Inner container — heading + player stacked ---- */
.homepage-hero .container {
  display:        flex;
  flex-direction: column;
  gap:            6rem;        /* 96px — between heading block and player */
}

@media (max-width: 991px) {
  .homepage-hero .container {
    gap: 6rem;                 /* 96px */
  }
}

@media (max-width: 767px) {
  .homepage-hero .container {
    gap: 2rem;               /* 32px */
  }
}


/* ============================================================
   Heading block
   ============================================================ */

.homepage-hero__heading {
  display:        flex;
  flex-direction: column;
  gap:            4rem;        /* 64px — between H1 and intro row */
  width:          100%;
}


/* ---- Intro grid — body+badges left column, actions right ---- */

.homepage-hero__intro {
  display:               grid;
  grid-template-areas:
    "body    actions"
    "badges  actions";
  grid-template-columns: 1fr auto;
  column-gap:            2.25rem;   /* 36px */
  row-gap:               2rem;      /* 32px */
  align-items:           start;
  width:                 100%;
}

.homepage-hero__body {
  grid-area:   body;
  max-width:   46.875rem;      /* 800px */
  margin:      0;
  font-size:   1.25rem;
  font-weight: var(--font-weight-regular);
  line-height: 1.75rem;
  color:       var(--foreground);
}

.homepage-hero__actions {
  grid-area:   actions;
  display:     flex;
  flex-wrap:   wrap;
  gap:         var(--spacing-3);
  align-items: flex-start;
}

.homepage-hero__secondary-cta {
  display: grid;
  gap:     10px;
}

.homepage-hero__secondary-note {
  margin:       0;
  text-align:   center;
  font-size:    var(--font-size-xs);
  line-height:  var(--line-height-xs);
  font-weight:  var(--font-weight-regular);
  color:        var(--muted-foreground);
}

.homepage-hero__badges {
  grid-area: badges;
  max-width: 46.875rem;   /* match body text max-width so badges row aligns */
}

@media (max-width: 991px) {
  .homepage-hero__intro {
    display:        flex;
    flex-direction: column;
    gap:            2.25rem;
  }

  .homepage-hero__body {
    max-width: 100%;
  }

  .homepage-hero__badges {
    margin-top: calc(2rem - 2.25rem);   /* net gap from actions = 2rem */
  }
}

@media (max-width: 520px) {
  .homepage-hero__badges {
    /* Bleed the G2BadgeRow strip past the container padding */
    margin-left:  -2rem;
    margin-right: -2rem;
  }
}


/* ============================================================
   Built-in player — sits above the skyline illustration
   ============================================================ */

.homepage-hero__player {
  position: relative;
  z-index:  1;
  width:    100%;
}




/* ============================================================
   Bottom decoration image — absolutely positioned, takes no space
   Fixed 1512×126px, centered horizontally
   ============================================================ */

.homepage-hero__decoration {
  position:         absolute;
  bottom:           0;
  left:             50%;
  transform:        translateX(-50%);
  width:            1512px;
  max-width:        none;
  height:           126px;
  pointer-events:   none;
  z-index:          0;
  mask-image:       linear-gradient(to right, transparent 0%, black 6%, black 94%, transparent 100%);
  -webkit-mask-image: linear-gradient(to right, transparent 0%, black 6%, black 94%, transparent 100%);
}


/* ============================================================
   No-player fallback — collapse the container gap and add space
   so the illustration is visible:
   64px gap + 126px illustration height = 190px bottom padding
   ============================================================ */

.homepage-hero--no-player {
  padding-bottom: 190px;
}

.homepage-hero--no-player .container {
  gap: 0;
}


/* ============================================================
   Side-by-side layout variant — `layout="side-by-side"`

   Figma: file TQRYxDeQhrpyaPztHCWi8f, node 274:10045 ("Hero ALT2").
   Row: heading 496 | 32 gap | player 596 = 1124px, which is 100px WIDER than
   the 1024px container. Figma keeps the heading flush with the container's
   left gutter (x=244 @1512, where every section below starts) and lets the
   player bleed right to 1368.

   That bleed uses the project's standard **escape-the-container grid** —
   the same technique as VrHeroSection / AirHeroSection / HybridHeroSection.
   See docs/escape-the-container-grid.md for the full pattern and why a
   negative margin or an overflowing flex row is not an acceptable substitute.

   Everything here is CSS. The markup is byte-identical in both layouts —
   only `data-layout` on the section changes — so no text node is added,
   removed, reordered, or re-parented, and A/B tooling bound to these nodes
   keeps matching in either layout.
   ============================================================ */

/* ---- <992px fallback ----
   This variant passes `size="m"` to DemoPlayer at every width (see
   HomepageHero.tsx — the size must be decided at render time or the server
   emits the L player and the browser flashes it before hydration). Below 992px
   the row falls back to stacking, and there the M card is styled to read the
   way the L player used to: full container width, square bottom corners, and
   sitting flush on the skyline with no reserved bottom padding.

   So the floating-card treatment (rounded bottom, reserved padding) lives in
   the >=992px block, NOT here.

   The card keeps DemoPlayerM's own 596px cap at every width — it is not
   stretched to fill the container. Centre it so the capped card does not sit
   orphaned against the container's left edge. A no-op at >=992, where the grid
   column is already <=596. */

.homepage-hero[data-layout="side-by-side"] .demo-player-frame {
  margin-inline: auto;
}


/* ---- Live-demo CTA (Figma node 274:11684) — ALL breakpoints ----
   The CTA restyle belongs to the variant, not to the desktop layout, so it sits
   outside the media query: it drops the 16px outer padding (the box is inset
   only by the card's own 12px), tightens copy->button to 16px, drops the copy
   to 14/20 from 20/28, and bolds the lead sentence onto its own line. The
   bordered box itself already matches Figma (24px padding, 16px radius,
   --secondary, 0.5px --border), as does the `lg` Button (14px, 10px/24px, 40px).

   The `__lead`/`__rest` spans are present in every layout (see HomepageHero.tsx)
   and inline by default, so the stacked layout still reads as one continuous
   sentence — only this variant breaks and boldens them. */
.homepage-hero[data-layout="side-by-side"] .demo-player-live-cta {
  padding: 0 var(--spacing-3) var(--spacing-3);   /* 0 12px 12px */
}

.homepage-hero[data-layout="side-by-side"] .demo-player-live-cta__inner {
  gap: var(--spacing-4);   /* 16px — Figma; DemoPlayer default is 24px */
}

.homepage-hero[data-layout="side-by-side"] .demo-player-live-cta__text {
  font-size:   var(--font-size-sm);     /* 14px — default is 20px */
  line-height: var(--line-height-sm);   /* 20px — default is 28px */
}

.homepage-hero[data-layout="side-by-side"] .demo-player-live-cta__lead {
  display:     block;
  font-weight: var(--font-weight-bold);
}


@media (min-width: 992px) {
  .homepage-hero[data-layout="side-by-side"] {
    /* The skyline decoration is pinned to the section bottom and is 126px tall.
       Stacked puts the player flush on top of it; in the two-column layout the
       content column runs far lower, so reserve the decoration's height plus
       Figma's 19px clearance (skyline top 571 vs content bottom 552) so the
       CTAs never land on it. */
    padding-bottom: 160px;
  }

  /* Here the player is a free-floating rounded card, not flush against the
     decoration, so undo the flatBottom the stacked layout needs. Done in CSS so
     the `flatBottom` prop — and the markup — stay identical in both layouts. */
  .homepage-hero[data-layout="side-by-side"] .demo-player-frame[data-flat-bottom] {
    border-bottom-left-radius:  var(--radius-lg);
    border-bottom-right-radius: var(--radius-lg);
  }

  /* The existing `.container` div is re-cast as the wide wrapper + grid, so the
     variant stays CSS-only. 1480/48px are `.container-wide`'s own values.

     Track 1 is the collapsing gutter: `(100% - 1024px) / 2 - 32px` is exactly
     the distance from the wide container's edge to the standard container's
     edge (minus the 32px spacer), so track 3 starts at x=244 @1512 — aligned
     with every `.container` section on the page. As the viewport narrows the
     clamp drives it to 0px and the row reclaims that space instead of
     overflowing. Tracks 3/5 are `minmax(0, …)` so once the gutter is spent
     they shrink instead of pushing the page into horizontal scroll. */
  .homepage-hero[data-layout="side-by-side"] .container {
    display:               grid;
    grid-template-columns: clamp(0px, calc((100% - 1024px) / 2 - 32px), 148px)
                           32px
                           minmax(0, 496px)
                           32px
                           minmax(0, 596px)
                           1fr;
    align-items:           start;   /* Figma tops both columns at y=0 */
    gap:                   0;
    max-width:             calc(1384px + 96px);   /* 1480 — .container-wide */
    padding:               0 3rem;                /* 48px — .container-wide */
  }

  .homepage-hero[data-layout="side-by-side"] .homepage-hero__heading {
    grid-column: 3;
    /* Paint above the decoration, a later sibling at z-index 0. */
    position:    relative;
    z-index:     1;
    gap:         2rem;   /* 32px — H1 to intro (Figma 191 - 159); stacked uses 4rem */
  }

  .homepage-hero[data-layout="side-by-side"] .homepage-hero__player {
    grid-column: 5;
    min-width:   0;      /* <=596px also makes DemoPlayer's own ResizeObserver
                            render it at size "m" */
  }

  /* Intro drops the stacked grid (body+badges | actions) for a single column,
     body -> badges -> actions. Per-child margins carry the rhythm because
     Figma's three vertical gaps are not uniform. */
  .homepage-hero[data-layout="side-by-side"] .homepage-hero__intro {
    display:        flex;
    flex-direction: column;
    gap:            0;
  }

  .homepage-hero[data-layout="side-by-side"] .homepage-hero__body {
    order:     1;
    max-width: none;
  }

  .homepage-hero[data-layout="side-by-side"] .homepage-hero__badges {
    order:      2;
    max-width:  none;
    margin-top: 2rem;    /* 32px — body to medal row (Figma 116 - 84) */
  }

  /* Figma's medal row is 420px — six 60px badges + five 12px gaps, NOT
     stretched to the column width. Overrides the primitive's count-derived
     115px-per-badge cap, which would let them grow to ~69px in this column. */
  .homepage-hero[data-layout="side-by-side"] .g2-badge-row {
    max-width: 420px;
  }

  /* No hairline above the medal row in this frame — the 32px gap does that job.
     Hidden rather than removed so the DOM matches the stacked layout exactly;
     display:none also collapses .g2-badge-row's own 2rem divider->badges gap. */
  .homepage-hero[data-layout="side-by-side"] .g2-badge-row__divider {
    display: none;
  }

  .homepage-hero[data-layout="side-by-side"] .homepage-hero__actions {
    order:      3;
    margin-top: 2.25rem;   /* 36px — medal row to buttons (Figma 221.17 - 185.17) */
  }

  /* ---- Player card: 520px including the live-demo CTA ----
     Figma "Demo player V3" = 12 pad + 398 body + 10 + 88 CTA + 12 = 520.
     Pin the card and let the body take whatever the CTA leaves, rather than
     hard-coding a body height that would drift the moment the CTA copy
     rewraps. The M transcript pane already scrolls, so it absorbs the change.
     Scoped here only — DemoPlayerM's 474px default is right everywhere else,
     including this hero's own stacked layout. */
  .homepage-hero[data-layout="side-by-side"] .demo-player-frame {
    display:        flex;
    flex-direction: column;
    height:         520px;
  }

  .homepage-hero[data-layout="side-by-side"] .demo-player[data-size="m"] {
    height:     auto;
    flex:       1 1 auto;
    min-height: 0;
  }
}


/* ============================================================
   Mobile — landscape/tablet (≤767px)
   ============================================================ */

@media (max-width: 767px) {
  .homepage-hero {
    padding-top: 5rem;         /* 80px */
  }

  .homepage-hero__heading {
    gap:            2rem;    /* 32px */
    padding-bottom: 2rem;      /* 32px */
  }

  .homepage-hero__actions {
    flex-direction: column;
  }

  .homepage-hero__secondary-note {
    padding-left: 1.5rem;
    text-align:   left;
  }
}


/* ============================================================
   Portrait mobile (≤479px)
   ============================================================ */

@media (max-width: 479px) {
  .homepage-hero {
    padding-top: 4rem;         /* 64px */
  }

}

/* ============================================================
   Container — shared responsive layout constraint
   Provides 1024px max content width with responsive side padding.
   Import this in any component that uses the .container class.
   ============================================================ */

.container {
  position:   relative;
  width:      100%;
  max-width:  calc(1024px + 160px); /* 1024px content + 80px × 2 */
  padding:    0 80px;
  margin:     0 auto;
  box-sizing: border-box;
}

/* Tablet (≤991px): 60px sides */
@media (max-width: 991px) {
  .container {
    padding: 0 60px;
  }
}

/* Landscape mobile (≤767px): 2rem sides */
@media (max-width: 767px) {
  .container {
    padding: 0 2rem;
  }
}



/* ============================================================
   Wide container — 1360px content + 48px side padding
   Used for full-bleed section content blocks (slider, big cards)
   that need to be wider than the standard 1024px text container.
   ============================================================ */

.container-wide {
  width:      100%;
  max-width:  calc(1384px + 96px);   /* 1384px content + 48px × 2 */
  padding:    0 3rem;                /* 48px sides */
  margin:     0 auto;
  box-sizing: border-box;
}

/* Tablet (≤991px): 16px less than .container (60px → 44px) */
@media (max-width: 991px) {
  .container-wide {
    padding: 0 44px;
  }
}

/* Landscape mobile (≤767px): 16px less than .container (2rem → 1rem) */
@media (max-width: 767px) {
  .container-wide {
    padding: 0 1rem;
  }
}


/* ============================================================
   G2BadgeRow — Horizontal row of G2 badge images.
   Desktop: static flex row.
   Mobile (≤520px): infinite auto-scroll strip with touch drag,
   driven by JS in G2BadgeRow.tsx.
   ============================================================ */

.g2-badge-row {
  display:        flex;
  flex-direction: column;
  gap:            2rem;   /* divider → badges */
  /* Count-derived cap (set inline in G2BadgeRow.tsx) so no badge exceeds 115px. */
  max-width:      var(--g2-row-max-width, none);
}

.g2-badge-row__divider {
  width:      100%;
  border-top: 1px solid var(--divider);
}

.g2-badge-row__strip {
  mix-blend-mode: multiply;
}

.g2-badge-row__track {
  display:     flex;
  gap:         var(--spacing-3);   /* 12px */
  align-items: center;
  flex-wrap:   nowrap;
}

.g2-badge-row__clone {
  display: none;
}

.g2-badge-row__badge {
  flex:      1 1 60px;
  min-width: 0;
  height:    auto;
}


/* ============================================================
   Mobile scroll strip (≤520px)
   STANDARD: when the row becomes a scroll strip it MUST run full-bleed
   (edge-to-edge, full viewport width) — same as HomepageHero. The primitive
   can't know the caller's padding, so every consumer is responsible for the
   bleed: add negative margins equal to the container's horizontal padding on
   the wrapper around <G2BadgeRow> at ≤520px (e.g. HomepageHero & AirHeroSection
   use `margin: 0 -2rem`). See docs/conventions.md.
   ============================================================ */

@media (max-width: 520px) {
  /* Drop the badge-width cap so the marquee strip stays full-bleed. */
  .g2-badge-row {
    max-width: none;
  }

  .g2-badge-row__strip {
    overflow: hidden;
  }

  .g2-badge-row__track {
    gap:         0;
    will-change: transform;
  }

  /* Each badge owns its trailing gap — both halves equal width → seamless loop */
  .g2-badge-row__badge {
    flex:         none;
    width:        60px;
    margin-right: var(--spacing-3);   /* 12px — must match SET_WIDTH calc in G2BadgeRow.tsx */
  }

  .g2-badge-row__clone {
    display: contents;
  }
}

