// Trellum — PFI, Block, Approach, Contact pages

const PFI = ({ setPage, h1Ref }) => (
  <Page>
    {/* HEADER */}
    <section style={{ background: 'var(--teal)', padding: '96px 48px 64px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <FadeIn delay={200}><Eyebrow>Practice · PFI & long-term FM contracts</Eyebrow></FadeIn>
        <FadeIn delay={320}>
          <PageHeadingH1 ref={h1Ref} style={{
            fontSize: 'clamp(2.5rem, 5.5vw, 4rem)', color: 'var(--paper)',
            lineHeight: 1.05, maxWidth: 980, marginTop: 16,
          }}>
            Read the contract <Em>the way it is actually operated</Em>.
          </PageHeadingH1>
        </FadeIn>
        <FadeIn delay={1100}>
          <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 17, color: 'rgba(245,245,243,0.78)', maxWidth: 640, marginTop: 28, lineHeight: 1.7 }}>
            PFI is a 25-year contract in which specialist contract knowledge naturally concentrates with the operator. Authority teams turn over; operator commercial leads do not. Trellum sits with the authority team, reading the payment mechanism from first principles against recorded service events, so the authority sits in quarterly reviews with the same depth of understanding as the people across the table.
          </p>
        </FadeIn>
        <FadeIn delay={1300} style={{ marginTop: 36, display: 'flex', gap: 12, flexWrap: 'wrap' }}>
          <Button variant="primary" onClick={() => setPage('contact')}>Request a PM audit</Button>
          <Button variant="ghostDark" onClick={() => setPage('approach')}>How Trellum works</Button>
        </FadeIn>
      </div>
    </section>

    {/* MAP */}
    <section style={{ background: 'var(--paper)', padding: '96px 48px 0' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <InView style={{ textAlign: 'center', marginBottom: 40 }}>
          <div style={{ fontFamily: 'var(--ff-body)', fontSize: 10, fontWeight: 500, letterSpacing: '0.15em', textTransform: 'uppercase', color: 'var(--canton)' }}>
            UK PFI Contracts — Density × Sector
          </div>
          <div style={{ fontFamily: 'var(--ff-body)', fontSize: 10, fontWeight: 400, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--canton)', marginTop: 8 }}>
            653 PFI contracts · 20 sectors · 12 regions
          </div>
        </InView>
        <PFIMap onRequestAudit={() => setPage('contact')} />
      </div>
    </section>

    {/* THE PROBLEM PRECISELY */}
    <section style={{ background: 'var(--paper)', padding: '96px 48px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 56 }} className="mob-stack">
        <InView>
          <SectionLabel>The condition</SectionLabel>
          <h2 style={{ fontFamily: 'var(--ff-display)', fontSize: 32, color: 'var(--slate)', lineHeight: 1.15, fontWeight: 400, letterSpacing: '-0.01em', margin: '0 0 20px' }}>
            The contract was written in 2004. <Em>The team has turned over three times.</Em>
          </h2>
          <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.75 }}>
            PM schedules run anywhere from 50–500 pages of defined terms, availability logic, and deduction calculations. Most estates teams inherited them.
          </p>
          <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.75 }}>
            The audit reads the schedule against the organisation's recorded service events — helpdesk logs, BMS availability data, PPM records — and returns a register of where contractual deduction entitlement and reported position diverge.
          </p>
        </InView>
        <InView style={{ background: '#FFFFFF', border: '1px solid var(--stone)', borderRadius: 8, padding: 32 }}>
          <Eyebrow>The condition</Eyebrow>
          <div style={{ marginTop: 16 }}>
            {[
              ['653 live', 'UK PFI contracts — IPA, 2024'],
              ['2028–2037', 'Handback window for live UK PFI contracts'],
              ['£136bn', 'Unitary charge remaining — IPA, 2024'],
              ['25 years', 'Typical PFI contract length'],
            ].map(([v, l], i) => (
              <div key={v} style={{
                display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
                padding: '16px 0',
                borderTop: i === 0 ? 'none' : '1px solid var(--stone-light)',
              }}>
                <span style={{ fontFamily: 'var(--ff-display)', fontSize: 22, color: 'var(--teal)', letterSpacing: '-0.005em' }}>{v}</span>
                <span style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 12, color: 'var(--charcoal)', letterSpacing: '0.02em', textAlign: 'right' }}>{l}</span>
              </div>
            ))}
          </div>
        </InView>
      </div>
    </section>

    {/* THE AUDIT */}
    <section style={{ background: 'var(--paper)', padding: '0 48px 96px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto', paddingTop: 96, borderTop: '1px solid var(--stone)' }}>
        <InView><SectionLabel>The audit</SectionLabel></InView>
        <InView as="h2" style={{ fontFamily: 'var(--ff-display)', fontSize: 'clamp(1.75rem, 3vw, 2.25rem)', color: 'var(--slate)', margin: '0 0 32px', fontWeight: 400, letterSpacing: '-0.01em', lineHeight: 1.2, maxWidth: 820 }}>
          A scoped read of the schedule <Em>against the evidence.</Em>
        </InView>
        <InView as="p" style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.75, maxWidth: 720, margin: 0 }}>
          The Payment Mechanism Audit reads the schedule&apos;s availability and deduction logic against the recorded service events the authority holds — helpdesk logs, BMS availability data, PPM records — and returns a register of where contractual deduction entitlement and reported position diverge.
        </InView>
        <InView as="p" style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.75, maxWidth: 720, margin: '20px 0 0' }}>
          The work is delivered as a fixed-fee sprint with a single named deliverable: a written audit and a working register, lodged in a format the authority team can extend as operational data builds up.
        </InView>
        <InView style={{ marginTop: 32 }}>
          {['Payment mechanism', 'PFI', 'PPP', 'CAFM', 'Hand-back', 'Deduction risk'].map((t) => <Tag key={t}>{t}</Tag>)}
        </InView>
      </div>
    </section>

    {/* HOW AN ENGAGEMENT RUNS */}
    <section style={{ background: 'var(--paper)', padding: '0 48px 96px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto', paddingTop: 96, borderTop: '1px solid var(--stone)' }}>
        <InView><SectionLabel>How a Payment Mechanism Audit runs</SectionLabel></InView>
        <InView as="h2" style={{ fontFamily: 'var(--ff-display)', fontSize: 'clamp(1.75rem, 3vw, 2.25rem)', color: 'var(--slate)', margin: '0 0 48px', fontWeight: 400, letterSpacing: '-0.01em', lineHeight: 1.2 }}>
          Four scoped weeks. <Em>Senior-led throughout.</Em>
        </InView>
        <InView style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }} className="mob-stack">
          {[
            ['W01', 'Brief', 'One-page scope. Contract number, key schedules, named accountable officer, target deliverable date.'],
            ['W02', 'Read', 'PM schedule read. Helpdesk / BMS data request. Interviews: contract manager, compliance lead, finance.'],
            ['W03', 'Map', 'Deduction triggers mapped against 6–12 months of service events. Register drafted.'],
            ['W04', 'Hand-off', 'Written audit. Workshop with client team. Register lodged in client system — maintained without us.'],
          ].map(([w, title, body]) => (
            <div key={w} style={{ border: '1px solid var(--stone)', borderRadius: 8, padding: 24, background: '#FFFFFF' }}>
              <div style={{ width: 32, height: 2, background: 'var(--canton)', marginBottom: 14 }} />
              <div style={{ fontFamily: 'var(--ff-body)', fontSize: 10, fontWeight: 500, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--canton)' }}>{w}</div>
              <div style={{ fontFamily: 'var(--ff-display)', fontSize: 18, color: 'var(--slate)', marginTop: 10, fontWeight: 400, letterSpacing: '-0.005em' }}>{title}</div>
              <div style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 13, color: 'var(--charcoal)', lineHeight: 1.6, marginTop: 8 }}>{body}</div>
            </div>
          ))}
        </InView>
      </div>
    </section>

    <CTABand
      eyebrow="Start with the audit"
      heading={<>Hand us your PM schedule and six months of helpdesk data. <Em>The audit starts the week the brief lands.</Em></>}
      body="Fixed fee. The deliverable is a written audit and a working register, handed over in a format your team can extend as operational data builds up."
      primaryLabel="Request a PM audit"
      primaryOnClick={() => setPage('contact')}
      secondaryLabel="Residential block management →"
      secondaryOnClick={() => setPage('block')}
    />
  </Page>
);

