const {
  HexGrid, SiteNav, SiteFooter, PageShell, FAQList, CloseCTA,
  ConnectedFlow, Screen, contactHref,
} = window.GS;

const PhoneIcon = ({ size = 16 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" aria-hidden="true">
    <path d="M7 3.8h2.1c.4 0 .7.3.8.6l.7 2.4c.1.4 0 .8-.3 1L9 9.1a11 11 0 0 0 5.9 5.9l1.3-1.3c.3-.3.7-.4 1-.3l2.4.7c.3.1.6.4.6.8v2.1c0 1-.8 1.9-1.9 1.8C11.4 18.4 5.6 12.6 5.2 6.7 5.1 5.6 6 4.8 7 4.8V3.8z" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round" />
  </svg>
);

const DocIcon = () => (
  <svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true">
    <path d="M7 3.5h7l4 4V20a1.5 1.5 0 0 1-1.5 1.5h-9.5A1.5 1.5 0 0 1 5.5 20V5A1.5 1.5 0 0 1 7 3.5z" fill="none" stroke="currentColor" strokeWidth="1.6" />
    <path d="M14 3.5V8h4.5M8 12h8M8 16h5" fill="none" stroke="currentColor" strokeWidth="1.6" />
  </svg>
);

const PeopleIcon = () => (
  <svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true">
    <circle cx="9" cy="8" r="2.2" fill="none" stroke="currentColor" strokeWidth="1.6" />
    <circle cx="16" cy="9" r="1.8" fill="none" stroke="currentColor" strokeWidth="1.6" />
    <path d="M4.8 18.2c.6-2.4 2.4-3.7 4.2-3.7s3.6 1.3 4.2 3.7M14 14.6c1.3-.3 2.6.2 3.4 1.6" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
  </svg>
);

const PersonIcon = () => (
  <svg width="18" height="18" viewBox="0 0 24 24" aria-hidden="true">
    <circle cx="12" cy="8" r="2.4" fill="none" stroke="currentColor" strokeWidth="1.6" />
    <path d="M7 18.5c.7-2.6 2.5-3.9 5-3.9s4.3 1.3 5 3.9" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" />
  </svg>
);

const WAVE = [8, 14, 22, 12, 28, 18, 10, 34, 20, 40, 24, 32, 16, 36, 22, 28, 14, 24, 12, 18, 8, 14, 6, 10, 5, 8];

const CallDesk = () => (
  <figure className="screen call-desk" aria-label="Example workflow: an inbound absence call handled by a voice assistant, then absence recorded, cover outreach, and the agency updated. Not a live system.">
    <div className="screen-top">
      <span className="call-phone"><PhoneIcon /></span>
      <span className="call-title">Inbound Absence Call</span>
      <span className="screen-tag">Example workflow</span>
    </div>
    <div className="call-incoming">
      <div>
        <div className="col-label">Incoming call · example</div>
        <div className="call-report">Worker absence report</div>
        <div className="status-sub">Eastview · 07:00–15:00 shift</div>
      </div>
      <div className="call-phone-badge" aria-hidden="true"><PhoneIcon size={16} /></div>
    </div>
    <div className="call-assistant">
      <div className="col-label">AI Voice Assistant</div>
      <div className="call-wave" aria-hidden="true">
        {WAVE.map((height, index) => (
          <span key={index} style={{ height, opacity: index < 16 ? 1 : 0.35 }} />
        ))}
      </div>
      <div className="call-caption">
        <PhoneIcon size={12} />
        <span>Voice conversation · Absence details collected</span>
      </div>
    </div>
    <div className="call-join" aria-hidden="true"><span /></div>
    <div className="call-outcomes">
      {[
        ['Absence', 'Recorded', <DocIcon key="d" />],
        ['Cover', 'Outreach', <PeopleIcon key="p" />],
        ['Agency', 'Updated', <PersonIcon key="a" />],
      ].map(([title, detail, icon]) => (
        <div className="call-outcome" key={title}>
          <span className="call-outcome-icon">{icon}</span>
          <strong>{title}</strong>
          <span>{detail}</span>
        </div>
      ))}
    </div>
    <figcaption className="screen-cap">Illustrative workflow; replacement confirmation depends on worker availability and the configured process.</figcaption>
  </figure>
);

const Hero = () => (
  <section className="section-hero">
    <div className="hero-glow-right" aria-hidden="true" />
    <HexGrid opacity={0.05} id="hex-absence" />
    <div className="split relative">
      <div>
        <div className="eyebrow">
          <span className="dot" aria-hidden="true" />
          Absence Management for recruitment agencies
        </div>
        <h1 className="h1">Absence Management Software for Recruitment Agencies.</h1>
        <p className="statement">Every Absence Call Answered. Without Interrupting Your Consultants.</p>
        <p className="lede">
          Your AI-powered absence management assistant answers incoming calls, collects absence details and coordinates the next steps — from identifying replacement workers to updating your team.
        </p>
        <div className="actions">
          <a className="btn-primary" href={contactHref('absence-management')}>Discuss Absence Management</a>
          <a className="btn-secondary" href="#how-it-works">See How It Works</a>
        </div>
      </div>
      <CallDesk />
    </div>
  </section>
);

const manualSteps = [
  ['01', 'Take the absence call', 'Collect the details while other work stops.'],
  ['02', 'Work out which booking is affected', 'Check the worker, shift and client details.'],
  ['03', 'Find possible replacement workers', 'Review availability, suitability and who can cover.'],
  ['04', 'Contact and chase for cover', 'Call, message and follow up until someone responds.'],
  ['05', 'Update the record and inform the client', 'Log the outcome and communicate what happens next.'],
];

const Problem = () => (
  <section className="section section-alt" aria-labelledby="problem-title">
    <div className="split-even problem-split">
      <div className="problem-copy">
        <div className="kicker">The problem</div>
        <h2 className="h2" id="problem-title">Your Consultants Should Be Making Placements. Not Managing Absence Calls.</h2>
        <p className="lede">
          When a worker reports an absence, your consultants can end up answering calls, identifying affected shifts, searching for replacement workers, chasing confirmations and updating clients.
        </p>
        <p className="problem-point">That&apos;s time spent on administration instead of filling vacancies, developing client relationships and generating revenue.</p>
      </div>
      <article className="card problem-flow" aria-label="A typical manual absence process">
        <p className="problem-flow-label">The manual process</p>
        <h3>One Absence. Multiple Admin Tasks.</h3>
        <ol>
          {manualSteps.map(([n, title, text]) => (
            <li key={n}>
              <span className="problem-num">{n}</span>
              <div>
                <strong>{title}</strong>
                <p>{text}</p>
              </div>
            </li>
          ))}
        </ol>
        <p className="problem-cost">The real cost is not just the absence. <span>It&apos;s the consultant time used to manage everything around it.</span></p>
      </article>
    </div>
  </section>
);

const Solution = () => (
  <section className="section" aria-labelledby="solution-title">
    <div className="kicker">The solution</div>
    <h2 className="h2" id="solution-title">A Recorded Workflow, With People Where the Decision Sits.</h2>
    <div className="grid-2 mt-32 solution-grid">
      <article className="card solution-auto">
        <h3>Handled Automatically</h3>
        <div className="solution-bits">
          <div className="solution-bit">
            <strong>Capture &amp; match</strong>
            <p>The system records the absence and matches it to the correct worker, shift and booking information.</p>
          </div>
          <div className="solution-bit">
            <strong>Replacement outreach</strong>
            <p>Eligible replacement workers are contacted through the channels your agency has configured.</p>
          </div>
          <div className="solution-bit">
            <strong>Record &amp; route</strong>
            <p>Actions and outcomes are written back to the record, with exceptions passed on only when needed.</p>
          </div>
        </div>
        <p className="solution-line">Routine handling is automated before anyone on your team needs to step in.</p>
      </article>
      <article className="card card-accent">
        <h3>Your Team Stays in Control</h3>
        <p>The system handles the repetitive calls, replacement outreach and follow-ups. When a decision is needed, your consultant receives a clear summary and a simple approval request — rather than having to chase workers, make multiple calls or manually coordinate every step.</p>
        <p className="solution-line">The system does the legwork. Your team makes the decisions.</p>
        <figure className="approval-example" aria-label="Illustrative approval request. Not a live control.">
          <div className="approval-top">
            <span>Example approval</span>
            <span className="screen-tag">Illustrative</span>
          </div>
          <div className="approval-detail">
            <strong>Proposed replacement</strong>
            <span>Available worker · Eastview · 07:00–15:00</span>
          </div>
          <div className="approval-actions" aria-hidden="true">
            <span className="btn-primary">Approve</span>
            <span className="btn-secondary">Review</span>
          </div>
        </figure>
      </article>
    </div>
  </section>
);

const stages = [
  { n: '01', title: 'Notify', text: 'The worker reports the absence by phone or another channel the agency has set up.' },
  { n: '02', title: 'Capture', text: 'Reason, timing and any questions you require are stored against the notification.' },
  { n: '03', title: 'Identify', text: 'The relevant shift and worker record are checked from the information available to the system.' },
  { n: '04', title: 'Search', text: 'Eligible replacement workers are identified using the rules and availability data you supply.' },
  { n: '05', title: 'Contact', text: 'Those workers are contacted on the channels configured for that workflow.' },
  { n: '06', title: 'Update', text: 'A confirmation, an open shift or an exception is recorded and routed to the right people.' },
];

const How = () => (
  <section className="section section-alt" id="how-it-works" aria-labelledby="how-title">
    <div className="kicker">How it works</div>
    <h2 className="h2" id="how-title">From Notification to a Recorded Outcome.</h2>
    <p className="lede mt-16">
      Each stage can be adjusted. Contacting a replacement is not the same as filling the shift. If nobody suitable confirms, the shift stays open and a person takes the case.
    </p>
    <ConnectedFlow steps={stages} />
  </section>
);

const capabilities = [
  ['Inbound reporting', 'Workers can report an absence without waiting for a coordinator to pick up, on the number or channel you assign.'],
  ['Language support', 'Where the voice service supports it, a call can be handled in more than one language. That is configured per workflow, not assumed for every caller.'],
  ['Replacement coordination', 'Eligible workers are contacted from the shift and availability information the system can see.'],
  ['Configurable notifications', 'Managers, clients or coordinators can be notified at the points you choose.'],
  ['Audit record', 'The report, questions, contact attempts and outcome are kept together so the team can see what happened.'],
  ['Escalation', 'Unconfirmed cover, missing data or a rule that needs approval is passed to a member of staff with the context attached.'],
];

const weekMarks = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
const markedDays = new Set(['Mon', 'Tue', 'Thu']);

const InsightIcon = ({ d }) => (
  <svg width="16" height="16" viewBox="0 0 24 24" aria-hidden="true">
    <path d={d} fill="none" stroke="#f5b544" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
  </svg>
);

const InsightDesk = () => (
  <figure className="screen insight-desk" aria-label="Illustrative absence intelligence. Not a live dashboard, and not a client’s results.">
    <div className="screen-top">
      <InsightIcon d="M4 19 V10 M10 19 V5 M16 19 V13 M22 19 H2" />
      <strong>Absence Intelligence</strong>
      <span className="screen-tag">Illustrative</span>
    </div>
    <div className="insight-areas">
      <div className="insight-area">
        <h3><InsightIcon d="M4 16c2-6 4-6 6 0s4 6 6 0 4-6 6 0" /> Recurring absence patterns</h3>
        <div className="insight-week" aria-hidden="true">
          {weekMarks.map((day) => (
            <span key={day} className={markedDays.has(day) ? 'is-marked' : ''}>{day}</span>
          ))}
        </div>
        <p className="insight-hint">Example marks for early shifts. Not a measured week.</p>
        <ul>
          <li>Short-notice absences that repeat</li>
          <li>Grouped by shift, site and day</li>
          <li>Change across the records already kept</li>
        </ul>
      </div>
      <div className="insight-area">
        <h3><InsightIcon d="M12 21s7-6.2 7-11a7 7 0 1 0-14 0c0 4.8 7 11 7 11z M12 10.5h.01" /> Shift and site</h3>
        <ul>
          <li>Shifts that keep needing emergency cover</li>
          <li>Sites with repeated disruption</li>
          <li>Hours that may need a stronger reserve</li>
          <li>Shortages worth a planning review</li>
        </ul>
      </div>
      <div className="insight-area">
        <h3><InsightIcon d="M5 12h14 M13 6l6 6-6 6" /> Replacement</h3>
        <ul>
          <li>Cover requests started</li>
          <li>Confirmed, still open, or with staff</li>
          <li>Replies recorded against each request</li>
          <li>Where a standby pool could help</li>
        </ul>
      </div>
    </div>
    <div className="insight-scenario">
      <div className="auto-label">Example operational insight</div>
      <strong>Repeated short-notice absences affecting early shifts at Client Site A.</strong>
      <div className="auto-label">Suggested response</div>
      <p>Develop a dedicated standby worker pool and review shift-cover arrangements with the client.</p>
    </div>
    <figcaption className="screen-cap">
      An illustration of what can be read from the absence, shift, contact attempts and outcome already kept. Not a live analytics view, and not a client result. A named worker’s history would stay with authorised staff, and would not be treated as a conclusion about health or conduct.
    </figcaption>
  </figure>
);

const partnerPoints = [
  'Identify problems before they become persistent client complaints.',
  'Hold more informed client review meetings.',
  'Recommend improved shift-cover arrangements.',
  'Demonstrate attentiveness to operational challenges.',
  'Build confidence in the agency’s management of temporary workforces.',
];

const Insights = () => (
  <section className="section" id="insights" aria-labelledby="insight-title">
    <div className="insight-split">
      <div>
        <div className="kicker">Insights &amp; intelligence</div>
        <h2 className="h2" id="insight-title">Turn Absence Data Into Stronger Client Relationships.</h2>
        <p className="lede">
          Every absence call creates valuable operational information. Identify recurring absence patterns, discover which shifts are repeatedly affected and understand where replacement cover is proving difficult.
        </p>
        <p className="body">
          Use those insights to address recurring problems with your clients, recommend practical improvements and demonstrate the value your agency provides.
        </p>
        <ul className="insight-benefits">
          <li>Recurring disruption, visible by shift, site and day.</li>
          <li>Cover that is repeatedly hard to confirm.</li>
          <li>A practical change to recommend, not only a record of the call.</li>
        </ul>
        <p className="insight-point">The client relationship strengthens when the conversation is about the pattern, and what to change, rather than the latest missed shift alone.</p>
      </div>
      <InsightDesk />
    </div>
    <div className="insight-close">
      <h3>From Reactive Supplier to Proactive Recruitment Partner.</h3>
      <p>Give clients evidence of recurring staffing challenges and bring practical solutions to account reviews, instead of discussing individual missed shifts in isolation.</p>
      <div className="insight-points">
        {partnerPoints.map((point) => (
          <article className="card" key={point}><p>{point}</p></article>
        ))}
      </div>
      <article className="card insight-report">
        <div className="insight-report-top">
          <h3>Client account summaries</h3>
          <span className="screen-tag">Scoped with you</span>
        </div>
        <p>A periodic summary for an account review can be prepared from these records: trends over the period, the shifts affected most often, replacement outcomes, recurring bottlenecks, and the improvements you recommend. Producing that pack is part of the scope agreed with the agency. It is not an automated report already running, and it would not include a worker’s health detail.</p>
      </article>
    </div>
  </section>
);

const Capabilities = () => (
  <section className="section" aria-labelledby="cap-title">
    <div className="kicker">Capabilities</div>
    <h2 className="h2" id="cap-title">What the System Is Built to Handle.</h2>
    <div className="grid-3 mt-40">
      {capabilities.map(([title, text]) => (
        <article className="card" key={title}>
          <h3>{title}</h3>
          <p>{text}</p>
        </article>
      ))}
    </div>
  </section>
);

const StatusPanel = () => (
  <Screen
    label="Cover status"
    caption="Example statuses for illustration. A shift is not treated as filled until a replacement is confirmed."
  >
    <div className="stack">
      <div className="status-row ok">
        <div>
          <div className="status-title">Absence recorded</div>
          <div className="status-sub">Eastview · 07:00–15:00 · today · reason captured</div>
        </div>
      </div>
      <div className="status-row">
        <div>
          <div className="status-title">Replacement contact in progress</div>
          <div className="status-sub">Eligible workers contacted · waiting for a confirmation</div>
        </div>
      </div>
      <div className="status-row">
        <div>
          <div className="status-title">Escalation if nobody confirms</div>
          <div className="status-sub">Coordinator receives the record and the contact attempts</div>
        </div>
      </div>
    </div>
  </Screen>
);

const exampleSteps = [
  ['Call matched', 'Worker, shift and timing identified'],
  ['Cover workflow started', 'Eligible workers contacted'],
  ['Outcome recorded', 'Staff updated or escalation triggered'],
];

const Example = () => (
  <section className="section section-alt" aria-labelledby="example-title">
    <div className="split-even example-top">
      <div>
        <div className="kicker">A realistic example</div>
        <h2 className="h2" id="example-title">One Morning Absence, Handled From Call to Cover.</h2>
        <p className="lede">
          A worker calls before a morning shift and says they cannot attend. The system matches the absence to the correct booking, records the details and starts the next steps based on the agency’s configured process.
        </p>
        <ul className="example-steps">
          {exampleSteps.map(([title, text]) => (
            <li key={title}><strong>{title}</strong> — {text}</li>
          ))}
        </ul>
      </div>
      <StatusPanel />
    </div>
  </section>
);

const Benefits = () => (
  <section className="section" aria-labelledby="benefits-title">
    <div className="kicker">Operational benefits</div>
    <h2 className="h2" id="benefits-title">Clearer Handling of the Same Work.</h2>
    <div className="grid-4 mt-40">
      {[
        ['Less administrative handling', 'The first questions and the contact sequence do not all sit with a coordinator.'],
        ['More consistent recording', 'Reason, shift and outcome are stored in the same place each time.'],
        ['Quicker notification', 'The people who need to know can be told when the report arrives, not after a voicemail is found.'],
        ['Visibility of open cover', 'Outstanding shifts stay on a status list instead of in a personal notebook.'],
      ].map(([title, text]) => (
        <article className="card" key={title}>
          <h3>{title}</h3>
          <p>{text}</p>
        </article>
      ))}
    </div>
    <div className="actions">
      <a className="btn-primary" href={contactHref('absence-management')}>Discuss Absence Management</a>
    </div>
  </section>
);

const Integrations = () => (
  <section className="section section-alt" aria-labelledby="int-title">
    <div className="split-even">
      <div>
        <div className="kicker">Integrations</div>
        <h2 className="h2" id="int-title">Connected Where Access Exists.</h2>
        <p className="lede mt-16">
          Absence Management can be scoped against a worker database, a rota, an ATS or another operational tool. A connection is only promised once we have confirmed how that system can be reached.
        </p>
        <p className="body mt-16">
          Scheduling and the wider operational picture sit with <a className="text-link" href="/agency-operations.html">Agency Operations</a>. Absence Management is the workflow for the absence itself.
        </p>
      </div>
      <ul className="list">
        {[
          'Worker and availability records the agency can provide.',
          'Rota or scheduling data, where an export or integration exists.',
          'Notifications into the inboxes or systems your coordinators already use.',
          'A written record your team can review after the event.',
        ].map((item) => <li key={item}>{item}</li>)}
      </ul>
    </div>
  </section>
);

const Audience = () => (
  <section className="section" aria-labelledby="who-title">
    <div className="kicker">Who it is for</div>
    <h2 className="h2" id="who-title">Shift-Based Recruitment Teams.</h2>
    <p className="lede mt-16">Agencies where a missed absence call becomes a missed shift.</p>
    <div className="grid-4 mt-40">
      {[
        ['Industrial staffing', 'Temporary and site-based workers, with cover needed before a shift starts.'],
        ['Healthcare staffing', 'Care and clinical bookings where the client still needs to be informed.'],
        ['Logistics and driving', 'Early starts and depot shifts that cannot wait for the office to open.'],
        ['Other shift-based desks', 'Any recruitment operation that coordinates named workers against a rota.'],
      ].map(([title, text]) => (
        <article className="card" key={title}>
          <h3>{title}</h3>
          <p>{text}</p>
        </article>
      ))}
    </div>
  </section>
);

const Pricing = () => (
  <section className="section section-alt" aria-labelledby="price-title">
    <div className="narrow">
      <div className="kicker">Pricing</div>
      <h2 className="h2" id="price-title">Scoped to the Operation, Not a Flat Rate.</h2>
      <p className="lede mt-16">
        Commercial terms depend on the shape of the workflow. We quote after a short discussion. There is no standard price list on this page.
      </p>
    </div>
    <div className="grid-3 mt-40">
      {[
        ['Workforce and volume', 'How many workers report absence, and how often the line is used.'],
        ['Integrations', 'Which rota, database or messaging tools need to be connected, and how access is granted.'],
        ['Workflow and support', 'Approval rules, escalation paths, languages and the level of ongoing support.'],
      ].map(([title, text]) => (
        <article className="card" key={title}>
          <h3>{title}</h3>
          <p>{text}</p>
        </article>
      ))}
    </div>
  </section>
);

const faqs = [
  ['Can workers report an absence outside office hours?', 'The reporting channel can stay available outside the hours you choose. What happens next — a contact sequence, a queued task, or an escalation — is part of the configuration.'],
  ['Does it already know our workers?', 'It uses the worker, shift and availability information you make available. It does not invent people who are not on that record.'],
  ['What if a person needs to approve the cover?', 'The workflow stops at that approval, shows the context, and waits. A replacement is not treated as confirmed until the rule you set has been met.'],
  ['Will it integrate with our rota or ATS?', 'Only where that system provides a usable route in. We confirm access before including a connection in the scope.'],
  ['Can our team still handle a case themselves?', 'Yes. Staff can review, take over or close a case. The report and the attempts remain on the record.'],
  ['How is it deployed?', 'Discovery, configuration, testing with your scenarios, then launch. The timetable is agreed from the scope. It is not the same length for every agency.'],
];

function AbsencePage() {
  return (
    <PageShell>
      <SiteNav active="Absence Management" />
      <main id="content">
        <Hero />
        <Problem />
        <Solution />
        <How />
        <Insights />
        <Capabilities />
        <Example />
        <Benefits />
        <Integrations />
        <Audience />
        <Pricing />
        <section className="section" aria-labelledby="faq-title">
          <div className="kicker">Questions</div>
          <h2 className="h2" id="faq-title">Absence Management Questions</h2>
          <FAQList items={faqs} />
        </section>
        <CloseCTA
          title="See It Against Your Rota."
          text="Tell us how absence cover works today. We will map the workflow and where a person still needs to decide."
          primary={{ href: contactHref('absence-management'), label: 'Discuss Absence Management' }}
          secondary={{ href: '/agency-operations.html', label: 'Explore Agency Operations' }}
        />
      </main>
      <SiteFooter />
    </PageShell>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<AbsencePage />);
