/* global React, Icon, SectionHead, MegaFooter, ContactStatus */
const { useState: useStateRentals, useEffect: useEffectRentals } = React;

// ===================================================================
// Rentals — sub-routed
// ===================================================================
// `/rentals`               → RentalsLanding (hero + reviews + FAQ)
// `/rentals/equipment`     → EquipmentPage (Booqable widgets, native)
// `/rentals/contact`       → RentalsContactPage
// `/rentals/open-account`  → OpenAccountPage (slim hero + Notion form)
//
// All sub-pages share the `rentals-light` chrome (light theme, rentals
// nav, rentals footer). The big hero only appears on the landing —
// every sub-page gets its own slim VR—XX header so it feels distinct.
//
// The Booqable JS widget script is loaded on every rentals route via
// `useBooqable()` so the floating cart persists as users move between
// the landing, equipment, FAQs, contact and open-account pages.
// ===================================================================

const BOOQABLE_SRC = 'https://ff981641-1ae6-4700-9720-0b8c06579658.assets.booqable.com/v2/booqable.js';

function useBooqable() {
  const [status, setStatus] = useStateRentals('loading');
  useEffectRentals(() => {
    const existing = document.querySelector(`script[src="${BOOQABLE_SRC}"]`);
    if (existing) {
      setStatus(existing.dataset.bqStatus || 'loaded');
      return;
    }
    const s = document.createElement('script');
    s.src = BOOQABLE_SRC;
    s.async = true;
    s.onload = () => { s.dataset.bqStatus = 'loaded'; setStatus('loaded'); };
    s.onerror = () => { s.dataset.bqStatus = 'error'; setStatus('error'); };
    document.head.appendChild(s);
    const t = setTimeout(() => setStatus((p) => p === 'loading' ? 'error' : p), 8000);
    return () => clearTimeout(t);
  }, []);
  return status;
}