// ─────────── BLOCK ───────────
const Block = ({ setPage, h1Ref }) => (
  <Page>
    <section style={{ background: 'var(--teal)', padding: '96px 48px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <FadeIn delay={200}><Eyebrow>Practice · Residential block management</Eyebrow></FadeIn>
        <FadeIn delay={320}>
          <PageHeadingH1 ref={h1Ref} style={{ fontSize: 'clamp(2.5rem, 5.5vw, 4rem)', color: 'var(--paper)', lineHeight: 1.05, maxWidth: 980, marginTop: 16 }}>
            BSA golden thread — built for <Em>the moment someone asks to see it.</Em>
          </PageHeadingH1>
        </FadeIn>
        <FadeIn delay={1100}>
          <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 17, color: 'rgba(245,245,243,0.78)', maxWidth: 640, marginTop: 28, lineHeight: 1.7 }}>
            The Building Safety Act introduced a statutory duty-holder regime over higher-risk residential blocks. Managing agents, RMCs and RTMs carrying HRBs now operate against an evidence standard most organisations were never asked to build. Trellum reads the information requirements against the records the organisation holds and produces the register, model and process that the Accountable Person carries into a safety-case review.
          </p>
        </FadeIn>
        <FadeIn delay={1300} style={{ marginTop: 36, display: 'flex', gap: 12, flexWrap: 'wrap' }}>
          <Button variant="primary" onClick={() => setPage('contact')}>Request a gap audit</Button>
          <Button variant="ghostDark" onClick={() => setPage('approach')}>How Trellum works</Button>
        </FadeIn>
      </div>
    </section>

    <section style={{ background: 'var(--paper)', padding: '96px 48px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto', display: 'grid', gridTemplateColumns: '1.15fr 1fr', gap: 56 }} className="mob-stack">
        <InView>
          <SectionLabel>The regulatory step-change</SectionLabel>
          <h2 style={{ fontFamily: 'var(--ff-display)', fontSize: 32, color: 'var(--slate)', lineHeight: 1.2, fontWeight: 400, letterSpacing: '-0.01em', margin: '0 0 20px' }}>
            The BSA raised the standard for the entire delivery chain. <Em>Everyone is operating against the same new regime.</Em>
          </h2>
          <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.75 }}>
            Under the Building Safety Act 2022 and the Higher-Risk Buildings regulations, the Accountable Person is legally responsible for assessing and managing building-safety risks — and for demonstrating compliance, in evidence, to the Building Safety Regulator.
          </p>
          <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.75 }}>
            Most RMCs, RTMs and managing agents inherited the statutory duty-holder regime without the accompanying infrastructure. Existing management agreements were drafted for operational service delivery, before the BSA set the evidence standard that now applies to the same work.
          </p>
        </InView>
        <InView style={{ background: 'var(--stone-light)', borderRadius: 8, padding: 32 }}>
          <Eyebrow>What the BSR expects to see</Eyebrow>
          <div style={{ marginTop: 16 }}>
            {[
              ['01', 'Asset information model — current, auditable, versioned'],
              ['02', 'Safety-case report — risk-based, not checklist'],
              ['03', 'Mandatory occurrence reporting route — operable'],
              ['04', 'Resident engagement strategy — evidenced, not filed'],
              ['05', 'Golden-thread hand-off — at any change of AP'],
            ].map(([n, body], i) => (
              <div key={n} style={{
                display: 'grid', gridTemplateColumns: '22px 1fr', gap: 8,
                padding: '12px 0',
                borderTop: i === 0 ? 'none' : '1px solid var(--stone)',
              }}>
                <div style={{ fontFamily: 'var(--ff-display)', fontStyle: 'italic', fontSize: 14, color: 'var(--canton)', lineHeight: 1.55 }}>{n}</div>
                <div style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 13, color: 'var(--slate)', lineHeight: 1.55 }}>{body}</div>
              </div>
            ))}
          </div>
        </InView>
      </div>
    </section>

    <section style={{ background: 'var(--paper)', padding: '0 48px 96px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto', paddingTop: 96, borderTop: '1px solid var(--stone)' }}>
        <InView><SectionLabel>The audit</SectionLabel></InView>
        <InView as="h2" style={{ fontFamily: 'var(--ff-display)', fontSize: 'clamp(1.75rem, 3vw, 2.25rem)', color: 'var(--slate)', margin: '0 0 32px', fontWeight: 400, letterSpacing: '-0.01em', lineHeight: 1.2, maxWidth: 820 }}>
          A gap register against <Em>the statutory information requirements.</Em>
        </InView>
        <InView as="p" style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.75, maxWidth: 720, margin: 0 }}>
          The Golden Thread Gap Audit reads the information requirements of BSA Part 4 and the Higher-Risk Buildings regulations against the records the organisation currently holds. The output is a gap register, mapped to the statutory obligation each line sits against.
        </InView>
        <InView as="p" style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.75, maxWidth: 720, margin: '20px 0 0' }}>
          The work is delivered as a fixed-fee sprint with a single named deliverable: an audit-ready register the Accountable Person can carry into a safety-case review without modification.
        </InView>
        <InView style={{ marginTop: 32 }}>
          {['BSA', 'Golden thread', 'HRB', 'Accountable Person', 'Safety case', 'S.91 engagement'].map((t) => <Tag key={t}>{t}</Tag>)}
        </InView>
      </div>
    </section>

    <section style={{ background: 'var(--paper)', padding: '0 48px 96px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto', paddingTop: 96, borderTop: '1px solid var(--stone)' }}>
        <InView><SectionLabel>Who we support in the duty-holder map</SectionLabel></InView>
        <InView as="h2" style={{ fontFamily: 'var(--ff-display)', fontSize: 'clamp(1.75rem, 3vw, 2.25rem)', color: 'var(--slate)', margin: '0 0 48px', fontWeight: 400, letterSpacing: '-0.01em', lineHeight: 1.2 }}>
          Four positions. <Em>Different obligations.</Em>
        </InView>
        <InView style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16 }} className="mob-stack">
          {[
            ['Managing agents', 'Named agent to an RMC, RTM or freeholder for one or more HRBs. Carrying operational delivery but not the statutory duty.'],
            ['RMC directors', 'Resident Management Company directors. Often carry the AP duty by default and need the framework to discharge it.'],
            ['RTM companies', 'Right-to-Manage companies taking on management from the freeholder. Need to inherit a defensible evidence base.'],
            ['Named Accountable Persons', 'The statutory duty-holder. Needs the golden thread, the safety-case report, and an operable complaints route.'],
          ].map(([title, body]) => (
            <div key={title} style={{ border: '1px solid var(--stone)', borderRadius: 8, padding: 24, background: '#FFFFFF' }}>
              <div style={{ width: 32, height: 2, background: 'var(--canton)', marginBottom: 14 }} />
              <div style={{ fontFamily: 'var(--ff-display)', fontSize: 17, color: 'var(--slate)', fontWeight: 400, letterSpacing: '-0.005em' }}>{title}</div>
              <div style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 13, color: 'var(--charcoal)', lineHeight: 1.6, marginTop: 10 }}>{body}</div>
            </div>
          ))}
        </InView>
      </div>
    </section>

    <CTABand
      eyebrow="Start with a readiness review"
      heading={<>Tell us your portfolio and your duty-holder structure. <Em>We read the information requirements against what you hold.</Em></>}
      body="Scoped against the information requirements of BSA Part 4. The output is an audit-ready report, traceable to the statutory obligation each line sits against — not a checklist."
      primaryLabel="Request a gap audit"
      primaryOnClick={() => setPage('contact')}
      secondaryLabel="PFI & FM contracts →"
      secondaryOnClick={() => setPage('pfi')}
    />
  </Page>
);

