/* =====================================================================
   LeadsNimble Industries — "Built for every industry": a seamless,
   auto-scrolling photo rail of nine industry cards, 3-up on desktop.

   Ported 1:1 from leadsnimble_html:
     src/html/partials/industries.html
     src/css/components/industries.css      (.indc marquee, .icard slab + scrim)
     src/js/modules/icar.js                 (clone-once loop, N-up card sizing)
     src/js/modules/photos.js               (the photo layer — see note below)
     src/css/base/2-layout.css              (.wrap, .section--soft, .section__head, .eyebrow)
     src/css/base/3-utilities.css           (.reveal stagger, reduced motion)
     src/css/themes/aurora-nightfall/tokens.css

   The theme's design tokens are resolved to literal values and re-scoped
   under --lnid-*, so the widget renders identically regardless of the active
   WP theme and never leaks variables into the rest of the page. LIGHT is the
   default mode (matching the reference build's mode.txt and the rest of the
   family); [data-mode="dark"] on <html> flips the SECTION palette.

   PHOTOS: the reference probes each URL with an off-DOM Image() and only
   injects an <img> on success, because its nine photos did not exist yet.
   Here they DO — they ship with the plugin and every card is an Elementor
   media control — so the probe is dropped and the <img> is rendered server
   side, which also buys srcset, width/height and lazy-loading. Same visual
   result, one fewer round trip per card.

   THE CARD SLAB IS MODE-INDEPENDENT. In the reference, --hcard-bg is the
   "inverted slab" token: deep purple #2a1f5c in light mode, near-white
   #f5f6ff in dark. But .icard__t / .icard__desc are hard-coded white, so the
   dark-mode card would be white-on-white. The build ships in LIGHT, so the
   deep purple IS the design — it is kept in both modes here and given its own
   control group (same call as the Showcase widget's aurora stage). Set the
   dark-mode slab from the Style tab if you ever want them to differ.

   MARQUEE MECHANICS (do not "simplify"): lnew-industries.js appends ONE clone
   of the full card set and the CSS translates the track by exactly one set
   width — that is what makes the loop seamless. --lnid-n (card count),
   --lnid-card-w (exact N-up fit) and --lnid-dur (count x seconds-per-card, so
   the cadence is constant at every viewport) are all written by the JS onto
   the carousel element; the values below are only the pre-JS fallback.
   ===================================================================== */

/* Local reset. Wrapped in :where() so it carries ZERO specificity — a bare
   `.lnew-industries p` would be (0,1,1) and would outrank every (0,1,0)
   component class below it. See [[hero-widget-feature]] / [[nav-widget-feature]]
   for the traps this avoids. Do not unwrap. */
.lnew-industries, .lnew-industries *, .lnew-industries *::before, .lnew-industries *::after { box-sizing: border-box; }
:where(.lnew-industries) :where(a) { color: inherit; text-decoration: none; }
:where(.lnew-industries) :where(p) { margin: 0; }
:where(.lnew-industries) :where(figure) { margin: 0; }
:where(.lnew-industries) :where(article) { margin: 0; }
:where(.lnew-industries) :where(svg) { display: block; }
:where(.lnew-industries) :where(img) { max-width: 100%; display: block; }
:where(.lnew-industries) :where(h1, h2, h3) { margin: 0; }

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

  /* ---- the rail ---- */
  --lnid-gap: 18px;               /* read back by the JS to size the cards */
  --lnid-rail-top: 8px;
  --lnid-fade: 5%;                /* edge mask — cards dissolve, never clip */
  --lnid-card-w: 340px;           /* JS overwrites for an exact N-up fit */
  --lnid-n: 9;                    /* JS overwrites with the real card count */
  --lnid-dur: 46s;                /* JS overwrites: count x seconds-per-card */

  /* ---- the card ---- */
  --lnid-card-ratio: 1 / 1;
  --lnid-card-radius: 24px;
  --lnid-lift: -6px;
  --lnid-zoom-rest: 1.05;
  --lnid-zoom: 1.12;

  --lnid-cap-inset: 20px;
  --lnid-cap-gap: 5px;
  --lnid-rule-w: 30px;
  --lnid-rule-h: 3px;
  --lnid-card-t-size: 19px;
  --lnid-card-d-size: 13px;
  --lnid-desc-max: 60px;

  --lnid-ic-size: 46px;
  --lnid-ic-radius: 14px;
  --lnid-ic-inset: 16px;
  --lnid-ic-glyph: 22px;

  --lnid-line-top: 40px;
  --lnid-line-size: 20px;

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

  /* ---- SECTION palette · LIGHT (the site's default mode) ---- */
  --lnid-bg: #cfd7ee;             /* --bg-soft, i.e. .section--soft */
  --lnid-ink: #12122a;
  --lnid-body: #454a63;
  --lnid-muted: #6b7089;

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

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

  --lnid-card-shadow: 0 18px 34px -16px rgba(20,20,55,.34);
  --lnid-shadow-lg: 0 30px 70px rgba(30,30,80,.16);

  /* ---- CARD palette · mode-INDEPENDENT (see the header note) ---- */
  --lnid-slab: #2a1f5c;
  --lnid-card-ink: #ffffff;
  --lnid-card-desc-ink: rgba(255,255,255,.82);
  --lnid-ic-bg: rgba(18,16,45,.30);
  --lnid-ic-border: rgba(255,255,255,.30);
  --lnid-ic-ink: #ffffff;

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

