/* ============================================================
   LegalHubHeroBlock — Figma N6oJX6O9cUvOOEVBwsf57w, frame "Hero section"
   946:8413. Spec: LegalHubHeroBlock.figma.md.

   The wrapper that makes the hero and the social-proof bento one visual unit.
   It owns exactly one thing: the grained ground band behind both of them.
   All layout stays in the two section stylesheets.
   ============================================================ */

.legal-hub-hero-block {
  position:    relative;
  width:       100%;
  background:  var(--background);
  box-sizing:  border-box;
}

/* Figma 946:8415 — 725px tall, bottom edge flush with the frame's (1364).
   Bottom-pinned rather than offset from the top, so it stays put no matter what
   the hero above it does; `.grained-ground` (section.css) paints the fill and
   the grain ramp. `max-height` keeps it inside the block at narrow widths,
   where the two sections can be shorter than 725px combined. */
.legal-hub-hero-block__ground {
  position:       absolute;
  right:          0;
  bottom:         0;
  left:           0;
  height:         725px;
  max-height:     100%;
  pointer-events: none;
  /* Stacking context, so the grain's `multiply` blends against the band's own
     fill and nothing else. Both sections paint above it — see below. */
  z-index:        0;
}

/* Each section paints its own page-cream background so it still stands alone in
   its own story. In here the band owns the surface, so that background has to
   go or it would cover the band completely.

   The hero already carries `z-index: 150` of its own (it has to out-rank the
   section below it for the player's dropdown); the bento only needs to clear
   the band. */
.legal-hub-hero-block > .legal-hub-hero,
.legal-hub-hero-block > .legal-hub-social-proof {
  background: none;
}

.legal-hub-hero-block > .legal-hub-social-proof {
  z-index: 1;
}

/* ============================================================
   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;
  }
}


/* ============================================================
   LegalHubHeroSection — Figma Z4nd44TYu5d8ttn7Y73Djs, node 865:5644.
   Spec: LegalHubHeroSection.figma.md.

   The row is a plain centered 1162px wrapper, NOT `.container` and NOT the
   escape-the-container grid HomepageHero needs: Figma centres it (175 + 1162 +
   175 = 1512), so a max-width + auto margins is exact. Sections below the hero
   are on the standard 1024px `.container` and deliberately do not align with it.
   ============================================================ */

.legal-hub-hero {
  position:      relative;
  z-index:       150;
  width:         100%;
  /* 160px — the hero row's top edge sits 160px below the section's top edge in
     Figma (the earlier 128px came from reading the row's y in *frame*, not
     section, coordinates). Section box = 160 + 520 row + 48 = 728. */
  padding-top:   10rem;     /* 160px */
  /* 48px — what Figma's "Hero (ALT2)" frame leaves under the 520px row (it
     ends at 728; the row ends at 680). An earlier build read 64 here by taking
     the row's bottom as 648, which missed the H1 frame's own 32px offset, and
     the hero→bento gap came out 152 against Figma's 120.
     LegalHubSocialProofSection carries the other 72, so each section still
     stands alone in its own story. */
  padding-bottom: 3rem;     /* 48px */
  font-family:   var(--font-family-default);
  background:    var(--background);
  box-sizing:    border-box;
}

/* ---- Row: copy | player ----
   Proportional tracks (508 : 596) so both columns scale together below 1162px
   instead of one collapsing. 58px is Figma's gap (player x=567.26 in the row). */
.legal-hub-hero__row {
  /* Above LegalHubHeroBlock's ground band, which is an earlier sibling of this
     section at z-index 0. */
  position:              relative;
  z-index:               1;
  display:               grid;
  grid-template-columns: minmax(0, 508fr) minmax(0, 596fr);
  gap:                   3.625rem;   /* 58px */
  align-items:           center;     /* copy column is justify-center vs the 520px player */
  width:                 100%;
  max-width:             calc(1162px + 96px);
  padding:               0 3rem;     /* 48px — matches .container-wide's gutters */
  margin:                0 auto;
  box-sizing:            border-box;
}


/* ============================================================
   Copy column (865:5691)
   ============================================================ */

.legal-hub-hero__copy {
  display:        flex;
  flex-direction: column;
  gap:            var(--spacing-9);   /* 36px — H1 → intro, intro → actions */
  min-width:      0;
}

/* Figma sets this hero's H1 at 60px, larger than `.page-h1`'s repo-wide 48px.
   Kept as a raw value scoped to this section rather than a new global token —
   the type scale stops at `--font-size-3xl` (30px), and adding a 5xl would
   invite other pages to drift onto it. See spec watch-item 1.

   Fluid between 992px and 1258px: the copy track is proportional, so at 992px
   it is only ~386px wide and a fixed 60px headline would rewrap into six lines,
   blowing the row past 520px. The formula keeps the type at a constant fraction
   of the track — track total is `100vw - 96 padding - 58 gap`, of which the
   copy column takes 508/1104 — so 60/1104 of it reproduces Figma's 60px exactly
   at >=1258px (where the row hits its max-width) and scales down in lockstep
   below that. Floors at `.page-h1`'s 48px.

   `text-wrap: balance` (not `pretty`) does the line breaking: the headline is a
   single <h1> with no hard line spans, and Figma's three lines come out of the
   481px measure evenly instead of a long-long-short ragged stack. `pretty` only
   protects the LAST line from an orphan and would leave the first two uneven —
   balance is the right tool for a short display heading (browsers cap it at ~6
   lines, and this is 3). */
.legal-hub-hero__title {
  font-size:   clamp(3rem, calc((100vw - 154px) * 60 / 1104), 3.75rem);
  line-height: 1.1;       /* 66px at 60px — Figma's three baselines sit 66px
                             apart, not the 60px the spec claimed */
  max-width:   481px;     /* Figma text box width — also the measure `balance`
                             works within */
  text-wrap:   balance;
}

.legal-hub-hero__intro {
  display:        flex;
  flex-direction: column;
  gap:            var(--spacing-8);   /* 32px — body → medal row */
}