// ─────────── APPROACH ───────────
const Approach = ({ setPage, h1Ref }) => (
  <Page>
    <section style={{ background: 'var(--paper)', padding: '96px 48px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <FadeIn delay={200}><Eyebrow>Approach</Eyebrow></FadeIn>
        <FadeIn delay={320}>
          <PageHeadingH1 ref={h1Ref} style={{ fontSize: 'clamp(2.5rem, 5vw, 3.75rem)', color: 'var(--slate)', lineHeight: 1.08, maxWidth: 920, marginTop: 16 }}>
            A practitioner advisory for organisations <Em>inside</Em> the built environment — not consulting to it.
          </PageHeadingH1>
        </FadeIn>
        <FadeIn delay={1100}>
          <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 17, color: 'var(--charcoal)', lineHeight: 1.7, maxWidth: 680, marginTop: 28 }}>
            Trellum is an expert practitioner. It is built on experience from a sequence of roles that together cover the built environment from the point of transaction to the point of digital operation.
          </p>
        </FadeIn>
        <FadeIn delay={1300} style={{ marginTop: 40, borderLeft: '2px solid var(--canton)', paddingLeft: 16, maxWidth: 620 }}>
          <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 14, color: '#7F8A88', margin: 0, lineHeight: 1.7 }}>
            Trellum is built on operational depth and commercial expertise — on having held the contract, the compliance duty, and the digital tooling requirements together, not as separate disciplines.
          </p>
        </FadeIn>
      </div>
    </section>

    <section style={{ background: 'var(--teal)', padding: '96px 48px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <InView><Eyebrow>The four layers</Eyebrow></InView>
        <InView as="h2" style={{ fontFamily: 'var(--ff-display)', fontSize: 'clamp(2rem, 3.5vw, 2.75rem)', color: 'var(--paper)', maxWidth: 820, margin: '16px 0 24px', fontWeight: 400, letterSpacing: '-0.01em', lineHeight: 1.15 }}>
          Four layers. <Em>Each built on the one before.</Em>
        </InView>
        <InView as="p" style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'rgba(245,245,243,0.75)', maxWidth: 680, marginBottom: 56, lineHeight: 1.7 }}>
          The career history is not generalist. It is four compounding layers of expertise that almost no one in the built environment advisory market carries simultaneously.
        </InView>
        {[
          ['01', 'Commercial', 'Sales, lettings, property management, leasehold block management, FM business development. Understanding built environment assets as commercial objects — valuation logic, yield, occupancy, stakeholder relationships. Critically: experience on the sell side of FM contracts. What procurement directors care about. What gets promised versus what gets delivered.'],
          ['02', 'Technical', 'Estate management within regulated industries, water treatment, civils and groundworks operations. Hard engineering in regulated, process-critical environments where failure has legal and environmental consequence. Operating plant under statutory permit. Understanding what compliance means when the stakes are material, not theoretical.'],
          ['03', 'Contractual', 'PFI FM, complex outsourced FM operations, multi-party contract and compliance management. Reading and operating against payment mechanisms, service standards, lifecycle obligations, and performance monitoring regimes. Managing contractors who are also reporting counterparts.'],
          ['04', 'Digital', 'AI tooling, software development, AI adoption programmes built for the people using them, and automation pipelines. Production capability — building working systems rather than specifying them. Led in a live environment.'],
        ].map(([n, t, b], i) => (
          <InView key={n} style={{
            display: 'grid', gridTemplateColumns: '80px 1fr auto',
            padding: '24px 0',
            borderTop: i === 0 ? '1px solid rgba(191,200,198,0.18)' : 'none',
            borderBottom: '1px solid rgba(191,200,198,0.18)',
            alignItems: 'start',
          }}>
            <div style={{ fontFamily: 'var(--ff-display)', fontStyle: 'italic', fontSize: 36, color: 'var(--canton)', lineHeight: 1 }}>{n}</div>
            <div>
              <div style={{ fontFamily: 'var(--ff-display)', fontSize: 22, color: 'var(--paper)', lineHeight: 1.2 }}>{t}</div>
              <div style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 14, color: 'rgba(245,245,243,0.65)', marginTop: 6, maxWidth: 640, lineHeight: 1.65 }}>{b}</div>
            </div>
            <div />
          </InView>
        ))}
      </div>
    </section>

    <section style={{ background: 'var(--paper)', padding: '96px 48px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <InView><SectionLabel>What the combination produces</SectionLabel></InView>
        <InView as="h2" style={{ fontFamily: 'var(--ff-display)', fontSize: 32, color: 'var(--slate)', maxWidth: 820, margin: 0, fontWeight: 400, letterSpacing: '-0.01em', lineHeight: 1.15 }}>
          A full-lifecycle view of the built environment — <Em>from transaction to digital operation.</Em>
        </InView>
        <InView as="p" style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.75, maxWidth: 680, marginTop: 24 }}>
          The career behind Trellum followed the built environment as a system across its lifecycle — from the point of transaction, through occupancy and compliance management, through hard engineering, to contract-governed operation — and the digital systems and frameworks Trellum has built sit on that arc. That full-lifecycle view is what lets Trellum see FM problems that specialists in any one layer cannot.
        </InView>
      </div>
    </section>

    <section style={{ background: 'var(--stone-light)', padding: '96px 48px' }} className="mob-pad">
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <InView><SectionLabel>Method</SectionLabel></InView>
        <InView as="h2" style={{ fontFamily: 'var(--ff-display)', fontSize: 32, color: 'var(--slate)', maxWidth: 820, margin: '0 0 48px', fontWeight: 400, letterSpacing: '-0.01em', lineHeight: 1.15 }}>
          How every engagement runs.
        </InView>
        {[
          ['01', 'Read the contract', 'The clause is the fact. Advisory without contract literacy is decoration.'],
          ['02', 'Evidence over assertion', 'Every claim is backed by document, schedule, register, or timestamp. No hedging language.'],
          ['03', 'Deployable outputs', 'Frameworks, registers, templates, toolkits. Not slide decks filed after the meeting.'],
          ['04', 'Role-specific', 'A helpdesk operator and an AP duty-holder do different jobs. Their tooling should too.'],
          ['05', 'Practitioner voice', "Senior FM people. Trellum has sat on the client's side of the table. The writing reflects it."],
          ['06', 'Teams kept capable', 'Leave the client able to maintain the framework without us. Measured by what survives year two.'],
        ].map(([n, t, b], i) => (
          <InView key={n}>
            <RuledRow n={n} title={t} body={b} first={i === 0} cols="60px 1fr 1fr" />
          </InView>
        ))}
      </div>
    </section>

    <CTABand
      eyebrow="Start with a diagnostic"
      heading={<>A three-to-five day read of your operation — <Em>before you commit to a programme.</Em></>}
      body="Structured review of systems, data quality, contract literacy and compliance posture. The deliverable is a written assessment your team can act on."
      primaryLabel="Request an assessment"
      primaryOnClick={() => setPage('contact')}
    />
  </Page>
);

