/* =====================================================================
   LeadsNimble Social Proof 2 — the REWRITTEN social-proof section from
   leadsnimble_html, shipped ALONGSIDE lnew-social.css (which stays exactly
   as it was). Same arrangement as lnew-hero2 / lnew-nav2 / lnew-solution2.

   Ported 1:1 from leadsnimble_html:
     src/html/partials/social-proof.html
     src/css/components/social-proof.css    (.stats/.stat band, .rev carousel)
     src/js/modules/rev.js                  (clone-once loop, CSS metronome)
     src/js/modules/reveal.js               (index-staggered scroll reveal)
     src/css/base/1-reset.css               (document defaults it relies on)
     src/css/base/2-layout.css              (.wrap, .section, .section__head, .eyebrow)
     src/css/base/3-utilities.css           (.reveal / .reveal--scale, reduced motion)
     src/css/themes/aurora-nightfall/tokens.css

   WHAT ACTUALLY CHANGED vs lnew-social (v1). Only the stat band was
   rewritten; the testimonial focus-carousel underneath is byte-for-byte the
   same design. The reference's own comment records why:

       "Rebuilt to match .hstats (hero.css) exactly — a bounded glass panel,
        icon LEFT + text-column RIGHT, place-items:center for the icon."

     v1  three SEPARATE cards in a 3-col grid; centred text; a gradient
         number over a muted label; no icon; 24px radius; per-card shadow;
         glass + backdrop-blur in dark mode; stacked at 920px.
     v2  ONE bounded panel (width:max-content, centred) holding three
         icon+text ROWS separated by a vertical hairline; a solid gradient
         icon chip with a white glyph and a facet corner
         (radius 15/15/15/5); left-aligned text; an uppercase, letter-spaced
         label; 30px radius; ONE panel shadow with a glass highlight inset;
         NO backdrop blur in either mode; stacks at 640px, where the
         divider turns horizontal and insets 24px from each end.

   TWO REFERENCE RULES THAT ARE DEAD AND ARE DELIBERATELY NOT PORTED:
     · base/4-responsive.css  `.stat b { font-size: 38px }` at <=460px.
       build.sh concatenates base/ BEFORE components/, and
       `.stat__text b` (same 0,1,1 specificity) restates the size, so the
       responsive rule never wins. Porting it would CHANGE the design.
     · `@media (max-width: 920px) { .stats { grid-template-columns: 1fr } }`
       is left over from v1 — the band is flex now, so it does nothing.
     (Third time this trap has shown up in this plugin; see the solution2 and
      hero2 CSS headers.)

   Everything else follows the family conventions unchanged: theme tokens are
   resolved to literals and re-scoped under --lnsp2-*, so the widget renders
   identically regardless of the active WP theme and never leaks a variable
   into the rest of the page. LIGHT is the default mode (the reference build's
   mode.txt); [data-mode="dark"] on <html> flips the palette.

   THREE THINGS THAT LOOK LIKE MISTAKES BUT ARE THE REFERENCE:

   1. THE QUOTE INSET (--lnsp2-q-inset: 17px 40px) IS MARGIN, NOT PADDING.
      The reference resets p, ul and ol but NOT blockquote, so every .rev__q
      carries the UA default `margin: 1em 40px` (1em of the inherited 17px
      body size). Absolutely positioned with inset:0 and box-sizing:
      border-box, an auto height/width is solved by subtracting MARGIN from
      the containing block — padding would NOT do the same job, because it is
      already inside the border-box size and the stretch equation only pulls
      margin out of it. Padding here renders the quote at the stage's full
      232px/942px box every time, with zero shrink.

   2. THE ACTIVE AVATAR'S INNER RING is --lnsp2-ring-bg, i.e. the card
      surface. In dark mode that surface is rgba(255,255,255,.035) — almost
      invisible — so the ring reads as a single accent hoop there and as a
      white gap + accent hoop in light. Its own control if you want parity.

   3. NO DROP SHADOW ON THE AVATARS, only box-shadow rings. A shadow on a
      52px circle inside a 96px strip casts a visible horizontal line under
      the whole strip once ten of them line up.

   LOOP MECHANICS (do not "simplify"): lnew-social2.js clones the avatar strip
   so the centring translate never has to rewind — it advances a position `p`
   across the doubled strip and, at the loop boundary, snaps p back by N with
   the transition frozen. Both positions show an identical window, so the jump
   is invisible. --lnsp2-ava / --lnsp2-ava-gap are READ BACK by that script,
   so resizing the avatars from the Style tab keeps the arithmetic exact.

   THE STACK SWITCH is measured on the BAND, not the viewport, so the widget
   behaves the same inside a narrow Elementor column as it does full width.
   The @media fallback at the bottom reproduces the reference's own 640px
   switch for the no-JS case and is disabled the moment the script marks the
   section with .lnew-social2--js, so the two can never disagree.
   ===================================================================== */

