"use client";

import React, { useRef, useState, useEffect } from "react";
import dynamic from "next/dynamic";
import { motion, useMotionValue, useTransform, type MotionValue } from "framer-motion";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { P, STRATEGIES, WINNER_INDEX, ENGINE_STEPS, CONSTRAINT_LIST, STRATEGY_SCORES } from "./theme";

const LogisticsBrainCanvas = dynamic(() => import("./LogisticsBrainCanvas"), { ssr: false });

/** Rounds a MotionValue to an integer for the animated stat counters.
 *  Writes to the DOM imperatively so it never triggers a setState during the
 *  parent's render (which `useTransform` emits synchronously on re-render). */
function Counter({ mv }: { mv: MotionValue<number> }) {
  const ref = useRef<HTMLSpanElement>(null);
  useEffect(() => {
    const write = (x: number) => {
      if (ref.current) ref.current.textContent = String(Math.round(x));
    };
    write(mv.get());
    return mv.on("change", write);
  }, [mv]);
  return <span ref={ref}>{Math.round(mv.get())}</span>;
}



/** Active step index from scroll progress (−1 before the engine starts). */
function stepFromProgress(p: number): number {
  let s = -1;
  for (let i = 0; i < ENGINE_STEPS.length; i++) if (p >= ENGINE_STEPS[i].at) s = i;
  return s;
}

/** Persistent top rail: the 6 engine steps, with the current one highlighted. */
function StepRail({ active }: { active: number }) {
  return (
    <div className="dm-lb-rail" aria-hidden>
      {ENGINE_STEPS.map((s, i) => {
        const state = i < active ? "done" : i === active ? "current" : "todo";
        return (
          <React.Fragment key={s.n}>
            {i > 0 && <span className={`dm-lb-rail__line is-${i <= active ? "on" : "off"}`} />}
            <div className={`dm-lb-rail__step is-${state}`}>
              <span className="dm-lb-rail__num">{i < active ? "✓" : s.n}</span>
              <span className="dm-lb-rail__title">{s.title}</span>
            </div>
          </React.Fragment>
        );
      })}
    </div>
  );
}

/**
 * One workflow card that travels through the story. The outer anchor pins it to
 * its stage position (Left / Center / Right / Center-Hero); the inner motion card
 * slides + scales into that anchor in lockstep with scroll, so as the camera moves
 * through the stages the card visibly moves with the narrative instead of sitting
 * fixed in one corner.
 */
function StoryCard({
  step,
  index,
  pos,
  opacity,
  y,
  x,
  scale,
  num,
  kicker,
  title,
  children,
}: {
  step: number;
  index: number;
  pos: "left" | "center" | "right" | "hero";
  opacity: MotionValue<number>;
  y: MotionValue<number>;
  x: MotionValue<number>;
  scale: MotionValue<number>;
  num: string;
  kicker: string;
  title: string;
  children?: React.ReactNode;
}) {
  // Don't mount this beat's card until its step is active.
  if (step !== index) return null;
  return (
    <div className={`dm-lb-card-anchor is-${pos}`}>
      <motion.div className="dm-lb-card-story" style={{ opacity, y, x, scale }}>
        <div className="dm-lb-card-story__head">
          <span className="dm-lb-pillar__num">{num}</span>
          <span className="dm-lb-pillar__kicker">{kicker}</span>
        </div>
        <h3 className="dm-lb-pillar__title">{title}</h3>
        {children}
      </motion.div>
    </div>
  );
}

/**
 * "Logistics Brain" — one sticky, fullscreen, scroll-driven cinematic WebGL
 * section. A single GSAP ScrollTrigger maps scroll position to a normalized
 * progress value that drives the R3F scene, the camera spline and this overlay
 * in lockstep, so the whole thing reads as one continuous shot.
 */
