// products.jsx — Products listing page (PLP)
const { useState, useMemo } = React;

// ─── Data ────────────────────────────────────────────────────────
const CATEGORIES = [
  { id: "panels", lab: "Category 01", v: "Solar panels", c: "8 products · 5 brands" },
  { id: "batteries", lab: "Category 02", v: "Batteries", c: "7 products · 6 brands" },
  { id: "inverters", lab: "Category 03", v: "Inverters", c: "6 products · 4 brands" },
  { id: "accessories", lab: "Category 04", v: "Accessories", c: "9 products · 5 brands" }];


const PRODUCTS = {
  panels: [
    { brand: "Aiko", h: "Neostar 2S 450W", power: "450 W", eff: "23.2%", warranty: "25 yr", price: "$330", unit: "ea", badges: ["std"], filters: { brand: "Aiko", power: "400-449", finish: "all-black" } },
    { brand: "Aiko", h: "Comet 2S 480W", power: "480 W", eff: "24.0%", warranty: "25 yr", price: "$385", unit: "ea", badges: ["new"], filters: { brand: "Aiko", power: "450-499", finish: "all-black" } },
    { brand: "Q.Cell", h: "Q.PEAK Duo BLK ML-G11+ 410W", power: "410 W", eff: "21.6%", warranty: "25 yr", price: "$240", unit: "ea", badges: [], filters: { brand: "Q.Cell", power: "400-449", finish: "all-black" } },
    { brand: "Trina", h: "Vertex S+ TSM-NEG9R.28 440W", power: "440 W", eff: "22.5%", warranty: "25 yr", price: "$280", unit: "ea", badges: [], filters: { brand: "Trina", power: "400-449", finish: "silver" } },
    { brand: "REC", h: "Alpha Pure-RX 470W", power: "470 W", eff: "22.6%", warranty: "25 yr", price: "$420", unit: "ea", badges: ["premium"], filters: { brand: "REC", power: "450-499", finish: "all-black" } },
    { brand: "Jinko", h: "Tiger Neo N-Type 425W", power: "425 W", eff: "21.8%", warranty: "25 yr", price: "$220", unit: "ea", badges: ["budget"], filters: { brand: "Jinko", power: "400-449", finish: "silver" } },
    { brand: "Aiko", h: "Black Hole 2S 460W", power: "460 W", eff: "23.6%", warranty: "25 yr", price: "$355", unit: "ea", badges: [], filters: { brand: "Aiko", power: "450-499", finish: "all-black" } },
    { brand: "LONGi", h: "Hi-MO 6 Explorer 440W", power: "440 W", eff: "22.5%", warranty: "25 yr", price: "$260", unit: "ea", badges: [], filters: { brand: "LONGi", power: "400-449", finish: "all-black" } }
  ],
  batteries: [
    { brand: "Tesla", h: "Powerwall 3", power: "11.5 kW", cap: "13.5 kWh", warranty: "10 yr", price: "$11,500", unit: "fitted", badges: ["std"], filters: { brand: "Tesla", capacity: "13-15", chem: "lfp" } },
    { brand: "Tesla", h: "Powerwall 3 Expansion", power: "—", cap: "13.5 kWh", warranty: "10 yr", price: "$7,500", unit: "fitted", badges: [], filters: { brand: "Tesla", capacity: "13-15", chem: "lfp" } },
    { brand: "Sigenergy", h: "SigenStor 8.0", power: "6 kW", cap: "8.0 kWh", warranty: "10 yr", price: "$9,100", unit: "fitted", badges: [], filters: { brand: "Sigenergy", capacity: "8-12", chem: "lfp" } },
    { brand: "BYD", h: "Battery-Box Premium HVS 10.2", power: "8.5 kW", cap: "10.2 kWh", warranty: "10 yr", price: "$10,400", unit: "fitted", badges: [], filters: { brand: "BYD", capacity: "8-12", chem: "lfp" } },
    { brand: "Sungrow", h: "SBR128", power: "9.6 kW", cap: "12.8 kWh", warranty: "10 yr", price: "$10,800", unit: "fitted", badges: [], filters: { brand: "Sungrow", capacity: "13-15", chem: "lfp" } },
    { brand: "GoodWe", h: "Lynx Home U 10.8", power: "8 kW", cap: "10.8 kWh", warranty: "10 yr", price: "$9,400", unit: "fitted", badges: ["budget"], filters: { brand: "GoodWe", capacity: "8-12", chem: "lfp" } },
    { brand: "Enphase", h: "IQ Battery 5P", power: "3.84 kW", cap: "5.0 kWh", warranty: "15 yr", price: "$7,200", unit: "fitted", badges: ["new"], filters: { brand: "Enphase", capacity: "0-7", chem: "lfp" } }
  ],
  inverters: [
    { brand: "Sungrow", h: "SH10RT Hybrid", power: "10 kW", phase: "Single", warranty: "10 yr", price: "$3,400", unit: "fitted", badges: ["std"], filters: { brand: "Sungrow", power: "8-10", phase: "single" } },
    { brand: "Sungrow", h: "SH15T Hybrid", power: "15 kW", phase: "Three", warranty: "10 yr", price: "$4,200", unit: "fitted", badges: [], filters: { brand: "Sungrow", power: "11-15", phase: "three" } },
    { brand: "Fronius", h: "GEN24 10.0 Plus", power: "10 kW", phase: "Three", warranty: "10 yr", price: "$4,800", unit: "fitted", badges: ["premium"], filters: { brand: "Fronius", power: "8-10", phase: "three" } },
    { brand: "GoodWe", h: "ET 10kW Hybrid", power: "10 kW", phase: "Three", warranty: "10 yr", price: "$3,100", unit: "fitted", badges: ["budget"], filters: { brand: "GoodWe", power: "8-10", phase: "three" } },
    { brand: "Enphase", h: "IQ8M Microinverter", power: "330 W", phase: "Single", warranty: "25 yr", price: "$210", unit: "ea", badges: [], filters: { brand: "Enphase", power: "0-7", phase: "single" } },
    { brand: "Sungrow", h: "SG8.0RS String", power: "8 kW", phase: "Single", warranty: "10 yr", price: "$2,400", unit: "fitted", badges: [], filters: { brand: "Sungrow", power: "8-10", phase: "single" } }
  ],
  accessories: [
    { brand: "Sungrow", h: "EVDC11 EV charger", power: "11 kW", warranty: "5 yr", price: "$1,890", unit: "fitted", badges: [], filters: { brand: "Sungrow", type: "ev" } },
    { brand: "Tesla", h: "Wall Connector Gen 3", power: "11 kW", warranty: "4 yr", price: "$1,650", unit: "fitted", badges: ["new"], filters: { brand: "Tesla", type: "ev" } },
    { brand: "SOLO", h: "Consumption monitoring kit", power: "—", warranty: "10 yr", price: "$340", unit: "fitted", badges: [], filters: { brand: "SOLO", type: "monitoring" } },
    { brand: "Catch Power", h: "Solar Relay", power: "20 A", warranty: "5 yr", price: "$420", unit: "fitted", badges: [], filters: { brand: "Catch Power", type: "monitoring" } },
    { brand: "SOLO", h: "Bird & critter mesh kit", power: "—", warranty: "10 yr", price: "$580", unit: "fitted", badges: [], filters: { brand: "SOLO", type: "mounting" } },
    { brand: "Clenergy", h: "PV-ezRack SolarRoof", power: "—", warranty: "12 yr", price: "—", unit: "incl.", badges: ["std"], filters: { brand: "Clenergy", type: "mounting" } },
    { brand: "Sungrow", h: "WiNet-S WiFi/Eth dongle", power: "—", warranty: "5 yr", price: "$120", unit: "fitted", badges: [], filters: { brand: "Sungrow", type: "monitoring" } },
    { brand: "Schneider", h: "ATS load-shed contactor", power: "63 A", warranty: "5 yr", price: "$680", unit: "fitted", badges: [], filters: { brand: "Schneider", type: "backup" } },
    { brand: "SOLO", h: "Switchboard upgrade — single phase", power: "—", warranty: "10 yr", price: "$1,200", unit: "fitted", badges: [], filters: { brand: "SOLO", type: "backup" } }
  ]
};