.legal-hub-hero__body {
  max-width:   50rem;     /* 800px */
  margin:      0;
  font-size:   var(--font-size-xl);     /* 20px */
  line-height: var(--line-height-xl);   /* 28px */
  font-weight: var(--font-weight-regular);
  color:       var(--foreground);
}

/* Figma's medal row is 420px — six 60px badges + five 12px gaps, NOT stretched
   to the column. Overrides G2BadgeRow's count-derived per-badge cap. */
.legal-hub-hero__badges .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 primitive's markup is untouched; this also
   collapses its own divider→badges gap. */
.legal-hub-hero__badges .g2-badge-row__divider {
  display: none;
}

/* Flex + 12px gap come from the shared `.btn-pair` (section.css). Two things
   are ours: the cross-axis alignment (the note makes the secondary column
   taller, and both buttons must top-align), and `nowrap` — the collapse point
   is measured in JS (LegalHubHeroSection.tsx), and btn-pair's own `wrap` would
   beat that measurement to it and drop the secondary onto its own line at its
   natural width instead of the equal width the stacked state wants. Same
   trade-off AirHeroSection makes. */
.legal-hub-hero__actions {
  align-items: flex-start;
  flex-wrap:   nowrap;
}

/* Both children must keep their natural width: the effect measures them in the
   row state to decide when to stack, and flex's default `shrink: 1` would let
   them compress first — so it would measure the already-squeezed widths, judge
   that they still fit, and both leave the buttons visibly squashed AND size the
   stacked primary to a too-narrow value. Overflow is not a risk: the observer
   switches to `stacked` on the same frame the row stops fitting. */
.legal-hub-hero__actions > * {
  flex-shrink: 0;
}

/* Narrowest state: the two buttons stack, both sized to the secondary group by
   the measuring effect. Chosen by JS, not a breakpoint. */
.legal-hub-hero__actions[data-cta="stacked"] {
  flex-direction: column;
}

.legal-hub-hero__secondary-cta {
  display: grid;
  gap:     10px;   /* Figma "Button wrapper" gap */
}

.legal-hub-hero__secondary-note {
  margin:      0;
  text-align:  center;
  white-space: nowrap;   /* wrap as a whole unit, never mid-phrase — also keeps
                            the measured group width stable */
  font-size:   var(--font-size-xs);     /* 12px */
  line-height: var(--line-height-xs);   /* 16px */
  font-weight: var(--font-weight-regular);
  color:       var(--muted-foreground);
}


/* ============================================================
   Player column (865:5716 "Demo player V3", 596×520)

   Same wiring as HomepageHero's side-by-side layout — see that file's comments
   for why the size is a prop rather than a ResizeObserver result. Everything
   here is scoped to `.legal-hub-hero`; DemoPlayer's own defaults are untouched.
   ============================================================ */

.legal-hub-hero__player {
  position:  relative;
  z-index:   1;
  min-width: 0;
  width:     100%;
}

/* Keep the M card's own 596px cap centred rather than orphaned left once the
   column is wider than the card (only reachable while stacked). */
.legal-hub-hero .demo-player-frame {
  margin-inline: auto;
}

/* Live-demo CTA (Figma "Live demo CTA" 865:5839): no outer padding beyond the
   card's own 12px, 16px copy→button, 14/20 text, bold lead on its own line. */
.legal-hub-hero .demo-player-live-cta {
  padding: 0 var(--spacing-3) var(--spacing-3);   /* 0 12px 12px */
}

.legal-hub-hero .demo-player-live-cta__inner {
  gap: var(--spacing-4);   /* 16px — DemoPlayer default is 24px */
}

.legal-hub-hero .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 */
}

.legal-hub-hero .demo-player-live-cta__lead {
  display:     block;
  font-weight: var(--font-weight-bold);
}

@media (min-width: 992px) {
  /* 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, so the height
     can't drift when the CTA copy rewraps. The M transcript pane scrolls. */
  .legal-hub-hero .demo-player-frame {
    display:        flex;
    flex-direction: column;
    height:         520px;
  }

  .legal-hub-hero .demo-player[data-size="m"] {
    height:     auto;
    flex:       1 1 auto;
    min-height: 0;
  }
}


/* ============================================================
   Tablet + mobile
   ============================================================ */

@media (max-width: 991px) {
  /* Half the desktop 48. Stacked, the player card sits directly above the
     social-proof bento, and 48 + that section's 72 read as a hole between two
     cards that belong together; 24 + its 36 halves the pair to 60. The ≤767
     rule below overrides this again with the mobile frame's 12. */
  .legal-hub-hero {
    /* The desktop 160px is the air Figma leaves above a two-column hero on a
       1512 frame. Stacked, it reads as a hole above the headline — the mobile
       frame opens at 32 (the ≤767 rule below). 64 is the tablet middle. */
    padding-top:    4rem;     /* 64px */
    padding-bottom: 1.5rem;   /* 24px */
  }

  .legal-hub-hero__row {
    grid-template-columns: minmax(0, 1fr);
    gap:                   4rem;   /* 64px — copy → player when stacked */
    /* Stacked, the hero drops onto `.container`'s gutter ladder (60px / 32px)
       rather than `.container-wide`'s (44 / 16), so the copy shares one left
       edge with every section beneath it. The 175px desktop inset is Figma's
       and stays — it only applies while the row is two columns. */
    padding:               0 60px;
  }

  /* The fluid 60px headline is desktop-only; stacked, the copy column is full
     width again so the `.page-h1` ladder (48 → 36 → 32) and its 1.15 take over.
     `max-width` is dropped but `text-wrap: balance` stays: it keeps the wrapped
     headline from ending on a one-word line at every stacked width. */
  .legal-hub-hero__title {
    font-size:   3rem;   /* 48px */
    line-height: 1.15;
    max-width:   none;
  }
}