export default function LogisticsBrainSection({ connected = false }: { connected?: boolean } = {}) {
  const containerRef = useRef<HTMLDivElement>(null);
  const progressRef = useRef(0);
  const scroll = useMotionValue(0);

  const [pinState, setPinState] = useState<"before" | "pinned" | "after">("before");
  const [step, setStep] = useState(-1);
  const [mountScene, setMountScene] = useState(false);
  const [sceneActive, setSceneActive] = useState(false);
  const [isMobile, setIsMobile] = useState(false);
  const [reduced, setReduced] = useState(false);

  useEffect(() => {
    const mqMobile = window.matchMedia("(max-width: 767px)");
    const mqReduce = window.matchMedia("(prefers-reduced-motion: reduce)");
    const sync = () => { setIsMobile(mqMobile.matches); setReduced(mqReduce.matches); };
    sync();
    mqMobile.addEventListener("change", sync);
    mqReduce.addEventListener("change", sync);
    return () => { mqMobile.removeEventListener("change", sync); mqReduce.removeEventListener("change", sync); };
  }, []);

  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const mountIo = new IntersectionObserver(
      (entries) => {
        if (entries.some((e) => e.isIntersecting)) {
          setMountScene(true);
          setSceneActive(true);
          mountIo.disconnect();
        }
      },
      { rootMargin: "70% 0px" },
    );
    const activeIo = new IntersectionObserver(
      (entries) => setSceneActive(entries.some((e) => e.isIntersecting)),
      { rootMargin: "10% 0px" },
    );
    mountIo.observe(el);
    activeIo.observe(el);
    return () => { mountIo.disconnect(); activeIo.disconnect(); };
  }, []);

  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    gsap.registerPlugin(ScrollTrigger);
    let lastPin: "before" | "pinned" | "after" = "before";
    let lastStep = -1;
    const st = ScrollTrigger.create({
      trigger: el,
      start: "top top",
      end: "bottom bottom",
      // Match Workflow 1's responsiveness (0.4) so the camera + overlay track the
      // scroll with the same snappy feel — 0.5 made this section lag noticeably.
      scrub: 0.4,
      invalidateOnRefresh: true,
      onUpdate: (self) => {
        const p = self.progress;
        progressRef.current = p;
        scroll.set(p);
        const ns = p <= 0.0002 ? "before" : p >= 0.9998 ? "after" : "pinned";
        if (ns !== lastPin) { lastPin = ns; setPinState(ns); }
        const nstep = stepFromProgress(p);
        if (nstep !== lastStep) { lastStep = nstep; setStep(nstep); }
      },
    });
    const refresh = setTimeout(() => ScrollTrigger.refresh(), 120);
    return () => { clearTimeout(refresh); st.kill(); };
  }, [scroll]);

  // Overlay transforms.
  const introOpacity = useTransform(scroll, [0, 0.04, 0.1], [1, 1, 0]);
  // Persistent header (title + step rail) fades in after the intro and out at the finale.
  const headerOpacity = useTransform(scroll, [0.04, 0.1, P.finale - 0.04, P.finale + 0.02], [0, 1, 1, 0]);

  // Per-beat kinetic-typography pillars (cross-fade across each story beat).
  const p1o = useTransform(scroll, [0.135, 0.165, 0.255, 0.275], [0, 1, 1, 0]);
  const p1y = useTransform(scroll, [0.135, 0.175], [26, 0]);
  const p2o = useTransform(scroll, [0.29, 0.32, 0.415, 0.435], [0, 1, 1, 0]);
  const p2y = useTransform(scroll, [0.29, 0.33], [26, 0]);
  const p3o = useTransform(scroll, [0.45, 0.48, 0.575, 0.595], [0, 1, 1, 0]);
  const p3y = useTransform(scroll, [0.45, 0.49], [26, 0]);
  const p4o = useTransform(scroll, [0.61, 0.64, 0.715, 0.735], [0, 1, 1, 0]);
  const p4y = useTransform(scroll, [0.61, 0.65], [26, 0]);
  const p5o = useTransform(scroll, [0.75, 0.78, 0.855, 0.875], [0, 1, 1, 0]);
  const p5y = useTransform(scroll, [0.75, 0.79], [26, 0]);

  // Horizontal slide + scale per beat — same windows as the opacity above, so the
  // card glides between its stage anchors (Left → Center → Right → Left → Center-Hero)
  // in lockstep with the camera. Each card enters from the direction of the previous
  // stage and drifts toward the next as it leaves, reading as one continuous travel.
  const p1x = useTransform(scroll, [0.135, 0.165, 0.255, 0.275], [-52, 0, 0, 52]);
  const p1s = useTransform(scroll, [0.135, 0.165, 0.255, 0.275], [0.965, 1, 1, 0.965]);
  const p2x = useTransform(scroll, [0.29, 0.32, 0.415, 0.435], [-52, 0, 0, 52]);
  const p2s = useTransform(scroll, [0.29, 0.32, 0.415, 0.435], [0.965, 1, 1, 0.965]);
  const p3x = useTransform(scroll, [0.45, 0.48, 0.575, 0.595], [-52, 0, 0, -52]);
  const p3s = useTransform(scroll, [0.45, 0.48, 0.575, 0.595], [0.965, 1, 1, 0.965]);
  const p4x = useTransform(scroll, [0.61, 0.64, 0.715, 0.735], [52, 0, 0, 52]);
  const p4s = useTransform(scroll, [0.61, 0.64, 0.715, 0.735], [0.965, 1, 1, 0.965]);
  // Hero (final selection): scales up a touch and holds center as it settles.
  const p5x = useTransform(scroll, [0.75, 0.78, 0.855, 0.875], [-52, 0, 0, 0]);
  const p5s = useTransform(scroll, [0.75, 0.78, 0.855, 0.875], [0.97, 1.05, 1.05, 1.0]);

  const finaleOpacity = useTransform(scroll, [P.finale - 0.02, P.finale + 0.04], [0, 1]);
  const finaleY = useTransform(scroll, [P.finale - 0.02, P.finale + 0.06], [40, 0]);
  const taglineOpacity = useTransform(scroll, [P.finale + 0.04, P.finale + 0.1], [0, 1]);

  const orders = useTransform(scroll, [P.finale, 0.97], [0, 59]);
  const cost = useTransform(scroll, [P.finale, 0.97], [0, 18]);

  return (
    <section ref={containerRef} className={`dm-lb is-${pinState}${connected ? " is-connected" : ""}`} aria-label="Logistics Brain — one intelligent system">
      <div className="dm-lb-sticky">
        <div className="dm-lb-card">
          {mountScene && (
            <div className="dm-lb-canvas">
              <LogisticsBrainCanvas progress={progressRef} reduced={reduced} isMobile={isMobile} active={sceneActive && pinState === "pinned"} />
            </div>
          )}
          {/* Overlay is mounted only once the section is pinned/activated, so its
              content (intro hint, header, story cards) can never be seen during the
              approach ("before"), where the sticky sits at the top of the tall
              section just off the previous workflow's seam. */}
          {pinState !== "before" && (
          <div className="dm-lb-ui">
            {/* Persistent header: what this is + where we are in the workflow */}
            <motion.div className="dm-lb-top" style={{ opacity: headerOpacity }}>
              <div className="dm-lb-eyebrow">
                <span className="dm-lb-dot" /> MileTruth Routing Engine
              </div>
              <StepRail active={step} />
            </motion.div>

            <motion.div className="dm-lb-scrollhint" style={{ opacity: introOpacity }}>
              <span>Scroll to see how every delivery is planned</span>
              <span className="dm-lb-arrow">↓</span>
            </motion.div>

            {/* STEP 01 — Generate Routes (card anchored LEFT) */}
            <StoryCard step={step} index={0} pos="left" opacity={p1o} y={p1y} x={p1x} scale={p1s} num="01" kicker="Generate Routes" title="We create many delivery plans at once">
              <div className="dm-lb-chips">
                {STRATEGIES.map((s, i) => (
                  <span key={s} className={`dm-lb-chip${i === WINNER_INDEX ? " dm-lb-chip--active" : ""}`}>{s}</span>
                ))}
              </div>
              <p className="dm-lb-pillar__foot">6 different ways to deliver all 59 orders — generated in milliseconds.</p>
            </StoryCard>

            {/* STEP 02 — Check Constraints (card anchored CENTER) */}
            <StoryCard step={step} index={1} pos="center" opacity={p2o} y={p2y} x={p2x} scale={p2s} num="02" kicker="Check Constraints" title="Every plan must respect real-world limits">
              <ul className="dm-lb-constraints">
                {CONSTRAINT_LIST.map((c) => (
                  <li key={c.label}>
                    <span className="dm-lb-constraints__icon">{c.icon}</span>
                    <span className="dm-lb-constraints__label">{c.label}</span>
                    <span className="dm-lb-constraints__note">{c.note}</span>
                  </li>
                ))}
              </ul>
              <p className="dm-lb-pillar__stat"><strong>59/59</strong> delivered <em>vs 34/59 when battery limits are ignored</em></p>
            </StoryCard>

            {/* STEP 03 — Score & Compare (card anchored RIGHT) */}
            <StoryCard step={step} index={2} pos="right" opacity={p3o} y={p3y} x={p3x} scale={p3s} num="03" kicker="Score &amp; Compare" title="Each plan is scored by total delivery cost">
              <ul className="dm-lb-board">
                {STRATEGY_SCORES.map((s) => (
                  <li key={s.name} className={s.win ? "is-win" : ""}>
                    <span className="dm-lb-board__name">{s.name}{s.win && <span className="dm-lb-board__tag">WINNER</span>}</span>
                    <span className="dm-lb-board__track"><span className="dm-lb-board__fill" style={{ width: `${s.score}%` }} /></span>
                    <span className="dm-lb-board__score">{s.score}</span>
                  </li>
                ))}
              </ul>
            </StoryCard>

            {/* STEP 04 — Guarantee On-Time (card anchored LEFT) */}
            <StoryCard step={step} index={3} pos="left" opacity={p4o} y={p4y} x={p4x} scale={p4s} num="04" kicker="Guarantee On-Time" title="Any plan even 1 minute late is rejected">
              <div className="dm-lb-sla">
                <span className="dm-lb-sla__badge">⏱️ On-time only</span>
                <span className="dm-lb-sla__x">✕ Late plan → dropped</span>
              </div>
              <p className="dm-lb-pillar__foot">We only keep plans that hit every promised delivery window.</p>
            </StoryCard>

            {/* STEP 05 — Pick & Dispatch (card anchored CENTER, hero) */}
            <StoryCard step={step} index={4} pos="hero" opacity={p5o} y={p5y} x={p5x} scale={p5s} num="05" kicker="Pick &amp; Dispatch" title="The winning plan is sent to the fleet">
              <div className="dm-lb-winner">✓ Multi-Trip selected — lowest cost, zero delays</div>
              <div className="dm-lb-chips">
                <span className="dm-lb-chip">EV Bikes</span>
                <span className="dm-lb-chip">Autos</span>
                <span className="dm-lb-chip">Cargo Trucks</span>
              </div>
            </StoryCard>

            {/* STEP 06 — Results: KPI cards */}
            <motion.div className="dm-lb-finale" style={{ opacity: finaleOpacity }}>
              <motion.div className="dm-lb-kpis" style={{ y: finaleY }}>
                <div className="dm-lb-kpi">
                  <span className="dm-lb-kpi__num"><Counter mv={orders} />/59</span>
                  <span className="dm-lb-kpi__label">Orders Delivered</span>
                </div>
                <div className="dm-lb-kpi dm-lb-kpi--green">
                  <span className="dm-lb-kpi__num">0</span>
                  <span className="dm-lb-kpi__label">SLA Misses</span>
                </div>
                <div className="dm-lb-kpi">
                  <span className="dm-lb-kpi__num"><Counter mv={cost} />%</span>
                  <span className="dm-lb-kpi__label">Cost Saved</span>
                </div>
              </motion.div>

              <motion.div className="dm-lb-logo" style={{ opacity: taglineOpacity }}>
                <span className="dm-lb-logo__mark" />
                MileTruth
              </motion.div>
            </motion.div>
          </div>
          )}
        </div>
      </div>
      <style>{styles}</style>
    </section>
  );
}