const FILTERS_BY_CAT = {
  panels: [
    { key: "brand", lab: "Brand", opts: ["Aiko", "Q.Cell", "Trina", "REC", "Jinko", "LONGi"] },
    { key: "power", lab: "Power", opts: [["400-449", "400–449 W"], ["450-499", "450–499 W"]] },
    { key: "finish", lab: "Finish", opts: [["all-black", "All-black"], ["silver", "Silver frame"]] }
  ],
  batteries: [
    { key: "brand", lab: "Brand", opts: ["Tesla", "Sigenergy", "BYD", "Sungrow", "GoodWe", "Enphase"] },
    { key: "capacity", lab: "Usable kWh", opts: [["0-7", "≤ 7 kWh"], ["8-12", "8–12 kWh"], ["13-15", "13–15 kWh"]] },
    { key: "chem", lab: "Chemistry", opts: [["lfp", "LFP (lithium iron phosphate)"]] }
  ],
  inverters: [
    { key: "brand", lab: "Brand", opts: ["Sungrow", "Fronius", "GoodWe", "Enphase"] },
    { key: "power", lab: "Power", opts: [["0-7", "≤ 7 kW"], ["8-10", "8–10 kW"], ["11-15", "11–15 kW"]] },
    { key: "phase", lab: "Phase", opts: [["single", "Single"], ["three", "Three"]] }
  ],
  accessories: [
    { key: "brand", lab: "Brand", opts: ["SOLO", "Sungrow", "Tesla", "Catch Power", "Clenergy", "Schneider"] },
    { key: "type", lab: "Type", opts: [["ev", "EV charging"], ["monitoring", "Monitoring"], ["mounting", "Mounting & mesh"], ["backup", "Backup & switchgear"]] }
  ]
};

