/* Stethos — landing page, sections A (hero → counter-intuitive).
   Composes the design-system primitives from the compiled bundle. */
const DS = window.LatentHealthDesignSystem_2f3a71;
const { Button, Badge, Card, Eyebrow, StatCard } = DS;

const MAXW = 1120;

function Container({ children, style }) {
  return <div style={{ maxWidth: MAXW, margin: '0 auto', padding: '0 32px', ...style }}>{children}</div>;
}

function Section({ id, children, style, pad = 120 }) {
  return (
    <section id={id} style={{ position: 'relative', padding: `${pad}px 0`, ...style }}>
      <Container>{children}</Container>
    </section>
  );
}

/* Scroll-triggered swoosh-in: fades + eases into place whenever it enters view, and resets if you scroll back past it.
   Uses a manual scroll/resize rect check (not IntersectionObserver — unreliable in some preview contexts) with a
   mount-time fallback so content is never permanently stuck hidden. */
function Reveal({ children, delay = 0, distance = 34, style }) {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    function check() {
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight;
      setShown(r.top < vh * 0.92 && r.bottom > 0);
    }
    check();
    const id = setInterval(check, 120);
    window.addEventListener('scroll', check, { passive: true });
    window.addEventListener('resize', check);
    return () => { clearInterval(id); window.removeEventListener('scroll', check); window.removeEventListener('resize', check); };
  }, []);
  return (
    <div ref={ref} style={{
      opacity: shown ? 1 : 0, transform: shown ? 'none' : `translateY(${distance}px) scale(0.985)`,
      transition: `opacity 1.1s cubic-bezier(0.16,1,0.3,1) ${delay}ms, transform 1.1s cubic-bezier(0.16,1,0.3,1) ${delay}ms`,
      willChange: 'opacity, transform',
      ...style,
    }}>{children}</div>
  );
}

/* ---------------- Nav ---------------- */
function Nav() {
  return (
    <div style={{
      position: 'sticky', top: 0, zIndex: 100,
      backdropFilter: 'blur(14px)', WebkitBackdropFilter: 'blur(14px)',
      background: 'rgba(10,11,13,0.72)', borderBottom: '1px solid var(--border)',
    }}>
      <Container style={{ display: 'flex', alignItems: 'center', height: 60, gap: 24 }}>
        <a href="#top" style={{ display: 'flex', alignItems: 'center', gap: 9, color: 'var(--text-primary)' }}>
          <span style={{
            width: 10, height: 10, borderRadius: '50%', background: 'var(--cyan-500)',
            boxShadow: '0 0 12px 2px var(--cyan-glow)',
          }} />
          <span style={{ fontFamily: 'var(--font-display)', fontSize: 22, fontWeight: 600, letterSpacing: '-0.02em' }}>Stethos</span>
        </a>
        <div style={{ flex: 1 }} />
        <div style={{ display: 'flex', gap: 26, alignItems: 'center' }} className="lh-navlinks">
          <a href="#problem" style={{ color: 'var(--text-secondary)', fontSize: 14 }}>Problem</a>
          <a href="#flow" style={{ color: 'var(--text-secondary)', fontSize: 14 }}>How it works</a>
          <a href="#mandate" style={{ color: 'var(--text-secondary)', fontSize: 14 }}>Mandate</a>
        </div>
        <Button variant="primary" size="sm" iconRight="→" href="/demo">Live demo</Button>
      </Container>
    </div>
  );
}

/* ---------------- Hero ---------------- */
function Hero() {
  return (
    <section id="top" style={{ position: 'relative', overflow: 'hidden', borderBottom: '1px solid var(--border)' }}>
      <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none' }} className="lh-ambient" />
      <Container style={{ padding: '132px 32px 108px', position: 'relative', textAlign: 'center' }}>
        <h1 style={{
          fontSize: 'clamp(40px, 6vw, 74px)', lineHeight: 1.04, letterSpacing: '-0.03em',
          maxWidth: 940, fontWeight: 500, margin: '0 auto',
        }}>
          Hospitals find out a stay went badly forty days after the patient goes home.
        </h1>
        <p style={{
          fontFamily: 'var(--font-body)', fontSize: 19, lineHeight: 1.55, color: 'var(--text-secondary)',
          maxWidth: 620, marginTop: 28, margin: '28px auto 0',
        }}>
          Your hospital already collects the signals. We just read them, in real time.
          See dissatisfaction while there's still time to fix it.
        </p>
        <div style={{ display: 'flex', gap: 14, marginTop: 40, flexWrap: 'wrap', justifyContent: 'center' }}>
          <Button variant="primary" size="lg" iconRight="→" href="/demo">See the live demo</Button>
          <Button variant="ghost" size="lg" href="#flow">How it works</Button>
        </div>
      </Container>
    </section>
  );
}

