// SOLO — Installers page
// AU-wide locator. Search by postcode/city/state. Map + grid of installer cards.

const { useState, useMemo } = React;

const Word = ({ light }) =>
<a href="index.html#top" className="word">
    <img src={light ? "assets/SOLO_WORDMARK_WHITE.svg" : "assets/SOLO_WORDMARK_BLACK.svg"} alt="SOLO" />
  </a>;


function Announce() {
  return (
    <div className="announce">
      <span className="dot">●</span>  Launching 2026 · Fixed prices online · No salesman
    </div>);

}

function Topbar() {
  return (
    <div className="topbar edge">
      <div className="left">
        <Word />
        <nav>
          <a href="how-it-works.html">How it works</a>
          <a href="systems.html">Systems</a>
          <a href="products.html">Products</a>
          <a href="installers.html" aria-current="page" style={{ color: "var(--solo-black)", fontWeight: 600 }}>Installers</a>
          <a href="faq.html">FAQ</a>
        </nav>
      </div>
      <div className="right">
        <span className="ann"><span className="mono-tag"><span className="dot"></span>Ballarat 3350</span></span>
        <a className="btn btn-primary btn-sm" href="index.html#hero">Get my price <span className="arrow">→</span></a>
      </div>
    </div>);

}

// ─────────────────────────────────────────────────────────────────
//  DATA — installers across AU
//  Coordinates are SVG-space (% of viewBox) for our schematic AU map.
//  status: live | next | later
// ─────────────────────────────────────────────────────────────────
const STATES = [
{ id: "VIC", label: "Victoria", count: 4 },
{ id: "NSW", label: "New South Wales", count: 3 },
{ id: "QLD", label: "Queensland", count: 2 },
{ id: "SA", label: "South Australia", count: 2 },
{ id: "WA", label: "Western Australia", count: 1 },
{ id: "TAS", label: "Tasmania", count: 1 },
{ id: "ACT", label: "Australian Capital Territory", count: 1 }];