@media (max-width: 767px) {
  /* The mobile frame (N6oJX6O9cUvOOEVBwsf57w 929:13372) opens the headline
     flush under the 72px navbar. 80px was far more air than that; 32 keeps a
     little without reading as a gap. The 12 below pairs with the social-proof
     section's own 12 to make the frame's 24px between the player and the
     bento. */
  .legal-hub-hero {
    padding-top:    2rem;      /* 32px */
    padding-bottom: 0.75rem;   /* 12px — half of the frame's 24 */
  }

  .legal-hub-hero__row {
    gap:     2rem;    /* 32px */
    padding: 0 2rem;  /* 32px — `.container` at this width, and the frame's
                         32px inset for the copy column */
  }

  /* The frame insets the copy 32px but the player card only 16 — the same
     gutter the bento below it uses. Half the row's gutter is given back here
     so the two cards line up down the page. */
  .legal-hub-hero__player {
    /* `width: auto`, not the base 100%: a percentage width is resolved against
       the grid area, so with `width: 100%` the negative margins only SHIFTED
       the 100%-wide box 16px left instead of widening it — which is why the
       card read as left-aligned with a gap on the right. Letting the grid item
       stretch lets both margins pull the edges out symmetrically. */
    width:         auto;
    margin-inline: -1rem;   /* 16px */
  }

  .legal-hub-hero__title {
    font-size: 2.25rem;   /* 36px */
  }
}

/* G2BadgeRow turns into an auto-scrolling strip at <=520px and that strip MUST
   run full-bleed; the primitive can't know our gutter, so the consumer bleeds
   it (docs/conventions.md → "G2 badge marquee — always full-bleed on mobile").
   The 420px cap has to go with it: `.legal-hub-hero__badges .g2-badge-row`
   out-specifies the primitive's own `max-width: none`, so left in place it
   would pin the marquee to 420px instead of letting it run edge to edge. */
@media (max-width: 520px) {
  .legal-hub-hero__badges {
    margin-left:  -2rem;   /* cancels the row's 2rem gutter at <=767px */
    margin-right: -2rem;
  }

  .legal-hub-hero__badges .g2-badge-row {
    max-width: none;
  }
}

@media (max-width: 479px) {
  .legal-hub-hero {
    padding-top: 1.5rem;   /* 24px */
  }

  .legal-hub-hero__title {
    font-size: 2rem;   /* 32px */
  }
}

/* ============================================================
   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;
  }
}

/* ============================================================
   LegalHubSocialProofSection — Figma Z4nd44TYu5d8ttn7Y73Djs, node 865:5846.
   Spec: LegalHubSocialProofSection.figma.md.
   ============================================================ */

.legal-hub-social-proof {
  position:    relative;
  width:       100%;
  /* Figma leaves 120px between the hero row (ends 680) and this bento (starts
     800); the hero owns 48 of it (see LegalHubHeroSection.css), so 72 here.
     Was 88 against a 64 — a 152px total, from an earlier reading that put the
     row's bottom at 648 and missed the H1 frame's 32px offset. */
  padding-top:    4.5rem;   /* 72px */
  padding-bottom: 5rem;     /* 80px — logo reel bottom (1285) to hero frame end (1364) */
  font-family: var(--font-family-default);
  box-sizing:  border-box;

  /* The grained ground behind this section belongs to LegalHubHeroBlock, which
     wraps it and the hero and paints Figma's one 725px rect (946:8415) as a
     single band. This section paints only its own page-cream background, which
     the block clears so the band shows through. Nothing here slices a ramp. */
}

/* Same 1162px centred wrapper as the hero — not `.container`. */
.legal-hub-social-proof__wrap {
  width:      100%;
  max-width:  calc(1162px + 96px);
  padding:    0 3rem;   /* 48px */
  margin:     0 auto;
  box-sizing: border-box;
}

.legal-hub-social-proof__bento {
  /* 16 (inset) + 260 (row) + 16 = the card's 292px height. The logo reel used
     to live in here too; it is now a full-bleed band below the card. */
  padding:        1rem 0.9375rem;
  background:     var(--secondary);
  border-radius:  var(--radius-lg);   /* 24px */
  box-sizing:     border-box;
  overflow:       hidden;
}

/* `stretch`, not `flex-start`: below ~1258px the stats/ratings column grows
   taller than the blue tile's natural 263px (labels rewrap, the ratings row
   pairs up) and a flex-start tile left a dead notch under itself. At the design
   width the tile IS the taller item, so stretch changes nothing there. */
.legal-hub-social-proof__row {
  display:     flex;
  gap:         var(--spacing-6);   /* 24px */
  align-items: stretch;
}


/* ============================================================
   Blue quote tile (865:5848)
   ============================================================ */

.legal-hub-social-proof__quote-card {
  display:        flex;
  flex-direction: column;
  gap:            var(--spacing-5);   /* 20px */
  flex:           0 0 300px;
  width:          300px;
  padding:        var(--spacing-3) var(--spacing-4) var(--spacing-5);   /* 12 16 20 */
  /* Figma: white with a 20% #59B7D9 overlay — `--opacity-info-20` is exactly
     that colour (#59B7D933), so the two layers reproduce it precisely. */
  background:     linear-gradient(var(--opacity-info-20), var(--opacity-info-20)),
                  var(--card);
  border:         0.5px solid var(--border);
  border-radius:  var(--radius-md);   /* 16px */
  box-sizing:     border-box;
}

.legal-hub-social-proof__headline-stat {
  display:        flex;
  flex-direction: column;
  gap:            var(--spacing-1-5);   /* 6px */
  padding:        var(--spacing-3) var(--spacing-2) 0 var(--spacing-4);   /* 12 8 0 16 */
}

/* 60px is outside the repo type scale (which stops at `--font-size-3xl`, 30px).
   Kept as a scoped raw value rather than a new global token — same call as the
   hero H1. See spec watch-item 1. */
