/* =====================================================================
   LeadsNimble Hero 2 — "Leads from anywhere" aurora wiring hero.

   Ported 1:1 from leadsnimble_html @ v0.3.0:
     src/html/partials/hero.html            (hero shell, wiring SVG + channel
                                             carousels, hstats, chanmq, trusted)
     src/css/components/hero.css            (hero, hnet, hstats, chanmq,
                                             trusted, marquee)
     src/css/components/buttons.css         (.btn / --primary / --ghost / --lg)
     src/css/base/2-layout.css              (.wrap, .eyebrow, .accent-text)
     src/css/base/3-utilities.css           (.reveal stagger, reduced motion)
     src/css/themes/aurora-nightfall/       (tokens + the animated aurora, the
       tokens.css / overrides.css            flat #0a0a12 hero fill, the bottom
                                             vignette and the primary-button
                                             glow — overrides.css concatenates
                                             LAST in build.sh, so where the two
                                             layers disagree the OVERRIDE is the
                                             design that ships and is what is
                                             flattened in here.)

   ---------------------------------------------------------------------
   MODE LOCK. Unlike .lnew-hero (V1), this section is DARK-LOCKED, exactly as
   the reference is: hero.css redeclares every token a hero descendant reads
   with the site's dark literals, so the band stays dark regardless of the
   [data-mode] the nav's toggle writes on <html>. That is why there is ONE
   palette here and not a light/dark pair — a second [data-mode="dark"] block
   would be dead weight, and a light variant of this hero does not exist in the
   reference. Every --lnh2-* token below is still writable from the Style tab.

   NAV OFFSET. The reference nav is a 76px sticky bar in normal flow, so its
   hero only needs padding-top:36px. This site's .lnew-nav is a floating pill
   that pulls the next section up under itself with margin-bottom:-84px, so the
   hero must first repay that 84px before the reference's own 36px gap starts.
   Hence padding-top: calc(--lnh2-nav-flow + --lnh2-pad-t) with the two halves
   separately controllable — set the nav offset to 0 if the nav ever becomes a
   normal-flow bar here too.

   The theme's design tokens are resolved to literal values and re-scoped under
   --lnh2-*, so the widget renders identically regardless of the active WP theme
   and never leaks variables into the rest of the page.
   ===================================================================== */

/* Local reset. Wrapped in :where() so it carries ZERO specificity — a bare
   `.lnew-hero2 p` would be (0,1,1) and would outrank every (0,1,0) component
   class below it, silently eating the note's spacing and the marquee's list
   resets. See [[hero-widget-feature]] / [[nav-widget-feature]]. Do not unwrap. */
.lnew-hero2, .lnew-hero2 *, .lnew-hero2 *::before, .lnew-hero2 *::after { box-sizing: border-box; }
:where(.lnew-hero2) :where(a) { color: inherit; text-decoration: none; }
:where(.lnew-hero2) :where(img) { max-width: 100%; display: block; }
:where(.lnew-hero2) :where(ul, ol) { margin: 0; padding: 0; list-style: none; }
:where(.lnew-hero2) :where(p) { margin: 0; }
:where(.lnew-hero2) :where(svg) { display: block; }
:where(.lnew-hero2) :where(h1, h2, h3) { margin: 0; }