/* Local reset. Wrapped in :where() so it carries ZERO specificity — a bare
   `.lnew-social2 p` would be (0,1,1) and would outrank every (0,1,0)
   component class below it. Do not unwrap. */
.lnew-social2, .lnew-social2 *, .lnew-social2 *::before, .lnew-social2 *::after { box-sizing: border-box; }
:where(.lnew-social2) :where(a) { color: inherit; text-decoration: none; }
:where(.lnew-social2) :where(p) { margin: 0; }
:where(.lnew-social2) :where(figure) { margin: 0; }
:where(.lnew-social2) :where(blockquote) { margin: 0; padding: 0; border: 0; quotes: none; }
:where(.lnew-social2) :where(blockquote)::before,
:where(.lnew-social2) :where(blockquote)::after { content: none; }
:where(.lnew-social2) :where(svg) { display: block; }
:where(.lnew-social2) :where(img) { max-width: 100%; display: block; }
:where(.lnew-social2) :where(h1, h2, h3) { margin: 0; }
:where(.lnew-social2) :where(b) { font-weight: 700; }

.lnew-social2 {
  /* ---- motion / geometry ---- */
  --lnsp2-ease: cubic-bezier(.22,1,.36,1);
  --lnsp2-rv-dist: 70px;
  --lnsp2-rv-dur: 1.2s;
  --lnsp2-rv-step: 70ms;
  --lnsp2-maxw: 1360px;
  --lnsp2-gutter: 28px;
  --lnsp2-title-size: clamp(31px, 3.6vw, 47px);
  --lnsp2-head-gap: 56px;

  /* ---- the stat band (the rewritten part) ---- */
  --lnsp2-stats-radius: 30px;      /* --radius-xl */
  --lnsp2-stats-gap-b: 64px;
  --lnsp2-stat-pad: 28px 36px;
  --lnsp2-stat-pad-stack: 20px 24px;
  --lnsp2-stat-gap: 16px;          /* chip -> text column */
  --lnsp2-div-inset: 16%;          /* vertical hairline, top and bottom */
  --lnsp2-div-inset-stack: 24px;   /* horizontal hairline, each end */
  --lnsp2-ic-size: 50px;
  --lnsp2-ic-radius: 15px 15px 15px 5px;   /* the house facet corner */
  --lnsp2-ic-glyph: 23px;
  --lnsp2-ic-stroke: 2.1;
  --lnsp2-stat-num-size: clamp(27px, 2.6vw, 36px);
  --lnsp2-stat-label-size: 12.5px;
  --lnsp2-stat-label-gap: 5px;
  --lnsp2-stat-label-track: .04em;

  /* ---- the carousel shell ---- */
  --lnsp2-rev-maxw: 940px;
  --lnsp2-card-radius: 32px;
  --lnsp2-card-pad: 40px 48px;
  --lnsp2-bloom-blur: 42px;
  --lnsp2-bloom-op: .65;
  --lnsp2-bloom-radius: 44px;
  --lnsp2-bloom-top: -3%;
  --lnsp2-bloom-bottom: -7%;
  --lnsp2-bloom-1: 42%;            /* accent   mix, top-left lobe */
  --lnsp2-bloom-2: 34%;            /* accent-2 mix, bottom-right lobe */

  /* ---- the quote ---- */
  --lnsp2-qmark-size: 44px;
  --lnsp2-qmark-gap: 10px;
  --lnsp2-stage-min: 232px;
  --lnsp2-stage-fit: 0px;          /* JS raises this when a review runs long */
  --lnsp2-q-gap: 24px;
  --lnsp2-q-inset: 17px 40px;      /* see note 1 in the header */
  --lnsp2-text-size: clamp(19px, 2.4vw, 28px);
  --lnsp2-text-maxw: 720px;
  --lnsp2-text-lh: 1.42;
  --lnsp2-star-size: 18px;
  --lnsp2-star-gap: 5px;
  --lnsp2-name-size: 16px;
  --lnsp2-role-size: 14px;
  --lnsp2-fade-dur: .5s;

  /* ---- the avatar strip ---- */
  --lnsp2-strip-w: 400px;
  --lnsp2-strip-h: 96px;
  --lnsp2-strip-top: 28px;
  --lnsp2-strip-bottom: 2px;
  --lnsp2-strip-fade: 24%;
  --lnsp2-ava: 52px;               /* read back by lnew-social2.js */
  --lnsp2-ava-gap: 20px;           /* read back by lnew-social2.js */
  --lnsp2-ava-font: 15px;
  --lnsp2-ava-scale: 1.5;
  --lnsp2-ava-rest: .82;
  --lnsp2-ava-op: .5;
  --lnsp2-ring-1: 3px;
  --lnsp2-ring-2: 5px;
  --lnsp2-slide-dur: .6s;

  /* ---- cadence ---- */
  --lnsp2-dwell: 5200ms;

  /* ---- type ---- */
  --lnsp2-font-sans: 'DM Sans', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  --lnsp2-font-head: 'Parkinsans', 'DM Sans', sans-serif;

  /* ---- palette · LIGHT (the site's default mode) ---- */
  --lnsp2-bg: #dde2f4;             /* --bg — a plain .section, not --soft/--tint */
  --lnsp2-ink: #12122a;
  --lnsp2-body: #454a63;
  --lnsp2-muted: #6b7089;
  --lnsp2-surface: #ffffff;
  --lnsp2-line: #e7e9f4;
  --lnsp2-line-2: #f0f1f8;

  --lnsp2-eyebrow-bg: #eef0ff;
  --lnsp2-eyebrow-ink: #5b46e0;
  --lnsp2-eyebrow-border: #e0e3ff;

  --lnsp2-grad-1: #6366f1;
  --lnsp2-grad-2: #a855f7;
  --lnsp2-grad-3: #22d3ee;
  --lnsp2-accent-grad: linear-gradient(100deg, var(--lnsp2-grad-1) 0%, var(--lnsp2-grad-2) 52%, var(--lnsp2-grad-3) 100%);
  --lnsp2-accent: #6d5cf5;
  --lnsp2-accent-2: #22d3ee;
  --lnsp2-accent-halo: rgba(139,124,255,.28);

  /* The band is ONE surface with ONE shadow: a glass highlight inset over
     --shadow-md. There is no backdrop blur in either mode here — that was a
     v1 stat-tile behaviour and the rewrite dropped it. */
  --lnsp2-stats-bg: #ffffff;
  --lnsp2-stats-hi: rgba(255,255,255,.90);   /* --glass-hi */
  --lnsp2-stats-shadow: 0 12px 34px rgba(30,30,80,.10);
  --lnsp2-ic-ink: #ffffff;
  --lnsp2-ic-glow: rgba(99,102,241,.4);

  --lnsp2-card-bg: #ffffff;
  --lnsp2-card-shadow: 0 30px 70px rgba(30,30,80,.16);

  --lnsp2-q-1: #8b7cff;            /* opening quote-mark gradient */
  --lnsp2-q-2: #22d3ee;
  --lnsp2-star-1: #ffd76a;
  --lnsp2-star-2: #f0a71b;
  --lnsp2-star-shadow: rgba(176,108,0,.28);
  --lnsp2-ring-bg: #ffffff;
  --lnsp2-ring-ink: rgba(109,92,245,.55);   /* = the reference's accent at 55% */

  position: relative;
  overflow-x: clip;
  padding-top: 112px;
  padding-bottom: 112px;
  background: var(--lnsp2-bg);
  font-family: var(--lnsp2-font-sans);
  color: var(--lnsp2-body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ---- palette · DARK ([data-mode="dark"] on <html>, written by the nav's
   mode toggle). Unlike v1's stat tiles, NOTHING here frosts in dark: the
   rewritten band is a plain --surface panel in both modes. ---- */
[data-mode="dark"] .lnew-social2 {
  --lnsp2-bg: #0a0a12;
  --lnsp2-ink: #f5f6ff;
  --lnsp2-body: #b8bed6;
  --lnsp2-muted: #949bbb;
  --lnsp2-surface: rgba(255,255,255,.035);
  --lnsp2-line: rgba(255,255,255,.10);
  --lnsp2-line-2: rgba(255,255,255,.06);

  --lnsp2-eyebrow-bg: rgba(255,255,255,.05);
  --lnsp2-eyebrow-ink: #cdc6ff;
  --lnsp2-eyebrow-border: rgba(255,255,255,.12);

  --lnsp2-accent: #8b7cff;

  --lnsp2-stats-bg: rgba(255,255,255,.035);
  --lnsp2-stats-hi: rgba(255,255,255,.10);
  --lnsp2-stats-shadow: 0 12px 34px rgba(0,0,0,.5);

  --lnsp2-card-bg: rgba(255,255,255,.035);
  --lnsp2-card-shadow: 0 34px 74px rgba(0,0,0,.62);
  --lnsp2-ring-bg: rgba(255,255,255,.035);
  --lnsp2-ring-ink: rgba(139,124,255,.55);
}

/* The two SVG gradients are declared once per instance in the markup with
   ids suffixed by the element id; their stops take their colour from here, so
   the Style tab controls them like everything else. */
.lnew-social2__qs-1 { stop-color: var(--lnsp2-q-1); }
.lnew-social2__qs-2 { stop-color: var(--lnsp2-q-2); }
.lnew-social2__ss-1 { stop-color: var(--lnsp2-star-1); }
.lnew-social2__ss-2 { stop-color: var(--lnsp2-star-2); }

/* Announced, never seen: the star row is aria-hidden decoration, so the
   rating is exposed as text instead. */
.lnew-social2__sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* =====================================================================
   Layout shell
   ===================================================================== */
.lnew-social2__wrap {
  width: 100%;
  max-width: var(--lnsp2-maxw);
  margin-inline: auto;
  padding-inline: var(--lnsp2-gutter);
}

.lnew-social2__head {
  max-width: none;
  margin-inline: auto;
  margin-bottom: var(--lnsp2-head-gap);
  text-align: center;
}

/* =====================================================================
   Eyebrow
   ===================================================================== */
.lnew-social2__eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--lnsp2-font-sans);
  font-size: 13px; font-weight: 600; letter-spacing: .02em;
  color: var(--lnsp2-eyebrow-ink);
  background: var(--lnsp2-eyebrow-bg);
  border: 1px solid var(--lnsp2-eyebrow-border);
  padding: 7px 14px; border-radius: 100px;
}
/* Dim indicator lamp: glows up, fades out, then holds dark. The long unlit
   hold is the point — a continuous sine pulse reads as decoration, a lit/unlit
   cycle with a gap reads as a status light. */