.legal-hub-social-proof__headline-value {
  margin:      0;
  font-size:   3.75rem;   /* 60px */
  /* Figma's text node is 66px tall for a 60px face — 1.1, not 1. At `1` the
     label rides 6px high and the whole tile comes up 254px instead of 260. */
  line-height: 1.1;       /* 66px */
  font-weight: var(--font-weight-light);
  color:       var(--foreground);
}

.legal-hub-social-proof__headline-label {
  margin:      0;
  font-size:   var(--font-size-xl);     /* 20px */
  line-height: var(--line-height-xl);   /* 28px */
  font-weight: var(--font-weight-regular);
  color:       var(--foreground);
}

/* Takes the slack when the tile is stretched taller than its content; the
   hairline stays pinned under the headline stat and `__quote-body`'s auto block
   margins centre the quote in whatever is left. At the design height there is no
   slack, so the auto margins collapse and this renders exactly as before. */
.legal-hub-social-proof__quote {
  display:        flex;
  flex-direction: column;
  gap:            var(--spacing-5);   /* 20px */
  flex:           1 1 auto;
}

/* Figma's opening quote is a separate blue mark hung outside the text column
   (9x8px of ink at 2px/25px into the quote block), not part of the sentence —
   so the string starts on `Smith.ai` and only closes with a curly quote.
   36px of the body face puts the ink at exactly that size and offset.

   Anchored to `__quote-body`, NOT to `__quote`: the body now moves inside the
   quote block (centred when the tile is stretched, again when the tile goes
   side-by-side on tablet) and a mark pinned to the block would be left behind.
   -3px is the old 18px-from-the-block offset minus the body's own 21px inset
   (the 0.5px rule + the 20px gap), so the ink lands where it always did. */
.legal-hub-social-proof__quote-body::before {
  content:     '“';
  position:    absolute;
  left:        0;
  top:         -3px;
  font-size:   2.25rem;    /* 36px */
  line-height: 1;
  color:       var(--info);
}

.legal-hub-social-proof__rule {
  width:  100%;
  height: 0;
  margin: 0;
  border: 0;
  border-top: 0.5px solid var(--border);
}

.legal-hub-social-proof__quote-body {
  position:       relative;
  display:        flex;
  flex-direction: column;
  gap:            var(--spacing-3);   /* 12px */
  margin-block:   auto;
  padding-inline: var(--spacing-4);   /* 16px */
}

.legal-hub-social-proof__quote-text {
  margin:      0;
  font-size:   var(--font-size-base);     /* 16px */
  line-height: var(--line-height-base);   /* 24px */
  font-weight: var(--font-weight-light);
  color:       var(--foreground);
}

.legal-hub-social-proof__author {
  display:     flex;
  flex-wrap:   wrap;
  gap:         var(--spacing-2);   /* 8px */
  align-items: center;
  margin:      0;
  font-size:   var(--font-size-xs);     /* 12px */
  line-height: var(--line-height-xs);   /* 16px */
  font-weight: var(--font-weight-regular);
}

.legal-hub-social-proof__author-name { color: var(--foreground); }
.legal-hub-social-proof__author-role { color: var(--muted-foreground); }


/* ============================================================
   Stats + ratings column (865:5873)
   ============================================================ */

/* A size container: the stats row and the ratings row answer to the width THEY
   have, not the viewport's. The same ~700px column happens at a 1050px viewport
   (side by side with the tile) and at an 820px one (stacked under it), and it
   wants the same treatment in both. Rules that react to it live in the
   `@container lh-proof-main` blocks at the bottom of this file. */
.legal-hub-social-proof__main {
  container-type: inline-size;
  container-name: lh-proof-main;
  display:        flex;
  flex-direction: column;
  /* Figma sets the pill+stats block at y=12..202 and the ratings row at y=206
     inside a 254px column — the stats' own 24px bottom padding carries the
     visual breathing room, so the flex gap is only 4px. */
  gap:            var(--spacing-1);   /* 4px */
  flex:           1 1 0;
  min-width:      0;
  padding-top:    var(--spacing-3);   /* 12px */
}

.legal-hub-social-proof__head {
  display:        flex;
  flex-direction: column;
  gap:            var(--spacing-4);   /* 16px */
  align-items:    flex-start;
}

.legal-hub-social-proof__pill {
  margin:        0;
  padding:       var(--spacing-1) var(--spacing-4);   /* 4px 16px */
  background:    var(--card);
  border-radius: var(--radius-full);
  font-size:     var(--font-size-xs);     /* 12px */
  line-height:   var(--line-height-xs);   /* 16px */
  font-weight:   var(--font-weight-medium);
  color:         var(--muted-foreground);
}

/* Figma: stat(158) | spacer | stat(262) | spacer | stat(245) with 12px gaps
   inside an 808px column, leaving ~47px per spacer. Expressed as `fr` so the
   whole row keeps those exact proportions at any width instead of the wider
   stats swallowing the slack and rewrapping their labels differently. */
.legal-hub-social-proof__stats {
  display:               grid;
  grid-template-columns: 158fr 47fr 262fr 47fr 245fr;
  gap:                   var(--spacing-3);   /* 12px */
  align-items:           stretch;
  width:                 100%;
}

.legal-hub-social-proof__stat {
  display:         flex;
  flex-direction:  column;
  gap:             var(--spacing-1-5);   /* 6px */
  /* Figma starts every stat's number at y=24 in the 150px row. `flex-end` reads
     the same at desktop (all three columns wrap to two label lines and stretch
     equal) but bottom-aligns `4,000+` alone once the row rewraps on tablet. */
  justify-content: flex-start;
  min-width:       0;
  padding:         var(--spacing-6) var(--spacing-4);   /* 24px 16px */
  box-sizing:      border-box;
}

/* Figma's separator is a 142px line in the spacer column, top-aligned with the
   150px stats row (the row is items-start) — centring it drops it 4px. */
/* Only the stacked layout draws a hairline under the last stat; in a row it
   would be a sixth grid item wrapping to a line of its own. */
.legal-hub-social-proof__stat-rule--trailing {
  display: none;
}