const INSTALLERS = [
// LIVE
{ id: "ballarat", city: "Ballarat", state: "VIC", status: "live", launch: "May 2026", x: 56, y: 76,
  postcodes: ["3350", "3352", "3353", "3355", "3356", "3357", "3373", "3375"],
  lead: { name: "Jason Whittaker", role: "Lead installer · 23 years on the tools", initial: "J" },
  crew: 3, jobs: 14, capacity: "8 / week",
  blurb: "Ex-Origin sub-contractor, walked off two of them. The reason SOLO exists in the postcode." },

// NEXT (Q3-Q4 2026)
{ id: "geelong", city: "Geelong", state: "VIC", status: "next", launch: "Aug 2026", x: 54, y: 78,
  postcodes: ["3220", "3216", "3217", "3218", "3219", "3221", "3222", "3223", "3224", "3225", "3226", "3227", "3228", "3231"],
  lead: { name: "Priya Ranganathan", role: "Lead installer · 11 years · CEC A-grade", initial: "P" },
  crew: 3, jobs: 0, capacity: "10 / week from Aug",
  blurb: "Hired in March 2026 from Solahart Geelong. Lives in Belmont. First crew on the books outside Ballarat." },
{ id: "bendigo", city: "Bendigo", state: "VIC", status: "next", launch: "Sep 2026", x: 56, y: 73,
  postcodes: ["3550", "3551", "3552", "3554", "3555", "3556", "3557", "3558", "3559"],
  lead: { name: "Tom Rasmussen", role: "Lead installer · 9 years · CEC A-grade", initial: "T" },
  crew: 2, jobs: 0, capacity: "6 / week from Sep",
  blurb: "Sparky-turned-installer, ex-Sungrow technical. Knows the Sungrow SH10RT cold." },
{ id: "melbourne-east", city: "Melbourne — East", state: "VIC", status: "next", launch: "Oct 2026", x: 57, y: 79,
  postcodes: ["3000", "3121", "3122", "3123", "3124", "3125", "3126", "3127", "3128", "3129", "3130", "3131", "3132", "3133", "3134", "3135"],
  lead: { name: "Yuki Tanaka", role: "Lead installer · 14 years · 3-phase specialist", initial: "Y" },
  crew: 4, jobs: 0, capacity: "12 / week from Oct",
  blurb: "Hawthorn-based. Built a name on tile-and-batten heritage roofs in inner-east — tricky work, no leaks." },

{ id: "adelaide", city: "Adelaide — Inner", state: "SA", status: "next", launch: "Sep 2026", x: 38, y: 79,
  postcodes: ["5000", "5006", "5007", "5008", "5009", "5061", "5062", "5063", "5064", "5065", "5066", "5067", "5068", "5152"],
  lead: { name: "Rebecca Mountford", role: "Lead installer · 12 years · ex-Tindo", initial: "R" },
  crew: 3, jobs: 0, capacity: "8 / week from Sep",
  blurb: "Built her last crew at Tindo Solar (the Adelaide manufacturer). Still has the rolodex." },
{ id: "adelaide-hills", city: "Adelaide Hills", state: "SA", status: "later", launch: "Q1 2027", x: 39, y: 79,
  postcodes: ["5152", "5153", "5154", "5155", "5156", "5157", "5158", "5159", "5160"],
  lead: { name: "TBD — hiring", role: "Lead installer · open role", initial: "?" },
  crew: 0, jobs: 0, capacity: "Hiring",
  blurb: "Hiring now. Looking for a CEC A-grade with hills-fire-zone experience and a clean record." },

{ id: "sydney-inner", city: "Sydney — Inner West", state: "NSW", status: "later", launch: "Q4 2026", x: 73, y: 71,
  postcodes: ["2010", "2008", "2009", "2037", "2038", "2039", "2040", "2041", "2042", "2043", "2044", "2045", "2046", "2047", "2048"],
  lead: { name: "Alex Beaumont", role: "Lead installer · 16 years · 3-phase + heritage", initial: "A" },
  crew: 4, jobs: 0, capacity: "12 / week from Nov",
  blurb: "Newtown-based, came from Solar Service Group. Knows every council quirk between Petersham and Annandale." },
{ id: "sydney-north", city: "Sydney — North Shore", state: "NSW", status: "later", launch: "Q1 2027", x: 73, y: 70,
  postcodes: ["2060", "2061", "2062", "2063", "2064", "2065", "2066", "2067", "2068", "2069", "2070", "2071", "2072", "2073"],
  lead: { name: "TBD — hiring", role: "Lead installer · open role", initial: "?" },
  crew: 0, jobs: 0, capacity: "Hiring",
  blurb: "Hiring. Three-storey heritage waterfronts, narrow access, council overlays — not for the faint of heart." },
{ id: "newcastle", city: "Newcastle", state: "NSW", status: "later", launch: "Q1 2027", x: 73, y: 67,
  postcodes: ["2300", "2301", "2302", "2303", "2304", "2305", "2306", "2307", "2308"],
  lead: { name: "TBD — hiring", role: "Lead installer · open role", initial: "?" },
  crew: 0, jobs: 0, capacity: "Hiring",
  blurb: "Coastal, salt-rated mounting required. Looking for someone with marine-environment experience." },

{ id: "brisbane", city: "Brisbane — Inner", state: "QLD", status: "later", launch: "Q1 2027", x: 70, y: 50,
  postcodes: ["4000", "4005", "4006", "4007", "4051", "4059", "4064", "4065", "4066", "4067", "4068", "4069", "4101", "4102", "4103"],
  lead: { name: "Marcus Liu", role: "Lead installer · 13 years · cyclone-rated", initial: "M" },
  crew: 3, jobs: 0, capacity: "10 / week from Feb",
  blurb: "Currently at Origin Solar QLD, joining us March 2027. Cyclone-rated mounting, AS/NZS 1170.2 fluent." },
{ id: "gold-coast", city: "Gold Coast", state: "QLD", status: "later", launch: "Q2 2027", x: 71, y: 52,
  postcodes: ["4217", "4218", "4220", "4221", "4222", "4223", "4225", "4226", "4227", "4228"],
  lead: { name: "TBD — hiring", role: "Lead installer · open role", initial: "?" },
  crew: 0, jobs: 0, capacity: "Hiring",
  blurb: "Hiring. Salt environment + cyclone region + tile-and-batten dominant. Premium for the right person." },

{ id: "perth", city: "Perth — Inner", state: "WA", status: "later", launch: "Q2 2027", x: 14, y: 65,
  postcodes: ["6000", "6005", "6006", "6007", "6008", "6009", "6010", "6011", "6012", "6014", "6050", "6051", "6052"],
  lead: { name: "TBD — hiring", role: "Lead installer · open role", initial: "?" },
  crew: 0, jobs: 0, capacity: "Hiring",
  blurb: "Hiring. WA's Synergy network has its own quirks — looking for someone who's done 50+ Synergy connections." },

{ id: "hobart", city: "Hobart", state: "TAS", status: "later", launch: "Q3 2027", x: 60, y: 95,
  postcodes: ["7000", "7004", "7005", "7007", "7008", "7009", "7010", "7011", "7050"],
  lead: { name: "TBD — hiring", role: "Lead installer · open role", initial: "?" },
  crew: 0, jobs: 0, capacity: "Hiring",
  blurb: "Hiring. Lower irradiance, smaller market — but the rebate stack and feed-in tariff make it work." },

{ id: "canberra", city: "Canberra", state: "ACT", status: "later", launch: "Q2 2027", x: 70, y: 78,
  postcodes: ["2600", "2601", "2602", "2603", "2604", "2605", "2606", "2611", "2612", "2614"],
  lead: { name: "TBD — hiring", role: "Lead installer · open role", initial: "?" },
  crew: 0, jobs: 0, capacity: "Hiring",
  blurb: "Hiring. ACT's Sustainable Household Scheme is the most generous battery rebate in the country — get in early." }];