const BRANDS = [
  { name: "Aiko", spec: "ABC cell tech", role: "Standard panel", lockup: "AIKO" },
  { name: "Tesla", spec: "Powerwall 3 · LFP", role: "Standard battery", lockup: "TESLA" },
  { name: "Sungrow", spec: "Hybrid inverter range", role: "Standard inverter", lockup: "SUNGROW" },
  { name: "Q.Cell", spec: "German cell heritage", role: "Budget alt panel", lockup: "Q.CELL" },
  { name: "Trina", spec: "Vertex N-type", role: "Tier-1 alt panel", lockup: "TRINA" },
  { name: "REC", spec: "Norwegian, premium", role: "Premium alt panel", lockup: "REC" },
  { name: "Sigenergy", spec: "All-in-one storage", role: "Slimline alt battery", lockup: "SIGENERGY" },
  { name: "BYD", spec: "HVS modular battery", role: "Alt battery", lockup: "BYD" },
  { name: "Fronius", spec: "Austrian inverters", role: "Premium alt inverter", lockup: "FRONIUS" },
  { name: "GoodWe", spec: "Hybrid range", role: "Budget alt inverter", lockup: "GOODWE" },
  { name: "Enphase", spec: "Microinverter pioneer", role: "Module-level alt", lockup: "ENPHASE" },
  { name: "Clenergy", spec: "Roof racking", role: "Mounting standard", lockup: "CLENERGY" }];