.legal-hub-social-proof__stat-rule {
  justify-self: center;
  align-self:   start;
  width:        0;
  height:       142px;
  border-left:  0.5px solid var(--border);
}

.legal-hub-social-proof__stat-value {
  margin:      0;
  font-size:   2.25rem;   /* 36px — between --font-size-3xl (30) and the scale's end */
  line-height: 2.5rem;    /* 40px */
  font-weight: var(--font-weight-regular);
  color:       var(--foreground);
}

.legal-hub-social-proof__stat-label {
  margin:      0;
  font-size:   var(--font-size-lg);     /* 18px */
  line-height: var(--line-height-lg);   /* 28px */
  font-weight: var(--font-weight-regular);
  color:       var(--muted-foreground);
}

/* Inside this bento the four scores are bare — no chip background, border or
   heavy padding. All scoped to the section; RatingsBar's own strip styling is
   what every other consumer still gets.

   Only the descendant rules below are set here. `.ratings-bar--strip` carries the
   row's own grid (4 equal tracks, 12px gaps) on a single class, exactly like the
   section's hook, so anything set on the row itself is decided by stylesheet
   order rather than intent — and the primitive's grid already lands within ~11px
   of Figma's row at each end. Content-sized tracks would want 843px in an 808px
   column, so the grid is left to the primitive on purpose. */
/* Figma spreads four naturally-sized groups across the 808px row (edges ~11px,
   ~24px between) rather than sitting them in four equal columns. RatingsBar's
   own `repeat(4, 1fr)` grid + 12px gap is right for its card layout elsewhere;
   here it stretches each group and breaks the tight logo→stars rhythm. */
/* Doubled class: RatingsBar.css loads AFTER this file (the primitive is imported
   below the section's own stylesheet), so a single-class rule ties on
   specificity and loses on order. */
/* A grid of four content-sized tracks spread by `space-around` renders exactly
   like the flex row this replaces, but it can be re-tracked to two columns in
   the container query below. Flex wrapping could only ever drop ONE mark to a
   second row (3 + 1), which is what it did between ~1130px and 1258px. */
.legal-hub-social-proof__ratings.ratings-bar {
  display:               grid;
  grid-template-columns: repeat(4, max-content);
  justify-content:       space-around;
  gap:                   0;
}

.legal-hub-social-proof__ratings .ratings-bar__item {
  flex: 0 0 auto;
}

/* THE spacing fix: RatingsBar pads every mark out to a fixed 64px box, which is
   invisible for Capterra and Trustpilot (both exactly 64 wide) but appends dead
   space to the two narrow marks — Clutch (48) read as a 32px logo→stars gap and
   G2 (30) as 50px, against Figma's flat 16px for all four. Let the box hug the
   mark so the 16px `gap` on `__item` is the whole gap. */
.legal-hub-social-proof__ratings .ratings-bar__logo {
  width: auto;
}

.legal-hub-social-proof__ratings .ratings-bar__item {
  /* 9 + 30 (the tallest mark, G2) + 9 = Figma's 48px ratings row. RatingsBar's
     own 24px padding makes it 62px here and pushes the logo reel down with it. */
  padding:       9px var(--spacing-1);
  gap:           var(--spacing-4);                    /* 16px */
  background:    none;
  border:        0;
  border-radius: 0;
}

/* Stop the meta block from growing — Figma keeps logo + stars + score tight. */
.legal-hub-social-proof__ratings .ratings-bar__meta {
  flex: 0 0 auto;
}

/* Figma's stars are 12.8px with 3.2px gaps → 76.8px for the row of five. */
.legal-hub-social-proof__ratings .ratings-bar__stars {
  flex:      0 0 auto;
  width:     76.8px;
  max-width: none;
}


/* ============================================================
   Full-bleed logo reel (946:9014)
   ============================================================ */

/* Sits outside `__wrap`, so it already spans the viewport. Figma leaves 80px
   between the card's bottom edge and the logo band; the reel's own top padding
   (24px + 34px of label space) covers 58 of it.

   The reel runs `edgeFade="mask"` (set in the TSX), so its edges are cut out of
   the reel itself and the grained band behind shows through them untouched. The
   default `wash` cannot work here: it paints a flat `--background` gradient over
   the logos, which on a grained band reads as two smooth ungrained rectangles
   244px wide. An earlier build tried to hide that by rebinding `--background` to
   a `color-mix()` guess at the band's colour at this depth; the colour was close
   but the missing texture still gave it away. */
.legal-hub-social-proof__reel {
  --logo-reel-edge-fade-width: 244px;

  margin-top: 2.875rem;   /* 46px */
}


/* ============================================================
   Tablet + mobile
   ============================================================ */

@media (max-width: 991px) {
  /* Half the desktop 72, to the hero's halved 48 — 60px between the player card
     and this one once they are stacked. The ≤767 rule below takes it to the
     mobile frame's 12. */
  .legal-hub-social-proof {
    padding-top: 2.25rem;   /* 36px */
  }

  .legal-hub-social-proof__wrap {
    padding: 0 44px;
  }

  .legal-hub-social-proof__row {
    flex-direction: column;
    /* Mobile frame: the tile ends at 276 and the stats column starts at 308. */
    gap:            var(--spacing-8);   /* 32px */
  }

  .legal-hub-social-proof__quote-card {
    flex:  0 0 auto;
    width: 100%;
  }

  .legal-hub-social-proof__main {
    width:       100%;
    padding-top: 0;
  }

  /* The mobile frame closes the card 16px under the ratings, the same as its
     other three sides. Owner's call to give the paired ratings rows a little
     more room to land in: 24 here, so the last row clears the card edge by 36
     (its own 12px of padding included). */
  .legal-hub-social-proof__bento {
    padding-bottom: var(--spacing-6);   /* 24px */
  }
}

/* Tablet only: the tile is full-width but its content is not tall enough to
   fill it, so the headline stat and the quote sit side by side with the
   hairline stood on its end between them, both vertically centred. Below 768
   the mobile frame stacks them again. */