const styles = `
/* Scroll length tuned for pacing: ~77vh per engine step (was 107vh) so the 6
   beats complete in noticeably less scrolling — closer to Workflow 1's cadence
   and with far less perceived empty space between workflows. Beat windows are
   progress-based (0…1), so they stay correctly aligned at any height. */
.dm-lb { position: relative; height: 460vh; background: transparent; }
.dm-lb-sticky { position: absolute; top: 0; left: 0; width: 100%; height: 100vh; overflow: hidden;
  will-change: transform; transform: translateZ(0); backface-visibility: hidden; }
.dm-lb.is-pinned .dm-lb-sticky { position: fixed; top: 0; left: 0; }
.dm-lb.is-after .dm-lb-sticky { position: absolute; top: auto; bottom: 0; }

.dm-lb-card {
  position: absolute !important; inset: 20px !important;
  border-radius: 28px !important; overflow: hidden !important;
  background: radial-gradient(120% 100% at 50% 0%, #12090c 0%, #0a070a 55%, #060507 100%) !important;
  border: 1px solid rgba(192,18,39,0.16) !important;
  box-shadow: 0 30px 90px -30px rgba(0,0,0,0.85), inset 0 1px 0 rgba(255,255,255,0.04) !important;
  box-sizing: border-box !important;
}
@media (max-width: 767px) { .dm-lb-card { inset: 10px !important; border-radius: 20px !important; } }

/* Connected mode (inside Workflow 2): flatten the card's bottom edge and flush it to
   the section's bottom so the Innovation card below butts directly against it, reading
   as one continuous container — mirrors the Optimisation → Performance seam in Workflow 1. */
.dm-lb.is-connected .dm-lb-card {
  top: 20px !important; left: 20px !important; right: 20px !important; bottom: 0 !important;
  border-radius: 28px 28px 0 0 !important; border-bottom: none !important;
  /* Flush against the Innovation card below — drop the heavy downward shadow so it
     doesn't cast a dark band onto that card's top edge (the two read as one container). */
  box-shadow: none !important;
}
@media (max-width: 767px) {
  .dm-lb.is-connected .dm-lb-card {
    top: 10px !important; left: 10px !important; right: 10px !important; bottom: 0 !important;
    border-radius: 20px 20px 0 0 !important;
  }
}

.dm-lb-canvas { position: absolute; inset: 0; z-index: 1; }
.dm-lb-canvas canvas { display: block; }

.dm-lb-ui { position: absolute; inset: 0; z-index: 4; pointer-events: none;
  font-family: var(--font-space-grotesk), var(--font-manrope), system-ui, sans-serif; color: #eaf2ff; }

/* ---- Persistent header: title + 6-step engine rail ----
   Offset the bar below the site's fixed navbar (~104px desktop / ~100px mobile once
   .dm-header-scrolled is active). The section pins full-viewport, so without this the
   eyebrow badge would sit under the navbar (z-index 10000) and get clipped. */
.dm-lb-top { position: absolute; top: clamp(96px, 13vh, 128px); left: 0; right: 0; z-index: 5;
  display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 0 16px; overflow: visible; }
.dm-lb-eyebrow {
  display: inline-flex; align-items: center; gap: 8px; font-size: 13px; line-height: 1.35; letter-spacing: 0.18em; font-weight: 700; text-transform: uppercase;
  color: #ffffff; padding: 9px 20px; border-radius: 999px; background: rgba(192,18,39,0.16);
  border: 1px solid rgba(226,53,66,0.45); backdrop-filter: blur(8px); white-space: nowrap; overflow: visible; }
.dm-lb-dot { width: 6px; height: 6px; border-radius: 50%; background: #E2354A; box-shadow: 0 0 10px #E2354A; }

.dm-lb-rail { display: flex; align-items: center; justify-content: center; flex-wrap: nowrap; max-width: min(1160px, 96vw); }
.dm-lb-rail__step { display: inline-flex; align-items: center; gap: 8px; padding: 6px 13px; border-radius: 999px; flex-shrink: 0;
  background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.08);
  backdrop-filter: blur(6px); transition: all 0.45s cubic-bezier(0.22,1,0.36,1); }
.dm-lb-rail__num { width: 20px; height: 20px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 800; color: rgba(255,255,255,0.9); background: rgba(255,255,255,0.12); }
.dm-lb-rail__title { font-size: clamp(12.5px, 1.05vw, 14px); font-weight: 700; letter-spacing: 0.04em; color: rgba(255,255,255,0.95); white-space: nowrap; }
.dm-lb-rail__step.is-current { background: rgba(192,18,39,0.18); border-color: rgba(226,53,66,0.55); box-shadow: 0 0 22px -6px rgba(226,53,66,0.7); }
.dm-lb-rail__step.is-current .dm-lb-rail__num { background: linear-gradient(135deg,#E2354A,#C01227); color: #fff; }
.dm-lb-rail__step.is-current .dm-lb-rail__title { color: #fff; }
.dm-lb-rail__step.is-done .dm-lb-rail__num { background: #22C55E; color: #04130a; }
.dm-lb-rail__step.is-done .dm-lb-rail__title { color: rgba(255,255,255,0.92); }
.dm-lb-rail__line { width: 14px; height: 1px; background: rgba(255,255,255,0.12); margin: 0 3px; transition: background 0.45s ease; }
.dm-lb-rail__line.is-on { background: linear-gradient(90deg,#22C55E,#E2354A); }

.dm-lb-scrollhint { position: absolute; bottom: clamp(26px, 6vh, 60px); left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px; font-size: 12px; letter-spacing: 0.12em;
  color: rgba(240,228,230,0.72); text-transform: uppercase; text-align: center; }
.dm-lb-arrow { font-size: 18px; animation: dmLbBob 1.8s ease-in-out infinite; }
@keyframes dmLbBob { 0%,100% { transform: translateY(0); opacity: 0.5; } 50% { transform: translateY(6px); opacity: 1; } }

/* ---- Story card: a premium light-glass panel that TRAVELS between stage
   anchors. The anchor pins the stage position; the inner card slides/scales into
   it (Left → Center → Right → Left → Center-Hero) in lockstep with scroll. ---- */
.dm-lb-card-anchor { position: absolute; bottom: clamp(26px, 7vh, 64px); z-index: 6; pointer-events: none; }
.dm-lb-card-anchor.is-left { left: clamp(18px, 4vw, 56px); }
.dm-lb-card-anchor.is-right { right: clamp(18px, 4vw, 56px); }
.dm-lb-card-anchor.is-center,
.dm-lb-card-anchor.is-hero { left: 50%; transform: translateX(-50%); }
/* Hero (final selection) sits a little higher + centred so it reads as the payoff. */
.dm-lb-card-anchor.is-hero { bottom: clamp(40px, 9vh, 92px); }

.dm-lb-card-story { position: relative; width: min(440px, 84vw); pointer-events: auto;
  will-change: opacity, transform; transform-origin: bottom center;
  padding: 18px 20px; border-radius: 18px;
  /* Premium light glass — clean SaaS surface, brand red used only as a top accent. */
  background: rgba(255,255,255,0.94);
  border: 1px solid rgba(15,23,42,0.08); border-top: 3px solid #C01227;
  box-shadow: 0 28px 70px -34px rgba(15,23,42,0.45); }
.dm-lb-card-anchor.is-hero .dm-lb-card-story { width: min(480px, 88vw);
  box-shadow: 0 38px 92px -34px rgba(192,18,39,0.4); }
.dm-lb-card-story__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.dm-lb-pillar__num { font-size: 12px; font-weight: 700; letter-spacing: 0.1em; color: #ffffff;
  background: linear-gradient(135deg, #E2354A, #C01227); border-radius: 7px; padding: 3px 8px; }
.dm-lb-pillar__kicker { font-size: clamp(11px, 1.1vw, 13px); font-weight: 700; letter-spacing: 0.18em;
  text-transform: uppercase; color: #C01227; }
.dm-lb .dm-lb-pillar__title { margin: 0 0 12px !important; padding: 0 !important; color: #0f172a !important;
  font-weight: 700 !important; text-transform: none !important; letter-spacing: -0.015em !important;
  font-size: clamp(17px, 1.9vw, 24px) !important; line-height: 1.18 !important; }
.dm-lb-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 10px; }
/* Strategy pills — white pills, soft border + light shadow, brand-red active state. */
.dm-lb-chip { font-size: 11.5px; font-weight: 600; letter-spacing: 0.02em; color: #334155;
  padding: 5px 12px; border-radius: 999px; background: #ffffff;
  border: 1px solid rgba(15,23,42,0.1); box-shadow: 0 1px 2px rgba(15,23,42,0.06); white-space: nowrap; }
.dm-lb-chip--active { color: #ffffff; background: linear-gradient(135deg, #E2354A, #C01227);
  border-color: transparent; box-shadow: 0 6px 16px -6px rgba(192,18,39,0.5); }
.dm-lb-pillar__foot { margin: 0; font-size: clamp(12px, 1.1vw, 13.5px); line-height: 1.45; color: #475569; }
.dm-lb-pillar__stat { margin: 6px 0 0; font-size: clamp(12.5px, 1.2vw, 15px); color: #475569; }
.dm-lb-pillar__stat strong { color: #16a34a; font-weight: 800; font-size: 1.25em; }
.dm-lb-pillar__stat em { font-style: normal; color: #94a3b8; }

/* Constraints checklist (step 02) */
.dm-lb-constraints { list-style: none; margin: 0 0 10px; padding: 0; display: grid; gap: 7px; }
.dm-lb-constraints li { display: flex; align-items: center; gap: 9px; }
.dm-lb-constraints__icon { font-size: 14px; width: 20px; text-align: center; }
.dm-lb-constraints__label { font-size: 13px; font-weight: 700; color: #0f172a; min-width: 84px; }
.dm-lb-constraints__note { font-size: 12px; color: #64748b; }

/* Scored leaderboard (step 03) */
.dm-lb-board { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.dm-lb-board li { display: grid; grid-template-columns: 104px 1fr 26px; align-items: center; gap: 9px; }
.dm-lb-board__name { font-size: 11.5px; font-weight: 600; color: #64748b; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.dm-lb-board li.is-win .dm-lb-board__name { color: #0f172a; font-weight: 800; }
.dm-lb-board__tag { font-size: 8px; font-weight: 800; letter-spacing: 0.08em; color: #fff;
  background: linear-gradient(135deg,#E2354A,#C01227); padding: 2px 5px; border-radius: 5px; }
.dm-lb-board__track { height: 7px; border-radius: 999px; background: rgba(15,23,42,0.08); overflow: hidden; }
.dm-lb-board__fill { display: block; height: 100%; border-radius: 999px; background: rgba(100,116,139,0.45); }
.dm-lb-board li.is-win .dm-lb-board__fill { background: linear-gradient(90deg,#E2354A,#C01227); box-shadow: 0 0 12px rgba(226,53,66,0.4); }
.dm-lb-board__score { font-size: 12px; font-weight: 700; color: #64748b; text-align: right; }
.dm-lb-board li.is-win .dm-lb-board__score { color: #0f172a; }

/* SLA badges (step 04) */
.dm-lb-sla { display: flex; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.dm-lb-sla__badge { font-size: 12px; font-weight: 700; color: #15803d; background: rgba(34,197,94,0.1);
  border: 1px solid rgba(34,197,94,0.3); padding: 6px 12px; border-radius: 999px; }
.dm-lb-sla__x { font-size: 12px; font-weight: 700; color: #b91c1c; background: rgba(239,68,68,0.08);
  border: 1px solid rgba(239,68,68,0.28); padding: 6px 12px; border-radius: 999px; }

/* Winner banner (step 05) */
.dm-lb-winner { font-size: 13.5px; font-weight: 700; color: #0f172a; margin-bottom: 10px; padding: 9px 13px; border-radius: 12px;
  background: linear-gradient(135deg, rgba(192,18,39,0.08), rgba(34,197,94,0.08)); border: 1px solid rgba(226,53,66,0.32); }

/* ---- Finale: KPI cards ---- */
.dm-lb-finale { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 0 20px; }
.dm-lb-kpis { display: flex; gap: clamp(14px, 2.4vw, 28px); margin-bottom: clamp(28px, 6vh, 56px); flex-wrap: wrap; justify-content: center; }
.dm-lb-kpi { display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: clamp(150px, 18vw, 210px);
  padding: 22px 26px; border-radius: 18px; background: rgba(16,9,11,0.9); border: 1px solid rgba(226,53,66,0.28);
  box-shadow: 0 24px 60px -28px rgba(0,0,0,0.9); }
.dm-lb-kpi--green { border-color: rgba(34,197,94,0.4); }
.dm-lb-kpi__num { font-size: clamp(38px, 5.5vw, 72px); font-weight: 800; line-height: 1; letter-spacing: -0.03em;
  color: #fff; text-shadow: 0 0 32px rgba(226,53,66,0.55), 0 0 12px rgba(192,18,39,0.5); }
.dm-lb-kpi--green .dm-lb-kpi__num { color: #4ade80; text-shadow: 0 0 32px rgba(34,197,94,0.6); }
.dm-lb-kpi__label { font-size: clamp(10px, 1.1vw, 13px); letter-spacing: 0.14em; text-transform: uppercase; color: rgba(232,222,224,0.62); }

.dm-lb-logo { display: inline-flex; align-items: center; gap: 12px; font-size: clamp(22px, 3vw, 40px); font-weight: 800;
  letter-spacing: -0.01em; color: #fff; margin-bottom: 18px; text-shadow: 0 0 30px rgba(192,18,39,0.55); }
.dm-lb-logo__mark { width: clamp(20px, 2.4vw, 30px); height: clamp(20px, 2.4vw, 30px); border-radius: 8px;
  background: conic-gradient(from 140deg, #E2354A, #C01227, #8A0E1F, #C8102E, #E2354A);
  box-shadow: 0 0 28px rgba(192,18,39,0.75); }

/* Hide the step titles on narrower screens so the rail stays a single tidy row of numbers. */
@media (max-width: 1000px) {
  .dm-lb-rail__title { display: none; }
  .dm-lb-rail__step { padding: 5px 7px; }
  .dm-lb-rail__line { width: 9px; }
}
@media (max-width: 767px) {
  .dm-lb { height: 400vh; }
  .dm-lb-kpis { gap: 12px; }
  .dm-lb-kpi { min-width: 96px; padding: 14px 14px; }
  /* On phones every stage collapses to one centred, full-width position — the
     horizontal travel only reads on wider screens. */
  .dm-lb-card-anchor,
  .dm-lb-card-anchor.is-left,
  .dm-lb-card-anchor.is-right,
  .dm-lb-card-anchor.is-center,
  .dm-lb-card-anchor.is-hero { left: 50%; right: auto; transform: translateX(-50%); bottom: clamp(20px, 5vh, 44px); }
  .dm-lb-card-story,
  .dm-lb-card-anchor.is-hero .dm-lb-card-story { width: calc(100vw - 28px); padding: 14px 16px; }
  .dm-lb-board li { grid-template-columns: 88px 1fr 24px; }
  .dm-lb-constraints__note { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .dm-lb-arrow { animation: none !important; }
}
`;