const cmpStatus = (s) => s === "live" ? 0 : s === "next" ? 1 : 2;
const STATES_WITH_ALL = [{ id: "all", label: "All Australia" }, ...STATES];

// ─────────────────────────────────────────────────────────────────
//  AU map — schematic. Rough coast outline + state boundaries.
//  ViewBox 100 × 100; locations placed in roughly correct relative positions.
// ─────────────────────────────────────────────────────────────────
function AUMap({ items, activeId, onPin }) {
  return (
    <div className="ins-map">
      <div className="head">
        <span className="lab">Australia · Coverage map</span>
        <div className="legend">
          <span><span className="swatch live"></span>Live</span>
          <span><span className="swatch next"></span>Next 6 mo</span>
          <span><span className="swatch later"></span>Later</span>
        </div>
      </div>
      <svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet" aria-label="Map of Australia with installer locations">
        {/* Schematic AU coastline — simplified */}
        <path
          d="M 6,52 L 6,62 L 8,68 L 10,72 L 14,75 L 18,76 L 22,77 L 28,80 L 34,82 L 38,82 L 42,80 L 48,82 L 54,84 L 56,86 L 58,87 L 62,86 L 64,82 L 64,78 L 66,76 L 68,76 L 72,76 L 76,74 L 80,70 L 82,66 L 82,60 L 80,55 L 78,50 L 74,48 L 70,46 L 70,42 L 70,36 L 68,32 L 66,28 L 60,28 L 54,30 L 48,32 L 42,34 L 36,36 L 30,38 L 24,42 L 18,46 L 12,48 Z"
          fill="var(--solo-white)"
          stroke="var(--solo-black)"
          strokeWidth="0.5" />

        {/* Tasmania */}
        <ellipse cx="60" cy="93" rx="6" ry="3.5" fill="var(--solo-white)" stroke="var(--solo-black)" strokeWidth="0.5" />

        {/* Faint state borders (schematic) */}
        <g stroke="var(--solo-cool)" strokeWidth="0.25" strokeDasharray="0.5 0.5" fill="none" opacity="0.6">
          <line x1="44" y1="32" x2="44" y2="82" />
          <line x1="64" y1="36" x2="64" y2="78" />
          <line x1="60" y1="60" x2="44" y2="60" />
          <line x1="64" y1="60" x2="80" y2="60" />
          <line x1="44" y1="74" x2="64" y2="74" />
        </g>

        {/* State labels */}
        <g fontFamily="var(--solo-font-mono)" fontSize="2.6" letterSpacing="0.4" fill="var(--solo-cool)" textAnchor="middle">
          <text x="22" y="64">WA</text>
          <text x="42" y="74">SA</text>
          <text x="56" y="80">VIC</text>
          <text x="73" y="66">NSW</text>
          <text x="68" y="42">QLD</text>
          <text x="60" y="92" fill="var(--solo-black)">TAS</text>
          <text x="70" y="80" fontSize="1.8">ACT</text>
        </g>

        {/* Pins */}
        {items.map((p) => {
          const r = p.status === "live" ? 1.8 : 1.4;
          const isActive = activeId === p.id;
          return (
            <g key={p.id} className={`map-pin ${p.status}${isActive ? " active" : ""}`} transform={`translate(${p.x} ${p.y})`} onClick={() => onPin(p.id)}>
              <circle className="ring" r={r + 1.2} cx="0" cy="0" fill="var(--solo-white)" stroke="var(--solo-black)" strokeWidth="0.4" opacity="0.6" />
              <circle className="ring" r={r} cx="0" cy="0" />
              {p.status === "live" && <circle r={r * 0.4} cx="0" cy="0" fill="var(--solo-black)" />}
              <text className="map-label" x="0" y={r + 3.4} textAnchor="middle" fontSize="2.2">{p.city.toUpperCase().split(" — ")[0]}</text>
            </g>);

        })}
      </svg>
    </div>);

}

