/* ==========================================================================
   Teams.jsx  —  @role
   Teams page. Sections: hero, credibility, why-now (macro-chart.js), recognition (tilting coin-rings), support (teams-domains.js), what-becomes-possible (teams-possible.js), engagement models (teams-engagements.js), contact. Tech niche named here only.
   ========================================================================== */
/* PSL Teams Page — desktop mockup
   Class reuse: .m-nav, .m-footer, .m-cta, .m-btn-* from method.css.
   Brand-consistent palette (navy/blue/turquoise, Mona Sans).
   Immersive UX: dark-navy hero, count-up stats, logo marquee, scroll rail,
   animated timeline spine, mouse-tilt domain cards, arc-gauge horizons. */

const { useState, useEffect, useRef, useCallback } = React;

const useInView = (rootMargin = "-10% 0px -10% 0px") => {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    if (!ref.current || seen) return;
    const io = new IntersectionObserver(
      (entries) => entries.forEach((e) => {
        if (e.isIntersecting) {setSeen(true);io.disconnect();}
      }),
      { rootMargin, threshold: 0.05 }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, [rootMargin, seen]);
  return [ref, seen];
};

const useCountUp = (target, seen, duration = 1500) => {
  const [val, setVal] = useState(0);
  useEffect(() => {
    if (!seen) return;
    let raf, start;
    const ease = (t) => 1 - Math.pow(1 - t, 3);
    const step = (ts) => {
      if (!start) start = ts;
      const p = Math.min(1, (ts - start) / duration);
      setVal(Math.round(target * ease(p)));
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [target, seen, duration]);
  return val;
};

/* ---------- Scroll progress rail ---------- */
const T_Rail = ({ sections }) => {
  const [active, setActive] = useState(0);
  const [darkSection, setDarkSection] = useState(true);
  useEffect(() => {
    const onScroll = () => {
      const mid = window.scrollY + window.innerHeight * 0.4;
      let cur = 0;
      let isDark = false;
      sections.forEach((s, i) => {
        const el = document.getElementById(s.id);
        if (!el) return;
        if (el.offsetTop <= mid) {
          cur = i;
          isDark = !!s.dark;
        }
      });
      setActive(cur);
      setDarkSection(isDark);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, [sections]);
  return (
    <nav className="t-rail" aria-label="Page sections">
      {sections.map((s, i) =>
      <button
        key={s.id}
        type="button"
        className={"t-rail-dot" + (darkSection ? " is-dark" : "") + (active === i ? " active" : "")}
        aria-label={"Jump to " + s.label}
        onClick={() => {
          const el = document.getElementById(s.id);
          if (el) window.scrollTo({ top: el.offsetTop - 40, behavior: "smooth" });
        }}>

          <span className="t-rail-label">{s.label}</span>
        </button>
      )}
    </nav>);

};

/* ---------- Sticky section banner (Method-style .m-snav) ---------- */
const T_jumpTo = (id) => {
  const el = document.getElementById(id);
  if (!el) return;
  const y = el.getBoundingClientRect().top + window.scrollY - 84;
  window.scrollTo({ top: y, behavior: "smooth" });
};
const T_SNav = ({ sections }) => {
  const [active, setActive] = useState(-1);
  useEffect(() => {
    const onScroll = () => {
      const triggerY = 140;
      let current = -1;
      sections.forEach((sec, i) => {
        const el = document.getElementById(sec.id);
        if (el && el.getBoundingClientRect().top <= triggerY) current = i;
      });
      // hide once the hero is still on screen (before first section)
      const first = document.getElementById(sections[0].id);
      if (first && first.getBoundingClientRect().top > triggerY) current = -1;
      setActive(current);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, [sections]);

  return (
    <nav className={"t-snav" + (active >= 0 ? " is-on" : "")} aria-label="On this page">
      <div className="t-snav-inner">
        <span className="t-snav-eyebrow">For teams</span>
        <ol className="t-snav-list">
          {sections.map((sec, i) =>
          <li key={sec.id}>
              <button
                className={"t-snav-link" + (i === active ? " is-current" : "")}
                onClick={() => T_jumpTo(sec.id)}
                aria-current={i === active ? "true" : undefined}>
                <span className="t-snav-num">{String(i + 1).padStart(2, "0")}</span>
                {sec.label}
              </button>
            </li>
          )}
        </ol>
      </div>
    </nav>);

};

/* ---------- Nav (uses negative logo over dark hero) ---------- */
const T_Nav = () => {
  const links = [
  { id: "home", label: "Home" },
  { id: "method", label: "Method" },
  { id: "teams", label: "Teams" },
  { id: "individuals", label: "Individuals" }];

  return (
    <nav className="m-nav" style={{ background: "transparent", borderBottom: "1px solid rgba(255,255,255,0.12)", position: "absolute", top: 0, left: 0, right: 0, zIndex: 10 }}>
      <div className="m-container m-nav-inner">
        <a href="#" className="m-nav-logo" aria-label="Performance Systems Lab home">
          <img src="assets/logos/PSL-Logo-Negative.png" alt="Performance Systems Lab" />
        </a>
        <div className="m-nav-links">
          {links.map((l) =>
          <a key={l.id} href="#" className={"m-nav-link" + (l.id === "teams" ? " active" : "")}
          style={{ color: l.id === "teams" ? "var(--m-turquoise)" : "rgba(255,255,255,0.78)" }}>
              {l.label}
            </a>
          )}
          <a href="#" className="m-nav-cta">Diagnostic</a>
        </div>
      </div>
    </nav>);

};

/* =====================================================================
   01 — HERO (dark navy)
   ===================================================================== */
const T_Hero = () => {
  const [ref, seen] = useInView("0px");
  return (
    <section id="hero" className={"t-hero" + (seen ? " is-in" : "")} ref={ref}>
      <div className="t-hero-bg" aria-hidden>
        <span className="t-bloom t-bloom-1" />
        <span className="t-bloom t-bloom-2" />
        <span className="t-bloom t-bloom-3" />
        <div className="t-hero-grid" />
      </div>
      <div className="m-container">
        <span className="t-hero-eyebrow">Performance Advisory for Leadership Teams</span>
        <h1 className="t-hero-h">
          Teams that perform under pressure aren't working harder.{" "}
          <span className="t-hero-h-mark">They're built differently.</span>
        </h1>
        <p className="t-hero-sub">
          The cause is rarely motivation — it's structural. PSL redesigns the conditions behind consistent delivery — governance, operating rhythms, and capacity design — becoming the structural counterpart to your leadership team.
        </p>
        <div className="t-hero-cta-row">
          <a href="#" className="m-btn m-btn-primary m-btn-shine">
            <span>Take the Team Diagnostic</span>
            <span className="m-btn-arrow" aria-hidden>→</span>
          </a>
          <a href="#contact" className="m-btn m-btn-secondary">
            <span>Discuss an engagement →</span>
          </a>
        </div>
        <p className="t-hero-supporting">
          Free · ~7 min · completed by one senior leader on the team's behalf, with a full team-by-member assessment to follow. Built for technology, engineering, and digital transformation leaders.
        </p>
        <div className="t-hero-trust">
          <span className="t-hero-trust-label">Designed alongside leadership at</span>
          <div className="t-hero-trust-logos" aria-label="Client organisations">
            <img className="t-logo-hsbc" src="assets/logos/clients/hsbc.png" alt="HSBC" />
            <img className="t-logo-vodafone" src="assets/logos/clients/vodafone.png" alt="Vodafone" />
            <img className="t-logo-santander" src="assets/logos/clients/santander.png" alt="Santander" />
            <img className="t-logo-claranet" src="assets/logos/clients/claranet.png" alt="Claranet" />
            <img className="t-logo-callsign" src="assets/logos/clients/callsign.png" alt="Callsign" />
          </div>
        </div>
      </div>
    </section>);
};

/* =====================================================================
   02 — CREDIBILITY (count-up + marquee)
   ===================================================================== */
const StatNum = ({ value, suffix, seen }) => {
  const n = useCountUp(value, seen);
  return (
    <span className="t-stat-num">
      <span>{n}</span>
      {suffix && <span className="t-stat-num-suffix">{suffix}</span>}
    </span>);

};

/* =====================================================================
   01b — WHY NOW (macro context: AI + digital transformation)
   Names the audience explicitly and sets up Recognition.
   ===================================================================== */
const CountText = ({ target, seen }) => {
  const [txt, setTxt] = React.useState(target);
  React.useEffect(() => {
    if (!seen) { setTxt(target); return; }
    const parts = String(target).match(/(\d+|\D+)/g) || [];
    const targets = parts.map((p) => /^\d+$/.test(p) ? parseInt(p, 10) : null);
    const dur = 1100, t0 = performance.now();
    let raf;
    const tick = (t) => {
      const p = Math.min((t - t0) / dur, 1);
      const e = 1 - Math.pow(1 - p, 3);
      setTxt(parts.map((seg, i) => targets[i] == null ? seg : String(Math.round(e * targets[i]))).join(""));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [seen, target]);
  return <>{txt}</>;
};

const T_WhyNow = () => {
  const [ref, seen] = useInView();
  const chartRef = React.useRef(null);
  React.useEffect(() => {
    if (window.__pslMacro && chartRef.current && !chartRef.current.dataset.rendered) {
      chartRef.current.dataset.rendered = "1";
      window.__pslMacro.render(chartRef.current);
    }
  }, []);
  const signals = [
    { stat: "60%+", label: "of digital transformation programmes underdeliver against original goals — the operating model lags the strategy." },
    { stat: "2–3×", label: "the cadence of change since AI adoption began. Most team operating models were built for the old pace." },
    { stat: "1 in 3", label: "senior delivery leaders report that performance issues now appear faster than their governance can respond." },
  ];
  return (
    <section id="why-now" ref={ref} className={"m-section t-whynow" + (seen ? " is-in" : "")} data-screen-label="Why Now">
      <div className="m-container">
        <div className="t-whynow-grid">
        <div className="t-whynow-narrative">
            <span className="m-overline t-anim-fadeup t-d0">The macro context</span>
            <h2 className="m-h2 t-anim-fadeup t-d1">
              Technology is changing the pace. Most team <span className="m-h-accent">operating models haven't caught up.</span>
            </h2>
            <p className="m-section-intro t-anim-fadeup t-d2">
              Technology teams, software engineering organisations, and digital transformation programmes are accelerating faster than the structural conditions beneath them. Since AI adoption began, strategy moves quickly while operating models, governance, and capacity design move slowly. The gap is where performance breaks down.
            </p>
            <p className="t-whynow-body t-anim-fadeup t-d3">
              PSL was built for this moment — for leadership teams running through AI adoption, cloud and platform transformation, regulated change, and complex programme delivery in environments where the pressure is structural, not motivational.
            </p>
          </div>
        <div className="t-macro-mount t-anim-fadeup t-d2" ref={chartRef} aria-label="Pressure gap chart: expected output rises as team size steps down with each wave of AI tools" />
        </div>

        <ul className="t-whynow-stats t-anim-fadeup t-d3">
          {signals.map((s, i) => (
            <li key={i} className="t-whynow-stat">
              <span className="t-whynow-stat-num"><CountText target={s.stat} seen={seen} /></span>
              <span className="t-whynow-stat-label">{s.label}</span>
            </li>
          ))}
        </ul>
      </div>
    </section>);
};

const T_Creds = () => {
  const [ref, seen] = useInView();
  const stats = [
  { value: 10, suffix: "+", eyebrow: "Years", label: "leading complex delivery across regulated, enterprise, and high-pressure environments." },
  { value: 25, suffix: "+", eyebrow: "Organisations", label: "across financial services, global retail, cloud infrastructure, and cybersecurity." },
  { value: 8, suffix: "", eyebrow: "Structural Areas", label: "Three performance domains and five practice areas — the model behind every PSL engagement." }];

  const logos = ["Callsign", "Natura", "Claranet", "Aviva", "Lloyds", "Microsoft Cloud", "Vodafone"];
  const marqueeLogos = [...logos, ...logos];
  return (
    <section id="creds" className={"t-creds" + (seen ? " is-in" : "")} ref={ref}>
      <div className="m-container">
        <div className="t-creds-stats">
          {stats.map((s, i) =>
          <div key={i} className="t-stat">
              <StatNum value={s.value} suffix={s.suffix} seen={seen} />
              <span className="t-stat-eyebrow">{s.eyebrow}</span>
              <p className="t-stat-label">{s.label}</p>
            </div>
          )}
        </div>
      </div>
    </section>);

};

/* =====================================================================
   03 — RECOGNITION (animated timeline)
   ===================================================================== */
const T_RecogRing = ({ domain, num }) => {
  // Small 3D torus matching the "How PSL Supports Teams" rings, one per domain.
  const themes = {
    "Performance Identity": { face0: "#A55CFF", face1: "#7A2BE6", wall0: "#5615CD", wall1: "#3D0F8C", in0: "#5A1FB5", in1: "#8B45F0", id: "id", tilt: -20 },
    "Execution Architecture": { face0: "#3DEFC0", face1: "#0FB388", wall0: "#0E6E55", wall1: "#054032", in0: "#0E8A68", in1: "#1FC79A", id: "arch", tilt: 0 },
    "Sustainable Capacity": { face0: "#6E6EFF", face1: "#3A3AD8", wall0: "#2424A8", wall1: "#10105C", in0: "#2A2AB0", in1: "#5050E0", id: "cap", tilt: 20 }
  };
  const t = themes[domain] || themes["Performance Identity"];
  const fId = "trr-face-" + t.id, wId = "trr-wall-" + t.id, iId = "trr-in-" + t.id;
  return (
    <span className="t-recog-ringwrap" style={{ "--tilt": t.tilt + "deg" }}>
      <svg className="t-recog-ring" viewBox="0 0 48 30" width="50" height="31" aria-hidden focusable="false">
        <defs>
          <linearGradient id={fId} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor={t.face0} />
            <stop offset="1" stopColor={t.face1} />
          </linearGradient>
          <linearGradient id={wId} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor={t.wall0} />
            <stop offset="1" stopColor={t.wall1} />
          </linearGradient>
          <linearGradient id={iId} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0" stopColor={t.in1} />
            <stop offset="1" stopColor={t.in0} />
          </linearGradient>
        </defs>
        <path d="M 4,14 A 20,7.4 0 0 0 44,14 L 44,18.5 A 20,7.4 0 0 1 4,18.5 Z" fill={`url(#${wId})`} />
        <path d="M 4,14 A 20,7.4 0 1 0 44,14 A 20,7.4 0 1 0 4,14 Z M 12.5,14 A 11.5,4.4 0 1 0 35.5,14 A 11.5,4.4 0 1 0 12.5,14 Z" fill={`url(#${fId})`} fillRule="evenodd" />
        <ellipse cx="24" cy="14.3" rx="11.5" ry="4.4" fill={`url(#${iId})`} />
        <path d="M 12.5,14 A 11.5,4.4 0 0 1 35.5,14" fill="none" stroke="rgba(0,0,0,0.14)" strokeWidth="0.9" strokeLinecap="round" />
        <path d="M 12.7,14.6 A 11.5,4.4 0 0 0 35.3,14.6" fill="none" stroke="rgba(255,255,255,0.28)" strokeWidth="0.7" strokeLinecap="round" />
        <ellipse cx="24" cy="12.7" rx="20" ry="7.4" fill="none" stroke="rgba(255,255,255,0.32)" strokeWidth="0.6" />
      </svg>
      <span className="t-recog-ringtip">Ring {num}</span>
    </span>);

};

const T_Recognition = () => {
  const [ref, seen] = useInView();
  const signals = [
  {
    text: "When the pressure is highest, that's exactly when your leadership team starts pulling in different directions.",
    tag: "Performance Identity",
    tagColor: "violet",
  },
  {
    text: "Your team is working hard with clear priorities — but delivery still isn't landing the way it should.",
    tag: "Execution Architecture",
    tagColor: "emerald",
  },
  {
    text: "The pace only holds because a few people keep carrying it — not because the system is built to sustain it.",
    tag: "Sustainable Capacity",
    tagColor: "blue",
  }];


  return (
    <section id="recognition" className={"m-section t-recog" + (seen ? " is-in" : "")} ref={ref}>
      <div className="m-container">
        <span className="m-overline t-anim-fadeup t-d0">Recognition</span>
        <h2 className="m-h2 t-anim-fadeup t-d1">Sound like your team?</h2>
        <p className="m-section-intro t-anim-fadeup t-d2">
          When a team is accelerating faster than the operating model beneath it, these patterns tend to appear — and rarely alone.
        </p>
        <div className="t-recog-table t-anim-fadeup t-d2" role="table">
          <div className="t-recog-thead" role="row">
            <span role="columnheader">The pattern</span>
            <span role="columnheader">Where it traces to</span>
          </div>
          {signals.map((s, i) =>
          <div key={i} className={"t-recog-tr t-recog-row-" + s.tagColor} role="row">
              <p className="t-recog-td-text" role="cell">{s.text}</p>
              <span className="t-recog-td-domain" role="cell">
                <T_RecogRing domain={s.tag} num={i + 1} />
                {s.tag}
              </span>
            </div>
          )}
        </div>
      </div>
    </section>);

};

/* =====================================================================
   04 — DOMAINS (mouse-tilt cards)
   ===================================================================== */
const T_Domain = ({ card, idx }) => {
  const cardRef = useRef(null);
  const onMove = useCallback((e) => {
    const el = cardRef.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    const x = (e.clientX - r.left) / r.width;
    const y = (e.clientY - r.top) / r.height;
    el.style.setProperty("--tilt-x", `${(0.5 - y) * 9}deg`);
    el.style.setProperty("--tilt-y", `${(x - 0.5) * 9}deg`);
    el.style.setProperty("--gleam-x", `${x * 100}%`);
    el.style.setProperty("--gleam-y", `${y * 100}%`);
  }, []);
  const onLeave = useCallback(() => {
    const el = cardRef.current;
    if (!el) return;
    el.style.setProperty("--tilt-x", "0deg");
    el.style.setProperty("--tilt-y", "0deg");
  }, []);
  const theme = ["blue", "teal", "violet"][idx] || "blue";
  // Each card highlights its corresponding ring in the PSL Performance System logo.
  // ring 0 = Performance Identity (outer/violet)
  // ring 1 = Execution Architecture (middle/blue)
  // ring 2 = Sustainable Capacity (inner/emerald)
  const ringLabel = ["Ring 01", "Ring 02", "Ring 03"][idx];
  return (
    <article ref={cardRef} className={`t-domain t-domain-${theme}`} onMouseMove={onMove} onMouseLeave={onLeave}>
      <span className="t-domain-badge" aria-hidden>
        <svg viewBox="0 0 48 48" width="48" height="48" className="t-domain-rings">
          <circle cx="24" cy="24" r="20" fill="none" stroke="currentColor" strokeWidth="1.5" className={"t-domain-ring t-domain-ring-1" + (idx === 0 ? " is-active" : "")} />
          <circle cx="24" cy="24" r="14" fill="none" stroke="currentColor" strokeWidth="1.5" className={"t-domain-ring t-domain-ring-2" + (idx === 1 ? " is-active" : "")} />
          <circle cx="24" cy="24" r="8" fill="none" stroke="currentColor" strokeWidth="1.5" className={"t-domain-ring t-domain-ring-3" + (idx === 2 ? " is-active" : "")} />
        </svg>
      </span>
      <span className="t-domain-num">{ringLabel}</span>
      <span className="t-domain-descriptor">{card.desc}</span>
      <h3 className="t-domain-h">{card.h}</h3>
      <p className="t-domain-body">{card.body}</p>
      <div className="t-domain-fail">
        <span className="t-domain-fail-label">Without it</span>
        <p className="t-domain-fail-body">{card.fail}</p>
      </div>
    </article>);

};

/* =====================================================================
   04.5 — ENGAGEMENT MODELS (replaces "What You Receive")
   Three consultative paths leadership can engage with PSL.
   No pricing — bespoke proposals for Deep Dive + Advisory.
   ===================================================================== */
const T_Engagements = () => {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (window.__pslEngagements && ref.current && !ref.current.dataset.rendered) {
      ref.current.dataset.rendered = "1";
      window.__pslEngagements.render(ref.current);
    }
  }, []);
  return (
    <section
      id="engagements"
      className="m-section t-engagements-v2"
      data-screen-label="Engagement Models"
    >
      <div className="m-container">
        <div ref={ref} />
      </div>
    </section>);
};


/* =====================================================================
   03b — WHERE THE SYSTEM COMES FROM (sport + research + delivery)
   Reuses Method page's .m-origins-* visual language: three image cards
   with tag chip, headline, body, and "Maps to" footer. Teams variant
   refocuses copy on tech/digital teams.
   ===================================================================== */
const T_Lineage = () => {
  const [ref, seen] = useInView();
  const tiles = [
    {
      img: "assets/method/rugby-lg.jpg",
      tag: "Elite-sport principles",
      h: "Rugby — the lineout.",
      body: "Coordinated execution under contested pressure. Roles defined, lift timed, decision made the moment the ball is released. The structure is rehearsed; the outcome is held when conditions go non-linear.",
      lesson: "Performance Identity · Execution Architecture",
    },
    {
      img: "assets/method/boxing-lg.jpg",
      tag: "Periodisation & load",
      h: "Boxing — the round.",
      body: "Twelve cycles of intensity engineered around recovery, pace, and adaptive readiness. Champions are built in how the load is structured between rounds, not in the punches themselves.",
      lesson: "Sustainable Capacity",
    },
    {
      img: "assets/method/corporate-lg.jpg",
      tag: "A decade of complex delivery",
      h: "The team that has to deliver.",
      body: "The same principles, translated for technology, software engineering, and digital transformation teams. Sustained pressure. Contested priorities. Decisions made on incomplete information against unforgiving timelines.",
      lesson: "All three domains, applied",
    },
  ];
  return (
    <section id="lineage" ref={ref} className={"m-section m-origins m-origins-v5" + (seen ? " is-in" : "")} data-screen-label="Where the System Comes From">
      <div className="m-container">
        <span className="m-overline">Where the system comes from</span>
        <h2 className="m-h2">
          The discipline is borrowed from environments where pressure is the design constraint.
        </h2>
        <p className="m-section-intro">
          Elite sport has spent a century refining how human performance behaves under sustained, contested pressure. The same structural logic — identity, architecture, capacity — translates directly into the technology teams now navigating the same conditions through AI adoption and digital transformation. PSL is the bridge between the two.
        </p>
        <ul className="m-origins-grid">
          {tiles.map((t, i) => (
            <li key={i} className="m-origin" style={{ "--m-i": i }}>
              <div className="m-origin-frame">
                <img src={t.img} alt={t.h} loading="lazy" />
                <span className="m-origin-tag">{t.tag}</span>
              </div>
              <h3 className="m-origin-h">{t.h}</h3>
              <p className="m-origin-body">{t.body}</p>
              <div className="m-origin-foot">
                <span className="m-origin-foot-label">Maps to</span>
                <span className="m-origin-foot-value">{t.lesson}</span>
              </div>
            </li>
          ))}
        </ul>
        <a href="#" className="t-lineage-method-link">
          See the full Method
          <svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
            <path d="M3 8h10M9 4l4 4-4 4" />
          </svg>
        </a>
      </div>
    </section>);
};

const T_Support = () => {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (window.__pslTeamsDomains && ref.current && !ref.current.dataset.rendered) {
      ref.current.dataset.rendered = "1";
      window.__pslTeamsDomains.render(ref.current);
    }
  }, []);
  return (
    <section id="support" className="m-section t-support-v2" ref={ref} data-screen-label="How PSL Supports Teams">
      <div />
    </section>);

};

/* =====================================================================
   05 — WHAT CHANGES (arc gauges)
   ===================================================================== */
const Horizon = ({ h, idx, seen }) => {
  const pct = useCountUp(h.pct, seen, 1800);
  return (
    <article className="t-horizon">
      <div className="t-horizon-meta">
        <span className="t-horizon-window">{h.window}</span>
        <span className="t-horizon-num">HORIZON 0{idx + 1}</span>
      </div>
      <div className="t-horizon-arc">
        <svg className="t-arc-svg" viewBox="0 0 120 120">
          <defs>
            <linearGradient id="t-arc-grad" x1="0" y1="0" x2="1" y2="1">
              <stop offset="0%" stopColor="#4644B9" />
              <stop offset="100%" stopColor="#19E6C4" />
            </linearGradient>
          </defs>
          <circle className="t-arc-track" cx="60" cy="60" r="50" fill="none" strokeWidth="6" />
          <circle className="t-arc-fill" cx="60" cy="60" r="50" fill="none" strokeWidth="6" strokeLinecap="round" />
        </svg>
        <div className="t-arc-label">
          <span className="t-arc-pct">{pct}%</span>
          <span className="t-arc-cap">{h.pctLabel}</span>
        </div>
      </div>
      <h3 className="t-horizon-h">{h.h}</h3>
      <p className="t-horizon-body">{h.body}</p>
      <ul className="t-horizon-tags">
        {h.tags.map((t) => <li key={t}>{t}</li>)}
      </ul>
    </article>);

};

const T_WhatChanges = () => {
  const ref = React.useRef(null);
  const mountRef = React.useRef(null);
  React.useEffect(() => {
    if (window.__pslWhatPossible && mountRef.current && !mountRef.current.dataset.rendered) {
      mountRef.current.dataset.rendered = "1";
      window.__pslWhatPossible.render(mountRef.current);
    }
  }, []);

  return (
    <section id="changes" className="m-section t-changes-v2" ref={ref} data-screen-label="What Becomes Possible">
      <div className="m-container">
        <div ref={mountRef} />
      </div>
    </section>);
};

/* =====================================================================
   05b — HOW THE ENGAGEMENT WORKS (journey progression)
   Mirrors the Method page's "From Diagnosis to Ongoing Advisory" section.
   Reuses .m-journey-* styles from method.css for visual consistency.
   ===================================================================== */
const T_Process = () => {
  const [ref, seen] = useInView();
  const stops = [
    {
      window: "Pre-engagement",
      label: "Diagnostic",
      body: "Every engagement begins with a Team Diagnostic scored across the three domains. Evidence replaces assumption — leadership knows where the structural constraint actually sits.",
      barFill: 0.05,
      tags: [],
    },
    {
      window: "Weeks 1 – 4",
      label: "Insight Session",
      body: "PSL leadership walks you through the readout, the named constraint, and the structural fix. Diagnostic data becomes a board-ready interpretation.",
      barFill: 0.25,
      tags: [],
    },
    {
      window: "Within 90 days",
      label: "Embedded Design",
      body: "Targeted interventions across the relevant practice areas — operating rhythms, decision rituals, workshops, training, or governance redesign as scoped. Delivery becomes more predictable, heroics decrease, and forecasts tighten.",
      barFill: 0.6,
      tags: ["Predictable delivery", "Fewer heroics", "Tight forecast band"],
    },
    {
      window: "6 – 12 months",
      label: "Ongoing Advisory",
      body: "Quarterly Performance System Reviews provide structural oversight. Sustainable Capacity work shows its returns — cycles become resilient, engagement holds through pressure, and the team becomes structurally difficult to break.",
      barFill: 1,
      tags: ["Cycle resilience", "Engagement holds", "Difficult to break"],
    },
  ];

  return (
    <section id="process" ref={ref} className={"m-section m-journey m-journey-v5" + (seen ? " is-in" : "")} data-screen-label="How the engagement works">
      <div className="m-container">
        <span className="m-overline">From Diagnostic to Ongoing Advisory</span>
        <h2 className="m-h2">
          A structured progression — and the pattern of change it produces.
        </h2>
        <p className="m-section-intro">
          Engagements move through four stages. The first two replace assumption with evidence. The second two are where the pattern of change becomes visible — first in delivery, then in capacity.
        </p>

        <div className="m-journey-track" aria-hidden>
          <span className="m-journey-track-line" />
        </div>
        <ol className="m-journey-grid">
          {stops.map((s, i) => (
            <li key={i} className="m-journey-stop" style={{ "--m-i": i }}>
              <div className="m-journey-dot" aria-hidden />
              <div className="m-journey-num">{String(i + 1).padStart(2, "0")}</div>
              <span className="m-journey-window">{s.window}</span>
              <h3 className="m-journey-label">{s.label}</h3>
              <div className="m-journey-bar" aria-hidden>
                <span className="m-journey-bar-fill" style={{ "--fill": s.barFill }} />
              </div>
              <p className="m-journey-body">{s.body}</p>
              {s.tags.length > 0 && (
                <ul className="m-journey-tags">
                  {s.tags.map((t, j) => <li key={j}>{t}</li>)}
                </ul>
              )}
            </li>
          ))}
        </ol>
      </div>
    </section>);
};

/* =====================================================================
   06 — CONTACT (replaces closing CTA)
   Quote + contact form + diagnostic fallback.
   ===================================================================== */
const T_Contact = () => {
  const [ref, seen] = useInView();
  return (
    <section id="contact" ref={ref} className={"m-section t-contact" + (seen ? " is-in" : "")} data-screen-label="Talk to PSL">
      <div className="m-cta-bg" aria-hidden>
        <span className="m-bloom m-bloom-cta-1" />
        <span className="m-bloom m-bloom-cta-2" />
      </div>
      <div className="m-container t-contact-grid">
        <div className="t-contact-narrative">
          <span className="m-overline">Talk to PSL</span>
          <h2 className="m-cta-h">A short conversation about where your team is, and what structural change would move it most.</h2>
          <blockquote className="t-contact-quote">
            <p>"Some of the most valuable conversations we've had on leadership performance in years. PSL came in with structure, not a sales pitch."</p>
            <span>— Programme director, regulated delivery</span>
          </blockquote>
          <div className="t-contact-fallback">
            <span className="t-contact-fallback-label">Not ready to talk?</span>
            <a href="#" className="t-contact-fallback-link">
              Take the free Team Diagnostic
              <svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
                <path d="M3 8h10M9 4l4 4-4 4" />
              </svg>
            </a>
          </div>
        </div>

        <form className="t-contact-form" onSubmit={(e) => { e.preventDefault(); }} aria-label="Contact PSL">
          <label className="t-contact-field t-contact-field-name">
            <span>Your name</span>
            <span className="t-input-wrap">
              <input type="text" placeholder=" " autoComplete="name" />
              <span className="t-type-caret" aria-hidden />
            </span>
          </label>
          <label className="t-contact-field">
            <span>Organisation</span>
            <input type="text" placeholder="HSBC · Lloyds · Cybersecurity firm…" autoComplete="organization" />
          </label>
          <label className="t-contact-field">
            <span>Work email</span>
            <input type="email" placeholder="leader@company.com" autoComplete="email" />
          </label>
          <label className="t-contact-field">
            <span>What would you like to discuss?</span>
            <span className="t-select-wrap">
              <select className="t-contact-select" defaultValue="">
                <option value="" disabled>Select a focus…</option>
                <option>Team Performance Diagnostic</option>
                <option>Deep Dive Engagement</option>
                <option>Advisory Partnership</option>
                <option>Workshop with an elite-performance guest speaker</option>
                <option>Not sure yet — a general conversation</option>
              </select>
              <svg className="t-select-chevron" viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden>
                <path d="M4 6l4 4 4-4" />
              </svg>
            </span>
          </label>
          <label className="t-contact-field t-contact-field-area">
            <span>Anything you'd like us to know? <em>(optional)</em></span>
            <textarea rows="3" placeholder="Where the pressure is showing up, what you've already tried…" />
          </label>
          <button type="submit" className="m-btn m-btn-primary m-btn-shine t-contact-submit">
            <span>Request a conversation</span>
            <span className="m-btn-arrow" aria-hidden>→</span>
          </button>
          <p className="t-contact-fineprint">No obligation. PSL responds personally within 2 working days.</p>
        </form>
      </div>
    </section>);
};


/* ---------- CONTEXTS — image strip (moved from Individuals) ---------- */
const T_Contexts = () => {
  const tiles = [
  {
    img: "assets/individuals/trading-floor-md.jpg",
    tag: "On the floor",
    h: "When the pace doesn't relent, structure is the only thing that scales."
  },
  {
    img: "assets/individuals/whiteboard-md.jpg",
    tag: "In the room",
    h: "When alignment matters, the standard you hold becomes the standard the room holds."
  },
  {
    img: "assets/individuals/late-night-md.jpg",
    tag: "After hours",
    h: "When effort is no longer the differentiator, recovery becomes the work."
  }];

  return (
    <section id="contexts" className="t-strip" data-screen-label="Contexts">
      <div className="m-container">
        <div className="t-strip-head">
          <span className="m-overline t-anim-fadeup t-d0">Where this shows up</span>
          <h2 className="m-h2 t-anim-fadeup t-d1">
            The conditions that test the system are everywhere. The system is what holds.
          </h2>
        </div>
        <div className="t-strip-grid">
          {tiles.map((t, i) =>
          <article key={i} className="t-tile t-anim-fadeup" style={{ transitionDelay: `${i * 0.08}s` }}>
              <img src={t.img} alt={t.tag} loading="lazy" />
              <div className="t-tile-caption">
                <div className="t-tile-tag">{t.tag}</div>
                <div className="t-tile-h">{t.h}</div>
              </div>
            </article>
          )}
        </div>
      </div>
    </section>);

};

/* ---------- Footer (reuse) ---------- */
const T_Footer = () =>
<footer className="m-footer">
    <div className="m-container">
      <div className="m-footer-top">
        <div className="m-footer-brand">
          <img src="assets/logos/PSL-Logo-Negative.png" alt="Performance Systems Lab" className="m-footer-logo" />
          <p className="m-footer-tag">
            PSL helps leaders, teams, and organisations design the structural conditions that allow consistent execution when pressure is sustained.
          </p>
        </div>
        <nav className="m-footer-nav" aria-label="Footer">
          <a href="#">Home</a>
          <a href="#">Method</a>
          <a href="#">Teams</a>
          <a href="#">Individuals</a>
          <a href="#">About</a>
        </nav>
      </div>
      <div className="m-footer-bottom">
        <span>© 2026 Performance Systems Lab™. All rights reserved.</span>
        <div className="m-footer-legal">
          <a href="#">Terms</a>
          <a href="#">Privacy</a>
        </div>
      </div>
    </div>
  </footer>;


const Teams = () => {
  const sections = [
  { id: "hero", label: "Opening", dark: true },
  { id: "why-now", label: "Why Now", dark: false },
  { id: "recognition", label: "Recognition", dark: false },
  { id: "support", label: "The Three Domains", dark: false },
  { id: "changes", label: "What Becomes Possible", dark: false },
  { id: "engagements", label: "Engagement Models", dark: false },
  { id: "contact", label: "Talk to PSL", dark: true }];

  const navSections = [
  { id: "why-now", label: "Why now" },
  { id: "recognition", label: "Recognition" },
  { id: "support", label: "The system" },
  { id: "changes", label: "What changes" },
  { id: "engagements", label: "Engagement" },
  { id: "contact", label: "Talk to PSL" }];

  return (
    <div className="psl-method psl-method-v5 psl-teams" data-screen-label="01 PSL Teams Page">
      <PSLNav theme="light" active="teams" overlay />
      <T_SNav sections={navSections} />
      <T_Hero />
      <T_WhyNow />
      <T_Recognition />
      <T_Support />
      <T_WhatChanges />
      <T_Engagements />
      <T_Contact />
      <PSLFooter />
    </div>);

};

Object.assign(window, { Teams });