const FAQ = [
{
  q: 'Business hours',
  a: 'Staffed hours (someone at the desk for calls, emails and live booking support): Mon–Fri 09:00–17:00, weekends closed, bank holidays closed. Collection & returns (when you can pick kit up or drop it back): Mon–Fri 08:30–18:00, Sat 08:30–17:00, Sun 10:00–16:00, bank holidays by arrangement. Outside collection hours we can usually still accommodate, subject to technician availability — flat £25 per collection or return. Confirm the day before via WhatsApp.',
  aBody: (
    <>
      <p><strong>Staffed hours</strong> — when the team is at the desk for calls, emails and live booking support:</p>
      <ul className="faq-list">
        <li>Mon–Fri · 09:00–17:00</li>
        <li>Sat–Sun · Closed</li>
        <li>Bank holidays · Closed</li>
      </ul>
      <p style={{ marginTop: 14 }}><strong>Collection &amp; returns</strong> — when you can pick kit up or drop it back at the studio:</p>
      <ul className="faq-list">
        <li>Mon–Fri · 08:30–18:00</li>
        <li>Saturday · 08:30–17:00</li>
        <li>Sunday · 10:00–16:00</li>
        <li>Bank holidays · By arrangement</li>
      </ul>
      <p style={{ marginTop: 14 }}><strong>After hours</strong> — outside the collection window we can usually still accommodate, subject to technician availability. Flat <strong>£25</strong> per out-of-hours collection or return. Confirm the day before via WhatsApp.</p>
    </>
  )
},
{
  q: 'Address & parking',
  a: 'Access House, 207-211 The Vale, London W3 7QS. Free on-site parking during collections, returns, and kit prep. Acton Central Station is a five-minute walk.',
  link: { url: 'https://www.google.com/maps/search/?api=1&query=Access+House+207-211+The+Vale+Acton+London+W3+7QS', label: 'Open in Google Maps →' }
},
{
  q: 'Hire periods & late returns',
  a: 'A standard single-day hire means collection after 3pm the previous day and return by 11am the following day — that overnight window is included in the day rate. Multi-day hires follow the same structure. Saturday + Sunday counts as a single hire day. Returns after 11am are charged at a full additional day rate.'
},
{
  q: 'Who can rent from us?',
  a: 'Production companies, agencies, and freelance crew. First-time direct clients complete a quick verification: photo ID held next to face, two recent proofs of address (PDF, dated within 3 months), and two trade references from custom-domain (non-Gmail) email addresses.'
},
{
  q: 'Payment & accounts',
  a: 'New direct clients book on a Cash Account: full payment in advance via bank transfer or card before any kit is prepped. After a successful first hire you can move to a Credit Account with 30-day terms (invoices over £250 default to 30 days; smaller invoices stay payment-on-collection until a track record is established). Hire-in insurance covering the full replacement value of the kit is required — happy to recommend brokers if you need one.'
},
{
  q: 'Collection & delivery',
  a: 'Collect from our Acton studio within staffed hours. Driven delivery within the M25 is £45 per hour, central London congestion zone is £65 per hour, small deliveries under 10kg are £25 per hour — time is calculated on a return-trip basis. Nationwide courier on request. Weekend slots are limited — book early.'
},
{
  q: 'Prep & checkout',
  a: 'Every kit is bench-tested, projected (lenses), and packed by our techs before it leaves the building. We don\'t have a prep space on-site for clients — if you need one, get in touch and we\'ll see if we can work something out.'
},
{
  q: 'Minimum order size',
  a: 'Every booking has a £25 minimum spend. Worth knowing before you build a single-item list — sometimes it\'s cheaper to add a second item than meet the minimum on one.'
},
{
  q: 'Damage, loss & cancellations',
  a: 'The renter is liable for any damage, loss or theft of the kit while it is in their care. Hire-in insurance covering the full replacement value is required on every booking. Accidental damage is invoiced via Booqable with photos; items not returned within 24 hours of the scheduled return are invoiced at full replacement value. Cancellation: free more than 14 days before pickup, 50% of the rental value 48 hours to 14 days before, non-refundable inside 48 hours.',
  aBody: (
    <>
      <p>The renter is liable for any damage, loss or theft of the kit while it is in their care. Hire-in insurance covering the full replacement value of the kit is required on every booking — happy to recommend brokers if you need one.</p>
      <p style={{ marginTop: 12 }}>Accidental damage is invoiced through Booqable with photos so you can pass it to your insurer. Items not returned within 24 hours of the scheduled return are invoiced at full replacement value.</p>
      <p style={{ marginTop: 12 }}><strong>Cancellations</strong></p>
      <table className="faq-table">
        <thead>
          <tr><th>Cancellation window</th><th>Charge</th></tr>
        </thead>
        <tbody>
          <tr><td>More than 14 days before pickup</td><td>Free</td></tr>
          <tr><td>48 hours to 14 days before pickup</td><td>50% of rental value</td></tr>
          <tr><td>Within 48 hours of pickup</td><td>Non-refundable</td></tr>
        </tbody>
      </table>
    </>
  )
}];


// ===================================================================
// Slim per-page hero — used by every sub-page.
// ===================================================================
function RentalsSubHero({ idx, label, title, lead }) {
  return (
    <section className="rentals-subhero">
      <div className="container">
        <div className="eyebrow"><span className="idx">{idx}</span> {label}</div>
        <h1 dangerouslySetInnerHTML={{ __html: title }} />
        {lead && <p className="lead">{lead}</p>}
      </div>
    </section>);

}