const COMPAT_NOTES = [
  { n: "01", h: "DC-coupled stack: Aiko + Sungrow + Powerwall 3", p: "Our standard. The panel's IV curve sits inside Sungrow's MPPT range; the Powerwall's DC port pairs cleanly with the SH10RT. Tested as a unit, warranted as a unit." },
  { n: "02", h: "Three-phase homes: Sungrow SH15T", p: "If your switchboard's three-phase, we swap to the SH15T. Same MPPT logic; the Powerwall 3 still hangs off it. No micros-and-AC-coupling workaround." },
  { n: "03", h: "Battery-only retrofits: AC-coupled Powerwall 3", p: "If you already own panels and just want a battery, Powerwall 3 has a built-in solar inverter. We don't replace working inverters for the sake of it." },
  { n: "04", h: "What we won't fit on the same system", p: "Aiko panels with Enphase micros (warranty mismatch). Q.Cell + Tesla DC-coupled (rated string voltage too low at cold-temp limits). We'll tell you no when no is the right answer." }];


// ─── Icons ────────────────────────────────────────────────────────
function PanelImg() {
  return (
    <svg viewBox="0 0 60 60" fill="none">
      <rect x="4" y="6" width="52" height="48" stroke="currentColor" strokeWidth="1.5" />
      <line x1="4" y1="22" x2="56" y2="22" stroke="currentColor" strokeWidth="1" />
      <line x1="4" y1="38" x2="56" y2="38" stroke="currentColor" strokeWidth="1" />
      <line x1="21" y1="6" x2="21" y2="54" stroke="currentColor" strokeWidth="1" />
      <line x1="38" y1="6" x2="38" y2="54" stroke="currentColor" strokeWidth="1" />
    </svg>);

}
function BatteryImg() {
  return (
    <svg viewBox="0 0 60 60" fill="none">
      <rect x="10" y="6" width="40" height="48" stroke="currentColor" strokeWidth="1.5" />
      <rect x="14" y="14" width="32" height="6" fill="currentColor" />
      <rect x="14" y="24" width="32" height="6" fill="currentColor" />
      <rect x="14" y="34" width="32" height="6" fill="currentColor" />
      <rect x="14" y="44" width="22" height="6" stroke="currentColor" strokeWidth="1" />
    </svg>);

}
function InverterImg() {
  return (
    <svg viewBox="0 0 60 60" fill="none">
      <rect x="10" y="8" width="40" height="44" stroke="currentColor" strokeWidth="1.5" />
      <circle cx="30" cy="22" r="6" stroke="currentColor" strokeWidth="1.5" />
      <line x1="18" y1="38" x2="42" y2="38" stroke="currentColor" strokeWidth="1.5" />
      <line x1="18" y1="44" x2="34" y2="44" stroke="currentColor" strokeWidth="1.5" />
    </svg>);

}
function AccessoryImg() {
  return (
    <svg viewBox="0 0 60 60" fill="none">
      <rect x="14" y="14" width="32" height="32" stroke="currentColor" strokeWidth="1.5" />
      <circle cx="30" cy="30" r="6" stroke="currentColor" strokeWidth="1.5" />
      <line x1="6" y1="30" x2="14" y2="30" stroke="currentColor" strokeWidth="1.5" />
      <line x1="46" y1="30" x2="54" y2="30" stroke="currentColor" strokeWidth="1.5" />
      <line x1="30" y1="6" x2="30" y2="14" stroke="currentColor" strokeWidth="1.5" />
      <line x1="30" y1="46" x2="30" y2="54" stroke="currentColor" strokeWidth="1.5" />
    </svg>);

}

const CAT_IMG = { panels: <PanelImg />, batteries: <BatteryImg />, inverters: <InverterImg />, accessories: <AccessoryImg /> };

// ─── Sections ────────────────────────────────────────────────────
function Topbar() {
  return (
    <div className="topbar edge">
      <div className="left">
        <a className="word" href="index.html"><img src="assets/SOLO_WORDMARK_BLACK.svg" alt="SOLO" /></a>
        <nav>
          <a href="how-it-works.html">How it works</a>
          <a href="systems.html">Systems</a>
          <a href="products.html" style={{ borderBottom: "1.5px solid var(--solo-black)", paddingBottom: 4 }}>Products</a>
          <a href="installers.html">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>);

}

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

}