.lnew-social2__eyebrow-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--lnsp2-accent);
  box-shadow: 0 0 0 4px var(--lnsp2-accent-halo);
  opacity: .45;
  animation: lnsp2-dot-lamp 5.2s ease-in-out infinite;
}
@keyframes lnsp2-dot-lamp {
  0%        { opacity: .35; box-shadow: 0 0 0 4px var(--lnsp2-accent-halo), 0 0 0 0 transparent; }
  8%        { opacity: 1;   box-shadow: 0 0 0 4px var(--lnsp2-accent-halo), 0 0 7px 1px var(--lnsp2-accent); }
  22%       { opacity: 1;   box-shadow: 0 0 0 4px var(--lnsp2-accent-halo), 0 0 7px 1px var(--lnsp2-accent); }
  40%, 100% { opacity: .35; box-shadow: 0 0 0 4px var(--lnsp2-accent-halo), 0 0 0 0 transparent; }
}

/* =====================================================================
   Title + lead
   ===================================================================== */
.lnew-social2__title {
  font-family: var(--lnsp2-font-head);
  font-weight: 500;
  font-size: var(--lnsp2-title-size);
  margin-top: 18px;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--lnsp2-ink);
  text-wrap: balance;
}
.lnew-social2__title-accent {
  background: var(--lnsp2-accent-grad);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.lnew-social2__lead {
  margin-top: 18px;
  font-size: 18px;
  color: var(--lnsp2-muted);
  line-height: 1.65;
  text-wrap: balance;
}

/* =====================================================================
   The stat band — one bounded panel, icon LEFT + text column RIGHT.

   `width: max-content` is what makes the panel hug its three rows and sit
   centred instead of spanning the container; `max-width: 100%` is what lets
   it squeeze rather than overflow once the viewport drops under its natural
   width. Both are the reference's. gap is 0 — the rows meet, and the seam is
   drawn by the ::before hairline so it can be inset from the panel's edges.
   ===================================================================== */
.lnew-social2__stats {
  --lnsp2-rv-step: 55ms;           /* dense row: item 3 isn't half a second late */
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: 0;
  margin: 0 auto var(--lnsp2-stats-gap-b);
  width: max-content;
  max-width: 100%;
  border-radius: var(--lnsp2-stats-radius);
  background: var(--lnsp2-stats-bg);
  border: 1px solid var(--lnsp2-line);
  box-shadow: inset 0 1px 0 var(--lnsp2-stats-hi), var(--lnsp2-stats-shadow);
}

.lnew-social2__stat {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--lnsp2-stat-gap);
  padding: var(--lnsp2-stat-pad);
}