// ===================================================================
// /rentals — landing page (big hero + 4 cards)
// ===================================================================
// ===================================================================
// Reviews — Google reviews shown as a 3-up grid of cards. Each card
// links to Google Maps reviews; the bottom CTA opens the full list.
// REVIEWS_TOTAL is the count Google shows for the listing (update as
// more reviews come in). To swap the featured three, replace entries
// in REVIEWS with text from the Google review you want surfaced.
// ===================================================================
const GOOGLE_REVIEWS_URL = 'https://www.google.com/maps/place/Valley+Rentals/@51.5061014,-0.2620762,17z/data=!4m8!3m7!1s0x48760f2a724d1c33:0xaa5d67f6abb38bfc!8m2!3d51.5060981!4d-0.2595013!9m1!1b1!16s%2Fg%2F11vbw9dmpt';
const REVIEWS_TOTAL = 10;

const REVIEWS = [
{
  author: 'Fenton Dyer',
  rating: 5,
  date: '2 years ago',
  text: "I had a top tier experience with Valley Rentals. Friendly and clear communication, fair prices, and easy to pick up and drop off. Glad to say this is everything you'd want from a rental house!",
  url: ''
},
{
  author: 'Mark Winterlin',
  rating: 5,
  date: '2 months ago',
  text: 'Valley Rentals is my go-to kit hire company. They have excellent service, are always responsive and take the initiative to tackle any problems, and Max and the team are always lovely to work with. Highly recommended!',
  url: ''
},
{
  author: 'Ben Stewart',
  rating: 5,
  date: 'a year ago',
  text: 'Max is super knowledgeable and helpful with the kit he rents out, and the kit is in pristine condition. He is reasonably priced, and very organised with quotes and expectations. Would definitely rent from him again!',
  url: ''
}];


// Single-star SVG — filled-vs-empty driven by parent class. We render
// 5 stars per card and toggle the .filled class up to `rating`.
function ReviewStar({ filled }) {
  return (
    <svg className={`rr-star ${filled ? 'filled' : ''}`} viewBox="0 0 20 20" width="14" height="14" aria-hidden="true">
      <path d="M10 1.5l2.6 5.3 5.9.85-4.25 4.15.99 5.85L10 14.9 4.76 17.65l.99-5.85L1.5 7.65l5.9-.85L10 1.5z" fill="currentColor" />
    </svg>);

}

function ReviewsSection() {
  return (
    <section className="rentals-reviews">
      <div className="container">
        <div className="rr-head">
          <div className="eyebrow"><span className="idx">T—01</span> What clients say</div>
          <h2>Reviewed on <em>Google</em>.</h2>
          <div className="rr-summary">
            <span className="rr-stars-row" aria-label="5 out of 5 stars">
              {Array.from({ length: 5 }, (_, i) => <ReviewStar key={i} filled />)}
            </span>
            <span className="rr-summary-num">5.0</span>
            <span className="rr-summary-source">· {REVIEWS_TOTAL} reviews on Google</span>
          </div>
        </div>

        <div className="rr-grid">
          {REVIEWS.map((r, i) =>
          <a
            key={i}
            href={r.url || GOOGLE_REVIEWS_URL}
            target="_blank"
            rel="noopener noreferrer"
            className="rr-card"
            data-hover="Read">
              <span className="rr-stars-row" aria-label={`${r.rating} out of 5 stars`}>
                {Array.from({ length: 5 }, (_, k) => <ReviewStar key={k} filled={k < r.rating} />)}
              </span>
              <p className="rr-text">{r.text}</p>
              <div className="rr-author-row">
                <span className="rr-author">{r.author}</span>
                {r.date && <span className="rr-date">{r.date}</span>}
              </div>
            </a>
          )}
        </div>

        <div className="rr-cta">
          <a href={GOOGLE_REVIEWS_URL} target="_blank" rel="noopener noreferrer" className="rr-cta-link" data-hover="Open">
            See all reviews on Google
            <Icon name="arrow-up-right" size={14} />
          </a>
        </div>
      </div>
    </section>);

}