/* ---- SECTION palette · DARK ([data-mode="dark"] on <html>, written by the
   nav's mode toggle). The card tokens above are intentionally absent. ---- */
[data-mode="dark"] .lnew-industries {
  --lnid-bg: #10101d;
  --lnid-ink: #f5f6ff;
  --lnid-body: #b8bed6;
  --lnid-muted: #949bbb;

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

  --lnid-accent: #8b7cff;
  --lnid-shadow-lg: 0 34px 74px rgba(0,0,0,.62);
  --lnid-card-shadow: 0 18px 34px -16px rgba(0,0,0,.5);
}

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

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

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

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

/* =====================================================================
   The rail — nine cards flow through an N-up viewport.

   overflow-x: clip (not hidden) so the cards' soft drop-shadow still shows
   BELOW the rail instead of being cut into a hard line, and doesn't smear
   onto the section at the fades. `hidden` would also create a scroll
   container, which breaks position: sticky in any ancestor.
   ===================================================================== */
.lnew-industries__carousel {
  position: relative;
  margin-top: var(--lnid-rail-top);
  overflow-x: clip;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--lnid-fade), #000 calc(100% - var(--lnid-fade)), transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 var(--lnid-fade), #000 calc(100% - var(--lnid-fade)), transparent 100%);
}
.lnew-industries__track {
  display: flex;
  width: max-content;
  animation: lnid-scroll var(--lnid-dur) linear infinite;
  will-change: transform;
}
@keyframes lnid-scroll {
  to { transform: translateX(calc(-1 * var(--lnid-n) * (var(--lnid-card-w) + var(--lnid-gap)))); }
}

/* Keyboard focus ALWAYS pauses (a rail that keeps moving under a focused
   link is unusable); the pointer pause is the widget's own toggle. */
.lnew-industries__carousel:focus-within .lnew-industries__track { animation-play-state: paused; }
.lnew-industries--hover-pause .lnew-industries__carousel:hover .lnew-industries__track { animation-play-state: paused; }

/* Right-to-left travel. `reverse` replays the very same keyframe backwards,
   so the [set][clone] seam still lands exactly on a card boundary. */
.lnew-industries--reverse .lnew-industries__track { animation-direction: reverse; }

/* Auto-scroll off: a calm, manually-scrollable rail. The JS skips the clone
   pass in this mode, so there is exactly one of each card to scroll through. */
.lnew-industries--static .lnew-industries__carousel {
  overflow-x: auto;
  -webkit-mask-image: none; mask-image: none;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scroll-snap-type: x proximity;
}
.lnew-industries--static .lnew-industries__track { animation: none; }
.lnew-industries--static .lnew-industries__card { scroll-snap-align: start; }

/* =====================================================================
   The card — a full-bleed photo melting into the brand slab, with the
   label sitting on the solid part of that melt.
   ===================================================================== */
.lnew-industries__card {
  position: relative;
  display: block;
  flex: 0 0 var(--lnid-card-w);
  margin-right: var(--lnid-gap);
  aspect-ratio: var(--lnid-card-ratio);
  border-radius: var(--lnid-card-radius);
  overflow: hidden;
  isolation: isolate;
  background: var(--lnid-slab);
  box-shadow: var(--lnid-card-shadow);
  transition: transform .5s var(--lnid-ease), box-shadow .5s var(--lnid-ease);
}
.lnew-industries__card:hover {
  transform: translateY(var(--lnid-lift));
  box-shadow: var(--lnid-shadow-lg), 0 24px 60px -26px var(--lnid-accent-halo);
}
/* Only when a card is a link — :focus-visible never matches a plain article. */
.lnew-industries__card:focus-visible {
  outline: 2px solid var(--lnid-accent);
  outline-offset: 3px;
}

.lnew-industries__media {
  position: absolute; inset: 0; z-index: 0;
  display: block; overflow: hidden;
  background: var(--lnid-slab);
}
.lnew-industries__media img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  transform: scale(var(--lnid-zoom-rest));
  transition: transform .8s var(--lnid-ease);
}
.lnew-industries__card:hover .lnew-industries__media img { transform: scale(var(--lnid-zoom)); }

/* Scrim — the photo melts into the slab at the bottom, for legibility.
   The first declaration is the fallback for engines without color-mix();
   the second wins wherever it parses. */