/* The seam. Fades out at both ends so it never touches the panel's rounded
   corners — a full-height 1px rule would clip visibly against the radius. */
.lnew-social2__stat + .lnew-social2__stat::before {
  content: "";
  position: absolute;
  left: 0;
  top: var(--lnsp2-div-inset);
  bottom: var(--lnsp2-div-inset);
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--lnsp2-line-2) 20%, var(--lnsp2-line-2) 80%, transparent);
}

/* Solid gradient chip + white glyph. The reference's note: a soft-tint chip
   with a thin currentColor stroke read as near-invisible on some displays;
   this is bold and unmissable regardless of screen or compression.
   display:grid + place-items:center is the same mechanism the hero's stat
   chips already use successfully — deliberately not flex. */
.lnew-social2__stat-ic {
  flex: none;
  width: var(--lnsp2-ic-size);
  height: var(--lnsp2-ic-size);
  display: grid;
  place-items: center;
  border-radius: var(--lnsp2-ic-radius);
  background: var(--lnsp2-accent-grad);
  color: var(--lnsp2-ic-ink);
  box-shadow: 0 6px 16px -4px var(--lnsp2-ic-glow);
}
/* The reference hard-codes stroke="#ffffff" on the glyphs; here they paint
   with currentColor so the chip's ink is a single themeable token. */
