/* Superscript × Allied Pediatrics — short case study (Foothills format). */

const { useState, useEffect, useRef } = React;

/* ---------- helpers ---------- */
const easeOutCubic = (t) => 1 - Math.pow(1 - t, 3);

function useCountUp(target, { duration = 1500, start = 0, active = true } = {}) {
  const [value, setValue] = useState(active ? start : target);
  useEffect(() => {
    if (!active) return;
    let raf, started;
    const step = (ts) => {
      if (!started) started = ts;
      const t = Math.min(1, (ts - started) / duration);
      setValue(start + (target - start) * easeOutCubic(t));
      if (t < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [target, active, duration, start]);
  return value;
}

function useInView(opts = { threshold: 0.2, once: true }) {
  const ref = useRef(null);
  const [inView, setInView] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const obs = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) { setInView(true); if (opts.once) obs.disconnect(); }
      else if (!opts.once) setInView(false);
    }, { threshold: opts.threshold ?? 0.2 });
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);
  return [ref, inView];
}

function CountStat({ to, from = 0, prefix = "", suffix = "", duration = 1500, decimals = 0 }) {
  const [ref, inView] = useInView();
  const v = useCountUp(to, { start: from, duration, active: inView });
  const display = decimals > 0 ? v.toFixed(decimals) : Math.round(v).toLocaleString();
  return <span ref={ref}>{prefix}{display}{suffix}</span>;
}

function Section({ id, num, title, children }) {
  return (
    <section className="section" id={id}>
      <div className="wrap">
        <div className="sec-head">
          <div className="sec-head__num"><span>{num}</span></div>
          <h2 className="sec-head__title">{title}</h2>
        </div>
        {children}
      </div>
    </section>
  );
}

/* ---------- nav ---------- */
function Nav({ active, onJump }) {
  const items = [["before", "[01] BEFORE"], ["solution", "[02] PRODUCT"], ["results", "[03] RESULTS"]];
  return (
    <nav className="nav">
      <div className="nav__brand">
        <img src="assets/superscript-logo.svg" alt="Superscript" className="nav__logo" />
        <span style={{ color: "var(--ss-grey-3)" }}>/ CASE STUDY</span>
      </div>
      <div className="nav__crumbs">
        {items.map(([id, label]) => (
          <button key={id} className={"nav__crumb " + (active === id ? "is-active" : "")} onClick={() => onJump(id)}>
            <span className="dot"></span><span className="nav__crumb-label">{label}</span>
          </button>
        ))}
      </div>
      <div className="nav__meta">
        <span>CLIENT / <b>ALLIED PEDIATRICS</b></span>
      </div>
    </nav>
  );
}

/* ---------- hero ---------- */
function Hero() {
  return (
    <header className="hero">
      <div className="hero__client">
        <img src="assets/allied.webp" alt="Allied Pediatrics" style={{ height: 40, width: "auto", display: "block" }} />
        <span style={{ marginLeft: "auto" }}>TRI-STATE · PEDIATRICS · 30+ SITES</span>
      </div>

      <h1 className="hero__title">
        Allied Pediatrics more than doubled their upfront collections in one week with Superscript, by <em style={{ color: "var(--ss-blue)" }}>charging at check-in</em>.
      </h1>

      <div className="hero__strip">
        <div className="hero__stat">
          <span className="hero__stat-value"><CountStat to={2.5} suffix="×" decimals={1} duration={1700} /></span>
          <span className="hero__stat-label">UPFRONT YIELD LIFT</span>
          <span className="hero__stat-delta">↗ 22% → 56% · WEEK ONE</span>
        </div>
        <div className="hero__stat">
          <span className="hero__stat-value"><CountStat to={56} suffix="%" duration={1700} /></span>
          <span className="hero__stat-label">COLLECTED UPFRONT</span>
          <span className="hero__stat-delta">WITH SUPERSCRIPT · FROM 22%</span>
        </div>
        <div className="hero__stat">
          <span className="hero__stat-value"><CountStat to={20} prefix="+" suffix="%" duration={1700} /></span>
          <span className="hero__stat-label">DAILY PATIENT PAYMENTS</span>
          <span className="hero__stat-delta">VS FIVE-MONTH BASELINE</span>
        </div>
        <div className="hero__stat">
          <span className="hero__stat-value"><CountStat to={3} duration={1700} /></span>
          <span className="hero__stat-label">PILOT SITES LIVE</span>
          <span className="hero__stat-delta">CHESTER · BELLMORE · GARDEN CITY</span>
        </div>
      </div>
    </header>
  );
}