@media (min-width: 768px) and (max-width: 991px) {
  /* `stretch`, so the hairline between the halves can run the tile's full
     content height. The two halves centre themselves inside it instead —
     `__headline-stat` here, the quote via `__quote-body`'s auto margins. */
  .legal-hub-social-proof__quote-card {
    flex-direction: row;
    align-items:    stretch;
    gap:            var(--spacing-8);   /* 32px */
  }

  .legal-hub-social-proof__headline-stat {
    flex:            0 1 auto;
    justify-content: center;
    padding-block:   var(--spacing-3);   /* 12px — no longer the tile's top edge */
  }

  .legal-hub-social-proof__quote {
    flex-direction: row;
    align-items:    stretch;
    flex:           1 1 0;
    min-width:      0;
  }

  /* Same 0.5px hairline, rotated. Stacked it runs the tile's full width, well
     past the text it divides; standing up it does the same vertically. */
  .legal-hub-social-proof__rule {
    width:      0;
    height:     auto;
    align-self: stretch;
    border-top:  0;
    border-left: 0.5px solid var(--border);
  }
}

@media (max-width: 767px) {
  /* Mobile frame: 24px from the player card to this one (the hero above pays
     the other 12), and 84px under the logo row before the next section — 24 of
     which is the reel's own bottom padding. */
  .legal-hub-social-proof {
    padding-top:    0.75rem;   /* 12px */
    padding-bottom: 3.75rem;   /* 60px */
  }

  .legal-hub-social-proof__wrap {
    padding: 0 1rem;
  }

  /* Mobile frame: the tile is 338 wide inside a 370 bento — 16px, not 15. The
     bottom keeps the 24px set above; a shorthand here would undo it. */
  .legal-hub-social-proof__bento {
    padding-top:    1rem;
    padding-inline: 1rem;
  }

  /* The mobile frame insets the headline block 24px from the tile edge, 8px
     less than the quote below it (16px card padding + 8px here). */
  .legal-hub-social-proof__headline-stat {
    padding-inline: var(--spacing-2) var(--spacing-2);   /* 8px */
  }

  /* The frame leaves 24px between the bento and the reel band, and the band
     opens with 6px above the label pill (LogoReel spends the rest of its top
     padding on the 34px pill band itself). 24 + 6 - the 24px `pad-y` the reel
     already carries above the pill = 6. */
  .legal-hub-social-proof__reel {
    margin-top: var(--spacing-1-5);   /* 6px */
  }

  /* LogoReel halves its logos (4rem -> 2rem) and its gap below 768px. Figma
     draws this reel at full size on mobile, so the three sizing properties are
     handed back here. Only the edge fade keeps the primitive's mobile value —
     the section's 244px fade is most of a phone's width.

     Doubled class on purpose: LogoReel.css is imported after this file, so a
     single-class rule would tie on specificity and lose on order. */
  .legal-hub-social-proof__reel.logo-reel {
    --logo-reel-gap:         3.5rem;   /* 56px */
    --logo-reel-logo-height: 4rem;     /* 64px */
    --logo-reel-pad-y:       var(--spacing-6);   /* 24px */
  }
}


/* ============================================================
   Container queries — the stats + ratings column
   ============================================================ */

/* 786px is where the four ratings groups (722px of marks) still keep 16px
   between neighbours — the same gap each group uses INTERNALLY between its logo
   and its stars. Below that they read as one run-on row, so the column drops to
   two per row, and the stats give up Figma's proportional tracks (which squeeze
   `4,000+`'s label to a third of the width the other two get) for equal ones at
   the mobile frame's 16/24 label size. */
@container lh-proof-main (max-width: 786px) {
  /* Figma's own 158 / 262 / 245 proportions, minus the two spacer columns the
     desktop row spends its slack on. Equal thirds were tried and rejected: they
     leave `4,000+`'s one-line label swimming while the other two wrap.

     The 9rem floor on the first column only binds at the very bottom of the
     side-by-side range (a 542px column at a 992px viewport), where a straight
     158/665 share would be 117px and break `Law firms trust Smith.ai` over
     three lines. Above ~700px it never applies. */
  .legal-hub-social-proof__stats {
    grid-template-columns: minmax(9rem, 158fr) auto 262fr auto 245fr;
  }

  /* Figma's 142px is a measurement of the 150px desktop row; once the labels
     rewrap taller the hairline has to follow the row instead. */
  .legal-hub-social-proof__stat-rule {
    align-self: stretch;
    height:     auto;
  }

  .legal-hub-social-proof__stat-label {
    font-size:   var(--font-size-base);     /* 16px */
    line-height: var(--line-height-base);   /* 24px */
  }

  /* FIRST response to a narrow column: stand each mark up — logo above its
     stars — which is the mobile frame's own treatment and takes an item from
     ~190px wide to ~105. All four still fit on one row well past the width a
     side-by-side row gives up at. Only when even that stops fitting do they
     pair off (the 548px query below).

     `space-between` over content-sized tracks: stacked marks are all the same
     width (the stars+score line is wider than any of the four logos), so the
     gaps come out even, and with the 16px inline padding the outer two land on
     the same edges as the stat text above. No row gap and no margin — the row
     keeps the desktop rhythm; the mobile frame's extra spacing is added only
     where that frame actually applies (the stacked query below). */
  .legal-hub-social-proof__ratings.ratings-bar {
    grid-template-columns: repeat(4, max-content);
    justify-content:       space-between;
  }

  /* 12px above the logo and below the score, 16px inline, per the mobile frame.
     The 9px base is a measurement of the 48px desktop row; the inline padding
     lines the marks up with the stat NUMBERS (which sit 16px inside their
     column) rather than with the column edges the hairlines stand on. */
  .legal-hub-social-proof__ratings .ratings-bar__item {
    flex-direction:  column;
    align-items:     flex-start;
    justify-content: flex-start;
    gap:             var(--spacing-4);   /* 16px between logo and stars */
    padding:         var(--spacing-3) var(--spacing-4);
  }

  /* Every mark gets the SAME 16px slot, so all four stars rows sit on one line.
     Left to themselves the marks are 14 / 30 / 16 / 15px tall and G2's circle
     pushed its own stars 16px lower than the other three.

     `flex: 0 0 auto` because RatingsBar grows this box in its own stacked
     layout (≤479px), which in a column flex means growing it *taller*.

     The slot is the mobile frame's: it draws all four in a 14–16px band and
     lets G2's 30px circle overflow it rather than shrinking the circle, so the
     primitive's `max-height` clamp is lifted here to reproduce that. The
     overflow is centred — 7px into the item's 12px top padding, 7px into the
     16px gap below — and collides with neither. */
  .legal-hub-social-proof__ratings .ratings-bar__logo {
    flex:     0 0 auto;
    height:   1rem;   /* 16px */
    overflow: visible;
  }

  .legal-hub-social-proof__ratings .ratings-bar__brand-img {
    max-height: none;
  }

  .legal-hub-social-proof__ratings .ratings-bar__meta {
    flex:            0 0 auto;
    justify-content: flex-start;
  }
}