.lnew-hero2 {
  /* ---- motion / geometry ---- */
  --lnh2-ease: cubic-bezier(.22,1,.36,1);
  --lnh2-rv-dist: 70px;
  --lnh2-rv-dur: 1.2s;
  --lnh2-rv-step: 70ms;
  --lnh2-maxw: 1360px;
  --lnh2-gutter: 28px;
  --lnh2-nav-flow: 84px;
  --lnh2-pad-t: 36px;
  --lnh2-pad-b: 96px;
  --lnh2-radius-xl: 30px;
  --lnh2-radius-pill: 100px;
  --lnh2-btn-radius: 13px;

  /* ---- type ---- */
  --lnh2-font-sans: 'DM Sans', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
  --lnh2-font-head: 'Parkinsans', 'DM Sans', sans-serif;
  /* the headline only: a punchier display face than the rest of the site's
     headings, so the single biggest line on the page carries more character. */
  --lnh2-font-hero: 'Bricolage Grotesque', 'Parkinsans', sans-serif;
  --lnh2-hero-size: clamp(40px, 4.6vw, 58px);
  --lnh2-hero-tracking: -0.03em;
  --lnh2-head-tracking: -0.02em;

  /* ---- palette · DARK-LOCKED (see the mode note above) ---- */
  --lnh2-bg: #0a0a12;
  --lnh2-surface: rgba(255,255,255,.035);
  --lnh2-ink: #f5f6ff;
  --lnh2-body: #b8bed6;
  --lnh2-muted: #949bbb;
  --lnh2-muted-2: #6d7398;
  --lnh2-line: rgba(255,255,255,.10);
  --lnh2-line-2: rgba(255,255,255,.06);

  --lnh2-accent: #8b7cff;
  --lnh2-accent-2: #22d3ee;
  --lnh2-accent-ink: #ffffff;
  --lnh2-grad-1: #6366f1;
  --lnh2-grad-2: #a855f7;
  --lnh2-grad-3: #22d3ee;
  --lnh2-accent-grad: linear-gradient(100deg, var(--lnh2-grad-1) 0%, var(--lnh2-grad-2) 52%, var(--lnh2-grad-3) 100%);
  --lnh2-accent-halo: rgba(139,124,255,.28);
  --lnh2-accent-soft-bg: rgba(139,124,255,.12);
  --lnh2-accent-soft-border: rgba(139,124,255,.24);

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

  --lnh2-glass-bg: rgba(255,255,255,.045);
  --lnh2-glass-blur: blur(14px) saturate(150%);
  --lnh2-glass-hi: rgba(255,255,255,.10);
  --lnh2-btn-shimmer: rgba(255,255,255,.42);

  /* stat-bar item padding as a TOKEN, not a hard property — see the note over
     the ≤560px block for why the Elementor control must not write `padding`
     straight onto .lnew-hero2__hstat. */
  --lnh2-hstat-pad: 18px 28px;

  --lnh2-shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --lnh2-shadow-md: 0 12px 34px rgba(0,0,0,.5);
  --lnh2-shadow-lg: 0 34px 74px rgba(0,0,0,.62);
  --lnh2-shadow-accent: 0 16px 44px rgba(99,102,241,.4);
  --lnh2-shadow-accent-hover: 0 22px 54px rgba(99,102,241,.5);
  --lnh2-btn-glow: 0 0 34px 3px rgba(139,124,255,.45);

  --lnh2-aurora-op: .8;
  --lnh2-vignette: radial-gradient(120% 80% at 50% 120%, rgba(10,10,18,.9), transparent 60%);
  --lnh2-net-op: .95;
  --lnh2-net-op-sm: .5;      /* under 640px the wiring steps back — see the media query */

  /* ---- channel carousel ---- */
  --lnh2-chan-dur: 12s;
  --lnh2-chan-n: 6;
  --lnh2-chan-shift: -5s;
  --lnh2-chan-wa: #25d366;
  --lnh2-chan-tg: #29a9ea;
  --lnh2-chan-em: #ea4335;
  --lnh2-chan-ph: #f59e0b;

  /* ---- nested "See it work" showcase ----
     the reference's `.showcase { margin-top: 88px }`, which is the ONLY
     geometry the showcase gains by being nested in the hero. */
  --lnh2-sc-gap: 88px;

  /* ---- marquees ---- */
  --lnh2-chanmq-dur: 34s;
  --lnh2-marquee-dur: 175s;
  --lnh2-marquee-gap: 64px;
  --lnh2-logo-h: 46px;
  --lnh2-logo-op: .85;
  --lnh2-logo-gray: .35;

  position: relative;
  overflow: hidden;
  padding-top: calc(var(--lnh2-nav-flow) + var(--lnh2-pad-t));
  padding-bottom: var(--lnh2-pad-b);
  background: var(--lnh2-bg);
  font-family: var(--lnh2-font-sans);
  color: var(--lnh2-body);
  font-size: 17px;
  line-height: 1.6;
  letter-spacing: normal;
  -webkit-font-smoothing: antialiased;
}

/* =====================================================================
   Background — animated aurora mesh + bottom vignette
   ===================================================================== */