// ===================================================================
// /rentals — landing page (hero, reviews, FAQ, footer). Mirrors the
// flow of the films home: editorial sections rather than a card grid.
// ===================================================================
// Hero photo carousel — cycles through the rentals photo library on the
// landing page. Cross-fade between the current and next slot every
// CYCLE_MS; the next index is computed off the previous to avoid jumps
// if React re-renders mid-interval.
const HERO_PHOTOS = [
  'assets/valley_rentals/IMG_5258.JPG',
  'assets/valley_rentals/IMG_9582.jpeg',
  'assets/valley_rentals/IMG_8033.JPG',
  'assets/valley_rentals/IMG_9088.JPG',
  'assets/valley_rentals/IMG_0526.JPG',
  'assets/valley_rentals/classicu-2026-01-26.jpg',
  'assets/valley_rentals/classicu-2026-02-03.jpg'
];
const HERO_CYCLE_MS = 5200;

// Shelf strip — horizontal photo row used inside the redesigned VR—02
// section. Different selection than the hero so the page doesn't repeat
// the same shots back-to-back. Click any thumbnail to open the lightbox.
const SHELF_STRIP_PHOTOS = [
  'assets/valley_rentals/IMG_2879.JPG',
  'assets/valley_rentals/IMG_8033.JPG',
  'assets/valley_rentals/IMG_9088.JPG',
  'assets/valley_rentals/classicu-2026-02-03.jpg'
];