/* ---------------- Problem ---------------- */
function ProblemSection() {
  return (
    <Section id="problem" style={{ borderBottom: '1px solid var(--border)', textAlign: 'center' }}>
      <Eyebrow style={{ color: 'var(--status-flagged)' }}>By the time the survey lands, it's history</Eyebrow>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 20, marginTop: 32, textAlign: 'left' }} className="lh-grid-3">
        <StatCard value="40" unit="days" label="average lag before a hospital learns a stay went badly" />
        <StatCard value="25–30%" label="of discharged patients ever respond to the survey" />
        <StatCard eyebrow="April 2025" value="CPERS" accent="alarm" label="CIHI decommissioned the system for comparing patient experience across Canadian hospitals. The survey lives on; the shared benchmark doesn't." />
      </div>
      <p style={{
        fontFamily: 'var(--font-body)', fontSize: 18, lineHeight: 1.6, color: 'var(--text-secondary)',
        maxWidth: 680, marginTop: 40, margin: '40px auto 0',
      }}>
        Patient experience is measured after the patient has left the building, by the minority who
        bother to answer. By the time the data arrives, the ward has turned over a hundred times.
        <span style={{ color: 'var(--text-primary)' }}> Nothing that shows up in that report can still be fixed.</span>
      </p>
    </Section>
  );
}

/* ---------------- Data flow (interactive explainer) ---------------- */
function DataFlowSection() {
  const FlowExplainer = window.FlowExplainer;
  return (
    <Section id="flow" style={{ borderBottom: '1px solid var(--border)' }}>
      <Reveal>
        <div style={{ textAlign: 'center' }}>
          <Eyebrow style={{ display: 'inline-block' }}>How it works</Eyebrow>
          <h2 style={{ fontSize: 'clamp(28px,4vw,44px)', letterSpacing: '-0.025em', maxWidth: 820, marginTop: 14, fontWeight: 500, margin: '14px auto 0' }}>
            Watch one patient decline, and see the moment we catch it.
          </h2>
          <p style={{ fontFamily: 'var(--font-body)', fontSize: 18, lineHeight: 1.6, color: 'var(--text-secondary)', maxWidth: 660, marginTop: 20, margin: '20px auto 0' }}>
            Two lines. The grey line is what a ward sees today; it looks fine. The dashed line is what
            Stethos predicts her satisfaction will be at discharge. Step through her stay and watch
            them come apart.
          </p>
        </div>
      </Reveal>
      <FlowExplainer />
      <div style={{ marginLeft: 'calc(50% - 50vw)', marginRight: 'calc(50% - 50vw)', width: '100vw', padding: '96px 40px 20px', marginTop: 80, boxSizing: 'border-box', borderTop: '1px solid var(--border)' }}>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 40 }}>
          <div style={{ minWidth: 0, maxWidth: 720, textAlign: 'center' }}>
            <Reveal><Eyebrow style={{ display: 'inline-block' }}>Under the hood</Eyebrow></Reveal>
            <Reveal delay={90}>
              <h3 style={{ fontFamily: 'var(--font-display)', fontSize: 30, fontWeight: 500, letterSpacing: '-0.02em', margin: '14px 0 10px', lineHeight: 1.15 }}>Where the signal comes from</h3>
            </Reveal>
            <Reveal delay={180}>
              <p style={{ fontFamily: 'var(--font-body)', fontSize: 16, lineHeight: 1.65, color: 'var(--text-secondary)', margin: 0 }}>
                Three sources already sit in the room: the call bell, the nurse-call system, the RTLS
                badge that tracks who visits and when. Two more slot in with zero new hardware: a
                room sensor and the EMR feed. All five stream into the model continuously, not once a
                quarter. It fuses them into a single number, updated every hour, and pushes a flag the
                moment that number crosses the line, hours or days before anyone would have noticed.
              </p>
            </Reveal>
          </div>
          <Reveal delay={260} style={{ minWidth: 0, width: '100%', maxWidth: 1300, alignSelf: 'center' }}>
            <DataFlowLiveMount />
          </Reveal>
        </div>
      </div>
    </Section>
  );
}
function DataFlowLiveMount() { const DataFlowLive = window.DataFlowLive; return <DataFlowLive maxScale={1.8} />; }