.lnew-hero2__bg { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.lnew-hero2__bg::before {
  content: ""; position: absolute; inset: -20%;
  background:
    radial-gradient(38% 42% at 22% 28%, rgba(99,102,241,.55), transparent 60%),
    radial-gradient(34% 38% at 78% 22%, rgba(168,85,247,.5), transparent 60%),
    radial-gradient(40% 44% at 62% 78%, rgba(34,211,238,.4), transparent 62%);
  filter: blur(60px);
  opacity: var(--lnh2-aurora-op);
  animation: lnh2-aurora-drift 16s ease-in-out infinite alternate;
}
@keyframes lnh2-aurora-drift {
  0%   { transform: translate3d(-3%, -2%, 0) scale(1.05); }
  50%  { transform: translate3d(4%, 3%, 0) scale(1.12); }
  100% { transform: translate3d(-2%, 4%, 0) scale(1.06); }
}
/* the reference draws this on .hero::after; a real element instead, so the
   Style tab can switch it off without fighting a pseudo's content property. */
.lnew-hero2__veil {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: var(--lnh2-vignette);
}

/* =====================================================================
   Ambient connection-wiring (behind the content)
   ===================================================================== */
.lnew-hero2__net {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  width: 100%; height: 100%; opacity: var(--lnh2-net-op);
  /* fade the wiring out behind the headline; show it toward top / sides / bottom */
  -webkit-mask-image: radial-gradient(120% 95% at 50% 35%, transparent 0, transparent 13%, #000 48%);
          mask-image: radial-gradient(120% 95% at 50% 35%, transparent 0, transparent 13%, #000 48%);
}
/* NOTE: `stroke` is deliberately NOT declared here. The wires inherit it from
   the parent <g stroke="url(#…)"> presentation attribute, whose gradient id is
   per-instance (two heroes on one page must not share a <defs>). A CSS stroke
   would win over that attribute and kill the gradient — recolour the wires via
   the Accent / Accent 2 palette controls, which drive the gradient stops. */
.lnew-hero2__wire { fill: none; stroke-width: 2.1; stroke-linecap: round; opacity: .82; vector-effect: non-scaling-stroke; }
/* dotted, not dashed: a near-zero dash length + the round linecap above draws
   each segment as a small circle, so the flow reads as travelling dots. */
.lnew-hero2__wire--dash { stroke-dasharray: .1 11; animation: lnh2-net-flow 9s linear infinite; }
.lnew-hero2__wire--dash:nth-of-type(2n) { animation-duration: 12s; }
.lnew-hero2__wire--dash:nth-of-type(3n) { animation-duration: 7s; animation-direction: reverse; }
@keyframes lnh2-net-flow { to { stroke-dashoffset: -132; } }

.lnew-hero2__nodes { filter: drop-shadow(0 0 6px var(--lnh2-accent-halo)); }
.lnew-hero2__node { fill: var(--lnh2-accent); opacity: 1; }
.lnew-hero2__node--hub { opacity: 1; transform-origin: 720px 440px; animation: lnh2-net-pulse 4.5s ease-in-out infinite; }
@keyframes lnh2-net-pulse { 0%, 100% { opacity: .6; transform: scale(1); } 50% { opacity: 1; transform: scale(1.18); } }

/* ---- channel-logo carousel at the 2 wire endpoints that sit fully clear of
   both the headline text and the mask's fade zone. Each slot stacks all the
   channel bubbles at the SAME point and cycles them on a timer: hold, fade,
   next — rather than spreading them across the fan, which would put one
   directly behind the headline. Icons are native SVG shapes (not an HTML
   overlay) so they inherit the exact same viewBox transform as the wire
   endpoints regardless of the net's xMidYMid-slice cropping.

   .lnew-hero2__chan-dot is a permanent small circle at the slot's centre —
   the same "socket" look as every other wire-endpoint node — so the wire
   visibly terminates at a point at all times. Each logo scales up FROM that
   point and shrinks back INTO it on exit. ---- */
.lnew-hero2__chan-dot { fill: var(--lnh2-accent); }
/* fully round bubble (rx = half the 30px box = a circle) — so a shrunk logo
   reads as the round dot itself, and the grow/shrink is a circle breathing
   out of / back into the circular dot, not a square popping in. */
.lnew-hero2__chan-bg { rx: 15px; ry: 15px; }
.lnew-hero2__chan-icon { fill: none; stroke: #fff; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.lnew-hero2__chan-slide {
  opacity: 0; transform: scale(0);
  /* transform-box:fill-box is ESSENTIAL: without it, SVG's default
     transform-box:view-box makes transform-origin:center resolve to the
     CENTRE OF THE WHOLE 1440x900 viewBox (720,450 — behind the headline), so
     the logo would scale toward/away from the hero centre instead of its own
     dot. fill-box re-bases the origin to the element's OWN bounding box. */
  transform-box: fill-box; transform-origin: center;
  filter: drop-shadow(0 4px 10px rgba(10,10,30,.4));
  animation: lnh2-chan-cycle var(--lnh2-chan-dur) ease-in-out infinite;
  /* delay = this slot's phase shift + this icon's own slot within the cycle.
     --ci (0-based index) is written inline by PHP so a reordered repeater can
     never desync the sequence; the per-icon step is the cycle divided by the
     number of channels, so the stagger stays even at any count. */
  animation-delay: calc(var(--shift, 0s) + var(--ci, 0) * (var(--lnh2-chan-dur) / var(--lnh2-chan-n)));
}
.lnew-hero2__chan-slide--wa .lnew-hero2__chan-bg { fill: var(--lnh2-chan-wa); }
.lnew-hero2__chan-slide--tg .lnew-hero2__chan-bg { fill: var(--lnh2-chan-tg); }
.lnew-hero2__chan-slide--em .lnew-hero2__chan-bg { fill: var(--lnh2-chan-em); }
.lnew-hero2__chan-slide--ph .lnew-hero2__chan-bg { fill: var(--lnh2-chan-ph); }
/* --ms / --ig take a per-instance <linearGradient> as a fill="url(#…)"
   presentation attribute in the markup — see the stroke note above for why
   those two are not restated here. Their stops read --lnh2-ms-* / --lnh2-ig-*. */

/* 2 slots, phase-shifted. Two things this buys:
   1. Different brands: the shift is ~2.5 logos apart in the sequence, so the
      two tips never show the same logo at once.
   2. A TIME gap on birth/death: an ODD number of seconds, so one tip's logos
      are born on even seconds and the other's on odd — a ~1s offset, so the
      two never pop in / fade out at the exact same instant.
   NEGATIVE shift (vs positive) starts s2 already mid-cycle, so both tips are
   live from the first frame instead of s2 sitting blank after load. */
.lnew-hero2__chan-slot--s1 { --shift: 0s; }
.lnew-hero2__chan-slot--s2 { --shift: var(--lnh2-chan-shift); }

/* CRITICAL constraint: the channels share one slot on a single cycle, so each
   logo owns 100/n % of it. The ENTIRE birth→hold→death must finish inside that
   window and leave a gap, or consecutive logos overlap on the dot. At the
   default 6 channels the window is 16.67% and the death lands at 15% — keep
   the channel count at 6 or fewer, or raise the cycle duration to match.
   The motion is authored as an ORGANIC life-cycle, not a place-and-remove:
     0    →2.5% born: emerges from the dot (scale .15 = dot-sized) and grows
     2.5 →6%   inflates past full size to a soft 1.1 overshoot (a "pop of life")
     6   →8%   eases back and settles to 1
     8   →10.5% HOLD, fully alive
     10.5→15%  DEATH: deflates gradually back down to dot size while fading
     15  →100% just the dot, a clean beat before the next is born */
@keyframes lnh2-chan-cycle {
  0%      { opacity: 0;  transform: scale(.15); }   /* asleep as the dot */
  1.5%    { opacity: .5; transform: scale(.32); }   /* gently wakes / emerges */
  4%      { opacity: 1;  transform: scale(.9); }    /* grows */
  6%      { opacity: 1;  transform: scale(1.1); }   /* soft overshoot */
  8%      { opacity: 1;  transform: scale(1); }     /* settles, fully alive */
  10%     { opacity: 1;  transform: scale(1); }     /* holds */
  12%     { opacity: .9; transform: scale(.72); }   /* death begins */
  13.5%   { opacity: .5; transform: scale(.4); }    /* sinking back */
  15%     { opacity: 0;  transform: scale(.15); }   /* returned into the dot */
  100%    { opacity: 0;  transform: scale(.15); }   /* just the dot, waiting */
}

/* =====================================================================
   Content column
   ===================================================================== */
.lnew-hero2__wrap { width: 100%; max-width: var(--lnh2-maxw); margin-inline: auto; padding-inline: var(--lnh2-gutter); }
.lnew-hero2__inner { position: relative; z-index: 1; display: block; text-align: center; }
.lnew-hero2__intro { max-width: 960px; margin-inline: auto; }

/* ---- eyebrow pill + its indicator lamp ---- */
.lnew-hero2__eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--lnh2-font-sans);
  font-size: 15px; font-weight: 600; letter-spacing: 0.02em; line-height: 1.6;
  color: var(--lnh2-eyebrow-ink);
  background: var(--lnh2-eyebrow-bg);
  border: 1px solid var(--lnh2-eyebrow-border);
  padding: 8px 18px; border-radius: var(--lnh2-radius-pill);
}
/* 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-hero2__eyebrow-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: none;
  background: var(--lnh2-accent);
  box-shadow: 0 0 0 4px var(--lnh2-accent-halo);
  opacity: .45;
  animation: lnh2-dot-lamp 5.2s ease-in-out infinite;
}
@keyframes lnh2-dot-lamp {
  0%        { opacity: .35; box-shadow: 0 0 0 4px var(--lnh2-accent-halo), 0 0 0 0 transparent; }
  8%        { opacity: 1;   box-shadow: 0 0 0 4px var(--lnh2-accent-halo), 0 0 7px 1px var(--lnh2-accent); }
  22%       { opacity: 1;   box-shadow: 0 0 0 4px var(--lnh2-accent-halo), 0 0 7px 1px var(--lnh2-accent); }
  40%, 100% { opacity: .35; box-shadow: 0 0 0 4px var(--lnh2-accent-halo), 0 0 0 0 transparent; }
}

/* `text-wrap: balance` is what actually makes the headline read as centred: it
   equalises line lengths so the block has matching left and right ragged edges
   instead of a stub last line. */
.lnew-hero2__title {
  font-family: var(--lnh2-font-hero);
  font-size: var(--lnh2-hero-size);
  font-weight: 700;
  line-height: 1.12;
  color: var(--lnh2-ink);
  margin: 36px 0 0;
  letter-spacing: var(--lnh2-hero-tracking);
  text-wrap: balance;
}
.lnew-hero2__title-accent {
  background: var(--lnh2-accent-grad);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.lnew-hero2__desc {
  margin-top: 44px; font-size: 21px; color: var(--lnh2-muted);
  line-height: 1.62; text-align: center; text-wrap: balance;
}
.lnew-hero2__actions { margin-top: 66px; display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }

/* reassurance line: one small centred caption, not a pill row */
.lnew-hero2__note { margin-top: 26px; font-size: 13.5px; font-weight: 600; color: var(--lnh2-muted); }

/* =====================================================================
   Buttons (ported from components/buttons.css + the aurora override)
   ===================================================================== */
.lnew-hero2__btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-family: var(--lnh2-font-sans);
  font-size: 15.5px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.6;
  padding: 13px 22px; border-radius: var(--lnh2-btn-radius);
  white-space: nowrap;
  /* isolation + overflow contain the shimmer sweep — see the stacking note below */
  position: relative; overflow: hidden; isolation: isolate;
  transition: transform .22s var(--lnh2-ease), box-shadow .3s var(--lnh2-ease),
              background .22s ease, border-color .22s ease, color .22s ease;
}
.lnew-hero2__btn svg { width: 15px; height: 15px; transition: transform .4s var(--lnh2-ease); }
.lnew-hero2__btn:hover svg { transform: translateX(4px); }
/* keep label + icon above the shimmer sweep */
.lnew-hero2__btn > * { position: relative; z-index: 2; }

.lnew-hero2__btn--primary {
  background: var(--lnh2-accent-grad); color: var(--lnh2-accent-ink); border: none;
  background-size: 130% 70%; background-position: 0% 50%;
  animation: lnh2-gradient-loop 7s ease-in-out infinite;
  /* the aurora override replaces buttons.css's flat shadow with a pill glow
     that grows on hover, and narrows the transition to the two properties it
     actually animates. */
  box-shadow: var(--lnh2-shadow-accent), 0 0 0 0 rgba(139,124,255,0);
  transition: box-shadow .4s var(--lnh2-ease), transform .22s var(--lnh2-ease);
}
.lnew-hero2__btn--primary:hover {
  transform: translateY(-2px);
  box-shadow: var(--lnh2-shadow-accent-hover), var(--lnh2-btn-glow);
}
@keyframes lnh2-gradient-loop {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

/* "Melt" shimmer sweep, fires once per hover.
   STACKING NOTE: :hover applies a transform, which creates a stacking context.
   Inside it a z-index:-1 pseudo would paint ABOVE the element's background — a
   hover-only flicker that is miserable to debug. Hence isolation:isolate above
   plus a POSITIVE z-index here. Do not "simplify" this to a negative z-index. */
.lnew-hero2__btn--primary::before {
  content: ""; position: absolute; z-index: 1; top: 0; bottom: 0; left: -45%; width: 45%;
  background: linear-gradient(100deg, transparent, var(--lnh2-btn-shimmer), transparent);
  transform: skewX(-18deg); opacity: 0; pointer-events: none;
}
.lnew-hero2__btn--primary:hover::before { opacity: 1; animation: lnh2-btn-melt .85s var(--lnh2-ease); }
@keyframes lnh2-btn-melt { from { left: -45%; } to { left: 120%; } }

.lnew-hero2__btn--ghost { background: var(--lnh2-surface); color: var(--lnh2-ink); border: 1px solid var(--lnh2-line); box-shadow: var(--lnh2-shadow-sm); }
.lnew-hero2__btn--ghost:hover { transform: translateY(-2px); border-color: var(--lnh2-accent); box-shadow: var(--lnh2-shadow-md); }

.lnew-hero2__btn--lg { padding: 16px 28px; font-size: 16.5px; border-radius: calc(var(--lnh2-btn-radius) + 1px); }

/* =====================================================================
   hstats — a floating glass capsule bar: icon medallion + figure + label per
   stat, tapered dividers (echoing the trusted caption's accent hairlines),
   each item lifting gently on hover. Reads as one small "proof panel", not
   three loose numbers on the hero background.
   ===================================================================== */
.lnew-hero2__hstats {
  margin: 52px auto 0; width: max-content; max-width: 100%;
  display: flex; align-items: stretch; justify-content: center;
  border-radius: var(--lnh2-radius-xl);
  background: var(--lnh2-glass-bg);
  -webkit-backdrop-filter: var(--lnh2-glass-blur); backdrop-filter: var(--lnh2-glass-blur);
  border: 1px solid var(--lnh2-line);
  box-shadow: inset 0 1px 0 var(--lnh2-glass-hi), var(--lnh2-shadow-md);
}
.lnew-hero2__hstat {
  display: flex; align-items: center; gap: 13px;
  padding: var(--lnh2-hstat-pad); text-align: left;
  transition: transform .35s var(--lnh2-ease);
}
.lnew-hero2__hstat:hover { transform: translateY(-3px); }
/* tapered hairline between items, not a flat border */
.lnew-hero2__hstat + .lnew-hero2__hstat { position: relative; }
.lnew-hero2__hstat + .lnew-hero2__hstat::before {
  content: ""; position: absolute; left: 0; top: 14%; bottom: 14%; width: 1px;
  background: linear-gradient(180deg, transparent, var(--lnh2-line-2) 20%, var(--lnh2-line-2) 80%, transparent);
}
.lnew-hero2__hstat-ic {
  flex: none; width: 38px; height: 38px; display: grid; place-items: center;
  border-radius: 12px 12px 12px 4px;
  color: var(--lnh2-accent); background: var(--lnh2-accent-soft-bg);
  box-shadow: inset 0 0 0 1px var(--lnh2-accent-soft-border);
}
.lnew-hero2__hstat-ic svg { width: 18px; height: 18px; }
.lnew-hero2__hstat-text { display: flex; flex-direction: column; }
.lnew-hero2__hstat-n {
  font-family: var(--lnh2-font-head); font-weight: 800;
  font-size: clamp(20px, 2.2vw, 25px); color: var(--lnh2-ink);
  letter-spacing: var(--lnh2-head-tracking); line-height: 1.1;
}
.lnew-hero2__hstat-l { margin-top: 3px; font-size: 12.5px; color: var(--lnh2-muted); white-space: nowrap; }

/* =====================================================================
   chanmq — looping channel-name strip. Same seamless -50% mechanic as the
   trusted marquee below, scoped separately so its own duration/spacing don't
   fight the 35-logo strip's tuning.
   ===================================================================== */
.lnew-hero2__chanmq {
  margin-top: 30px; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.lnew-hero2__chanmq-track { display: flex; width: max-content; animation: lnh2-marquee var(--lnh2-chanmq-dur) linear infinite; }
.lnew-hero2__chanmq-track li {
  display: flex; align-items: center; gap: 8px; margin-right: 12px;
  font-size: 13px; font-weight: 600; color: var(--lnh2-body); white-space: nowrap;
  padding: 8px 16px; border-radius: var(--lnh2-radius-pill);
  background: var(--lnh2-glass-bg);
  -webkit-backdrop-filter: var(--lnh2-glass-blur); backdrop-filter: var(--lnh2-glass-blur);
  border: 1px solid var(--lnh2-line);
}
.lnew-hero2__chanmq--pause:hover .lnew-hero2__chanmq-track { animation-play-state: paused; }
.lnew-hero2__chanmq-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }

/* =====================================================================
   Trusted band — a full-bleed frosted ribbon spanning the hero edge to edge
   (no wrap). Hairline top/bottom borders seat it against the hero; the
   marquee's own edge-mask fades the logos into the page gutter, so no side
   padding is needed.
   ===================================================================== */
.lnew-hero2__trusted {
  position: relative; z-index: 1; margin-top: 64px;
  padding: 32px 0 30px;
  background: var(--lnh2-glass-bg);
  -webkit-backdrop-filter: var(--lnh2-glass-blur); backdrop-filter: var(--lnh2-glass-blur);
  border-top: 1px solid var(--lnh2-line);
  border-bottom: 1px solid var(--lnh2-line);
  box-shadow: inset 0 1px 0 var(--lnh2-glass-hi);
}
.lnew-hero2__trusted-cap {
  display: flex; align-items: center; justify-content: center; gap: 18px;
  color: var(--lnh2-muted); font-size: 12px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; margin-bottom: 24px;
}
/* hairlines taper from the accent, not from a flat rule */
.lnew-hero2__trusted-cap::before, .lnew-hero2__trusted-cap::after { content: ""; height: 1px; flex: 0 1 96px; }
.lnew-hero2__trusted-cap::before { background: linear-gradient(90deg, transparent, var(--lnh2-accent)); opacity: .5; }
.lnew-hero2__trusted-cap::after  { background: linear-gradient(90deg, var(--lnh2-accent), transparent); opacity: .5; }

.lnew-hero2__marquee { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); }
/* Spacing is margin-right per item, NOT gap on the track. The loop translates
   exactly -50%, which only equals one full set if every item carries its own
   trailing space — with `gap` the track is N items + N-1 gaps, so half of it
   lands half a gap short and the seam visibly jumps. */
.lnew-hero2__track { display: flex; width: max-content; animation: lnh2-marquee var(--lnh2-marquee-dur) linear infinite; }
.lnew-hero2__track li { margin-right: var(--lnh2-marquee-gap); }
.lnew-hero2__marquee--pause:hover .lnew-hero2__track { animation-play-state: paused; }
/* `.lnew-hero2 ` prefix is load-bearing, not decoration: Elementor's
   frontend.min.css ships `.elementor img{height:auto}` at (0,1,1), which ties a
   bare `.lnew-hero2__track img` and would win or lose on enqueue order alone.
   The extra class makes this (0,2,1) so the logo height is never a coin toss. */
.lnew-hero2 .lnew-hero2__track img {
  height: var(--lnh2-logo-h); width: auto;
  opacity: var(--lnh2-logo-op); filter: grayscale(var(--lnh2-logo-gray));
  transition: opacity .35s var(--lnh2-ease), filter .35s var(--lnh2-ease), transform .35s var(--lnh2-ease);
}
.lnew-hero2__track img:hover { opacity: 1; filter: grayscale(0); transform: scale(1.08); }
@keyframes lnh2-marquee { to { transform: translateX(-50%); } }

/* =====================================================================
   Scroll reveal — --i is assigned by lnew-hero2.js (index within parent)
   ===================================================================== */
.lnew-hero2 .lnew-reveal {
  opacity: 0;
  transform: translate3d(0, var(--lnh2-rv-dist), 0);
  transition: opacity var(--lnh2-rv-dur) var(--lnh2-ease),
              transform var(--lnh2-rv-dur) var(--lnh2-ease);
  transition-delay: calc(var(--i, 0) * var(--lnh2-rv-step));
}
.lnew-hero2 .lnew-reveal.is-in { opacity: 1; transform: none; }
/* Elementor's editor canvas never fires our observer for off-screen nodes on
   re-render — show everything so the widget is never invisible while editing. */
.elementor-editor-active .lnew-hero2 .lnew-reveal { opacity: 1; transform: none; }

/* =====================================================================
   Responsive.

   Mirrors the reference's LIVE cascade only. base/4-responsive.css also
   carries .hero / .hero__title / .hero__desc / .btn--lg rules, but build.sh
   concatenates base/ BEFORE components/, so components/hero.css's unmediaed
   declarations win at every width and those four are dead in the shipped
   build. Re-adding them here would change the design, not preserve it.
   ===================================================================== */
@media (max-width: 1040px) {
  .lnew-hero2 { --lnh2-gutter: 24px; }
}
@media (max-width: 760px) {
  .lnew-hero2 { --lnh2-gutter: 20px; }
  /* the one .hero rule in 4-responsive.css that IS live: its (0,2,0) beats
     buttons.css's (0,1,0), so the CTAs go full-width on a phone. */
  .lnew-hero2__actions .lnew-hero2__btn { flex: 1 1 auto; justify-content: center; }
}
@media (max-width: 640px) {
  /* its own token rather than a fraction of --lnh2-net-op, so the reference's
     literal .5 survives exactly and the Style tab can still tune both states. */
  .lnew-hero2__net { opacity: var(--lnh2-net-op-sm); }
}
@media (max-width: 560px) {
  /* The eyebrow is one long sentence in a pill that can only ever be as wide as
     the content column. Below ~440px the reference's flat 15px overflows it and
     the line breaks with a two-character orphan ("… — 24/7") on its own row,
     with the status lamp then floating against the middle of a two-line block.
     Scaling the type with the viewport keeps it on ONE line down to ~355px, and
     `balance` splits it evenly rather than leaving an orphan on anything
     narrower still. Font size only — the pill's padding is an Elementor control
     (see the token note below), so setting it here would be dead CSS. */
  .lnew-hero2__eyebrow { font-size: clamp(12.5px, 3.4vw, 15px); text-wrap: balance; max-width: 100%; }

  .lnew-hero2__hstats {
    width: 100%;
    /* WHY THE TOKEN, AND WHY IT IS SET HERE, ON THE CONTAINER:
       the "Item Padding" control writes its 18px/28px default into
       post-<id>.css as `.elementor-N .elementor-element-X .lnew-hero2__hstat
       {padding:…}` — (0,4,0) and enqueued after this file, so a plain
       `.lnew-hero2__hstat{padding:…}` in this media query LOSES and the desktop
       28px side padding survives onto a 393px phone. That left each stat's text
       column ~29px wide, which is what wrapped "3 sec" onto two lines and broke
       "channels, one inbox" into three.
       Custom properties are not decided by specificity across elements: the
       nearest ancestor that sets one wins. The control sets --lnh2-hstat-pad on
       the widget wrapper, so re-setting it here — one level down, on .hstats —
       always wins inside this breakpoint no matter what the control emitted. */
    --lnh2-hstat-pad: 14px 10px;
  }
  .lnew-hero2__hstat { flex: 1 1 0; gap: 8px; }
  .lnew-hero2__hstat-ic { width: 30px; height: 30px; }
  .lnew-hero2__hstat-ic svg { width: 14px; height: 14px; }
  .lnew-hero2__hstat-n { font-size: 17px; }
  .lnew-hero2__hstat-l { font-size: 10.5px; white-space: normal; }
}
@media (max-width: 460px) {
  /* Only the gutter. base/4-responsive.css also tightens .btn--lg here, but
     components/buttons.css restates the same properties unmediaed AFTER it, so
     that rule never applies in the shipped build — and it isn't needed: the
     760px rule above already makes both CTAs flex:1 1 auto, so they wrap to
     one full-width pill each and fit a 360px viewport at the desktop padding.
     Re-adding it would make this hero narrower than the reference, not safer. */
  .lnew-hero2 { --lnh2-gutter: 16px; }
}
/* Small phones (iPhone 14 Pro is 393px): three side-by-side stats leave each
   label a ~59px text column, so even at 10.5px every label still wraps to two
   or three ragged lines beside its medallion. Stacking the medallion ABOVE the
   figure hands the text the item's full ~97px and centres the whole tile, so
   each stat reads as one unit instead of a squeezed row. */
@media (max-width: 440px) {
  .lnew-hero2__hstats { --lnh2-hstat-pad: 14px 8px; }
  .lnew-hero2__hstat { flex-direction: column; align-items: center; gap: 7px; text-align: center; }
  .lnew-hero2__hstat-text { align-items: center; }
  .lnew-hero2__hstat-l { text-wrap: balance; }
}

/* Coarse-pointer: hover lifts feel wrong on touch */
@media (hover: none) {
  .lnew-hero2__btn:hover, .lnew-hero2__hstat:hover { transform: none; }
}

/* =====================================================================
   NESTED "See it work" — the showcase block the reference moved INSIDE the
   hero at v0.3.0 (src/html/partials/hero.html, `.showcase` sitting as a
   sibling of `.hero__intro` inside `.wrap.hero__inner`).

   The block itself is the SAME component this plugin ships standalone as
   lnew_showcase, so its markup, its --lnsc-* tokens and lnew-showcase.css are
   reused verbatim — see render_showcase() in class-hero2-widget.php. Only the
   four things the reference changes by nesting live here:

     1. no wrap of its own — .lnew-hero2__wrap already applies the max-width
        and gutter, exactly as .wrap.hero__inner does in the reference (which
        is why the markup omits .lnew-showcase__wrap);
     2. no section padding and no background — it sits ON the hero;
     3. the 88px breathing room above it (hero.css `.showcase{margin-top:88px}`);
     4. the DARK palette, wired to this hero's own --lnh2-* tokens rather than
        redeclared: in the reference the showcase simply inherits the hero's
        dark-locked token block, so the hero's Colors controls must recolour it
        too. Values are identical to lnew-showcase.css's [data-mode="dark"]
        palette, so nothing shifts.

   EVERY selector here is (0,2,0) or higher, i.e. it beats lnew-showcase.css's
   own (0,1,0) rules — INCLUDING the ones inside its media queries — no matter
   which of the two stylesheets Elementor enqueues first. Do not "simplify"
   these to a single class. Elementor's generated control CSS is also (0,2,0)
   but always loads after both files, so the Style tab still wins.
   ===================================================================== */
.lnew-hero2 .lnew-showcase {
  /* 1 + 2 — the hero's wrap and background already cover both */
  --lnsc-pad-t: 0px;
  --lnsc-pad-b: 0px;
  background: none;
  /* the reference's nested .showcase is not a clipping context; the hero's own
     overflow:hidden is what contains the reveal travel. Keeping the standalone
     section's `overflow-x: clip` here would shave the stage's 70px drop shadow. */
  overflow: visible;

  /* 3 */
  margin-top: var(--lnh2-sc-gap);

  /* 4 — the hero's dark literals, by reference so the Colors tab flows through */
  --lnsc-ink: var(--lnh2-ink);
  --lnsc-body: var(--lnh2-body);
  --lnsc-muted: var(--lnh2-muted);
  --lnsc-eyebrow-bg: var(--lnh2-eyebrow-bg);
  --lnsc-eyebrow-ink: var(--lnh2-eyebrow-ink);
  --lnsc-eyebrow-border: var(--lnh2-eyebrow-border);
  --lnsc-accent: var(--lnh2-accent);
  --lnsc-accent-halo: var(--lnh2-accent-halo);
  --lnsc-grad-1: var(--lnh2-grad-1);
  --lnsc-grad-2: var(--lnh2-grad-2);
  --lnsc-grad-3: var(--lnh2-grad-3);
  --lnsc-shadow-md: var(--lnh2-shadow-md);
  /* `opacity: var(--hero-glow-op, .2)` in the reference — .5 inside the hero */
  --lnsc-glow-op: .5;
  --lnsc-font-sans: var(--lnh2-font-sans);
  --lnsc-font-head: var(--lnh2-font-head);

  /* the hero's own reveal distance/step drive it, so the two staggers agree */
  --lnsc-rv-dist: var(--lnh2-rv-dist);
  --lnsc-rv-dur: var(--lnh2-rv-dur);
  --lnsc-rv-step: var(--lnh2-rv-step);
  --lnsc-ease: var(--lnh2-ease);
}

/* The tab column and the screen stack travel sideways, not up: both
   `.lnew-hero2 .lnew-reveal` and `.lnew-showcase .lnew-reveal--left` are
   (0,2,0), so whichever stylesheet loads last would otherwise decide. (0,3,0)
   settles it. */
.lnew-hero2 .lnew-showcase .lnew-reveal--left  { transform: translate3d(calc(var(--lnsc-rv-dist) * -.7), 0, 0); }
.lnew-hero2 .lnew-showcase .lnew-reveal--right { transform: translate3d(calc(var(--lnsc-rv-dist) *  .7), 0, 0); }
.lnew-hero2 .lnew-showcase .lnew-reveal.is-in  { transform: none; }

/* Tabs are a left-aligned column inside a centred hero — .lnew-hero2__inner's
   text-align cascades into them exactly as .hero__inner's does upstream, so
   this only restates what the reference already resolves to. */
.lnew-hero2 .lnew-showcase .lnew-showcase__tab { text-align: left; }

@media (prefers-reduced-motion: reduce) {
  .lnew-hero2 .lnew-reveal { opacity: 1; transform: none; transition: none; }
  /* (0,3,0) — beats the two --left/--right rules above, which are (0,3,0) too
     but sit earlier in this file. */
  .lnew-hero2 .lnew-showcase .lnew-reveal { opacity: 1; transform: none; transition: none; }
  .lnew-hero2__track, .lnew-hero2__chanmq-track { animation: none !important; }
  .lnew-hero2__bg::before,
  .lnew-hero2__wire--dash,
  .lnew-hero2__node--hub,
  .lnew-hero2__eyebrow-dot,
  .lnew-hero2__btn--primary { animation: none !important; }
  .lnew-hero2__eyebrow-dot { opacity: 1; }
  .lnew-hero2__btn--primary::before { animation: none !important; display: none; }
  /* the carousel stops on its first channel rather than blinking */
  .lnew-hero2__chan-slide { animation: none !important; opacity: 0; }
  .lnew-hero2__chan-slide:first-of-type { opacity: 1; transform: none; }
  .lnew-hero2__hstat, .lnew-hero2__track img, .lnew-hero2__btn svg { transition: none !important; }
}