/* ---------- Skylight product demo (pediatric line items) ---------- */
const SKY_TREATMENTS = [
  { name: "Sick visit · level 3", price: 25.00, explainer: <>Priced using a <span className="sky__tag">$25 copay</span></> },
  { name: "Vaccine administration", price: 18.40, explainer: <>Priced using <span className="sky__tag">20% coinsurance</span> off of a <span className="sky__tag">$92 PNR</span></> },
  { name: "Well-child visit", price: 0.00, explainer: <>Fully covered as <span className="sky__tag">preventive care</span></> }
];

function SkylightDemo() {
  const [visible, setVisible] = useState(0);
  const [ref, inView] = useInView();
  useEffect(() => {
    if (!inView) return;
    setVisible(0);
    let i = 0;
    const interval = setInterval(() => { i++; setVisible(i); if (i >= SKY_TREATMENTS.length) clearInterval(interval); }, 800);
    return () => clearInterval(interval);
  }, [inView]);

  const total = SKY_TREATMENTS.slice(0, visible).reduce((s, it) => s + it.price, 0);
  const totalAnim = useCountUp(total, { duration: 500, active: inView });

  return (
    <div ref={ref} className="sky">
      <div className="sky__head">
        <button className="sky__chip">← Back</button>
        <div className="sky__title">Mia's appointment</div>
        <button className="sky__chip sky__chip--ghost">✕</button>
      </div>

      <div className="sky__card">
        <div className="sky__card-head">Dr. Patel @ 9:15am – 9:30am</div>
        {SKY_TREATMENTS.map((t, i) => (
          <div key={i} className={"sky__row " + (i < visible ? "is-in" : "")}>
            <div className="sky__row-top">
              <div className="sky__row-name"><span className="sky__minus">⊖</span>{t.name}</div>
              <div className="sky__row-price">${t.price.toFixed(2)}</div>
            </div>
            <div className="sky__row-explain">{t.explainer}</div>
          </div>
        ))}
      </div>

      <div className="sky__actions">
        <button className="sky__btn">+ / – Treatments</button>
        <button className="sky__btn">Hide explanations</button>
      </div>

      <div className="sky__total">
        <span className="sky__total-label">Total paid:</span>
        <span className="sky__total-val">${totalAnim.toFixed(2)}</span>
      </div>

      <div className="sky__pay">
        <span className="sky__pay-method">Payment method: <strong>Visa ••• 5687</strong></span>
        <button className="sky__btn sky__btn--outline">↓ Receipt</button>
      </div>
    </div>
  );
}

/* ---------- before / the gap ---------- */
function Before() {
  const [ref, inView] = useInView({ threshold: 0.25, once: true });
  return (
    <Section id="before" num="[01] / BEFORE"
             title={<>Allied collected copays well. They were losing on <em>coinsurance and deductibles</em>.</>}>
      <p className="body muted" style={{ maxWidth: 720, marginBottom: 48 }}>
        Allied is a high-volume pediatric group with over 30 locations and 150 practitioners through NYC, NJ, and Long Island. Even so, their copay collections were already over 90%. The leak was deductible and coinsurance balances, which patients racked up and they were only trying to collect weeks later, long after the visit.
      </p>

      <div ref={ref} style={{ maxWidth: 760 }}>
        <div className="label" style={{ marginBottom: 14 }}>BLENDED PATIENT COLLECTION · BEFORE SUPERSCRIPT</div>
        <div style={{ fontFamily: "var(--font-sans)", fontSize: 96, lineHeight: 0.9, letterSpacing: "-0.04em", fontWeight: 400 }}>
          76.4<span style={{ fontSize: 36, color: "var(--ss-grey-3)", marginLeft: 8 }}>%</span>
        </div>
        <div className="bar" style={{ height: 16, marginTop: 24 }}>
          <div className="bar__fill" style={{ width: inView ? "76.4%" : 0, background: "var(--ss-grey-1)" }} />
        </div>
        <div style={{ display: "flex", justifyContent: "space-between", marginTop: 10 }}>
          <span className="label" style={{ color: "var(--ss-grey-2)" }}>76.4% COLLECTED</span>
          <span className="label" style={{ color: "var(--ss-red)" }}>23.6% LEFT ON THE TABLE</span>
        </div>
      </div>
    </Section>
  );
}