.lnew-social2__stat-ic svg {
  width: var(--lnsp2-ic-glyph);
  height: var(--lnsp2-ic-glyph);
  stroke-width: var(--lnsp2-ic-stroke);
}
/* Icon-font and uploaded-SVG picks from the optional Custom Icon control. */
.lnew-social2__stat-ic i {
  display: block;
  font-size: var(--lnsp2-ic-glyph);
  line-height: 1;
  font-style: normal;
}
.lnew-social2__stat-ic img {
  width: var(--lnsp2-ic-glyph);
  height: var(--lnsp2-ic-glyph);
  object-fit: contain;
}

.lnew-social2__stat-text { display: flex; flex-direction: column; text-align: left; }
.lnew-social2__stat-text b {
  font-family: var(--lnsp2-font-head);
  font-size: var(--lnsp2-stat-num-size);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.05;
  background: var(--lnsp2-accent-grad);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.lnew-social2__stat-text span {
  margin-top: var(--lnsp2-stat-label-gap);
  font-size: var(--lnsp2-stat-label-size);
  font-weight: 600;
  letter-spacing: var(--lnsp2-stat-label-track);
  text-transform: uppercase;
  color: var(--lnsp2-muted);
}

/* ---- stacked band ---------------------------------------------------
   The panel goes full width, the rows become a column, and the seam turns
   horizontal and insets from each end instead of top and bottom. Applied by
   lnew-social2.js from the BAND's measured width; the @media at the bottom of
   this file is the no-JS fallback for the same switch. */
.lnew-social2__stats.is-stack { width: 100%; flex-direction: column; }
.lnew-social2__stats.is-stack .lnew-social2__stat { padding: var(--lnsp2-stat-pad-stack); }
.lnew-social2__stats.is-stack .lnew-social2__stat + .lnew-social2__stat::before {
  left: var(--lnsp2-div-inset-stack);
  right: var(--lnsp2-div-inset-stack);
  top: 0;
  bottom: auto;
  width: auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--lnsp2-line-2) 20%, var(--lnsp2-line-2) 80%, transparent);
}