// ─────────────────────────────────────────────────────────────────
//  Installer card
// ─────────────────────────────────────────────────────────────────
function InstallerCard({ item, hl, postcodeMatch }) {
  const statusBadge = item.status === "live" ? "Live · taking bookings" : item.status === "next" ? `Next · ${item.launch}` : `Later · ${item.launch}`;
  return (
    <div className={`ins-card ${item.status}`} id={item.id}>
      <div className="top">
        <div>
          <div className="city">{item.city}</div>
          <div className="state">{item.state} · {item.postcodes.length} postcodes</div>
        </div>
        <div className="badge">{statusBadge}</div>
      </div>
      <div className="body">
        <div className="lead">
          <div className="av">{item.lead.initial}</div>
          <div>
            <div className="name">{item.lead.name}</div>
            <div className="role">{item.lead.role}</div>
          </div>
        </div>
        <p style={{ margin: 0, fontSize: 14, lineHeight: 1.55, color: "var(--solo-dark)" }}>{item.blurb}</p>
        <div>
          <div style={{ fontFamily: "var(--solo-font-mono)", fontSize: 10, letterSpacing: "0.1em", textTransform: "uppercase", color: "var(--solo-cool)", marginBottom: 8 }}>Postcodes served</div>
          <div className="pcs">
            {item.postcodes.slice(0, 14).map((pc) =>
            <span key={pc} className={`pc${postcodeMatch === pc ? " match" : ""}`}>{pc}</span>
            )}
            {item.postcodes.length > 14 && <span className="pc" style={{ borderStyle: "dashed", color: "var(--solo-cool)" }}>+{item.postcodes.length - 14}</span>}
          </div>
        </div>
        <div className="stats">
          <div className="s">
            <div className="lab">Crew size</div>
            <div className="v">{item.crew || "—"}</div>
          </div>
          <div className="s">
            <div className="lab">Jobs done</div>
            <div className="v">{item.jobs}</div>
          </div>
          <div className="s">
            <div className="lab">Capacity</div>
            <div className="v" style={{ fontSize: 13 }}>{item.capacity}</div>
          </div>
        </div>
      </div>
      <div className="ftr">
        <span>{item.status === "live" ? "Book online · 60 sec" : `Notify me when ${item.city} opens`}</span>
        <span className="arrow">→</span>
      </div>
    </div>);

}

// ─────────────────────────────────────────────────────────────────
//  Closer + Footer
// ─────────────────────────────────────────────────────────────────
function Closer() {
  return (
    <section className="closer-strip">
      <div className="corner-print">
        <img src="assets/sun-prints/SUNPRINT-3350-66KW-BALLARAT.svg" alt="" style={{ width: "100%", height: "100%", objectFit: "cover", filter: "brightness(0) saturate(100%) invert(91%) sepia(50%) saturate(672%) hue-rotate(33deg) brightness(108%) contrast(101%)" }} />
      </div>
      <div className="edge">
        <div className="row">
          <h2>Your roof, your local installer. <em>No salesman in between.</em></h2>
          <div className="meta">
            We hire one crew per region. Employed, named, on the SOLO payroll. If we're not yet in your postcode, we'll tell you when we will be — and we'll keep our promise.
            <div className="cta">
              <a className="btn btn-primary btn-xl" href="index.html#hero">Get my price <span className="arrow">→</span></a>
              <a className="btn btn-ghost-light btn-xl" href="#hire">Apply to install</a>
            </div>
          </div>
        </div>
      </div>
    </section>);

}