// ─────────── CONTACT ───────────
const Contact = ({ setPage, h1Ref }) => {
  const [org, setOrg] = React.useState('');
  const [email, setEmail] = React.useState('');
  const [ctx, setCtx] = React.useState(null);
  const [note, setNote] = React.useState('');
  const [website, setWebsite] = React.useState(''); // honeypot
  const [submitted, setSubmitted] = React.useState(false);
  const [sending, setSending] = React.useState(false);
  const [sendError, setSendError] = React.useState(null);
  const [done, setDone] = React.useState(false);
  const err = (() => {
    if (sendError) return sendError;
    if (!submitted) return null;
    if (!org.trim()) return 'Organisation is required.';
    if (!email.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) return 'Please enter a valid email.';
    if (!note.trim()) return 'A short note is required.';
    return null;
  })();

  const onSubmit = async (e) => {
    e.preventDefault();
    setSubmitted(true);
    setSendError(null);
    if (!org.trim() || !email.trim() || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) || !note.trim()) return;
    setSending(true);
    try {
      const res = await fetch('/api/contact', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ org, email, ctx, note, website }),
      });
      if (!res.ok) {
        setSendError("Sorry — we couldn't send that. Email hello@trellum.co.uk directly.");
        return;
      }
      setDone(true);
    } catch {
      setSendError("Sorry — we couldn't send that. Email hello@trellum.co.uk directly.");
    } finally {
      setSending(false);
    }
  };

  const fieldLabel = {
    display: 'block', fontFamily: 'var(--ff-body)', fontSize: 11,
    fontWeight: 500, letterSpacing: '0.12em', textTransform: 'uppercase',
    color: 'var(--canton)', marginBottom: 8,
  };
  const fieldBox = {
    width: '100%', padding: '12px 14px', fontFamily: 'var(--ff-body)',
    fontSize: 14, fontWeight: 300, color: 'var(--charcoal)',
    background: '#FFFFFF', border: '1px solid var(--stone)', borderRadius: 4,
    boxSizing: 'border-box', outline: 'none',
    transition: 'border-color 140ms var(--ease-out)',
  };

  return (
    <Page>
      <section style={{ background: 'var(--paper)', padding: '96px 48px 0' }} className="mob-pad">
        <div style={{ maxWidth: 1100, margin: '0 auto' }}>
          <FadeIn delay={200}><Eyebrow>Contact</Eyebrow></FadeIn>
          <FadeIn delay={320}>
            <PageHeadingH1 ref={h1Ref} style={{ fontSize: 'clamp(2rem, 4vw, 3rem)', color: 'var(--slate)', lineHeight: 1.1, maxWidth: 860, marginTop: 16 }}>
              Tell us what you're carrying. <Em>We reply within two working days.</Em>
            </PageHeadingH1>
          </FadeIn>
        </div>
      </section>

      <section style={{ background: 'var(--paper)', padding: '56px 48px 96px' }} className="mob-pad">
        <div style={{ maxWidth: 1100, margin: '0 auto', display: 'grid', gridTemplateColumns: '1.1fr 1fr', gap: 64 }} className="mob-stack">
          {/* FORM */}
          <div style={{ background: '#FFFFFF', border: '1px solid var(--stone)', borderRadius: 8, padding: 32 }}>
            {!done && (
              <form onSubmit={onSubmit} noValidate style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
                {/* Honeypot — bots fill this; humans don't see it. */}
                <div aria-hidden="true" style={{ position: 'absolute', left: '-10000px', width: 1, height: 1, overflow: 'hidden' }}>
                  <label htmlFor="f-website">Website</label>
                  <input id="f-website" type="text" tabIndex={-1} autoComplete="off" value={website} onChange={(e) => setWebsite(e.target.value)} />
                </div>
                <div>
                  <label htmlFor="f-org" style={fieldLabel}>Organisation</label>
                  <input id="f-org" type="text" value={org} onChange={(e) => setOrg(e.target.value)} placeholder="e.g. Essex County Council — Estates" style={fieldBox} />
                </div>
                <div>
                  <label htmlFor="f-email" style={fieldLabel}>Email</label>
                  <input id="f-email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@organisation.gov.uk" style={fieldBox} />
                </div>
                <div>
                  <div style={fieldLabel}>Practice context</div>
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 8 }}>
                    {[
                      ['pfi', 'PFI & FM contracts'],
                      ['block', 'Residential block management'],
                      ['both', 'Both / unsure'],
                    ].map(([k, label]) => {
                      const sel = ctx === k;
                      return (
                        <button key={k} type="button" onClick={() => setCtx(k)} style={{
                          fontFamily: 'var(--ff-body)', fontSize: 12, fontWeight: 500,
                          padding: '11px 10px',
                          background: sel ? 'var(--teal)' : '#FFFFFF',
                          color: sel ? 'var(--paper)' : 'var(--charcoal)',
                          border: `1px solid ${sel ? 'var(--teal)' : 'var(--stone)'}`,
                          borderRadius: 4, cursor: 'pointer',
                          transition: 'all 140ms var(--ease-out)', textAlign: 'center',
                          letterSpacing: '0.01em', lineHeight: 1.3,
                        }}>{label}</button>
                      );
                    })}
                  </div>
                </div>
                <div>
                  <label htmlFor="f-note" style={fieldLabel}>What are you carrying?</label>
                  <textarea id="f-note" rows={6} value={note} onChange={(e) => setNote(e.target.value)}
                    placeholder="Payment mechanism, statutory compliance, digital adoption — in your own words. A paragraph is fine."
                    style={{ ...fieldBox, resize: 'vertical', lineHeight: 1.6 }} />
                </div>
                {err && (
                  <div style={{ fontFamily: 'var(--ff-body)', fontSize: 12, color: '#A44' }} role="alert">{err}</div>
                )}
                <div style={{ display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap' }}>
                  <button type="submit" aria-label="Send" disabled={sending} style={{
                    fontFamily: 'var(--ff-body)', fontSize: 13, fontWeight: 500,
                    padding: '11px 24px', background: 'var(--canton)', color: 'var(--paper)',
                    border: 'none', borderRadius: 4, cursor: sending ? 'wait' : 'pointer',
                    opacity: sending ? 0.6 : 1,
                    transition: 'background 140ms var(--ease-out)',
                  }}
                  onMouseEnter={(e) => { if (!sending) e.currentTarget.style.background = '#4F7771'; }}
                  onMouseLeave={(e) => { if (!sending) e.currentTarget.style.background = 'var(--canton)'; }}
                  >{sending ? 'Sending…' : 'Send'}</button>
                  <span style={{ fontFamily: 'var(--ff-body)', fontSize: 12, color: '#7F8A88' }}>
                    No autoresponder. A person replies.
                  </span>
                </div>
              </form>
            )}
            {done && (
              <div>
                <div style={{ width: 32, height: 2, background: 'var(--canton)', marginBottom: 20 }} />
                <h2 style={{ fontFamily: 'var(--ff-display)', fontSize: 26, color: 'var(--slate)', fontWeight: 400, letterSpacing: '-0.01em', margin: 0 }}>Received.</h2>
                <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 15, color: 'var(--charcoal)', lineHeight: 1.7, marginTop: 16 }}>
                  We will read your contact and reply within two working days. If the matter is time-sensitive, flag it in your note.
                </p>
                <button type="button" onClick={() => { setDone(false); setSubmitted(false); setOrg(''); setEmail(''); setNote(''); setCtx(null); setWebsite(''); setSendError(null); }} className="btn btn-ghost-light" style={{ marginTop: 24, fontSize: 13, padding: '11px 20px' }}>
                  Send another
                </button>
              </div>
            )}
          </div>

          {/* ASIDE */}
          <div>
            <Eyebrow>Direct</Eyebrow>
            <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 16, color: 'var(--charcoal)', lineHeight: 1.7, marginTop: 20 }}>
              For PFI, BSA or contract-specific enquiries, email directly. A single paragraph on what you're trying to defend is enough to start.
            </p>
            <div style={{ fontFamily: 'var(--ff-display)', fontSize: 22, color: 'var(--teal)', letterSpacing: '-0.01em', marginTop: 12 }}>
              hello@trellum.co.uk
            </div>

            <div style={{ marginTop: 40, paddingTop: 28, borderTop: '1px solid var(--stone-light)' }}>
              <Eyebrow tone="stone">Response</Eyebrow>
              <p style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 14, color: 'var(--charcoal)', lineHeight: 1.7, marginTop: 10 }}>
                Within two working days · UK business hours · no autoresponders.
              </p>
            </div>

            <div style={{ marginTop: 32, paddingTop: 28, borderTop: '1px solid var(--stone-light)' }}>
              <Eyebrow tone="stone">Useful to include</Eyebrow>
              <ul style={{ fontFamily: 'var(--ff-body)', fontWeight: 300, fontSize: 14, color: 'var(--charcoal)', lineHeight: 1.75, paddingLeft: 18, marginTop: 10 }}>
                <li>Contract reference or building address</li>
                <li>Duty-holder role or counter-party</li>
                <li>The question you actually want answered</li>
              </ul>
            </div>
          </div>
        </div>
      </section>
    </Page>
  );
};

Object.assign(window, { PFI, Block, Approach, Contact });