/* =====================================================================
   Testimonial focus-carousel — unchanged by the rewrite, and identical to
   lnew-social's. Kept as its own copy (not shared) so either widget can be
   restyled without touching the other.
   ===================================================================== */
.lnew-social2__rev {
  position: relative;
  max-width: var(--lnsp2-rev-maxw);
  margin: 0 auto;
}

/* Soft aurora bloom behind the card. The first background declaration is the
   fallback for engines without color-mix(); the second wins wherever it
   parses — the same two-declaration trick as lnew-industries.css. */
.lnew-social2__rev::before {
  content: ""; position: absolute; z-index: 0;
  inset: var(--lnsp2-bloom-top) 0 var(--lnsp2-bloom-bottom);
  background:
    radial-gradient(58% 80% at 14% 6%, var(--lnsp2-accent), transparent 60%),
    radial-gradient(58% 80% at 88% 96%, var(--lnsp2-accent-2), transparent 60%);
  background:
    radial-gradient(58% 80% at 14% 6%, color-mix(in srgb, var(--lnsp2-accent) var(--lnsp2-bloom-1), transparent), transparent 60%),
    radial-gradient(58% 80% at 88% 96%, color-mix(in srgb, var(--lnsp2-accent-2) var(--lnsp2-bloom-2), transparent), transparent 60%);
  filter: blur(var(--lnsp2-bloom-blur));
  opacity: var(--lnsp2-bloom-op);
  border-radius: var(--lnsp2-bloom-radius);
  pointer-events: none;
}
.lnew-social2--no-bloom .lnew-social2__rev::before { display: none; }

.lnew-social2__card {
  position: relative; z-index: 1;
  text-align: center;
  background: var(--lnsp2-card-bg);
  border: 1px solid var(--lnsp2-line);
  border-radius: var(--lnsp2-card-radius);
  padding: var(--lnsp2-card-pad);
  box-shadow: var(--lnsp2-card-shadow);
}
.lnew-social2__defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Premium opening quotation mark (aurora gradient) */
.lnew-social2__qmark { display: flex; justify-content: center; margin-bottom: var(--lnsp2-qmark-gap); }
.lnew-social2__qmark svg { width: var(--lnsp2-qmark-size); height: auto; }

/* ---- the crossfading stage ----
   Every quote is stacked at inset:0; only .is-active is painted. The stage
   therefore has no in-flow children and needs an explicit floor.
   --lnsp2-stage-fit is written by the script when a review is taller than that
   floor, so a longer quote grows the card instead of spilling out of it. */
.lnew-social2__stage {
  position: relative;
  min-height: max(var(--lnsp2-stage-min), var(--lnsp2-stage-fit, 0px));
}
.lnew-social2__q {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--lnsp2-q-gap);
  margin: var(--lnsp2-q-inset); padding: 0;
  opacity: 0; transform: translateY(12px); pointer-events: none;
  transition: opacity var(--lnsp2-fade-dur) var(--lnsp2-ease),
              transform calc(var(--lnsp2-fade-dur) + .05s) var(--lnsp2-ease);
}
.lnew-social2__q.is-active { opacity: 1; transform: none; pointer-events: auto; }

/* While the script measures the tallest review it stacks the quotes back into
   normal flow for one frame. Kept invisible and inert so nothing flashes. */
.lnew-social2__stage.is-measuring { min-height: 0; }
.lnew-social2__stage.is-measuring .lnew-social2__q {
  position: relative; inset: auto;
  opacity: 0; transform: none; transition: none; pointer-events: none;
}
/* Held for the single flush frame after a measurement, so the active quote
   snaps back to opacity 1 instead of fading in from the measured state. */
.lnew-social2__stage.is-nofx .lnew-social2__q { transition: none !important; }