function RentalsLanding({ onGoto }) {
  // Controlled-accordion state — only one FAQ open at a time. Mirrors the
  // pattern used by ServicesAccordion on the films home so the reveal
  // animation can use grid-template-rows: 0fr → 1fr instead of <details>'
  // discrete toggle. First item open by default for affordance.
  const [openFaq, setOpenFaq] = useStateRentals(0);
  // Hover-driven on devices with a fine pointer; click stays as the
  // fallback for keyboards and touch screens. matchMedia gate prevents
  // the open-then-instantly-close flicker when a tap synthesises both
  // mouseenter and click on iOS/Android.
  const [hoverOpens, setHoverOpens] = useStateRentals(false);
  React.useEffect(() => {
    const m = window.matchMedia('(hover: hover) and (pointer: fine)');
    const apply = () => setHoverOpens(m.matches);
    apply();
    m.addEventListener ? m.addEventListener('change', apply) : m.addListener(apply);
    return () => { m.removeEventListener ? m.removeEventListener('change', apply) : m.removeListener(apply); };
  }, []);

  // Hero carousel index. Two background layers rendered; we toggle which
  // shows the "current" photo by alternating opacity for a smooth cross-
  // fade. Paused if the user prefers reduced motion.
  const [heroIdx, setHeroIdx] = useStateRentals(0);
  React.useEffect(() => {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    const id = setInterval(() => setHeroIdx((i) => (i + 1) % HERO_PHOTOS.length), HERO_CYCLE_MS);
    return () => clearInterval(id);
  }, []);
  const nextHeroIdx = (heroIdx + 1) % HERO_PHOTOS.length;

  // Shelf-strip lightbox — opens a full-bleed view of any clicked photo.
  // Escape closes it; body scroll is locked while open.
  const [lightboxSrc, setLightboxSrc] = useStateRentals(null);
  React.useEffect(() => {
    if (!lightboxSrc) return;
    const onKey = (e) => { if (e.key === 'Escape') setLightboxSrc(null); };
    window.addEventListener('keydown', onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = prevOverflow; };
  }, [lightboxSrc]);

  return (
    <main className="page active rentals-light" data-screen-label="03b Rentals">

      {/* FAQPage structured data — surfaces in Google search results.
          The FAQ accordion now lives on the home page, so the schema
          ships from here too. */}
      <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify({
        "@context": "https://schema.org",
        "@type": "FAQPage",
        "mainEntity": FAQ.map((f) => ({
          "@type": "Question",
          "name": f.q,
          "acceptedAnswer": { "@type": "Answer", "text": f.a }
        }))
      }) }} />

      <section className="rentals-hero rentals-hero-cycle">
        <div className="rentals-hero-photos" aria-hidden="true">
          {HERO_PHOTOS.map((src, i) => (
            <div
              key={src}
              className={`rhp-slide${i === heroIdx ? ' is-current' : ''}`}
              style={{ backgroundImage: `url(${src})` }} />
          ))}
        </div>
        <div className="rentals-hero-veil" aria-hidden="true" />
        <div className="rentals-hero-blob" />
        <div className="container">
          <div className="eyebrow"><span className="idx">VR—01</span> Valley Rentals</div>
          <h1>Studio kit, <em>ready</em><br />when you are.</h1>
          <p className="lead">A working rental shelf out of our East Acton location — the same camera, lens and lighting packages we shoot with day-to-day. Hand-checked, prep included, no faff.</p>
          <div className="rentals-hero-stats">
            <div className="stat"><div className="num">230+</div><div className="lbl">Equipment items</div></div>
            <div className="stat"><div className="num">2hr</div><div className="lbl">Same-day prep window</div></div>
            <div className="stat"><div className="num">W3</div><div className="lbl">Acton, London</div></div>
          </div>
        </div>
      </section>

      <section className="rentals-shelf">
        <div className="container rentals-shelf-head">
          <div className="eyebrow"><span className="idx">VR—02</span> The shelf</div>
          <div className="rentals-shelf-grid">
            <h2>The same camera, lens and lighting we <em>shoot with</em> day-to-day.</h2>
            <div className="rentals-shelf-body">
              <p>Every box on the shelf has earned its place on a Valley shoot first. If it isn't reliable enough for our own crew, it isn't reliable enough to send out.</p>
              <p>Prep is included on every booking, batteries come charged, cards come formatted, and there's a real person at the desk to talk through anything unusual about your shoot.</p>
              <a href="/rentals/equipment" className="rentals-shelf-cta" data-hover="Browse">Browse the shelf <Icon name="arrow-up-right" /></a>
            </div>
          </div>
        </div>
        <div className="rentals-shelf-strip">
          {SHELF_STRIP_PHOTOS.map((src) => (
            <button
              key={src}
              type="button"
              className="rss-card"
              aria-label="Open larger view"
              onClick={() => setLightboxSrc(src)}>
              <div className="rss-photo" style={{ backgroundImage: `url(${src})` }} />
            </button>
          ))}
        </div>
      </section>

      {lightboxSrc && (
        <div
          className="rentals-lightbox"
          role="dialog"
          aria-modal="true"
          aria-label="Photo preview"
          onClick={() => setLightboxSrc(null)}>
          <img src={lightboxSrc} alt="" />
          <button
            type="button"
            className="rentals-lightbox-close"
            aria-label="Close preview"
            onClick={(e) => { e.stopPropagation(); setLightboxSrc(null); }}>
            <Icon name="close" size={16} />
          </button>
        </div>
      )}

      <ReviewsSection />

      <section id="faqs" className="rentals-faq">
        <div className="container">
          <SectionHead idx="VR—01" label="Rental SOP · FAQ" title="The <em>useful</em><br/>fine print." />
          <div className="faq-grid">
            {FAQ.map((f, i) => {
              const isOpen = openFaq === i;
              const toggle = () => setOpenFaq(isOpen ? -1 : i);
              return (
                <div
                  key={i}
                  className={`faq-item${isOpen ? ' is-open' : ''}`}
                  onMouseEnter={hoverOpens ? () => setOpenFaq(i) : undefined}
                  onMouseLeave={hoverOpens ? () => setOpenFaq((prev) => prev === i ? -1 : prev) : undefined}
                  data-hover={isOpen ? 'Close' : 'Open'}>
                  <button
                    type="button"
                    className="faq-head"
                    aria-expanded={isOpen}
                    onClick={toggle}>
                    <span className="faq-num">{String(i + 1).padStart(2, '0')}</span>
                    <span className="faq-q">{f.q}</span>
                    <span className="faq-toggle" aria-hidden="true"><Icon name="plus" size={14} /></span>
                  </button>
                  <div className="faq-body">
                    <div className="faq-body-inner">
                      <div className="faq-a">{f.aBody ? f.aBody : f.a}{f.link && <> <a href={f.link.url} target="_blank" rel="noopener noreferrer" className="faq-link">{f.link.label}</a></>}</div>
                    </div>
                  </div>
                </div>);

            })}
          </div>
        </div>
      </section>

      <MegaFooter onGoto={onGoto} isRentals />
    </main>);

}