/* ---------- product / solution ---------- */
function Solution() {
  return (
    <Section id="solution" num="[02] / PRODUCT"
             title={<>Superscript priced every visit upfront and let the front desk collect at check-in, <em>inside their existing EHR workflows</em>.</>}>
      <div className="demo-stage">
        <div className="demo-stage__viz">
          <SkylightDemo />
        </div>
        <div className="demo-stage__copy">
          <div>
            <div className="label" style={{ color: "var(--ss-blue)", marginBottom: 14 }}>SKYLIGHT · AT THE FRONT DESK</div>
            <p className="body" style={{ fontSize: 14, lineHeight: 1.5, marginTop: 0, marginBottom: 20 }}>
              Superscript piloted at 3 Allied sites, running on top of Athena. When an appointment is created, Superscript's pricing protocol generates a guaranteed price for every line item. Patients see a transparent price before their visit and can pay in advance or at the front desk.
            </p>
            <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 22 }}>
              <li>
                <div style={{ fontWeight: 600, fontSize: 16, letterSpacing: "-0.01em", marginBottom: 4 }}>A guaranteed price before the visit</div>
                <div className="body muted" style={{ fontSize: 14, lineHeight: 1.4 }}>Automated eligibility plus cost-share calculation. No payer calls.</div>
              </li>
              <li>
                <div style={{ fontWeight: 600, fontSize: 16, letterSpacing: "-0.01em", marginBottom: 4 }}>Collection at check-in</div>
                <div className="body muted" style={{ fontSize: 14, lineHeight: 1.4 }}>Parents see what they owe and pay at the front desk, instead of weeks later by statement. No surprise bills.</div>
              </li>
              <li>
                <div style={{ fontWeight: 600, fontSize: 16, letterSpacing: "-0.01em", marginBottom: 4 }}>No workflow change</div>
                <div className="body muted" style={{ fontSize: 14, lineHeight: 1.4 }}>Skylight sits inside the existing EHR, so the team kept working the way they already did.</div>
              </li>
            </ul>
          </div>

          {/* training-time callout — fills the copy column */}
          <div style={{ borderTop: "1px solid var(--ss-grey-5)", paddingTop: 26, marginTop: 28, display: "flex", alignItems: "center", gap: 20 }}>
            <div style={{ fontFamily: "var(--font-sans)", fontSize: 68, lineHeight: 0.85, letterSpacing: "-0.04em", color: "var(--ss-blue)", fontWeight: 400, whiteSpace: "nowrap" }}>
              <CountStat to={10} duration={1500} /><span style={{ fontFamily: "var(--font-mono)", fontSize: 12, textTransform: "uppercase", letterSpacing: "-0.03em", color: "var(--ss-black)", marginLeft: 10 }}>min</span>
            </div>
            <div style={{ flex: 1 }}>
              <div className="label" style={{ color: "var(--ss-black)", marginBottom: 5 }}>AVERAGE TIME TO TRAIN EACH ADMIN</div>
              <div className="body muted" style={{ fontSize: 13, lineHeight: 1.4 }}>Because Skylight lives inside the workflow the team already knows, onboarding took about ten minutes per person.</div>
            </div>
          </div>
        </div>
      </div>
    </Section>
  );
}