.lnew-social2__text {
  max-width: var(--lnsp2-text-maxw); margin: 0 auto;
  font-family: var(--lnsp2-font-head); font-weight: 500;
  font-size: var(--lnsp2-text-size);
  line-height: var(--lnsp2-text-lh);
  letter-spacing: -.01em;
  color: var(--lnsp2-ink);
  text-wrap: balance;
}
.lnew-social2__stars { display: inline-flex; gap: var(--lnsp2-star-gap); }
.lnew-social2__stars .lnew-social2__star {
  width: var(--lnsp2-star-size); height: var(--lnsp2-star-size);
  filter: drop-shadow(0 1px 1.5px var(--lnsp2-star-shadow));
}
/* Only ever drawn when a review is rated below the full five — at the
   reference's default rating this selector never matches anything. */
.lnew-social2__stars .lnew-social2__star--off { opacity: .26; filter: grayscale(1); }

.lnew-social2__who { display: flex; flex-direction: column; gap: 3px; }
.lnew-social2__name {
  font-family: var(--lnsp2-font-head); font-weight: 700;
  font-size: var(--lnsp2-name-size); color: var(--lnsp2-ink);
}
.lnew-social2__role { font-size: var(--lnsp2-role-size); color: var(--lnsp2-muted); }

/* =====================================================================
   The avatar strip
   ===================================================================== */
.lnew-social2__strip {
  position: relative;
  height: var(--lnsp2-strip-h);
  margin: var(--lnsp2-strip-top) auto var(--lnsp2-strip-bottom);
  max-width: var(--lnsp2-strip-w);
  overflow-x: clip;                /* clip, not hidden: the scaled active avatar
                                      still overflows the strip vertically */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--lnsp2-strip-fade), #000 calc(100% - var(--lnsp2-strip-fade)), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 var(--lnsp2-strip-fade), #000 calc(100% - var(--lnsp2-strip-fade)), transparent);
}
.lnew-social2__avatrack {
  position: absolute; top: 50%; left: 0;
  margin-top: calc(var(--lnsp2-ava) / -2);
  display: flex; align-items: center;
  transition: transform var(--lnsp2-slide-dur) var(--lnsp2-ease);
  will-change: transform;
}
.lnew-social2__ava {
  position: relative;
  flex: 0 0 var(--lnsp2-ava);
  width: var(--lnsp2-ava); height: var(--lnsp2-ava);
  margin-right: var(--lnsp2-ava-gap);
  border-radius: 50%; overflow: hidden;
  display: grid; place-items: center;
  font-family: var(--lnsp2-font-head); font-weight: 700;
  font-size: var(--lnsp2-ava-font); color: #fff; letter-spacing: .02em;
  background: linear-gradient(150deg, hsl(var(--h, 265) 72% 62%), hsl(calc(var(--h, 265) + 26) 74% 47%));
  opacity: var(--lnsp2-ava-op);
  transform: scale(var(--lnsp2-ava-rest));
  transition: transform var(--lnsp2-fade-dur) var(--lnsp2-ease),
              opacity var(--lnsp2-fade-dur) var(--lnsp2-ease),
              box-shadow var(--lnsp2-fade-dur) var(--lnsp2-ease);
}
.lnew-social2__ava img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; border-radius: 50%;
}
/* Rings only — no drop shadow, so nothing casts a shadow line below the strip. */
.lnew-social2__ava.is-active {
  opacity: 1;
  transform: scale(var(--lnsp2-ava-scale));
  z-index: 2;
  box-shadow: 0 0 0 var(--lnsp2-ring-1) var(--lnsp2-ring-bg),
              0 0 0 var(--lnsp2-ring-2) var(--lnsp2-ring-ink);
}
/* During the loop snap, freeze BOTH the track slide and the avatar scale so
   the re-centred clone doesn't visibly re-grow (driven from lnew-social2.js). */
.lnew-social2__strip.is-snapping .lnew-social2__avatrack,
.lnew-social2__strip.is-snapping .lnew-social2__ava { transition: none !important; }

/* =====================================================================
   The metronome — invisible; one run == one review's dwell. Advancing on
   `animationend` instead of setInterval is what keeps the cadence drift-free
   and lets hover / off-screen pause it with animation-play-state alone.
   ===================================================================== */
.lnew-social2__clock {
  position: absolute; top: 0; left: 0;
  width: 1px; height: 1px; opacity: 0; pointer-events: none;
}
@keyframes lnsp2-dwell { from { opacity: .001; } to { opacity: 0; } }
.lnew-social2__rev.is-playing .lnew-social2__clock { animation: lnsp2-dwell var(--lnsp2-dwell, 5200ms) linear; }
.lnew-social2__rev.is-paused .lnew-social2__clock { animation-play-state: paused; }
.lnew-social2--hover-pause .lnew-social2__rev:hover .lnew-social2__clock,
.lnew-social2__rev:focus-within .lnew-social2__clock { animation-play-state: paused; }