// ===================================================================
// /rentals/equipment — embed the hosted Booqable shop in a near-full
// screen iframe. The Valley nav stays pinned at the top; the iframe
// fills the rest of the viewport so visitors get the real booking
// experience (search, filters, dates, cart) without leaving our domain.
// ===================================================================
const BOOQABLE_SHOP_URL = 'https://valley-rentals.booqableshop.com';

function EquipmentPage({ onGoto }) {
  return (
    <main className="page active rentals-light" data-screen-label="03b Rentals · Equipment">
      <section id="equipment" className="rentals-shop-embed" aria-label="Booking shop">
        <iframe
          src={BOOQABLE_SHOP_URL}
          title="Valley Rentals — booking"
          allow="clipboard-write"
          loading="eager" />
        <p className="booqable-fallback">
          Trouble seeing the shop? Email <a href="mailto:rentals@valley.film">rentals@valley.film</a> with your dates and a kit list — we'll respond same business day.
        </p>
      </section>
    </main>);

}

// ===================================================================
// /rentals/contact — rentals-flavoured contact form
// ===================================================================
function RentalsContactPage({ onGoto }) {
  const [sent, setSent] = useStateRentals(false);
  const [sending, setSending] = useStateRentals(false);
  const [error, setError] = useStateRentals('');
  const [form, setForm] = useStateRentals({ name: '', company: '', email: '', brief: '', honeypot: '' });
  const set = (k) => (e) => setForm({ ...form, [k]: e.target.value });

  const progress = (() => {
    const has = (s) => (s || '').trim().length > 0;
    const emailOk = /\S+@\S+\.\S+/.test(form.email || '');
    const briefLen = (form.brief || '').trim().length;
    const briefScore = Math.min(1, briefLen / 80);
    const parts = [
    has(form.name) ? 1 : 0,
    has(form.company) ? 1 : 0,
    emailOk ? 1 : has(form.email) ? 0.4 : 0,
    briefScore];

    return parts.reduce((a, b) => a + b, 0) / parts.length;
  })();

  return (
    <main className="page active rentals-light" data-screen-label="03b Rentals · Contact">
      <RentalsSubHero
        idx="VR—04"
        label="Get in touch"
        title="Drop us your <em>dates</em><br/>and a kit list."
        lead="Same-day reply in working hours. For an active booking, reply to your Booqable email — that'll thread the conversation cleanly." />

      <section className="contact rentals-contact">
        <div className="container">
          <div>
            <div className="meta-block">
              <div className="meta-row">
                <div className="ico"><Icon name="mail" /></div>
                <div><div className="lbl">Email</div><a className="val val-link" href="mailto:rentals@valley.film">rentals@valley.film</a></div>
              </div>
              <div className="meta-row">
                <div className="ico"><Icon name="phone" /></div>
                <div><div className="lbl">WhatsApp</div><a className="val val-link" href="https://wa.me/message/UI5I3PDWH5Q3N1" target="_blank" rel="noopener noreferrer">+44 7771 039043</a></div>
              </div>
              <div className="meta-row">
                <div className="ico"><Icon name="instagram" /></div>
                <div><div className="lbl">Instagram</div><a className="val val-link" href="https://instagram.com/rentals.valley" target="_blank" rel="noopener noreferrer">@rentals.valley</a></div>
              </div>
              <div className="meta-row">
                <div className="ico"><Icon name="pin" /></div>
                <div><div className="lbl">Studio</div><a className="val val-link" href="https://www.google.com/maps/search/?api=1&query=Access+House+207-211+The+Vale+Acton+London+W3+7QS" target="_blank" rel="noopener noreferrer">Access House, 207–211 The Vale,<br />Acton, London W3 7QS</a></div>
              </div>
            </div>

            <div className="rentals-hours">
              <h3>Staffed hours</h3>
              <p className="rentals-hours-sub">When the team is at the desk for calls, emails and live booking support.</p>
              <dl>
                <div><dt>Mon–Fri</dt><dd>09:00 – 17:00</dd></div>
                <div><dt>Sat–Sun</dt><dd>Closed</dd></div>
                <div><dt>Bank holidays</dt><dd>Closed</dd></div>
              </dl>
            </div>

            <div className="rentals-hours">
              <h3>Collection &amp; returns</h3>
              <p className="rentals-hours-sub">When you can pick kit up or drop it back at the studio.</p>
              <dl>
                <div><dt>Mon–Fri</dt><dd>08:30 – 18:00</dd></div>
                <div><dt>Saturday</dt><dd>08:30 – 17:00</dd></div>
                <div><dt>Sunday</dt><dd>10:00 – 16:00</dd></div>
                <div><dt>Bank holidays</dt><dd>By arrangement</dd></div>
              </dl>
              <p className="rentals-hours-note">After-hours collection or return is usually available — confirm the day before via WhatsApp.</p>
            </div>
          </div>

          <div className="form-card">
            {sent ?
            <div className="contact-sent">
                <div className="check"><Icon name="check" /></div>
                <h3>Thanks — that's with us.</h3>
                <p>We'll come back to you within one business day. Reply to the email confirmation if anything urgent comes up before then.</p>
                <button className="btn-pri" style={{ marginTop: 24 }} onClick={() => setSent(false)} data-hover="New">Send another</button>
              </div> :

            <React.Fragment>
                <h3>Rental enquiry</h3>
                <p className="desc">A few lines is plenty — dates, a kit list, anything weird about the shoot.</p>
                <ContactStatus />
                <div className="step-indicator" aria-hidden="true">
                  {[0, 1, 2].map((i) => {
                  const segStart = i / 3;
                  const segEnd = (i + 1) / 3;
                  const fill = Math.max(0, Math.min(1, (progress - segStart) / (segEnd - segStart)));
                  return (
                    <div key={i} className={`dot ${fill > 0 ? 'filling' : ''}`}>
                        <span className="fill" style={{ transform: `scaleX(${fill})` }} />
                      </div>);

                })}
                </div>

                <div className="field-row">
                  <div className="field"><label>Your name</label><input value={form.name} onChange={set('name')} placeholder="Jordan Reeves" /></div>
                  <div className="field"><label>Company</label><input value={form.company} onChange={set('company')} placeholder="Company or production" /></div>
                </div>
                <div className="field-row">
                  <div className="field full"><label>Email</label><input type="email" value={form.email} onChange={set('email')} placeholder="jordan@brand.com" /></div>
                </div>

                <div className="field-row">
                  <div className="field full">
                    <label>Tell us about the shoot</label>
                    <textarea rows="4" value={form.brief} onChange={set('brief')} placeholder="Dates, kit list, anything that helps us prep cleanly." />
                  </div>
                </div>

                {/* Honeypot — hidden field. Real users leave it blank, bots fill it. */}
                <div aria-hidden="true" style={{ position: 'absolute', left: '-9999px', height: 0, overflow: 'hidden' }}>
                  <label>Don't fill this in <input type="text" tabIndex={-1} autoComplete="off" value={form.honeypot} onChange={set('honeypot')} /></label>
                </div>

                {error && <div className="form-error" role="alert">{error}</div>}

                <button className="submit" disabled={sending} onClick={async (e) => {
                e.preventDefault();
                setError('');
                if (!form.name.trim() || !form.email.trim() || !form.brief.trim()) {
                  setError('Please fill in your name, email, and a few lines about the shoot.');
                  return;
                }
                if (!/^\S+@\S+\.\S+$/.test(form.email)) {
                  setError('That email doesn\'t look right — please double-check.');
                  return;
                }
                setSending(true);
                try {
                  const resp = await fetch('/api/contact', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ ...form, kind: 'rentals' })
                  });
                  if (!resp.ok) throw new Error((await resp.json().catch(() => ({}))).error || 'Send failed');
                  setSent(true);
                } catch (err) {
                  setError('Couldn\'t send right now — please email rentals@valley.film directly.');
                } finally {
                  setSending(false);
                }
              }} data-hover="Send">
                  {sending ? 'Sending…' : <>Send enquiry <Icon name="arrow-right" /></>}
                </button>
              </React.Fragment>
            }
          </div>
        </div>
      </section>

      <MegaFooter onGoto={onGoto} isRentals />
    </main>);

}