/* ---------------- Insight (4 cards) ---------------- */
function InsightSection() {
  const cards = [
    ['Unmet need', 'Is she asking for something she isn’t getting?'],
    ['Latency', 'How long does she wait before anyone comes?'],
    ['Repetition', 'Is she asking for the same thing, again?'],
    ['Withdrawal', 'Has she stopped asking at all?'],
  ];
  return (
    <Section style={{ borderBottom: '1px solid var(--border)', textAlign: 'center' }}>
      <Eyebrow>We don’t measure happiness</Eyebrow>
      <h2 style={{ fontSize: 'clamp(28px,4vw,44px)', letterSpacing: '-0.025em', maxWidth: 720, marginTop: 14, fontWeight: 500, margin: '14px auto 0' }}>
        We infer it from the gap between need and response.
      </h2>
      <p style={{ fontFamily: 'var(--font-body)', fontSize: 18, lineHeight: 1.6, color: 'var(--text-secondary)', maxWidth: 680, marginTop: 22, margin: '22px auto 0' }}>
        You cannot ask a patient how they feel and expect the truth. They’re tired, they’re
        dependent on you, and they don’t want to be difficult. So we don’t ask. Every signal
        in a hospital room collapses into four questions:
      </p>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16, marginTop: 36, textAlign: 'center' }} className="lh-grid-4">
        {cards.map(([k, q], i) => (
          <Card key={i} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12, minHeight: 150 }}>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.1em', textTransform: 'uppercase', color: 'var(--cyan-300)' }}>{k}</span>
            <span style={{ fontFamily: 'var(--font-body)', fontSize: 16, lineHeight: 1.45, color: 'var(--text-primary)' }}>{q}</span>
          </Card>
        ))}
      </div>
    </Section>
  );
}

/* ---------------- Counter-intuitive (diverging chart) ---------------- */
function DivergeChart() {
  const W = 520, H = 220, PAD = 24;
  const n = 40;
  const bell = [], risk = [];
  for (let i = 0; i < n; i++) {
    const t = i / (n - 1);
    bell.push(0.7 - 0.62 * Math.pow(t, 1.3));            // call-bell rate drops
    risk.push(0.2 + 0.7 * Math.pow(t, 1.5));             // risk climbs
  }
  const x = (i) => PAD + (i / (n - 1)) * (W - PAD * 2);
  const y = (v) => H - PAD - v * (H - PAD * 2);
  const line = (arr) => 'M ' + arr.map((v, i) => `${x(i).toFixed(1)},${y(v).toFixed(1)}`).join(' L ');
  return (
    <svg viewBox={`0 0 ${W} ${H}`} style={{ width: '100%', height: 'auto', maxWidth: W }}>
      <path d={line(bell)} fill="none" stroke="var(--text-secondary)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
      <path d={line(risk)} fill="none" stroke="var(--status-flagged)" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
      <text x={x(n - 1)} y={y(bell[n - 1]) + 16} textAnchor="end" fontFamily="var(--font-mono)" fontSize="10" fill="var(--text-secondary)">call-bell rate</text>
      <text x={x(n - 1)} y={y(risk[n - 1]) - 8} textAnchor="end" fontFamily="var(--font-mono)" fontSize="10" fill="var(--status-flagged)">risk</text>
    </svg>
  );
}

function CounterSection() {
  return (
    <Section style={{ borderBottom: '1px solid var(--border)', textAlign: 'center' }}>
      <div>
        <div>
          <Eyebrow style={{ color: 'var(--status-flagged)' }}>The counter-intuitive part</Eyebrow>
          <h2 style={{ fontSize: 'clamp(28px,4vw,46px)', letterSpacing: '-0.025em', marginTop: 14, fontWeight: 500, maxWidth: 840, margin: '14px auto 0' }}>
            When she stops pressing the call bell, we get more worried.
          </h2>
          <p style={{ fontFamily: 'var(--font-body)', fontSize: 18, lineHeight: 1.6, color: 'var(--text-secondary)', marginTop: 22, maxWidth: 740, margin: '22px auto 0' }}>
            Going quiet doesn't mean she's fine. It means she's stopped expecting help.
            A flattening voice, shortening conversations, a call bell that falls silent, is the single
            strongest predictor of a stay that ends badly. Every system built on patient feedback
            misses this by design: <span style={{ color: 'var(--text-primary)' }}>by the time she'd complain, she's already stopped trying.</span>
          </p>
        </div>
      </div>
      <div style={{ marginTop: 44 }}><DivergeLiveMount /></div>
    </Section>
  );
}
function DivergeLiveMount() { const DivergeLive = window.DivergeLive; return <DivergeLive />; }

Object.assign(window, { Container, Section, Nav, Hero, ProblemSection, DataFlowSection, InsightSection, CounterSection });