/* =====================================================================
   Scroll reveal — --i is assigned by lnew-social2.js (index within parent)
   ===================================================================== */
.lnew-social2 .lnew-reveal {
  opacity: 0;
  transform: translate3d(0, var(--lnsp2-rv-dist), 0);
  transition: opacity var(--lnsp2-rv-dur) var(--lnsp2-ease),
              transform var(--lnsp2-rv-dur) var(--lnsp2-ease);
  transition-delay: calc(var(--i, 0) * var(--lnsp2-rv-step));
}
.lnew-social2 .lnew-reveal--scale {
  transform: translate3d(0, calc(var(--lnsp2-rv-dist) * .5), 0) scale(.94);
}
.lnew-social2 .lnew-reveal.is-in { opacity: 1; transform: none; }
.elementor-editor-active .lnew-social2 .lnew-reveal { opacity: 1; transform: none; }

/* =====================================================================
   Reduced motion: no cycle, no crossfade — the first review sits static.
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  .lnew-social2 .lnew-reveal { opacity: 1; transform: none; transition: none; }
  .lnew-social2__clock { animation: none !important; }
  .lnew-social2__q,
  .lnew-social2__ava,
  .lnew-social2__avatrack { transition: none !important; }
  .lnew-social2__eyebrow-dot { animation: none !important; opacity: 1; }
}

/* =====================================================================
   Responsive. Only the properties NO Style control owns live here — an
   Elementor selector carries no media query and would beat a rule of equal
   specificity on source order, so anything a control writes is left to the
   control's own tablet/mobile values.

   The 640px block below is the no-JS fallback ONLY: :not(.lnew-social2--js)
   turns it off the instant lnew-social2.js takes over, so the viewport rule
   and the script's own measured rule can never fight each other.

   THE DOUBLED CLASS IS LOAD-BEARING. An Elementor Style control emits
   `.elementor-widget-lnew_social2 .lnew-social2 { … }` — (0,2,0), no media
   query, so its DESKTOP value applies at every width and outranks a plain
   `.lnew-social2` rule here (0,1,0) even inside a media query. Anything a
   control owns therefore has to be restated at (0,3,0) to be reachable from
   this file at all. That is also why the narrow card values live on their own
   "· Narrow" controls targeting `.lnew-social2.lnew-social2--narrow` (also
   (0,3,0), and applied by the script) rather than as rules in here.
   ===================================================================== */
/* The reference drops .section__lead to 16.5px at 760px. That is NOT ported as
   a rule here, because it would be dead on arrival: the Lead Typography group
   control ships an 18px font-size default, which Elementor emits at (0,2,0)
   with no media query and which therefore wins at every width. The lead is a
   widget extra anyway — the reference's own social-proof head is just the
   eyebrow and the title, so it renders nothing by default. Set the group
   control's own mobile size if you add a lead and want it to shrink. */

@media (max-width: 640px) {
  .lnew-social2:not(.lnew-social2--js) .lnew-social2__stats {
    width: 100%;
    flex-direction: column;
  }
  .lnew-social2:not(.lnew-social2--js) .lnew-social2__stat {
    padding: var(--lnsp2-stat-pad-stack);
  }
  .lnew-social2:not(.lnew-social2--js) .lnew-social2__stat + .lnew-social2__stat::before {
    left: var(--lnsp2-div-inset-stack);
    right: var(--lnsp2-div-inset-stack);
    top: 0;
    bottom: auto;
    width: auto;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--lnsp2-line-2) 20%, var(--lnsp2-line-2) 80%, transparent);
  }
  /* The card half of the same switch, for the same no-JS case. Doubled class
     so it can outrank the desktop Style controls — see the note above. */
  .lnew-social2.lnew-social2:not(.lnew-social2--js) {
    --lnsp2-card-pad: 40px 26px 32px 26px;
    --lnsp2-card-radius: 26px;
    --lnsp2-stage-min: 280px;
    --lnsp2-q-inset: 17px 0px;
  }
}