// ===================================================================
// /rentals/open-account — Notion-form embed inside our shell
// ===================================================================
function OpenAccountPage({ onGoto }) {
  return (
    <main className="page active rentals-light" data-screen-label="03b Rentals · Open Account">
      <RentalsSubHero
        idx="VR—05"
        label="Open Account"
        title="One verification.<br/><em>Faster</em> bookings, credit terms."
        lead="Open a Valley Rentals account once and skip verification on every future booking. After a successful first hire, accounts unlock 30-day credit terms on invoices over £250 and access to repeat-client rates." />

      <section id="open-account" className="rentals-open-account">
        <div className="container">
          <div className="oa-intro">
            <h3>What you'll need to apply</h3>
            <ul className="oa-checklist">
              <li>Photo ID — passport, UK driving licence or national ID, held next to your face in the photo.</li>
              <li>Two proofs of address — utility bill, bank statement, council tax or mobile contract, dated within three months. PDF only.</li>
              <li>A link to your professional portfolio.</li>
              <li>Two trade references — business email and phone number for each. Custom-domain emails only (no Gmail).</li>
            </ul>
            <p className="oa-time">Takes about five minutes to complete.</p>
          </div>
        </div>

        <div className="oa-form-full">
          <iframe
            className="oa-form-iframe"
            src="https://valleyfilms.notion.site/ebd/13e47fd0362080819a2afdcb9d5a0275"
            title="Valley Rentals — Open Account application"
            loading="lazy"
            allow="clipboard-write" />

        </div>

        <div className="container">
          <p className="oa-alt">Already an account holder? Email <a href="mailto:rentals@valley.film">rentals@valley.film</a> to book directly.</p>
        </div>
      </section>

      <MegaFooter onGoto={onGoto} isRentals />
    </main>);

}

// ===================================================================
// Top-level switch — picks a sub-page based on rentalsSection prop.
// ===================================================================
function RentalsPage({ onGoto, rentalsSection }) {
  // Load the Booqable script on every rentals route so the floating
  // cart persists as the user moves between landing → equipment →
  // contact, etc. Returns the load status; the equipment page uses it
  // to swap in a fallback message if the script ever fails.
  const bqStatus = useBooqable();

  if (rentalsSection === 'equipment')    return <EquipmentPage onGoto={onGoto} bqStatus={bqStatus} />;
  if (rentalsSection === 'contact')      return <RentalsContactPage onGoto={onGoto} />;
  if (rentalsSection === 'open-account') return <OpenAccountPage onGoto={onGoto} />;
  return <RentalsLanding onGoto={onGoto} />;
}

Object.assign(window, { RentalsPage });