/* Four stood-up marks need 4 x 105 of content plus the 32px their inline
   padding puts between neighbours — 548px. Below that they pair off, which is
   what the mobile frame draws: two columns, **both left-aligned** at their
   track (the frame starts them at x=16 and x≈202 of a 338 block), not spread
   to the two edges the way the single row is. */
@container lh-proof-main (max-width: 548px) {
  .legal-hub-social-proof__ratings.ratings-bar {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    justify-items:         start;
  }
}

/* Narrow column: the mobile frame's stacked stats. One per row, the hairlines
   turned horizontal between them, and a closing one under the last (drawn as
   the grid's own bottom border — the markup only carries the two separators).

   Nested under the viewport query on purpose. The side-by-side layout bottoms
   out at a 542px column (a 992px viewport), which would otherwise stack the
   stats and leave the stretched tile beside them almost entirely empty; there
   the three narrow columns above are the better answer. Stacking is for the
   layout the mobile frame actually draws — tile above, column below. */
@media (max-width: 991px) {
  @container lh-proof-main (max-width: 600px) {
    .legal-hub-social-proof__stats {
      grid-template-columns: minmax(0, 1fr);
      gap:                   var(--spacing-2);   /* 8px above + below each rule */
    }

    .legal-hub-social-proof__stat-rule--trailing {
      display: block;
    }

    .legal-hub-social-proof__stat {
      gap:     var(--spacing-1);                          /* 4px */
      padding: var(--spacing-3) var(--spacing-4);         /* 12px 16px */
    }

    .legal-hub-social-proof__stat-rule {
      justify-self: stretch;
      align-self:   auto;
      width:        auto;
      height:       0;
      border-left:  0;
      border-top:   0.5px solid var(--border);
    }

    /* Only here does the mobile frame's ratings spacing apply: 32px below the
       stats block (4 of it is `__main`'s own gap) and 16px between the two
       rows. Above this width the pairs stay tight to the desktop rhythm. */
    .legal-hub-social-proof__ratings.ratings-bar {
      row-gap:    var(--spacing-4);   /* 16px */
      margin-top: 1.75rem;            /* 28px + the column's 4px gap */
    }
  }
}

/* ============================================================
   RatingsBar — internal shared rating pills strip
   ============================================================ */

.ratings-bar {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 1fr;
  gap: 12px;
}

.ratings-bar--grid-2-col {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ratings-bar__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-3);
  min-width: 0;
  padding: 1.5rem;
  background: var(--secondary);
  border: 0.5px solid var(--border);
  border-radius: 1.5rem;
  box-sizing: border-box;
}

.ratings-bar__logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  width: 64px;
}

.ratings-bar__meta {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--spacing-2);
  flex: 1 1 0;
  min-width: 0;
}

.ratings-bar__stars {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-items: center;
  gap: 4.16%;
  color: var(--primary);
  flex: 1 1 0;
  max-width: 96px;
}

.ratings-bar__star {
  display: block;
  min-width: 0;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
}

.ratings-bar__score {
  width: 1.25rem;
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-medium);
  line-height: var(--line-height-xs);
  color: var(--muted-foreground);
  text-align: center;
}

.ratings-bar__brand-img {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 100%;
  object-fit: contain;
}

@media (max-width: 991px) {
  .ratings-bar--strip {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 479px) {
  .ratings-bar__item {
    flex-direction: column;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--spacing-4);
    height: auto;
    padding-bottom: 2rem;
  }

  .ratings-bar__logo {
    flex-grow: 1;
  }

  .ratings-bar__meta {
    justify-content: flex-start;
    flex: unset;
  }
}

/* ============================================================
   LogoReel — infinite-scroll logo carousel with edge fades.
   Relies on --background from the parent context for fade colour.
   Design tokens from src/styles/tokens.css.
   ============================================================ */

.logo-reel {
  --logo-reel-edge-fade-width: 200px;
  --logo-reel-gap: 3.5rem;
  --logo-reel-logo-height: 4rem;
  --logo-reel-logo-max-height: none;
  --logo-reel-logo-max-width: none;
  --logo-reel-logo-slot-width: auto;
  --logo-reel-track-height: auto;
  --logo-reel-track-min-height: 0;
  --logo-reel-pad-y: var(--spacing-6);   /* 24px above + below the logo row */
  /* Room above the row for group-label pills. 0 unless a logo carries a
     `label`, in which case the component sets `data-has-labels`. */
  --logo-reel-label-space: 0px;

  position: relative;
  width:    100%;
  padding:  calc(var(--logo-reel-pad-y) + var(--logo-reel-label-space)) 0 var(--logo-reel-pad-y);
  overflow: hidden;
}