function Footer() {
  return (
    <footer className="edge">
      <div className="footer-line">
        <Word />
        <div>SOLO Solar Pty Ltd · ABN [pending] · getsolo.solar</div>
        <div className="links">
          <a href="how-it-works.html">How it works</a>
          <a href="systems.html">Systems</a>
          <a href="products.html">Products</a>
          <a href="installers.html">Installers</a>
          <a href="faq.html">FAQ</a>
          <a href="mailto:hello@getsolo.solar">hello@getsolo.solar</a>
        </div>
      </div>
    </footer>);

}

// ─────────────────────────────────────────────────────────────────
//  Page
// ─────────────────────────────────────────────────────────────────
function InstallersPage() {
  const [query, setQuery] = useState("");
  const [postcode, setPostcode] = useState("");
  const [activeState, setActiveState] = useState("all");
  const [activePin, setActivePin] = useState(null);

  const filtered = useMemo(() => {
    let list = [...INSTALLERS];
    if (activeState !== "all") list = list.filter((i) => i.state === activeState);
    if (postcode.trim().length === 4) {
      const exactMatch = list.filter((i) => i.postcodes.includes(postcode.trim()));
      if (exactMatch.length) list = exactMatch;
    }
    if (query.trim()) {
      const needle = query.toLowerCase().trim();
      list = list.filter((i) =>
      i.city.toLowerCase().includes(needle) ||
      i.state.toLowerCase().includes(needle) ||
      i.lead.name.toLowerCase().includes(needle) ||
      i.postcodes.some((p) => p.startsWith(needle)) ||
      STATES.find((s) => s.id === i.state)?.label.toLowerCase().includes(needle)
      );
    }
    list.sort((a, b) => cmpStatus(a.status) - cmpStatus(b.status));
    return list;
  }, [query, postcode, activeState]);

  const postcodeHit = useMemo(() => {
    if (postcode.trim().length !== 4) return null;
    const pc = postcode.trim();
    const hit = INSTALLERS.find((i) => i.postcodes.includes(pc));
    return { pc, hit };
  }, [postcode]);

  const liveCount = INSTALLERS.filter((i) => i.status === "live").length;
  const nextCount = INSTALLERS.filter((i) => i.status === "next").length;
  const laterCount = INSTALLERS.filter((i) => i.status === "later").length;
  const totalPostcodes = INSTALLERS.reduce((s, i) => s + i.postcodes.length, 0);

  const selected = filtered.find((i) => i.id === activePin) || filtered[0];

  return (
    <div className="page" id="top" data-volt="more" data-typescale="restrained">
      <Announce />
      <Topbar />

      <section className="section edge ins-hero">
        <span className="eyebrow"><span className="mono-tag"><span className="dot"></span>Installer locator · Australia-wide</span></span>
        <h1 className="ins-h1">One crew, <em>per postcode.</em></h1>
        <p className="lede">Every SOLO installer is a CEC-accredited employee — not a sub-contractor, not a national franchise, not a roving crew that bid lowest yesterday. Same Jason, same Ben, same Maddy on every Ballarat install. Find yours below.</p>

        <div className="ins-tally">
          <div className="s">
            <span className="lab">Live crews</span>
            <span className="v">{liveCount}<small>now</small></span>
          </div>
          <div className="s">
            <span className="lab">Opening next 6 months</span>
            <span className="v">{nextCount}<small>2026</small></span>
          </div>
          <div className="s">
            <span className="lab">Roadmap</span>
            <span className="v">{laterCount}<small>through 2027</small></span>
          </div>
          <div className="s">
            <span className="lab">Postcodes covered</span>
            <span className="v">{totalPostcodes}<small>and growing</small></span>
          </div>
        </div>
      </section>

      {/* Sticky toolbar */}
      <div className="ins-toolbar">
        <div className="edge">
          <div className="row">
            <div className="ins-search">
              <span className="gly">SEARCH</span>
              <input
                value={query}
                onChange={(e) => setQuery(e.target.value)}
                placeholder="city, state, installer name…"
                aria-label="Search installers" />

              {query &&
              <button
                onClick={() => setQuery("")}
                style={{ background: "transparent", border: 0, fontFamily: "var(--solo-font-mono)", fontSize: 12, letterSpacing: "0.1em", color: "var(--solo-cool)", cursor: "pointer" }}>
                CLEAR ✕
                </button>
              }
            </div>
            <div className="ins-pcode">
              <span className="lab">Postcode</span>
              <input
                value={postcode}
                onChange={(e) => setPostcode(e.target.value.replace(/\D/g, "").slice(0, 4))}
                placeholder="3350"
                maxLength={4}
                inputMode="numeric"
                aria-label="Postcode" />

            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 8, justifyContent: "flex-end" }}>
              <span style={{ fontFamily: "var(--solo-font-mono)", fontSize: 11, letterSpacing: "0.1em", color: "var(--solo-cool)", textTransform: "uppercase" }}>{filtered.length} of {INSTALLERS.length}</span>
              {(query || postcode || activeState !== "all") &&
              <button
                onClick={() => {setQuery("");setPostcode("");setActiveState("all");}}
                style={{ background: "transparent", border: "1px solid var(--solo-cool)", padding: "6px 12px", fontFamily: "var(--solo-font-mono)", fontSize: 11, letterSpacing: "0.1em", color: "var(--solo-black)", cursor: "pointer", borderRadius: 999, textTransform: "uppercase" }}>
                Reset
                </button>
              }
            </div>
          </div>
          <div className="filter-row">
            <span className="lab">State</span>
            {STATES_WITH_ALL.map((s) => {
              const count = s.id === "all" ? INSTALLERS.length : INSTALLERS.filter((i) => i.state === s.id).length;
              return (
                <button
                  key={s.id}
                  className={`ins-state-btn${activeState === s.id ? " active" : ""}${count === 0 ? " disabled" : ""}`}
                  disabled={count === 0}
                  onClick={() => setActiveState(s.id)}>
                  {s.id === "all" ? "All AU" : s.id}<span className="c">{count}</span>
                </button>);

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

      {/* Postcode hit banner */}
      {postcodeHit &&
      <section className="section edge" style={{ paddingBlock: 0, paddingTop: 24 }}>
          <div className={`pc-hit${postcodeHit.hit ? "" : " miss"}`}>
            <span className="icon">{postcodeHit.hit ? "✓" : "✕"}</span>
            <div>
              <div className="h">
                {postcodeHit.hit ?
              <>{postcodeHit.pc} · <b>{postcodeHit.hit.city}</b> — {postcodeHit.hit.status === "live" ? "Live now." : postcodeHit.hit.status === "next" ? `Opening ${postcodeHit.hit.launch}.` : `On the 2027 roadmap (${postcodeHit.hit.launch}).`}</> :
              <>{postcodeHit.pc} · No crew yet.</>
              }
              </div>
              <div className="s">{postcodeHit.hit ? `${postcodeHit.hit.lead.name} leads this region. ${postcodeHit.hit.crew} crew, ${postcodeHit.hit.capacity}.` : "Drop your email at the bottom and we'll tell you the day we open in your postcode."}</div>
            </div>
            <a className="btn btn-primary btn-sm" href={postcodeHit.hit ? `#${postcodeHit.hit.id}` : "#hire"}>{postcodeHit.hit ? "See crew →" : "Notify me →"}</a>
          </div>
        </section>
      }

      {/* Map + summary */}
      <section className="section edge" style={{ paddingTop: postcodeHit ? 24 : undefined }}>
        <div className="ins-map-wrap">
          <AUMap items={filtered} activeId={selected?.id} onPin={(id) => setActivePin(id)} />

          <div className="ins-summary">
            <span className="mono-tag"><span className="dot"></span>{filtered.length} {filtered.length === 1 ? "region" : "regions"}{activeState !== "all" ? ` in ${activeState}` : ""}</span>
            <h2>One employed crew per region. Promise.</h2>
            <p>We don't grow by adding sub-contractors. We grow by hiring full-time, on-the-books, super-paid installers — one lead, one crew, one geography. The map fills in slowly because hiring takes time. We'd rather be slow than be Origin.</p>

            {selected &&
            <div className="selected-card">
                <span className="lab">{selected.status === "live" ? "Live · taking bookings" : `${selected.launch} · ${selected.status === "next" ? "next 6 months" : "later"}`}</span>
                <div className="city">{selected.city}</div>
                <p style={{ margin: 0, fontSize: 14, lineHeight: 1.55, color: "var(--solo-dark)" }}>{selected.blurb}</p>
                <div className="meta">
                  <div>
                    <div className="k">Lead</div>
                    <div className="v">{selected.lead.name}</div>
                  </div>
                  <div>
                    <div className="k">Crew</div>
                    <div className="v">{selected.crew || "Hiring"}</div>
                  </div>
                  <div>
                    <div className="k">Postcodes</div>
                    <div className="v">{selected.postcodes.length}</div>
                  </div>
                  <div>
                    <div className="k">Capacity</div>
                    <div className="v">{selected.capacity}</div>
                  </div>
                </div>
              </div>
            }
          </div>
        </div>
      </section>

      {/* Card grid */}
      <section className="section edge" style={{ paddingTop: 0 }}>
        <div className="ins-list-head">
          <h2>{filtered.length === INSTALLERS.length ? "All regions" : "Filtered"}</h2>
          <span className="meta">Sorted: live → opening next → roadmap</span>
        </div>
        {filtered.length === 0 ?
        <div className="ins-empty">
            <div className="h">No matches.</div>
            <div className="s">Try a state, a city, or just a postcode.</div>
            <button className="btn btn-primary btn-lg" style={{ marginTop: 22 }} onClick={() => {setQuery("");setPostcode("");setActiveState("all");}}>Reset filters</button>
          </div> :

        <div className="ins-grid">
            {filtered.map((item) =>
          <InstallerCard key={item.id} item={item} postcodeMatch={postcodeHit?.hit?.id === item.id ? postcodeHit.pc : null} />
          )}
          </div>
        }
      </section>

      {/* Become an installer */}
      <section className="section edge hire" id="hire">
        <div className="lhs">
          <span className="mono-tag"><span className="dot"></span>Hiring · 7 regions</span>
          <h2>Be the named installer in your region.</h2>
          <p>SOLO is hiring lead installers in <b>Adelaide Hills, Sydney North Shore, Newcastle, Gold Coast, Perth, Hobart, and Canberra</b> through 2026–2027. Employed, full-time, super-paid, with equity. You own the region. Your name is on the cards. The work is yours.</p>
          <div style={{ marginTop: 24 }}>
            <a className="btn btn-primary btn-xl" href="mailto:jobs@getsolo.solar">Apply <span className="arrow">→</span></a>
          </div>
        </div>
        <div>
          <ul className="checklist">
            <li>
              <span className="ck">✓</span>
              <div>
                <div className="h">CEC accredited (A-grade), 5+ years</div>
                <div className="s">Or willing to upgrade — we'll pay for it.</div>
              </div>
              <span className="pay">Required</span>
            </li>
            <li>
              <span className="ck">✓</span>
              <div>
                <div className="h">Local for 5+ years</div>
                <div className="s">You know the council, the network operator, the roofs.</div>
              </div>
              <span className="pay">Required</span>
            </li>
            <li>
              <span className="ck">✓</span>
              <div>
                <div className="h">Employed · super · equity</div>
                <div className="s">Salary + super + 0.1–0.4% of company stock, vested over 4 years.</div>
              </div>
              <span className="pay">$130k–$165k</span>
            </li>
            <li>
              <span className="ck">✓</span>
              <div>
                <div className="h">No quota, no commission</div>
                <div className="s">We sell at fixed price online. Your job is install quality and customer outcome.</div>
              </div>
              <span className="pay">Promise</span>
            </li>
            <li>
              <span className="ck">✓</span>
              <div>
                <div className="h">Build your own crew</div>
                <div className="s">You hire your sparkies and apprentices. We pay them. They report to you.</div>
              </div>
              <span className="pay">Day one</span>
            </li>
            <li>
              <span className="ck">✓</span>
              <div>
                <div className="h">10-year warranty backing</div>
                <div className="s">SOLO carries the workmanship warranty. You don't get an angry call in 2034.</div>
              </div>
              <span className="pay">Backed</span>
            </li>
          </ul>
        </div>
      </section>

      <Closer />
      <Footer />
    </div>);

}

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