function Hero({ cat, setCat }) {
  return (
    <section className="edge plp-hero">
      <div className="eyebrow">Products · 30 SKUs · 14 brands</div>
      <h1 className="plp-h1">Every component <em>we'll fit.</em></h1>
      <p className="lede">If we don't list it, we don't install it. Each item below is a real SKU one of our crews has fitted in the last 90 days, with the price we paid and the price you'd pay if you swapped from the standard. No ghost SKUs, no "depending on availability" footnotes.</p>
      <div className="plp-rail">
        {CATEGORIES.map((c) =>
        <a key={c.id} href={`#${c.id}`} className={cat === c.id ? "active" : ""} onClick={(e) => {e.preventDefault();setCat(c.id);}}>
            <span className="lab">{c.lab}</span>
            <span className="v">{c.v}</span>
            <span className="c">{c.c}</span>
          </a>
        )}
      </div>
    </section>);

}

function Filters({ cat, filters, setFilters, products }) {
  const groups = FILTERS_BY_CAT[cat] || [];
  const toggle = (key, val) => {
    const cur = filters[key] || [];
    const next = cur.includes(val) ? cur.filter((v) => v !== val) : [...cur, val];
    setFilters({ ...filters, [key]: next });
  };
  const clear = () => setFilters({});
  const totalActive = Object.values(filters).reduce((a, b) => a + (b?.length || 0), 0);
  return (
    <aside className="plp-filters">
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", paddingBottom: 14, borderBottom: "1px solid var(--solo-black)" }}>
        <span style={{ fontFamily: "var(--solo-font-display)", fontWeight: 700, fontSize: 16, letterSpacing: "-0.01em" }}>Filters</span>
        <button onClick={clear} disabled={!totalActive} style={{ background: "transparent", border: 0, fontFamily: "var(--solo-font-mono)", fontSize: 11, letterSpacing: "0.06em", color: totalActive ? "var(--solo-black)" : "var(--solo-cool)", cursor: totalActive ? "pointer" : "default", textTransform: "uppercase" }}>
          Clear {totalActive ? `(${totalActive})` : ""}
        </button>
      </div>
      {groups.map((g) => {
        const counts = {};
        products.forEach((p) => {
          const v = p.filters?.[g.key];
          if (v) counts[v] = (counts[v] || 0) + 1;
        });
        return (
          <div key={g.key} className="filter-group">
            <div className="head">
              <span>{g.lab}</span>
              <span className="ct">{g.opts.length}</span>
            </div>
            <div className="opts">
              {g.opts.map((o) => {
                const [val, label] = Array.isArray(o) ? o : [o, o];
                const checked = (filters[g.key] || []).includes(val);
                return (
                  <label key={val} className="filter-opt">
                    <input type="checkbox" checked={checked} onChange={() => toggle(g.key, val)} />
                    <span>{label}</span>
                    <span className="ct">{counts[val] || 0}</span>
                  </label>);

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

      })}
    </aside>);

}

function ProductCard({ p, cat, view }) {
  return (
    <article className="product-card">
      <div className="imgwrap">
        <div className="badges">
          {p.badges?.includes("std") && <span className="badge std">Standard</span>}
          {p.badges?.includes("new") && <span className="badge new">New 2026</span>}
          {p.badges?.includes("premium") && <span className="badge">Premium</span>}
          {p.badges?.includes("budget") && <span className="badge">Budget</span>}
        </div>
        {CAT_IMG[cat]}
      </div>
      <div className="body">
        <div className="brand">{p.brand}</div>
        <h3>{p.h}</h3>
        <div className="specs">
          {p.power &&
          <div className="s">
              <span className="k">{cat === "panels" ? "Power" : cat === "batteries" ? "Peak" : cat === "inverters" ? "Output" : "Rating"}</span>
              <span className="v">{p.power}</span>
            </div>
          }
          {p.eff &&
          <div className="s">
              <span className="k">Efficiency</span>
              <span className="v">{p.eff}</span>
            </div>
          }
          {p.cap &&
          <div className="s">
              <span className="k">Usable</span>
              <span className="v">{p.cap}</span>
            </div>
          }
          {p.phase &&
          <div className="s">
              <span className="k">Phase</span>
              <span className="v">{p.phase}</span>
            </div>
          }
          <div className="s">
            <span className="k">Warranty</span>
            <span className="v">{p.warranty}</span>
          </div>
        </div>
        <div className="foot">
          <span className={`price ${p.price === "—" ? "unit" : ""}`}>
            {p.price}
            {p.price !== "—" && <small>{p.unit}</small>}
          </span>
          <span className="arrow">→</span>
        </div>
      </div>
    </article>);

}

function ProductList() {
  const [cat, setCat] = useState("panels");
  const [filters, setFilters] = useState({});
  const [sort, setSort] = useState("standard");
  const [view, setView] = useState("grid");

  const all = PRODUCTS[cat] || [];
  const filtered = useMemo(() => {
    const active = Object.entries(filters).filter(([_, v]) => v?.length);
    if (!active.length) return all;
    return all.filter((p) => active.every(([k, v]) => v.includes(p.filters?.[k])));
  }, [all, filters]);

  const sorted = useMemo(() => {
    const list = [...filtered];
    const num = (s) => parseFloat(String(s).replace(/[^0-9.]/g, "")) || 0;
    if (sort === "price-asc") list.sort((a, b) => num(a.price) - num(b.price));
    if (sort === "price-desc") list.sort((a, b) => num(b.price) - num(a.price));
    if (sort === "power") list.sort((a, b) => num(b.power) - num(a.power));
    if (sort === "warranty") list.sort((a, b) => num(b.warranty) - num(a.warranty));
    if (sort === "standard") list.sort((a, b) => (b.badges?.includes("std") ? 1 : 0) - (a.badges?.includes("std") ? 1 : 0));
    return list;
  }, [filtered, sort]);

  React.useEffect(() => { setFilters({}); }, [cat]);

  return (
    <>
      <Hero cat={cat} setCat={setCat} />
      <section className="edge">
        <div className="plp-body" id={cat}>
          <Filters cat={cat} filters={filters} setFilters={setFilters} products={all} />
          <div>
            <div className="plp-toolbar">
              <div className="results">
                <span className="lab">{CATEGORIES.find((c) => c.id === cat)?.v}</span>
                <span className="v">{sorted.length}<small>of {all.length} products</small></span>
              </div>
              <div className="controls">
                <span className="lab">Sort</span>
                <select value={sort} onChange={(e) => setSort(e.target.value)}>
                  <option value="standard">Standard first</option>
                  <option value="price-asc">Price · low → high</option>
                  <option value="price-desc">Price · high → low</option>
                  <option value="power">Power · high → low</option>
                  <option value="warranty">Warranty · longest</option>
                </select>
                <div className="view-toggle">
                  <button className={view === "grid" ? "active" : ""} onClick={() => setView("grid")} aria-label="Grid view">
                    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                      <rect x="0.5" y="0.5" width="5" height="5" stroke="currentColor" />
                      <rect x="8.5" y="0.5" width="5" height="5" stroke="currentColor" />
                      <rect x="0.5" y="8.5" width="5" height="5" stroke="currentColor" />
                      <rect x="8.5" y="8.5" width="5" height="5" stroke="currentColor" />
                    </svg>
                  </button>
                  <button className={view === "list" ? "active" : ""} onClick={() => setView("list")} aria-label="List view">
                    <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                      <line x1="0" y1="2" x2="14" y2="2" stroke="currentColor" strokeWidth="1.5" />
                      <line x1="0" y1="7" x2="14" y2="7" stroke="currentColor" strokeWidth="1.5" />
                      <line x1="0" y1="12" x2="14" y2="12" stroke="currentColor" strokeWidth="1.5" />
                    </svg>
                  </button>
                </div>
              </div>
            </div>
            <div className={`product-grid ${view === "list" ? "list-view" : ""}`}>
              {sorted.map((p, i) =>
              <ProductCard key={i} p={p} cat={cat} view={view} />
              )}
            </div>
          </div>
        </div>
      </section>
    </>);

}

function BrandStrip() {
  return (
    <section className="edge brand-strip">
      <div className="head">
        <h2>14 brands. <span style={{ color: "var(--solo-cool)" }}>Hand-picked, not affiliate.</span></h2>
        <p>We don't take kickbacks from manufacturers. Brands are listed because their gear earned a slot on a SOLO crew's van — not because they paid for it.</p>
      </div>
      <div className="brands-grid">
        {BRANDS.map((b, i) =>
        <div key={i} className="brand-card">
            <div className="lockup">
              {b.lockup}
              <small>{b.spec}</small>
            </div>
            <div className="ct">
              Role
              <b>{b.role}</b>
            </div>
          </div>
        )}
      </div>
    </section>);

}

function Compatibility() {
  return (
    <section className="edge compat">
      <div className="compat-grid">
        <div>
          <span className="mono-tag"><span className="dot black"></span>Compatibility · 04 notes</span>
          <h2>What pairs with what.</h2>
          <p>You can mix from any of these lists, but not every combination passes our pre-install check. Here are the four big ones — the rest is in the configurator footnotes.</p>
        </div>
        <div className="compat-list">
          {COMPAT_NOTES.map((c, i) =>
          <div key={i} className="compat-row">
              <span className="n">{c.n}</span>
              <div>
                <div className="h">{c.h}</div>
                <p className="p">{c.p}</p>
              </div>
            </div>
          )}
        </div>
      </div>
    </section>);

}

function Closer() {
  return (
    <section className="closer-strip edge">
      <div className="row">
        <div>
          <h2>Don't shop the SKUs. <em>Shop the system.</em></h2>
          <p className="meta" style={{ marginTop: 24 }}>The standard is the standard for a reason — but if you want a slimmer battery or a three-phase inverter, it's two clicks in the configurator.</p>
          <div className="cta">
            <a href="systems.html" className="btn btn-primary btn-lg">Configure my system <span className="arrow">→</span></a>
            <a href="index.html#hero" className="btn btn-ghost-light btn-lg">Get my price</a>
          </div>
        </div>
        <div style={{ alignSelf: "end" }}>
          <div className="mono-tag" style={{ background: "transparent", borderColor: "rgba(255,255,255,.32)", color: "rgba(255,255,255,.72)" }}>
            <span className="dot"></span>Indicative · 9.9 kW + 13.5 kWh · post-rebate
          </div>
          <div style={{ fontFamily: "var(--solo-font-display)", fontWeight: 900, fontSize: 88, letterSpacing: "-0.04em", lineHeight: 0.9, color: "var(--solo-volt)", marginTop: 18 }}>
            $16,800
          </div>
          <div style={{ fontFamily: "var(--solo-font-mono)", fontSize: 12, letterSpacing: "0.06em", color: "rgba(255,255,255,.6)", textTransform: "uppercase", marginTop: 8 }}>
            Ballarat 3350 · post-rebate · GST inc.
          </div>
        </div>
      </div>
    </section>);

}

function Footer() {
  return (
    <footer className="edge">
      <div className="footer-line">
        <a className="word" href="index.html"><img src="assets/SOLO_WORDMARK_BLACK.svg" alt="SOLO" /></a>
        <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>
        </div>
        <div>SOLO Energy Pty Ltd · ABN 12 345 678 901 · CEC retailer code SOLO-00428</div>
      </div>
    </footer>);

}

function Page() {
  return (
    <div className="page" id="top" data-volt="more" data-typescale="restrained" data-sunprint="corner">
      <Announce />
      <Topbar />
      <ProductList />
      <BrandStrip />
      <Compatibility />
      <Closer />
      <Footer />
    </div>);

}

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