/* Pill height (24px) + the 10px it clears the logo row by. */
.logo-reel[data-has-labels] {
  --logo-reel-label-space: 34px;
}

/* ---- Edge fades ----
   Two mechanisms, picked by `edgeFade` (see LogoReel.tsx):

   `wash` — an opaque gradient in `--background` painted OVER the logos. The
   default, and what every consumer on a flat surface uses.

   `mask` — the reel itself is masked, so the logos fade to transparent and the
   backdrop shows through unchanged. Required over a textured backdrop: a wash
   there is a flat patch of colour sitting on top of the texture, visible as a
   smooth rectangle the width of the fade. */

/* Left and right wash fades — colour inherits from parent section */
.logo-reel[data-edge-fade="wash"]::before,
.logo-reel[data-edge-fade="wash"]::after {
  content:        '';
  position:       absolute;
  top:            0;
  bottom:         0;
  width:          var(--logo-reel-edge-fade-width);
  pointer-events: none;
  z-index:        1;
}

.logo-reel[data-edge-fade="wash"]::before {
  left:       0;
  background: linear-gradient(to right, var(--background) 30%, transparent);
}

.logo-reel[data-edge-fade="wash"]::after {
  right:      0;
  background: linear-gradient(to left, var(--background) 30%, transparent);
}

/* Masked edges. The reel's own box is masked rather than the scroller, which
   translates — a mask on a moving element would travel with it. */
.logo-reel[data-edge-fade="mask"] {
  -webkit-mask-image: linear-gradient(to right,
                        transparent,
                        #000 var(--logo-reel-edge-fade-width),
                        #000 calc(100% - var(--logo-reel-edge-fade-width)),
                        transparent);
          mask-image: linear-gradient(to right,
                        transparent,
                        #000 var(--logo-reel-edge-fade-width),
                        #000 calc(100% - var(--logo-reel-edge-fade-width)),
                        transparent);
}

/* Scroller — flex row of 4 identical tracks; animates to exactly -25% (= 1 track width). */
.logo-reel__scroller {
  display:   flex;
  width:     max-content;
  animation: logo-reel-scroll var(--logo-reel-duration) linear infinite;
}

/* Each track holds all logos once. padding-right = gap so the trailing space is baked in,
   making each track's width identical to (logos + n gaps). -25% lands flush on track 2. */
.logo-reel__track {
  display:       flex;
  align-items:   center;
  gap:           var(--logo-reel-gap);
  height:        var(--logo-reel-track-height);
  min-height:    var(--logo-reel-track-min-height);
  padding-right: var(--logo-reel-gap);
  flex-shrink:   0;
}

@keyframes logo-reel-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-25%); }
}

/* Respect reduced-motion preference */
@media (prefers-reduced-motion: reduce) {
  .logo-reel {
    --logo-reel-track-height: auto;
  }

  .logo-reel::before,
  .logo-reel::after {
    display: none;
  }

  .logo-reel[data-edge-fade="mask"] {
    -webkit-mask-image: none;
            mask-image: none;
  }

  .logo-reel__scroller {
    animation: none;
    width: 100%;
  }

  .logo-reel__track[aria-hidden="true"] {
    display: none;
  }

  .logo-reel__track:not([aria-hidden="true"]) {
    width: 100%;
    flex-wrap: wrap;
    justify-content: center;
    padding-right: 0;
  }

  /* The wrapped fallback has no single row for a hanging pill or a group rule
     to sit against, so both are dropped and the extra top padding with them. */
  .logo-reel[data-has-labels] {
    --logo-reel-label-space: 0px;
  }

  .logo-reel__label,
  .logo-reel__divider {
    display: none;
  }
}

.logo-reel__wrap {
  position:    relative;
  display:     flex;
  align-items: center;
  justify-content: center;
  width:       var(--logo-reel-logo-slot-width);
  flex-shrink: 0;
}

/* Group label — a pill hung above the logo that opens the group, left-aligned
   with it. Absolute so it never widens the slot or shifts the row's rhythm. */
.logo-reel__label {
  position:      absolute;
  left:          0;
  bottom:        calc(100% + 10px);
  padding:       var(--spacing-1) 0.875rem;   /* 4px 14px — 14 is off the spacing scale */
  background:    var(--card);
  border-radius: var(--radius-full);
  font-size:     var(--font-size-xs);     /* 12px */
  line-height:   var(--line-height-xs);   /* 16px */
  font-weight:   var(--font-weight-medium);
  color:         var(--muted-foreground);
  white-space:   nowrap;
}

/* Hairline between two labelled groups. Zero-width, so it inherits a full gap
   on each side; it spans the logo row plus the label space above it. */
.logo-reel__divider {
  align-self:  flex-start;
  flex:        0 0 auto;
  width:       0;
  height:      calc(var(--logo-reel-logo-height) + var(--logo-reel-label-space));
  margin-top:  calc(-1 * var(--logo-reel-label-space));
  border-left: 0.75px solid var(--border);
}

/* Optional text item after the last logo. It is not a logo, so it opts out of
   the fixed slot width and sizes to its own copy; everything visual (font,
   colour) is the consumer's call. */
.logo-reel__trailing {
  width:       auto;
  white-space: nowrap;
}

/* Images are @2x — display at half their natural size.
   64px = half of 128px native height. width: auto preserves aspect ratio. */
.logo-reel__img {
  display:    block;
  height:     var(--logo-reel-logo-height);
  max-width:  var(--logo-reel-logo-max-width);
  max-height: var(--logo-reel-logo-max-height);
  width:      auto;
  object-fit: contain;
}

/* Dark scheme — invert monochrome logos */
.logo-reel[data-scheme="dark"] .logo-reel__img {
  filter: invert(1) brightness(0.85);
}


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

@media (max-width: 767px) {
  .logo-reel {
    --logo-reel-edge-fade-width: 80px;
    --logo-reel-gap: 2rem;
    --logo-reel-logo-height: 2rem;
    --logo-reel-pad-y: var(--spacing-7);
  }
}