.lnew-industries__card::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to top, var(--lnid-slab) 0%, transparent 66%);
  background: linear-gradient(to top,
    var(--lnid-slab) 0%,
    color-mix(in srgb, var(--lnid-slab) 82%, transparent) 22%,
    color-mix(in srgb, var(--lnid-slab) 28%, transparent) 46%,
    transparent 66%);
}

/* Glass icon chip. Hidden by default — the reference build removed it — and
   restored by the widget's "Show Icon Chip" toggle. */
.lnew-industries__ic { display: none; }
.lnew-industries--chips .lnew-industries__ic {
  position: absolute; z-index: 3;
  top: var(--lnid-ic-inset); left: var(--lnid-ic-inset);
  width: var(--lnid-ic-size); height: var(--lnid-ic-size);
  border-radius: var(--lnid-ic-radius);
  display: grid; place-items: center;
  color: var(--lnid-ic-ink);
  background: var(--lnid-ic-bg);
  border: 1px solid var(--lnid-ic-border);
  -webkit-backdrop-filter: blur(10px) saturate(140%); backdrop-filter: blur(10px) saturate(140%);
  box-shadow: 0 6px 18px rgba(6,7,20,.28);
}
.lnew-industries__ic svg { width: var(--lnid-ic-glyph); height: var(--lnid-ic-glyph); }

/* Caption over the slab, bottom-left */
.lnew-industries__cap {
  position: absolute; z-index: 3;
  inset: auto var(--lnid-cap-inset) var(--lnid-cap-inset);
  display: flex; flex-direction: column; gap: var(--lnid-cap-gap);
  text-align: left;
}
.lnew-industries__cap::before {
  content: ""; width: var(--lnid-rule-w); height: var(--lnid-rule-h);
  border-radius: 3px; margin-bottom: 5px;
  background: var(--lnid-accent-grad);
}
.lnew-industries__card-t {
  color: var(--lnid-card-ink);
  font-family: var(--lnid-font-head);
  font-size: var(--lnid-card-t-size);
  font-weight: 600; line-height: 1.12; letter-spacing: -.01em;
}
/* max-height (not height) is what lets the one-liner animate open without a
   measured pixel value — it is capped by --lnid-desc-max, which is a control. */
.lnew-industries__card-d {
  color: var(--lnid-card-desc-ink);
  font-size: var(--lnid-card-d-size);
  line-height: 1.5;
  max-height: 0; opacity: 0; transform: translateY(6px);
  transition: max-height .5s var(--lnid-ease), opacity .4s var(--lnid-ease), transform .5s var(--lnid-ease);
}
.lnew-industries__card:hover .lnew-industries__card-d,
.lnew-industries--desc-always .lnew-industries__card-d {
  max-height: var(--lnid-desc-max); opacity: 1; transform: none;
}

/* =====================================================================
   Closing line
   ===================================================================== */
.lnew-industries__line {
  margin-top: var(--lnid-line-top);
  font-family: var(--lnid-font-head);
  font-size: var(--lnid-line-size);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--lnid-ink);
  text-align: center;
}

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

/* ---- reduced motion: a calm, manually-scrollable rail. The JS also skips
   the clone pass so the rail holds one of each card. ---- */
@media (prefers-reduced-motion: reduce) {
  .lnew-industries .lnew-reveal { opacity: 1; transform: none; transition: none; }
  .lnew-industries__carousel {
    overflow-x: auto;
    -webkit-mask-image: none; mask-image: none;
    -webkit-overflow-scrolling: touch;
  }
  .lnew-industries__track { animation: none; }
  .lnew-industries__card,
  .lnew-industries__media img,
  .lnew-industries__card-d { transition: none; }
  .lnew-industries__card-d { max-height: var(--lnid-desc-max); opacity: 1; transform: none; }
  .lnew-industries__eyebrow-dot { animation: none !important; opacity: 1; }
}

/* =====================================================================
   Responsive. The N-up card width is computed in JS from the widget's own
   "cards per view" controls, so there is deliberately no width breakpoint
   here — only the type that the reference scales down. Sizing that a Style
   control owns is NOT repeated here (an Elementor rule carries no media
   query and would beat it at equal specificity via source order).
   ===================================================================== */
@media (max-width: 760px) {
  .lnew-industries__lead { font-size: 16.5px; }
}

/* Coarse pointer: no hover to pause the rail, so keep the one-liner visible —
   and drop the sticky :hover a tap leaves behind. */
@media (hover: none) {
  .lnew-industries__card-d { max-height: var(--lnid-desc-max); opacity: 1; transform: none; }
  .lnew-industries .lnew-industries__card:hover {
    transform: none;
    box-shadow: var(--lnid-card-shadow);
  }
  .lnew-industries .lnew-industries__card:hover .lnew-industries__media img { transform: scale(var(--lnid-zoom-rest)); }
}