/* ---------- results ---------- */
function Results() {
  const [ref, inView] = useInView({ threshold: 0.2, once: true });
  const MAX = 60; // bar scale: top yield ~ full track
  const sites = [
    { label: "GARDEN CITY", pre: 22.5, post: 59.6, lift: "2.6×" },
    { label: "BELLMORE",    pre: 24.5, post: 59.3, lift: "2.4×" },
    { label: "CHESTER",     pre: 20.0, post: 49.4, lift: "2.5×" }
  ];
  return (
    <Section id="results" num="[03] / RESULTS"
             title={<>Upfront yield went from 22% to <em>56%</em> in the first week live.</>}>
      <p className="body muted" style={{ maxWidth: 720, marginBottom: 40 }}>
        Upfront yield is the share of patient responsibility collected at or before the time of service. Across Chester, Bellmore, and Garden City, it more than doubled in week one, and daily patient payments rose 20% against the prior five-month baseline.
      </p>

      <div ref={ref} style={{ display: "flex", flexDirection: "column", gap: 56 }}>

        {/* 3-cell comparison header */}
        <div className="compare">
          <div className="compare__cell">
            <div className="compare__label">PRE-SUPERSCRIPT · BASELINE</div>
            <div className="compare__big"><CountStat to={22.3} suffix="%" decimals={1} duration={1500} /></div>
            <div className="compare__cap">AVG ACROSS 3 SITES</div>
          </div>
          <div className="compare__cell">
            <div className="compare__label">WITH SUPERSCRIPT · WEEK ONE</div>
            <div className="compare__big is-after"><CountStat to={56.1} suffix="%" decimals={1} duration={1500} /></div>
            <div className="compare__cap">AVG ACROSS 3 SITES</div>
          </div>
          <div className="compare__cell">
            <div className="compare__label">UPFRONT YIELD LIFT</div>
            <div className="compare__big is-lift"><CountStat to={2.5} suffix="×" decimals={1} duration={1500} /></div>
            <div className="compare__cap">22.3% → 56.1%</div>
          </div>
        </div>

        {/* per-location PRE/POST bars */}
        <div>
          <div className="label" style={{ color: "var(--ss-black)", marginBottom: 18 }}>UPFRONT YIELD BY SITE</div>
          <div className="uy-bars">
            {sites.map((s, i) => (
              <div key={i} className="uy-row">
                <div className="uy-name">{s.label}</div>
                <div className="uy-pair">
                  <div className="uy-line">
                    <span className="uy-tag uy-tag--pre">PRE</span>
                    <div className="uy-track">
                      <div className="uy-fill uy-fill--pre" style={{ width: inView ? (s.pre / MAX * 100) + "%" : 0, transitionDelay: (i * 0.1) + "s" }} />
                    </div>
                    <span className="uy-val uy-val--pre">{s.pre}%</span>
                  </div>
                  <div className="uy-line">
                    <span className="uy-tag uy-tag--post">POST</span>
                    <div className="uy-track">
                      <div className="uy-fill uy-fill--post" style={{ width: inView ? (s.post / MAX * 100) + "%" : 0, transitionDelay: (i * 0.1 + 0.15) + "s" }} />
                    </div>
                    <span className="uy-val uy-val--post">{s.post}%</span>
                  </div>
                </div>
                <div className="uy-lift">{s.lift}</div>
              </div>
            ))}
          </div>
        </div>

        {/* outcome strip — no dollar figures */}
        <div className="outcome-strip">
          <div>
            <div className="label" style={{ color: "var(--ss-grey-3)", marginBottom: 6 }}>DAILY PATIENT PAYMENTS</div>
            <div style={{ fontSize: 34, letterSpacing: "-0.025em", color: "var(--ss-blue)", fontWeight: 500, lineHeight: 1 }}>+20%</div>
            <div className="label" style={{ color: "var(--ss-grey-2)", marginTop: 6 }}>VS FIVE-MONTH BASELINE</div>
          </div>
          <div>
            <div className="label" style={{ color: "var(--ss-grey-3)", marginBottom: 6 }}>ON TRACK · PATIENT YIELD</div>
            <div style={{ fontSize: 34, letterSpacing: "-0.025em", color: "var(--ss-blue)", fontWeight: 500, lineHeight: 1 }}>90%+</div>
            <div className="label" style={{ color: "var(--ss-grey-2)", marginTop: 6 }}>SHARE OF OWED ULTIMATELY COLLECTED</div>
          </div>
          <div>
            <div className="label" style={{ color: "var(--ss-grey-3)", marginBottom: 6 }}>RESULT</div>
            <div style={{ fontSize: 16, lineHeight: 1.45, color: "var(--ss-black)", letterSpacing: "-0.01em" }}>
              At this pace, they are on track to lift blended collection from 76.4% to over 90% of what patients owe, the benchmark Superscript's live sites reach.
            </div>
          </div>
        </div>
      </div>
    </Section>
  );
}

/* ---------- CTA footer ---------- */
function CtaFooter() {
  return (
    <section className="cta">
      <div className="wrap">
        <div className="cta__big">
          Show patients a transparent price, <em>at the moment they are most likely to pay</em>.
        </div>
        <div className="cta__row">
          <a className="cta__btn" href="https://calendar.app.google/HXP6d7W5GDf65NW59" target="_blank" rel="noopener">Book a demo →</a>
          <span>SUPERSCRIPT · HEALTHCARE'S FIRST PRICING PROTOCOL</span>
        </div>
      </div>
    </section>
  );
}

/* ---------- app ---------- */
function App() {
  const [active, setActive] = useState("before");
  useEffect(() => {
    const ids = ["before", "solution", "results"];
    const els = ids.map(id => document.getElementById(id)).filter(Boolean);
    if (!els.length) return;
    const obs = new IntersectionObserver((entries) => {
      const visible = entries.filter(e => e.isIntersecting);
      if (!visible.length) return;
      visible.sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);
      setActive(visible[0].target.id);
    }, { threshold: [0.15, 0.4], rootMargin: "-80px 0px -50% 0px" });
    els.forEach(el => obs.observe(el));
    return () => obs.disconnect();
  }, []);
  const jump = (id) => {
    const el = document.getElementById(id);
    if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 60, behavior: "smooth" });
  };
  return (
    <>
      <Nav active={active} onJump={jump} />
      <main className="page">
        <Hero />
        <Before />
        <Solution />
        <Results />
        <CtaFooter />
      </main>
    </>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
